diff --git a/include/input.h b/include/input.h index d36c83f..bc268f9 100644 --- a/include/input.h +++ b/include/input.h @@ -140,6 +140,8 @@ extern bool keyboard_focus; void handle_events(void); bool key_is_down(enum sact_keycode code); void key_clear_flag(void); +bool joy_key_is_down(uint8_t code); +void joy_clear_flag(void); void mouse_get_pos(int *x, int *y); void mouse_set_pos(int x, int y); void mouse_get_wheel(int *forward, int *back); diff --git a/include/xsystem4.h b/include/xsystem4.h index 812e080..eb66711 100644 --- a/include/xsystem4.h +++ b/include/xsystem4.h @@ -18,6 +18,7 @@ #define XSYSTEM4_H #include +#include struct config { char *game_name; @@ -32,6 +33,8 @@ struct config { char *bgi_path; char *wai_path; + + bool joypad; }; extern struct config config; diff --git a/src/asset_manager.c b/src/asset_manager.c index ce99217..51ff512 100644 --- a/src/asset_manager.c +++ b/src/asset_manager.c @@ -180,8 +180,6 @@ void asset_manager_init(void) } } - NOTICE("%d CG archives", ald_count[ASSET_CG]); - // open ALD archives ald_init(ASSET_BGM, ald_filenames[ASSET_BGM], ald_count[ASSET_BGM]); ald_init(ASSET_SOUND, ald_filenames[ASSET_SOUND], ald_count[ASSET_SOUND]); diff --git a/src/hll/SACT2.c b/src/hll/SACT2.c index 24bb86c..664513f 100644 --- a/src/hll/SACT2.c +++ b/src/hll/SACT2.c @@ -655,12 +655,13 @@ int sact_Mouse_SetPos(int x, int y) void sact_Joypad_ClearKeyDownFlag(int n) { - // TODO + joy_clear_flag(); } int sact_Joypad_IsKeyDown(int num, int key) { - return 0; // TODO + handle_events(); + return joy_key_is_down(key); } //int SACT2_Joypad_GetNumof(void); diff --git a/src/input.c b/src/input.c index 73884e2..053bc6b 100644 --- a/src/input.c +++ b/src/input.c @@ -22,6 +22,7 @@ #include "vm.h" bool key_state[VK_NR_KEYCODES]; +bool joybutton_state[SDL_CONTROLLER_BUTTON_MAX]; static enum sact_keycode sdl_keytable[] = { [SDL_SCANCODE_0] = VK_0, [SDL_SCANCODE_1] = VK_1, @@ -134,6 +135,9 @@ static enum sact_keycode sdl_keytable[] = { bool mouse_focus = true; bool keyboard_focus = true; +#define MAX_CONTROLLERS 4 +static SDL_GameController *controllers[MAX_CONTROLLERS]; + static enum sact_keycode sdl_to_sact_button(int button) { switch (button) { @@ -153,6 +157,39 @@ bool key_is_down(enum sact_keycode code) return key_state[code]; } +bool joy_key_is_down(uint8_t code) +{ + // Default SACT key mapping in comments below + switch (code) { + case 1: // Left Arrow + return joybutton_state[SDL_CONTROLLER_BUTTON_DPAD_LEFT]; + case 2: // Right Arrow + return joybutton_state[SDL_CONTROLLER_BUTTON_DPAD_RIGHT]; + case 3: // Up Arrow + return joybutton_state[SDL_CONTROLLER_BUTTON_DPAD_UP]; + case 4: // Down Arrow + return joybutton_state[SDL_CONTROLLER_BUTTON_DPAD_DOWN]; + case 5: // Esc + return joybutton_state[SDL_CONTROLLER_BUTTON_BACK] || joybutton_state[SDL_CONTROLLER_BUTTON_START]; + case 6: // Enter + return joybutton_state[SDL_CONTROLLER_BUTTON_A]; + case 7: // Space + return joybutton_state[SDL_CONTROLLER_BUTTON_Y]; + case 8: // Ctrl + return joybutton_state[SDL_CONTROLLER_BUTTON_B]; + case 9: // a + return joybutton_state[SDL_CONTROLLER_BUTTON_LEFTSTICK]; + case 10: // z + return joybutton_state[SDL_CONTROLLER_BUTTON_RIGHTSTICK]; + case 11: // Page Up + return joybutton_state[SDL_CONTROLLER_BUTTON_LEFTSHOULDER]; + case 12: // Page Down + return joybutton_state[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER]; + default: + return false; + } +} + void key_clear_flag(void) { for (int i = 0; i < VK_NR_KEYCODES; i++) { @@ -160,8 +197,16 @@ void key_clear_flag(void) } } +void joy_clear_flag(void) +{ + for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) { + joybutton_state[i] = false; + } +} + void mouse_get_pos(int *x, int *y) { + SDL_PumpEvents(); SDL_GetMouseState(x, y); } @@ -199,6 +244,14 @@ static void mouse_event(SDL_MouseButtonEvent *e) key_state[code] = e->state == SDL_PRESSED; } +static void controller_button_event(SDL_ControllerButtonEvent *e) +{ + if (e->state != SDL_PRESSED) { + NOTICE("UNPRESSED"); + } + joybutton_state[e->button] = e->state == SDL_PRESSED; +} + static void(*input_handler)(const char*); static void(*editing_handler)(const char*, int, int); @@ -264,6 +317,14 @@ void handle_events(void) case SDL_MOUSEWHEEL: wheel_dir = e.wheel.y; break; + case SDL_CONTROLLERDEVICEADDED: + if (e.cdevice.which < MAX_CONTROLLERS) + controllers[e.cdevice.which] = SDL_GameControllerOpen(e.cdevice.which); + break; + case SDL_CONTROLLERBUTTONUP: + case SDL_CONTROLLERBUTTONDOWN: + controller_button_event(&e.cbutton); + break; case SDL_TEXTINPUT: if (input_handler) input_handler(e.text.text); diff --git a/src/system4.c b/src/system4.c index 4eedc4e..76ae709 100644 --- a/src/system4.c +++ b/src/system4.c @@ -51,6 +51,7 @@ struct config config = { .view_height = 600, .mixer_nr_channels = 0, .mixer_channels = NULL, + .joypad = false, }; char *unix_path(const char *path) @@ -348,9 +349,10 @@ static void usage(void) puts(" -a, --audit Audit AIN file for xsystem4 compatibility"); puts(" --font-mincho Specify the path to the mincho font to use"); puts(" --font-gothic Specify the path to the gothic font to use"); + puts(" -j, --joypad Enable joypad"); puts(" --nodebug Disable debugger"); #ifdef DEBUGGER_ENABLED - puts(" --debug Start in debugger"); + puts(" --debug Start in debugger"); #endif } @@ -359,6 +361,7 @@ enum { LOPT_AUDIT, LOPT_FONT_MINCHO, LOPT_FONT_GOTHIC, + LOPT_JOYPAD, LOPT_NODEBUG, #ifdef DEBUGGER_ENABLED LOPT_DEBUG, @@ -384,13 +387,14 @@ int main(int argc, char *argv[]) { "audit", no_argument, 0, LOPT_AUDIT }, { "font-mincho", required_argument, 0, LOPT_FONT_MINCHO }, { "font-gothic", required_argument, 0, LOPT_FONT_GOTHIC }, + { "joypad", no_argument, 0, LOPT_JOYPAD }, { "nodebug", no_argument, 0, LOPT_NODEBUG }, #ifdef DEBUGGER_ENABLED { "debug", no_argument, 0, LOPT_DEBUG }, #endif }; int option_index = 0; - int c = getopt_long(argc, argv, "ha", long_options, &option_index); + int c = getopt_long(argc, argv, "haj", long_options, &option_index); if (c == -1) break; @@ -409,6 +413,10 @@ int main(int argc, char *argv[]) case LOPT_FONT_GOTHIC: font_gothic = optarg; break; + case 'j': + case LOPT_JOYPAD: + config.joypad = true; + break; #ifdef DEBUGGER_ENABLED case LOPT_NODEBUG: dbg_enabled = false; diff --git a/src/video.c b/src/video.c index 5bcaed5..cbfb3e5 100644 --- a/src/video.c +++ b/src/video.c @@ -175,7 +175,10 @@ static int gl_initialize(void) int gfx_init(void) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) + uint32_t flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO; + if (config.joypad) + flags |= SDL_INIT_GAMECONTROLLER; + if (SDL_Init(flags) < 0) ERROR("SDL_Init failed: %s", SDL_GetError()); #ifdef USE_GLES diff --git a/subprojects/libsys4 b/subprojects/libsys4 index 7b6fd0b..a397645 160000 --- a/subprojects/libsys4 +++ b/subprojects/libsys4 @@ -1 +1 @@ -Subproject commit 7b6fd0b3ba0d789b3928f8db4b8f0a6f9801b98e +Subproject commit a3976458d45940f0d72c1b7b67824e0531320baa