From fb976ab26c6ea97c3e970a6a3fe742228a8b7371 Mon Sep 17 00:00:00 2001 From: Wolfy Date: Mon, 11 Dec 2017 00:12:38 -0600 Subject: [PATCH] more quad stuff --- src/d_clisrv.c | 22 ++- src/d_main.c | 13 +- src/d_netcmd.c | 136 +++++++++++++++++- src/d_netcmd.h | 4 +- src/doomstat.h | 4 + src/g_game.c | 268 +++++++++++++++++++++++++++++++++-- src/g_game.h | 6 +- src/g_input.c | 45 ++++-- src/g_input.h | 3 +- src/hardware/hw_main.c | 48 ++++++- src/hu_stuff.c | 2 +- src/i_joy.h | 2 +- src/i_system.h | 34 +++++ src/k_kart.c | 2 +- src/m_menu.c | 26 ++-- src/p_local.h | 10 +- src/p_user.c | 28 ++++ src/r_main.c | 66 +++++++++ src/r_main.h | 4 +- src/sdl/Srb2SDL-vc10.vcxproj | 5 + src/sdl/i_system.c | 130 ++++++++++++++++- 21 files changed, 804 insertions(+), 54 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c5cb0c70..0bb3d3db 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -95,6 +95,8 @@ UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. #endif SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) +SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) +SINT8 nodetoplayer4[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen boolean nodeingame[MAXNETNODES]; // set false as nodes leave game static tic_t nettics[MAXNETNODES]; // what tic the client have received @@ -125,6 +127,8 @@ static UINT8 mynode; // my address pointofview server static UINT8 localtextcmd[MAXTEXTCMD]; static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen +static UINT8 localtextcmd3[MAXTEXTCMD]; // splitscreen +static UINT8 localtextcmd4[MAXTEXTCMD]; // splitscreen static tic_t neededtic; SINT8 servernode = 0; // the number of the server node /// \brief do we accept new players? @@ -2313,6 +2317,8 @@ static void Command_connect(void) } splitscreen = false; + splitscreen3 = false; + splitscreen4 = false; SplitScreen_OnChange(); botingame = false; botskin = 0; @@ -3083,7 +3089,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) // Clear player before joining, lest some things get set incorrectly // HACK: don't do this for splitscreen, it relies on preset values - if (!splitscreen && !botingame) + if ((!splitscreen || !splitscreen3 || !splitscreen4) && !botingame) CL_ClearPlayer(newplayernum); playeringame[newplayernum] = true; G_AddPlayer(newplayernum); @@ -3287,7 +3293,7 @@ void SV_StartSinglePlayerServer(void) // no more tic the game with this settings! SV_StopServer(); - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) multiplayer = true; } @@ -4410,9 +4416,19 @@ static void Local_Maketic(INT32 realtics) if (!dedicated) rendergametic = gametic; // translate inputs (keyboard/mouse/joystick) into game controls G_BuildTiccmd(&localcmds, realtics); - if (splitscreen || botingame) + if ((splitscreen || splitscreen3 || splitscreen4) || botingame) + { G_BuildTiccmd2(&localcmds2, realtics); + if (splitscreen3 || splitscreen4) + { + G_BuildTiccmd3(&localcmds3, realtics); + + if (splitscreen4) + G_BuildTiccmd4(&localcmds4, realtics); + } + } + localcmds.angleturn |= TICCMD_RECEIVED; } diff --git a/src/d_main.c b/src/d_main.c index 7cc78b40..7b262998 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -120,7 +120,10 @@ postimg_t postimgtype = postimg_none; INT32 postimgparam; postimg_t postimgtype2 = postimg_none; INT32 postimgparam2; - +postimg_t postimgtype3 = postimg_none; +INT32 postimgparam3; +postimg_t postimgtype4 = postimg_none; +INT32 postimgparam4; #ifdef _XBOX boolean nomidimusic = true, nosound = true; boolean nodigimusic = true; @@ -628,8 +631,12 @@ void D_SRB2Loop(void) // Lagless camera! Yay! if (gamestate == GS_LEVEL && netgame) { - if (splitscreen && camera2.chase) + if ((splitscreen || splitscreen3 || splitscreen4) && camera2.chase) P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false); + if ((splitscreen3 || splitscreen4) && camera3.chase) + P_MoveChaseCamera(&players[thirddisplayplayer], &camera3, false); + if (splitscreen4 && camera4.chase) + P_MoveChaseCamera(&players[fourthdisplayplayer], &camera3, false); if (camera.chase) P_MoveChaseCamera(&players[displayplayer], &camera, false); } @@ -706,6 +713,8 @@ void D_StartTitle(void) CL_ClearPlayer(i); splitscreen = false; + splitscreen3 = false; + splitscreen4 = false; SplitScreen_OnChange(); botingame = false; botskin = 0; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5e0db8d4..20316d99 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1674,6 +1674,30 @@ void SendWeaponPref2(void) SendNetXCmd2(XD_WEAPONPREF, buf, 1); } +void SendWeaponPref3(void) +{ + XBOXSTATIC UINT8 buf[1]; + + buf[0] = 0; + if (players[thirddisplayplayer].pflags & PF_FLIPCAM) + buf[0] |= 1; + if (players[thirddisplayplayer].pflags & PF_ANALOGMODE) + buf[0] |= 2; + //SendNetXCmd3(XD_WEAPONPREF, buf, 1); +} + +void SendWeaponPref4(void) +{ + XBOXSTATIC UINT8 buf[1]; + + buf[0] = 0; + if (players[fourthdisplayplayer].pflags & PF_FLIPCAM) + buf[0] |= 1; + if (players[fourthdisplayplayer].pflags & PF_ANALOGMODE) + buf[0] |= 2; + //SendNetXCmd4(XD_WEAPONPREF, buf, 1); +} + static void Got_WeaponPref(UINT8 **cp,INT32 playernum) { UINT8 prefs = READUINT8(*cp); @@ -1688,11 +1712,19 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) void D_SendPlayerConfig(void) { SendNameAndColor(); - if (splitscreen || botingame) + if ((splitscreen || splitscreen3 || splitscreen4) || botingame) SendNameAndColor2(); + if (splitscreen3 || splitscreen4) + SendNameAndColor3(); + if (splitscreen4) + SendNameAndColor4(); SendWeaponPref(); - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) SendWeaponPref2(); + if (splitscreen3 || splitscreen4) + SendWeaponPref3(); + if (splitscreen4) + SendWeaponPref4(); } // Only works for displayplayer, sorry! @@ -2520,6 +2552,16 @@ static void Command_Teamchange2_f(void) SendNetXCmd2(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } +static void Command_Teamchange3_f(void) +{ + ; +} + +static void Command_Teamchange4_f(void) +{ + ; +} + static void Command_ServerTeamChange_f(void) { changeteam_union NetPacket; @@ -4315,6 +4357,8 @@ void Command_ExitGame_f(void) CL_ClearPlayer(i); splitscreen = false; + splitscreen3 = false; + splitscreen4 = false; SplitScreen_OnChange(); botingame = false; botskin = 0; @@ -4509,6 +4553,28 @@ static void Name2_OnChange(void) SendNameAndColor2(); } +static void Name3_OnChange(void) +{ + if (cv_mute.value) //Third player can't be admin. + { + CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); + CV_StealthSet(&cv_playername3, player_names[thirddisplayplayer]); + } + else + SendNameAndColor3(); +} + +static void Name4_OnChange(void) +{ + if (cv_mute.value) //Secondary player can't be admin. + { + CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); + CV_StealthSet(&cv_playername4, player_names[fourthdisplayplayer]); + } + else + SendNameAndColor4(); +} + /** Sends a skin change for the console player, unless that player is moving. * \sa cv_skin, Skin2_OnChange, Color_OnChange * \author Graue @@ -4541,7 +4607,7 @@ static void Skin_OnChange(void) */ static void Skin2_OnChange(void) { - if (!Playing() || !splitscreen) + if (!Playing() || (!splitscreen || !splitscreen3 || !splitscreen4)) return; // do whatever you want if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer)) @@ -4553,6 +4619,34 @@ static void Skin2_OnChange(void) } } +static void Skin3_OnChange(void) +{ + if (!Playing() || (!splitscreen3 || !splitscreen4)) + return; // do whatever you want + + if (CanChangeSkin(thirddisplayplayer) && !P_PlayerMoving(thirddisplayplayer)) + SendNameAndColor3(); + else + { + CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); + CV_StealthSet(&cv_skin3, skins[players[thirddisplayplayer].skin].name); + } +} + +static void Skin4_OnChange(void) +{ + if (!Playing() || !splitscreen4) + return; // do whatever you want + + if (CanChangeSkin(fourthdisplayplayer) && !P_PlayerMoving(fourthdisplayplayer)) + SendNameAndColor4(); + else + { + CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); + CV_StealthSet(&cv_skin4, skins[players[fourthdisplayplayer].skin].name); + } +} + /** Sends a color change for the console player, unless that player is moving. * \sa cv_playercolor, Color2_OnChange, Skin_OnChange * \author Graue @@ -4587,7 +4681,7 @@ static void Color_OnChange(void) */ static void Color2_OnChange(void) { - if (!Playing() || !splitscreen) + if (!Playing() || (!splitscreen || !splitscreen3 || !splitscreen4)) return; // do whatever you want if (!P_PlayerMoving(secondarydisplayplayer)) @@ -4602,6 +4696,40 @@ static void Color2_OnChange(void) } } +static void Color3_OnChange(void) +{ + if (!Playing() || (!splitscreen3 || !splitscreen4)) + return; // do whatever you want + + if (!P_PlayerMoving(thirddisplayplayer)) + { + // Color change menu scrolling fix is no longer necessary + SendNameAndColor3(); + } + else + { + CV_StealthSetValue(&cv_playercolor3, + players[thirddisplayplayer].skincolor); + } +} + +static void Color4_OnChange(void) +{ + if (!Playing() || !splitscreen4) + return; // do whatever you want + + if (!P_PlayerMoving(fourthdisplayplayer)) + { + // Color change menu scrolling fix is no longer necessary + SendNameAndColor4(); + } + else + { + CV_StealthSetValue(&cv_playercolor4, + players[fourthdisplayplayer].skincolor); + } +} + /** Displays the result of the chat being muted or unmuted. * The server or remote admin should already know and be able to talk * regardless, so this is only displayed to clients. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d9506105..bbac7975 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -87,8 +87,8 @@ extern consvar_t cv_autobalance; extern consvar_t cv_teamscramble; extern consvar_t cv_scrambleonchange; -extern consvar_t cv_useranalog, cv_useranalog2; -extern consvar_t cv_analog, cv_analog2; +extern consvar_t cv_useranalog, cv_useranalog2, cv_useranalog3, cv_useranalog4; +extern consvar_t cv_analog, cv_analog2, cv_analog3, cv_analog4; extern consvar_t cv_netstat; #ifdef WALLSPLATS diff --git a/src/doomstat.h b/src/doomstat.h index 0e04a781..5163a709 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -110,6 +110,10 @@ extern postimg_t postimgtype; extern INT32 postimgparam; extern postimg_t postimgtype2; extern INT32 postimgparam2; +extern postimg_t postimgtype3; +extern INT32 postimgparam3; +extern postimg_t postimgtype4; +extern INT32 postimgparam4; extern INT32 viewwindowx, viewwindowy; extern INT32 viewwidth, scaledviewwidth; diff --git a/src/g_game.c b/src/g_game.c index c3a0f381..0927d213 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -57,6 +57,8 @@ UINT8 botcolor; JoyType_t Joystick; JoyType_t Joystick2; +JoyType_t Joystick3; +JoyType_t Joystick4; // 1024 bytes is plenty for a savegame #define SAVEGAMESIZE (1024) @@ -370,6 +372,8 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_crosshair3 = {"crosshair3", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_crosshair4 = {"crosshair4", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -957,6 +961,162 @@ static INT32 Joy2Axis(axis_input_e axissel) return retaxis; } +static INT32 Joy3Axis(axis_input_e axissel) +{ + INT32 retaxis; + INT32 axisval; + boolean flp = false; + + //find what axis to get + switch (axissel) + { + case AXISTURN: + axisval = cv_turnaxis3.value; + break; + case AXISMOVE: + axisval = cv_moveaxis3.value; + break; + case AXISLOOK: + axisval = cv_lookaxis3.value; + break; + case AXISSTRAFE: + axisval = cv_sideaxis3.value; + break; + case AXISFIRE: + axisval = cv_fireaxis3.value; + break; + case AXISFIRENORMAL: + axisval = cv_firenaxis3.value; + break; + default: + return 0; + } + + + if (axisval < 0) //odd -axises + { + axisval = -axisval; + flp = true; + } +#ifdef _arch_dreamcast + if (axisval == 7) // special case + { + retaxis = joy3xmove[1] - joy3ymove[1]; + goto skipDC; + } + else +#endif + if (axisval > JOYAXISSET*2 || axisval == 0) //not there in array or None + return 0; + + if (axisval%2) + { + axisval /= 2; + retaxis = joy3xmove[axisval]; + } + else + { + axisval--; + axisval /= 2; + retaxis = joy3ymove[axisval]; + } + +#ifdef _arch_dreamcast + skipDC: +#endif + + if (retaxis < (-JOYAXISRANGE)) + retaxis = -JOYAXISRANGE; + if (retaxis > (+JOYAXISRANGE)) + retaxis = +JOYAXISRANGE; + if (!Joystick3.bGamepadStyle && axissel < AXISDEAD) + { + const INT32 jdeadzone = JOYAXISRANGE/4; + if (-jdeadzone < retaxis && retaxis < jdeadzone) + return 0; + } + if (flp) retaxis = -retaxis; //flip it around + return retaxis; +} + +static INT32 Joy3Axis(axis_input_e axissel) +{ + INT32 retaxis; + INT32 axisval; + boolean flp = false; + + //find what axis to get + switch (axissel) + { + case AXISTURN: + axisval = cv_turnaxis4.value; + break; + case AXISMOVE: + axisval = cv_moveaxis4.value; + break; + case AXISLOOK: + axisval = cv_lookaxis4.value; + break; + case AXISSTRAFE: + axisval = cv_sideaxis4.value; + break; + case AXISFIRE: + axisval = cv_fireaxis4.value; + break; + case AXISFIRENORMAL: + axisval = cv_firenaxis4.value; + break; + default: + return 0; + } + + + if (axisval < 0) //odd -axises + { + axisval = -axisval; + flp = true; + } +#ifdef _arch_dreamcast + if (axisval == 7) // special case + { + retaxis = joy4xmove[1] - joy4ymove[1]; + goto skipDC; + } + else +#endif + if (axisval > JOYAXISSET*2 || axisval == 0) //not there in array or None + return 0; + + if (axisval%2) + { + axisval /= 2; + retaxis = joy4xmove[axisval]; + } + else + { + axisval--; + axisval /= 2; + retaxis = joy4ymove[axisval]; + } + +#ifdef _arch_dreamcast + skipDC: +#endif + + if (retaxis < (-JOYAXISRANGE)) + retaxis = -JOYAXISRANGE; + if (retaxis > (+JOYAXISRANGE)) + retaxis = +JOYAXISRANGE; + if (!Joystick4.bGamepadStyle && axissel < AXISDEAD) + { + const INT32 jdeadzone = JOYAXISRANGE/4; + if (-jdeadzone < retaxis && retaxis < jdeadzone) + return 0; + } + if (flp) retaxis = -retaxis; //flip it around + return retaxis; +} + // // G_BuildTiccmd @@ -1680,6 +1840,26 @@ static void UserAnalog2_OnChange(void) CV_SetValue(&cv_analog2, 0); } +static void UserAnalog3_OnChange(void) +{ + if (botingame) + return; + if (cv_useranalog3.value) + CV_SetValue(&cv_analog3, 1); + else + CV_SetValue(&cv_analog3, 0); +} + +static void UserAnalog4_OnChange(void) +{ + if (botingame) + return; + if (cv_useranalog4.value) + CV_SetValue(&cv_analog4, 1); + else + CV_SetValue(&cv_analog4, 0); +} + static void Analog_OnChange(void) { if (!cv_cam_dist.string) @@ -1702,7 +1882,7 @@ static void Analog_OnChange(void) static void Analog2_OnChange(void) { - if (!(splitscreen || botingame) || !cv_cam2_dist.string) + if (!((splitscreen || splitscreen3 || splitscreen4) || botingame) || !cv_cam2_dist.string) return; // cameras are not initialized at this point @@ -1720,6 +1900,46 @@ static void Analog2_OnChange(void) SendWeaponPref2(); } +static void Analog3_OnChange(void) +{ + if (!((splitscreen3 || splitscreen4) || botingame) || !cv_cam3_dist.string) + return; + + // cameras are not initialized at this point + + if (!cv_chasecam3.value && cv_analog3.value) { + CV_SetValue(&cv_analog3, 0); + return; + } + + if (cv_analog3.value) + players[thirddisplayplayer].pflags |= PF_ANALOGMODE; + else + players[thirddisplayplayer].pflags &= ~PF_ANALOGMODE; + + SendWeaponPref3(); +} + +static void Analog4_OnChange(void) +{ + if (!(splitscreen4 || botingame) || !cv_cam4_dist.string) + return; + + // cameras are not initialized at this point + + if (!cv_chasecam4.value && cv_analog4.value) { + CV_SetValue(&cv_analog4, 0); + return; + } + + if (cv_analog4.value) + players[fourthdisplayplayer].pflags |= PF_ANALOGMODE; + else + players[fourthdisplayplayer].pflags &= ~PF_ANALOGMODE; + + SendWeaponPref4(); +} + // // G_DoLoadLevel // @@ -1768,8 +1988,12 @@ void G_DoLoadLevel(boolean resetplayer) if (camera.chase) P_ResetCamera(&players[displayplayer], &camera); - if (camera2.chase && splitscreen) + if (camera2.chase && (splitscreen || splitscreen3 || splitscreen4)) P_ResetCamera(&players[secondarydisplayplayer], &camera2); + if (camera3.chase && (splitscreen3 || splitscreen4)) + P_ResetCamera(&players[thirddisplayplayer], &camera3); + if (camera4.chase && splitscreen4) + P_ResetCamera(&players[fourthdisplayplayer], &camera4); // clear cmd building stuff memset(gamekeydown, 0, sizeof (gamekeydown)); @@ -1777,6 +2001,8 @@ void G_DoLoadLevel(boolean resetplayer) { joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; + joy3xmove[i] = joy3ymove[i] = 0; + joy4xmove[i] = joy4ymove[i] = 0; } mousex = mousey = 0; mouse2x = mouse2y = 0; @@ -1786,7 +2012,7 @@ void G_DoLoadLevel(boolean resetplayer) } static INT32 pausedelay = 0; -static INT32 camtoggledelay, camtoggledelay2 = 0; +static INT32 camtoggledelay, camtoggledelay2, camtoggledelay3, camtoggledelay4 = 0; // // G_Responder @@ -1797,7 +2023,7 @@ boolean G_Responder(event_t *ev) // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown && ev->data1 == KEY_F12) { - if (splitscreen || !netgame) + if ((splitscreen || splitscreen3 || splitscreen4) || !netgame) displayplayer = consoleplayer; else { @@ -1974,6 +2200,24 @@ boolean G_Responder(event_t *ev) CV_SetValue(&cv_chasecam2, cv_chasecam2.value ? 0 : 1); } } + if (ev->data1 == gamecontrol3[gc_camtoggle][0] + || ev->data1 == gamecontrol3[gc_camtoggle][1]) + { + if (!camtoggledelay3) + { + camtoggledelay3 = NEWTICRATE / 7; + CV_SetValue(&cv_chasecam3, cv_chasecam3.value ? 0 : 1); + } + } + if (ev->data1 == gamecontrol4[gc_camtoggle][0] + || ev->data1 == gamecontrol4[gc_camtoggle][1]) + { + if (!camtoggledelay4) + { + camtoggledelay4 = NEWTICRATE / 7; + CV_SetValue(&cv_chasecam4, cv_chasecam4.value ? 0 : 1); + } + } return true; case ev_keyup: @@ -2508,13 +2752,13 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) { if (nummapthings) { - if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer)) + if (playernum == consoleplayer || ((splitscreen || splitscreen3 || splitscreen4) && playernum == secondarydisplayplayer) || ((splitscreen3 || splitscreen4) && playernum == thirddisplayplayer) || (splitscreen4 && playernum == fourthdisplayplayer)) CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the first mapthing!\n")); spawnpoint = &mapthings[0]; } else { - if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer)) + if (playernum == consoleplayer || ((splitscreen || splitscreen3 || splitscreen4) && playernum == secondarydisplayplayer) || ((splitscreen3 || splitscreen4) && playernum == thirddisplayplayer) || (splitscreen4 && playernum == fourthdisplayplayer)) CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the origin!\n")); //P_MovePlayerToSpawn handles this fine if the spawnpoint is NULL. } @@ -2713,8 +2957,12 @@ void G_DoReborn(INT32 playernum) if (camera.chase) P_ResetCamera(&players[displayplayer], &camera); - if (camera2.chase && splitscreen) + if (camera2.chase && (splitscreen || splitscreen3 || splitscreen4)) P_ResetCamera(&players[secondarydisplayplayer], &camera2); + if (camera3.chase && (splitscreen3 || splitscreen4)) + P_ResetCamera(&players[thirddisplayplayer], &camera3); + if (camera4.chase && splitscreen4) + P_ResetCamera(&players[fourthdisplayplayer], &camera4); // clear cmd building stuff memset(gamekeydown, 0, sizeof (gamekeydown)); @@ -2722,6 +2970,8 @@ void G_DoReborn(INT32 playernum) { joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; + joy3xmove[i] = joy3ymove[i] = 0; + joy4xmove[i] = joy4ymove[i] = 0; } mousex = mousey = 0; mouse2x = mouse2y = 0; @@ -3523,7 +3773,7 @@ static void M_ForceLoadGameResponse(INT32 ch) cursaveslot = -1; displayplayer = consoleplayer; - multiplayer = splitscreen = false; + multiplayer = splitscreen = splitscreen3 = splitscreen4 = false; if (setsizeneeded) R_ExecuteSetViewSize(); @@ -3611,7 +3861,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) // gameaction = ga_nothing; // G_SetGamestate(GS_LEVEL); displayplayer = consoleplayer; - multiplayer = splitscreen = false; + multiplayer = splitscreen = splitscreen3 = splitscreen4 = false; // G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1); if (setsizeneeded) diff --git a/src/g_game.h b/src/g_game.h index a60f7561..9369665c 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,10 +54,12 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu -extern consvar_t cv_crosshair, cv_crosshair2; +extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; +extern consvar_t cv_sideaxis3,cv_turnaxis3,cv_moveaxis3,cv_lookaxis3,cv_fireaxis3,cv_firenaxis3; +extern consvar_t cv_sideaxis4,cv_turnaxis4,cv_moveaxis4,cv_lookaxis4,cv_fireaxis4,cv_firenaxis4; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_last, cv_ghost_guest, cv_ghost_staff; //cv_ghost_bestlap // mouseaiming (looking up/down with the mouse or keyboard) @@ -79,7 +81,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n); INT16 G_ClipAimingPitch(INT32 *aiming); INT16 G_SoftwareClipAimingPitch(INT32 *aiming); -extern angle_t localangle, localangle2; +extern angle_t localangle, localangle2, localangle3, localangle4; extern INT32 localaiming, localaiming2; // should be an angle_t but signed // diff --git a/src/g_input.c b/src/g_input.c index a8b56a33..0b2573a9 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -37,7 +37,8 @@ INT32 mlooky; // like mousey but with a custom sensitivity for mlook INT32 mouse2x, mouse2y, mlook2y; // joystick values are repeated -INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; +INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET], +joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET]; // current state of the keys: true if pushed UINT8 gamekeydown[NUMINPUTS]; @@ -58,6 +59,8 @@ static dclick_t mousedclicks[MOUSEBUTTONS]; static dclick_t joydclicks[JOYBUTTONS + JOYHATS*4]; static dclick_t mouse2dclicks[MOUSEBUTTONS]; static dclick_t joy2dclicks[JOYBUTTONS + JOYHATS*4]; +static dclick_t joy3dclicks[JOYBUTTONS + JOYHATS*4]; +static dclick_t joy4dclicks[JOYBUTTONS + JOYHATS*4]; // protos static UINT8 G_CheckDoubleClick(UINT8 state, dclick_t *dt); @@ -121,6 +124,22 @@ void G_MapEventsToControls(event_t *ev) if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3; break; + case ev_joystick3: + i = ev->data1; + if (i >= JOYAXISSET) + break; + if (ev->data2 != INT32_MAX) joy3xmove[i] = ev->data2; + if (ev->data3 != INT32_MAX) joy3ymove[i] = ev->data3; + break; + + case ev_joystick4: + i = ev->data1; + if (i >= JOYAXISSET) + break; + if (ev->data2 != INT32_MAX) joy4xmove[i] = ev->data2; + if (ev->data3 != INT32_MAX) joy4ymove[i] = ev->data3; + break; + case ev_mouse2: // buttons are virtual keys mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f)); mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f)); @@ -1299,10 +1318,10 @@ void G_SaveKeySetting(FILE *f) for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol3 \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(gamecontrolbis[i][0])); + G_KeynumToString(gamecontrol3[i][0])); - if (gamecontrolbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); + if (gamecontrol3[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol3[i][1])); else fprintf(f, "\n"); } @@ -1310,10 +1329,10 @@ void G_SaveKeySetting(FILE *f) for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol4 \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(gamecontrolbis[i][0])); + G_KeynumToString(gamecontrol4[i][0])); - if (gamecontrolbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); + if (gamecontrol4[i][1]) + fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol4[i][1])); else fprintf(f, "\n"); } @@ -1334,6 +1353,14 @@ void G_CheckDoubleUsage(INT32 keynum) gamecontrolbis[i][0] = KEY_NULL; if (gamecontrolbis[i][1] == keynum) gamecontrolbis[i][1] = KEY_NULL; + if (gamecontrol3[i][0] == keynum) + gamecontrol3[i][0] = KEY_NULL; + if (gamecontrol3[i][1] == keynum) + gamecontrol3[i][1] = KEY_NULL; + if (gamecontrol4[i][0] == keynum) + gamecontrol4[i][0] = KEY_NULL; + if (gamecontrol4[i][1] == keynum) + gamecontrol4[i][1] = KEY_NULL; } } } @@ -1405,7 +1432,7 @@ void Command_Setcontrol3_f(void) return; } - setcontrol(gamecontrolbis, na); + setcontrol(gamecontrol3, na); } void Command_Setcontrol4_f(void) @@ -1420,5 +1447,5 @@ void Command_Setcontrol4_f(void) return; } - setcontrol(gamecontrolbis, na); + setcontrol(gamecontrol4, na); } \ No newline at end of file diff --git a/src/g_input.h b/src/g_input.h index 42eaaed9..180816ae 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -131,7 +131,8 @@ extern INT32 mousex, mousey; extern INT32 mlooky; //mousey with mlookSensitivity extern INT32 mouse2x, mouse2y, mlook2y; -extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; +extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET], +joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET]; // current state of the keys: true if pushed extern UINT8 gamekeydown[NUMINPUTS]; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a4785f12..3797e94b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4055,8 +4055,18 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t angle_t shadowdir; // Set direction - if (splitscreen && stplyr != &players[displayplayer]) + if ((splitscreen || splitscreen3 || splitscreen4) && stplyr != &players[displayplayer]) + { shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); + + if ((splitscreen3 || splitscreen4) && stplyr != &players[displayplayer]) + { + shadowdir = localangle3 + FixedAngle(cv_cam3_rotate.value); + + if (splitscreen4 && stplyr != &players[displayplayer]) + shadowdir = localangle4 + FixedAngle(cv_cam4_rotate.value); + } + } else shadowdir = localangle + FixedAngle(cv_cam_rotate.value); @@ -5534,8 +5544,12 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) FTransform stransform; postimg_t *type; - if (splitscreen && player == &players[secondarydisplayplayer]) + if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) type = &postimgtype2; + else if ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + type = &postimgtype3; + else if (splitscreen4 && player == &players[fourthdisplayplayer]) + type = &postimgtype4; else type = &postimgtype; @@ -5563,7 +5577,13 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) gr_centery = gr_basecentery; gr_viewwindowy = gr_baseviewwindowy; gr_windowcentery = gr_basewindowcentery; - if (splitscreen && viewnumber == 1) + if ((splitscreen || splitscreen3) && (viewnumber == 1 || viewnumber == 2)) + { + gr_viewwindowy += (vid.height/2); + gr_windowcentery += (vid.height/2); + } + + if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) { gr_viewwindowy += (vid.height/2); gr_windowcentery += (vid.height/2); @@ -5641,7 +5661,7 @@ if (0) #endif //Hurdler: it doesn't work in splitscreen mode - drawsky = splitscreen; + drawsky = splitscreen || splitscreen3 || splitscreen4; HWR_ClearSprites(); @@ -5661,8 +5681,12 @@ if (0) // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; - else if (splitscreen && player == &players[secondarydisplayplayer]) + else if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) viewangle = localaiming2; + else if ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + viewangle = localaiming3; + else if (splitscreen4 && player == &players[fourthdisplayplayer]) + viewangle = localaiming4; // Handle stuff when you are looking farther up or down. if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) @@ -5753,8 +5777,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) FRGBAFloat ClearColor; - if (splitscreen && player == &players[secondarydisplayplayer]) + if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) type = &postimgtype2; + else if ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + type = &postimgtype3; + else if (splitscreen4 && player == &players[fourthdisplayplayer]) + type = &postimgtype4; else type = &postimgtype; @@ -5793,7 +5821,13 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) gr_centery = gr_basecentery; gr_viewwindowy = gr_baseviewwindowy; gr_windowcentery = gr_basewindowcentery; - if (splitscreen && viewnumber == 1) + if ((splitscreen || splitscreen3) && (viewnumber == 1 || viewnumber == 2)) + { + gr_viewwindowy += (vid.height/2); + gr_windowcentery += (vid.height/2); + } + + if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) { gr_viewwindowy += (vid.height/2); gr_windowcentery += (vid.height/2); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 231edb90..72d465dc 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1802,7 +1802,7 @@ static void HU_DrawRankings(void) HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer); // draw spectators in a ticker across the bottom - if (!splitscreen && G_GametypeHasSpectators()) + if ((!splitscreen || !splitscreen3 || !splitscreen4) && G_GametypeHasSpectators()) HU_DrawSpectatorTicker(); } diff --git a/src/i_joy.h b/src/i_joy.h index 5cba1af0..316011fc 100644 --- a/src/i_joy.h +++ b/src/i_joy.h @@ -53,6 +53,6 @@ typedef struct JoyType_s JoyType_t; for palyer 1 and 2's joystick/gamepad */ -extern JoyType_t Joystick, Joystick2; +extern JoyType_t Joystick, Joystick2, Joystick3, Joystick4; #endif // __I_JOY_H__ diff --git a/src/i_system.h b/src/i_system.h index d61f2d16..a166629b 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -138,6 +138,24 @@ void I_Tactile(FFType Type, const JoyFF_t *Effect); */ void I_Tactile2(FFType Type, const JoyFF_t *Effect); +/** \brief Forcefeedback for the third joystick + +\param Type what kind of Effect +\param Effect Effect Info + +\return void +*/ +void I_Tactile3(FFType Type, const JoyFF_t *Effect); + +/** \brief Forcefeedback for the fourth joystick + +\param Type what kind of Effect +\param Effect Effect Info + +\return void +*/ +void I_Tactile4(FFType Type, const JoyFF_t *Effect); + /** \brief to set up the first joystick scale */ void I_JoyScale(void); @@ -146,6 +164,14 @@ void I_JoyScale(void); */ void I_JoyScale2(void); +/** \brief to set up the third joystick scale +*/ +void I_JoyScale3(void); + +/** \brief to set up the fourth joystick scale +*/ +void I_JoyScale4(void); + // Called by D_SRB2Main. /** \brief to startup the first joystick @@ -156,6 +182,14 @@ void I_InitJoystick(void); */ void I_InitJoystick2(void); +/** \brief to startup the third joystick +*/ +void I_InitJoystick3(void); + +/** \brief to startup the fourth joystick +*/ +void I_InitJoystick4(void); + /** \brief return the number of joystick on the system */ INT32 I_NumJoys(void); diff --git a/src/k_kart.c b/src/k_kart.c index df25cfa8..f79b5f1e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4057,7 +4057,7 @@ void K_LoadKartHUDGraphics(void) static INT32 STRINGY(INT32 y) { // Copied from st_stuff.c - if (splitscreen) + if (splitscreen || splitscreen3) { y >>= 1; if (stplyr != &players[displayplayer]) diff --git a/src/m_menu.c b/src/m_menu.c index 4c06c3e6..fb9fb0d4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -277,8 +277,8 @@ static void M_SetupMultiPlayer4(INT32 choice); // Controls menu_t OP_ControlsDef, /*OP_ControlListDef,*/ OP_MoveControlsDef; menu_t /*OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef,*/ OP_CustomControlsDef; -menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef; -menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; +menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_P3ControlsDef, OP_P4ControlsDef, OP_MouseOptionsDef; +menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def, OP_Joystick3Def, OP_Joystick4Def; static void M_VideoModeMenu(INT32 choice); static void M_Setup1PControlsMenu(INT32 choice); static void M_Setup2PControlsMenu(INT32 choice); @@ -888,11 +888,13 @@ static menuitem_t MP_MainMenu[] = {IT_CALL | IT_STRING, NULL, "JOIN GAME (Specify IP)", M_ConnectIPMenu, 40}, #endif {IT_CALL | IT_STRING, NULL, "TWO PLAYER GAME", M_StartSplitServerMenu, 60}, + {IT_CALL | IT_STRING, NULL, "THREE PLAYER GAME", M_StartSplitServerMenu, 70}, + {IT_CALL | IT_STRING, NULL, "FOUR PLAYER GAME", M_StartSplitServerMenu, 80}, - {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}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 1", M_SetupMultiPlayer, 100}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 2", M_SetupMultiPlayer2, 110}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 3", M_SetupMultiPlayer3, 120}, + {IT_CALL | IT_STRING, NULL, "SETUP PLAYER 4", M_SetupMultiPlayer4, 130}, }; static menuitem_t MP_ServerMenu[] = @@ -7114,6 +7116,8 @@ static void M_Setup1PControlsMenu(INT32 choice) { (void)choice; setupcontrols_secondaryplayer = false; + setupcontrols_thirdplayer = false; + setupcontrols_fourthplayer = false; setupcontrols = gamecontrol; // was called from main Options (for console player, then) currentMenu->lastOn = itemOn; @@ -7133,6 +7137,8 @@ static void M_Setup2PControlsMenu(INT32 choice) { (void)choice; setupcontrols_secondaryplayer = true; + setupcontrols_thirdplayer = false; + setupcontrols_fourthplayer = false; setupcontrols = gamecontrolbis; currentMenu->lastOn = itemOn; @@ -7152,7 +7158,9 @@ static void M_Setup3PControlsMenu(INT32 choice) { (void)choice; setupcontrols_thirdplayer = true; - setupcontrols = gamecontrolbis; + setupcontrols_secondaryplayer = false; + setupcontrols_fourthplayer = false; + setupcontrols = gamecontrol3; currentMenu->lastOn = itemOn; // Hide the three non-P3 controls @@ -7171,7 +7179,9 @@ static void M_Setup4PControlsMenu(INT32 choice) { (void)choice; setupcontrols_fourthplayer = true; - setupcontrols = gamecontrolbis; + setupcontrols_secondaryplayer = false; + setupcontrols_thirdplayer = false; + setupcontrols = gamecontrol4; currentMenu->lastOn = itemOn; // Hide the three non-P4 controls diff --git a/src/p_local.h b/src/p_local.h index 673aa4fc..c8a4095e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -109,15 +109,23 @@ typedef struct camera_s fixed_t momx, momy, momz; } camera_t; -extern camera_t camera, camera2; +extern camera_t camera, camera2, camera3, camera4; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed; extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height; extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed; +extern consvar_t cv_cam3_dist, cv_cam3_still, cv_cam3_height; +extern consvar_t cv_cam3_speed, cv_cam3_rotate, cv_cam3_rotspeed; + +extern consvar_t cv_cam4_dist, cv_cam4_still, cv_cam4_height; +extern consvar_t cv_cam4_speed, cv_cam4_rotate, cv_cam4_rotspeed; + extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; +extern fixed_t t_cam3_dist, t_cam3_height, t_cam3_rotate; +extern fixed_t t_cam4_dist, t_cam4_height, t_cam4_rotate; fixed_t P_GetPlayerHeight(player_t *player); fixed_t P_GetPlayerSpinHeight(player_t *player); diff --git a/src/p_user.c b/src/p_user.c index 5e47cdde..d4f01a03 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8090,6 +8090,22 @@ static void CV_CamRotate2_OnChange(void) CV_SetValue(&cv_cam2_rotate, cv_cam2_rotate.value % 360); } +static void CV_CamRotate3_OnChange(void) +{ + if (cv_cam3_rotate.value < 0) + CV_SetValue(&cv_cam3_rotate, cv_cam3_rotate.value + 360); + else if (cv_cam3_rotate.value > 359) + CV_SetValue(&cv_cam3_rotate, cv_cam3_rotate.value % 360); +} + +static void CV_CamRotate4_OnChange(void) +{ + if (cv_cam4_rotate.value < 0) + CV_SetValue(&cv_cam4_rotate, cv_cam4_rotate.value + 360); + else if (cv_cam4_rotate.value > 359) + CV_SetValue(&cv_cam4_rotate, cv_cam4_rotate.value % 360); +} + static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; @@ -8106,6 +8122,18 @@ consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_dist = {"cam3_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_height = {"cam3_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_still = {"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_speed = {"cam3_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_rotate = {"cam3_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam3_rotspeed = {"cam3_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_dist = {"cam4_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_height = {"cam4_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_still = {"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_speed = {"cam4_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_rotate = {"cam4_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate4_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam4_rotspeed = {"cam4_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; fixed_t t_cam_dist = -42; fixed_t t_cam_height = -42; diff --git a/src/r_main.c b/src/r_main.c index e50e8001..93222deb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -134,16 +134,26 @@ static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Fla static void ChaseCam_OnChange(void); static void ChaseCam2_OnChange(void); +static void ChaseCam3_OnChange(void); +static void ChaseCam4_OnChange(void); static void FlipCam_OnChange(void); static void FlipCam2_OnChange(void); +static void FlipCam3_OnChange(void); +static void FlipCam4_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); +void SendWeaponPref3(void); +void SendWeaponPref4(void); consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasecam = {"chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chasecam3 = {"chasecam3", "On", CV_CALL, CV_OnOff, ChaseCam3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chasecam4 = {"chasecam4", "On", CV_CALL, CV_OnOff, ChaseCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_flipcam3 = {"flipcam3", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam3_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_flipcam4 = {"flipcam4", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -220,6 +230,26 @@ static void ChaseCam2_OnChange(void) CV_SetValue(&cv_analog2, 1); } +static void ChaseCam3_OnChange(void) +{ + if (botingame) + return; + if (!cv_chasecam3.value || !cv_useranalog3.value) + CV_SetValue(&cv_analog3, 0); + else + CV_SetValue(&cv_analog3, 1); +} + +static void ChaseCam4_OnChange(void) +{ + if (botingame) + return; + if (!cv_chasecam4.value || !cv_useranalog4.value) + CV_SetValue(&cv_analog4, 0); + else + CV_SetValue(&cv_analog4, 1); +} + static void FlipCam_OnChange(void) { if (cv_flipcam.value) @@ -240,6 +270,26 @@ static void FlipCam2_OnChange(void) SendWeaponPref2(); } +static void FlipCam3_OnChange(void) +{ + if (cv_flipcam3.value) + players[thirddisplayplayer].pflags |= PF_FLIPCAM; + else + players[thirddisplayplayer].pflags &= ~PF_FLIPCAM; + + SendWeaponPref3(); +} + +static void FlipCam4_OnChange(void) +{ + if (cv_flipcam4.value) + players[fourthdisplayplayer].pflags |= PF_FLIPCAM; + else + players[fourthdisplayplayer].pflags &= ~PF_FLIPCAM; + + SendWeaponPref4(); +} + // // R_PointOnSide // Traverse BSP (sub) tree, @@ -1379,6 +1429,8 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam2); + CV_RegisterVar(&cv_chasecam3); + CV_RegisterVar(&cv_chasecam4); CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_shadowoffs); CV_RegisterVar(&cv_skybox); @@ -1397,6 +1449,20 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_cam2_rotate); CV_RegisterVar(&cv_cam2_rotspeed); + CV_RegisterVar(&cv_cam3_dist); + CV_RegisterVar(&cv_cam3_still); + CV_RegisterVar(&cv_cam3_height); + CV_RegisterVar(&cv_cam3_speed); + CV_RegisterVar(&cv_cam3_rotate); + CV_RegisterVar(&cv_cam3_rotspeed); + + CV_RegisterVar(&cv_cam4_dist); + CV_RegisterVar(&cv_cam4_still); + CV_RegisterVar(&cv_cam4_height); + CV_RegisterVar(&cv_cam4_speed); + CV_RegisterVar(&cv_cam4_rotate); + CV_RegisterVar(&cv_cam4_rotspeed); + CV_RegisterVar(&cv_showhud); CV_RegisterVar(&cv_translucenthud); diff --git a/src/r_main.h b/src/r_main.h index 2e768cb9..cabf17b6 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -73,8 +73,8 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe extern consvar_t cv_showhud, cv_translucenthud; extern consvar_t cv_homremoval; -extern consvar_t cv_chasecam, cv_chasecam2; -extern consvar_t cv_flipcam, cv_flipcam2; +extern consvar_t cv_chasecam, cv_chasecam2, cv_chasecam3, cv_chasecam4; +extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4; extern consvar_t cv_shadow, cv_shadowoffs; extern consvar_t cv_translucency; extern consvar_t cv_precipdensity, cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index b6c42f3f..4d1ed0a5 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -77,6 +77,11 @@ <_ProjectFileVersion>10.0.30319.1 false + + + false + + {72b01aca-7a1a-4f7b-acef-2607299cf052} diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index bd4c93a6..7f3f2791 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -209,10 +209,26 @@ SDLJoyInfo_t JoyInfo; */ static INT32 joystick2_started = 0; -/** \brief SDL inof about joystick 2 +/** \brief SDL info about joystick 2 */ SDLJoyInfo_t JoyInfo2; +/** \brief Third joystick up and running +*/ +static INT32 joystick3_started = 0; + +/** \brief SDL info about joystick 3 +*/ +SDLJoyInfo_t JoyInfo3; + +/** \brief Fourth joystick up and running +*/ +static INT32 joystick4_started = 0; + +/** \brief SDL info about joystick 4 +*/ +SDLJoyInfo_t JoyInfo4; + #ifdef HAVE_TERMIOS static INT32 fdmouse2 = -1; static INT32 mouse2_started = 0; @@ -821,6 +837,18 @@ void I_JoyScale2(void) JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value; } +void I_JoyScale3(void) +{ + Joystick3.bGamepadStyle = cv_joyscale3.value==0; + JoyInfo3.scale = Joystick3.bGamepadStyle?1:cv_joyscale3.value; +} + +void I_JoyScale4(void) +{ + Joystick4.bGamepadStyle = cv_joyscale4.value==0; + JoyInfo4.scale = Joystick4.bGamepadStyle?1:cv_joyscale4.value; +} + /** \brief Joystick 1 buttons states */ static UINT64 lastjoybuttons = 0; @@ -1161,6 +1189,54 @@ static void I_ShutdownJoystick2(void) } } +/** \brief Shuts down joystick 3 + + +\return void +*/ +static void I_ShutdownJoystick3(void) +{ + INT32 i; + event_t event; + event.type = ev_keyup; + event.data2 = 0; + event.data3 = 0; + + lastjoy3buttons = lastjoy3hats = 0; + + // emulate the up of all joystick buttons + for (i = 0; i < JOYBUTTONS; i++) + { + event.data1 = KEY_2JOY1 + i; + D_PostEvent(&event); + } + + // emulate the up of all joystick hats + for (i = 0; i < JOYHATS*4; i++) + { + event.data1 = KEY_2HAT1 + i; + D_PostEvent(&event); + } + + // reset joystick position + event.type = ev_joystick3; + for (i = 0; i < JOYAXISSET; i++) + { + event.data1 = i; + D_PostEvent(&event); + } + + JoyReset(&JoyInfo3); + if (!joystick_started && !joystick3_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + if (cv_usejoystick3.value == 0) + { + DEBFILE("I_Joystick3: SDL's Joystick system has been shutdown\n"); + } + } +} + void I_GetJoystick2Events(void) { static event_t event = {0,0,0,0}; @@ -1420,12 +1496,46 @@ void I_InitJoystick2(void) joystick2_started = 1; } +void I_InitJoystick3(void) +{ + //I_ShutdownJoystick3(); + SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); + if (!strcmp(cv_usejoystick3.string, "0") || M_CheckParm("-nojoy")) + return; + /*if (joy_open3(cv_usejoystick3.string) != -1) + JoyInfo3.oldjoy = atoi(cv_usejoystick3.string); + else + { + cv_usejoystick3.value = 0; + return; + } + joystick3_started = 1;*/ +} + +void I_InitJoystick4(void) +{ + //I_ShutdownJoystick4(); + SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); + if (!strcmp(cv_usejoystick3.string, "0") || M_CheckParm("-nojoy")) + return; + /*if (joy_open4(cv_usejoystick4.string) != -1) + JoyInfo4.oldjoy = atoi(cv_usejoystick4.string); + else + { + cv_usejoystick4.value = 0; + return; + } + joystick4_started = 1;*/ +} + static void I_ShutdownInput(void) { if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) { JoyReset(&JoyInfo); JoyReset(&JoyInfo2); + JoyReset(&JoyInfo3); + JoyReset(&JoyInfo4); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } @@ -1954,6 +2064,24 @@ FUNCMATH ticcmd_t *I_BaseTiccmd2(void) return &emptycmd2; } +/** \brief empty ticcmd for player 3 +*/ +static ticcmd_t emptycmd3; + +FUNCMATH ticcmd_t *I_BaseTiccmd3(void) +{ + return &emptycmd3; +} + +/** \brief empty ticcmd for player 4 +*/ +static ticcmd_t emptycmd4; + +FUNCMATH ticcmd_t *I_BaseTiccmd4(void) +{ + return &emptycmd4; +} + #if defined (_WIN32) static HMODULE winmm = NULL; static DWORD starttickcount = 0; // hack for win2k time bug