diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7b3925e9..9bbb73ef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -129,6 +129,8 @@ static void Command_StopMovie_f(void); static void Command_Map_f(void); static void Command_ResetCamera_f(void); +static void Command_View_f (void); + static void Command_Addfile(void); static void Command_ListWADS_f(void); #ifdef DELFILE @@ -708,6 +710,11 @@ void D_RegisterClientCommands(void) COM_AddCommand("resetcamera", Command_ResetCamera_f); + COM_AddCommand("view", Command_View_f); + COM_AddCommand("view2", Command_View_f); + COM_AddCommand("view3", Command_View_f); + COM_AddCommand("view4", Command_View_f); + COM_AddCommand("setcontrol", Command_Setcontrol_f); COM_AddCommand("setcontrol2", Command_Setcontrol2_f); COM_AddCommand("setcontrol3", Command_Setcontrol3_f); @@ -1885,6 +1892,138 @@ static void Command_ResetCamera_f(void) P_ResetCamera(&players[displayplayer], &camera); } +static INT32 +RoundToValidPlayerNum (INT32 playernum) +{ + INT32 playernuml, playernumr; + for (playernuml = playernum; --playernuml > 0; ) + { + if (playeringame[playernuml]) + break; + } + for (playernumr = playernum ;; ) + { + if (++playernumr == MAXPLAYERS) + { + playernum = playernuml; + break; + } + if (playeringame[playernumr]) + { + if (playernum - playernuml < playernumr - playernum) + playernum = playernuml;/* "round" down */ + else + playernum = playernumr; + break; + } + } + return playernum; +} + +static INT32/* Consider replacing nametonum with this */ +LookupPlayer (const char *s) +{ + INT32 playernum; + + if (*s == '0')/* clever way to bypass atoi */ + return 0; + + if (( playernum = atoi(s) )) + { + playernum = max(min(playernum, MAXPLAYERS-1), 0);/* not out of range */ + return playernum; + } + + for (playernum = 0; playernum < MAXPLAYERS; ++playernum) + { + /* Consider strcasestr? */ + /* Match name (case-insensitively) fully, or partially the start. */ + if (playeringame[playernum]) + if (stricmp(player_names[playernum], s) == 0 || + strstr(player_names[playernum], s) == player_names[playernum] ) + { + return playernum; + } + } + return -1;/* We can't "round" a name! */ +} + +#define PRINTVIEWPOINT( pre,suf ) \ + CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\ + (*displayplayerp), player_names[(*displayplayerp)]); +static void +Command_View_f (void) +{ + INT32 *displayplayerp; + int viewnum; + INT32 playernum, oldplayernum; + char c; + /* easy peasy */ + c = COM_Argv(0)[strlen(COM_Argv(0))-1];/* may be digit */ + switch (c) + { + case '2': viewnum = 2; break; + case '3': viewnum = 3; break; + case '4': viewnum = 4; break; + default: viewnum = 1; + } + displayplayerp = G_GetDisplayplayerPtr(viewnum); + + if (COM_Argc() > 1)/* switch to player */ + { + if (viewnum > splitscreen+2)/* We must arrange in order. */ + { + CONS_Alert(CONS_WARNING, + "You may not change viewpoints more than " + "once ahead the current number of splits. " + "Use view%d instead.\n", splitscreen+2); + return; + } + + if (( playernum = LookupPlayer(COM_Argv(1)) ) == -1) + { + CONS_Alert(CONS_WARNING, "There is no player by that name!\n"); + return; + } + + oldplayernum = playernum; + + if (!playeringame[playernum]) + { + playernum = RoundToValidPlayerNum(playernum); + } + + if ((*displayplayerp) == playernum) + return; + + (*displayplayerp) = playernum; + G_ResetViews(viewnum); + + if ((*displayplayerp) != oldplayernum)/* differ parameter */ + { + if (playernum == oldplayernum)/* skipped some */ + { + CONS_Alert(CONS_NOTICE, + "Another viewpoint is already set to that player.\n"); + } + else + { + CONS_Alert(CONS_NOTICE, "There is no player using that slot.\n"); + } + PRINTVIEWPOINT ("Now "," instead") + } + else + PRINTVIEWPOINT ("Now ",) + } + else/* print current view */ + { + if (splitscreen < viewnum-1)/* We can't see those guys! */ + return; + PRINTVIEWPOINT ("Currently ",) + } +} +#undef PRINTVIEWPOINT + // ======================================================================== // play a demo, add .lmp for external demos diff --git a/src/g_game.c b/src/g_game.c index 63e5fb72..c6c091fc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1825,13 +1825,9 @@ boolean G_Responder(event_t *ev) { if (!splitscreen) { - splitscreen = 1; secondarydisplayplayer = displayplayer; G_ResetViews(2); - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - R_ExecuteSetViewSize(); - return true; } @@ -1844,13 +1840,9 @@ boolean G_Responder(event_t *ev) { if (splitscreen == 1) { - splitscreen = 2; thirddisplayplayer = displayplayer; G_ResetViews(3); - P_ResetCamera(&players[thirddisplayplayer], &camera3); - R_ExecuteSetViewSize(); - return true; } @@ -1863,13 +1855,9 @@ boolean G_Responder(event_t *ev) { if (splitscreen == 2) { - splitscreen = 3; fourthdisplayplayer = displayplayer; G_ResetViews(4); - P_ResetCamera(&players[fourthdisplayplayer], &camera4); - R_ExecuteSetViewSize(); - return true; } @@ -2156,6 +2144,18 @@ static INT32 G_FindView(INT32 startview) return startview; } +INT32 * +G_GetDisplayplayerPtr (UINT8 viewnum) +{ + switch (viewnum) + { + case 2: return &secondarydisplayplayer; + case 3: return &thirddisplayplayer; + case 4: return &fourthdisplayplayer; + } + return &displayplayer; +} + // // G_ResetViews // Ensures all viewpoints are valid @@ -2163,6 +2163,8 @@ static INT32 G_FindView(INT32 startview) void G_ResetViews(UINT8 viewnum) { INT32 tempplayer; + INT32 *displayplayerp; + camera_t *camerap; if (!viewnum || viewnum == 1) { @@ -2171,6 +2173,18 @@ void G_ResetViews(UINT8 viewnum) displayplayer = G_FindView(tempplayer); } + if (viewnum > 1 && multiplayer && demoplayback) + if (viewnum == splitscreen+2) + { + splitscreen = viewnum-1; + + displayplayerp = (G_GetDisplayplayerPtr(viewnum)); + camerap = (P_GetCameraPtr(viewnum)); + + P_ResetCamera(&players[(*displayplayerp)], camerap); + R_ExecuteSetViewSize(); + } + if (splitscreen && demoplayback) { diff --git a/src/g_game.h b/src/g_game.h index 256dd2cf..b64fcabb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -226,6 +226,8 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed void G_Ticker(boolean run); boolean G_Responder(event_t *ev); +INT32 * G_GetDisplayplayerPtr (UINT8 viewnum); + void G_ResetViews(UINT8 viewnum); void G_AddPlayer(INT32 playernum); diff --git a/src/p_local.h b/src/p_local.h index cf1387fe..46afc75e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -126,6 +126,8 @@ 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; +camera_t * P_GetCameraPtr (UINT8 viewnum); + fixed_t P_GetPlayerHeight(player_t *player); fixed_t P_GetPlayerSpinHeight(player_t *player); void P_AddPlayerScore(player_t *player, UINT32 amount); diff --git a/src/p_user.c b/src/p_user.c index f20c57b8..ce8e3f07 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8124,6 +8124,18 @@ fixed_t t_cam4_rotate = -42; #define MAXCAMERADIST 140*FRACUNIT // Max distance the camera can be in front of the player (2D mode) +camera_t * +P_GetCameraPtr (UINT8 viewnum) +{ + switch (viewnum) + { + case 2: return &camera2; + case 3: return &camera3; + case 4: return &camera4; + } + return &camera; +} + void P_ResetCamera(player_t *player, camera_t *thiscam) { tic_t tries = 0;