From 805d9eab9ab3f1180e6b182f702928195bfef87b Mon Sep 17 00:00:00 2001 From: infvaL <38145742+infval@users.noreply.github.com> Date: Mon, 9 Apr 2018 01:37:16 +0300 Subject: [PATCH] Add multitap support up to 4 players NES Four Score (default) and 4-Players Adaptor (menu option) are supported. Warning: the emulator slows down when a multitap is plugged. --- src/drivers/ps2/browser.c | 2 +- src/drivers/ps2/cnfsettings.c | 108 +++++++++++++++++++++++++++++++++- src/drivers/ps2/menu.c | 24 +++++++- src/drivers/ps2/ps2fceu.h | 3 +- src/drivers/ps2/ps2input.c | 23 +++----- 5 files changed, 142 insertions(+), 18 deletions(-) diff --git a/src/drivers/ps2/browser.c b/src/drivers/ps2/browser.c index d5d7362..53329e0 100644 --- a/src/drivers/ps2/browser.c +++ b/src/drivers/ps2/browser.c @@ -624,7 +624,7 @@ char* Browser(int files_too, int menu_id) if(selection != oldselect) { gsKit_clear(gsGlobal,GS_SETREG_RGBAQ(0x00,0x00,0x00,0x80,0x00)); - browser_primitive("FCEUltra PS2 Beta 0.93","Browser", &BG_TEX, menu_x1, menu_y1, menu_x2, menu_y2); + browser_primitive("FCEUltra PS2 B0.93 [x.1.0]","Browser", &BG_TEX, menu_x1, menu_y1, menu_x2, menu_y2); if(selection > max_item) { list_offset = text_line - (selection - max_item) * FONT_HEIGHT; diff --git a/src/drivers/ps2/cnfsettings.c b/src/drivers/ps2/cnfsettings.c index 2724baa..bb2684e 100644 --- a/src/drivers/ps2/cnfsettings.c +++ b/src/drivers/ps2/cnfsettings.c @@ -210,6 +210,24 @@ void Load_Global_CNF(char *CNF_path_p) else if(!strcmp(name,"JOY2_Down")) { Settings.PlayerInput[1][10] = (u16)strtoul(value,NULL,16); } else if(!strcmp(name,"JOY2_Left")) { Settings.PlayerInput[1][11] = (u16)strtoul(value,NULL,16); } else if(!strcmp(name,"JOY2_Right")) { Settings.PlayerInput[1][12] = (u16)strtoul(value,NULL,16); } + //Player 3 Settings + else if(!strcmp(name,"JOY3_A")) { Settings.PlayerInput[2][5] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_B")) { Settings.PlayerInput[2][6] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Select")) { Settings.PlayerInput[2][7] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Start")) { Settings.PlayerInput[2][8] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Up")) { Settings.PlayerInput[2][9] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Down")) { Settings.PlayerInput[2][10] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Left")) { Settings.PlayerInput[2][11] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY3_Right")) { Settings.PlayerInput[2][12] = (u16)strtoul(value,NULL,16); } + //Player 4 Settings + else if(!strcmp(name,"JOY4_A")) { Settings.PlayerInput[3][5] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_B")) { Settings.PlayerInput[3][6] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Select")) { Settings.PlayerInput[3][7] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Start")) { Settings.PlayerInput[3][8] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Up")) { Settings.PlayerInput[3][9] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Down")) { Settings.PlayerInput[3][10] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Left")) { Settings.PlayerInput[3][11] = (u16)strtoul(value,NULL,16); } + else if(!strcmp(name,"JOY4_Right")) { Settings.PlayerInput[3][12] = (u16)strtoul(value,NULL,16); } } //Set so only first player controls emulator controls @@ -219,6 +237,18 @@ void Load_Global_CNF(char *CNF_path_p) Settings.PlayerInput[1][3] = 0xFFFF; Settings.PlayerInput[1][4] = 0xFFFF; + Settings.PlayerInput[2][0] = 0xFFFF; + Settings.PlayerInput[2][1] = 0xFFFF; + Settings.PlayerInput[2][2] = 0xFFFF; + Settings.PlayerInput[2][3] = 0xFFFF; + Settings.PlayerInput[2][4] = 0xFFFF; + + Settings.PlayerInput[3][0] = 0xFFFF; + Settings.PlayerInput[3][1] = 0xFFFF; + Settings.PlayerInput[3][2] = 0xFFFF; + Settings.PlayerInput[3][3] = 0xFFFF; + Settings.PlayerInput[3][4] = 0xFFFF; + //begin hdd path mounting if(!strncmp(Settings.elfpath,"hdd0:/", 6)) { @@ -328,6 +358,18 @@ char* Load_Control_CNF(char *CNF_path_p, int port) Settings.PlayerInput[1][3] = 0xFFFF; Settings.PlayerInput[1][4] = 0xFFFF; + Settings.PlayerInput[2][0] = 0xFFFF; + Settings.PlayerInput[2][1] = 0xFFFF; + Settings.PlayerInput[2][2] = 0xFFFF; + Settings.PlayerInput[2][3] = 0xFFFF; + Settings.PlayerInput[2][4] = 0xFFFF; + + Settings.PlayerInput[3][0] = 0xFFFF; + Settings.PlayerInput[3][1] = 0xFFFF; + Settings.PlayerInput[3][2] = 0xFFFF; + Settings.PlayerInput[3][3] = 0xFFFF; + Settings.PlayerInput[3][4] = 0xFFFF; + /*if(strlen(CNF_p)) //Was there any unprocessed CNF remainder ? CNF_edited = false; //false == current settings match CNF file else @@ -521,6 +563,24 @@ void Save_Global_CNF(char *CNF_path_p) "JOY2_Down = 0x%04x\r\n" "JOY2_Left = 0x%04x\r\n" "JOY2_Right = 0x%04x\r\n" + ";Player 3 Controls\r\n" + "JOY3_A = 0x%04x\r\n" + "JOY3_B = 0x%04x\r\n" + "JOY3_Select = 0x%04x\r\n" + "JOY3_Start = 0x%04x\r\n" + "JOY3_Up = 0x%04x\r\n" + "JOY3_Down = 0x%04x\r\n" + "JOY3_Left = 0x%04x\r\n" + "JOY3_Right = 0x%04x\r\n" + ";Player 4 Controls\r\n" + "JOY4_A = 0x%04x\r\n" + "JOY4_B = 0x%04x\r\n" + "JOY4_Select = 0x%04x\r\n" + "JOY4_Start = 0x%04x\r\n" + "JOY4_Up = 0x%04x\r\n" + "JOY4_Down = 0x%04x\r\n" + "JOY4_Left = 0x%04x\r\n" + "JOY4_Right = 0x%04x\r\n" "# ------------------------------------------------------------\r\n" "# End-Of-File for FCEUltra.CNF\r\n" "%n", //NB: The %n specifier causes NO output, but only a measurement @@ -548,6 +608,7 @@ void Save_Global_CNF(char *CNF_path_p) Settings.PlayerInput[0][10], Settings.PlayerInput[0][11], Settings.PlayerInput[0][12], + Settings.PlayerInput[1][5], Settings.PlayerInput[1][6], Settings.PlayerInput[1][7], @@ -556,6 +617,24 @@ void Save_Global_CNF(char *CNF_path_p) Settings.PlayerInput[1][10], Settings.PlayerInput[1][11], Settings.PlayerInput[1][12], + + Settings.PlayerInput[2][5], + Settings.PlayerInput[2][6], + Settings.PlayerInput[2][7], + Settings.PlayerInput[2][8], + Settings.PlayerInput[2][9], + Settings.PlayerInput[2][10], + Settings.PlayerInput[2][11], + Settings.PlayerInput[2][12], + + Settings.PlayerInput[3][5], + Settings.PlayerInput[3][6], + Settings.PlayerInput[3][7], + Settings.PlayerInput[3][8], + Settings.PlayerInput[3][9], + Settings.PlayerInput[3][10], + Settings.PlayerInput[3][11], + Settings.PlayerInput[3][12], &CNF_size); // Note that the final argument above measures accumulated string size, @@ -586,7 +665,8 @@ void Save_Global_CNF(char *CNF_path_p) void Default_Global_CNF(void) { - Settings.current_palette = 1; + Settings.input_4players_adaptor = 0; + Settings.current_palette = 1; Settings.offset_x = 0; Settings.offset_y = 0; Settings.interlace = 0; @@ -624,6 +704,32 @@ void Default_Global_CNF(void) Settings.PlayerInput[1][10] = PAD_DOWN; Settings.PlayerInput[1][11] = PAD_LEFT; Settings.PlayerInput[1][12] = PAD_RIGHT; + Settings.PlayerInput[2][0] = 0xFFFF; + Settings.PlayerInput[2][1] = 0xFFFF; + Settings.PlayerInput[2][2] = 0xFFFF; + Settings.PlayerInput[2][3] = 0xFFFF; + Settings.PlayerInput[2][4] = 0xFFFF; + Settings.PlayerInput[2][5] = PAD_CROSS; + Settings.PlayerInput[2][6] = PAD_SQUARE; + Settings.PlayerInput[2][7] = PAD_SELECT; + Settings.PlayerInput[2][8] = PAD_START; + Settings.PlayerInput[2][9] = PAD_UP; + Settings.PlayerInput[2][10] = PAD_DOWN; + Settings.PlayerInput[2][11] = PAD_LEFT; + Settings.PlayerInput[2][12] = PAD_RIGHT; + Settings.PlayerInput[3][0] = 0xFFFF; + Settings.PlayerInput[3][1] = 0xFFFF; + Settings.PlayerInput[3][2] = 0xFFFF; + Settings.PlayerInput[3][3] = 0xFFFF; + Settings.PlayerInput[3][4] = 0xFFFF; + Settings.PlayerInput[3][5] = PAD_CROSS; + Settings.PlayerInput[3][6] = PAD_SQUARE; + Settings.PlayerInput[3][7] = PAD_SELECT; + Settings.PlayerInput[3][8] = PAD_START; + Settings.PlayerInput[3][9] = PAD_UP; + Settings.PlayerInput[3][10] = PAD_DOWN; + Settings.PlayerInput[3][11] = PAD_LEFT; + Settings.PlayerInput[3][12] = PAD_RIGHT; } diff --git a/src/drivers/ps2/menu.c b/src/drivers/ps2/menu.c index 65e680c..dd66012 100644 --- a/src/drivers/ps2/menu.c +++ b/src/drivers/ps2/menu.c @@ -560,7 +560,7 @@ void Ingame_Menu(void) { "Load State" }, { "Filtering: "}, { "LowPass: " }, - { "Configure Input" }, + { "4-Players Adaptor: " }, { "Rapidfire Switch: "}, { "RapidFire P1: " }, { "RapidFire P2: " }, @@ -588,6 +588,12 @@ void Ingame_Menu(void) else sprintf(options[i],"%s%s",options[i],"On"); break; + case 5: + if(!Settings.input_4players_adaptor) + sprintf(options[i],"%s%s",options[i],"Off"); + else + sprintf(options[i],"%s%s",options[i],"On"); + break; case 6: if(!Settings.turbo) { sprintf(options[i],"%s%s",options[i],"Off"); @@ -725,6 +731,22 @@ void Ingame_Menu(void) } option_changed = 1; break; + case 5: + Settings.input_4players_adaptor ^= 1; + if(Settings.input_4players_adaptor) { + FCEUI_SetInputFC(SIFC_4PLAYER, NULL, 0); + temp = strstr(options[i],"Off"); + *temp = 0; + strcat(options[i],"On"); + } + else { + FCEUI_SetInputFC(SIFC_NONE, NULL, 0); + temp = strstr(options[i],"On"); + *temp = 0; + strcat(options[i],"Off"); + } + option_changed = 1; + break; case 6: Settings.turbo ^= 1; if(Settings.turbo) { diff --git a/src/drivers/ps2/ps2fceu.h b/src/drivers/ps2/ps2fceu.h index 00dddb2..8c42c2a 100644 --- a/src/drivers/ps2/ps2fceu.h +++ b/src/drivers/ps2/ps2fceu.h @@ -22,7 +22,8 @@ typedef struct { char savepath[1024]; char skinpath[1024]; u16 PlayerInput[4][13]; - int current_palette; + u8 input_4players_adaptor; + int current_palette; } vars; typedef struct { diff --git a/src/drivers/ps2/ps2input.c b/src/drivers/ps2/ps2input.c index 2d1c77a..30abdf6 100644 --- a/src/drivers/ps2/ps2input.c +++ b/src/drivers/ps2/ps2input.c @@ -359,24 +359,16 @@ unsigned char Get_PS2Input(int mport) void Set_NESInput() { - void *NESPads; int attrib = 0; if(mtapGetConnection(0) != 1) { FCEUI_DisableFourScore(1); - NESPads = &NESButtons; - FCEUI_SetInput(0, SI_GAMEPAD, NESPads, attrib); - FCEUI_SetInput(1, SI_GAMEPAD, NESPads, attrib); } else { FCEUI_DisableFourScore(0); - NESPads = &NESButtons; - FCEUI_SetInputFC(SIFC_4PLAYER, NESPads, attrib); - FCEUI_SetInput(0, SI_GAMEPAD, NESPads, attrib); - FCEUI_SetInput(1, SI_GAMEPAD, NESPads, attrib); -// FCEUI_SetInput(2, SI_GAMEPAD, NESPads, attrib); -// FCEUI_SetInput(3, SI_GAMEPAD, NESPads, attrib); } + FCEUI_SetInput(0, SI_GAMEPAD, &NESButtons, attrib); + FCEUI_SetInput(1, SI_GAMEPAD, &NESButtons, attrib); } int Get_NESInput() @@ -389,7 +381,7 @@ int Get_NESInput() } if(Settings.turbo) { - NESButtons = ( Get_PS2TurboInput(0) ); //first player + NESButtons = ( Get_PS2TurboInput(0) << 0); //first player NESButtons |= ( Get_PS2TurboInput(1) << 8); //second player if(rapid_a[0]) @@ -405,10 +397,13 @@ int Get_NESInput() NESButtons |= 0x200; } else { - NESButtons = ( Get_PS2Input(0) ); //first player + NESButtons = ( Get_PS2Input(0) << 0); //first player NESButtons |= ( Get_PS2Input(1) << 8); //second player -// NESButtons |= ( Get_PS2Input(2) << 16); //third player -// NESButtons |= ( Get_PS2Input(3) << 24); //4th player + } + + if (mtapGetConnection(0) == 1) { + NESButtons |= ( Get_PS2Input(2) << 16); //third player + NESButtons |= ( Get_PS2Input(3) << 24); //4th player } return 0;