diff --git a/.gitignore b/.gitignore index 427b402..3ea2339 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ sm64config.txt # SDL SDL/include + +# libc++ from Termux +android/lib/*/libc++_shared.so diff --git a/Android.mk b/Android.mk index 5e5da57..856abca 100644 --- a/Android.mk +++ b/Android.mk @@ -58,6 +58,7 @@ ULTRA_SRC_DIRS := $(addprefix $(LOCAL_PATH)/,$(ULTRA_SRC_DIRS)) # Source code files LEVEL_C_FILES := $(wildcard $(LOCAL_PATH)/levels/*/leveldata.c) $(wildcard $(LOCAL_PATH)/levels/*/script.c) $(wildcard $(LOCAL_PATH)/levels/*/geo.c) C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) $(LEVEL_C_FILES) +CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) ULTRA_C_FILES := \ alBnkfNew.c \ @@ -83,7 +84,7 @@ LOCAL_SHORT_COMMANDS := true LOCAL_SHARED_LIBRARIES := SDL2 LOCAL_LDLIBS := -lEGL -lGLESv2 -llog LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include $(LOCAL_PATH)/include $(LOCAL_PATH)/src $(PC_BUILD_DIR) $(PC_BUILD_DIR)/include -LOCAL_CFLAGS := -DNON_MATCHING -DAVOID_UB -DTARGET_LINUX -DENABLE_OPENGL -DWIDESCREEN -DF3DEX_GBI_2E -D_LANGUAGE_C -DNO_SEGMENTED_MEMORY -D$(VERSION_DEF) -DSTDC_HEADERS -DUSE_GLES -DRAPI_GL -DWAPI_SDL2 -DAAPI_SDL2 -DCAPI_SDL2 -DHAVE_SDL2 +LOCAL_CFLAGS := -DNON_MATCHING -DAVOID_UB -DTARGET_LINUX -DENABLE_OPENGL -DWIDESCREEN -DF3DEX_GBI_2E -D_LANGUAGE_C -DNO_SEGMENTED_MEMORY -D$(VERSION_DEF) -DSTDC_HEADERS -DUSE_GLES -DRAPI_GL -DWAPI_SDL2 -DAAPI_SDL2 -DCAPI_SDL2 -DHAVE_SDL2 -O3 ifeq ($(TOUCH_CONTROLS),1) LOCAL_CFLAGS += -DTOUCH_CONTROLS @@ -102,6 +103,6 @@ ifeq ($(EXTERNAL_DATA),1) LOCAL_CFLAGS += -DEXTERNAL_DATA -DFS_BASEDIR="\"$(BASEDIR)\"" endif -LOCAL_SRC_FILES := $(C_FILES) $(GENERATED_C_FILES) $(ULTRA_C_FILES) $(GODDARD_C_FILES) $(LOCAL_PATH)/sound/sound_data.c +LOCAL_SRC_FILES := $(C_FILES) $(CXX_FILES) $(GENERATED_C_FILES) $(ULTRA_C_FILES) $(GODDARD_C_FILES) $(LOCAL_PATH)/sound/sound_data.c include $(BUILD_SHARED_LIBRARY) diff --git a/Makefile b/Makefile index 32bd066..0797256 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,9 @@ TARGET_WEB ?= 0 # Makeflag to enable OSX fixes OSX_BUILD ?= 0 +# Enable -no-pie linker option +NO_PIE ?= 1 + # Specify the target you are building for, TARGET_BITS=0 means native TARGET_ARCH ?= native TARGET_BITS ?= 0 @@ -59,11 +62,11 @@ NO_LDIV ?= 0 # Renderers: GL, GL_LEGACY, D3D11, D3D12 RENDER_API ?= GL -# Window managers: SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API) +# Window managers: SDL1, SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API) WINDOW_API ?= SDL2 -# Audio backends: SDL2 +# Audio backends: SDL1, SDL2 AUDIO_API ?= SDL2 -# Controller backends (can have multiple, space separated): SDL2 +# Controller backends (can have multiple, space separated): SDL2, SDL1 CONTROLLER_API ?= SDL2 # Misc settings for EXTERNAL_DATA @@ -465,7 +468,7 @@ else CXX := emcc endif -LD := $(CC) +LD := $(CXX) #We need some cpp support for DynOS here ifeq ($(DISCORDRPC),1) LD := $(CXX) @@ -501,7 +504,9 @@ SDLCONFIG := $(CROSS)sdl2-config BACKEND_CFLAGS := -DRAPI_$(RENDER_API)=1 -DWAPI_$(WINDOW_API)=1 -DAAPI_$(AUDIO_API)=1 # can have multiple controller APIs BACKEND_CFLAGS += $(foreach capi,$(CONTROLLER_API),-DCAPI_$(capi)=1) -BACKEND_LDFLAGS := +BACKEND_LDFLAG0S := + +SDL1_USED := 0 SDL2_USED := 0 # for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI @@ -512,7 +517,7 @@ ifeq ($(WINDOW_API),DXGI) endif BACKEND_LDFLAGS += -ld3dcompiler -ldxgi -ldxguid BACKEND_LDFLAGS += -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -static -else ifeq ($(WINDOW_API),SDL2) +else ifeq ($(findstring SDL,$(WINDOW_API)),SDL) ifeq ($(WINDOWS_BUILD),1) BACKEND_LDFLAGS += -lglew32 -lglu32 -lopengl32 else ifeq ($(TARGET_ANDROID),1) @@ -524,24 +529,35 @@ else ifeq ($(WINDOW_API),SDL2) else BACKEND_LDFLAGS += -lGL endif - SDL_USED := 2 endif -ifeq ($(AUDIO_API),SDL2) - SDL_USED := 2 +ifneq (,$(findstring SDL2,$(AUDIO_API)$(WINDOW_API)$(CONTROLLER_API))) + SDL2_USED := 1 endif -ifneq (,$(findstring SDL,$(CONTROLLER_API))) - SDL_USED := 2 +ifneq (,$(findstring SDL1,$(AUDIO_API)$(WINDOW_API)$(CONTROLLER_API))) + SDL1_USED := 1 +endif + +ifeq ($(SDL1_USED)$(SDL2_USED),11) + $(error Cannot link both SDL1 and SDL2 at the same time) endif # SDL can be used by different systems, so we consolidate all of that shit into this -ifeq ($(SDL_USED),2) + +ifeq ($(SDL2_USED),1) + SDLCONFIG := $(CROSS)sdl2-config + BACKEND_CFLAGS += -DHAVE_SDL2=1 +else ifeq ($(SDL1_USED),1) + SDLCONFIG := $(CROSS)sdl-config + BACKEND_CFLAGS += -DHAVE_SDL1=1 +endif + +ifneq ($(SDL1_USED)$(SDL2_USED),00) ifeq ($(TARGET_ANDROID),1) - BACKEND_CFLAGS += -DHAVE_SDL2=1 BACKEND_LDFLAGS += -lhidapi -lSDL2 else - BACKEND_CFLAGS += -DHAVE_SDL2=1 `$(SDLCONFIG) --cflags` + BACKEND_CFLAGS += `$(SDLCONFIG) --cflags` ifeq ($(WINDOWS_BUILD),1) BACKEND_LDFLAGS += `$(SDLCONFIG) --static-libs` -lsetupapi -luser32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion else @@ -637,7 +653,7 @@ endif ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) ifeq ($(TARGET_WEB),1) -LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" + LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=64MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" else ifeq ($(WINDOWS_BUILD),1) LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread $(BACKEND_LDFLAGS) -static @@ -668,9 +684,13 @@ else ifeq ($(OSX_BUILD),1) LDFLAGS := -lm $(BACKEND_LDFLAGS) -no-pie -lpthread else - LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread + LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -lpthread -ldl + ifeq ($(NO_PIE), 1) + LDFLAGS += -no-pie + endif + ifeq ($(DISCORDRPC),1) - LDFLAGS += -ldl -Wl,-rpath . + LDFLAGS += -Wl,-rpath . endif endif # End of LDFLAGS @@ -734,10 +754,22 @@ res: $(BASEPACK_PATH) $(BASEPACK_LST): $(EXE_DEPEND) @mkdir -p $(BUILD_DIR)/$(BASEDIR) @echo -n > $(BASEPACK_LST) - @echo "$(BUILD_DIR)/sound/bank_sets sound/bank_sets" >> $(BASEPACK_LST) - @echo "$(BUILD_DIR)/sound/sequences.bin sound/sequences.bin" >> $(BASEPACK_LST) - @echo "$(BUILD_DIR)/sound/sound_data.ctl sound/sound_data.ctl" >> $(BASEPACK_LST) - @echo "$(BUILD_DIR)/sound/sound_data.tbl sound/sound_data.tbl" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/bank_sets.be.64 sound/bank_sets.be.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/bank_sets.be.32 sound/bank_sets.be.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/bank_sets.le.64 sound/bank_sets.le.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/bank_sets.le.32 sound/bank_sets.le.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sequences.bin.be.64 sound/sequences.bin.be.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sequences.bin.be.32 sound/sequences.bin.be.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sequences.bin.le.64 sound/sequences.bin.le.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sequences.bin.le.32 sound/sequences.bin.le.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.ctl.be.64 sound/sound_data.ctl.be.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.ctl.be.32 sound/sound_data.ctl.be.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.ctl.le.64 sound/sound_data.ctl.le.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.ctl.le.32 sound/sound_data.ctl.le.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.tbl.be.64 sound/sound_data.tbl.be.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.tbl.be.32 sound/sound_data.tbl.be.32" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.tbl.le.64 sound/sound_data.tbl.le.64" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.tbl.le.32 sound/sound_data.tbl.le.32" >> $(BASEPACK_LST) @$(foreach f, $(wildcard $(SKYTILE_DIR)/*), echo $(f) gfx/$(f:$(BUILD_DIR)/%=%) >> $(BASEPACK_LST);) @find actors -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; @find levels -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; @@ -901,21 +933,66 @@ $(ENDIAN_BITWIDTH): tools/determine-endian-bitwidth.c @rm $@.dummy1 @rm $@.dummy2 -$(SOUND_BIN_DIR)/sound_data.ctl: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) $(ENDIAN_BITWIDTH) - $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/sound_data.tbl $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH)) +$(SOUND_BIN_DIR)/sound_data.ctl.be.64: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) + $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl.be.64 $(SOUND_BIN_DIR)/sound_data.tbl.be.64 $(VERSION_CFLAGS) --endian big --bitwidth 64 -$(SOUND_BIN_DIR)/sound_data.tbl: $(SOUND_BIN_DIR)/sound_data.ctl +$(SOUND_BIN_DIR)/sound_data.ctl.be.32: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) + $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl.be.32 $(SOUND_BIN_DIR)/sound_data.tbl.be.32 $(VERSION_CFLAGS) --endian big --bitwidth 32 + +$(SOUND_BIN_DIR)/sound_data.ctl.le.64: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) + $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl.le.64 $(SOUND_BIN_DIR)/sound_data.tbl.le.64 $(VERSION_CFLAGS) --endian little --bitwidth 64 + +$(SOUND_BIN_DIR)/sound_data.ctl.le.32: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) + $(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl.le.32 $(SOUND_BIN_DIR)/sound_data.tbl.le.32 $(VERSION_CFLAGS) --endian little --bitwidth 32 + +$(SOUND_BIN_DIR)/sound_data.tbl.be.64: $(SOUND_BIN_DIR)/sound_data.ctl.be.64 + @true + +$(SOUND_BIN_DIR)/sound_data.tbl.be.32: $(SOUND_BIN_DIR)/sound_data.ctl.be.32 + @true + +$(SOUND_BIN_DIR)/sound_data.tbl.le.64: $(SOUND_BIN_DIR)/sound_data.ctl.le.64 + @true + +$(SOUND_BIN_DIR)/sound_data.tbl.le.32: $(SOUND_BIN_DIR)/sound_data.ctl.le.32 @true ifeq ($(VERSION),sh) -$(SOUND_BIN_DIR)/sequences.bin: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) $(ENDIAN_BITWIDTH) - $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH)) +$(SOUND_BIN_DIR)/sequences.bin.be.64: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.be.64 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian big --bitwidth 64 + +$(SOUND_BIN_DIR)/sequences.bin.be.32: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.be.32 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian big --bitwidth 32 + +$(SOUND_BIN_DIR)/sequences.bin.le.64: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.le.64 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian little --bitwidth 64 + +$(SOUND_BIN_DIR)/sequences.bin.le.32: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/jp/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.le.32 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian little --bitwidth 32 else -$(SOUND_BIN_DIR)/sequences.bin: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) $(ENDIAN_BITWIDTH) - $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) $$(cat $(ENDIAN_BITWIDTH)) +$(SOUND_BIN_DIR)/sequences.bin.be.64: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.be.64 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian big --bitwidth 64 + +$(SOUND_BIN_DIR)/sequences.bin.be.32: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.be.32 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian big --bitwidth 32 + +$(SOUND_BIN_DIR)/sequences.bin.le.64: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.le.64 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian little --bitwidth 64 + +$(SOUND_BIN_DIR)/sequences.bin.le.32: $(SOUND_BANK_FILES) sound/sequences.json sound/sequences/ sound/sequences/$(VERSION)/ $(SOUND_SEQUENCE_FILES) + $(PYTHON) tools/assemble_sound.py --sequences $@ $(SOUND_BIN_DIR)/bank_sets.le.32 sound/sound_banks/ sound/sequences.json $(SOUND_SEQUENCE_FILES) $(VERSION_CFLAGS) --endian little --bitwidth 32 endif -$(SOUND_BIN_DIR)/bank_sets: $(SOUND_BIN_DIR)/sequences.bin +$(SOUND_BIN_DIR)/bank_sets.be.64: $(SOUND_BIN_DIR)/sequences.bin.be.64 + @true + +$(SOUND_BIN_DIR)/bank_sets.be.32: $(SOUND_BIN_DIR)/sequences.bin.be.32 + @true + +$(SOUND_BIN_DIR)/bank_sets.le.64: $(SOUND_BIN_DIR)/sequences.bin.le.64 + @true + +$(SOUND_BIN_DIR)/bank_sets.le.32: $(SOUND_BIN_DIR)/sequences.bin.le.32 @true $(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o @@ -937,7 +1014,11 @@ $(SOUND_BIN_DIR)/%.inc.c: $(SOUND_BIN_DIR)/% endif -$(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.inc.c $(SOUND_BIN_DIR)/sequences.bin.inc.c $(SOUND_BIN_DIR)/bank_sets.inc.c +$(SOUND_BIN_DIR)/sound_data.o: \ + $(SOUND_BIN_DIR)/sound_data.ctl.be.64.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.be.64.inc.c $(SOUND_BIN_DIR)/sequences.bin.be.64.inc.c $(SOUND_BIN_DIR)/bank_sets.be.64.inc.c \ + $(SOUND_BIN_DIR)/sound_data.ctl.be.32.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.be.32.inc.c $(SOUND_BIN_DIR)/sequences.bin.be.32.inc.c $(SOUND_BIN_DIR)/bank_sets.be.32.inc.c \ + $(SOUND_BIN_DIR)/sound_data.ctl.le.64.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.le.64.inc.c $(SOUND_BIN_DIR)/sequences.bin.le.64.inc.c $(SOUND_BIN_DIR)/bank_sets.le.64.inc.c \ + $(SOUND_BIN_DIR)/sound_data.ctl.le.32.inc.c $(SOUND_BIN_DIR)/sound_data.tbl.le.32.inc.c $(SOUND_BIN_DIR)/sequences.bin.le.32.inc.c $(SOUND_BIN_DIR)/bank_sets.le.32.inc.c $(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h @@ -1026,6 +1107,7 @@ APK_FILES := $(shell find android/ -type f) $(APK): $(EXE) $(APK_FILES) cp -r android $(BUILD_DIR) && \ + cp $(PREFIX)/lib/libc++_shared.so $(BUILD_DIR)/android/lib/$(ARCH_APK)/ && \ cp $(EXE) $(BUILD_DIR)/android/lib/$(ARCH_APK)/ && \ cd $(BUILD_DIR)/android && \ zip -r ../../../$@ ./* && \ diff --git a/enhancements/60fps_ex.patch b/enhancements/60fps_ex.patch index 54f16fa..f9103f4 100644 --- a/enhancements/60fps_ex.patch +++ b/enhancements/60fps_ex.patch @@ -112,7 +112,7 @@ index 802d97a..1b0d677 100644 /** A node that allows an object to specify a different culling radius than the diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c -index 5b6775f..2c11e25 100644 +index 1da535b..49a5c03 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -8,6 +8,7 @@ @@ -1890,19 +1890,10 @@ index 0467495..fa4eb33 100644 using namespace Microsoft::WRL; // For ComPtr diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c -index 5f4c690..de96bbd 100644 +index 42b8541..388e137 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c -@@ -61,7 +61,7 @@ static void (*touch_up_callback)(void* event); - // whether to use timer for frame control - static bool use_timer = true; - // time between consequtive game frames --static const int frame_time = 1000 / FRAMERATE; -+static const int frame_time = 1000 / (2 * FRAMERATE); - - const SDL_Scancode windows_scancode_table[] = { - /* 0 1 2 3 4 5 6 7 */ -@@ -153,11 +153,11 @@ int test_vsync(void) { +@@ -161,11 +161,11 @@ static int test_vsync(void) { * On SGI models, turning vsync off will help with framerate, but the best is 60fps patch. * The actual solution would be to render or copy the buffer to a texture * and then render that to the screen.*/ @@ -1916,11 +1907,11 @@ index 5f4c690..de96bbd 100644 #endif } -@@ -165,7 +165,11 @@ static inline void gfx_sdl_set_vsync(const bool enabled) { +@@ -173,7 +173,11 @@ static inline void gfx_sdl_set_vsync(const bool enabled) { if (enabled) { // try to detect refresh rate SDL_GL_SetSwapInterval(1); -- const int vblanks = test_vsync(); +- const int vblanks = gCLIOpts.SyncFrames ? (int)gCLIOpts.SyncFrames : test_vsync(); + int vblanks = test_vsync(); + if (vblanks & 1) + vblanks = 0; // not divisible by 60, fuck that @@ -1929,8 +1920,17 @@ index 5f4c690..de96bbd 100644 if (vblanks) { printf("determined swap interval: %d\n", vblanks); SDL_GL_SetSwapInterval(vblanks); +@@ -258,7 +262,7 @@ static void gfx_sdl_init(const char *window_title) { + gfx_sdl_set_fullscreen(); + + perf_freq = SDL_GetPerformanceFrequency(); +- frame_time = perf_freq / FRAMERATE; ++ frame_time = perf_freq / (2 * FRAMERATE); + + for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { + inverted_scancode_table[windows_scancode_table[i]] = i; diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c -index a3c9817..8c61830 100644 +index 5fda297..35d50db 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -84,6 +84,25 @@ void send_display_list(struct SPTask *spTask) { diff --git a/enhancements/DynOS.1.0.patch b/enhancements/DynOS.1.0.patch new file mode 100644 index 0000000..280eebf --- /dev/null +++ b/enhancements/DynOS.1.0.patch @@ -0,0 +1,7795 @@ +diff --git a/Makefile b/Makefile +index 22dabaf..10c1868 100644 +--- a/Makefile ++++ b/Makefile +@@ -451,6 +451,7 @@ ifeq ($(TARGET_ANDROID),1) + INCLUDE_CFLAGS += -I SDL/include + endif + ENDIAN_BITWIDTH := $(BUILD_DIR)/endian-and-bitwidth ++include dynos.mk + + # Huge deleted N64 section was here + +diff --git a/data/dynos.c.h b/data/dynos.c.h +new file mode 100644 +index 0000000..35a6241 +--- /dev/null ++++ b/data/dynos.c.h +@@ -0,0 +1,28 @@ ++#ifndef DYNOS_C_H ++#define DYNOS_C_H ++#ifndef __cplusplus ++ ++#include "dynos.h" ++ ++// The action signature is "bool (*) (const char *)" ++// The input is the button internal name (not label) ++// The output is the result of the action ++#define DYNOS_DEFINE_ACTION(func) \ ++DYNOS_AT_STARTUP static void dynos_opt_add_action_##func() { \ ++ dynos_opt_add_action(#func, func, false); \ ++} ++ ++s32 dynos_opt_get_value (const char *name); ++void dynos_opt_set_value (const char *name, s32 value); ++void dynos_opt_add_action (const char *funcname, bool (*funcptr)(const char *), bool overwrite); ++ ++void *dynos_update_cmd (void *cmd); ++void dynos_update_gfx (); ++void dynos_update_opt (void *pad); ++bool dynos_sanity_check_geo (s16 graphNodeType); ++bool dynos_sanity_check_seq (u8 loBits); ++s32 dynos_gfx_import_texture (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); ++void dynos_gfx_swap_animations (void *ptr); ++ ++#endif ++#endif +diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h +new file mode 100644 +index 0000000..b84c816 +--- /dev/null ++++ b/data/dynos.cpp.h +@@ -0,0 +1,714 @@ ++#ifndef DYNOS_CPP_H ++#define DYNOS_CPP_H ++#ifdef __cplusplus ++ ++#include "dynos.h" ++ ++#define FUNCTION_CODE (u32) 0x434E5546 ++#define POINTER_CODE (u32) 0x52544E50 ++ ++// ++// Enums ++// ++ ++enum { ++ DATA_TYPE_NONE = 0, ++ DATA_TYPE_LIGHT, ++ DATA_TYPE_TEXTURE, ++ DATA_TYPE_VERTEX, ++ DATA_TYPE_DISPLAY_LIST, ++ DATA_TYPE_GEO_LAYOUT, ++ DATA_TYPE_ANIMATION_VALUE, ++ DATA_TYPE_ANIMATION_INDEX, ++ DATA_TYPE_ANIMATION, ++ DATA_TYPE_ANIMATION_TABLE, ++ DATA_TYPE_GFXDYNCMD, ++ DATA_TYPE_UNUSED, ++}; ++ ++enum { ++ DOPT_NONE = 0, ++ ++ DOPT_TOGGLE, ++ DOPT_CHOICE, ++ DOPT_SCROLL, ++ DOPT_BIND, ++ DOPT_BUTTON, ++ DOPT_SUBMENU, ++ ++ // These ones are used by the Warp to Level built-in submenu ++ DOPT_CHOICELEVEL, ++ DOPT_CHOICEAREA, ++ DOPT_CHOICESTAR, ++#ifndef DYNOS_COOP ++ DOPT_CHOICEPARAM, ++#endif ++}; ++ ++#ifdef DYNOS_COOP ++enum { ++ DYNOS_COOP_COMMAND_NONE, ++ DYNOS_COOP_COMMAND_WARP_TO_LEVEL, ++ DYNOS_COOP_COMMAND_WARP_TO_CASTLE, ++ DYNOS_COOP_COMMAND_RESTART_LEVEL, ++ DYNOS_COOP_COMMAND_EXIT_LEVEL, ++}; ++#endif ++ ++// ++// DynOS Array ++// A vector-like array, implemented to be processed really fast, but cannot handle C++ complex classes like std::string ++// ++ ++template ++class Array { ++public: ++ inline Array() : mBuffer(NULL), mCount(0), mCapacity(0) { ++ } ++ ++ inline Array(const std::initializer_list &aList) : mBuffer(NULL), mCount(0), mCapacity(0) { ++ Resize(aList.size()); ++ memcpy(mBuffer, aList.begin(), mCount * sizeof(T)); ++ } ++ ++ inline Array(const T *aBegin, const T *aEnd) : mBuffer(NULL), mCount(0), mCapacity(0) { ++ Resize(aEnd - aBegin); ++ memcpy(mBuffer, aBegin, mCount * sizeof(T)); ++ } ++ ++ inline Array(const Array &aOther) : mBuffer(NULL), mCount(0), mCapacity(0) { ++ Resize(aOther.mCount); ++ memcpy(mBuffer, aOther.mBuffer, mCount * sizeof(T)); ++ } ++ ++ inline void operator=(const Array &aOther) { ++ Resize(aOther.mCount); ++ memcpy(mBuffer, aOther.mBuffer, mCount * sizeof(T)); ++ } ++ ++ inline ~Array() { ++ Clear(); ++ } ++ ++public: ++ void Resize(s32 aCount) { ++ if (aCount > mCapacity) { ++ mCapacity = MAX(aCount, MAX(16, mCapacity * 2)); ++ T *_Buffer = (T *) calloc(mCapacity, sizeof(T)); ++ if (mBuffer) { ++ memcpy(_Buffer, mBuffer, mCount * sizeof(T)); ++ free(mBuffer); ++ } ++ mBuffer = _Buffer; ++ } ++ mCount = aCount; ++ } ++ ++ void Add(const T& aItem) { ++ Resize(mCount + 1); ++ mBuffer[mCount - 1] = aItem; ++ } ++ ++ void Remove(s32 aIndex) { ++ memmove(mBuffer + aIndex, mBuffer + aIndex + 1, (mCount - aIndex - 1) * sizeof(T)); ++ mCount--; ++ } ++ ++ void Pop() { ++ mCount--; ++ } ++ ++ void RemoveAll() { ++ mCount = 0; ++ } ++ ++ void Clear() { ++ if (mBuffer) free(mBuffer); ++ mBuffer = NULL; ++ mCount = 0; ++ mCapacity = 0; ++ } ++ ++ s32 Find(const T& aItem) const { ++ for (s32 i = 0; i != mCount; ++i) { ++ if (mBuffer[i] == aItem) { ++ return i; ++ } ++ } ++ return -1; ++ } ++ ++ template ++ s32 FindIf(Predicate aPredicate) const { ++ for (s32 i = 0; i != mCount; ++i) { ++ if (aPredicate(mBuffer[i])) { ++ return i; ++ } ++ } ++ return -1; ++ } ++ ++public: ++ inline const T *begin() const { return mBuffer; } ++ inline const T *end() const { return mBuffer + mCount; } ++ inline T *begin() { return mBuffer; } ++ inline T *end() { return mBuffer + mCount; } ++ ++ inline const T &operator[](s32 aIndex) const { return mBuffer[aIndex]; } ++ inline T &operator[](s32 aIndex) { return mBuffer[aIndex]; } ++ ++ inline s32 Count() const { return mCount; } ++ inline bool Empty() const { return mCount == 0; } ++ ++public: ++ void Read(FILE *aFile) { ++ s32 _Length = 0; fread(&_Length, sizeof(s32), 1, aFile); ++ Resize(_Length); ++ fread(mBuffer, sizeof(T), _Length, aFile); ++ } ++ ++ void Write(FILE *aFile) const { ++ fwrite(&mCount, sizeof(s32), 1, aFile); ++ fwrite(mBuffer, sizeof(T), mCount, aFile); ++ } ++ ++private: ++ T *mBuffer; ++ s32 mCount; ++ s32 mCapacity; ++}; ++ ++// ++// DynOS String ++// A fixed-size string that doesn't require heap memory allocation ++// ++ ++#define STRING_SIZE 95 ++class String { ++public: ++ inline String() : mCount(0) { ++ mBuffer[0] = 0; ++ } ++ ++ inline String(const char *aString) : mCount(0) { ++ if (aString) { ++ u64 _Length = strlen(aString); ++ mCount = MIN(_Length, STRING_SIZE - 1); ++ memcpy(mBuffer, aString, _Length); ++ } ++ mBuffer[mCount] = 0; ++ } ++ ++ template ++ inline String(const char *aFmt, Args... aArgs) : mCount(0) { ++ snprintf(mBuffer, STRING_SIZE, aFmt, aArgs...); ++ mCount = (u8) strlen(mBuffer); ++ mBuffer[mCount] = 0; ++ } ++ ++ inline String(const String &aOther) : mCount(0) { ++ mCount = aOther.mCount; ++ memcpy(mBuffer, aOther.mBuffer, mCount); ++ mBuffer[mCount] = 0; ++ } ++ ++ inline void operator=(const String &aOther) { ++ mCount = aOther.mCount; ++ memcpy(mBuffer, aOther.mBuffer, mCount); ++ mBuffer[mCount] = 0; ++ } ++ ++public: ++ void Add(char aChar) { ++ if (mCount == STRING_SIZE - 1) return; ++ mBuffer[mCount++] = aChar; ++ mBuffer[mCount] = 0; ++ } ++ ++ void Remove(s32 aIndex) { ++ memmove(mBuffer + aIndex, mBuffer + aIndex + 1, (mCount-- - aIndex - 1)); ++ mBuffer[mCount] = 0; ++ } ++ ++ void RemoveAll() { ++ mCount = 0; ++ mBuffer[0] = 0; ++ } ++ ++ void Clear() { ++ mCount = 0; ++ mBuffer[0] = 0; ++ } ++ ++ s32 Find(char aChar, s32 aStart = 0) const { ++ for (u8 i = (u8) aStart; i < mCount; ++i) { ++ if (mBuffer[i] == aChar) { ++ return (s32) i; ++ } ++ } ++ return -1; ++ } ++ ++ s32 Find(const char *aString, s32 aStart = 0) const { ++ const char *_Ptr = strstr(mBuffer + aStart, aString); ++ if (_Ptr) return (s32) (_Ptr - mBuffer); ++ return -1; ++ } ++ ++ s32 FindLast(char aChar) const { ++ for (u8 i = mCount; i != 0; --i) { ++ if (mBuffer[i - 1] == aChar) { ++ return (s32) (i - 1); ++ } ++ } ++ return -1; ++ } ++ ++ String SubString(s32 aStart, s32 aCount = STRING_SIZE - 1) const { ++ if (aStart >= mCount) return String(); ++ if (aCount < 0) aCount = STRING_SIZE - 1; ++ aCount = MIN(aCount, mCount - aStart); ++ String _String; ++ _String.mCount = aCount; ++ memcpy(_String.mBuffer, mBuffer + aStart, aCount); ++ _String.mBuffer[aCount] = 0; ++ return _String; ++ } ++ ++public: ++ inline const char *begin() const { return mBuffer; } ++ inline const char *end() const { return mBuffer + mCount; } ++ inline char *begin() { return mBuffer; } ++ inline char *end() { return mBuffer + mCount; } ++ ++ inline const char &operator[](s32 aIndex) const { return mBuffer[aIndex]; } ++ inline char &operator[](s32 aIndex) { return mBuffer[aIndex]; } ++ ++ inline s32 Length() const { return (s32) mCount; } ++ inline bool Empty() const { return mCount == 0; } ++ ++public: ++ bool operator==(const char *aString) const { ++ if (strlen(aString) != mCount) return false; ++ for (u8 i = 0; i != mCount; ++i) { ++ if (aString[i] != mBuffer[i]) { ++ return false; ++ } ++ } ++ return true; ++ } ++ ++ bool operator==(const String &aOther) const { ++ if (aOther.mCount != mCount) return false; ++ for (u8 i = 0; i != mCount; ++i) { ++ if (aOther.mBuffer[i] != mBuffer[i]) { ++ return false; ++ } ++ } ++ return true; ++ } ++ ++ bool operator!=(const char *aString) const { ++ if (strlen(aString) != mCount) return true; ++ for (u8 i = 0; i != mCount; ++i) { ++ if (aString[i] != mBuffer[i]) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ bool operator!=(const String &aOther) const { ++ if (aOther.mCount != mCount) return true; ++ for (u8 i = 0; i != mCount; ++i) { ++ if (aOther.mBuffer[i] != mBuffer[i]) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++public: ++ void Read(FILE *aFile) { ++ fread(&mCount, sizeof(u8), 1, aFile); ++ fread(mBuffer, sizeof(char), mCount, aFile); ++ mBuffer[mCount] = 0; ++ } ++ ++ void Write(FILE *aFile) const { ++ fwrite(&mCount, sizeof(u8), 1, aFile); ++ fwrite(mBuffer, sizeof(char), mCount, aFile); ++ } ++ ++ s32 ParseInt() const { ++ s32 i = 0; ++ if (mBuffer[1] == 'x') { ++ sscanf(mBuffer + 2, "%x", &i); ++ } else { ++ sscanf(mBuffer, "%d", &i); ++ } ++ return i; ++ } ++ ++ f32 ParseFloat() const { ++ f32 f = 0.f; ++ sscanf(mBuffer, "%f", &f); ++ return f; ++ } ++ ++private: ++ char mBuffer[STRING_SIZE]; ++ u8 mCount; ++}; ++static_assert(sizeof(String) == (STRING_SIZE + 1), "sizeof(String) must be (STRING_SIZE + 1)"); ++ ++// ++// Types ++// ++ ++template ++using Pair = std::pair; ++ ++typedef std::string SysPath; ++ ++class NoCopy { ++ protected: ++ NoCopy() {} ++ ~NoCopy() {} ++ private: ++ NoCopy(const NoCopy &) = delete; ++ void operator=(const NoCopy &) = delete; ++}; ++ ++struct TexData : NoCopy { ++ Array mPngData; ++ Array mRawData; ++ s32 mRawWidth = -1; ++ s32 mRawHeight = -1; ++ s32 mRawFormat = -1; ++ s32 mRawSize = -1; ++ bool mUploaded = false; ++}; ++ ++struct AnimData : NoCopy { ++ s16 mFlags = 0; ++ s16 mUnk02 = 0; ++ s16 mUnk04 = 0; ++ s16 mUnk06 = 0; ++ s16 mUnk08 = 0; ++ Pair mUnk0A; ++ Pair> mValues; ++ Pair> mIndex; ++ u32 mLength = 0; ++}; ++ ++template ++struct DataNode : NoCopy { ++ String mName; ++ T* mData = NULL; ++ u32 mSize = 0; ++ Array mTokens; ++ u64 mModelIdentifier = 0; ++ u64 mLoadIndex = 0; ++}; ++template ++using DataNodes = Array*>; ++ ++struct GfxContext { ++ DataNode* mCurrentTexture = NULL; ++ DataNode* mCurrentPalette = NULL; ++}; ++ ++template ++using AnimBuffer = Pair>; ++struct GfxData : NoCopy { ++ ++ // Model data ++ DataNodes mLights; ++ DataNodes mTextures; ++ DataNodes mVertices; ++ DataNodes mDisplayLists; ++ DataNodes mGeoLayouts; ++ ++ // Animation data ++ Array *> mAnimValues; ++ Array *> mAnimIndices; ++ DataNodes mAnimations; ++ Array> mAnimationTable; ++ ++ // Current ++ u64 mLoadIndex = 0; ++ s32 mErrorCount = 0; ++ u32 mModelIdentifier = 0; ++ SysPath mPackFolder; ++ Array mPointerList; ++ GfxContext mGfxContext; ++ Array mGeoNodeStack; ++}; ++ ++struct ActorGfx { ++ GfxData *mGfxData = NULL; ++ GraphNode *mGraphNode = NULL; ++ s32 mPackIndex = 0; ++}; ++ ++struct PackData { ++ SysPath mPath; ++}; ++ ++typedef Pair Label; ++struct DynosOption : NoCopy { ++ String mName; ++ String mConfigName; // Name used in the config file ++ Label mLabel; ++ Label mTitle; // Full caps label, displayed with colored font ++ DynosOption *mPrev; ++ DynosOption *mNext; ++ DynosOption *mParent; ++ bool mDynos; // true from create, false from convert ++ u8 mType; ++ ++ // TOGGLE ++ struct Toggle : NoCopy { ++ bool *mTog; ++ } mToggle; ++ ++ // CHOICE ++ struct Choice : NoCopy { ++ Array