Added graphics options menu, fixed issues with exiting not saving battery in some cases

This commit is contained in:
Lior Halphon 2017-10-14 14:10:26 +03:00
parent c66e9a06cf
commit 2dfe22e834
3 changed files with 82 additions and 8 deletions

View File

@ -14,7 +14,7 @@ SDL_PixelFormat *pixel_format = NULL;
enum scaling_mode scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR; enum scaling_mode scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR;
enum pending_command pending_command; enum pending_command pending_command;
unsigned command_parameter; unsigned command_parameter;
GB_color_correction_mode_t color_correction_mode = GB_COLOR_CORRECTION_EMULATE_HARDWARE;
#ifdef __APPLE__ #ifdef __APPLE__
#define MODIFIER_NAME " " CMD_STRING #define MODIFIER_NAME " " CMD_STRING
@ -156,8 +156,10 @@ static void draw_text_centered(uint32_t *buffer, unsigned y, const char *string,
struct menu_item { struct menu_item {
const char *string; const char *string;
void (*handler)(void); void (*handler)(void);
const char *(*value_getter)(void);
}; };
static const struct menu_item *current_menu = NULL; static const struct menu_item *current_menu = NULL;
static const struct menu_item *root_menu = NULL;
static unsigned current_selection = 0; static unsigned current_selection = 0;
static enum { static enum {
@ -168,7 +170,7 @@ static enum {
static void item_exit(void) static void item_exit(void)
{ {
exit(0); pending_command = GB_SDL_QUIT_COMMAND;
} }
static unsigned current_help_page = 0; static unsigned current_help_page = 0;
@ -178,19 +180,61 @@ static void item_help(void)
gui_state = SHOWING_HELP; gui_state = SHOWING_HELP;
} }
static void enter_graphics_menu(void);
static const struct menu_item paused_menu[] = { static const struct menu_item paused_menu[] = {
{"Resume", NULL}, {"Resume", NULL},
{"Graphic Options", enter_graphics_menu},
{"Help", item_help}, {"Help", item_help},
{"Exit", item_exit}, {"Exit", item_exit},
{NULL,} {NULL,}
}; };
static const struct menu_item nonpaused_menu[] = { static const struct menu_item nonpaused_menu[] = {
{"Graphic Options", enter_graphics_menu},
{"Help", item_help}, {"Help", item_help},
{"Exit", item_exit}, {"Exit", item_exit},
{NULL,} {NULL,}
}; };
const char *current_scaling_mode(void)
{
return (const char *[]){"Fill Entire Window", "Retain Aspect Ratio", "Retain Integer Factor"}[scaling_mode];
}
const char *current_color_correction_mode(void)
{
return (const char *[]){"Disabled", "Correct Color Curves", "Emulate Hardware", "Preserve Brightness"}[color_correction_mode];
}
static void cycle_color_correction(void)
{
if (color_correction_mode == GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS) {
color_correction_mode = GB_COLOR_CORRECTION_DISABLED;
}
else {
color_correction_mode++;
}
}
static void return_to_root_menu(void)
{
current_menu = root_menu;
current_selection = 0;
}
static const struct menu_item graphics_menu[] = {
{"Scaling Mode:", cycle_scaling, current_scaling_mode},
{"Color Correction:", cycle_color_correction, current_color_correction_mode},
{"Back", return_to_root_menu},
{NULL,}
};
static void enter_graphics_menu(void)
{
current_menu = graphics_menu;
current_selection = 0;
}
extern void set_filename(const char *new_filename, bool new_should_free); extern void set_filename(const char *new_filename, bool new_should_free);
void run_gui(bool is_running) void run_gui(bool is_running)
@ -213,7 +257,8 @@ void run_gui(bool is_running)
SDL_Event event; SDL_Event event;
gui_state = is_running? SHOWING_MENU : SHOWING_DROP_MESSAGE; gui_state = is_running? SHOWING_MENU : SHOWING_DROP_MESSAGE;
bool should_render = true; bool should_render = true;
current_menu = is_running? paused_menu : nonpaused_menu; current_menu = root_menu = is_running? paused_menu : nonpaused_menu;
current_selection = 0;
while (SDL_WaitEvent(&event)) { while (SDL_WaitEvent(&event)) {
if (should_render) { if (should_render) {
should_render = false; should_render = false;
@ -226,9 +271,14 @@ void run_gui(bool is_running)
break; break;
case SHOWING_MENU: case SHOWING_MENU:
draw_text_centered(pixels, 16, "SameBoy", gui_palette_native[3], gui_palette_native[0], false); draw_text_centered(pixels, 16, "SameBoy", gui_palette_native[3], gui_palette_native[0], false);
unsigned i = 0; unsigned i = 0, y = 40;
for (const struct menu_item *item = current_menu; item->string; item++, i++) { for (const struct menu_item *item = current_menu; item->string; item++, i++) {
draw_text_centered(pixels, 12 * i + 40, item->string, gui_palette_native[3], gui_palette_native[0], i == current_selection); draw_text_centered(pixels, y, item->string, gui_palette_native[3], gui_palette_native[0], i == current_selection);
y += 12;
if (item->value_getter) {
draw_text_centered(pixels, y, item->value_getter(), gui_palette_native[3], gui_palette_native[0], false);
y += 12;
}
} }
break; break;
case SHOWING_HELP: case SHOWING_HELP:
@ -243,8 +293,15 @@ void run_gui(bool is_running)
} }
switch (event.type) { switch (event.type) {
case SDL_QUIT: { case SDL_QUIT: {
if (!is_running) {
exit(0); exit(0);
} }
else {
pending_command = GB_SDL_QUIT_COMMAND;
return;
}
}
case SDL_WINDOWEVENT: { case SDL_WINDOWEVENT: {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) { if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
update_viewport(); update_viewport();
@ -290,6 +347,12 @@ void run_gui(bool is_running)
else if (event.key.keysym.sym == SDLK_RETURN) { else if (event.key.keysym.sym == SDLK_RETURN) {
if (current_menu[current_selection].handler) { if (current_menu[current_selection].handler) {
current_menu[current_selection].handler(); current_menu[current_selection].handler();
if (pending_command) {
if (!is_running && pending_command == GB_SDL_QUIT_COMMAND) {
exit(0);
}
return;
}
should_render = true; should_render = true;
} }
else { else {

View File

@ -2,6 +2,7 @@
#define gui_h #define gui_h
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <Core/gb.h>
extern SDL_Window *window; extern SDL_Window *window;
extern SDL_Renderer *renderer; extern SDL_Renderer *renderer;
@ -24,10 +25,12 @@ enum pending_command {
GB_SDL_RESET_COMMAND, GB_SDL_RESET_COMMAND,
GB_SDL_NEW_FILE_COMMAND, GB_SDL_NEW_FILE_COMMAND,
GB_SDL_TOGGLE_MODEL_COMMAND, GB_SDL_TOGGLE_MODEL_COMMAND,
GB_SDL_QUIT_COMMAND,
}; };
extern enum pending_command pending_command; extern enum pending_command pending_command;
extern unsigned command_parameter; extern unsigned command_parameter;
extern GB_color_correction_mode_t color_correction_mode;
void update_viewport(void); void update_viewport(void);
void cycle_scaling(void); void cycle_scaling(void);

View File

@ -83,8 +83,8 @@ static void handle_events(GB_gameboy_t *gb)
{ {
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_QUIT:
GB_save_battery(gb, battery_save_path_ptr); pending_command = GB_SDL_QUIT_COMMAND;
exit(0); break;
case SDL_DROPFILE: { case SDL_DROPFILE: {
set_filename(event.drop.file, true); set_filename(event.drop.file, true);
@ -102,6 +102,7 @@ static void handle_events(GB_gameboy_t *gb)
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
run_gui(true); run_gui(true);
GB_set_color_correction_mode(gb, color_correction_mode);
break; break;
case SDLK_c: case SDLK_c:
@ -215,8 +216,10 @@ static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b)
static void debugger_interrupt(int ignore) static void debugger_interrupt(int ignore)
{ {
if (!GB_is_inited(&gb)) return;
/* ^C twice to exit */ /* ^C twice to exit */
if (GB_debugger_is_stopped(&gb)) { if (GB_debugger_is_stopped(&gb)) {
GB_save_battery(&gb, battery_save_path_ptr);
exit(0); exit(0);
} }
GB_debugger_break(&gb); GB_debugger_break(&gb);
@ -267,6 +270,10 @@ static bool handle_pending_command(void)
case GB_SDL_TOGGLE_MODEL_COMMAND: case GB_SDL_TOGGLE_MODEL_COMMAND:
dmg = !dmg; dmg = !dmg;
return true; return true;
case GB_SDL_QUIT_COMMAND:
GB_save_battery(&gb, battery_save_path_ptr);
exit(0);
} }
return false; return false;
} }
@ -290,6 +297,7 @@ restart:
GB_set_pixels_output(&gb, pixels); GB_set_pixels_output(&gb, pixels);
GB_set_rgb_encode_callback(&gb, rgb_encode); GB_set_rgb_encode_callback(&gb, rgb_encode);
GB_set_sample_rate(&gb, have_aspec.freq); GB_set_sample_rate(&gb, have_aspec.freq);
GB_set_color_correction_mode(&gb, color_correction_mode);
} }
bool error = false; bool error = false;