[GTK3] Handle config.boot_rom_path

This commit is contained in:
Maximilian Mader 2019-09-26 20:31:58 +02:00
parent ef682ec0c5
commit 2d8aced75c
Signed by: Max
GPG Key ID: F71D56A3151C4FB3

View File

@ -15,7 +15,7 @@
typedef struct UserData { typedef struct UserData {
bool fullscreen; bool fullscreen;
GFile *file; GFile *file;
gchar *bootrom_path; gchar *boot_rom_path;
gchar *config_path; gchar *config_path;
GB_model_t model; GB_model_t model;
} UserData; } UserData;
@ -25,7 +25,7 @@ typedef struct{
uint16_t w, h; uint16_t w, h;
} Rect; } Rect;
static void run(UserData *user_data); static void run(GApplication *app, UserData *user_data);
static GtkApplication *main_application; static GtkApplication *main_application;
static GtkBuilder *builder; static GtkBuilder *builder;
@ -209,7 +209,8 @@ static GMenuModel *get_menu_model(GApplication *app, const char *id) {
} }
static void quit(GApplication *app) { static void quit(GApplication *app) {
g_application_quit(app); // Tell our own main loop to quit.
// This will allow our run() and therefore our activate() methods to end.
running = false; running = false;
} }
@ -414,7 +415,6 @@ G_MODULE_EXPORT void on_boot_rom_location_changed(GtkWidget *w, gpointer user_da
g_print("New value: %s\n", gtk_combo_box_get_active_id(box)); g_print("New value: %s\n", gtk_combo_box_get_active_id(box));
} }
// This functions gets called immediately after registration of the GApplication // This functions gets called immediately after registration of the GApplication
static void startup(GApplication *app, gpointer user_data_gptr) { static void startup(GApplication *app, gpointer user_data_gptr) {
UserData *user_data = user_data_gptr; UserData *user_data = user_data_gptr;
@ -533,7 +533,7 @@ static void activate(GApplication *app, gpointer user_data_gptr) {
// Start the emulation loop. // Start the emulation loop.
// This loop takes care of the GTK main loop. // This loop takes care of the GTK main loop.
run(user_data); run(app, user_data);
} }
// This function gets called when there are files to open. // This function gets called when there are files to open.
@ -552,6 +552,7 @@ static void open(GApplication *app, GFile **files, gint n_files, const gchar *hi
activate(app, user_data_gptr); activate(app, user_data_gptr);
} }
// This function gets called when the application is closed.
static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar *hint, gpointer user_data_gptr) { static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar *hint, gpointer user_data_gptr) {
g_print("SHUTDOWN\n"); g_print("SHUTDOWN\n");
@ -671,7 +672,7 @@ static void update_window_geometry() {
image_buffers[2] = malloc(buffer_size); image_buffers[2] = malloc(buffer_size);
} }
static void run(UserData *user_data) { static void run(GApplication *app, UserData *user_data) {
GB_model_t prev_model = GB_get_model(&gb); GB_model_t prev_model = GB_get_model(&gb);
GB_model_t model = user_data->model? user_data->model : GB_MODEL_CGB_E; // TODO: Model from config GB_model_t model = user_data->model? user_data->model : GB_MODEL_CGB_E; // TODO: Model from config
@ -704,54 +705,67 @@ static void run(UserData *user_data) {
GError *error; GError *error;
char *boot_rom_path; char *boot_rom_path;
char *boot_rom_name;
GBytes *boot_rom_f; GBytes *boot_rom_f;
const guchar *boot_rom_data; const guchar *boot_rom_data;
gsize boot_rom_size; gsize boot_rom_size;
if (user_data->bootrom_path) { if (user_data->boot_rom_path) {
g_print("Trying to load boot ROM from %s\n", user_data->bootrom_path); g_print("Trying to load boot ROM from %s\n", user_data->boot_rom_path);
if (GB_load_boot_rom(&gb, user_data->bootrom_path)) { if (GB_load_boot_rom(&gb, user_data->boot_rom_path)) {
g_printerr("Falling back to internal boot ROM\n"); g_printerr("Falling back to boot ROM from config\n");
goto internal_bootrom; goto config_boot_rom;
} }
} }
else { internal_bootrom: else { config_boot_rom:
switch (model) { switch (model) {
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
boot_rom_path = RESOURCE_PREFIX "bootroms/dmg_boot.bin"; boot_rom_name = "dmg_boot.bin";
break; break;
case GB_MODEL_SGB: case GB_MODEL_SGB:
case GB_MODEL_SGB_PAL: case GB_MODEL_SGB_PAL:
case GB_MODEL_SGB_NO_SFC: case GB_MODEL_SGB_NO_SFC:
boot_rom_path = RESOURCE_PREFIX "bootroms/sgb_boot.bin"; boot_rom_name = "sgb_boot.bin";
break; break;
case GB_MODEL_SGB2: case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_SGB2_NO_SFC:
boot_rom_path = RESOURCE_PREFIX "bootroms/sgb2_boot.bin"; boot_rom_name = "sgb2_boot.bin";
break; break;
case GB_MODEL_CGB_C: case GB_MODEL_CGB_C:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E:
boot_rom_path = RESOURCE_PREFIX "bootroms/cgb_boot.bin"; boot_rom_name = "cgb_boot.bin";
break; break;
case GB_MODEL_AGB: case GB_MODEL_AGB:
boot_rom_path = RESOURCE_PREFIX "bootroms/agb_boot.bin"; boot_rom_name = "agb_boot.bin";
break; break;
} }
boot_rom_f = g_resources_lookup_data(boot_rom_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error); if (config.boot_rom_path != NULL) {
boot_rom_path = g_build_filename(config.boot_rom_path, boot_rom_name, NULL);
if (boot_rom_f == NULL) { g_print("Trying to load boot ROM from %s\n", boot_rom_path);
g_printerr("Failed to load internal boot ROM: %s\n", boot_rom_path);
g_error_free(error); if (GB_load_boot_rom(&gb, boot_rom_path)) {
exit(EXIT_FAILURE); g_printerr("Falling back to internal boot ROM\n");
goto internal_boot_rom;
}
} }
else { internal_boot_rom:
boot_rom_path = g_build_filename(RESOURCE_PREFIX "bootroms/", boot_rom_name, NULL);
boot_rom_f = g_resources_lookup_data(boot_rom_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
boot_rom_data = g_bytes_get_data(boot_rom_f, &boot_rom_size); if (boot_rom_f == NULL) {
GB_load_boot_rom_from_buffer(&gb, boot_rom_data, boot_rom_size); g_printerr("Failed to load internal boot ROM: %s\n", boot_rom_path);
g_error_free(error);
exit(EXIT_FAILURE);
}
boot_rom_data = g_bytes_get_data(boot_rom_f, &boot_rom_size);
GB_load_boot_rom_from_buffer(&gb, boot_rom_data, boot_rom_size);
}
} }
if (user_data->file != NULL) { if (user_data->file != NULL) {
@ -779,6 +793,10 @@ static void run(UserData *user_data) {
GB_run(&gb); GB_run(&gb);
} }
} }
// Quit our application properly.
// This fires the “shutdown” signal.
g_application_quit(app);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -791,7 +809,7 @@ int main(int argc, char *argv[]) {
GOptionEntry entries[] = { GOptionEntry entries[] = {
{ "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Show the application version", NULL }, { "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Show the application version", NULL },
{ "fullscreen", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Start in fullscreen mode", NULL }, { "fullscreen", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Start in fullscreen mode", NULL },
{ "bootrom", 'b', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &user_data.bootrom_path, "Path to the boot ROM to use", "<file path>" }, { "bootrom", 'b', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &user_data.boot_rom_path, "Path to the boot ROM to use", "<file path>" },
{ "model", 'm', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, NULL, "Override the model type to emulate", "<model type>" }, { "model", 'm', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, NULL, "Override the model type to emulate", "<model type>" },
{ "config", 'c', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &user_data.config_path, "Override the path of the configuration file", "<file path>" }, { "config", 'c', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &user_data.config_path, "Override the path of the configuration file", "<file path>" },
{ NULL } { NULL }