diff --git a/Makefile b/Makefile index eec314e23..e824b3d6b 100644 --- a/Makefile +++ b/Makefile @@ -455,13 +455,24 @@ endif OBJDUMP := objdump OBJCOPY := objcopy PYTHON := python3 +HOST_ELF_CC := clang --target=x86_64-unknown-linux-gnu -ifeq ($(TARGET_MACOS),1) +ifeq ($(TARGET_WINDOWS),1) AS := i686-w64-mingw32-as OBJDUMP := i686-w64-mingw32-objdump OBJCOPY := i686-w64-mingw32-objcopy endif +ifeq ($(TARGET_MACOS),1) + BINUTILS_PREFIX := $(shell brew --prefix binutils 2>/dev/null) + ifneq ($(wildcard $(BINUTILS_PREFIX)/bin/objdump),) + OBJDUMP := $(BINUTILS_PREFIX)/bin/objdump + endif + ifneq ($(wildcard $(BINUTILS_PREFIX)/bin/objcopy),) + OBJCOPY := $(BINUTILS_PREFIX)/bin/objcopy + endif +endif + # Platform-specific compiler and linker flags, including SDL stuff SDLCONFIG_CFLAGS := $(shell sdl2-config --cflags) @@ -685,9 +696,11 @@ $(BUILD_DIR)/src/game/hud.o: $(BUILD_DIR)/include/text_strings.h ifeq ($(CUSTOM_TEXTURES),1) $(BUILD_DIR)/%: %.png + @mkdir -p $(@D) printf "%s%b" "$(patsubst %.png,%,$^)" '\0' > $@ $(BUILD_DIR)/%.inc.c: $(BUILD_DIR)/% %.png + @mkdir -p $(@D) hexdump -v -e '1/1 "0x%X,"' $< > $@ echo "0x00" >> $@ echo >> $@ @@ -702,20 +715,24 @@ TEXTURE_ENCODING := u8 # Convert PNGs to RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4 binary files $(BUILD_DIR)/%: %.png $(call print,Converting:,$<,$@) + @mkdir -p $(@D) $(V)$(N64GRAPHICS) -s raw -i $@ -g $< -f $(lastword $(subst ., ,$@)) $(BUILD_DIR)/%.inc.c: %.png $(call print,Converting:,$<,$@) + @mkdir -p $(@D) $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$(basename $<))) # Color Index CI8 $(BUILD_DIR)/%.ci8: %.ci8.png $(call print,Converting:,$<,$@) + @mkdir -p $(@D) $(V)$(N64GRAPHICS_CI) -i $@ -g $< -f ci8 # Color Index CI4 $(BUILD_DIR)/%.ci4: %.ci4.png $(call print,Converting:,$<,$@) + @mkdir -p $(@D) $(V)$(N64GRAPHICS_CI) -i $@ -g $< -f ci4 endif @@ -729,29 +746,35 @@ ifeq ($(TARGET_N64),1) # TODO: ideally this would be `-Trodata-segment=0x07000000` but that doesn't set the address $(BUILD_DIR)/%.elf: $(BUILD_DIR)/%.o $(call print,Linking ELF file:,$<,$@) + @mkdir -p $(@D) $(V)$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map -o $@ $< # Override for leveldata.elf, which otherwise matches the above pattern .SECONDEXPANSION: $(BUILD_DIR)/levels/%/leveldata.elf: $(BUILD_DIR)/levels/%/leveldata.o $(BUILD_DIR)/bin/$$(TEXTURE_BIN).elf $(call print,Linking ELF file:,$<,$@) + @mkdir -p $(@D) $(V)$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map --just-symbols=$(BUILD_DIR)/bin/$(TEXTURE_BIN).elf -o $@ $< $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf $(call print,Extracting compressible data from:,$<,$@) + @mkdir -p $(@D) $(V)$(EXTRACT_DATA_FOR_MIO) $< $@ $(BUILD_DIR)/levels/%/leveldata.bin: $(BUILD_DIR)/levels/%/leveldata.elf $(call print,Extracting compressible data from:,$<,$@) + @mkdir -p $(@D) $(V)$(EXTRACT_DATA_FOR_MIO) $< $@ # Compress binary file $(BUILD_DIR)/%.mio0: $(BUILD_DIR)/%.bin $(call print,Compressing:,$<,$@) + @mkdir -p $(@D) $(V)$(MIO0TOOL) $< $@ # convert binary mio0 to object file $(BUILD_DIR)/%.mio0.o: $(BUILD_DIR)/%.mio0 $(call print,Converting MIO0 to ELF:,$<,$@) + @mkdir -p $(@D) $(V)$(LD) -r -b binary $< -o $@ endif @@ -761,10 +784,12 @@ endif $(BUILD_DIR)/%.table: %.aiff $(call print,Extracting codebook:,$<,$@) + @mkdir -p $(@D) $(V)$(AIFF_EXTRACT_CODEBOOK) $< >$@ $(BUILD_DIR)/%.aifc: $(BUILD_DIR)/%.table %.aiff $(call print,Encoding ADPCM:,$(word 2,$^),$@) + @mkdir -p $(@D) $(V)$(VADPCM_ENC) -c $^ $@ $(ENDIAN_BITWIDTH): $(TOOLS_DIR)/determine-endian-bitwidth.c @@ -777,6 +802,7 @@ $(ENDIAN_BITWIDTH): $(TOOLS_DIR)/determine-endian-bitwidth.c $(SOUND_BIN_DIR)/sound_data.ctl: sound/sound_banks/ $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS) $(ENDIAN_BITWIDTH) @$(PRINT) "$(GREEN)Generating: $(BLUE)$@ $(NO_COL)\n" + @mkdir -p $(@D) $(V)$(PYTHON) $(TOOLS_DIR)/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/ctl_header $(SOUND_BIN_DIR)/sound_data.tbl $(SOUND_BIN_DIR)/tbl_header $(C_DEFINES) $$(cat $(ENDIAN_BITWIDTH)) $(SOUND_BIN_DIR)/sound_data.tbl: $(SOUND_BIN_DIR)/sound_data.ctl @@ -810,31 +836,38 @@ $(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o # Convert binary file to a comma-separated list of byte values for inclusion in C code $(BUILD_DIR)/%.inc.c: $(BUILD_DIR)/% $(call print,Converting to C:,$<,$@) + @mkdir -p $(@D) $(V)hexdump -v -e '1/1 "0x%X,"' $< > $@ $(V)echo >> $@ # Generate animation data $(BUILD_DIR)/assets/mario_anim_data.c: $(wildcard assets/anims/*.inc.c) @$(PRINT) "$(GREEN)Generating animation data $(NO_COL)\n" + @mkdir -p $(@D) $(V)$(PYTHON) $(TOOLS_DIR)/mario_anims_converter.py > $@ # Generate demo input data $(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/*.bin) @$(PRINT) "$(GREEN)Generating demo data $(NO_COL)\n" + @mkdir -p $(@D) $(V)$(PYTHON) $(TOOLS_DIR)/demo_data_converter.py assets/demo_data.json $(DEF_INC_CFLAGS) > $@ # Encode in-game text strings $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in $(call print,Encoding:,$<,$@) + @mkdir -p $(@D) $(V)$(TEXTCONV) charmap.txt $< $@ $(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in $(call print,Encoding:,$<,$@) + @mkdir -p $(@D) $(V)$(TEXTCONV) charmap_menu.txt $< $@ $(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h @$(PRINT) "$(GREEN)Preprocessing: $(BLUE)$@ $(NO_COL)\n" + @mkdir -p $(@D) $(V)$(CPP) $(CPPFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h @$(PRINT) "$(GREEN)Preprocessing: $(BLUE)$@ $(NO_COL)\n" + @mkdir -p $(@D) $(V)$(CPP) $(CPPFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ # Level headers @@ -861,14 +894,17 @@ $(GLOBAL_ASM_DEP).$(NON_MATCHING): # Compile C/C++ code $(BUILD_DIR)/%.o: %.cpp $(call print,Compiling:,$<,$@) + @mkdir -p $(@D) @$(CXX) -fsyntax-only $(CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< $(V)$(CXX) -c $(CFLAGS) -o $@ $< $(BUILD_DIR)/%.o: %.c $(call print,Compiling:,$<,$@) + @mkdir -p $(@D) @$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< $(V)$(CC) -c $(CFLAGS) -o $@ $< $(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c $(call print,Compiling:,$<,$@) + @mkdir -p $(@D) @$(CC_CHECK) $(CC_CHECK_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< $(V)$(CC) -c $(CFLAGS) -o $@ $< @@ -928,9 +964,27 @@ $(BUILD_DIR)/src/audio/seqplayer.copt: COPTFLAGS := -inline_manual endif # Assemble assembly code +ifeq ($(TARGET_N64),1) +$(BUILD_DIR)/%.o: %.s + $(call print,Assembling:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(dir $(BUILD_DIR)/$*.d) + $(V)$(CPP) $(CPPFLAGS) $< | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ +else +ifeq ($(TARGET_MACOS),1) +$(BUILD_DIR)/%.o: %.s + $(call print,Assembling:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(dir $(BUILD_DIR)/$*.d) + $(V)$(HOST_ELF_CC) -c -x assembler-with-cpp $(DEF_INC_CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d -o $@ $< +else $(BUILD_DIR)/%.o: %.s $(call print,Assembling:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(dir $(BUILD_DIR)/$*.d) $(V)$(CPP) $(CPPFLAGS) $< | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ +endif +endif # Assemble RSP assembly code $(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin: rsp/%.s diff --git a/Makefile.split b/Makefile.split index 23e2e340e..d4fba53cd 100644 --- a/Makefile.split +++ b/Makefile.split @@ -146,7 +146,7 @@ $(BUILD_DIR)/levels/%/leveldata.elf: SEGMENT_ADDRESS := 0x07000000 # TODO: Generate these rules from the level configs? -define level_rules = +define level_rules $(1)_SEG7_FILES := $$(patsubst %.png,%.inc.c,$$(wildcard levels/$(1)/*.png)) $$(BUILD_DIR)/levels/$(1)/leveldata.o: $$(addprefix $$(BUILD_DIR)/,$$($(1)_SEG7_FILES)) $$(BUILD_DIR)/levels/$(1)/leveldata.elf: TEXTURE_BIN := $(2) @@ -174,9 +174,13 @@ $(eval $(call level_rules,menu,generic)) # Menu (File Select) # Ending cake textures are generated in a special way $(BUILD_DIR)/levels/ending/cake_eu.inc.c: levels/ending/cake_eu.png $(call print,Splitting:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(BUILD_DIR)/textures/skybox_tiles $(V)$(SKYCONV) $(SKYCONV_ARGS) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending $(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png $(call print,Splitting:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(BUILD_DIR)/textures/skybox_tiles $(V)$(SKYCONV) $(SKYCONV_ARGS) --type cake --split $^ $(BUILD_DIR)/levels/ending # -------------------------------------- @@ -245,6 +249,8 @@ $(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 $(BUILD_DIR)/bin/%_skybox.c: textures/skyboxes/%.png $(call print,Splitting:,$<,$@) + @mkdir -p $(@D) + @mkdir -p $(BUILD_DIR)/textures/skybox_tiles $(V)$(SKYCONV) $(SKYCONV_ARGS) --type sky --split $^ $(BUILD_DIR)/bin $(BUILD_DIR)/bin/%_skybox.elf: SEGMENT_ADDRESS := 0x0A000000 diff --git a/include/config.h b/include/config.h index 837df4e9e..df54053d2 100644 --- a/include/config.h +++ b/include/config.h @@ -1,6 +1,10 @@ #ifndef CONFIG_H #define CONFIG_H +#if defined(TARGET_MACOS) || defined(TARGET_LINUX) +#include +#endif + /** * @file config.h * A catch-all file for configuring various bugfixes and other settings diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index eb0a19230..6095649aa 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -18,13 +18,14 @@ #define GL_GLEXT_PROTOTYPES 1 #include "SDL_opengl.h" #else +#define GL_GLEXT_PROTOTYPES 1 #ifndef TARGET_MACOS #include #else +#include #include #include #endif -#define GL_GLEXT_PROTOTYPES 1 #ifndef TARGET_MACOS #include #endif @@ -104,6 +105,8 @@ static GLint blur_position_location = -1; static GLint blur_texcoord_location = -1; static GLint blur_screen_width_location = -1; +static void destroy_internal_framebuffer(void); + static int get_display_index(void) { int display_index = (int) configDefaultMonitor - 1; int num_displays = SDL_GetNumVideoDisplays(); @@ -363,7 +366,7 @@ static void blit_internal_framebuffer(GLuint texture) { glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &array_buffer_binding); uint32_t window_width, window_height; - get_display_dimensions(&window_width, &window_height); + gfx_get_dimensions(&window_width, &window_height); glBindFramebuffer(GL_FRAMEBUFFER, 0); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 886755383..d7c40d2b8 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -8,6 +8,9 @@ #if defined(TARGET_MACOS) || defined(TARGET_LINUX) #include #endif +#ifdef TARGET_MACOS +#include +#endif #ifdef TARGET_LINUX #include #endif diff --git a/src/pc/gfx/gfx_pc.h b/src/pc/gfx/gfx_pc.h index 03cfc59ce..0adba5f8a 100644 --- a/src/pc/gfx/gfx_pc.h +++ b/src/pc/gfx/gfx_pc.h @@ -19,6 +19,7 @@ extern "C" { void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, const char *game_name, bool start_in_fullscreen); struct GfxRenderingAPI *gfx_get_current_rendering_api(void); +void gfx_get_dimensions(uint32_t *width, uint32_t *height); void gfx_start_frame(void); void gfx_run(Gfx *commands); void gfx_end_frame(void); diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 19f0af866..9513e0e42 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -23,16 +23,16 @@ #define GL_GLEXT_PROTOTYPES 1 #include "SDL_opengl.h" #else +#define GL_GLEXT_PROTOTYPES 1 #ifndef TARGET_MACOS #include #include #else -#include #include #include +#include #include #endif -#define GL_GLEXT_PROTOTYPES 1 #ifndef TARGET_MACOS #include #endif @@ -182,6 +182,9 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { window_height = DESIRED_SCREEN_HEIGHT; SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); +#ifdef TARGET_MACOS + SDL_SetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, "1"); +#endif SDL_Init(SDL_INIT_VIDEO); @@ -191,7 +194,7 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { wnd = SDL_CreateWindow(game_name, SDL_WINDOWPOS_UNDEFINED_DISPLAY(configDefaultMonitor-1), SDL_WINDOWPOS_UNDEFINED_DISPLAY(configDefaultMonitor-1), - window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE); #if defined(_WIN32) || defined(_WIN64) // Set window icon from embedded resources @@ -355,9 +358,21 @@ static void gfx_sdl_handle_events(void) { break; #endif case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED && (SDL_GetWindowFlags(SDL_GetWindowFromID(event.window.windowID)) & SDL_WINDOW_FULLSCREEN) == 0) { - window_width = event.window.data1; - window_height = event.window.data2; + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + Uint32 window_flags = SDL_GetWindowFlags(SDL_GetWindowFromID(event.window.windowID)); + bool is_fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0; + + if (fullscreen_state != is_fullscreen) { + fullscreen_state = is_fullscreen; + if (on_fullscreen_changed_callback != NULL) { + on_fullscreen_changed_callback(is_fullscreen); + } + } + + if (!is_fullscreen) { + window_width = event.window.data1; + window_height = event.window.data2; + } } break;