From 15751dfd472bc2689fa4b2d2b2869f62e30630f9 Mon Sep 17 00:00:00 2001 From: Wolfy Date: Fri, 8 Dec 2017 01:29:01 -0600 Subject: [PATCH] initial quad stuff (does not work) --- src/d_netcmd.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++- src/d_netcmd.h | 10 +++ src/doomstat.h | 4 + src/g_game.c | 28 +++++- src/g_input.c | 54 +++++++++++ src/g_input.h | 6 ++ src/m_menu.c | 180 ++++++++++++++++++++++++++++++++++++- src/r_things.h | 2 + 8 files changed, 516 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4eff3242..5e0db8d4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -91,10 +91,16 @@ static void ForceSkin_OnChange(void); static void Name_OnChange(void); static void Name2_OnChange(void); +static void Name3_OnChange(void); +static void Name4_OnChange(void); static void Skin_OnChange(void); static void Skin2_OnChange(void); +static void Skin3_OnChange(void); +static void Skin4_OnChange(void); static void Color_OnChange(void); static void Color2_OnChange(void); +static void Color3_OnChange(void); +static void Color4_OnChange(void); static void DummyConsvar_OnChange(void); static void SoundTest_OnChange(void); @@ -136,6 +142,9 @@ static void Command_Mapmd5_f(void); static void Command_Teamchange_f(void); static void Command_Teamchange2_f(void); +static void Command_Teamchange3_f(void); +static void Command_Teamchange4_f(void); + static void Command_ServerTeamChange_f(void); static void Command_Clearscores_f(void); @@ -169,6 +178,8 @@ static void Command_Archivetest_f(void); void SendWeaponPref(void); void SendWeaponPref2(void); +//void SendWeaponPref3(void); +//void SendWeaponPref4(void); static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) @@ -229,12 +240,18 @@ consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL, // these are just meant to be saved to the config consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playername3 = {"name3", "Knuckles", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playername4 = { "name4", "Metal Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name4_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player colors consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playercolor3 = {"color3", "Red", CV_CALL|CV_NOINIT, Color_cons_t, Color3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playercolor4 = {"color4", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color4_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player's skin, saved for commodity, when using a favorite skins wad.. consvar_t cv_skin = {"skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skin2 = {"skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_skin3 = {"skin3", DEFAULTSKIN3, CV_CALL|CV_NOINIT, NULL, Skin3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_skin4 = {"skin4", DEFAULTSKIN4, CV_CALL|CV_NOINIT, NULL, Skin4_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skipmapcheck = {"skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -258,6 +275,10 @@ consvar_t cv_usejoystick = {"use_joystick", "0", CV_SAVE|CV_CALL, usejoystick_co I_InitJoystick, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usejoystick2 = {"use_joystick2", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_usejoystick3 = {"use_joystick3", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +I_InitJoystick3, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_usejoystick4 = {"use_joystick4", "0", CV_SAVE|CV_CALL, usejoystick_cons_t, +I_InitJoystick4, 0, NULL, NULL, 0, 0, NULL}; #endif #if (defined (LJOYSTICK) || defined (HAVE_SDL)) #ifdef LJOYSTICK @@ -266,6 +287,8 @@ consvar_t cv_joyport2 = {"joyport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, #endif consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_joyscale3 = {"joyscale3", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale3, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_joyscale4 = {"joyscale4", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale4, 0, NULL, NULL, 0, 0, NULL}; #else consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save @@ -410,6 +433,8 @@ consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL INT16 gametype = GT_RACE; // SRB2kart boolean splitscreen = false; +boolean splitscreen3 = false; +boolean splitscreen4 = false; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; @@ -436,6 +461,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "DELFILE", "SETMOTD", "SUICIDE", + "DEMOTED", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -648,6 +674,8 @@ void D_RegisterClientCommands(void) COM_AddCommand("changeteam", Command_Teamchange_f); COM_AddCommand("changeteam2", Command_Teamchange2_f); + COM_AddCommand("changeteam3", Command_Teamchange3_f); + COM_AddCommand("changeteam4", Command_Teamchange4_f); COM_AddCommand("playdemo", Command_Playdemo_f); COM_AddCommand("timedemo", Command_Timedemo_f); @@ -658,6 +686,8 @@ void D_RegisterClientCommands(void) COM_AddCommand("setcontrol", Command_Setcontrol_f); COM_AddCommand("setcontrol2", Command_Setcontrol2_f); + COM_AddCommand("setcontrol3", Command_Setcontrol3_f); + COM_AddCommand("setcontrol4", Command_Setcontrol4_f); COM_AddCommand("screenshot", M_ScreenShot); COM_AddCommand("startmovie", Command_StartMovie_f); @@ -695,6 +725,14 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_playername2); CV_RegisterVar(&cv_playercolor2); CV_RegisterVar(&cv_skin2); + // third player + CV_RegisterVar(&cv_playername3); + CV_RegisterVar(&cv_playercolor3); + CV_RegisterVar(&cv_skin3); + // fourth player + CV_RegisterVar(&cv_playername4); + CV_RegisterVar(&cv_playercolor4); + CV_RegisterVar(&cv_skin4); #ifdef SEENAMES CV_RegisterVar(&cv_seenames); @@ -766,12 +804,16 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_usejoystick); CV_RegisterVar(&cv_usejoystick2); + CV_RegisterVar(&cv_usejoystick3); + CV_RegisterVar(&cv_usejoystick4); #ifdef LJOYSTICK CV_RegisterVar(&cv_joyport); CV_RegisterVar(&cv_joyport2); #endif CV_RegisterVar(&cv_joyscale); CV_RegisterVar(&cv_joyscale2); + CV_RegisterVar(&cv_joyscale3); + CV_RegisterVar(&cv_joyscale4); // Analog Control CV_RegisterVar(&cv_analog); @@ -1242,7 +1284,7 @@ static void SendNameAndColor2(void) { INT32 secondplaya; - if (!splitscreen && !botingame) + if ((!splitscreen || !splitscreen3 || !splitscreen4) && !botingame) return; // can happen if skin2/color2/name2 changed if (secondarydisplayplayer != consoleplayer) @@ -1335,6 +1377,200 @@ static void SendNameAndColor2(void) // Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! } +static void SendNameAndColor3(void) +{ + INT32 thirdplaya; + + if ((!splitscreen3 || !splitscreen4) && !botingame) + return; // can happen if skin2/color2/name2 changed + + if (thirddisplayplayer != consoleplayer) + thirdplaya = thirddisplayplayer; + else // HACK + thirdplaya = 2; + + // normal player colors + if (G_GametypeHasTeams()) + { + if (players[thirdplaya].ctfteam == 1 && cv_playercolor3.value != skincolor_redteam) + CV_StealthSetValue(&cv_playercolor3, skincolor_redteam); + else if (players[thirdplaya].ctfteam == 2 && cv_playercolor3.value != skincolor_blueteam) + CV_StealthSetValue(&cv_playercolor3, skincolor_blueteam); + } + + // never allow the color "none" + if (!cv_playercolor3.value) + { + if (players[thirdplaya].skincolor) + CV_StealthSetValue(&cv_playercolor3, players[thirdplaya].skincolor); + else if (skins[players[thirdplaya].skin].prefcolor) + CV_StealthSetValue(&cv_playercolor3, skins[players[thirdplaya].skin].prefcolor); + else + CV_StealthSet(&cv_playercolor3, cv_playercolor3.defaultvalue); + } + + // We'll handle it later if we're not playing. + if (!Playing()) + return; + + // If you're not in a netgame, merely update the skin, color, and name. + if (botingame) + { + players[thirdplaya].skincolor = botcolor; + if (players[thirdplaya].mo) + players[thirdplaya].mo->color = players[thirdplaya].skincolor; + SetPlayerSkinByNum(thirdplaya, botskin-1); + return; + } + else if (!netgame && !modeattacking) + { + INT32 foundskin; + + CleanupPlayerName(thirdplaya, cv_playername3.zstring); + strcpy(player_names[thirdplaya], cv_playername3.zstring); + + // don't use thirddisplayplayer: the third player must be 2 + players[thirdplaya].skincolor = cv_playercolor3.value; + if (players[thirdplaya].mo) + players[thirdplaya].mo->color = players[thirdplaya].skincolor; + + if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player + { + const INT32 forcedskin = cv_forceskin.value; + + SetPlayerSkinByNum(thirdplaya, forcedskin); + CV_StealthSet(&cv_skin3, skins[forcedskin].name); + } + else if ((foundskin = R_SkinAvailable(cv_skin3.string)) != -1) + { + boolean notsame; + + cv_skin2.value = foundskin; + + notsame = (cv_skin3.value != players[thirdplaya].skin); + + SetPlayerSkin(thirdplaya, cv_skin3.string); + + if (notsame) + { + CV_StealthSetValue(&cv_playercolor3, skins[players[thirdplaya].skin].prefcolor); + + players[thirdplaya].skincolor = (cv_playercolor3.value&0x3F) % MAXSKINCOLORS; + + if (players[thirdplaya].mo) + players[thirdplaya].mo->color = players[thirdplaya].skincolor; + } + } + else + { + cv_skin3.value = players[thirdplaya].skin; + CV_StealthSet(&cv_skin3, skins[players[thirdplaya].skin].name); + // will always be same as current + SetPlayerSkin(thirdplaya, cv_skin3.string); + } + return; + } + + // Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! +} + +static void SendNameAndColor4(void) +{ + INT32 fourthplaya; + + if (!splitscreen4 && !botingame) + return; // can happen if skin4/color4/name4 changed + + if (fourthdisplayplayer != consoleplayer) + fourthplaya = fourthdisplayplayer; + else // HACK + fourthplaya = 3; + + // normal player colors + if (G_GametypeHasTeams()) + { + if (players[fourthplaya].ctfteam == 1 && cv_playercolor4.value != skincolor_redteam) + CV_StealthSetValue(&cv_playercolor4, skincolor_redteam); + else if (players[fourthplaya].ctfteam == 2 && cv_playercolor4.value != skincolor_blueteam) + CV_StealthSetValue(&cv_playercolor4, skincolor_blueteam); + } + + // never allow the color "none" + if (!cv_playercolor4.value) + { + if (players[fourthplaya].skincolor) + CV_StealthSetValue(&cv_playercolor4, players[fourthplaya].skincolor); + else if (skins[players[fourthplaya].skin].prefcolor) + CV_StealthSetValue(&cv_playercolor4, skins[players[fourthplaya].skin].prefcolor); + else + CV_StealthSet(&cv_playercolor4, cv_playercolor4.defaultvalue); + } + + // We'll handle it later if we're not playing. + if (!Playing()) + return; + + // If you're not in a netgame, merely update the skin, color, and name. + if (botingame) + { + players[fourthplaya].skincolor = botcolor; + if (players[fourthplaya].mo) + players[fourthplaya].mo->color = players[fourthplaya].skincolor; + SetPlayerSkinByNum(fourthplaya, botskin-1); + return; + } + else if (!netgame && !modeattacking) + { + INT32 foundskin; + + CleanupPlayerName(fourthplaya, cv_playername4.zstring); + strcpy(player_names[fourthplaya], cv_playername4.zstring); + + // don't use fourthdisplayplayer: the second player must be 4 + players[fourthplaya].skincolor = cv_playercolor4.value; + if (players[fourthplaya].mo) + players[fourthplaya].mo->color = players[fourthplaya].skincolor; + + if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player + { + const INT32 forcedskin = cv_forceskin.value; + + SetPlayerSkinByNum(fourthplaya, forcedskin); + CV_StealthSet(&cv_skin4, skins[forcedskin].name); + } + else if ((foundskin = R_SkinAvailable(cv_skin4.string)) != -1) + { + boolean notsame; + + cv_skin4.value = foundskin; + + notsame = (cv_skin4.value != players[fourthplaya].skin); + + SetPlayerSkin(fourthplaya, cv_skin4.string); + + if (notsame) + { + CV_StealthSetValue(&cv_playercolor4, skins[players[fourthplaya].skin].prefcolor); + + players[fourthplaya].skincolor = (cv_playercolor4.value&0x3F) % MAXSKINCOLORS; + + if (players[fourthplaya].mo) + players[fourthplaya].mo->color = players[fourthplaya].skincolor; + } + } + else + { + cv_skin4.value = players[fourthplaya].skin; + CV_StealthSet(&cv_skin4, skins[players[fourthplaya].skin].name); + // will always be same as current + SetPlayerSkin(fourthplaya, cv_skin4.string); + } + return; + } + + // Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! +} + static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { player_t *p = &players[playernum]; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d5287ddf..d9506105 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -26,12 +26,16 @@ extern consvar_t cv_seenames, cv_allowseenames; extern consvar_t cv_usemouse; extern consvar_t cv_usejoystick; extern consvar_t cv_usejoystick2; +extern consvar_t cv_usejoystick3; +extern consvar_t cv_usejoystick4; #ifdef LJOYSTICK extern consvar_t cv_joyport; extern consvar_t cv_joyport2; #endif extern consvar_t cv_joyscale; extern consvar_t cv_joyscale2; +extern consvar_t cv_joyscale3; +extern consvar_t cv_joyscale4; extern consvar_t cv_controlperkey; // splitscreen with second mouse @@ -59,6 +63,12 @@ extern consvar_t cv_skin; extern consvar_t cv_playername2; extern consvar_t cv_playercolor2; extern consvar_t cv_skin2; +extern consvar_t cv_playername3; +extern consvar_t cv_playercolor3; +extern consvar_t cv_skin3; +extern consvar_t cv_playername4; +extern consvar_t cv_playercolor4; +extern consvar_t cv_skin4; extern consvar_t cv_touchtag; extern consvar_t cv_hidetime; diff --git a/src/doomstat.h b/src/doomstat.h index 11560259..0e04a781 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -78,6 +78,8 @@ extern boolean multiplayer; extern INT16 gametype; extern boolean splitscreen; +extern boolean splitscreen3; +extern boolean splitscreen4; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; @@ -118,6 +120,8 @@ extern boolean gamedataloaded; extern INT32 consoleplayer; extern INT32 displayplayer; extern INT32 secondarydisplayplayer; // for splitscreen +extern INT32 thirddisplayplayer; +extern INT32 fourthdisplayplayer; // Maps of special importance extern INT16 spstage_start; diff --git a/src/g_game.c b/src/g_game.c index e0fb25c0..c3a0f381 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -110,6 +110,8 @@ player_t players[MAXPLAYERS]; INT32 consoleplayer; // player taking events and displaying INT32 displayplayer; // view being displayed INT32 secondarydisplayplayer; // for splitscreen +INT32 thirddisplayplayer; +INT32 fourthdisplayplayer; tic_t gametic; tic_t levelstarttic; // gametic at level start @@ -294,10 +296,16 @@ static UINT8 *savebuffer; // Analog Control static void UserAnalog_OnChange(void); static void UserAnalog2_OnChange(void); +static void UserAnalog3_OnChange(void); +static void UserAnalog4_OnChange(void); static void Analog_OnChange(void); static void Analog2_OnChange(void); +static void Analog3_OnChange(void); +static void Analog4_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); +void SendWeaponPref3(void); +void SendWeaponPref4(void); static CV_PossibleValue_t crosshair_cons_t[] = {{0, "Off"}, {1, "Cross"}, {2, "Angle"}, {3, "Point"}, {0, NULL}}; static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, @@ -370,12 +378,16 @@ consvar_t cv_mousemove = {"mousemove", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_mousemove2 = {"mousemove2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog3 = {"analog3", "Off", CV_CALL, CV_OnOff, Analog3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog4 = {"analog4", "Off", CV_CALL, CV_OnOff, Analog4_OnChange, 0, NULL, NULL, 0, 0, NULL}; #ifdef DC consvar_t cv_useranalog = {"useranalog", "On", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_useranalog2 = {"useranalog2", "On", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; #else consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog3 = {"useranalog3", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog4 = {"useranalog4", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog4_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif typedef enum @@ -434,7 +446,11 @@ consvar_t cv_fireaxis2 = {"joyaxis2_fire", "LAnalog", CV_SAVE, joyaxis_cons_t, N consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "RAnalog", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #else consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis3 = {"joyaxis3_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_turnaxis4 = {"joyaxis4_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_moveaxis3 = {"joyaxis3_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_moveaxis4 = {"joyaxis4_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef _arch_dreamcast consvar_t cv_sideaxis2 = {"joyaxis2_side", "Triggers", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #elif defined (_XBOX) @@ -444,12 +460,20 @@ consvar_t cv_lookaxis2 = {"joyaxis2_look", "Alt Y-Axis", CV_SAVE, joyaxis_cons_t consvar_t cv_sideaxis2 = {"joyaxis2_side", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #else consvar_t cv_sideaxis2 = {"joyaxis2_side", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_sideaxis3 = {"joyaxis3_side", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_sideaxis4 = {"joyaxis4_side", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif #ifndef _XBOX consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookaxis3 = {"joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lookaxis4 = {"joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif consvar_t cv_fireaxis2 = {"joyaxis2_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis3 = {"joyaxis3_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fireaxis4 = {"joyaxis4_fire", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_firenaxis3 = {"joyaxis3_firenormal", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_firenaxis4 = {"joyaxis4_firenormal", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -942,8 +966,8 @@ static INT32 Joy2Axis(axis_input_e axissel) // // set secondaryplayer true to build player 2's ticcmd in splitscreen mode // -INT32 localaiming, localaiming2; -angle_t localangle, localangle2; +INT32 localaiming, localaiming2, localaiming3, localaiming4; +angle_t localangle, localangle2, localangle3, localangle4; static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! diff --git a/src/g_input.c b/src/g_input.c index 4d90065e..a8b56a33 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -45,6 +45,8 @@ UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control INT32 gamecontrol[num_gamecontrols][2]; INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player +INT32 gamecontrol3[num_gamecontrols][2]; // tertiary splitscreen player +INT32 gamecontrol4[num_gamecontrols][2]; // quarternary splitscreen player typedef struct { @@ -1293,6 +1295,28 @@ void G_SaveKeySetting(FILE *f) else fprintf(f, "\n"); } + + for (i = 1; i < num_gamecontrols; i++) + { + fprintf(f, "setcontrol3 \"%s\" \"%s\"", gamecontrolname[i], + G_KeynumToString(gamecontrolbis[i][0])); + + if (gamecontrolbis[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); + else + fprintf(f, "\n"); + } + + for (i = 1; i < num_gamecontrols; i++) + { + fprintf(f, "setcontrol4 \"%s\" \"%s\"", gamecontrolname[i], + G_KeynumToString(gamecontrolbis[i][0])); + + if (gamecontrolbis[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); + else + fprintf(f, "\n"); + } } void G_CheckDoubleUsage(INT32 keynum) @@ -1368,3 +1392,33 @@ void Command_Setcontrol2_f(void) setcontrol(gamecontrolbis, na); } + +void Command_Setcontrol3_f(void) +{ + INT32 na; + + na = (INT32)COM_Argc(); + + if (na != 3 && na != 4) + { + CONS_Printf(M_GetText("setcontrol23 [<2nd keyname>]: set controls for player 3\n")); + return; + } + + setcontrol(gamecontrolbis, na); +} + +void Command_Setcontrol4_f(void) +{ + INT32 na; + + na = (INT32)COM_Argc(); + + if (na != 3 && na != 4) + { + CONS_Printf(M_GetText("setcontrol4 [<2nd keyname>]: set controls for player 4\n")); + return; + } + + setcontrol(gamecontrolbis, na); +} \ No newline at end of file diff --git a/src/g_input.h b/src/g_input.h index 50b491ad..42eaaed9 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -139,8 +139,12 @@ extern UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control extern INT32 gamecontrol[num_gamecontrols][2]; extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player +extern INT32 gamecontrol3[num_gamecontrols][2]; +extern INT32 gamecontrol4[num_gamecontrols][2]; #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) +#define PLAYER3INPUTDOWN(gc) (gamekeydown[gamecontrol3[gc][0]] || gamekeydown[gamecontrol3[gc][1]]) +#define PLAYER4INPUTDOWN(gc) (gamekeydown[gamecontrol4[gc][0]] || gamekeydown[gamecontrol4[gc][1]]) // peace to my little coder fingers! // check a gamecontrol being active or not @@ -156,6 +160,8 @@ INT32 G_KeyStringtoNum(const char *keystr); void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); void Command_Setcontrol_f(void); void Command_Setcontrol2_f(void); +void Command_Setcontrol3_f(void); +void Command_Setcontrol4_f(void); void G_Controldefault(void); void G_SaveKeySetting(FILE *f); void G_CheckDoubleUsage(INT32 keynum); diff --git a/src/m_menu.c b/src/m_menu.c index c639d3dc..4c06c3e6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -174,7 +174,9 @@ static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 skullAnimCounter = 10; // skull animation counter static boolean setupcontrols_secondaryplayer; -static INT32 (*setupcontrols)[2]; // pointer to the gamecontrols of the player being edited +static boolean setupcontrols_thirdplayer; +static boolean setupcontrols_fourthplayer; +static INT32 (*setupcontrols)[4]; // pointer to the gamecontrols of the player being edited // shhh... what am I doing... nooooo! static INT32 vidm_testingmode = 0; @@ -267,6 +269,8 @@ static void M_ChooseRoom(INT32 choice); #endif static void M_SetupMultiPlayer(INT32 choice); static void M_SetupMultiPlayer2(INT32 choice); +static void M_SetupMultiPlayer3(INT32 choice); +static void M_SetupMultiPlayer4(INT32 choice); // Options // Split into multiple parts due to size @@ -278,8 +282,12 @@ menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; static void M_VideoModeMenu(INT32 choice); static void M_Setup1PControlsMenu(INT32 choice); static void M_Setup2PControlsMenu(INT32 choice); +static void M_Setup3PControlsMenu(INT32 choice); +static void M_Setup4PControlsMenu(INT32 choice); static void M_Setup1PJoystickMenu(INT32 choice); static void M_Setup2PJoystickMenu(INT32 choice); +static void M_Setup3PJoystickMenu(INT32 choice); +static void M_Setup4PJoystickMenu(INT32 choice); static void M_AssignJoystick(INT32 choice); static void M_ChangeControl(INT32 choice); @@ -883,6 +891,8 @@ static menuitem_t MP_MainMenu[] = {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 1", M_SetupMultiPlayer, 80}, {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 2", M_SetupMultiPlayer2, 90}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 3", M_SetupMultiPlayer3, 100}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 4", M_SetupMultiPlayer4, 110}, }; static menuitem_t MP_ServerMenu[] = @@ -1002,8 +1012,10 @@ static menuitem_t OP_ControlsMenu[] = { {IT_SUBMENU | IT_STRING, NULL, "Player 1 Controls...", &OP_P1ControlsDef, 10}, {IT_SUBMENU | IT_STRING, NULL, "Player 2 Controls...", &OP_P2ControlsDef, 20}, + {IT_SUBMENU | IT_STRING, NULL, "Player 3 Controls...", &OP_P3ControlsDef, 30}, + {IT_SUBMENU | IT_STRING, NULL, "Player 4 Controls...", &OP_P4ControlsDef, 40}, - {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 40}, + {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 60}, }; static menuitem_t OP_P1ControlsMenu[] = @@ -1027,7 +1039,29 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam2 , 50}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 60}, - {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 80}, + {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 70}, +}; + +static menuitem_t OP_P3ControlsMenu[] = +{ + {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup3PControlsMenu, 10}, + {IT_SUBMENU | IT_STRING, NULL, "Third Joystick Options...", &OP_Joystick3Def , 20}, + + {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam3 , 40}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair3, 50}, + + {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog3, 60}, +}; + +static menuitem_t OP_P4ControlsMenu[] = +{ + {IT_CALL | IT_STRING, NULL, "Control Configuration...", M_Setup4PControlsMenu, 10}, + {IT_SUBMENU | IT_STRING, NULL, "Fourth Joystick Options...", &OP_Joystick4Def , 20}, + + {IT_STRING | IT_CVAR, NULL, "Camera" , &cv_chasecam4 , 40}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair4, 50}, + + {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog4, 60}, }; /*static menuitem_t OP_ControlListMenu[] = @@ -1130,6 +1164,28 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis2 , 80}, }; +static menuitem_t OP_Joystick3Menu[] = +{ + {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup3PJoystickMenu, 10}, + {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis3 , 30}, + {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis3 , 40}, + {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis3 , 50}, + {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis3 , 60}, + {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis3 , 70}, + {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis3 , 80}, +}; + +static menuitem_t OP_Joystick4Menu[] = +{ + {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup4PJoystickMenu, 10}, + {IT_STRING | IT_CVAR, NULL, "Axis For Turning" , &cv_turnaxis4 , 30}, + {IT_STRING | IT_CVAR, NULL, "Axis For Moving" , &cv_moveaxis4 , 40}, + {IT_STRING | IT_CVAR, NULL, "Axis For Strafe" , &cv_sideaxis4 , 50}, + {IT_STRING | IT_CVAR, NULL, "Axis For Looking" , &cv_lookaxis4 , 60}, + {IT_STRING | IT_CVAR, NULL, "Axis For Firing" , &cv_fireaxis4 , 70}, + {IT_STRING | IT_CVAR, NULL, "Axis For NFiring" , &cv_firenaxis4 , 80}, +}; + static menuitem_t OP_JoystickSetMenu[] = { {IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, '0'}, @@ -1693,10 +1749,14 @@ menu_t OP_MoveControlsDef = CONTROLMENUSTYLE(OP_MoveControlsMenu, &OP_ControlsDe menu_t OP_CustomControlsDef = CONTROLMENUSTYLE(OP_CustomControlsMenu, &OP_MoveControlsDef); menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_ControlsDef, 60, 30); menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_ControlsDef, 60, 30); +menu_t OP_P3ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P3ControlsMenu, &OP_ControlsDef, 60, 30); +menu_t OP_P4ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P4ControlsMenu, &OP_ControlsDef, 60, 30); menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 60, 30); menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 60, 30); menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 60, 30); menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 60, 30); +menu_t OP_Joystick3Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick3Menu, &OP_P3ControlsDef, 60, 30); +menu_t OP_Joystick4Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick4Menu, &OP_P4ControlsDef, 60, 30); menu_t OP_JoystickSetDef = { "M_CONTRO", @@ -6833,6 +6893,68 @@ static void M_SetupMultiPlayer2(INT32 choice) M_SetupNextMenu(&MP_PlayerSetupDef); } +// start the multiplayer setup menu, for third player (splitscreen mode) +static void M_SetupMultiPlayer3(INT32 choice) +{ + (void)choice; + + multi_state = &states[mobjinfo[MT_PLAYER].seestate]; + multi_tics = multi_state->tics; + strcpy(setupm_name, cv_playername3.string); + + // set for splitscreen third player + setupm_player = &players[thirddisplayplayer]; + setupm_cvskin = &cv_skin3; + setupm_cvcolor = &cv_playercolor3; + setupm_cvname = &cv_playername3; + + // For whatever reason this doesn't work right if you just use ->value + setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); + if (setupm_fakeskin == -1) + setupm_fakeskin = 0; + setupm_fakecolor = setupm_cvcolor->value; + + // disable skin changes if we can't actually change skins + if (splitscreen && !CanChangeSkin(thirddisplayplayer)) + MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + else + MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + + MP_PlayerSetupDef.prevMenu = currentMenu; + M_SetupNextMenu(&MP_PlayerSetupDef); +} + +// start the multiplayer setup menu, for third player (splitscreen mode) +static void M_SetupMultiPlayer4(INT32 choice) +{ + (void)choice; + + multi_state = &states[mobjinfo[MT_PLAYER].seestate]; + multi_tics = multi_state->tics; + strcpy(setupm_name, cv_playername4.string); + + // set for splitscreen fourth player + setupm_player = &players[fourthdisplayplayer]; + setupm_cvskin = &cv_skin4; + setupm_cvcolor = &cv_playercolor4; + setupm_cvname = &cv_playername4; + + // For whatever reason this doesn't work right if you just use ->value + setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); + if (setupm_fakeskin == -1) + setupm_fakeskin = 0; + setupm_fakecolor = setupm_cvcolor->value; + + // disable skin changes if we can't actually change skins + if (splitscreen && !CanChangeSkin(fourthdisplayplayer)) + MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + else + MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + + MP_PlayerSetupDef.prevMenu = currentMenu; + M_SetupNextMenu(&MP_PlayerSetupDef); +} + static boolean M_QuitMultiPlayerMenu(void) { size_t l; @@ -6962,6 +7084,20 @@ static void M_Setup2PJoystickMenu(INT32 choice) M_SetupJoystickMenu(choice); } +static void M_Setup3PJoystickMenu(INT32 choice) +{ + setupcontrols_thirdplayer = true; + OP_JoystickSetDef.prevMenu = &OP_Joystick3Def; + M_SetupJoystickMenu(choice); +} + +static void M_Setup4PJoystickMenu(INT32 choice) +{ + setupcontrols_fourthplayer = true; + OP_JoystickSetDef.prevMenu = &OP_Joystick4Def; + M_SetupJoystickMenu(choice); +} + static void M_AssignJoystick(INT32 choice) { if (setupcontrols_secondaryplayer) @@ -7012,6 +7148,44 @@ static void M_Setup2PControlsMenu(INT32 choice) M_SetupNextMenu(&OP_MoveControlsDef); } +static void M_Setup3PControlsMenu(INT32 choice) +{ + (void)choice; + setupcontrols_thirdplayer = true; + setupcontrols = gamecontrolbis; + currentMenu->lastOn = itemOn; + + // Hide the three non-P3 controls + OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[14].status = IT_GRAYEDOUT2; + // Hide the pause/console controls too + OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; + + OP_MoveControlsDef.prevMenu = &OP_P3ControlsDef; + M_SetupNextMenu(&OP_MoveControlsDef); +} + +static void M_Setup4PControlsMenu(INT32 choice) +{ + (void)choice; + setupcontrols_fourthplayer = true; + setupcontrols = gamecontrolbis; + currentMenu->lastOn = itemOn; + + // Hide the three non-P4 controls + OP_MoveControlsMenu[12].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[13].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[14].status = IT_GRAYEDOUT2; + // Hide the pause/console controls too + OP_MoveControlsMenu[10].status = IT_GRAYEDOUT2; + OP_MoveControlsMenu[11].status = IT_GRAYEDOUT2; + + OP_MoveControlsDef.prevMenu = &OP_P4ControlsDef; + M_SetupNextMenu(&OP_MoveControlsDef); +} + // Draws the Customise Controls menu static void M_DrawControl(void) { diff --git a/src/r_things.h b/src/r_things.h index 6fd65c9b..675579c8 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -68,6 +68,8 @@ void R_DrawMasked(void); // should be all lowercase!! S_SKIN processing does a strlwr #define DEFAULTSKIN "sonic" #define DEFAULTSKIN2 "tails" // secondary player +#define DEFAULTSKIN3 "knuckles" // third player +#define DEFAULTSKIN4 "metalsonic" // fourth player typedef struct {