Compare commits

...

10 Commits

59 changed files with 837899 additions and 837175 deletions

4
.gitignore vendored
View File

@ -21,4 +21,6 @@ minecraft/region*.lights.vtx
minecraft/region*.dump
minecraft/gen/map.txt
test.pack
pack_main
pack_main
.gdb_history
*.pcm

View File

@ -5,21 +5,29 @@ OBJCOPY=$(PREFIX)objcopy
OBJARCH = elf64-x86-64
OPT = -O0 -march=x86-64-v3
OPT = -Og -march=x86-64-v3
DEBUG = -g
CSTD = -std=gnu23
CXXSTD = -std=gnu++23
CFLAGS += -g
CFLAGS += -fpic
CFLAGS += -I./include
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -Wno-error=unused-but-set-variable
CFLAGS += -Wno-error=unknown-pragmas -Wno-unknown-pragmas
CFLAGS += -Wno-error=unused-function
CFLAGS += -Wno-error=array-bounds
CFLAGS += -fno-strict-aliasing
ifdef READ_PACK_FILE
CFLAGS += -DREAD_PACK_FILE
endif
CFLAGS += -I./include
CFLAGS += -I../SDL3-dist/include
CFLAGS += -I../opus-dist/include
LDFLAGS += -lm
ifeq ($(shell uname),Linux)
LDFLAGS += -Wl,-z noexecstack
endif
MINECRAFT_OBJS = \
minecraft/love2dworld/inthash.o \
@ -54,6 +62,7 @@ OBJS = \
src/lua_api.o \
src/pixel_line_art.o \
src/flame.o \
src/audio.o \
data/scenes/ship20/ship20.o \
data/scenes/noodle/noodle.o \
data/scenes/shadow_test/shadow_test.o \
@ -64,28 +73,26 @@ ifdef READ_PACK_FILE
OBJS += test.pack.o
endif
all: test.so
all: main
%.o: %.c
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(OPT) -c $< -o $@
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@
%.o: %.cpp
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(OPT) -c $< -o $@
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@
test.pack: pack_main
./pack_main $@ $(shell cat filenames.txt)
PACK_FILENAMES = $(shell cat filenames.txt)
test.pack: tool/pack_file $(PACK_FILENAMES)
./tool/pack_file $@ $(PACK_FILENAMES)
test.pack.o: test.pack
$(OBJCOPY) -I binary -O $(OBJARCH) $< $@
test.so: $(OBJS)
$(CC) $(ARCH) $(OPT) -Wl,-z noexecstack -shared -g $^ -o $@ -lSDL3
test.dll: $(OBJS)
$(CXX) $(ARCH) $(OPT) -mthreads -static -mdll -static-libstdc++ -static-libgcc -g $^ -o $@ -L. -lSDL3 $(WINDOWS)
$(CXX) $(ARCH) $(OPT) -mthreads -static -mdll -static-libstdc++ -static-libgcc $(DEBUG) $^ -o $@ -L. -lSDL3 $(WINDOWS)
main: $(OBJS) src/main.o
$(CC) $(ARCH) $(LDFLAGS) $(OPT) -g $^ -o $@
main: $(OBJS) src/main.o ../SDL3-dist/lib64/libSDL3.a ../opus-dist/lib/libopus.a
$(CC) $(ARCH) $(LDFLAGS) $(OPT) $(DEBUG) $^ -o $@
clean:
find . -type f ! -name "*.*" -delete

BIN
audio/Suite.opus.bin Normal file

Binary file not shown.

View File

@ -55,3 +55,4 @@ data/scenes/book/book.idx
shader/flame.vert
shader/flame.frag
minecraft/flame.data
audio/Suite.opus.bin

7
include/audio.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
namespace audio {
void init();
void load();
void update();
}

View File

@ -1,14 +0,0 @@
#pragma once
#ifdef _WIN32
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#define DECL __cdecl
#else
#define EXPORT __attribute__((dllexport))
#define DECL __attribute__((__cdecl__))
#endif
#else
#define EXPORT
#define DECL
#endif

View File

@ -1,18 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int draw_font_start();
int draw_font(int font_ix, char const * text, int x, int y);
void draw_line_quad_start();
void draw_line(int x1, int y1, int x2, int y2);
void draw_set_color(float r, float g, float b);
void draw_quad(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4);
#ifdef __cplusplus
}
#endif

View File

