Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable loading zipped rom files #535

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 62 additions & 10 deletions Core/gb.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include <sys/select.h>
#include <unistd.h>
#endif

#ifdef GB_HAS_MINIZIP
#include <minizip/unzip.h>
#endif

#include "random.h"
#include "gb.h"

Expand Down Expand Up @@ -320,32 +325,82 @@ 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 GB_HAS_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)

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);
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 GB_HAS_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, file_info.uncompressed_size);
unzCloseCurrentFile(z);
unzClose(z);
init_new_rom(gb);
return 0;
}
#endif

#define GBS_ENTRY 0x61
#define GBS_ENTRY_SIZE 13

Expand Down Expand Up @@ -741,10 +796,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 {
Expand Down
2 changes: 2 additions & 0 deletions Core/gb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 20 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ DATA_DIR ?= $(PREFIX)/share/sameboy/
FREEDESKTOP ?= true
endif

ENABLE_MINIZIP ?= 1

default: $(DEFAULT)

ifeq ($(MAKECMDGOALS),)
Expand Down Expand Up @@ -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 := -DGB_HAS_MINIZIP
ifeq (,$(PKG_CONFIG))
MINIZIP_LDFLAGS := -lminizip -lz
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
Expand Down Expand Up @@ -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 $@)
Expand Down Expand Up @@ -356,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
Expand Down Expand Up @@ -395,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
Expand All @@ -420,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
Expand All @@ -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) $@
Expand All @@ -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
Expand All @@ -473,15 +484,15 @@ $(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) $@
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 $@)
Expand Down
1 change: 1 addition & 0 deletions OpenDialog/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion OpenDialog/windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down