# HG changeset patch # User Mike Pavone # Date 1371194704 25200 # Node ID c26e48a93fa33fe939f26e2e096c219e965c9c72 # Parent c20607e5b27273da82012f502ae032013c542771 Make keybindings data driven so they can be populated from a config file later diff -r c20607e5b272 -r c26e48a93fa3 blastem.c --- a/blastem.c Thu Jun 13 22:23:15 2013 -0700 +++ b/blastem.c Fri Jun 14 00:25:04 2013 -0700 @@ -988,6 +988,174 @@ return context; } +enum { + BIND_NONE, + BIND_GAMEPAD1, + BIND_GAMEPAD2, + BIND_UI +}; + +typedef enum { + UI_DEBUG_MODE_INC, + UI_DEBUG_PAL_INC, + UI_ENTER_DEBUGGER +} ui_action; + +typedef struct { + uint8_t bind_type; + uint8_t subtype_a; + uint8_t subtype_b; + uint8_t value; +} keybinding; + +keybinding * bindings[256]; + +void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + bindings[bucket] = malloc(sizeof(keybinding) * 256); + memset(bindings[bucket], 0, sizeof(keybinding) * 256); + } + int idx = keycode & 0xFF; + bindings[bucket][idx].bind_type = bind_type; + bindings[bucket][idx].subtype_a = subtype_a; + bindings[bucket][idx].subtype_b = subtype_b; + bindings[bucket][idx].value = value; +} + +#define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) + +#define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) +#define BUTTON_Z GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x01) +#define DPAD_DOWN GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x02) +#define BUTTON_Y GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x02) +#define DPAD_LEFT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x04) +#define BUTTON_X GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x04) +#define DPAD_RIGHT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x08) +#define BUTTON_MODE GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x08) +#define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10) +#define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10) +#define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20) +#define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20) + +void bind_gamepad(int keycode, int gamepadnum, int button) +{ + + if (gamepadnum < 1 || gamepadnum > 2) { + return; + } + uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; + bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); +} + +void bind_ui(int keycode, ui_action action) +{ + bind_key(keycode, BIND_UI, action, 0, 0); +} + +void handle_keydown(int keycode) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + return; + } + int idx = keycode & 0xFF; + keybinding * binding = bindings[bucket] + idx; + switch(binding->bind_type) + { + case BIND_GAMEPAD1: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + gamepad_1.input[binding->subtype_a] |= binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + gamepad_1.input[binding->subtype_b] |= binding->value; + } + break; + case BIND_GAMEPAD2: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + gamepad_2.input[binding->subtype_a] |= binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + gamepad_2.input[binding->subtype_b] |= binding->value; + } + break; + } +} + +uint8_t ui_debug_mode = 0; +uint8_t ui_debug_pal = 0; + +void handle_keyup(int keycode) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + return; + } + int idx = keycode & 0xFF; + keybinding * binding = bindings[bucket] + idx; + switch(binding->bind_type) + { + case BIND_GAMEPAD1: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + gamepad_1.input[binding->subtype_a] &= ~binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + gamepad_1.input[binding->subtype_b] &= ~binding->value; + } + break; + case BIND_GAMEPAD2: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + gamepad_2.input[binding->subtype_a] &= ~binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + gamepad_2.input[binding->subtype_b] &= ~binding->value; + } + break; + case BIND_UI: + switch (binding->subtype_a) + { + case UI_DEBUG_MODE_INC: + ui_debug_mode++; + if (ui_debug_mode == 4) { + ui_debug_mode = 0; + } + render_debug_mode(ui_debug_mode); + break; + case UI_DEBUG_PAL_INC: + ui_debug_pal++; + if (ui_debug_pal == 4) { + ui_debug_pal = 0; + } + render_debug_pal(ui_debug_pal); + break; + case UI_ENTER_DEBUGGER: + break_on_sync = 1; + break; + } + break; + } +} + +void set_keybindings() +{ + bind_gamepad(RENDERKEY_UP, 1, DPAD_UP); + bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN); + bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT); + bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT); + bind_gamepad('a', 1, BUTTON_A); + bind_gamepad('s', 1, BUTTON_B); + bind_gamepad('d', 1, BUTTON_C); + bind_gamepad('q', 1, BUTTON_X); + bind_gamepad('w', 1, BUTTON_Y); + bind_gamepad('e', 1, BUTTON_Z); + bind_gamepad('\r', 1, BUTTON_START); + bind_gamepad('f', 1, BUTTON_MODE); + bind_ui('[', UI_DEBUG_MODE_INC); + bind_ui(']', UI_DEBUG_PAL_INC); + bind_ui('u', UI_ENTER_DEBUGGER); +} + typedef struct bp_def { struct bp_def * next; uint32_t address; @@ -2000,6 +2168,7 @@ if (i < 0) { strcpy(sram_filename + fname_size, ".sram"); } + set_keybindings(); init_run_cpu(&gen, debug, address_log); return 0; diff -r c20607e5b272 -r c26e48a93fa3 blastem.h --- a/blastem.h Thu Jun 13 22:23:15 2013 -0700 +++ b/blastem.h Fri Jun 14 00:25:04 2013 -0700 @@ -35,6 +35,7 @@ #define GAMEPAD_TH0 0 #define GAMEPAD_TH1 1 #define GAMEPAD_EXTRA 2 +#define GAMEPAD_NONE 0xF extern io_port gamepad_1; extern io_port gamepad_2; @@ -42,6 +43,8 @@ void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction); uint16_t read_dma_value(uint32_t address); m68k_context * debugger(m68k_context * context, uint32_t address); +void handle_keydown(int keycode); +void handle_keyup(int keycode); #endif //BLASTEM_H_ diff -r c20607e5b272 -r c26e48a93fa3 render.h --- a/render.h Thu Jun 13 22:23:15 2013 -0700 +++ b/render.h Fri Jun 14 00:25:04 2013 -0700 @@ -1,5 +1,5 @@ -#ifndef RENDER_SDL_H_ -#define RENDER_SDL_H_ +#ifndef RENDER_H_ +#define RENDER_H_ #include "vdp.h" #include "psg.h" @@ -13,6 +13,15 @@ void render_fps(uint32_t fps); uint32_t render_audio_buffer(); uint32_t render_sample_rate(); +void render_debug_mode(uint8_t mode); +void render_debug_pal(uint8_t pal); -#endif //RENDER_SDL_H_ +//TODO: Throw an ifdef in here once there's more than one renderer +#include +#define RENDERKEY_UP SDLK_UP +#define RENDERKEY_DOWN SDLK_DOWN +#define RENDERKEY_LEFT SDLK_LEFT +#define RENDERKEY_RIGHT SDLK_RIGHT +#endif //RENDER_H_ + diff -r c20607e5b272 -r c26e48a93fa3 render_sdl.c --- a/render_sdl.c Thu Jun 13 22:23:15 2013 -0700 +++ b/render_sdl.c Fri Jun 14 00:25:04 2013 -0700 @@ -1,4 +1,3 @@ -#include #include #include #include "render.h" @@ -299,135 +298,28 @@ } } -#define DPAD_UP 0x01 -#define BUTTON_Z 0x01 -#define DPAD_DOWN 0x02 -#define BUTTON_Y 0x02 -#define DPAD_LEFT 0x04 -#define BUTTON_X 0x04 -#define DPAD_RIGHT 0x08 -#define BUTTON_MODE 0x08 -#define BUTTON_A 0x10 -#define BUTTON_B 0x10 -#define BUTTON_START 0x20 -#define BUTTON_C 0x20 +void render_debug_mode(uint8_t mode) +{ + if (mode < 4) { + render_dbg = mode; + } +} + +void render_debug_pal(uint8_t pal) +{ + if (pal < 4) { + debug_pal = pal; + } +} int32_t handle_event(SDL_Event *event) { - FILE * outfile; switch (event->type) { case SDL_KEYDOWN: - switch(event->key.keysym.sym) - { - case SDLK_LEFTBRACKET: - render_dbg++; - if (render_dbg == 4) { - render_dbg = 0; - } - break; - case SDLK_RIGHTBRACKET: - debug_pal++; - if (debug_pal == 4) { - debug_pal = 0; - } - break; - case SDLK_t: - /*outfile = fopen("state.gst", "wb"); - fwrite("GST\0\0\0\xE0\x40", 1, 8, outfile); - vdp_save_state(context, outfile); - fclose(outfile); - puts("state saved to state.gst");*/ - break; - case SDLK_u: - return 1; - case SDLK_RETURN: - gamepad_1.input[GAMEPAD_TH0] |= BUTTON_START; - break; - case SDLK_UP: - gamepad_1.input[GAMEPAD_TH0] |= DPAD_UP; - gamepad_1.input[GAMEPAD_TH1] |= DPAD_UP; - break; - case SDLK_DOWN: - gamepad_1.input[GAMEPAD_TH0] |= DPAD_DOWN; - gamepad_1.input[GAMEPAD_TH1] |= DPAD_DOWN; - break; - case SDLK_LEFT: - gamepad_1.input[GAMEPAD_TH1] |= DPAD_LEFT; - break; - case SDLK_RIGHT: - gamepad_1.input[GAMEPAD_TH1] |= DPAD_RIGHT; - break; - case SDLK_a: - gamepad_1.input[GAMEPAD_TH0] |= BUTTON_A; - //printf("BUTTON_A Dn | GAMEPAD_TH0: %X\n", gamepad_1.input[GAMEPAD_TH0]); - break; - case SDLK_s: - gamepad_1.input[GAMEPAD_TH1] |= BUTTON_B; - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_B; - break; - case SDLK_d: - gamepad_1.input[GAMEPAD_TH1] |= BUTTON_C; - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_C; - break; - case SDLK_q: - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_X; - break; - case SDLK_w: - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_Y; - break; - case SDLK_e: - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_Z; - break; - case SDLK_f: - gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_MODE; - break; - } + handle_keydown(event->key.keysym.sym); break; case SDL_KEYUP: - switch(event->key.keysym.sym) - { - case SDLK_RETURN: - gamepad_1.input[GAMEPAD_TH0] &= ~BUTTON_START; - break; - case SDLK_UP: - gamepad_1.input[GAMEPAD_TH0] &= ~DPAD_UP; - gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_UP; - break; - case SDLK_DOWN: - gamepad_1.input[GAMEPAD_TH0] &= ~DPAD_DOWN; - gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_DOWN; - break; - case SDLK_LEFT: - gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_LEFT; - break; - case SDLK_RIGHT: - gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_RIGHT; - break; - case SDLK_a: - gamepad_1.input[GAMEPAD_TH0] &= ~BUTTON_A; - //printf("BUTTON_A Up | GAMEPAD_TH0: %X\n", gamepad_1.input[GAMEPAD_TH0]); - break; - case SDLK_s: - gamepad_1.input[GAMEPAD_TH1] &= ~BUTTON_B; - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_B; - break; - case SDLK_d: - gamepad_1.input[GAMEPAD_TH1] &= ~BUTTON_C; - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_C; - break; - case SDLK_q: - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_X; - break; - case SDLK_w: - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_Y; - break; - case SDLK_e: - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_Z; - break; - case SDLK_f: - gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_MODE; - break; - } + handle_keyup(event->key.keysym.sym); break; case SDL_QUIT: puts("");