@ -4,6 +4,8 @@
namespace minecraft {
extern world::state * current_world;
static const int max_world_count = 10;
extern world::state world_state[max_world_count];
void load();
void draw();

View File

@ -16,7 +16,8 @@ struct {
{1152, 3180}, // candle.obj
{4332, 1584}, // custom_mushroom.obj
{5916, 36}, // fence.obj
{5952, 24}, // stair.obj
{5976, 12}, // tall_grass.obj
{5988, 2082}, // wall_torch.obj
{5952, 24}, // slab.obj
{5976, 24}, // stair.obj
{6000, 12}, // tall_grass.obj
{6012, 2082}, // wall_torch.obj
};

View File

@ -1,12 +0,0 @@
#pragma once
namespace pixel_line_art {
void load();
void draw_line_quad_start();
void draw_line(int x1, int y1, int x2, int y2);
void draw_set_color(float r, float g, float b);
void draw_quad(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4);
}

View File

@ -1,28 +1,25 @@
#pragma once
#include "declarations.h"
#ifdef __cplusplus
extern "C" {
#endif
EXPORT void DECL load(const char * source_path);
EXPORT void DECL draw();
EXPORT void DECL love2d_state_load();
EXPORT void DECL love2d_state_restore();
EXPORT void DECL update_keyboard(int up, int down, int left, int right,
int w, int s, int a, int d,
int t, int g, int f, int h,
int i, int k, int j, int l,
int q, int e);
EXPORT void DECL update_mouse(int x, int y);
EXPORT void DECL update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder,
int start);
EXPORT void DECL update(float time);
void load(const char * source_path);
void draw();
void love2d_state_load();
void love2d_state_restore();
void update_keyboard(int up, int down, int left, int right,
int w, int s, int a, int d,
int t, int g, int f, int h,
int i, int k, int j, int l,
int q, int e);
void update_mouse(int x, int y);
void update_joystick(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder,
int start);
void update(float time);
#ifdef __cplusplus
}

View File

