From e22b24b81ae63f29596eeae2fb2112e75e424f5b Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sun, 31 Dec 2023 17:00:46 +0100 Subject: [PATCH] First dummy input implementation --- Makefile | 2 + platform/ps2/emu.c | 41 +++++++ platform/ps2/in_ps2.c | 268 ++++++++++++++++++++++++++++++++++++++++++ platform/ps2/in_ps2.h | 6 + platform/ps2/plat.c | 12 -- 5 files changed, 317 insertions(+), 12 deletions(-) create mode 100644 platform/ps2/emu.c create mode 100644 platform/ps2/in_ps2.c create mode 100644 platform/ps2/in_ps2.h diff --git a/Makefile b/Makefile index 4174c294..cbed7900 100644 --- a/Makefile +++ b/Makefile @@ -239,6 +239,8 @@ ifeq "$(PLATFORM)" "ps2" CFLAGS += -DUSE_BGR555 # -DLOG_TO_FILE LDLIBS += -lpatches -lgskit -ldmakit -lps2_drivers OBJS += platform/ps2/plat.o +OBJS += platform/ps2/emu.o +OBJS += platform/ps2/in_ps2.o USE_FRONTEND = 1 endif ifeq "$(PLATFORM)" "libretro" diff --git a/platform/ps2/emu.c b/platform/ps2/emu.c new file mode 100644 index 00000000..4ff7f16a --- /dev/null +++ b/platform/ps2/emu.c @@ -0,0 +1,41 @@ +#include + +#include +#include +#include + +#include "in_ps2.h" +#include "../libpicofe/input.h" +#include "../common/input_pico.h" +#include "../common/emu.h" + +static struct in_default_bind in_ps2_defbinds[] = +{ + { PAD_UP, IN_BINDTYPE_PLAYER12, GBTN_UP }, + { PAD_DOWN, IN_BINDTYPE_PLAYER12, GBTN_DOWN }, + { PAD_LEFT, IN_BINDTYPE_PLAYER12, GBTN_LEFT }, + { PAD_RIGHT, IN_BINDTYPE_PLAYER12, GBTN_RIGHT }, + { PAD_SQUARE, IN_BINDTYPE_PLAYER12, GBTN_A }, + { PAD_CROSS, IN_BINDTYPE_PLAYER12, GBTN_B }, + { PAD_CIRCLE, IN_BINDTYPE_PLAYER12, GBTN_C }, + { PAD_START, IN_BINDTYPE_PLAYER12, GBTN_START }, + { PAD_TRIANGLE, IN_BINDTYPE_EMU, PEVB_SWITCH_RND }, + { PAD_L1, IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, + { PAD_R1, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, + { PAD_SELECT, IN_BINDTYPE_EMU, PEVB_MENU }, + { 0, 0, 0 } +}; + +void plat_init(void) +{ + init_joystick_driver(false); + in_ps2_init(in_ps2_defbinds); + in_probe(); + init_audio_driver(); + // plat_get_data_dir(rom_fname_loaded, sizeof(rom_fname_loaded)); +} + +void plat_finish(void) { + deinit_audio_driver(); + deinit_joystick_driver(false); +} \ No newline at end of file diff --git a/platform/ps2/in_ps2.c b/platform/ps2/in_ps2.c new file mode 100644 index 00000000..d58d514c --- /dev/null +++ b/platform/ps2/in_ps2.c @@ -0,0 +1,268 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "libpad.h" +#include "libmtap.h" + +#include "../libpicofe/input.h" +#include "in_ps2.h" + +#define IN_PS2_PREFIX "ps2:" +#define IN_PS2_NBUTTONS 32 +#define ANALOG_DEADZONE 80 + +/* note: in_ps2 handles combos (if 2 btns have the same bind, + * both must be pressed for action to happen) */ +static int in_ps2_combo_keys = 0; +static int in_ps2_combo_acts = 0; + +static uintptr_t padBuf[2][4]; +static uint32_t padConnected[2][4]; // 2 ports, 4 slots +static uint32_t padOpen[2][4]; +static uint32_t maxslot[2]; + + +static const char *in_ps2_keys[IN_PS2_NBUTTONS] = { + [0 ... IN_PS2_NBUTTONS-1] = NULL, +}; + + +/* calculate bit number from bit mask (logarithm to the basis 2) */ +static int lg2(unsigned v) +{ + /* credits to https://graphics.stanford.edu/~seander/bithacks.html */ + int r, s; + + r = (v > 0xFFFF) << 4; v >>= r; + s = (v > 0xFF ) << 3; v >>= s; r |= s; + s = (v > 0xF ) << 2; v >>= s; r |= s; + s = (v > 0x3 ) << 1; v >>= s; r |= s; + r |= (v >> 1); + return r; +} + +static unsigned int ps2_pad_read() +{ + unsigned int paddata; + struct padButtonStatus buttons; + int32_t ret, port, slot; + + + // Using for now port 0, slot 0 + port = 0; + slot = 0; + + ret = padRead(port, slot, &buttons); + + if (ret != 0) { + paddata = 0xffff ^ buttons.btns; + } + + // analog.. + // buttons &= ~(PS2_NUB_UP|PS2_NUB_DOWN|PS2_NUB_LEFT|PS2_NUB_RIGHT); + // if (pad.Lx < 128 - ANALOG_DEADZONE) buttons |= PS2_NUB_LEFT; + // if (pad.Lx > 128 + ANALOG_DEADZONE) buttons |= PS2_NUB_RIGHT; + // if (pad.Ly < 128 - ANALOG_DEADZONE) buttons |= PS2_NUB_UP; + // if (pad.Ly > 128 + ANALOG_DEADZONE) buttons |= PS2_NUB_DOWN; + + return paddata; +} + +static unsigned in_ps2_get_bits(void) +{ + unsigned mask = + PAD_UP|PAD_DOWN|PAD_LEFT|PAD_RIGHT | + PAD_CIRCLE|PAD_CROSS|PAD_TRIANGLE|PAD_SQUARE | + PAD_L1|PAD_R1|PAD_SELECT|PAD_START; + // PS2_NUB_UP|PS2_NUB_DOWN|PS2_NUB_LEFT|PS2_NUB_RIGHT | + + return ps2_pad_read() & mask; +} + +static void in_ps2_probe(const in_drv_t *drv) +{ + in_register(IN_PS2_PREFIX "PS2 pad", -1, NULL, + IN_PS2_NBUTTONS, in_ps2_keys, 1); +} + +static void in_ps2_free(void *drv_data) +{ + +} + +static const char * const * +in_ps2_get_key_names(const in_drv_t *drv, int *count) +{ + *count = IN_PS2_NBUTTONS; + return in_ps2_keys; +} + +/* ORs result with pressed buttons */ +static int in_ps2_update(void *drv_data, const int *binds, int *result) +{ + int type_start = 0; + int i, t; + unsigned keys; + + keys = in_ps2_get_bits(); + + if (keys & in_ps2_combo_keys) { + result[IN_BINDTYPE_EMU] = in_combos_do(keys, binds, IN_PS2_NBUTTONS, + in_ps2_combo_keys, in_ps2_combo_acts); + type_start = IN_BINDTYPE_PLAYER12; + } + + for (i = 0; keys; i++, keys >>= 1) { + if (!(keys & 1)) + continue; + + for (t = type_start; t < IN_BINDTYPE_COUNT; t++) + result[t] |= binds[IN_BIND_OFFS(i, t)]; + } + + return 0; +} + +int in_ps2_update_keycode(void *data, int *is_down) +{ + static unsigned old_val = 0; + unsigned val, diff, i; + + val = in_ps2_get_bits(); + diff = val ^ old_val; + if (diff == 0) + return -1; + + /* take one bit only */ + for (i = 0; i < sizeof(diff)*8; i++) + if (diff & (1< kc */ + keycode = -keycode; + for (i = 0; i < KEY_PBTN_MAP_SIZE; i++) + if (key_pbtn_map[i].pbtn == keycode) + return key_pbtn_map[i].key; + } + else + { + for (i = 0; i < KEY_PBTN_MAP_SIZE; i++) + if (key_pbtn_map[i].key == keycode) + return key_pbtn_map[i].pbtn; + } + + return 0; +} + +/* remove binds of missing keys, count remaining ones */ +static int in_ps2_clean_binds(void *drv_data, int *binds, int *def_binds) +{ + int i, count = 0; + + for (i = 0; i < IN_PS2_NBUTTONS; i++) { + int t, offs; + for (t = 0; t < IN_BINDTYPE_COUNT; t++) { + offs = IN_BIND_OFFS(i, t); + if (in_ps2_keys[i] == NULL) + binds[offs] = def_binds[offs] = 0; + if (binds[offs]) + count++; + } + } + + in_combos_find(binds, IN_PS2_NBUTTONS, &in_ps2_combo_keys, &in_ps2_combo_acts); + + return count; +} + +static const in_drv_t in_ps2_drv = { + .prefix = IN_PS2_PREFIX, + .probe = in_ps2_probe, + .free = in_ps2_free, + .get_key_names = in_ps2_get_key_names, + .clean_binds = in_ps2_clean_binds, + .update = in_ps2_update, + .update_keycode = in_ps2_update_keycode, + .menu_translate = in_ps2_menu_translate, +}; + +void in_ps2_init(struct in_default_bind *defbinds) +{ + int i, j; + + for (j = 0; j < 2; j++) { + mtapPortOpen(j); + + for (i = 0; i < 4; i++) { + padConnected[j][i] = 0; + padOpen[j][i] = 0; + padBuf[j][i] = memalign(64, 256); + padPortOpen(j, i, padBuf[j][i]); + } + } + + /* PS2 keys have bit masks, Picodrive wants bit numbers */ + for (i = 0; defbinds[i].code; i++) + defbinds[i].code = lg2(defbinds[i].code); + for (i = 0; i < KEY_PBTN_MAP_SIZE; i++) + key_pbtn_map[i].key = lg2(key_pbtn_map[i].key); + + in_ps2_combo_keys = in_ps2_combo_acts = 0; + + /* fill keys array, converting key bitmasks to bit numbers */ + in_ps2_keys[lg2(PAD_UP)] = "Up"; + in_ps2_keys[lg2(PAD_LEFT)] = "Left"; + in_ps2_keys[lg2(PAD_DOWN)] = "Down"; + in_ps2_keys[lg2(PAD_RIGHT)] = "Right"; + in_ps2_keys[lg2(PAD_START)] = "Start"; + in_ps2_keys[lg2(PAD_SELECT)] = "Select"; + in_ps2_keys[lg2(PAD_L1)] = "L1"; + in_ps2_keys[lg2(PAD_R1)] = "R1"; + in_ps2_keys[lg2(PAD_TRIANGLE)] = "Triangle"; + in_ps2_keys[lg2(PAD_CIRCLE)] = "Circle"; + in_ps2_keys[lg2(PAD_CROSS)] = "Cross"; + in_ps2_keys[lg2(PAD_SQUARE)] = "Square"; + // in_ps2_keys[lg2(PS2_NUB_UP)] = "Analog up"; + // in_ps2_keys[lg2(PS2_NUB_LEFT)] = "Analog left"; + // in_ps2_keys[lg2(PS2_NUB_DOWN)] = "Analog down"; + // in_ps2_keys[lg2(PS2_NUB_RIGHT)] = "Analog right"; + + in_register_driver(&in_ps2_drv, defbinds, NULL); +} + diff --git a/platform/ps2/in_ps2.h b/platform/ps2/in_ps2.h new file mode 100644 index 00000000..0f9bc8df --- /dev/null +++ b/platform/ps2/in_ps2.h @@ -0,0 +1,6 @@ + +struct in_default_bind; + +void in_ps2_init(struct in_default_bind *defbinds); + +void in_ps2_deinit(); diff --git a/platform/ps2/plat.c b/platform/ps2/plat.c index c3585dff..02b3d73d 100644 --- a/platform/ps2/plat.c +++ b/platform/ps2/plat.c @@ -45,18 +45,6 @@ static void deinit_drivers() { deinit_ps2_filesystem_driver(); } -void plat_init(void) -{ - init_joystick_driver(false); - init_audio_driver(); -} - - -void plat_finish(void) { - deinit_audio_driver(); - deinit_joystick_driver(false); -} - int plat_target_init(void) { return 0; -- 2.39.2