From d873abfadf73c92a9476eab4ad8391fdd2fdffa8 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Thu, 27 Jun 2024 02:27:07 +0200 Subject: [PATCH] Switch to embedding cartridge templates and boot ROM as GResources Also set up gdk-pixbuf in the Makefile, which will be used for image ops --- Makefile | 34 ++++++++++++++----------- XdgThumbnailer/emulate.c | 16 +++++++++--- XdgThumbnailer/main.c | 1 - XdgThumbnailer/main.h | 6 ++--- XdgThumbnailer/resources.gresource.xml | 9 +++++++ XdgThumbnailer/thumbnail.c | 35 ++++++++++++++++++++++++-- 6 files changed, 78 insertions(+), 23 deletions(-) create mode 100644 XdgThumbnailer/resources.gresource.xml diff --git a/Makefile b/Makefile index dc6645c..9f75427 100644 --- a/Makefile +++ b/Makefile @@ -225,6 +225,12 @@ GIO_CFLAGS += -DG_ENABLE_DEBUG else GIO_CFLAGS += -DG_DISABLE_ASSERT endif + +GDK_PIXBUF_CFLAGS := $(shell $(PKG_CONFIG) --cflags gdk-pixbuf-2.0) +GDK_PIXBUF_LDFLAGS := $(shell $(PKG_CONFIG) --libs gdk-pixbuf-2.0) + +LIBPNG_CFLAGS := $(shell $(PKG_CONFIG) --cflags libpng) +LIBPNG_LDFLAGS := $(shell $(PKG_CONFIG) --libs libpng) endif ifeq (,$(PKG_CONFIG)) @@ -338,7 +344,7 @@ endif cocoa: $(BIN)/SameBoy.app quicklook: $(BIN)/SameBoy.qlgenerator -xdg-thumbnailer: $(BIN)/XdgThumbnailer/sameboy-thumbnailer $(BIN)/XdgThumbnailer/cgb_boot_fast.bin $(patsubst QuickLook/%.png,$(BIN)/XdgThumbnailer/%.png,$(wildcard QuickLook/*.png)) +xdg-thumbnailer: $(BIN)/XdgThumbnailer/sameboy-thumbnailer sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/mgb_boot.bin $(BIN)/SDL/cgb0_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders $(BIN)/SDL/Palettes bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/cgb0_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/mgb_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin @@ -377,7 +383,7 @@ IOS_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(IOS_SOURCES)) QUICKLOOK_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(QUICKLOOK_SOURCES)) SDL_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(SDL_SOURCES)) TESTER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(TESTER_SOURCES)) -XDG_THUMBNAILER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(XDG_THUMBNAILER_SOURCES)) $(OBJ)/XdgThumbnailer/interface.c.o +XDG_THUMBNAILER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(XDG_THUMBNAILER_SOURCES)) $(OBJ)/XdgThumbnailer/interface.c.o $(OBJ)/XdgThumbnailer/resources.c.o lib: $(PUBLIC_HEADERS) @@ -423,18 +429,26 @@ $(OBJ)/SDL/%.c.o: SDL/%.c $(OBJ)/XdgThumbnailer/%.c.o: XdgThumbnailer/%.c -@$(MKDIR) -p $(dir $@) - $(CC) $(CFLAGS) $(GIO_CFLAGS) -DG_LOG_DOMAIN='"sameboy-thumbnailer"' -c $< -o $@ + $(CC) $(CFLAGS) $(GIO_CFLAGS) $(GDK_PIXBUF_CFLAGS) $(LIBPNG_CFLAGS) -DG_LOG_DOMAIN='"sameboy-thumbnailer"' -c $< -o $@ # Make sure not to attempt compiling this before generating the interface code. $(OBJ)/XdgThumbnailer/main.c.o: $(OBJ)/XdgThumbnailer/interface.h +# Make sure not to attempt compiling this before generating the resource code. +$(OBJ)/XdgThumbnailer/emulate.c.o: $(OBJ)/XdgThumbnailer/resources.h # Silence warnings for this. It is code generated not by us, so we do not want `-Werror` to break # compilation with some version of the generator and/or compiler. -$(OBJ)/XdgThumbnailer/interface.c.o: $(OBJ)/XdgThumbnailer/interface.c +$(OBJ)/XdgThumbnailer/%.c.o: $(OBJ)/XdgThumbnailer/%.c -@$(MKDIR) -p $(dir $@) - $(CC) $(CFLAGS) $(GIO_CFLAGS) -DG_LOG_DOMAIN='"sameboy-thumbnailer"' -w -c $< -o $@ + $(CC) $(CFLAGS) $(GIO_CFLAGS) $(GDK_PIXBUF_CFLAGS) $(LIBPNG_CFLAGS) -DG_LOG_DOMAIN='"sameboy-thumbnailer"' -w -c $< -o $@ + $(OBJ)/XdgThumbnailer/interface.c $(OBJ)/XdgThumbnailer/interface.h: XdgThumbnailer/interface.xml -@$(MKDIR) -p $(dir $@) gdbus-codegen --c-generate-autocleanup none --c-namespace Thumbnailer --interface-prefix org.freedesktop.thumbnails. --generate-c-code $(OBJ)/XdgThumbnailer/interface $< +$(OBJ)/XdgThumbnailer/resources.c $(OBJ)/XdgThumbnailer/resources.h: %: XdgThumbnailer/resources.gresource.xml $(BIN)/BootROMs/cgb_boot_fast.bin + -@$(MKDIR) -p $(dir $@) + CC=$(CC) glib-compile-resources --dependency-file $@.mk --generate-phony-targets --generate --target $@ $< +-include $(OBJ)/XdgThumbnailer/resources.c.mk $(OBJ)/XdgThumbnailer/resources.h.mk + $(OBJ)/OpenDialog/%.c.o: OpenDialog/%.c -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@ @@ -560,7 +574,7 @@ $(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs $(BIN)/XdgThumbnailer/sameboy-thumbnailer: $(CORE_OBJECTS) $(XDG_THUMBNAILER_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(FAT_FLAGS) $(GIO_LDFLAGS) + $(CC) $^ -o $@ $(LDFLAGS) $(GIO_LDFLAGS) $(GDK_PIXBUF_LDFLAGS) $(LIBPNG_LDFLAGS) # SDL Port @@ -627,14 +641,6 @@ $(BIN)/SameBoy-iOS.app/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $< $@ -$(BIN)/XdgThumbnailer/%.png: QuickLook/%.png - -@$(MKDIR) -p $(dir $@) - cp -f $< $@ - -$(BIN)/XdgThumbnailer/%.bin: $(BOOTROMS_DIR)/%.bin - -@$(MKDIR) -p $(dir $@) - cp -f $< $@ - $(BIN)/SDL/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $< $@ diff --git a/XdgThumbnailer/emulate.c b/XdgThumbnailer/emulate.c index 0c8c848..bd403e1 100644 --- a/XdgThumbnailer/emulate.c +++ b/XdgThumbnailer/emulate.c @@ -1,11 +1,13 @@ #include "emulate.h" #include +#include #include #include "Core/gb.h" -#include "Core/memory.h" -#include "glibconfig.h" + +// Auto-generated via `glib-compile-resources` from `resources.gresource.xml`. +#include "build/obj/XdgThumbnailer/resources.h" #define NB_FRAMES_TO_EMULATE (60 * 10) @@ -67,7 +69,15 @@ unsigned emulate(enum FileKind kind, unsigned char const *rom, size_t rom_size, GB_gameboy_t gb; GB_init(&gb, GB_MODEL_CGB_E); - GB_load_boot_rom_from_buffer(&gb, (unsigned char const *)boot_rom, sizeof(boot_rom)); + GError *error = NULL; + GBytes *boot_rom = g_resource_lookup_data(resources_get_resource(), "/thumbnailer/cgb_boot_fast.bin", G_RESOURCE_LOOKUP_FLAGS_NONE, &error); + g_assert_no_error(error); + size_t boot_rom_size; + unsigned char const *boot_rom_data = g_bytes_get_data(boot_rom, &boot_rom_size); + g_assert_cmpuint(boot_rom_size, ==, BOOT_ROM_SIZE); + GB_load_boot_rom_from_buffer(&gb, boot_rom_data, boot_rom_size); + g_bytes_unref(boot_rom); + if (kind == KIND_ISX) { g_assert_not_reached(); // TODO: implement GB_load_isx_from_buffer } diff --git a/XdgThumbnailer/main.c b/XdgThumbnailer/main.c index 663b603..ff38402 100644 --- a/XdgThumbnailer/main.c +++ b/XdgThumbnailer/main.c @@ -111,7 +111,6 @@ int main(int argc, char const *argv[]) // unsigned active_worker_threads = 0; // Create the task queue *before* starting to accept tasks from D-Bus. init_tasks(); - load_boot_rom(); // Likewise, create the main loop before then, so it can be aborted even before entering it. main_loop = g_main_loop_new(NULL, FALSE); diff --git a/XdgThumbnailer/main.h b/XdgThumbnailer/main.h index 76438e1..76a32c0 100644 --- a/XdgThumbnailer/main.h +++ b/XdgThumbnailer/main.h @@ -3,9 +3,9 @@ // As defined in the thumbnailer spec. enum ErrorCode { ERROR_UNKNOWN_SCHEME_OR_MIME, - ERROR_SPECIALIZED_THUMBNAILER_CONNECTION_FAILED, - ERROR_INVALID_DATA, - ERROR_THUMBNAIILING_THUMBNAIL, + ERROR_SPECIALIZED_THUMBNAILER_CONNECTION_FAILED, // Not applicable. + ERROR_INVALID_DATA, // Any file can be decoded as a GB ROM, apparently! + ERROR_THUMBNAIILING_THUMBNAIL, // We defer checking this to the generic thumbnailer. ERROR_COULD_NOT_WRITE, ERROR_UNSUPPORTED_FLAVOR, }; diff --git a/XdgThumbnailer/resources.gresource.xml b/XdgThumbnailer/resources.gresource.xml new file mode 100644 index 0000000..f30ec17 --- /dev/null +++ b/XdgThumbnailer/resources.gresource.xml @@ -0,0 +1,9 @@ + + + + QuickLook/CartridgeTemplate.png + QuickLook/ColorCartridgeTemplate.png + QuickLook/UniversalCartridgeTemplate.png + build/bin/BootROMs/cgb_boot_fast.bin + + diff --git a/XdgThumbnailer/thumbnail.c b/XdgThumbnailer/thumbnail.c index f95a890..e1ce61f 100644 --- a/XdgThumbnailer/thumbnail.c +++ b/XdgThumbnailer/thumbnail.c @@ -11,6 +11,20 @@ #define THUMBNAILING_ERROR_DOMAIN (g_quark_from_static_string("thumbnailing")) +/* --- */ + +enum CartridgeType { + CART_DMG_ONLY, + CART_DUAL, + CART_CGB_ONLY, +}; + +void load_cartridge_images(void) { + // TODO +} + +/* --- */ + struct TaskData { char *contents; size_t length; @@ -25,6 +39,8 @@ static void destroy_task_data(void *data) g_slice_free(struct TaskData, task_data); } +/* --- */ + static void generate_thumbnail(GTask *task, void *source_object, void *data, GCancellable *cancellable) { @@ -33,8 +49,21 @@ static void generate_thumbnail(GTask *task, void *source_object, void *data, uint32_t screen[160 * 144]; unsigned cgb_flag = emulate(task_data->kind, (unsigned char const *)task_data->contents, task_data->length, screen); - // TODO: generate the thumbnail from `screen` and `cgb_flag`. - (void)cgb_flag; + + // Generate the thumbnail from `screen` and `cgb_flag`. + enum CartridgeType type; + switch (cgb_flag) { + case 0xC0: + type = CART_CGB_ONLY; + break; + case 0x80: + type = CART_DUAL; + break; + default: + type = CART_DMG_ONLY; + break; + } + (void)type; g_task_return_boolean(task, TRUE); g_object_unref(task); @@ -69,6 +98,8 @@ static void on_file_ready(GObject *source_object, GAsyncResult *res, void *user_ g_task_run_in_thread(task, generate_thumbnail); } +/* --- */ + static void on_thumbnailing_end(GObject *source_object, GAsyncResult *res, void *user_data) { // TODO: start a new thread if some task is pending.