diff --git a/src/d_main.c b/src/d_main.c index 467976c1..9c63bd91 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -252,6 +252,11 @@ void D_ProcessEvents(void) if (M_Responder(ev)) continue; // menu ate the event + // Demo input: + if (demo.playback) + if (M_DemoResponder(ev)) + continue; // demo ate the event + // console input if (CON_Responder(ev)) continue; // ate the event @@ -447,7 +452,7 @@ static void D_Display(void) { if (i > 0) // Splitscreen-specific { - switch (i) + switch (i) { case 1: if (splitscreen > 1) @@ -475,7 +480,7 @@ static void D_Display(void) break; } - + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7dff1231..4c3a0f48 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2040,6 +2040,9 @@ static void Command_View_f(void) return; } + if (demo.freecam) + return; + displayplayerp = &displayplayers[viewnum-1]; if (COM_Argc() > 1)/* switch to player */ diff --git a/src/g_game.c b/src/g_game.c index b8a1a3bf..761b0e8d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1868,7 +1868,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 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) + && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]) && !demo.freecam) { if (!demo.playback && (splitscreen || !netgame)) displayplayers[0] = consoleplayer; @@ -1884,7 +1884,7 @@ boolean G_Responder(event_t *ev) } } - if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback) + if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam) { if (ev->data1 == gamecontrolbis[gc_viewpoint][0] || ev->data1 == gamecontrolbis[gc_viewpoint][1]) { @@ -1928,11 +1928,8 @@ boolean G_Responder(event_t *ev) return true; } - // Anything else opens the menu if not already open, except for a few keys... - if (!( - // Rankings - ev->data1 == gamecontrol[gc_scores][0] || ev->data1 == gamecontrol[gc_scores][1] - )) + // open menu but only w/ esc + if (ev->data1 == 32) { M_StartControlPanel(); @@ -6005,6 +6002,9 @@ void G_PreviewRewind(tic_t previewtime) players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j]; } + if (demo.freecam) + return; // nope + for (i = splitscreen; i >= 0; i--) P_ResetCamera(&players[displayplayers[i]], &camera[i]); } @@ -6046,6 +6046,9 @@ void G_ConfirmRewind(tic_t rewindtime) COM_BufInsertText("renderview on\n"); + if (demo.freecam) + return; // don't touch from there + splitscreen = oldss; displayplayers[0] = olddp1; displayplayers[1] = olddp2; diff --git a/src/g_game.h b/src/g_game.h index a69f9142..40b90e99 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -60,6 +60,9 @@ struct demovars_s { DSM_WILLSAVE, DSM_SAVED } savemode; + + boolean freecam; + }; extern struct demovars_s demo; diff --git a/src/k_kart.c b/src/k_kart.c index 10d772ba..bd0ec107 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8750,6 +8750,7 @@ void K_drawKartHUD(void) { boolean isfreeplay = false; boolean battlefullscreen = false; + boolean freecam = demo.freecam; //disable some hud elements w/ freecam UINT8 i; // Define the X and Y for each drawn object @@ -8759,7 +8760,7 @@ void K_drawKartHUD(void) // Draw that fun first person HUD! Drawn ASAP so it looks more "real". for (i = 0; i <= splitscreen; i++) { - if (stplyr == &players[displayplayers[i]] && !camera[i].chase) + if (stplyr == &players[displayplayers[i]] && !camera[i].chase && !freecam) K_drawKartFirstPerson(); } @@ -8780,7 +8781,7 @@ void K_drawKartHUD(void) if (!demo.title && (!battlefullscreen || splitscreen)) { // Draw the CHECK indicator before the other items, so it's overlapped by everything else - if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting) + if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting && !freecam) K_drawKartPlayerCheck(); // Draw WANTED status @@ -8801,7 +8802,7 @@ void K_drawKartHUD(void) } } - if (battlefullscreen) + if (battlefullscreen && !freecam) { #ifdef HAVE_BLUA if (LUA_HudEnabled(hud_battlefullscreen)) @@ -8812,7 +8813,7 @@ void K_drawKartHUD(void) // Draw the item window #ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_item)) + if (LUA_HudEnabled(hud_item) && !freecam) #endif K_drawKartItem(); @@ -8835,7 +8836,7 @@ void K_drawKartHUD(void) } } - if (!stplyr->spectator) // Bottom of the screen elements, don't need in spectate mode + if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode { if (demo.title) // Draw title logo instead in demo.titles { @@ -8924,7 +8925,7 @@ void K_drawKartHUD(void) } // Race overlays - if (G_RaceGametype()) + if (G_RaceGametype() && !freecam) { if (stplyr->exiting) K_drawKartFinish(); @@ -8932,7 +8933,7 @@ void K_drawKartHUD(void) K_drawLapStartAnim(); } - if (modeattacking) // everything after here is MP and debug only + if (modeattacking || freecam) // everything after here is MP and debug only return; if (G_BattleGametype() && !splitscreen && (stplyr->kartstuff[k_yougotem] % 2)) // * YOU GOT EM * diff --git a/src/m_menu.c b/src/m_menu.c index 97b1ce9b..6b01ec9e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -319,6 +319,7 @@ static void M_PlaybackFastForward(INT32 choice); static void M_PlaybackAdvance(INT32 choice); static void M_PlaybackSetViews(INT32 choice); static void M_PlaybackAdjustView(INT32 choice); +static void M_PlaybackToggleFreecam(INT32 choice); static void M_PlaybackQuit(INT32 choice); static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked @@ -518,24 +519,23 @@ static menuitem_t MISC_ReplayOptionsMenu[] = static menuitem_t PlaybackMenu[] = { - {IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu", M_SelectableClearMenus, 0}, + {IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu (Esc)", M_SelectableClearMenus, 0}, - {IT_CALL | IT_STRING, "M_PREW", "Rewind", M_PlaybackRewind, 20}, - {IT_CALL | IT_STRING, "M_PPAUSE", "Pause", M_PlaybackPause, 36}, - {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward", M_PlaybackFastForward, 52}, - {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame", M_PlaybackRewind, 20}, + {IT_CALL | IT_STRING, "M_PREW", "Rewind ([)", M_PlaybackRewind, 20}, + {IT_CALL | IT_STRING, "M_PPAUSE", "Pause (\\)", M_PlaybackPause, 36}, + {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward (])", M_PlaybackFastForward, 52}, + {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame ([)", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36}, - {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame", M_PlaybackAdvance, 52}, + {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame (])", M_PlaybackAdvance, 52}, - {IT_ARROWS | IT_STRING, "M_PVIEWS", "View Count", M_PlaybackSetViews, 72}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint", M_PlaybackAdjustView, 88}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 2", M_PlaybackAdjustView, 104}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 3", M_PlaybackAdjustView, 120}, - {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 4", M_PlaybackAdjustView, 136}, + {IT_ARROWS | IT_STRING, "M_PVIEWS", "View Count (- and =)", M_PlaybackSetViews, 72}, + {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint (1)", M_PlaybackAdjustView, 88}, + {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 2 (2)", M_PlaybackAdjustView, 104}, + {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 3 (3)", M_PlaybackAdjustView, 120}, + {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 4 (4)", M_PlaybackAdjustView, 136}, - //{IT_CALL | IT_STRING, "M_POPTS", "More Options...", M_ReplayHut, 156}, - //{IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 172}, - {IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 156}, + {IT_CALL | IT_STRING, "M_PVIEWS", "Toggle Free Camera (')", M_PlaybackToggleFreecam, 156}, + {IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 172}, }; typedef enum { @@ -551,6 +551,7 @@ typedef enum playback_view2, playback_view3, playback_view4, + playback_freecamera, //playback_moreoptions, playback_quit } playback_e; @@ -2792,6 +2793,56 @@ boolean M_Responder(event_t *ev) case KEY_UPARROW: ch = KEY_RIGHTARROW; break; case KEY_RIGHTARROW: ch = KEY_DOWNARROW; break; case KEY_DOWNARROW: ch = KEY_LEFTARROW; break; + + // arbitrary keyboard shortcuts because fuck you + + case '\'': // toggle freecam + M_PlaybackToggleFreecam(0); + break; + + case ']': // ffw / advance frame (depends on if paused or not) + if (paused) + M_PlaybackAdvance(0); + else + M_PlaybackFastForward(0); + break; + + case '[': // rewind /backupframe, uses the same function + M_PlaybackRewind(0); + break; + + case '\\': // pause + M_PlaybackPause(0); + break; + + // viewpoints, an annoyance (tm) + case '-': // viewpoint minus + M_PlaybackSetViews(-1); // yeah lol. + break; + + case '=': // viewpoint plus + M_PlaybackSetViews(1); // yeah lol. + break; + + // switch viewpoints: + case '1': // viewpoint for p1 (also f12) + // maximum laziness: + if (!demo.freecam) + G_AdjustView(1, 1, true); + break; + case '2': // viewpoint for p2 + if (!demo.freecam) + G_AdjustView(2, 1, true); + break; + case '3': // viewpoint for p3 + if (!demo.freecam) + G_AdjustView(3, 1, true); + break; + case '4': // viewpoint for p4 + if (!demo.freecam) + G_AdjustView(4, 1, true); + break; + default: break; } } @@ -2950,6 +3001,93 @@ boolean M_Responder(event_t *ev) return true; } +// special responder for demos +boolean M_DemoResponder(event_t *ev) +{ + + INT32 ch = -1; // cur event data + boolean eatinput = false; // :omnom: + + //should be accounted for beforehand but just to be safe... + if (!demo.playback || demo.title) + return false; + + if (noFurtherInput) + { + // Ignore input after enter/escape/other buttons + // (but still allow shift keyup so caps doesn't get stuck) + return false; + } + else if (ev->type == ev_keydown) + { + ch = ev->data1; + // since this is ONLY for demos, there isn't MUCH for us to do. + // mirrored from m_responder + + switch (ch) + { + // arbitrary keyboard shortcuts because fuck you + + case '\'': // toggle freecam + M_PlaybackToggleFreecam(0); + eatinput = true; + break; + + case ']': // ffw / advance frame (depends on if paused or not) + if (paused) + M_PlaybackAdvance(0); + else + M_PlaybackFastForward(0); + eatinput = true; + break; + + case '[': // rewind /backupframe, uses the same function + M_PlaybackRewind(0); + break; + + case '\\': // pause + M_PlaybackPause(0); + eatinput = true; + break; + + // viewpoints, an annoyance (tm) + case '-': // viewpoint minus + M_PlaybackSetViews(-1); // yeah lol. + eatinput = true; + break; + + case '=': // viewpoint plus + M_PlaybackSetViews(1); // yeah lol. + eatinput = true; + break; + + // switch viewpoints: + case '1': // viewpoint for p1 (also f12) + // maximum laziness: + if (!demo.freecam) + G_AdjustView(1, 1, true); + break; + case '2': // viewpoint for p2 + if (!demo.freecam) + G_AdjustView(2, 1, true); + break; + case '3': // viewpoint for p3 + if (!demo.freecam) + G_AdjustView(3, 1, true); + break; + case '4': // viewpoint for p4 + if (!demo.freecam) + G_AdjustView(4, 1, true); + break; + + default: break; + } + + } + return eatinput; +} + + // // M_Drawer // Called after the view has been rendered, @@ -5745,13 +5883,10 @@ static void M_DrawPlaybackMenu(void) { for (i = playback_viewcount; i <= playback_view4; i++) PlaybackMenu[i].status = IT_DISABLED; + PlaybackMenu[playback_freecamera].alphaKey = 72; + PlaybackMenu[playback_quit].alphaKey = 88; - //PlaybackMenu[playback_moreoptions].alphaKey = 72; - //PlaybackMenu[playback_quit].alphaKey = 88; - PlaybackMenu[playback_quit].alphaKey = 72; - - //currentMenu->x = BASEVIDWIDTH/2 - 52; - currentMenu->x = BASEVIDWIDTH/2 - 44; + currentMenu->x = BASEVIDWIDTH/2 - 52; } else { @@ -5762,11 +5897,8 @@ static void M_DrawPlaybackMenu(void) for (i = splitscreen+1; i < 4; i++) PlaybackMenu[playback_view1+i].status = IT_DISABLED; - //PlaybackMenu[playback_moreoptions].alphaKey = 156; - //PlaybackMenu[playback_quit].alphaKey = 172; - PlaybackMenu[playback_quit].alphaKey = 156; - - //currentMenu->x = BASEVIDWIDTH/2 - 94; + PlaybackMenu[playback_freecamera].alphaKey = 156; + PlaybackMenu[playback_quit].alphaKey = 172; currentMenu->x = BASEVIDWIDTH/2 - 88; } @@ -5920,6 +6052,10 @@ static void M_PlaybackAdvance(INT32 choice) static void M_PlaybackSetViews(INT32 choice) { + + if (demo.freecam) + return; // not here. + if (choice > 0) { if (splitscreen < 3) @@ -5937,6 +6073,33 @@ static void M_PlaybackAdjustView(INT32 choice) G_AdjustView(itemOn - playback_viewcount, (choice > 0) ? 1 : -1, true); } +// this one's rather tricky +static void M_PlaybackToggleFreecam(INT32 choice) +{ + (void)choice; + M_ClearMenus(true); + + // remove splitscreen: + splitscreen = 0; + R_ExecuteSetViewSize(); + + P_InitCameraCmd(); // init camera controls + if (!demo.freecam) // toggle on + { + demo.freecam = true; + democam.cam = &camera[0]; // this is rather useful + } + else // toggle off + { + demo.freecam = false; + // reset democam vars: + democam.cam = NULL; + democam.turnheld = false; + democam.keyboardlook = false; // reset only these. localangle / aiming gets set before the cam does anything anyway + } +} + + static void M_PlaybackQuit(INT32 choice) { (void)choice; diff --git a/src/m_menu.h b/src/m_menu.h index 62c852e4..f9b88019 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -29,6 +29,9 @@ // Does all the real work of the menu interaction. boolean M_Responder(event_t *ev); +// Called by main loop, runs for demo playback. If this returns true, nullify any further user input. +boolean M_DemoResponder(event_t *ev); + // Called by main loop, only used for menu (skull cursor) animation. void M_Ticker(void); diff --git a/src/p_local.h b/src/p_local.h index 0d0ddc89..8b2d6333 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -109,6 +109,23 @@ typedef struct camera_s fixed_t pan; } camera_t; +// demo freecam or something before i commit die +struct demofreecam_s { + + camera_t *cam; // this is useful when the game is paused, notably + + fixed_t rewindx; + fixed_t rewindy; + fixed_t rewindz; // when rewinding, this is used to make sure the cam doesn't reset + + angle_t localangle; // keeps track of the cam angle for cmds + angle_t localaiming; // ditto with aiming + boolean turnheld; // holding turn button for gradual turn speed + boolean keyboardlook; // keyboard look +}; + +extern struct demofreecam_s democam; + extern camera_t camera[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed; @@ -133,7 +150,9 @@ void P_AddPlayerScore(player_t *player, UINT32 amount); void P_ResetCamera(player_t *player, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam); +void P_DemoCameraMovement(camera_t *cam); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); +void P_InitCameraCmd(void); boolean P_PlayerInPain(player_t *player); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_ResetPlayer(player_t *player); diff --git a/src/p_tick.c b/src/p_tick.c index 2502c721..0ed7fb0b 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -597,6 +597,8 @@ void P_Ticker(boolean run) leveltime = (leveltime-1) & ~3; G_PreviewRewind(leveltime); } + else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause! + P_DemoCameraMovement(democam.cam); return; } diff --git a/src/p_user.c b/src/p_user.c index ced8b2da..9b50a10a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -29,6 +29,7 @@ #include "m_random.h" #include "m_misc.h" #include "i_video.h" +#include "i_joy.h" #include "p_slopes.h" #include "p_spec.h" #include "r_splats.h" @@ -7204,6 +7205,220 @@ fixed_t t_cam4_rotate = -42; #define MAXCAMERADIST 140*FRACUNIT // Max distance the camera can be in front of the player (2D mode) +// Heavily simplified version of G_BuildTicCmd that only takes the local first player's control input and converts it to readable ticcmd_t +// we then throw that ticcmd garbage in the camera and make it move + +// redefine this +static fixed_t forwardmove[2] = {25<>16, 50<>16}; +static fixed_t sidemove[2] = {2<>16, 4<>16}; +static fixed_t angleturn[3] = {KART_FULLTURN/2, KART_FULLTURN, KART_FULLTURN/4}; // + slow turn + +static ticcmd_t cameracmd; + +struct demofreecam_s democam; + +// called by m_menu to reinit cam input every time it's toggled +void P_InitCameraCmd(void) +{ + memset(&cameracmd, 0, sizeof(ticcmd_t)); // initialize cmd +} + +static ticcmd_t *P_CameraCmd(camera_t *cam) +{ + INT32 laim, th, tspeed, forward, side, axis; //i + const INT32 speed = 1; + // these ones used for multiple conditions + boolean turnleft, turnright, mouseaiming; + boolean invertmouse, lookaxis, usejoystick, kbl; + angle_t lang; + + ticcmd_t *cmd = &cameracmd; + + if (!demo.playback) + return cmd; // empty cmd, no. + + lang = democam.localangle; + laim = democam.localaiming; + th = democam.turnheld; + kbl = democam.keyboardlook; + + G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver + + cmd->angleturn = (INT16)(lang >> 16); + cmd->aiming = G_ClipAimingPitch(&laim); + + mouseaiming = true; + invertmouse = cv_invertmouse.value; + lookaxis = cv_lookaxis.value; + + usejoystick = true; + turnright = InputDown(gc_turnright, 1); + turnleft = InputDown(gc_turnleft, 1); + + axis = JoyAxis(AXISTURN, 1); + + if (encoremode) + { + turnright ^= turnleft; // swap these using three XORs + turnleft ^= turnright; + turnright ^= turnleft; + axis = -axis; + } + + if (axis != 0) + { + turnright = turnright || (axis > 0); + turnleft = turnleft || (axis < 0); + } + forward = side = 0; + + // use two stage accelerative turning + // on the keyboard and joystick + if (turnleft || turnright) + th += 1; + else + th = 0; + + if (th < SLOWTURNTICS) + tspeed = 2; // slow turn + else + tspeed = speed; + + // let movement keys cancel each other out + if (turnright && !(turnleft)) + { + cmd->angleturn = (INT16)(cmd->angleturn - (angleturn[tspeed])); + side += sidemove[1]; + } + else if (turnleft && !(turnright)) + { + cmd->angleturn = (INT16)(cmd->angleturn + (angleturn[tspeed])); + side -= sidemove[1]; + } + + cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8))); + + axis = JoyAxis(AXISMOVE, 1); + if (InputDown(gc_accelerate, 1) || (usejoystick && axis > 0)) + cmd->buttons |= BT_ACCELERATE; + axis = JoyAxis(AXISBRAKE, 1); + if (InputDown(gc_brake, 1) || (usejoystick && axis > 0)) + cmd->buttons |= BT_BRAKE; + axis = JoyAxis(AXISAIM, 1); + if (InputDown(gc_aimforward, 1) || (usejoystick && axis < 0)) + forward += forwardmove[1]; + if (InputDown(gc_aimbackward, 1) || (usejoystick && axis > 0)) + forward -= forwardmove[1]; + + + // spectator aiming shit, ahhhh... + INT32 player_invert = invertmouse ? -1 : 1; + INT32 screen_invert = 1; // nope + + // mouse look stuff (mouse look is not the same as mouse aim) + kbl = false; + + // looking up/down + laim += (mlooky<<19)*player_invert*screen_invert; + + axis = JoyAxis(AXISLOOK, 1); + + // spring back if not using keyboard neither mouselookin' + if (!kbl && !lookaxis && !mouseaiming) + laim = 0; + + if (InputDown(gc_lookup, 1) || (axis < 0)) + { + laim += KB_LOOKSPEED * screen_invert; + kbl = true; + } + else if (InputDown(gc_lookdown, 1) || (axis > 0)) + { + laim -= KB_LOOKSPEED * screen_invert; + kbl = true; + } + + if (InputDown(gc_centerview, 1)) // No need to put a spectator limit on this one though :V + laim = 0; + + cmd->aiming = G_ClipAimingPitch(&laim); + + mousex = mousey = mlooky = 0; + + if (forward > MAXPLMOVE) + forward = MAXPLMOVE; + else if (forward < -MAXPLMOVE) + forward = -MAXPLMOVE; + + if (side > MAXPLMOVE) + side = MAXPLMOVE; + else if (side < -MAXPLMOVE) + side = -MAXPLMOVE; + + if (forward || side) + { + cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); + cmd->sidemove = (SINT8)(cmd->sidemove + side); + } + + lang += (cmd->angleturn<<16); + + democam.localangle = lang; + democam.localaiming = laim; + democam.turnheld = th; + democam.keyboardlook = kbl; + + return cmd; +} + +void P_DemoCameraMovement(camera_t *cam) +{ + ticcmd_t *cmd; + angle_t thrustangle; + + // update democam stuff with what we got here: + democam.cam = cam; + democam.localangle = cam->angle; + democam.localaiming = cam->aiming; + + democam.rewindx = cam->x; + democam.rewindy = cam->y; + democam.rewindz = cam->z; + + // first off we need to get button input + cmd = P_CameraCmd(cam); + + cam->aiming = cmd->aiming<angle = cmd->angleturn<<16; + + // camera movement: + + if (cmd->buttons & BT_ACCELERATE) + cam->z += 32*mapobjectscale; + else if (cmd->buttons & BT_BRAKE) + cam->z -= 32*mapobjectscale; + + + cam->momx = cam->momy = cam->momz = 0; + if (cmd->forwardmove != 0) + { + + thrustangle = cam->angle >> ANGLETOFINESHIFT; + + cam->momx += FixedMul(cmd->forwardmove*mapobjectscale, FINECOSINE(thrustangle)); + cam->momy += FixedMul(cmd->forwardmove*mapobjectscale, FINESINE(thrustangle)); + cam->momz += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming)); + + //funny thing cameras aren't mobjs so we gotta handle this ourselves; + cam->x += cam->momx; + cam->y += cam->momy; + cam->z += cam->momz; + + // this.......... doesn't actually check for floors and walls and whatnot but the function to do that is a pure mess so fuck that. + // besides freecam going inside walls sounds pretty cool on paper. + } +} + void P_ResetCamera(player_t *player, camera_t *thiscam) { tic_t tries = 0; @@ -7262,7 +7477,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall boolean cameranoclip; subsector_t *newsubsec; #endif - + + if (demo.freecam) + { + P_DemoCameraMovement(thiscam); + return true; + } + // We probably shouldn't move the camera if there is no player or player mobj somehow if (!player || !player->mo) return true; diff --git a/src/st_stuff.c b/src/st_stuff.c index 50bac3ee..b51d8d6f 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1907,7 +1907,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, player_names[stplyr-players]); } } - else if (!demo.title) + /*else if (!demo.title) { if (!splitscreen) @@ -1927,7 +1927,7 @@ static void ST_overlayDrawer(void) { V_DrawCenteredThinString((vid.width/vid.dupx)/4, BASEVIDHEIGHT/2 - 12, V_HUDTRANSHALF|V_ALLOWLOWERCASE|K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT), player_names[stplyr-players]); } - } + }*/ // This is where we draw all the fun cheese if you have the chasecam off! /*if ((stplyr == &players[displayplayers[0]] && !camera[0].chase)