Let the SDL port choose a boot ROMs folder
This commit is contained in:
parent
e1f797c212
commit
7fc59b5cf4
2
Makefile
2
Makefile
@ -130,7 +130,7 @@ GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL)
|
|||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),windows32)
|
ifeq ($(PLATFORM),windows32)
|
||||||
CFLAGS += -IWindows -Drandom=rand --target=i386-pc-windows
|
CFLAGS += -IWindows -Drandom=rand --target=i386-pc-windows
|
||||||
LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lshell32 -lSDL2main -Wl,/MANIFESTFILE:NUL --target=i386-pc-windows
|
LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lshell32 -lole32 -lSDL2main -Wl,/MANIFESTFILE:NUL --target=i386-pc-windows
|
||||||
SDL_LDFLAGS := -lSDL2
|
SDL_LDFLAGS := -lSDL2
|
||||||
GL_LDFLAGS := -lopengl32
|
GL_LDFLAGS := -lopengl32
|
||||||
else
|
else
|
||||||
|
@ -18,3 +18,21 @@ char *do_open_rom_dialog(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *do_open_folder_dialog(void)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
NSWindow *key = [NSApp keyWindow];
|
||||||
|
NSOpenPanel *dialog = [NSOpenPanel openPanel];
|
||||||
|
dialog.title = @"Select Boot ROMs Folder";
|
||||||
|
dialog.canChooseDirectories = true;
|
||||||
|
dialog.canChooseFiles = false;
|
||||||
|
[dialog runModal];
|
||||||
|
[key makeKeyAndOrderFront:nil];
|
||||||
|
NSString *ret = [[[dialog URLs] firstObject] path];
|
||||||
|
if (ret) {
|
||||||
|
return strdup(ret.UTF8String);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define GTK_FILE_CHOOSER_ACTION_OPEN 0
|
#define GTK_FILE_CHOOSER_ACTION_OPEN 0
|
||||||
|
#define GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER 2
|
||||||
#define GTK_RESPONSE_ACCEPT -3
|
#define GTK_RESPONSE_ACCEPT -3
|
||||||
#define GTK_RESPONSE_CANCEL -6
|
#define GTK_RESPONSE_CANCEL -6
|
||||||
|
|
||||||
@ -111,3 +112,71 @@ lazy_error:
|
|||||||
fprintf(stderr, "Failed to display GTK dialog\n");
|
fprintf(stderr, "Failed to display GTK dialog\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *do_open_folder_dialog(void)
|
||||||
|
{
|
||||||
|
static void *handle = NULL;
|
||||||
|
|
||||||
|
TRY_DLOPEN("libgtk-3.so");
|
||||||
|
TRY_DLOPEN("libgtk-3.so.0");
|
||||||
|
TRY_DLOPEN("libgtk-2.so");
|
||||||
|
TRY_DLOPEN("libgtk-2.so.0");
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
goto lazy_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LAZY(gtk_init_check);
|
||||||
|
LAZY(gtk_file_chooser_dialog_new);
|
||||||
|
LAZY(gtk_dialog_run);
|
||||||
|
LAZY(g_free);
|
||||||
|
LAZY(gtk_widget_destroy);
|
||||||
|
LAZY(gtk_file_chooser_get_filename);
|
||||||
|
LAZY(g_log_set_default_handler);
|
||||||
|
LAZY(gtk_file_filter_new);
|
||||||
|
LAZY(gtk_file_filter_add_pattern);
|
||||||
|
LAZY(gtk_file_filter_set_name);
|
||||||
|
LAZY(gtk_file_chooser_add_filter);
|
||||||
|
LAZY(gtk_events_pending);
|
||||||
|
LAZY(gtk_main_iteration);
|
||||||
|
|
||||||
|
/* Shut up GTK */
|
||||||
|
g_log_set_default_handler(nop, NULL);
|
||||||
|
|
||||||
|
gtk_init_check(0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
void *dialog = gtk_file_chooser_dialog_new("Select Boot ROMs Folder",
|
||||||
|
0,
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||||
|
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||||
|
"_Open", GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
|
||||||
|
int res = gtk_dialog_run (dialog);
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
if (res == GTK_RESPONSE_ACCEPT) {
|
||||||
|
char *filename;
|
||||||
|
filename = gtk_file_chooser_get_filename(dialog);
|
||||||
|
ret = strdup(filename);
|
||||||
|
g_free(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (gtk_events_pending()) {
|
||||||
|
gtk_main_iteration();
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
|
||||||
|
while (gtk_events_pending()) {
|
||||||
|
gtk_main_iteration();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
lazy_error:
|
||||||
|
fprintf(stderr, "Failed to display GTK dialog\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
#define open_rom_h
|
#define open_rom_h
|
||||||
|
|
||||||
char *do_open_rom_dialog(void);
|
char *do_open_rom_dialog(void);
|
||||||
|
char *do_open_folder_dialog(void);
|
||||||
#endif /* open_rom_h */
|
#endif /* open_rom_h */
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
#include "open_dialog.h"
|
#include "open_dialog.h"
|
||||||
|
|
||||||
char *do_open_rom_dialog(void)
|
char *do_open_rom_dialog(void)
|
||||||
{
|
{
|
||||||
OPENFILENAMEW dialog;
|
OPENFILENAMEW dialog;
|
||||||
wchar_t filename[MAX_PATH] = {0};
|
static wchar_t filename[MAX_PATH] = {0};
|
||||||
|
|
||||||
memset(&dialog, 0, sizeof(dialog));
|
memset(&dialog, 0, sizeof(dialog));
|
||||||
dialog.lStructSize = sizeof(dialog);
|
dialog.lStructSize = sizeof(dialog);
|
||||||
@ -25,3 +26,32 @@ char *do_open_rom_dialog(void)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *do_open_folder_dialog(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
BROWSEINFOW dialog;
|
||||||
|
memset(&dialog, 0, sizeof(dialog));
|
||||||
|
|
||||||
|
dialog.ulFlags = BIF_USENEWUI;
|
||||||
|
dialog.lpszTitle = L"Select Boot ROMs Folder";
|
||||||
|
|
||||||
|
OleInitialize(NULL);
|
||||||
|
|
||||||
|
LPITEMIDLIST list = SHBrowseForFolderW(&dialog);
|
||||||
|
static wchar_t filename[MAX_PATH] = {0};
|
||||||
|
|
||||||
|
if (list) {
|
||||||
|
if (!SHGetPathFromIDListW(list, filename)) {
|
||||||
|
OleUninitialize();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char *ret = malloc(MAX_PATH * 4);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, filename, sizeof(filename), ret, MAX_PATH * 4, NULL, NULL);
|
||||||
|
CoTaskMemFree(list);
|
||||||
|
OleUninitialize();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
OleUninitialize();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
20
SDL/font.c
20
SDL/font.c
@ -1033,6 +1033,26 @@ uint8_t font[] = {
|
|||||||
_, _, _, X, X, _,
|
_, _, _, X, X, _,
|
||||||
_, _, _, _, X, _,
|
_, _, _, _, X, _,
|
||||||
_, _, _, _, _, _,
|
_, _, _, _, _, _,
|
||||||
|
|
||||||
|
/* Elipsis */
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
X, _, X, _, X, _,
|
||||||
|
_, _, _, _, _, _,
|
||||||
|
|
||||||
|
/* Mojibake */
|
||||||
|
X, X, X, X, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, _, _, _, X, _,
|
||||||
|
X, X, X, X, X, _,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t font_max = sizeof(font) / GLYPH_HEIGHT / GLYPH_WIDTH + ' ';
|
const uint8_t font_max = sizeof(font) / GLYPH_HEIGHT / GLYPH_WIDTH + ' ';
|
||||||
|
@ -12,5 +12,7 @@ extern const uint8_t font_max;
|
|||||||
#define CTRL_STRING "\x80\x81\x82"
|
#define CTRL_STRING "\x80\x81\x82"
|
||||||
#define SHIFT_STRING "\x83"
|
#define SHIFT_STRING "\x83"
|
||||||
#define CMD_STRING "\x84\x85"
|
#define CMD_STRING "\x84\x85"
|
||||||
|
#define ELLIPSIS_STRING "\x87"
|
||||||
|
#define MOJIBAKE_STRING "\x88"
|
||||||
#endif /* font_h */
|
#endif /* font_h */
|
||||||
|
|
||||||
|
43
SDL/gui.c
43
SDL/gui.c
@ -442,9 +442,50 @@ const char *current_rewind_string(unsigned index)
|
|||||||
return "Custom";
|
return "Custom";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *current_bootrom_string(unsigned index)
|
||||||
|
{
|
||||||
|
if (!configuration.bootrom_path[0]) {
|
||||||
|
return "Built-in Boot ROMs";
|
||||||
|
}
|
||||||
|
size_t length = strlen(configuration.bootrom_path);
|
||||||
|
static char ret[24] = {0,};
|
||||||
|
if (length <= 23) {
|
||||||
|
strcpy(ret, configuration.bootrom_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(ret, configuration.bootrom_path, 11);
|
||||||
|
memcpy(ret + 12, configuration.bootrom_path + length - 11, 11);
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < 24; i++) {
|
||||||
|
if (ret[i] < 0) {
|
||||||
|
ret[i] = MOJIBAKE_STRING[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (length > 23) {
|
||||||
|
ret[11] = ELLIPSIS_STRING[0];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toggle_bootrom(unsigned index)
|
||||||
|
{
|
||||||
|
if (configuration.bootrom_path[0]) {
|
||||||
|
configuration.bootrom_path[0] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char *folder = do_open_folder_dialog();
|
||||||
|
if (!folder) return;
|
||||||
|
if (strlen(folder) < sizeof(configuration.bootrom_path) - 1) {
|
||||||
|
strcpy(configuration.bootrom_path, folder);
|
||||||
|
}
|
||||||
|
free(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct menu_item emulation_menu[] = {
|
static const struct menu_item emulation_menu[] = {
|
||||||
{"Emulated Model:", cycle_model, current_model_string, cycle_model_backwards},
|
{"Emulated Model:", cycle_model, current_model_string, cycle_model_backwards},
|
||||||
{"SGB Revision:", cycle_sgb_revision, current_sgb_revision_string, cycle_sgb_revision_backwards},
|
{"SGB Revision:", cycle_sgb_revision, current_sgb_revision_string, cycle_sgb_revision_backwards},
|
||||||
|
{"Boot ROMs Folder:", toggle_bootrom, current_bootrom_string, toggle_bootrom},
|
||||||
{"Rewind Length:", cycle_rewind, current_rewind_string, cycle_rewind_backwards},
|
{"Rewind Length:", cycle_rewind, current_rewind_string, cycle_rewind_backwards},
|
||||||
{"Back", return_to_root_menu},
|
{"Back", return_to_root_menu},
|
||||||
{NULL,}
|
{NULL,}
|
||||||
@ -883,7 +924,7 @@ const char *current_joypad_name(unsigned index)
|
|||||||
// SDL returns a name with repeated and trailing spaces
|
// SDL returns a name with repeated and trailing spaces
|
||||||
while (*orig_name && i < sizeof(name) - 2) {
|
while (*orig_name && i < sizeof(name) - 2) {
|
||||||
if (orig_name[0] != ' ' || orig_name[1] != ' ') {
|
if (orig_name[0] != ' ' || orig_name[1] != ' ') {
|
||||||
name[i++] = *orig_name;
|
name[i++] = *orig_name > 0? *orig_name : MOJIBAKE_STRING[0];
|
||||||
}
|
}
|
||||||
orig_name++;
|
orig_name++;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,7 @@ typedef struct {
|
|||||||
/* v0.14 */
|
/* v0.14 */
|
||||||
unsigned padding;
|
unsigned padding;
|
||||||
uint8_t color_temperature;
|
uint8_t color_temperature;
|
||||||
|
char bootrom_path[4096];
|
||||||
} configuration_t;
|
} configuration_t;
|
||||||
|
|
||||||
extern configuration_t configuration;
|
extern configuration_t configuration;
|
||||||
|
16
SDL/main.c
16
SDL/main.c
@ -448,8 +448,6 @@ static bool handle_pending_command(void)
|
|||||||
|
|
||||||
static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type)
|
static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type)
|
||||||
{
|
{
|
||||||
bool error = false;
|
|
||||||
start_capturing_logs();
|
|
||||||
static const char *const names[] = {
|
static const char *const names[] = {
|
||||||
[GB_BOOT_ROM_DMG0] = "dmg0_boot.bin",
|
[GB_BOOT_ROM_DMG0] = "dmg0_boot.bin",
|
||||||
[GB_BOOT_ROM_DMG] = "dmg_boot.bin",
|
[GB_BOOT_ROM_DMG] = "dmg_boot.bin",
|
||||||
@ -460,8 +458,17 @@ static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type)
|
|||||||
[GB_BOOT_ROM_CGB] = "cgb_boot.bin",
|
[GB_BOOT_ROM_CGB] = "cgb_boot.bin",
|
||||||
[GB_BOOT_ROM_AGB] = "agb_boot.bin",
|
[GB_BOOT_ROM_AGB] = "agb_boot.bin",
|
||||||
};
|
};
|
||||||
GB_load_boot_rom(gb, resource_path(names[type]));
|
bool use_built_in = true;
|
||||||
end_capturing_logs(true, error);
|
if (configuration.bootrom_path[0]) {
|
||||||
|
static char path[4096];
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", configuration.bootrom_path, names[type]);
|
||||||
|
use_built_in = GB_load_boot_rom(gb, path);
|
||||||
|
}
|
||||||
|
if (use_built_in) {
|
||||||
|
start_capturing_logs();
|
||||||
|
GB_load_boot_rom(gb, resource_path(names[type]));
|
||||||
|
end_capturing_logs(true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run(void)
|
static void run(void)
|
||||||
@ -649,6 +656,7 @@ int main(int argc, char **argv)
|
|||||||
configuration.border_mode %= GB_BORDER_ALWAYS + 1;
|
configuration.border_mode %= GB_BORDER_ALWAYS + 1;
|
||||||
configuration.rumble_mode %= GB_RUMBLE_ALL_GAMES + 1;
|
configuration.rumble_mode %= GB_RUMBLE_ALL_GAMES + 1;
|
||||||
configuration.color_temperature %= 21;
|
configuration.color_temperature %= 21;
|
||||||
|
configuration.bootrom_path[sizeof(configuration.bootrom_path) - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.model >= MODEL_MAX) {
|
if (configuration.model >= MODEL_MAX) {
|
||||||
|
Loading…
Reference in New Issue
Block a user