@ -1,7 +1,5 @@
#pragma once
#include "declarations.h"
namespace window {
extern float width;
extern float height;
@ -10,7 +8,7 @@ namespace window {
#ifdef __cplusplus
extern "C" {
#endif
EXPORT void DECL update_window(int width, int height);
void update_window(int width, int height);
#ifdef __cplusplus
}
#endif

View File

@ -26,7 +26,7 @@ namespace world {
};
// also update index_buffer_custom_offsets in include/minecraft_data.inc
const int custom_block_types = 6;
const int custom_block_types = 7;
const int instance_cfg_length = 64 + custom_block_types;
struct instance_cfg_entry {

View File

@ -1,5 +1,5 @@
local ffi = require 'ffi'
local joysticks
local joysticks = {}
function init_joysticks()
joysticks = {}

Binary file not shown.

View File

@ -9,6 +9,7 @@ Leaves,18,"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15",12,,,,
Unused,20,,11,,,,
Door Bottom,21,,18,,,,
Door Top,22,,17,,,,
(unknown),24,,3,,,,
Tall Grass,31,"0,1",22,tall_grass,two_sided,,
Tan Block 1,35,1,2,,,,
White Block 2,35,5,6,,,,
@ -24,6 +25,7 @@ Lilac Grass,37,,15,tall_grass,two_sided,,
Spider Plant,38,,13,tall_grass,two_sided,,
Spider Plant,39,,13,tall_grass,two_sided,,
Red Mushroom,40,,14,custom_mushroom,,,
Slab,44,"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15",4,slab,slab_oriented,,
Start/Finish Line,45,,16,,,,
Shadow Block,49,,20,,,,
Wall Torch,50,"1,2,3,4",62,wall_torch,"emits_light,torch_oriented",,

1 name block id data linear texture index custom mesh properties notes
9 Unused 20 11
10 Door Bottom 21 18
11 Door Top 22 17
12 (unknown) 24 3
13 Tall Grass 31 0,1 22 tall_grass two_sided
14 Tan Block 1 35 1 2
15 White Block 2 35 5 6
25 Spider Plant 38 13 tall_grass two_sided
26 Spider Plant 39 13 tall_grass two_sided
27 Red Mushroom 40 14 custom_mushroom
28 Slab 44 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 4 slab slab_oriented
29 Start/Finish Line 45 16
30 Shadow Block 49 20
31 Wall Torch 50 1,2,3,4 62 wall_torch emits_light,torch_oriented

View File

@ -85,9 +85,11 @@ def get_special(block_id, block_data):
return 1
if "stair_oriented" in decl.properties:
return 2
if "slab_oriented" in decl.properties:
return 3
return 0
if __name__ == "__main__":
from pprint import pprint
#print(sorted_custom_mesh)
pprint(sorted_decls)
print(sorted_custom_mesh)
#pprint(sorted_decls)

View File

@ -6,15 +6,15 @@ CROP=-255,-255:382,382
ALL_REGIONS=../midnightmeadow/all_regions.txt
cat <<EOF > $ALL_REGIONS
$HOME/MidnightMeadow/region/r.0.0.mcr
$HOME/MidnightMeadow/region/r.-1.-1.mcr
$HOME/MidnightMeadow/region/r.0.-1.mcr
$HOME/MidnightMeadow/region/r.-1.0.mcr
$HOME/sunnyhill/region/r.0.0.mcr
$HOME/sunnyhill/region/r.-1.-1.mcr
$HOME/sunnyhill/region/r.0.-1.mcr
$HOME/sunnyhill/region/r.-1.0.mcr
EOF
$PYTHON mc.py $HOME/MidnightMeadow/region/r.0.0.mcr ../midnightmeadow/region.0.0 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.-1.-1.mcr ../midnightmeadow/region.-1.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.0.-1.mcr ../midnightmeadow/region.0.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/MidnightMeadow/region/r.-1.0.mcr ../midnightmeadow/region.-1.0 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/sunnyhill/region/r.0.0.mcr ../midnightmeadow/region.0.0 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/sunnyhill/region/r.-1.-1.mcr ../midnightmeadow/region.-1.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/sunnyhill/region/r.0.-1.mcr ../midnightmeadow/region.0.-1 $ALL_REGIONS $CROP &
$PYTHON mc.py $HOME/sunnyhill/region/r.-1.0.mcr ../midnightmeadow/region.-1.0 $ALL_REGIONS $CROP &
wait

View File

@ -17,4 +17,4 @@ def write_obj(vertex_buffer, index_buffer, index_lookup, path):
state = obj.parse_obj_from_filename(path)
obj_state.append_triangles(state, vertex_buffer, index_buffer, index_lookup)
index_count = len(index_buffer) - index_start
print(f"{index_start}, {index_count}, // {path}")
print(f"{{{index_start}, {index_count}}}, // {path}")

35
minecraft/gen/slab.obj Normal file
View File

@ -0,0 +1,35 @@
# Blender 5.0.0
# www.blender.org
o Plane
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 0.000000 0.000000
v -1.000000 -0.000000 0.000000
vn 1.0000 -0.0000 -0.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 0.7071 0.7071
vn -0.0000 0.7071 -0.7071
vn -0.0000 -1.0000 -0.0000
vt 0.500000 0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.500000 0.500000
vt 0.000000 0.500000
vt 1.000000 0.500000
vt 1.000000 1.000000
vt 0.000000 0.500000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 1.000000 0.500000
s 0
f 5/1/1 1/2/1 3/3/1
f 6/4/2 4/2/2 2/3/2
f 2/3/3 5/5/3 6/6/3
f 5/7/4 4/8/4 6/9/4
f 1/2/5 4/10/5 3/11/5
f 2/3/3 1/2/3 5/5/3
f 5/7/4 3/12/4 4/8/4
f 1/2/5 2/3/5 4/10/5

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/home/bilbo/MidnightMeadow/region/r.0.0.mcr
/home/bilbo/MidnightMeadow/region/r.-1.-1.mcr
/home/bilbo/MidnightMeadow/region/r.0.-1.mcr
/home/bilbo/MidnightMeadow/region/r.-1.0.mcr
/home/bilbo/sunnyhill/region/r.0.0.mcr
/home/bilbo/sunnyhill/region/r.-1.-1.mcr
/home/bilbo/sunnyhill/region/r.0.-1.mcr
/home/bilbo/sunnyhill/region/r.-1.0.mcr

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

9
sdl3-build.sh Normal file
View File

@ -0,0 +1,9 @@
cmake ../SDL3-3.4.2/ -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=../SDL3-dist
cmake --build . --config Debug
cmake --install . --config Debug
# opus
../opus-1.6.1/configure LDFLAGS="-static" CFLAGS="-march=x86-64-v3 -O2 -pipe" --prefix=../opus-dist
make
make install

View File

@ -26,7 +26,7 @@ void main()
vec3 out_color = color.xyz * 0.1;
if (false) {
if (LightCount != 0) {
for (int i = 0; i < LightCount; i++) {
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
float light_distance = length(light_position - position.xyz);

View File

@ -41,5 +41,6 @@ void main()
Position = fs_in.Position.xzy;
Normal = vec4(normalize(fs_in.Normal.xzy), two_sided);
Color = texture_color.xyz;
//Color = vec3(normalize(fs_in.Normal.xzy));
Block = vec4(fs_in.BlockID, fs_in.Data, fs_in.TextureID, fs_in.Special);
}

View File

@ -35,6 +35,22 @@ vec3 orientation(vec3 position)
return vec3(position.x, position.y, -position.z);
else // "facing south"
return position;
} else if (Special == 2) { // oriented stair
if (Data == 0) {
return vec3(-position.x, position.y, position.z);
} else if (Data == 2) { //
return vec3(position.z, position.y, -position.x);
} else if (Data == 3) { //
return vec3(-position.z, position.y, position.x);
} else {
return position;
}
} else if (Special == 3) {
if (BlockPosition.x == -70) {
return vec3(position.z, position.y, -position.x);
} else {
return position;
}
} else {
return position;
}

123
src/audio.cpp Normal file
View File

@ -0,0 +1,123 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <opus/opus.h>
#include <SDL3/SDL.h>
#include "file.h"
#include "audio.h"
namespace audio {
int const frame_samples = 960; // 20 milliseconds @ 48kHz
int const sample_rate = 48000;
int const channels = 2;
int const sample_size = (sizeof (int16_t));
int const max_frame_size = 960 * 3; // 20ms at 48kHz
int const max_packet_size = 1275;
//
SDL_AudioStream * audio_stream;
SDL_AudioSpec audio_spec;
void const * audio_buf;
int audio_size;
int audio_samples_total;
int audio_offset;
int audio_samples_decoded;
OpusDecoder * opus_decoder;
void init()
{
audio_spec.channels = channels;
audio_spec.format = SDL_AUDIO_S16LE;
audio_spec.freq = sample_rate;
audio_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec, NULL, NULL);
assert(audio_stream);
SDL_ResumeAudioStreamDevice(audio_stream);
int err;
opus_decoder = opus_decoder_create(sample_rate, channels, &err);
if (err < 0) {
fprintf(stderr, "opus_decoder_create: %s\n", opus_strerror(err));
assert(!"opus_decoder_create");
}
}
void load()
{
audio_buf = file::read_file("audio/Suite.opus.bin", &audio_size);
assert(audio_buf != nullptr);
uint8_t const * buf = (uint8_t const *)audio_buf;
audio_samples_total
= (buf[3] << 24)
| (buf[2] << 16)
| (buf[1] << 8)
| (buf[0] << 0);
printf("audio samples total: %d\n", audio_samples_total);
audio_offset = 4;
audio_samples_decoded = 0;
}
inline static int min(int a, int b)
{
return (a < b) ? a : b;
}
void update()
{
int half_period_samples = audio_spec.freq / 2;
int half_period_size = half_period_samples * sample_size * audio_spec.channels;
if (SDL_GetAudioStreamQueued(audio_stream) < half_period_size) {
int put_samples = half_period_samples;
while (put_samples > 0) {
uint8_t const * buf = (uint8_t const *)audio_buf;
assert(audio_offset <= audio_size);
if (audio_offset == audio_size) {
assert(audio_samples_decoded == audio_samples_total);
audio_offset = 4;
audio_samples_decoded = 0;
int err = opus_decoder_ctl(opus_decoder, OPUS_RESET_STATE);
if (err < 0) {
fprintf(stderr, "opus_encoder_ctl(OPUS_RESET_STATE): %s\n", opus_strerror(err));
assert(!"opus_encoder_ctl");
}
}
uint16_t packet_size = (buf[audio_offset + 1] << 8) | (buf[audio_offset + 0] << 0);
audio_offset += 2;
int16_t decode_buf[max_frame_size * channels];
int frame_size = opus_decode(opus_decoder, &buf[audio_offset], packet_size, decode_buf, max_frame_size, 0);
if (frame_size < 0) {
fprintf(stderr, "opus_decode: %s\n", opus_strerror(frame_size));
assert(!"opus_decode\n");
}
audio_offset += packet_size;
int max_samples_this_frame = audio_samples_total - audio_samples_decoded;
assert(max_samples_this_frame > 0);
/*
if (frame_size > max_samples_this_frame) {
fprintf(stderr, "max samples %d %d\n", frame_size, max_samples_this_frame);
}
*/
frame_size = min(max_samples_this_frame, frame_size);
SDL_PutAudioStreamData(audio_stream,
(void *)decode_buf,
frame_size * channels * sample_size);
put_samples -= frame_size;
audio_samples_decoded += frame_size;
}
}
}
}

View File

@ -506,7 +506,6 @@ namespace collada::scene {
glUniform1i(layout.uniform.specular_sampler, 3);
}
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
glDisable(GL_CULL_FACE);
//glCullFace(GL_FRONT);

View File

@ -83,7 +83,6 @@ namespace flame {
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
glActiveTexture(GL_TEXTURE0);

View File

@ -2,11 +2,15 @@
#include <string.h>
#include "directxmath/directxmath.h"
#include "glad/gl.h"
#include "font/bitmap.h"
#include "font/outline.h"
#include "view.h"
#include "window.h"
extern font::bitmap::font * terminus_fonts;
extern font::outline::font * uncial_antiqua_fonts;
extern unsigned int empty_vertex_array_object;
extern unsigned int quad_index_buffer;
@ -80,6 +84,8 @@ namespace hud {
return y + font.desc->glyph_height;
}
static int frame = 0;
void draw()
{
static char buf[512];
@ -90,25 +96,55 @@ namespace hud {
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
y = draw_label<float>(ter_best, buf, 10, y, "fov: ", "%.3f", view::state.fov);
y = draw_label<int>(ter_best, buf, 10, y, "font_height: ", "%d", ter_best.desc->glyph_height);
//y = draw_label<float>(ter_best, buf, 10, y, "fov: ", "%.3f", view::state.fov);
//y = draw_label<int>(ter_best, buf, 10, y, "font_height: ", "%d", ter_best.desc->glyph_height);
font::bitmap::draw_string(ter_best, "keyboard:", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " move: w/a/s/d", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " look: up/down/left/right", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " elevate: q/e", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " warp: l", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, "gamepad:", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " move: left stick", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " look: right stick", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " elevate: left/right trigger", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, " warp: a", 10, y); y += ter_best.desc->glyph_height;
font::bitmap::draw_string(ter_best, "mouse:", 10, y); y += ter_best.desc->glyph_height;
y = draw_vector(ter_best, buf, y, " position", XMLoadFloat4((XMFLOAT4*)mouse_position));
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat4((XMFLOAT4*)mouse_block));
if (frame++ > 60 * 10)
return;
font::outline::draw_start(uncial_antiqua_fonts[0], empty_vertex_array_object, quad_index_buffer);
char const * title = "Technical demo: Bibliotheca";
int const title_length = strlen(title);
int title_width = 563;
int title_height = 31;
int title_x = (window::width - title_width) / 2.0;
int title_y = (window::height - title_height) / 2.0;
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
font::outline::draw_string(uncial_antiqua_fonts[0], title, title_x + 3, title_y + 3);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
font::outline::draw_string(uncial_antiqua_fonts[0], title, title_x + 0, title_y + 0);
/*
y = draw_label<float>(ter_best, buf, 10, y, "lighting.quadratic: ", "%.2f", lighting.quadratic);
y = draw_label<float>(ter_best, buf, 10, y, "lighting.linear: ", "%.2f", lighting.linear);
*/
/*
y = draw_vector(ter_best, buf, y, "eye", XMVectorSetW(view::state.eye, 0));
y = draw_vector(ter_best, buf, y, "at", XMVectorSetW(view::state.at, 0));
y = draw_vector(ter_best, buf, y, "forward", XMVectorSetW(view::state.forward, 0));
y = draw_label<float>(ter_best, buf, 10, y, "pitch: ", "%.4f", view::state.pitch);
y = draw_label<float>(ter_best, buf, 10, y, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
font::bitmap::draw_string(ter_best, "mouse:", 10, y);
y += ter_best.desc->glyph_height;
y = draw_vector(ter_best, buf, y, " position", XMLoadFloat4((XMFLOAT4*)mouse_position));
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat4((XMFLOAT4*)mouse_block));
*/
}
}

View File

@ -244,7 +244,6 @@ namespace line_art {
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glBindVertexArray(vertex_array_object);

View File

@ -1,45 +0,0 @@
#include "font/bitmap.h"
#include "pixel_line_art.h"
#include "lua_api.h"
extern font::bitmap::font * terminus_fonts;
extern unsigned int empty_vertex_array_object;
extern unsigned int quad_index_buffer;
int draw_font_start()
{
int font_ix = font::bitmap::best_font(font::bitmap::terminus, font::bitmap::terminus_length);
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
return font_ix;
}
int draw_font(int font_ix, char const * text, int x, int y)
{
font::bitmap::font const& ter_best = terminus_fonts[font_ix];
font::bitmap::draw_string(ter_best, text, x, y);
return ter_best.desc->glyph_height;
}
void draw_line_quad_start()
{
pixel_line_art::draw_line_quad_start();
}
void draw_line(int x1, int y1, int x2, int y2)
{
pixel_line_art::draw_line(x1, y1, x2, y2);
}
void draw_set_color(float r, float g, float b)
{
pixel_line_art::draw_set_color(r, g, b);
}
void draw_quad(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4)
{
pixel_line_art::draw_quad(x1, y1, x2, y2,
x3, y3, x4, y4);
}

View File

@ -1,53 +0,0 @@
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdbool.h>
#include "glad/gl.h"
#include <GLFW/glfw3.h>
extern void load();
extern void draw();
int main()
{
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(1024, 1024, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
const char* description;
glfwGetError(&description);
printf("Failed to create GLFW window: %s\n", description);
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress);
glViewport(0, 0, 1024, 1024);
load();
while(!glfwWindowShouldClose(window)) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
draw();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}

170
src/main.cpp Normal file
View File

@ -0,0 +1,170 @@
#include <stdio.h>
#include <string.h>
#include <SDL3/SDL.h>
#include "glad/gl.h"
#include "test.h"
#include "window.h"
#include "view.h"
#include "audio.h"
static int const max_gamepads = 16;
static SDL_Gamepad * gamepads[max_gamepads];
static int gamepad_count = 0;
void add_gamepad(SDL_JoystickID instance_id)
{
SDL_Gamepad * gamepad = SDL_OpenGamepad(instance_id);
char const * name = SDL_GetGamepadName(gamepad);
if (gamepad_count >= max_gamepads) {
printf("too many gamepads; ignoring gamepad %d %s\n", instance_id, name);
SDL_CloseGamepad(gamepad);
} else {
printf("add gamepad %d %s\n", instance_id, name);
gamepads[gamepad_count] = gamepad;
gamepad_count += 1;
}
}
void remove_gamepad(SDL_JoystickID instance_id)
{
for (int i = 0; i < gamepad_count; i++) {
if (SDL_GetGamepadID(gamepads[i]) == instance_id) {
int tail = (gamepad_count - i) - 1;
memcpy(&gamepads[i], &gamepads[i+1], tail * (sizeof (gamepads[0])));
return;
}
}
assert(!"remove_gamepad");
}
void update()
{
for (int i = 0; i < gamepad_count; i++) {
SDL_Gamepad * gamepad = gamepads[i];
int16_t leftx = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
int16_t lefty = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
int16_t rightx = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX);
int16_t righty = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY);
int16_t left_trigger = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER);
int16_t right_trigger = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
bool dpad_up = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP);
bool dpad_down = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
bool dpad_left = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
bool dpad_right = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
bool a = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_SOUTH);
bool b = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_EAST);
bool x = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_WEST);
bool y = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_NORTH);
bool left_shoulder = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
bool right_shoulder = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
bool start = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER);
float scale = 1.0f / 32767.0f;
update_joystick((float)leftx * scale,
(float)lefty * scale,
(float)rightx * scale,
(float)righty * scale,
(float)left_trigger * scale,
(float)right_trigger * scale,
dpad_up, dpad_down, dpad_left, dpad_right,
a, b, x, y,
left_shoulder, right_shoulder,
start);
}
view::update_transforms();
}
int main()
{
SDL_SetAppMetadata("Bibliotheca", "1.0", "st.idk.bibliotheca");
bool ret;
SDL_InitFlags sdl_flags
= SDL_INIT_EVENTS
| SDL_INIT_VIDEO
| SDL_INIT_JOYSTICK
| SDL_INIT_GAMEPAD
| SDL_INIT_AUDIO
;
ret = SDL_Init(sdl_flags);
if (!ret) {
fprintf(stderr, "SDL_Init(SDL_INIT_VIDEO): %s\n", SDL_GetError());
return 1;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_WindowFlags window_flags
= SDL_WINDOW_RESIZABLE
| SDL_WINDOW_OPENGL
;
SDL_Window * window = SDL_CreateWindow("Bibliotheca", 1024, 1024, window_flags);
if (window == NULL) {
fprintf(stderr, "SDL_CreateWindow: %s\n", SDL_GetError());
return 1;
}
SDL_GLContext context = SDL_GL_CreateContext(window);
if (context == NULL) {
fprintf(stderr, "SDL_GL_CreateContext: %s\n", SDL_GetError());
return 1;
}
int version = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
if (version == 0) {
fprintf(stderr, "gladLoadGL\n");
}
load(".");
audio::init();
audio::load();
update_window(1024, 1024);
while (true) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT:
goto exit;
case SDL_EVENT_KEY_DOWN:
if (event.key.key == SDLK_ESCAPE)
goto exit;
break;
case SDL_EVENT_WINDOW_RESIZED:
printf("%d %d\n", event.window.data1, event.window.data2);
break;
case SDL_EVENT_GAMEPAD_ADDED:
add_gamepad(event.gdevice.which);
break;
case SDL_EVENT_GAMEPAD_REMOVED:
remove_gamepad(event.gdevice.which);
break;
}
}
update();
draw();
audio::update();
SDL_GL_SwapWindow(window);
}
exit:
SDL_GL_DestroyContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

