From 9cc8b3320afa38e37682cfecd60c8acc0ecabfd6 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Wed, 4 Oct 2017 12:43:31 +0300 Subject: [PATCH] Starting to add a GUI to the SDL port --- Makefile | 4 +- SDL/background.bmp | Bin 0 -> 11592 bytes SDL/drop.bmp | Bin 69176 -> 0 bytes SDL/font.c | 956 +++++++++++++++++++++++++++++++++++++++++++++ SDL/font.h | 9 + SDL/gui.c | 213 ++++++++++ SDL/gui.h | 25 ++ SDL/main.c | 148 +------ 8 files changed, 1218 insertions(+), 137 deletions(-) create mode 100644 SDL/background.bmp delete mode 100644 SDL/drop.bmp create mode 100644 SDL/font.c create mode 100644 SDL/font.h create mode 100644 SDL/gui.c create mode 100644 SDL/gui.h diff --git a/Makefile b/Makefile index c185cf9..fcde67e 100755 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ endif cocoa: $(BIN)/SameBoy.app quicklook: $(BIN)/SameBoy.qlgenerator -sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/drop.bmp +sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp bootroms: $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin all: cocoa sdl tester @@ -267,7 +267,7 @@ $(BIN)/SDL/LICENSE: LICENSE $(BIN)/SDL/registers.sym: Misc/registers.sym cp -f $^ $@ -$(BIN)/SDL/drop.bmp: SDL/drop.bmp +$(BIN)/SDL/background.bmp: SDL/background.bmp cp -f $^ $@ # Boot ROMs diff --git a/SDL/background.bmp b/SDL/background.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4624cb2395bcfab8eba53aea3be99868f0fb6ab0 GIT binary patch literal 11592 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 */ + _, _, _, _, _, _ , + X, _, _, _, _, _ , + _, X, X, _, _, _ , + _, _, _, X, X, _ , + _, _, _, X, X, _ , + _, X, X, _, _, _ , + X, _, _, _, _, _ , + _, _, _, _, _, _ , + + /* ? */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, X, _ , + _, _, X, X, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* @ */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, X, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, _, X, X, _ , + X, _, _, _, _, _ , + _, X, X, X, X, _ , + + /* A */ + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* B */ + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* C */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* D */ + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* E */ + X, X, X, X, X, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, X, X, X, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* F */ + X, X, X, X, X, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, X, X, X, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + _, _, _, _, _, _ , + + /* G */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, _, _ , + X, _, X, X, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* H */ + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* I */ + X, X, X, X, X, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + X, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* J */ + _, _, X, X, X, _ , + _, _, _, _, X, _ , + _, _, _, _, X, _ , + _, _, _, _, X, _ , + _, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* K */ + X, _, _, _, X, _ , + X, _, _, X, _, _ , + X, _, X, _, _, _ , + X, X, _, _, _, _ , + X, _, X, _, _, _ , + X, _, _, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* L */ + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* M */ + X, _, _, _, X, _ , + X, X, _, X, X, _ , + X, X, _, X, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* N */ + X, _, _, _, X, _ , + X, X, _, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, _, X, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* O */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* P */ + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + X, _, _, _, _, _ , + X, _, _, _, _, _ , + _, _, _, _, _, _ , + + /* Q */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, X, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, X, X , + + /* R */ + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + X, _, X, _, _, _ , + X, _, _, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* S */ + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, _, _ , + _, X, X, X, _, _ , + _, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* T */ + X, X, X, X, X, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* U */ + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* V */ + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* W */ + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, X, _, X, X, _ , + X, X, _, X, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* X */ + X, _, _, _, X, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + _, _, X, _, _, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* Y */ + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, _, X, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* Z */ + X, X, X, X, X, _ , + _, _, _, _, X, _ , + _, _, _, X, _, _ , + _, _, X, _, _, _ , + _, X, _, _, _, _ , + X, _, _, _, _, _ , + X, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* [ */ + _, X, X, X, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, X, X, _, _ , + + /* \ */ + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, _, _, X, _ , + _, _, _, _, X, _ , + + /* ] */ + _, X, X, X, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, X, X, X, _, _ , + + /* ^ */ + _, _, X, _, _, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + + /* _ */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, X, X, X, X, X , + + /* ` */ + _, X, _, _, _, _ , + _, _, X, _, _, _ , + _, _, _, X, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + + /* a */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, _, _, _ , + _, _, _, X, _, _ , + _, X, X, X, _, _ , + X, _, _, X, _, _ , + _, X, X, _, X, _ , + _, _, _, _, _, _ , + + /* b */ + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, X, X, _, _ , + X, X, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* c */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, _, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* d */ + _, _, _, _, X, _ , + _, _, _, _, X, _ , + _, X, X, X, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* e */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, X, X, X, X, _ , + X, _, _, _, _, _ , + _, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* f */ + _, _, X, X, _, _ , + _, X, _, _, _, _ , + X, X, X, X, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, _, _, _, _ , + + /* g */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, X, _ , + X, _, _, X, _, _ , + _, X, X, _, _, _ , + _, _, _, X, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + + /* h */ + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, X, X, _, _ , + X, X, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* i */ + _, _, X, _, _, _ , + _, _, _, _, _, _ , + X, X, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* j */ + _, _, X, _, _, _ , + _, _, _, _, _, _ , + X, X, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + X, X, _, _, _, _ , + + /* k */ + X, _, _, _, _, _ , + X, _, _, _, _, _ , + X, _, _, _, X, _ , + X, _, X, X, _, _ , + X, X, _, _, _, _ , + X, _, X, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* l */ + X, X, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, X, X, _ , + _, _, _, _, _, _ , + + /* m */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, X, X, X, _, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + _, _, _, _, _, _ , + + /* n */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, X, X, _, _ , + X, X, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* o */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* p */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, X, X, X, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, X, _, _, X, _ , + X, _, X, X, _, _ , + X, _, _, _, _, _ , + + /* q */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, X, X, _ , + _, X, X, _, X, _ , + _, _, _, _, X, _ , + + /* r */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, _, X, _, _ , + _, X, X, _, X, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, _, _, _, _ , + + /* s */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, X, X, X, X, _ , + X, _, _, _, _, _ , + _, X, X, X, _, _ , + _, _, _, _, X, _ , + X, X, X, X, _, _ , + _, _, _, _, _, _ , + + /* t */ + _, _, _, _, _, _ , + _, X, _, _, _, _ , + X, X, X, X, X, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, X, X, X, _ , + _, _, _, _, _, _ , + + /* u */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, X, X, _ , + _, X, X, _, X, _ , + _, _, _, _, _, _ , + + /* v */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + _, _, X, _, _, _ , + _, _, _, _, _, _ , + + /* w */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, _, _, X, _ , + X, _, X, _, X, _ , + X, _, X, _, X, _ , + _, X, _, X, _, _ , + _, X, _, X, _, _ , + _, _, _, _, _, _ , + + /* x */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, _, _, X, _ , + _, X, _, X, _, _ , + _, _, X, _, _, _ , + _, X, _, X, _, _ , + X, _, _, _, X, _ , + _, _, _, _, _, _ , + + /* y */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, _, _, _, X, _ , + X, _, _, _, X, _ , + X, _, _, X, X, _ , + _, X, X, _, X, _ , + _, _, _, _, X, _ , + _, X, X, X, _, _ , + + /* z */ + _, _, _, _, _, _ , + _, _, _, _, _, _ , + X, X, X, X, X, _ , + _, _, _, X, _, _ , + _, _, X, _, _, _ , + _, X, _, _, _, _ , + X, X, X, X, X, _ , + _, _, _, _, _, _ , + + /* { */ + _, _, X, X, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, X, _, _, _, _ , + _, X, _, _, _, _ , + _, _, X, X, _, _ , + + /* | */ + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + + /* } */ + _, X, X, _, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, _, X, _, _, _ , + _, _, X, _, _, _ , + _, _, _, X, _, _ , + _, _, _, X, _, _ , + _, X, X, _, _, _ , + + /* ~ */ + _, _, _, _, _, X , + _, _, _, _, _, _ , + _, _, X, _, _, X , + _, X, _, X, _, X , + _, X, _, _, X, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , + _, _, _, _, _, _ , +}; diff --git a/SDL/font.h b/SDL/font.h new file mode 100644 index 0000000..0c2c78a --- /dev/null +++ b/SDL/font.h @@ -0,0 +1,9 @@ +#ifndef font_h +#define font_h + +#include +extern uint8_t font[]; +#define GLYPH_HEIGHT 8 +#define GLYPH_WIDTH 6 + +#endif /* font_h */ diff --git a/SDL/gui.c b/SDL/gui.c new file mode 100644 index 0000000..dab10ef --- /dev/null +++ b/SDL/gui.c @@ -0,0 +1,213 @@ +#include +#include +#include "utils.h" +#include "gui.h" +#include "font.h" + +static const SDL_Color gui_palette[4] = {{8, 24, 16,}, {57, 97, 57,}, {132, 165, 99}, {198, 222, 140}}; +static uint32_t gui_palette_native[4]; + +SDL_Window *window = NULL; +SDL_Renderer *renderer = NULL; +SDL_Texture *texture = NULL; +SDL_PixelFormat *pixel_format = NULL; +enum scaling_mode scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR; + + +#ifdef __APPLE__ +#define MODIFIER_NAME "Cmd" +#else +#define MODIFIER_NAME "Ctrl" +#endif + + +static const char help[] = +"Drop a GB or GBC ROM file to play.\n" +"\n" +"Controls:\n" +" D-Pad: Arrow Keys\n" +" A: X\n" +" B: Z\n" +" Start: Enter\n" +" Select: Backspace\n" +"\n" +"Keyboard Shortcuts: \n" +" Restart: " MODIFIER_NAME "+R\n" +" Pause: " MODIFIER_NAME "+P\n" +" Turbo: Space\n" +#ifdef __APPLE__ +" Mute/Unmute: " MODIFIER_NAME "+Shift+M\n" +#else +" Mute/Unmute: " MODIFIER_NAME "+M\n" +#endif +" Save state: " MODIFIER_NAME "+Number (0-9)\n" +" Load state: " MODIFIER_NAME "+Shift+Number (0-9)\n" +" Cycle between DMG/CGB emulation: " MODIFIER_NAME "+T\n" +" Cycle scaling modes: Tab" +; + +void cycle_scaling(void) +{ + scaling_mode++; + scaling_mode %= GB_SDL_SCALING_MAX; + update_viewport(); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); +} + +void update_viewport(void) +{ + int win_width, win_height; + SDL_GetWindowSize(window, &win_width, &win_height); + double x_factor = win_width / 160.0; + double y_factor = win_height / 144.0; + + if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) { + x_factor = (int)(x_factor); + y_factor = (int)(y_factor); + } + + if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) { + if (x_factor > y_factor) { + x_factor = y_factor; + } + else { + y_factor = x_factor; + } + } + + unsigned new_width = x_factor * 160; + unsigned new_height = y_factor * 144; + + SDL_Rect rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2, + new_width, new_height}; + SDL_RenderSetViewport(renderer, &rect); +} + +void show_help(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window); +} + +/* Does NOT check for bounds! */ +static void draw_char(uint32_t *buffer, unsigned char ch, uint32_t color) +{ + if (ch < ' ' || ch > '~') { + ch = '?'; + } + + uint8_t *data = &font[(ch - ' ') * GLYPH_WIDTH * GLYPH_HEIGHT]; + + for (unsigned y = GLYPH_HEIGHT; y--;) { + for (unsigned x = GLYPH_WIDTH; x--;) { + if (*(data++)) { + (*buffer) = color; + } + buffer++; + } + buffer += 160 - GLYPH_WIDTH; + } +} + +/* Does NOT check for bounds! */ +static void draw_bordered_char(uint32_t *buffer, unsigned char ch, uint32_t color, uint32_t border) +{ + draw_char(buffer - 1, ch, border); + draw_char(buffer + 1, ch, border); + draw_char(buffer - 160, ch, border); + draw_char(buffer + 160, ch, border); + draw_char(buffer, ch, color); +} + +static void draw_text(uint32_t *buffer, unsigned x, unsigned y, const char *string, uint32_t color, uint32_t border) +{ + unsigned orig_x = x; + while (*string) { + if (*string == '\n') { + x = orig_x; + y += GLYPH_HEIGHT + 4; + string++; + continue; + } + + if (x == 0 || x > 160 - GLYPH_WIDTH - 1 || y == 0 || y > 144 - GLYPH_HEIGHT - 1) { + break; + } + + draw_bordered_char(&buffer[x + 160 * y], *string, color, border); + x += GLYPH_WIDTH; + string++; + } +} + +static void draw_text_centered(uint32_t *buffer, unsigned y, const char *string, uint32_t color, uint32_t border) +{ + draw_text(buffer, 160 / 2 - (unsigned) strlen(string) * GLYPH_WIDTH / 2, y, string, color, border); +} + + +extern void set_filename(const char *new_filename, bool new_should_free); +void run_gui(void) +{ + /* Draw the "Drop file" screen */ + static SDL_Surface *converted_background = NULL; + if (!converted_background) { + SDL_Surface *background = SDL_LoadBMP(executable_relative_path("background.bmp")); + SDL_SetPaletteColors(background->format->palette, gui_palette, 0, 4); + converted_background = SDL_ConvertSurface(background, pixel_format, 0); + SDL_LockSurface(converted_background); + SDL_FreeSurface(background); + + for (unsigned i = 4; i--; ) { + gui_palette_native[i] = SDL_MapRGB(pixel_format, gui_palette[i].r, gui_palette[i].g, gui_palette[i].b); + } + } + + uint32_t pixels[160 * 144]; + memcpy(pixels, converted_background->pixels, sizeof(pixels)); + + draw_text_centered(pixels, 116, "Drop a GB or GBC", gui_palette_native[3], gui_palette_native[0]); + draw_text_centered(pixels, 128, "file to play", gui_palette_native[3], gui_palette_native[0]); + + SDL_UpdateTexture(texture, NULL, pixels, 160 * sizeof (uint32_t)); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + + SDL_Event event; + while (SDL_WaitEvent(&event)) { + switch (event.type) { + case SDL_QUIT: { + exit(0); + } + case SDL_WINDOWEVENT: { + if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + update_viewport(); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + } + break; + } + case SDL_DROPFILE: { + set_filename(event.drop.file, true); + return; + } + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_TAB) { + cycle_scaling(); + } +#ifndef __APPLE__ + else if (event.key.keysym.sym == SDLK_F1) { + show_help(); + } +#else + else if (event.key.keysym.sym == SDLK_QUESTION || (event.key.keysym.sym && (event.key.keysym.mod & KMOD_SHIFT))) { + show_help(); + } +#endif + break; + } + } +} diff --git a/SDL/gui.h b/SDL/gui.h new file mode 100644 index 0000000..28ffc55 --- /dev/null +++ b/SDL/gui.h @@ -0,0 +1,25 @@ +#ifndef gui_h +#define gui_h + +#include + +extern SDL_Window *window; +extern SDL_Renderer *renderer; +extern SDL_Texture *texture; +extern SDL_PixelFormat *pixel_format; + +enum scaling_mode { + GB_SDL_SCALING_ENTIRE_WINDOW, + GB_SDL_SCALING_KEEP_RATIO, + GB_SDL_SCALING_INTEGER_FACTOR, + GB_SDL_SCALING_MAX, +}; + +extern enum scaling_mode scaling_mode; + +void update_viewport(void); +void cycle_scaling(void); +void show_help(void); + +void run_gui(void); +#endif diff --git a/SDL/main.c b/SDL/main.c index e1fd764..d5035b9 100755 --- a/SDL/main.c +++ b/SDL/main.c @@ -2,8 +2,8 @@ #include #include #include "gb.h" - #include "utils.h" +#include "gui.h" #ifndef _WIN32 #define AUDIO_FREQUENCY 96000 @@ -12,37 +12,6 @@ #define AUDIO_FREQUENCY 44100 #endif -#ifdef __APPLE__ -#define MODIFIER_NAME "Cmd" -#else -#define MODIFIER_NAME "Ctrl" -#endif - -static const char help[] = -"Drop a GB or GBC ROM file to play.\n" -"\n" -"Controls:\n" -" D-Pad: Arrow Keys\n" -" A: X\n" -" B: Z\n" -" Start: Enter\n" -" Select: Backspace\n" -"\n" -"Keyboard Shortcuts: \n" -" Restart: " MODIFIER_NAME "+R\n" -" Pause: " MODIFIER_NAME "+P\n" -" Turbo: Space\n" -#ifdef __APPLE__ -" Mute/Unmute: " MODIFIER_NAME "+Shift+M\n" -#else -" Mute/Unmute: " MODIFIER_NAME "+M\n" -#endif -" Save state: " MODIFIER_NAME "+Number (0-9)\n" -" Load state: " MODIFIER_NAME "+Shift+Number (0-9)\n" -" Cycle between DMG/CGB emulation: " MODIFIER_NAME "+T\n" -" Cycle scaling modes: Tab" -; - GB_gameboy_t gb; static bool dmg = false; static bool paused = false; @@ -52,10 +21,15 @@ static char *filename = NULL; static bool should_free_filename = false; static char *battery_save_path_ptr; -static SDL_Window *window = NULL; -static SDL_Renderer *renderer = NULL; -static SDL_Texture *texture = NULL; -static SDL_PixelFormat *pixel_format = NULL; +void set_filename(const char *new_filename, bool new_should_free) +{ + if (filename && should_free_filename) { + free(filename); + } + filename = (char *) new_filename; + should_free_filename = new_should_free; +} + static SDL_AudioSpec want_aspec, have_aspec; static char *captured_log = NULL; @@ -106,53 +80,8 @@ static enum { GB_SDL_TOGGLE_MODEL_COMMAND, } pending_command; -static enum { - GB_SDL_SCALING_ENTIRE_WINDOW, - GB_SDL_SCALING_KEEP_RATIO, - GB_SDL_SCALING_INTEGER_FACTOR, - GB_SDL_SCALING_MAX, -} scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR; static unsigned command_parameter; -static void update_viewport(void) -{ - int win_width, win_height; - SDL_GetWindowSize(window, &win_width, &win_height); - double x_factor = win_width / 160.0; - double y_factor = win_height / 144.0; - - if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) { - x_factor = (int)(x_factor); - y_factor = (int)(y_factor); - } - - if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) { - if (x_factor > y_factor) { - x_factor = y_factor; - } - else { - y_factor = x_factor; - } - } - - unsigned new_width = x_factor * 160; - unsigned new_height = y_factor * 144; - - SDL_Rect rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2, - new_width, new_height}; - SDL_RenderSetViewport(renderer, &rect); -} - -static void cycle_scaling(void) -{ - scaling_mode++; - scaling_mode %= GB_SDL_SCALING_MAX; - update_viewport(); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); -} - static void handle_events(GB_gameboy_t *gb) { #ifdef __APPLE__ @@ -169,11 +98,7 @@ static void handle_events(GB_gameboy_t *gb) exit(0); case SDL_DROPFILE: { - if (should_free_filename) { - SDL_free(filename); - } - filename = event.drop.file; - should_free_filename = true; + set_filename(filename, true); pending_command = GB_SDL_NEW_FILE_COMMAND; break; } @@ -236,7 +161,7 @@ static void handle_events(GB_gameboy_t *gb) break; } case SDLK_QUESTION: - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window); + show_help(); #endif default: @@ -495,55 +420,8 @@ usage: SDL_EventState(SDL_DROPFILE, SDL_ENABLE); if (filename == NULL) { - /* Draw the "Drop file" screen */ - SDL_Surface *drop_backround = SDL_LoadBMP(executable_relative_path("drop.bmp")); - SDL_Surface *drop_converted = SDL_ConvertSurface(drop_backround, pixel_format, 0); - SDL_LockSurface(drop_converted); - SDL_UpdateTexture(texture, NULL, drop_converted->pixels, drop_converted->pitch); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - SDL_FreeSurface(drop_converted); - SDL_FreeSurface(drop_backround); - SDL_Event event; - while (SDL_WaitEvent(&event)) - { - switch (event.type) { - case SDL_QUIT: { - exit(0); - } - case SDL_WINDOWEVENT: { - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - update_viewport(); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - } - break; - } - case SDL_DROPFILE: { - filename = event.drop.file; - should_free_filename = true; - goto start; - } - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_TAB) { - cycle_scaling(); - } -#ifndef __APPLE__ - else if (event.key.keysym.sym == SDLK_F1) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window); - } -#else - else if (event.key.keysym.sym == SDLK_QUESTION || (event.key.keysym.sym && (event.key.keysym.mod & KMOD_SHIFT))) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window); - } -#endif - break; - } - } + run_gui(); } -start: run(); // Never returns return 0; }