From 28d7e2f209d49f1df97706b809885a67c8c6ce4b Mon Sep 17 00:00:00 2001 From: Brian Waters Date: Wed, 29 Mar 2023 02:37:13 -0400 Subject: [PATCH 1/5] Enable loading zipped rom files --- Core/gb.c | 66 ++++++++++++++++++++++++++++++++++++++------ Core/gb.h | 2 ++ Makefile | 19 ++++++++++--- OpenDialog/gtk.c | 1 + OpenDialog/windows.c | 2 +- 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index abf42c581..d83f647aa 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -9,6 +9,11 @@ #include #include #endif + +#ifdef HAVE_MINIZIP +#include +#endif + #include "random.h" #include "gb.h" @@ -320,7 +325,30 @@ static size_t rounded_rom_size(size_t size) return size; } +static void init_new_rom(GB_gameboy_t *gb) +{ + GB_configure_cart(gb); + gb->tried_loading_sgb_border = false; + gb->has_sgb_border = false; + load_default_border(gb); +} + int GB_load_rom(GB_gameboy_t *gb, const char *path) +{ +#ifdef HAVE_MINIZIP + size_t path_len = strlen(path); + const char *ext; + if (path_len > 4) { + ext = path + path_len - 4; + if (strcasecmp(ext, ".zip") == 0) { + return GB_load_rom_from_zip(gb, path); + } + } +#endif + return GB_load_rom_from_bin(gb, path); +} + +int GB_load_rom_from_bin(GB_gameboy_t *gb, const char *path) { GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) @@ -339,13 +367,38 @@ int GB_load_rom(GB_gameboy_t *gb, const char *path) memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */ fread(gb->rom, 1, gb->rom_size, f); fclose(f); - GB_configure_cart(gb); - gb->tried_loading_sgb_border = false; - gb->has_sgb_border = false; - load_default_border(gb); + init_new_rom(gb); return 0; } +#ifdef HAVE_MINIZIP +int GB_load_rom_from_zip(GB_gameboy_t *gb, const char *path) +{ + GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) + + unzFile *z = unzOpen(path); + unz_file_info file_info; + if (!z) { + GB_log(gb, "Could not open ZIP.\n"); + return -1; + } + unzGoToFirstFile(z); + unzGetCurrentFileInfo(z, &file_info, NULL, 0, NULL, 0, NULL, 0); + gb->rom_size = rounded_rom_size(file_info.uncompressed_size); + unzOpenCurrentFile(z); + if (gb->rom) { + free(gb->rom); + } + gb->rom = malloc(gb->rom_size); + memset(gb->rom, 0xFF, gb->rom_size); + unzReadCurrentFile(z, gb->rom, gb->rom_size); + unzCloseCurrentFile(z); + unzClose(z); + init_new_rom(gb); + return 0; +} +#endif + #define GBS_ENTRY 0x61 #define GBS_ENTRY_SIZE 13 @@ -741,10 +794,7 @@ void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t siz gb->rom = malloc(gb->rom_size); memset(gb->rom, 0xFF, gb->rom_size); memcpy(gb->rom, buffer, size); - GB_configure_cart(gb); - gb->tried_loading_sgb_border = false; - gb->has_sgb_border = false; - load_default_border(gb); + init_new_rom(gb); } typedef struct { diff --git a/Core/gb.h b/Core/gb.h index e072bbf5b..992b44191 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -901,6 +901,8 @@ void GB_set_user_data(GB_gameboy_t *gb, void *data); int GB_load_boot_rom(GB_gameboy_t *gb, const char *path); void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer, size_t size); int GB_load_rom(GB_gameboy_t *gb, const char *path); +int GB_load_rom_from_bin(GB_gameboy_t *gb, const char *path); +int GB_load_rom_from_zip(GB_gameboy_t *gb, const char *path); void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size); int GB_load_isx(GB_gameboy_t *gb, const char *path); int GB_load_gbs_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size, GB_gbs_info_t *info); diff --git a/Makefile b/Makefile index f43e1a5f2..6dde42f52 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,8 @@ DATA_DIR ?= $(PREFIX)/share/sameboy/ FREEDESKTOP ?= true endif +ENABLE_MINIZIP ?= 1 + default: $(DEFAULT) ifeq ($(MAKECMDGOALS),) @@ -168,6 +170,15 @@ GL_CFLAGS := $(shell $(PKG_CONFIG) --cflags gl) GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL) endif +ifneq ($(ENABLE_MINIZIP),0) +MINIZIP_CPPFLAGS := -DHAVE_MINIZIP +ifeq (,$(PKG_CONFIG)) +MINIZIP_LDFLAGS := -lminizip +else +MINIZIP_LDFLAGS := $(shell $(PKG_CONFIG) --libs minizip) +endif +endif + ifeq ($(PLATFORM),windows32) CFLAGS += -IWindows -Drandom=rand --target=i386-pc-windows LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lshell32 -lole32 -lSDL2main -Wl,/MANIFESTFILE:NUL --target=i386-pc-windows @@ -308,7 +319,7 @@ $(OBJ)/%.dep: % $(OBJ)/Core/%.c.o: Core/%.c -@$(MKDIR) -p $(dir $@) - $(CC) $(CFLAGS) $(FAT_FLAGS) -DGB_INTERNAL -c $< -o $@ + $(CC) $(CFLAGS) $(FAT_FLAGS) $(MINIZIP_CPPFLAGS) -DGB_INTERNAL -c $< -o $@ $(OBJ)/SDL/%.c.o: SDL/%.c -@$(MKDIR) -p $(dir $@) @@ -436,7 +447,7 @@ $(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs # Unix versions build only one binary $(BIN)/SDL/sameboy: $(CORE_OBJECTS) $(SDL_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) + $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) $(MINIZIP_LDFLAGS) ifeq ($(CONF), release) $(STRIP) $@ $(CODESIGN) $@ @@ -445,11 +456,11 @@ endif # Windows version builds two, one with a conole and one without it $(BIN)/SDL/sameboy.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:windows + $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) $(MINIZIP_LDFLAGS) -Wl,/subsystem:windows $(BIN)/SDL/sameboy_debugger.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:console + $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) $(MINIZIP_LDFLAGS) -Wl,/subsystem:console ifneq ($(USE_WINDRES),) $(OBJ)/%.o: %.rc diff --git a/OpenDialog/gtk.c b/OpenDialog/gtk.c index 2b08f1df8..cd3b4f2d9 100644 --- a/OpenDialog/gtk.c +++ b/OpenDialog/gtk.c @@ -109,6 +109,7 @@ char *do_open_rom_dialog(void) gtk_file_filter_add_pattern(filter, "*.gbc"); gtk_file_filter_add_pattern(filter, "*.sgb"); gtk_file_filter_add_pattern(filter, "*.isx"); + gtk_file_filter_add_pattern(filter, "*.zip"); gtk_file_filter_set_name(filter, "Game Boy ROMs"); gtk_file_chooser_add_filter(dialog, filter); diff --git a/OpenDialog/windows.c b/OpenDialog/windows.c index 5a0af0e32..425680d67 100644 --- a/OpenDialog/windows.c +++ b/OpenDialog/windows.c @@ -26,7 +26,7 @@ char *do_open_rom_dialog(void) dialog.lStructSize = sizeof(dialog); dialog.lpstrFile = filename; dialog.nMaxFile = MAX_PATH; - dialog.lpstrFilter = L"Game Boy ROMs\0*.gb;*.gbc;*.sgb;*.isx\0All files\0*.*\0\0"; + dialog.lpstrFilter = L"Game Boy ROMs\0*.gb;*.gbc;*.sgb;*.isx;*.zip\0All files\0*.*\0\0"; dialog.nFilterIndex = 1; dialog.lpstrFileTitle = NULL; dialog.nMaxFileTitle = 0; From cc55f5b745ae557e5ee80eb8207a2d993987aaa2 Mon Sep 17 00:00:00 2001 From: Brian Waters Date: Thu, 30 Mar 2023 18:54:21 -0400 Subject: [PATCH 2/5] Read the correct number of bytes from the ROM file --- Core/gb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index d83f647aa..b39a391ef 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -353,19 +353,21 @@ int GB_load_rom_from_bin(GB_gameboy_t *gb, const char *path) GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) FILE *f = fopen(path, "rb"); + size_t bin_size; if (!f) { GB_log(gb, "Could not open ROM: %s.\n", strerror(errno)); return errno; } fseek(f, 0, SEEK_END); - gb->rom_size = rounded_rom_size(ftell(f)); + bin_size = ftell(f); + gb->rom_size = rounded_rom_size(bin_size); fseek(f, 0, SEEK_SET); if (gb->rom) { free(gb->rom); } gb->rom = malloc(gb->rom_size); memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */ - fread(gb->rom, 1, gb->rom_size, f); + fread(gb->rom, 1, bin_size, f); fclose(f); init_new_rom(gb); return 0; @@ -391,7 +393,7 @@ int GB_load_rom_from_zip(GB_gameboy_t *gb, const char *path) } gb->rom = malloc(gb->rom_size); memset(gb->rom, 0xFF, gb->rom_size); - unzReadCurrentFile(z, gb->rom, gb->rom_size); + unzReadCurrentFile(z, gb->rom, file_info.uncompressed_size); unzCloseCurrentFile(z); unzClose(z); init_new_rom(gb); From 8d2013fc8647c011e5eab17dac00bb8d30ca28ae Mon Sep 17 00:00:00 2001 From: Brian Waters Date: Sat, 8 Apr 2023 03:20:49 -0400 Subject: [PATCH 3/5] Rename HAVE_MINIZIP to GB_HAS_MINIZIP --- Core/gb.c | 6 +++--- Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index b39a391ef..bc0a048d4 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -10,7 +10,7 @@ #include #endif -#ifdef HAVE_MINIZIP +#ifdef GB_HAS_MINIZIP #include #endif @@ -335,7 +335,7 @@ static void init_new_rom(GB_gameboy_t *gb) int GB_load_rom(GB_gameboy_t *gb, const char *path) { -#ifdef HAVE_MINIZIP +#ifdef GB_HAS_MINIZIP size_t path_len = strlen(path); const char *ext; if (path_len > 4) { @@ -373,7 +373,7 @@ int GB_load_rom_from_bin(GB_gameboy_t *gb, const char *path) return 0; } -#ifdef HAVE_MINIZIP +#ifdef GB_HAS_MINIZIP int GB_load_rom_from_zip(GB_gameboy_t *gb, const char *path) { GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb) diff --git a/Makefile b/Makefile index 6dde42f52..5129c15b0 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL) endif ifneq ($(ENABLE_MINIZIP),0) -MINIZIP_CPPFLAGS := -DHAVE_MINIZIP +MINIZIP_CPPFLAGS := -DGB_HAS_MINIZIP ifeq (,$(PKG_CONFIG)) MINIZIP_LDFLAGS := -lminizip else From 8a8c8a82021544098794f43bfc864eba9a0b1e78 Mon Sep 17 00:00:00 2001 From: Brian Waters Date: Sat, 8 Apr 2023 03:36:44 -0400 Subject: [PATCH 4/5] Link iOS, Cocoa, tester against minizip --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 5129c15b0..8f22bc8bc 100644 --- a/Makefile +++ b/Makefile @@ -367,7 +367,7 @@ $(BIN)/SameBoy-iOS.app: $(BIN)/SameBoy-iOS.app/SameBoy \ $(BIN)/SameBoy-iOS.app/SameBoy: $(CORE_OBJECTS) $(IOS_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) + $(CC) $^ -o $@ $(LDFLAGS) $(MINIZIP_LDFLAGS) ifeq ($(CONF), release) $(STRIP) $@ endif @@ -406,7 +406,7 @@ endif $(BIN)/SameBoy.app/Contents/MacOS/SameBoy: $(CORE_OBJECTS) $(COCOA_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) -framework OpenGL -framework AudioToolbox -framework AudioUnit -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework IOKit -framework PreferencePanes -framework Carbon -framework QuartzCore -framework Security -framework WebKit -weak_framework Metal -weak_framework MetalKit + $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) $(MINIZIP_LDFLAGS) -framework OpenGL -framework AudioToolbox -framework AudioUnit -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework IOKit -framework PreferencePanes -framework Carbon -framework QuartzCore -framework Security -framework WebKit -weak_framework Metal -weak_framework MetalKit ifeq ($(CONF), release) $(STRIP) $@ endif @@ -431,7 +431,7 @@ endif # once in the QL Generator. It should probably become a dylib instead. $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL: $(CORE_OBJECTS) $(QUICKLOOK_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) -Wl,-exported_symbols_list,QuickLook/exports.sym -bundle -framework Cocoa -framework Quicklook + $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) $(MINIZIP_LDFLAGS) -Wl,-exported_symbols_list,QuickLook/exports.sym -bundle -framework Cocoa -framework Quicklook ifeq ($(CONF), release) $(STRIP) $@ endif @@ -484,7 +484,7 @@ $(BIN)/SDL/SDL2.dll: $(BIN)/tester/sameboy_tester: $(CORE_OBJECTS) $(TESTER_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) + $(CC) $^ -o $@ $(LDFLAGS) $(MINIZIP_LDFLAGS) ifeq ($(CONF), release) $(STRIP) $@ $(CODESIGN) $@ @@ -492,7 +492,7 @@ endif $(BIN)/tester/sameboy_tester.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) -Wl,/subsystem:console + $(CC) $^ -o $@ $(LDFLAGS) $(MINIZIP_LDFLAGS) -Wl,/subsystem:console $(BIN)/SDL/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) From 444480cb14be963d3d564c2c56f0a60baf053b03 Mon Sep 17 00:00:00 2001 From: Brian Waters Date: Sat, 8 Apr 2023 05:42:54 -0400 Subject: [PATCH 5/5] Link against zlib when pkg-config is missing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8f22bc8bc..29f914584 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,7 @@ endif ifneq ($(ENABLE_MINIZIP),0) MINIZIP_CPPFLAGS := -DGB_HAS_MINIZIP ifeq (,$(PKG_CONFIG)) -MINIZIP_LDFLAGS := -lminizip +MINIZIP_LDFLAGS := -lminizip -lz else MINIZIP_LDFLAGS := $(shell $(PKG_CONFIG) --libs minizip) endif