View File

@ -45,8 +45,7 @@ namespace minecraft {
static unsigned int texture;
static const int max_world_count = 10;
static world::state world_state[max_world_count];
world::state world_state[max_world_count];
world::state * current_world;
void load_program()
@ -272,7 +271,7 @@ namespace minecraft {
for (int i = 0; i < world::descriptors_length; i++) {
per_world::load_world(&world::descriptors[i], world_state[i]);
}
current_world = &world_state[world::world_id::MIDNIGHTMEADOW];
current_world = &world_state[world::world_id::GRANDLECTURN];
}
static inline int popcount(int x)
@ -285,7 +284,6 @@ namespace minecraft {
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
glActiveTexture(GL_TEXTURE0);

View File

@ -109,7 +109,6 @@ namespace non_block {
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
XMVECTOR offset = view::state.at;

View File

@ -1,138 +0,0 @@
#include "glad/gl.h"
#include "directxmath/directxmath.h"
#include <stdio.h>
#include "opengl.h"
#include "window.h"
#include "pixel_line_art.h"
extern unsigned int quad_index_buffer;
namespace pixel_line_art {
struct layout {
struct {
unsigned int position;
} attribute;
struct {
unsigned int transform;
unsigned int base_color;
} uniform;
};
const layout layout = {
.attribute = {
.position = 0,
},
.uniform = {
.transform = 0,
.base_color = 1,
},
};
static unsigned int program;
static unsigned int vertex_array_object;
static unsigned int per_vertex_buffer;
static int const per_vertex_size = (sizeof (float)) * 2;
static void load_program()
{
program = compile_from_files("shader/pixel_line_art.vert",
nullptr,
"shader/pixel_line_art.frag");
}
static void load_vertex_attributes()
{
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
glVertexBindingDivisor(0, 0);
glEnableVertexAttribArray(layout.attribute.position);
glVertexAttribFormat(layout.attribute.position, 2, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(layout.attribute.position, 0);
glBindVertexArray(0);
}
static void load_per_vertex_buffer(int x1, int y1, int x2, int y2)
{
float vertex_data[] = {
(float)x1, (float)y1, (float)x2, (float)y2,
};
int vertex_data_size = (sizeof (vertex_data));
glBindBuffer(GL_ARRAY_BUFFER, per_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertex_data_size, vertex_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
static void load_per_vertex_buffer2(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4)
{
float vertex_data[] = {
(float)x1, (float)y1, (float)x2, (float)y2,
(float)x3, (float)y3, (float)x4, (float)y4,
};
int vertex_data_size = (sizeof (vertex_data));
glBindBuffer(GL_ARRAY_BUFFER, per_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertex_data_size, vertex_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void load()
{
load_program();
load_vertex_attributes();
glGenBuffers(1, &per_vertex_buffer);
}
static void set_transform(XMMATRIX const & transform)
{
XMFLOAT4X4 float_transform;
XMStoreFloat4x4(&float_transform, transform);
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
}
void draw_line_quad_start()
{
glUseProgram(program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glBindVertexArray(vertex_array_object);
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
XMMATRIX transform
= XMMatrixScaling(2.0f / window::width, -2.0f / window::height, 0)
* XMMatrixTranslation(-1, 1, 0);
set_transform(transform);
}
void draw_line(int x1, int y1, int x2, int y2)
{
load_per_vertex_buffer(x1, y1, x2, y2);
glDrawArrays(GL_LINES, 0, 2);
}
void draw_quad(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4)
{
load_per_vertex_buffer2(x1, y1, x2, y2,
x3, y3, x4, y4);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
void draw_set_color(float r, float g, float b)
{
glUniform3f(layout.uniform.base_color, r, g, b);
}
}

View File

@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include <SDL3/SDL.h>
#include "geometry_buffer.h"
#include "glad/gl.h"
#include "opengl.h"
@ -25,11 +27,9 @@
#include "collada/scene.h"
#include "collada/types.h"
#include "collada/instance_types.h"
#include "pixel_line_art.h"
#include "flame.h"
#include "new.h"
#include "popcount.h"
#include "declarations.h"
#include "world/entry_table.h"
#include "world/world.h"
@ -116,17 +116,12 @@ void load_quad_program()
quad_program = program;
}
extern "C" void * DECL SDL_GL_GetProcAddress(const char *proc);
void load(const char * source_path)
{
file::source_path_length = strlen(source_path);
assert(source_path[file::source_path_length - 1] != '/');
file::source_path = source_path;
fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress);
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
//
glBindVertexArray(0);
@ -157,12 +152,6 @@ void load(const char * source_path)
uncial_antiqua_fonts = New<font::outline::font>(font::outline::uncial_antiqua_length);
font::outline::load_fonts(uncial_antiqua_fonts, font::outline::uncial_antiqua, font::outline::uncial_antiqua_length);
//////////////////////////////////////////////////////////////////////
// pixel_line_art
//////////////////////////////////////////////////////////////////////
pixel_line_art::load();
//////////////////////////////////////////////////////////////////////
// quad
//////////////////////////////////////////////////////////////////////
@ -213,6 +202,13 @@ void load(const char * source_path)
flame::load_program();
flame::load_texture();
//////////////////////////////////////////////////////////////////////
// opengl state
//////////////////////////////////////////////////////////////////////
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
}
void check_collisions(collision::Sphere const & sphere, XMVECTOR const & direction,
@ -292,6 +288,29 @@ void minecraft_view_update(XMVECTOR direction)
view::state.eye = view::state.at - view::state.direction * view::at_distance;
}
static int world_id = 0;
void next_world()
{
world_id += 1;
if (world_id == 2)
world_id = 0;
if (world_id == 0) {
view::state.eye = XMVectorSet(4.71f, 65.30, 57.92, 1);
} else {
// midnightmeadow
view::state.eye = XMVectorSet(13.71f, -3.36, 92.92, 1);
}
view::state.at = view::state.eye + view::state.direction * view::at_distance;
minecraft::current_world = &minecraft::world_state[world_id];
printf("next world\n");
}
static int last_l = 0;
void update_keyboard(int up, int down, int left, int right,
int w, int s, int a, int d,
int t, int g, int f, int h,
@ -327,10 +346,18 @@ void update_keyboard(int up, int down, int left, int right,
if (true) {
minecraft_view_update(direction);
}
if (l && last_l == 0) {
next_world();
}
last_l = l;
}
void update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
static int last_a = 0;
void update_joystick(float lx, float ly,
float rx, float ry,
float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder,
@ -350,6 +377,11 @@ void update_joystick(int joystick_index,
minecraft_view_update(direction);
}
if (a && last_a == 0) {
next_world();
}
last_a = a;
//view::state.eye = view::state.eye + direction;
//view::state.at = view::state.at - view::state.direction * view::at_distance;
@ -378,8 +410,6 @@ void update(float time)
else
view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
*/
view::update_transforms();
}
void draw_quad()

View File

@ -105,11 +105,10 @@ namespace view {
// position
// grandlecturn
//state.eye = XMVectorSet(4.71f, 65.30, 57.92, 1);
state.eye = XMVectorSet(4.71f, 65.30, 57.92, 1);
// midnightmeadow
state.eye = XMVectorSet(13.71f, -3.36, 90.92, 1);
//state.eye = XMVectorSet(13.71f, -3.36, 90.92, 1);
state.at = state.eye + state.direction * at_distance;
//state.at = XMVectorSet(0, 0, 0, 1);
//state.eye = XMVectorSet(0, -100, 0, 1);

9
tool/Makefile Normal file
View File

@ -0,0 +1,9 @@
OPT = -O2
CFLAGS = -I../../opus-dist/include
CFLAGS = -I../include
opus_encode: opus_encode.c ../../opus-dist/lib/libopus.a
gcc -o $@ $(OPT) $(CFLAGS) -lm $^
pack_file: pack_file.cpp
g++ -o $@ $(OPT) $(CFLAGS) $^

BIN
tool/a.out Executable file

Binary file not shown.

BIN
tool/opus_encode Executable file

Binary file not shown.

121
tool/opus_encode.c Normal file
View File

@ -0,0 +1,121 @@
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <opus/opus.h>
const int frame_size = 960; // 20ms at 48kHz
const int sample_rate = 48000;
const int channels = 2;
const int bitrate = 128000;
const int max_packet_size = 3 * 1275;
int main(int argc, char *argv[])
{
assert(argc == 3);
int err;
OpusEncoder * encoder = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_AUDIO, &err);
if (err < 0) {
fprintf(stderr, "opus_encoder_create: %s\n", opus_strerror(err));
return 1;
}
err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(bitrate));
if (err < 0) {
fprintf(stderr, "opus_encoder_ctl(OPUS_SET_BITRATE): %s\n", opus_strerror(err));
return 1;
}
char const * input_filename = argv[1];
FILE * input_file = fopen(input_filename, "rb");
if (input_file == NULL) {
fprintf(stderr, "fopen(%s): %s\n", input_filename, strerror(errno));
return 1;
}
char const * output_filename = argv[2];
FILE * output_file = fopen(output_filename, "wb");
if (input_file == NULL) {
fprintf(stderr, "fopen(%s): %s\n", output_filename, strerror(errno));
return 1;
}
int16_t input[frame_size * channels];
uint8_t input_buf[frame_size * channels * (sizeof (int16_t))];
uint8_t encode_buf[max_packet_size];
int total_samples = 0;
size_t header_write_1 = fwrite(&total_samples, 1, (sizeof (int)), output_file);
if (header_write_1 != (sizeof (int))) {
fprintf(stderr, "fwrite: %s\n", strerror(errno));
return 1;
}
bool more_data = true;
while (more_data) {
size_t samples = fread(input_buf, (sizeof (int16_t)) * channels, frame_size, input_file);
if (samples == 0)
break;
total_samples += samples;
if (samples != frame_size) {
printf("padding short frame %ld\n", samples);
more_data = false;
for (int i = samples * channels; i < frame_size * channels; i++) {
input_buf[i * 2 + 0] = 0;
input_buf[i * 2 + 1] = 0;
}
}
samples = frame_size;
for (int i = 0; i < channels * frame_size; i++) {
// load little endian
input[i] = (input_buf[2 * i + 1] << 8) | (input_buf[2 * i + 0] << 0);
}
int bytes = opus_encode(encoder, input, frame_size, encode_buf, max_packet_size);
if (bytes < 0) {
fprintf(stderr, "opus_encode: %s\n", opus_strerror(bytes));
return 1;
}
assert(bytes <= 1275);
int16_t encode_bytes = bytes;
size_t bytes_write = fwrite(&encode_bytes, 1, (sizeof (encode_bytes)), output_file);
if (bytes_write != (sizeof (encode_bytes))) {
fprintf(stderr, "fwrite: %s\n", strerror(errno));
return 1;
}
size_t buf_write = fwrite(encode_buf, 1, bytes, output_file);
if (buf_write != bytes) {
fprintf(stderr, "fwrite: %s\n", strerror(errno));
return 1;
}
}
fflush(output_file);
int ret = fseek(output_file, SEEK_SET, 0);
if (ret != 0) {
fprintf(stderr, "fseek: %s\n", strerror(errno));
return 1;
}
size_t header_write_2 = fwrite(&total_samples, 1, (sizeof (int)), output_file);
if (header_write_2 != (sizeof (int))) {
fprintf(stderr, "fwrite: %s\n", strerror(errno));
return 1;
}
printf("total_samples: %d\n", total_samples);
fclose(output_file);
fclose(input_file);
return 0;
}

BIN
tool/pack_file Executable file

Binary file not shown.