Added open dialog to the SDL GUI, misc fixes
This commit is contained in:
parent
f9cc7a3b46
commit
cdc36f329e
@ -82,9 +82,9 @@ Start:
|
||||
|
||||
.sendCommand
|
||||
xor a
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
ld a, $30
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
|
||||
ldh a, [$80]
|
||||
call SendByte
|
||||
@ -112,9 +112,9 @@ Start:
|
||||
|
||||
; Done bit
|
||||
ld a, $20
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
ld a, $30
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
|
||||
; Update command
|
||||
ldh a, [$80]
|
||||
@ -128,10 +128,10 @@ Start:
|
||||
; Write to sound registers for DMG compatibility
|
||||
ld c, $13
|
||||
ld a, $c1
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
inc c
|
||||
ld a, 7
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
|
||||
; Init BG palette
|
||||
ld a, $fc
|
||||
@ -168,9 +168,9 @@ SendByte:
|
||||
jr c, .zeroBit
|
||||
add a ; 10 -> 20
|
||||
.zeroBit
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
ld a, $30
|
||||
ldh [c], a
|
||||
ld [c], a
|
||||
dec d
|
||||
ret z
|
||||
jr .loop
|
||||
|
@ -606,7 +606,7 @@ static void ld_dhl_d8(GB_gameboy_t *gb, uint8_t opcode)
|
||||
cycle_write(gb, gb->registers[GB_REGISTER_HL], data);
|
||||
}
|
||||
|
||||
uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
|
||||
static uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
|
||||
{
|
||||
uint8_t src_register_id;
|
||||
uint8_t src_low;
|
||||
|
19
Makefile
19
Makefile
@ -65,14 +65,25 @@ endif
|
||||
|
||||
# Set compilation and linkage flags based on target, platform and configuration
|
||||
|
||||
OPEN_DIALOG = OpenDialog/gtk.c
|
||||
|
||||
ifeq ($(PLATFORM),windows32)
|
||||
OPEN_DIALOG = OpenDialog/windows.c
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
OPEN_DIALOG = OpenDialog/cocoa.m
|
||||
endif
|
||||
|
||||
|
||||
CFLAGS += -Werror -Wall -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES
|
||||
SDL_LDFLAGS := -lSDL2 -lGL
|
||||
ifeq ($(PLATFORM),windows32)
|
||||
CFLAGS += -IWindows
|
||||
LDFLAGS += -lmsvcrt -lSDL2main -Wl,/MANIFESTFILE:NUL
|
||||
CFLAGS += -IWindows -Drandom=rand
|
||||
LDFLAGS += -lmsvcrt -lcomdlg32 -lSDL2main -Wl,/MANIFESTFILE:NUL
|
||||
SDL_LDFLAGS := -lSDL2 -lopengl32
|
||||
else
|
||||
LDFLAGS += -lc -lm
|
||||
LDFLAGS += -lc -lm -ldl
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
@ -120,7 +131,7 @@ all: cocoa sdl tester libretro
|
||||
# Get a list of our source files and their respective object file targets
|
||||
|
||||
CORE_SOURCES := $(shell ls Core/*.c)
|
||||
SDL_SOURCES := $(shell ls SDL/*.c)
|
||||
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG)
|
||||
TESTER_SOURCES := $(shell ls Tester/*.c)
|
||||
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
|
20
OpenDialog/cocoa.m
Normal file
20
OpenDialog/cocoa.m
Normal file
@ -0,0 +1,20 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "open_dialog.h"
|
||||
|
||||
|
||||
char *do_open_rom_dialog(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
NSWindow *key = [NSApp keyWindow];
|
||||
NSOpenPanel *dialog = [NSOpenPanel openPanel];
|
||||
dialog.title = @"Open ROM";
|
||||
dialog.allowedFileTypes = @[@"gb", @"gbc", @"sgb"];
|
||||
[dialog runModal];
|
||||
[key makeKeyAndOrderFront:nil];
|
||||
NSString *ret = [[[dialog URLs] firstObject] path];
|
||||
if (ret) {
|
||||
return strdup(ret.UTF8String);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
96
OpenDialog/gtk.c
Normal file
96
OpenDialog/gtk.c
Normal file
@ -0,0 +1,96 @@
|
||||
#include "open_dialog.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GTK_FILE_CHOOSER_ACTION_OPEN 0
|
||||
|
||||
|
||||
void *_gtk_file_chooser_dialog_new (const char *title,
|
||||
void *parent,
|
||||
int action,
|
||||
const char *first_button_text,
|
||||
...);
|
||||
bool _gtk_init_check (int *argc, char ***argv);
|
||||
int _gtk_dialog_run(void *);
|
||||
void _g_free(void *);
|
||||
void _g_object_unref(void *);
|
||||
char *_gtk_file_chooser_get_filename(void *);
|
||||
void _g_log_set_default_handler (void *function, void *data);
|
||||
void *_gtk_file_filter_new(void);
|
||||
void _gtk_file_filter_add_pattern(void *filter, const char *pattern);
|
||||
void _gtk_file_filter_set_name(void *filter, const char *name);
|
||||
void _gtk_file_chooser_add_filter(void *dialog, void *filter);
|
||||
|
||||
#define LAZY(symbol) static typeof(_##symbol) *symbol = NULL;\
|
||||
if (symbol == NULL) symbol = dlsym(handle, #symbol);\
|
||||
if (symbol == NULL) goto lazy_error
|
||||
#define TRY_DLOPEN(name) handle = handle? handle : dlopen(name, RTLD_NOW)
|
||||
|
||||
void nop(){}
|
||||
|
||||
char *do_open_rom_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(g_object_unref);
|
||||
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);
|
||||
|
||||
/* Shut up GTK */
|
||||
g_log_set_default_handler(nop, NULL);
|
||||
|
||||
gtk_init_check(0, 0);
|
||||
|
||||
|
||||
void *dialog = gtk_file_chooser_dialog_new("Open ROM",
|
||||
0,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"Open", 0, NULL);
|
||||
|
||||
|
||||
void *filter = gtk_file_filter_new();
|
||||
gtk_file_filter_add_pattern(filter, "*.gb");
|
||||
gtk_file_filter_add_pattern(filter, "*.gbc");
|
||||
gtk_file_filter_add_pattern(filter, "*.sgb");
|
||||
gtk_file_filter_set_name(filter, "Game Boy ROMs");
|
||||
gtk_file_chooser_add_filter(dialog, filter);
|
||||
|
||||
int res = gtk_dialog_run (dialog);
|
||||
char *ret = NULL;
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
char *filename;
|
||||
filename = gtk_file_chooser_get_filename(dialog);
|
||||
ret = strdup(filename);
|
||||
g_free(filename);
|
||||
}
|
||||
|
||||
g_object_unref(dialog);
|
||||
return ret;
|
||||
|
||||
lazy_error:
|
||||
fprintf(stderr, "Failed to display GTK dialog\n");
|
||||
return NULL;
|
||||
}
|
6
OpenDialog/open_dialog.h
Normal file
6
OpenDialog/open_dialog.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef open_rom_h
|
||||
#define open_rom_h
|
||||
|
||||
char *do_open_rom_dialog(void);
|
||||
|
||||
#endif /* open_rom_h */
|
28
OpenDialog/windows.c
Normal file
28
OpenDialog/windows.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <windows.h>
|
||||
#include "open_dialog.h"
|
||||
|
||||
char *do_open_rom_dialog(void)
|
||||
{
|
||||
OPENFILENAMEW dialog;
|
||||
wchar_t filename[MAX_PATH] = {0};
|
||||
|
||||
memset(&dialog, 0, sizeof(dialog));
|
||||
dialog.lStructSize = sizeof(dialog);
|
||||
dialog.lpstrFile = filename;
|
||||
dialog.nMaxFile = sizeof(filename);
|
||||
dialog.lpstrFilter = L"Game Boy ROMs\0*.gb;*.gbc;*.sgb\0All files\0*.*\0\0";
|
||||
dialog.nFilterIndex = 1;
|
||||
dialog.lpstrFileTitle = NULL;
|
||||
dialog.nMaxFileTitle = 0;
|
||||
dialog.lpstrInitialDir = NULL;
|
||||
dialog.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if (GetOpenFileNameW(&dialog) == TRUE)
|
||||
{
|
||||
char *ret = malloc(MAX_PATH * 4);
|
||||
WideCharToMultiByte(CP_UTF8, 0, filename, sizeof(filename), ret, MAX_PATH * 4, NULL, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
34
SDL/gui.c
34
SDL/gui.c
@ -1,4 +1,5 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <OpenDialog/open_dialog.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@ -97,11 +98,11 @@ configuration_t configuration =
|
||||
|
||||
|
||||
static const char *help[] ={
|
||||
"Drop a GB or GBC ROM\n"
|
||||
"file to play.\n"
|
||||
"Drop a ROM to play.\n"
|
||||
"\n"
|
||||
"Keyboard Shortcuts:\n"
|
||||
" Open Menu: Escape\n"
|
||||
" Open ROM: " MODIFIER_NAME "+O\n"
|
||||
" Reset: " MODIFIER_NAME "+R\n"
|
||||
" Pause: " MODIFIER_NAME "+P\n"
|
||||
" Save state: " MODIFIER_NAME "+(0-9)\n"
|
||||
@ -267,8 +268,19 @@ static void enter_controls_menu(unsigned index);
|
||||
static void enter_joypad_menu(unsigned index);
|
||||
static void enter_audio_menu(unsigned index);
|
||||
|
||||
extern void set_filename(const char *new_filename, typeof(free) *new_free_function);
|
||||
static void open_rom(unsigned index)
|
||||
{
|
||||
char *filename = do_open_rom_dialog();
|
||||
if (filename) {
|
||||
set_filename(filename, free);
|
||||
pending_command = GB_SDL_NEW_FILE_COMMAND;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct menu_item paused_menu[] = {
|
||||
{"Resume", NULL},
|
||||
{"Open ROM", open_rom},
|
||||
{"Emulation Options", enter_emulation_menu},
|
||||
{"Graphic Options", enter_graphics_menu},
|
||||
{"Audio Options", enter_audio_menu},
|
||||
@ -778,7 +790,6 @@ void connect_joypad(void)
|
||||
}
|
||||
}
|
||||
|
||||
extern void set_filename(const char *new_filename, bool new_should_free);
|
||||
void run_gui(bool is_running)
|
||||
{
|
||||
connect_joypad();
|
||||
@ -818,6 +829,9 @@ void run_gui(bool is_running)
|
||||
/* Convert Joypad and mouse events (We only generate down events) */
|
||||
if (gui_state != WAITING_FOR_KEY && gui_state != WAITING_FOR_JBUTTON) {
|
||||
switch (event.type) {
|
||||
case SDL_WINDOWEVENT:
|
||||
should_render = true;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (gui_state == SHOWING_HELP) {
|
||||
event.type = SDL_KEYDOWN;
|
||||
@ -957,7 +971,7 @@ void run_gui(bool is_running)
|
||||
break;
|
||||
}
|
||||
case SDL_DROPFILE: {
|
||||
set_filename(event.drop.file, true);
|
||||
set_filename(event.drop.file, SDL_free);
|
||||
pending_command = GB_SDL_NEW_FILE_COMMAND;
|
||||
return;
|
||||
}
|
||||
@ -995,7 +1009,17 @@ void run_gui(bool is_running)
|
||||
}
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
if (event.key.keysym.scancode == SDL_SCANCODE_RETURN && gui_state == WAITING_FOR_JBUTTON) {
|
||||
if (event.key.keysym.scancode == SDL_SCANCODE_O) {
|
||||
if (event.key.keysym.mod & MODIFIER) {
|
||||
char *filename = do_open_rom_dialog();
|
||||
if (filename) {
|
||||
set_filename(filename, free);
|
||||
pending_command = GB_SDL_NEW_FILE_COMMAND;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.key.keysym.scancode == SDL_SCANCODE_RETURN && gui_state == WAITING_FOR_JBUTTON) {
|
||||
should_render = true;
|
||||
if (joypad_configuration_progress != JOYPAD_BUTTONS_MAX) {
|
||||
configuration.joypad_configuration[joypad_configuration_progress] = -1;
|
||||
|
@ -9,6 +9,12 @@
|
||||
#define JOYSTICK_HIGH 0x4000
|
||||
#define JOYSTICK_LOW 0x3800
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
|
||||
extern GB_gameboy_t gb;
|
||||
|
||||
extern SDL_Window *window;
|
||||
|
29
SDL/main.c
29
SDL/main.c
@ -1,6 +1,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <OpenDialog/open_dialog.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <Core/gb.h>
|
||||
#include "utils.h"
|
||||
@ -30,18 +31,18 @@ static bool underclock_down = false, rewind_down = false, do_rewind = false, rew
|
||||
static double clock_mutliplier = 1.0;
|
||||
|
||||
static char *filename = NULL;
|
||||
static bool should_free_filename = false;
|
||||
static typeof(free) *free_function = NULL;
|
||||
static char *battery_save_path_ptr;
|
||||
|
||||
SDL_AudioDeviceID device_id;
|
||||
|
||||
void set_filename(const char *new_filename, bool new_should_free)
|
||||
void set_filename(const char *new_filename, typeof(free) *new_free_function)
|
||||
{
|
||||
if (filename && should_free_filename) {
|
||||
SDL_free(filename);
|
||||
if (filename && free_function) {
|
||||
free_function(filename);
|
||||
}
|
||||
filename = (char *) new_filename;
|
||||
should_free_filename = new_should_free;
|
||||
free_function = new_free_function;
|
||||
}
|
||||
|
||||
static SDL_AudioSpec want_aspec, have_aspec;
|
||||
@ -101,11 +102,6 @@ static void open_menu(void)
|
||||
|
||||
static void handle_events(GB_gameboy_t *gb)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
#define MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
@ -115,7 +111,7 @@ static void handle_events(GB_gameboy_t *gb)
|
||||
break;
|
||||
|
||||
case SDL_DROPFILE: {
|
||||
set_filename(event.drop.file, true);
|
||||
set_filename(event.drop.file, SDL_free);
|
||||
pending_command = GB_SDL_NEW_FILE_COMMAND;
|
||||
break;
|
||||
}
|
||||
@ -226,6 +222,17 @@ static void handle_events(GB_gameboy_t *gb)
|
||||
pending_command = GB_SDL_RESET_COMMAND;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_O: {
|
||||
if (event.key.keysym.mod & MODIFIER) {
|
||||
char *filename = do_open_rom_dialog();
|
||||
if (filename) {
|
||||
set_filename(filename, free);
|
||||
pending_command = GB_SDL_NEW_FILE_COMMAND;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_SCANCODE_P:
|
||||
if (event.key.keysym.mod & MODIFIER) {
|
||||
|
Loading…
Reference in New Issue
Block a user