summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blastem.c169
-rw-r--r--blastem.h3
-rw-r--r--render.h15
-rw-r--r--render_sdl.c138
4 files changed, 199 insertions, 126 deletions
diff --git a/blastem.c b/blastem.c
index e6cf065..42d3479 100644
--- a/blastem.c
+++ b/blastem.c
@@ -988,6 +988,174 @@ m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_
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 @@ int main(int argc, char ** argv)
if (i < 0) {
strcpy(sram_filename + fname_size, ".sram");
}
+ set_keybindings();
init_run_cpu(&gen, debug, address_log);
return 0;
diff --git a/blastem.h b/blastem.h
index 351ad9f..fce42a4 100644
--- a/blastem.h
+++ b/blastem.h
@@ -35,6 +35,7 @@ typedef struct {
#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 @@ extern io_port gamepad_2;
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 --git a/render.h b/render.h
index 2696786..bcf0913 100644
--- a/render.h
+++ b/render.h
@@ -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 @@ int wait_render_frame(vdp_context * context, int frame_limit);
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 <SDL.h>
+#define RENDERKEY_UP SDLK_UP
+#define RENDERKEY_DOWN SDLK_DOWN
+#define RENDERKEY_LEFT SDLK_LEFT
+#define RENDERKEY_RIGHT SDLK_RIGHT
+
+#endif //RENDER_H_
diff --git a/render_sdl.c b/render_sdl.c
index 0ea68ff..084adaf 100644
--- a/render_sdl.c
+++ b/render_sdl.c
@@ -1,4 +1,3 @@
-#include <SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include "render.h"
@@ -299,135 +298,28 @@ void render_wait_quit(vdp_context * context)
}
}
-#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("");