From 53cdc9bff39fec645a94975e489b9e04525297a3 Mon Sep 17 00:00:00 2001 From: valentecaio Date: Fri, 17 Jul 2020 16:25:42 -0300 Subject: [PATCH] multiplayer working with default button mapping and USB joystick for player 2 --- src/misc.cpp | 4 +- src/pad.cpp | 46 +++---- src/plugin_lib/plugin_lib.cpp | 2 +- src/port/sdl/frontend.cpp | 11 +- src/port/sdl/port.cpp | 229 ++++++++++++++++++---------------- src/port/sdl/port.h | 7 +- 6 files changed, 162 insertions(+), 137 deletions(-) diff --git a/src/misc.cpp b/src/misc.cpp index 7131fa12..cf5391e3 100755 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -783,7 +783,7 @@ int SaveState(const char *file) { || mdecFreeze(f, FREEZE_SAVE) ) goto error; - if (freeze_rw(f, FREEZE_SAVE, &player_controller[0], sizeof(struct ps1_controller))) + if (freeze_rw(f, FREEZE_SAVE, &controllers[0], sizeof(struct ps1_controller))) goto error; if (SaveFuncs.close(f)) { @@ -900,7 +900,7 @@ int LoadState(const char *file) { mdecFreeze(f, FREEZE_LOAD) ) goto error; - if (freeze_rw(f, FREEZE_LOAD, &player_controller[0], sizeof(struct ps1_controller))) + if (freeze_rw(f, FREEZE_LOAD, &controllers[0], sizeof(struct ps1_controller))) { goto error; } diff --git a/src/pad.cpp b/src/pad.cpp index 51e84059..3819cdb8 100755 --- a/src/pad.cpp +++ b/src/pad.cpp @@ -105,7 +105,7 @@ unsigned char PAD1_poll(unsigned char value) { // Don't enable Analog/Vibration for a Digital or DualAnalog controller CurCmd = value; g.CurByte1++; - if (player_controller[0].pad_controllertype != PSE_PAD_TYPE_ANALOGPAD) { + if (controllers[0].pad_controllertype != PSE_PAD_TYPE_ANALOGPAD) { CurCmd = CMD_READ_DATA_AND_VIBRATE; } g.CmdLen1 = 8; @@ -116,7 +116,7 @@ unsigned char PAD1_poll(unsigned char value) { return 0xF3; case CMD_QUERY_MODEL_AND_MODE: buf = stdmodel; - buf[4] = player_controller[0].pad_mode; + buf[4] = controllers[0].pad_mode; return 0xF3; case CMD_QUERY_ACT: buf = unk46; @@ -131,7 +131,7 @@ unsigned char PAD1_poll(unsigned char value) { buf = unk4d; return 0xF3; case CMD_CONFIG_MODE: - if (player_controller[0].configmode) { + if (controllers[0].configmode) { buf = stdcfg; return 0xF3; } @@ -147,18 +147,18 @@ unsigned char PAD1_poll(unsigned char value) { * and Dualshock features won't work. * */ - if (player_controller[0].pad_mode == 1) { - buf[4] = player_controller[0].joy_right_ax0; - buf[5] = player_controller[0].joy_right_ax1; - buf[6] = player_controller[0].joy_left_ax0; - buf[7] = player_controller[0].joy_left_ax1; + if (controllers[0].pad_mode == 1) { + buf[4] = controllers[0].joy_right_ax0; + buf[5] = controllers[0].joy_right_ax1; + buf[6] = controllers[0].joy_left_ax0; + buf[7] = controllers[0].joy_left_ax1; } else { g.CmdLen1 = 4; } - return player_controller[0].id; + return controllers[0].id; } } @@ -168,12 +168,12 @@ unsigned char PAD1_poll(unsigned char value) { if (g.CurByte1 == 2) { switch (CurCmd) { case CMD_CONFIG_MODE: - player_controller[0].configmode = value; + controllers[0].configmode = value; break; case CMD_SET_MODE_AND_LOCK: - player_controller[0].pad_mode = value; - player_controller[0].id = value ? 0x73 : 0x41; + controllers[0].pad_mode = value; + controllers[0].id = value ? 0x73 : 0x41; break; case CMD_QUERY_ACT: @@ -205,25 +205,25 @@ unsigned char PAD1_poll(unsigned char value) { } } - if (player_controller[0].pad_controllertype == PSE_PAD_TYPE_ANALOGPAD) + if (controllers[0].pad_controllertype == PSE_PAD_TYPE_ANALOGPAD) { switch (CurCmd) { case CMD_READ_DATA_AND_VIBRATE: - if (g.CurByte1 == player_controller[0].Vib[0]) { - player_controller[0].VibF[0] = value; + if (g.CurByte1 == controllers[0].Vib[0]) { + controllers[0].VibF[0] = value; #ifdef RUMBLE - if (player_controller[0].VibF[0] != 0) { + if (controllers[0].VibF[0] != 0) { Shake_Play(device, id_shake_level[3]); } #endif } - if (g.CurByte1 == player_controller[0].Vib[1]) { - player_controller[0].VibF[1] = value; + if (g.CurByte1 == controllers[0].Vib[1]) { + controllers[0].VibF[1] = value; #ifdef RUMBLE - if (player_controller[0].VibF[1] != 0) { + if (controllers[0].VibF[1] != 0) { Shake_Play(device, id_shake_level[value>>4]); } #endif @@ -232,13 +232,13 @@ unsigned char PAD1_poll(unsigned char value) { break; case CMD_VIBRATION_TOGGLE: for (uint8_t i = 0; i < 2; i++) { - if (player_controller[0].Vib[i] == g.CurByte1) + if (controllers[0].Vib[i] == g.CurByte1) buf[g.CurByte1] = 0; } if (value < 2) { - player_controller[0].Vib[value] = g.CurByte1; - if ((player_controller[0].id & 0x0f) < (g.CurByte1 - 1) / 2) { - player_controller[0].id = (player_controller[0].id & 0xf0) + (g.CurByte1 - 1) / 2; + controllers[0].Vib[value] = g.CurByte1; + if ((controllers[0].id & 0x0f) < (g.CurByte1 - 1) / 2) { + controllers[0].id = (controllers[0].id & 0xf0) + (g.CurByte1 - 1) / 2; } } break; diff --git a/src/plugin_lib/plugin_lib.cpp b/src/plugin_lib/plugin_lib.cpp index 09003dbc..c5724549 100755 --- a/src/plugin_lib/plugin_lib.cpp +++ b/src/plugin_lib/plugin_lib.cpp @@ -204,5 +204,5 @@ static void pl_stats_update(void) (unsigned int)(pl_data.cpu_cur + 0.5f), (unsigned int)(pl_data.fps_cur + 0.5f), pl_data.sinfo.pal ? 50 : 60, - player_controller[0].pad_mode?"A":"D"); + controllers[0].pad_mode?"A":"D"); } diff --git a/src/port/sdl/frontend.cpp b/src/port/sdl/frontend.cpp index 486eecc1..f900ad5c 100755 --- a/src/port/sdl/frontend.cpp +++ b/src/port/sdl/frontend.cpp @@ -83,6 +83,7 @@ static unsigned int key_read(void) default: break; } break; + case SDL_KEYUP: switch(event.key.keysym.sym) { case SDLK_UP: ret &= ~KEY_UP; break; @@ -105,6 +106,11 @@ static unsigned int key_read(void) default: break; } break; + + case SDL_JOYBUTTONDOWN: + // external joysticks + ret |= KEY_B; break; + default: break; } } @@ -1205,10 +1211,9 @@ static char* AnalogArrow_show() return buf; } -extern void Set_Controller_Mode(); +extern void Set_Controller_Mode(uint_fast8_t js); static int Analog_Mode_alter(u32 keys) { - if (keys & KEY_RIGHT) { Config.AnalogMode++; if (Config.AnalogMode > 3) Config.AnalogMode = 3; @@ -1216,7 +1221,7 @@ static int Analog_Mode_alter(u32 keys) Config.AnalogMode--; if (Config.AnalogMode < 1) Config.AnalogMode = 0; } - Set_Controller_Mode(); + Set_Controller_Mode(0); return 0; } diff --git a/src/port/sdl/port.cpp b/src/port/sdl/port.cpp index 976236ca..13d5daaf 100755 --- a/src/port/sdl/port.cpp +++ b/src/port/sdl/port.cpp @@ -57,26 +57,6 @@ enum { DKEY_TOTAL }; -// the index is the SDL id of the button -uint8_t joystick_config[] = { - DKEY_TRIANGLE, // 0 - DKEY_CIRCLE, - DKEY_CROSS, - DKEY_SQUARE, - DKEY_L1, - DKEY_R1, - DKEY_L2, - DKEY_R2, - DKEY_SELECT, - DKEY_START, - DKEY_L3, - DKEY_R3, - DKEY_UP, // 12 - DKEY_RIGHT, // 13 - DKEY_DOWN, // 14 - DKEY_LEFT // 15 -}; - static SDL_Surface *screen; unsigned short *SCREEN; int SCREEN_WIDTH = 640, SCREEN_HEIGHT = 480; @@ -579,16 +559,10 @@ static struct { { 0, 0 } }; -static uint16_t pad1 = 0xFFFF; - -static uint16_t pad2 = 0xFFFF; - -static uint16_t pad1_buttons = 0xFFFF; - -static unsigned short analog1 = 0; - -// 0 for native sticks, 1 for external js1, 2 for external js2 -SDL_Joystick* sdl_joy[3]; +// 0 for player 1, 1 for player 2 +static uint16_t pads[2] = {0xFFFF, 0xFFFF}; +static uint16_t pad_buttons[2] = {0xFFFF, 0xFFFF}; +static unsigned short analogs[2] = {0, 0}; #define joy_commit_range 8192 enum { @@ -598,58 +572,83 @@ enum { ANALOG_RIGHT = 8 }; -struct ps1_controller player_controller[2]; +// 0 for native buttons/sticks, 1 for external js1, 2 for external js2 +struct ps1_controller controllers[3]; -void Set_Controller_Mode() +void Set_Controller_Mode(uint_fast8_t i) { switch (Config.AnalogMode) { /* Digital. Required for some games. */ - default: player_controller[0].id = 0x41; - player_controller[0].pad_mode = 0; - player_controller[0].pad_controllertype = PSE_PAD_TYPE_STANDARD; + default: controllers[i].id = 0x41; + controllers[i].pad_mode = 0; + controllers[i].pad_controllertype = PSE_PAD_TYPE_STANDARD; break; /* DualAnalog. Some games might misbehave with Dualshock like Descent so this is for those */ - case 1: player_controller[0].id = 0x53; - player_controller[0].pad_mode = 1; - player_controller[0].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; + case 1: controllers[i].id = 0x53; + controllers[i].pad_mode = 1; + controllers[i].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; break; /* DualShock, required for Ape Escape. */ case 2: - player_controller[0].id = 0x41; - player_controller[0].pad_mode = 0; - player_controller[0].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; + controllers[i].id = 0x41; + controllers[i].pad_mode = 0; + controllers[i].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; break; case 3: - player_controller[0].id = 0x73; - player_controller[0].pad_mode = 1; - player_controller[0].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; + controllers[i].id = 0x73; + controllers[i].pad_mode = 1; + controllers[i].pad_controllertype = PSE_PAD_TYPE_ANALOGPAD; break; } } +void joy_map_read(uint8_t i) { + controllers[0].player = 0; + controllers[1].player = 1; + controllers[i].but_map[0] = DKEY_TRIANGLE; + controllers[i].but_map[1] = DKEY_CIRCLE; + controllers[i].but_map[2] = DKEY_CROSS; + controllers[i].but_map[3] = DKEY_SQUARE; + controllers[i].but_map[4] = DKEY_L1; + controllers[i].but_map[5] = DKEY_R1; + controllers[i].but_map[6] = DKEY_L2; + controllers[i].but_map[7] = DKEY_R2; + controllers[i].but_map[8] = DKEY_SELECT; + controllers[i].but_map[9] = DKEY_START; + controllers[i].but_map[10] = DKEY_L3; + controllers[i].but_map[11] = DKEY_R3; + controllers[i].but_map[12] = DKEY_UP; + controllers[i].but_map[13] = DKEY_RIGHT; + controllers[i].but_map[14] = DKEY_DOWN; + controllers[i].but_map[15] = DKEY_LEFT; +} + void joy_init() { - sdl_joy[0] = SDL_JoystickOpen(0); - sdl_joy[1] = SDL_JoystickOpen(1); - sdl_joy[2] = SDL_JoystickOpen(2); + for(uint8_t i = 0; i<3; i++) { + // init SDL joystick + controllers[i].sdl_joy = SDL_JoystickOpen(i); - player_controller[0].joy_left_ax0 = 127; - player_controller[0].joy_left_ax1 = 127; - player_controller[0].joy_right_ax0 = 127; - player_controller[0].joy_right_ax1 = 127; + // init analog axis + controllers[i].joy_left_ax0 = 127; + controllers[i].joy_left_ax1 = 127; + controllers[i].joy_right_ax0 = 127; + controllers[i].joy_right_ax1 = 127; - player_controller[0].Vib[0] = 0; - player_controller[0].Vib[1] = 0; - player_controller[0].VibF[0] = 0; - player_controller[0].VibF[1] = 0; + // init vibration + controllers[i].Vib[0] = 0; + controllers[i].Vib[1] = 0; + controllers[i].VibF[0] = 0; + controllers[i].VibF[1] = 0; - //player_controller[0].id = 0x41; - //player_controller[0].pad_mode = 0; - //player_controller[0].pad_controllertype = 0; + controllers[i].configmode = 0; - player_controller[0].configmode = 0; + // config analog mode according to game + Set_Controller_Mode(i); - Set_Controller_Mode(); + // read button mapping + joy_map_read(i); + } } void pad_update() @@ -658,6 +657,7 @@ void pad_update() SDL_Event event; bool popup_menu = false; uint_fast8_t i; + struct ps1_controller *controller; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -685,7 +685,7 @@ void pad_update() for (i = 0; i < DKEY_TOTAL; i++) if (event.key.keysym.sym == keymap[i].key) { - pad1_buttons &= ~(1 << keymap[i].bit); + pad_buttons[0] &= ~(1 << keymap[i].bit); break; } break; @@ -697,93 +697,107 @@ void pad_update() for (i = 0; i < DKEY_TOTAL; i++) if (event.key.keysym.sym == keymap[i].key) { - pad1_buttons |= (1 << keymap[i].bit); + pad_buttons[0] |= (1 << keymap[i].bit); break; } break; // analog sticks case SDL_JOYAXISMOTION: - pad1_buttons |= (1 << DKEY_UP); - pad1_buttons |= (1 << DKEY_DOWN); - pad1_buttons |= (1 << DKEY_LEFT); - pad1_buttons |= (1 << DKEY_RIGHT); + controllers[0].player = 0; // WHY ? + controllers[1].player = 1; + controller = &controllers[event.jaxis.which]; + axisval = event.jaxis.value; + + // printf("AXIS event.jaxis.value %d\n", event.jaxis.value); + // printf("AXIS event.jaxis.which %d\n", event.jaxis.which); + // printf("AXIS controller->player %d\n\n", controller->player); + + pad_buttons[controller->player] |= (1 << DKEY_UP); + pad_buttons[controller->player] |= (1 << DKEY_DOWN); + pad_buttons[controller->player] |= (1 << DKEY_LEFT); + pad_buttons[controller->player] |= (1 << DKEY_RIGHT); switch (event.jaxis.axis) { case 0: /* X axis */ - axisval = event.jaxis.value; if (Config.AnalogArrow == 1) { - analog1 &= ~(ANALOG_LEFT | ANALOG_RIGHT); + analogs[controller->player] &= ~(ANALOG_LEFT | ANALOG_RIGHT); if (axisval > joy_commit_range) { - analog1 |= ANALOG_RIGHT; + analogs[controller->player] |= ANALOG_RIGHT; } else if (axisval < -joy_commit_range) { - analog1 |= ANALOG_LEFT; + analogs[controller->player] |= ANALOG_LEFT; } } else { - player_controller[0].joy_left_ax0 = (axisval + 0x8000) >> 8; + controller->joy_left_ax0 = (axisval + 0x8000) >> 8; } break; case 1: /* Y axis */ - axisval = event.jaxis.value; if (Config.AnalogArrow == 1) { - analog1 &= ~(ANALOG_UP | ANALOG_DOWN); + analogs[controller->player] &= ~(ANALOG_UP | ANALOG_DOWN); if (axisval > joy_commit_range) { - analog1 |= ANALOG_DOWN; + analogs[controller->player] |= ANALOG_DOWN; } else if (axisval < -joy_commit_range) { - analog1 |= ANALOG_UP; + analogs[controller->player] |= ANALOG_UP; } } else { - player_controller[0].joy_left_ax1 = (axisval + 0x8000) >> 8; + controller->joy_left_ax1 = (axisval + 0x8000) >> 8; } break; case 2: /* X axis */ - axisval = event.jaxis.value; - player_controller[0].joy_right_ax0 = (axisval + 0x8000) >> 8; + controller->joy_right_ax0 = (axisval + 0x8000) >> 8; break; case 3: /* Y axis */ - axisval = event.jaxis.value; - player_controller[0].joy_right_ax1 = (axisval + 0x8000) >> 8; + controller->joy_right_ax1 = (axisval + 0x8000) >> 8; break; } break; // USB joystick buttons case SDL_JOYBUTTONDOWN: - pad1_buttons &= ~(1 << joystick_config[event.jbutton.button]); + controller = &controllers[event.jbutton.which]; + // printf("DOWN event.jbutton.which %d\n", event.jbutton.which); + // printf("DOWN controller->player %d\n", controller->player); + // printf("DOWN event.jbutton.button %d\n", event.jbutton.button); + // printf("DOWN controller->but_map[event.jbutton.button] %d\n", controller->but_map[event.jbutton.button]); + pad_buttons[controller->player] &= ~(1 << controller->but_map[event.jbutton.button]); break; case SDL_JOYBUTTONUP: - pad1_buttons |= (1 << joystick_config[event.jbutton.button]); + controller = &controllers[event.jbutton.which]; + pad_buttons[controller->player] |= (1 << controller->but_map[event.jbutton.button]); break; // USB joystick D-pad (HAT) case SDL_JOYHATMOTION: + controller = &controllers[event.jbutton.which]; // reset hat - pad1_buttons |= (1 << DKEY_UP); - pad1_buttons |= (1 << DKEY_DOWN); - pad1_buttons |= (1 << DKEY_LEFT); - pad1_buttons |= (1 << DKEY_RIGHT); + pad_buttons[controller->player] |= (1 << DKEY_UP); + pad_buttons[controller->player] |= (1 << DKEY_DOWN); + pad_buttons[controller->player] |= (1 << DKEY_LEFT); + pad_buttons[controller->player] |= (1 << DKEY_RIGHT); // get pressed direction(s) - if (event.jhat.value & SDL_HAT_UP) pad1_buttons &= ~(1 << joystick_config[12]); - if (event.jhat.value & SDL_HAT_RIGHT) pad1_buttons &= ~(1 << joystick_config[13]); - if (event.jhat.value & SDL_HAT_DOWN) pad1_buttons &= ~(1 << joystick_config[14]); - if (event.jhat.value & SDL_HAT_LEFT) pad1_buttons &= ~(1 << joystick_config[15]); + if (event.jhat.value & SDL_HAT_UP) pad_buttons[controller->player] &= ~(1 << controller->but_map[12]); + if (event.jhat.value & SDL_HAT_RIGHT) pad_buttons[controller->player] &= ~(1 << controller->but_map[13]); + if (event.jhat.value & SDL_HAT_DOWN) pad_buttons[controller->player] &= ~(1 << controller->but_map[14]); + if (event.jhat.value & SDL_HAT_LEFT) pad_buttons[controller->player] &= ~(1 << controller->but_map[15]); break; default: break; } } - if (Config.AnalogArrow == 1) { - if ((pad1_buttons & (1 << DKEY_UP)) && (analog1 & ANALOG_UP)) { - pad1_buttons &= ~(1 << DKEY_UP); - } - if ((pad1_buttons & (1 << DKEY_DOWN)) && (analog1 & ANALOG_DOWN)) { - pad1_buttons &= ~(1 << DKEY_DOWN); - } - if ((pad1_buttons & (1 << DKEY_LEFT)) && (analog1 & ANALOG_LEFT)) { - pad1_buttons &= ~(1 << DKEY_LEFT); - } - if ((pad1_buttons & (1 << DKEY_RIGHT)) && (analog1 & ANALOG_RIGHT)) { - pad1_buttons &= ~(1 << DKEY_RIGHT); + for(i = 0; i<2; i++) { + if (Config.AnalogArrow == 1) { + if ((pad_buttons[i] & (1 << DKEY_UP)) && (analogs[i] & ANALOG_UP)) { + pad_buttons[i] &= ~(1 << DKEY_UP); + } + if ((pad_buttons[i] & (1 << DKEY_DOWN)) && (analogs[i] & ANALOG_DOWN)) { + pad_buttons[i] &= ~(1 << DKEY_DOWN); + } + if ((pad_buttons[i] & (1 << DKEY_LEFT)) && (analogs[i] & ANALOG_LEFT)) { + pad_buttons[i] &= ~(1 << DKEY_LEFT); + } + if ((pad_buttons[i] & (1 << DKEY_RIGHT)) && (analogs[i] & ANALOG_RIGHT)) { + pad_buttons[i] &= ~(1 << DKEY_RIGHT); + } } } @@ -799,23 +813,24 @@ void pad_update() update_window_size(320, 240, false); GameMenu(); emu_running = true; - pad1_buttons |= (1 << DKEY_SELECT) | (1 << DKEY_START) | (1 << DKEY_CROSS); + pad_buttons[0] |= (1 << DKEY_SELECT) | (1 << DKEY_START) | (1 << DKEY_CROSS); update_window_size(gpu.screen.hres, gpu.screen.vres, Config.PsxType == PSX_TYPE_NTSC); if (Config.VideoScaling == 1) { video_clear_cache(); } emu_running = true; - pad1 |= (1 << DKEY_START); - pad1 |= (1 << DKEY_CROSS); + pads[0] |= (1 << DKEY_START); + pads[0] |= (1 << DKEY_CROSS); pl_resume(); // Tell plugin_lib we're reentering emu } - pad1 = pad1_buttons; + pads[0] = pad_buttons[0]; + pads[1] = pad_buttons[1]; } unsigned short pad_read(int num) { - return (num == 0 ? pad1 : pad2); + return pads[num]; } void video_flip(void) diff --git a/src/port/sdl/port.h b/src/port/sdl/port.h index 9e9f2996..54b308c2 100644 --- a/src/port/sdl/port.h +++ b/src/port/sdl/port.h @@ -11,6 +11,7 @@ #include #include #include +#include struct ps1_controller { uint8_t id; @@ -23,9 +24,13 @@ struct ps1_controller { uint8_t pad_mode; uint8_t pad_controllertype; uint8_t configmode; + uint8_t player; // player-1: 0, player-2: 1 + uint_least8_t but_map[16]; // mapping of SDL buttons, the index is the SDL id of the button + SDL_Joystick* sdl_joy; // used for native analog sticks and USB joysticks }; -extern struct ps1_controller player_controller[2]; +// 0 for native sticks, 1 for external js1, 2 for external js2 +extern struct ps1_controller controllers[3]; /////////////////////////// // Windows compatibility //