diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index d910c16..11f87f8 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -26,8 +26,9 @@ #include "libretro-common/include/streams/memory_stream.h" -#define MAX_PLAYERS 4 -#define MAX_PORTS 2 +#define MAX_PLAYERS 4 /* max supported players */ +#define MAX_PORTS 2 /* max controller ports, + * port 0 for player 1/3, port 1 for player 2/4 */ #define RETRO_DEVICE_GAMEPAD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) #define RETRO_DEVICE_ZAPPER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 0) @@ -55,8 +56,8 @@ static bool use_raw_palette; static bool use_par; static unsigned turbo_enabler[MAX_PLAYERS] = {0}; static unsigned turbo_delay = 0; -static int t[2] = { 0, 0 }; -static int zapper_mode = 0; /* 0=absolute 1=relative */ +static unsigned nes_device[MAX_PLAYERS] = {0}; +static unsigned zapper_mode = 0; /* 0=absolute 1=relative */ /* emulator-specific variables */ @@ -542,45 +543,41 @@ void retro_set_input_state(retro_input_state_t cb) void retro_set_controller_port_device(unsigned port, unsigned device) { - unsigned arg = 0; - void *InputDPtr; - - if (port < 2) /* port #0 = player1/player3, port #1 = player2/player4 */ + if (port < MAX_PORTS) /* port #0 = player1/player3, port #1 = player2/player4 */ { switch(device) { case RETRO_DEVICE_NONE: - t[port] = SI_NONE; - InputDPtr = NULL; + nes_device[port] = RETRO_DEVICE_NONE; + FCEUI_SetInput(port, SI_NONE, NULL, 0); + FCEU_printf(" Player %u: None\n", port + 1); break; case RETRO_DEVICE_GAMEPAD: - t[port] = SI_GAMEPAD; - InputDPtr = &JSReturn; + nes_device[port] = RETRO_DEVICE_GAMEPAD; + FCEUI_SetInput(port, SI_GAMEPAD, &JSReturn, 0); + FCEU_printf(" Player %u: Gamepad\n", port + 1); break; case RETRO_DEVICE_ZAPPER: - arg = 1; - t[port] = SI_ZAPPER; - InputDPtr = &MouseData[0]; + nes_device[port] = RETRO_DEVICE_ZAPPER; + FCEUI_SetInput(port, SI_ZAPPER, MouseData, 1); + FCEU_printf(" Player %u: Zapper\n", port + 1); break; - case RETRO_DEVICE_JOYPAD: - default: + case RETRO_DEVICE_JOYPAD: /* Assigned to auto configure devices */ + default: /* based on database */ if (GameInfo->input[port] == SI_ZAPPER) { - arg = 1; - t[port] = SI_ZAPPER; - InputDPtr = &MouseData[0]; + nes_device[port] = RETRO_DEVICE_ZAPPER; + FCEUI_SetInput(port, SI_ZAPPER, MouseData, 1); + FCEU_printf(" Player %u: Zapper\n", port + 1); } else { - t[port] = SI_GAMEPAD; - InputDPtr = &JSReturn; + nes_device[port] = RETRO_DEVICE_GAMEPAD; + FCEUI_SetInput(port, SI_GAMEPAD, &JSReturn, 0); + FCEU_printf(" Player %u: Gamepad\n", port + 1); } break; } - FCEUI_SetInput(port, t[port], InputDPtr, arg); - FCEU_printf("Player %d: %s\n", port + 1, - t[port] == SI_GAMEPAD ? "Gamepad" : - t[port] == SI_ZAPPER ? "Zapper" : "None"); } } @@ -610,9 +607,10 @@ void retro_set_environment(retro_environment_t cb) }; static const struct retro_controller_description pads[] = { - { "Auto", RETRO_DEVICE_JOYPAD }, + { "Auto (Gamepad/Zapper)", RETRO_DEVICE_JOYPAD }, { "Gamepad", RETRO_DEVICE_GAMEPAD }, { "Zapper", RETRO_DEVICE_ZAPPER }, + { NULL, 0 }, }; static const struct retro_controller_info ports[] = { @@ -1083,10 +1081,10 @@ static void check_variables(bool startup) static int mzx = 0, mzy = 0, mzb = 0; -void GetMouseData(uint32_t *zapdata) +void GetMouseData(unsigned port, uint32_t *zapdata) { bool adjx = false, adjy = false; - int right, bottom, port; + int right, bottom; #ifdef PSP adjx = adjy = use_overscan ? 1 : 0; @@ -1094,7 +1092,6 @@ void GetMouseData(uint32_t *zapdata) adjx = overscan_h ? 1 : 0; adjy = overscan_v ? 1 : 0; #endif - port = (GameInfo->type == GIT_VSUNI) ? 0 : 1; right = 256; bottom = 240; mzb = 0; @@ -1144,56 +1141,64 @@ unsigned char turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; static void FCEUD_UpdateInput(void) { - unsigned p, i; + unsigned player, i; unsigned char pad[4]; - for (p = 0; p < MAX_PLAYERS; p++) - pad[p] = 0; /* reset pads */ + for (player = 0; player < MAX_PLAYERS; player++) + pad[player] = 0; /* reset pads */ poll_cb(); - for (p = 0; p < MAX_PLAYERS; p++) + for (player = 0; player < MAX_PLAYERS; player++) { - for ( i = 0; i < 8; i++) - pad[p] |= input_cb(p, RETRO_DEVICE_JOYPAD, 0, bindmap[i].retro) ? bindmap[i].nes : 0; - - /* Turbo A and Turbo B buttons are - * mapped to Joypad X and Joypad Y - * in RetroArch joypad. - * - * We achieve this by keeping track of - * the number of times it increments - * the toggle counter and fire or not fire - * depending on whether the delay value has - * been reached. - */ - - if (turbo_enabler[p] == 1) + switch (nes_device[player]) { - /* Handle Turbo A & B buttons */ - for ( i = 8; i < 10; i++) - { - if (input_cb(0, RETRO_DEVICE_JOYPAD, 0, bindmap[i].retro)) + case RETRO_DEVICE_GAMEPAD: + for (i = 0; i < 8; i++) + pad[player] |= input_cb(player, RETRO_DEVICE_JOYPAD, 0, + bindmap[i].retro) ? bindmap[i].nes : 0; + + /* Turbo A and Turbo B buttons are + * mapped to Joypad X and Joypad Y + * in RetroArch joypad. + * + * We achieve this by keeping track of + * the number of times it increments + * the toggle counter and fire or not fire + * depending on whether the delay value has + * been reached. + */ + + if (turbo_enabler[player] == 1) { - if (turbo_button_toggle[p][i-8] == 0) - pad[p] |= bindmap[i].nes; - turbo_button_toggle[p][i-8]++; - if (turbo_button_toggle[p][i-8] > turbo_delay) - /* Reset the toggle if delay value is reached */ - turbo_button_toggle[p][i-8] = 0; + /* Handle Turbo A & B buttons */ + for (i = 8; i < 10; i++) + { + if (input_cb(player, RETRO_DEVICE_JOYPAD, 0, bindmap[i].retro)) + { + if (turbo_button_toggle[player][i-8] == 0) + pad[player] |= bindmap[i].nes; + turbo_button_toggle[player][i-8]++; + if (turbo_button_toggle[player][i-8] > turbo_delay) + /* Reset the toggle if delay value is reached */ + turbo_button_toggle[player][i-8] = 0; + } + else + /* If the button is not pressed, just reset the toggle */ + turbo_button_toggle[player][i-8] = 0; + } } - else - /* If the button is not pressed, just reset the toggle */ - turbo_button_toggle[p][i-8] = 0; - } + + JSReturn = (pad[0] & 0xff) | ((pad[1] & 0xff) << 8) | + ((pad[2] & 0xff) << 16) | ((pad[3] & 0xff) << 24); + break; /* RETRO_DEVICE_GAMEPAD */ + + case RETRO_DEVICE_ZAPPER: + GetMouseData(player, MouseData); + break; /* RETRO_DEVICE_ZAPPER */ } } - JSReturn = pad[0] | (pad[1] << 8) | (pad[2] << 16) | (pad[3] << 24); - - if (t[0] == SI_ZAPPER || t[1] == SI_ZAPPER) - GetMouseData(&MouseData[0]); - if (input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) FCEU_VSUniCoin(); /* Insert Coin VS System */ @@ -1748,6 +1753,10 @@ bool retro_load_game(const struct retro_game_info *game) return false; } + nes_device[0] = RETRO_DEVICE_GAMEPAD; + nes_device[1] = RETRO_DEVICE_GAMEPAD; + nes_device[2] = RETRO_DEVICE_NONE; + nes_device[3] = RETRO_DEVICE_NONE; FCEUI_SetInput(0, SI_GAMEPAD, &JSReturn, 0); FCEUI_SetInput(1, SI_GAMEPAD, &JSReturn, 0); @@ -1774,6 +1783,8 @@ bool retro_load_game(const struct retro_game_info *game) if (fourscore_db_list[i].crc == iNESGameCRC32) { FCEUI_DisableFourScore(0); + nes_device[2] = RETRO_DEVICE_GAMEPAD; + nes_device[3] = RETRO_DEVICE_GAMEPAD; break; } } @@ -1783,6 +1794,8 @@ bool retro_load_game(const struct retro_game_info *game) if (famicom_4p_db_list[i].crc == iNESGameCRC32) { FCEUI_SetInputFC(SIFC_4PLAYER, &JSReturn, 0); + nes_device[2] = RETRO_DEVICE_GAMEPAD; + nes_device[3] = RETRO_DEVICE_GAMEPAD; break; } } @@ -1885,3 +1898,4 @@ size_t retro_get_memory_size(unsigned type) return size; } +