mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-14 23:21:49 +00:00
Merge branch 'update-freecam' into 'master'
Replay Freecam Love, accessible during regular gameplay, spectate and pause game anywhere, probably other fixes See merge request KartKrew/Kart!1399
This commit is contained in:
commit
16d966d583
22 changed files with 257 additions and 299 deletions
|
|
@ -561,6 +561,11 @@ void D_ResetTiccmds(void)
|
|||
D_Clearticcmd(textcmds[i]->tic);
|
||||
}
|
||||
|
||||
ticcmd_t *D_LocalTiccmd(UINT8 ss)
|
||||
{
|
||||
return &localcmds[ss][0];
|
||||
}
|
||||
|
||||
void SendKick(UINT8 playernum, UINT8 msg)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
|
|
|||
|
|
@ -615,7 +615,9 @@ extern UINT8 playerconsole[MAXPLAYERS];
|
|||
|
||||
INT32 D_NumPlayers(void);
|
||||
boolean D_IsPlayerHumanAndGaming(INT32 player_number);
|
||||
|
||||
void D_ResetTiccmds(void);
|
||||
ticcmd_t *D_LocalTiccmd(UINT8 ss);
|
||||
|
||||
tic_t GetLag(INT32 node);
|
||||
UINT8 GetFreeXCmdSize(UINT8 playerid);
|
||||
|
|
|
|||
|
|
@ -886,11 +886,14 @@ void D_SRB2Loop(void)
|
|||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
rendertimefrac_unpaused = g_time.timefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
rendertimefrac_unpaused = FRACUNIT;
|
||||
}
|
||||
|
||||
if (interp || doDisplay)
|
||||
|
|
|
|||
|
|
@ -3690,11 +3690,14 @@ static void Command_Pause(void)
|
|||
CONS_Printf(M_GetText("You can't pause here.\n"));
|
||||
return;
|
||||
}
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifndef DEVELOP
|
||||
else if (modeattacking) // in time attack, pausing restarts the map
|
||||
{
|
||||
//M_ModeAttackRetry(0); // directly call from m_menu;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
SendNetXCmd(XD_PAUSE, &buf, 2);
|
||||
}
|
||||
|
|
@ -3715,8 +3718,11 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifndef DEVELOP
|
||||
if (modeattacking && !demo.playback)
|
||||
return;
|
||||
#endif
|
||||
|
||||
paused = READUINT8(*cp);
|
||||
dedicatedpause = READUINT8(*cp);
|
||||
|
|
|
|||
|
|
@ -206,9 +206,17 @@ class TiccmdBuilder
|
|||
return true;
|
||||
}
|
||||
|
||||
void toggle_freecam_input()
|
||||
{
|
||||
if (M_MenuButtonPressed(forplayer(), MBT_C))
|
||||
{
|
||||
P_ToggleDemoCamera();
|
||||
}
|
||||
}
|
||||
|
||||
bool director_input()
|
||||
{
|
||||
if (G_IsPartyLocal(displayplayers[forplayer()]) == true)
|
||||
if (demo.freecam || G_IsPartyLocal(displayplayers[forplayer()]) == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -239,12 +247,14 @@ class TiccmdBuilder
|
|||
}
|
||||
}
|
||||
|
||||
toggle_freecam_input();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spectator_analog_input()
|
||||
{
|
||||
if (!player()->spectator && !objectplacing)
|
||||
if (!player()->spectator && !objectplacing && !demo.freecam)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -261,7 +271,7 @@ class TiccmdBuilder
|
|||
|
||||
if (G_PlayerInputDown(forplayer(), gc_lookback, 0))
|
||||
{
|
||||
cmd->aiming -= joystickvector.yaxis;
|
||||
cmd->aiming -= (joystickvector.yaxis * KART_FULLTURN) / JOYAXISRANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -361,10 +371,28 @@ public:
|
|||
explicit TiccmdBuilder(ticcmd_t* cmd_, INT32 realtics_, UINT8 ssplayer_) :
|
||||
cmd(cmd_), realtics(realtics_), ssplayer(ssplayer_), viewnum(G_PartyPosition(g_localplayers[forplayer()]))
|
||||
{
|
||||
*cmd = {}; // blank ticcmd
|
||||
|
||||
if (demo.playback)
|
||||
auto regular_input = [this]
|
||||
{
|
||||
analog_input();
|
||||
common_button_input();
|
||||
};
|
||||
|
||||
if (demo.playback || demo.freecam || player()->spectator)
|
||||
{
|
||||
// freecam is controllable even while paused
|
||||
|
||||
*cmd = {};
|
||||
|
||||
if (!typing_input() && !director_input())
|
||||
{
|
||||
regular_input();
|
||||
|
||||
if (demo.freecam)
|
||||
{
|
||||
toggle_freecam_input();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -373,6 +401,8 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
*cmd = {}; // blank ticcmd
|
||||
|
||||
if (gamestate == GS_LEVEL && player()->playerstate == PST_REBORN)
|
||||
{
|
||||
return;
|
||||
|
|
@ -391,8 +421,7 @@ public:
|
|||
|
||||
if (!overlay)
|
||||
{
|
||||
analog_input();
|
||||
common_button_input();
|
||||
regular_input();
|
||||
}
|
||||
|
||||
cmd->angle = localangle[viewnum] >> TICCMD_REDUCE;
|
||||
|
|
|
|||
|
|
@ -4127,12 +4127,6 @@ void G_StopDemo(void)
|
|||
singletics = false;
|
||||
|
||||
demo.freecam = false;
|
||||
// reset democam shit too:
|
||||
democam.cam = NULL;
|
||||
democam.soundmobj = NULL;
|
||||
democam.localangle = 0;
|
||||
democam.localaiming = 0;
|
||||
democam.keyboardlook = false;
|
||||
|
||||
Z_Free(demo.skinlist);
|
||||
demo.skinlist = NULL;
|
||||
|
|
|
|||
35
src/g_game.c
35
src/g_game.c
|
|
@ -76,6 +76,10 @@
|
|||
#include "discord.h"
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
||||
gameaction_t gameaction;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
UINT8 ultimatemode = false;
|
||||
|
|
@ -861,7 +865,7 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
|
|||
INT32 limitangle;
|
||||
|
||||
// note: the current software mode implementation doesn't have true perspective
|
||||
limitangle = ANGLE_90 - ANG10; // Some viewing fun, but not too far down...
|
||||
limitangle = ANGLE_45; // Some viewing fun, but not too far down...
|
||||
|
||||
if (*aiming > limitangle)
|
||||
*aiming = limitangle;
|
||||
|
|
@ -871,6 +875,31 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming)
|
|||
return (INT16)((*aiming)>>16);
|
||||
}
|
||||
|
||||
void G_FinalClipAimingPitch(INT32 *aiming, player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch(aiming);
|
||||
}
|
||||
else
|
||||
{
|
||||
G_ClipAimingPitch(aiming);
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 G_GetValueFromControlTable(INT32 deviceID, INT32 deadzone, INT32 *controltable)
|
||||
{
|
||||
INT32 i, failret = NO_BINDS_REACHABLE;
|
||||
|
|
@ -3289,6 +3318,10 @@ boolean G_GametypeHasTeams(void)
|
|||
//
|
||||
boolean G_GametypeHasSpectators(void)
|
||||
{
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifdef DEVELOP
|
||||
return true;
|
||||
#endif
|
||||
return (netgame || (multiplayer && demo.netgame));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
|||
// clip the console player aiming to the view
|
||||
INT32 G_ClipAimingPitch(INT32 *aiming);
|
||||
INT16 G_SoftwareClipAimingPitch(INT32 *aiming);
|
||||
void G_FinalClipAimingPitch(INT32 *aiming, player_t *player, boolean skybox);
|
||||
|
||||
extern angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
|
||||
|
|
|
|||
|
|
@ -127,7 +127,10 @@ void K_CheckBumpers(void)
|
|||
{
|
||||
if (nobumpers > 0 && nobumpers >= numingame)
|
||||
{
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifndef DEVELOP
|
||||
P_DoAllPlayersExit(PF_NOCONTEST, false);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
src/k_hud.c
15
src/k_hud.c
|
|
@ -5169,7 +5169,8 @@ static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2], I
|
|||
|
||||
static void K_drawDirectorHUD(void)
|
||||
{
|
||||
const INT32 p = G_PartyMember(consoleplayer, R_GetViewNumber());
|
||||
const UINT8 viewnum = R_GetViewNumber();
|
||||
const INT32 p = viewnum < G_PartySize(consoleplayer) ? G_PartyMember(consoleplayer, viewnum) : -1;
|
||||
const char *itemtxt = "Join";
|
||||
UINT8 offs = 0;
|
||||
|
||||
|
|
@ -5192,12 +5193,15 @@ static void K_drawDirectorHUD(void)
|
|||
offs = 2;
|
||||
}
|
||||
|
||||
K_DrawDirectorButton(offs + 1, "Freecam", kp_button_c[0], 0);
|
||||
|
||||
if (p == -1 || !playeringame[p] || players[p].spectator == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K_DrawDirectorButton(offs + 1, "Director", kp_button_r,
|
||||
// TODO: this is too close to the screen bottom
|
||||
K_DrawDirectorButton(offs + 2, "Director", kp_button_r,
|
||||
(directorinfo.active ? V_YELLOWMAP : 0));
|
||||
|
||||
if (players[p].flashing)
|
||||
|
|
@ -5643,6 +5647,11 @@ void K_drawKartHUD(void)
|
|||
if (stplyr->karthud[khud_trickcool])
|
||||
K_drawTrickCool();
|
||||
|
||||
if (freecam)
|
||||
{
|
||||
K_DrawDirectorButton(3, "Freecam", kp_button_c[0], 0);
|
||||
}
|
||||
|
||||
if (modeattacking || freecam) // everything after here is MP and debug only
|
||||
return;
|
||||
|
||||
|
|
@ -5659,7 +5668,7 @@ void K_drawKartHUD(void)
|
|||
|
||||
K_drawKartPowerUps();
|
||||
|
||||
if (G_IsPartyLocal(displayplayers[viewnum]) == false && !demo.playback)
|
||||
if (G_IsPartyLocal(displayplayers[viewnum]) == false)
|
||||
{
|
||||
K_drawDirectorHUD();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,20 +236,7 @@ void M_PlaybackToggleFreecam(INT32 choice)
|
|||
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
|
||||
}
|
||||
P_ToggleDemoCamera();
|
||||
}
|
||||
|
||||
void M_PlaybackQuit(INT32 choice)
|
||||
|
|
|
|||
|
|
@ -1998,7 +1998,15 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
|
||||
if (!player->exiting && (specialstageinfo.valid == true || modeattacking & ATTACKING_SPB))
|
||||
{
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifdef DEVELOP
|
||||
if (type != DMG_SPECTATOR)
|
||||
{
|
||||
P_DoPlayerExit(player, PF_NOCONTEST);
|
||||
}
|
||||
#else
|
||||
P_DoPlayerExit(player, PF_NOCONTEST);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ struct camera_t
|
|||
// SRB2Kart: camera pitches on slopes
|
||||
angle_t pitch;
|
||||
|
||||
// Freecam: aiming needs to be reset after switching from chasecam
|
||||
boolean reset_aiming;
|
||||
|
||||
// Interpolation data
|
||||
fixed_t old_x, old_y, old_z;
|
||||
angle_t old_angle, old_aiming;
|
||||
|
|
@ -134,13 +137,7 @@ struct 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
|
||||
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
|
||||
|
||||
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
|
||||
UINT8 button_a_held; // A button was held since entering from menu, so don't move camera
|
||||
};
|
||||
|
||||
extern struct demofreecam_s democam;
|
||||
|
|
@ -159,7 +156,7 @@ 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);
|
||||
void P_ToggleDemoCamera(void);
|
||||
|
||||
boolean P_PlayerInPain(player_t *player);
|
||||
void P_ResetPlayer(player_t *player);
|
||||
|
|
|
|||
23
src/p_mobj.c
23
src/p_mobj.c
|
|
@ -11841,7 +11841,10 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
}
|
||||
else // Otherwise, never spectator.
|
||||
{
|
||||
// TODO: this would make a great debug feature for release
|
||||
#ifndef DEVELOP
|
||||
p->spectator = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11969,6 +11972,15 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
{
|
||||
K_ToggleDirector(players[consoleplayer].spectator && pcount > 0);
|
||||
}
|
||||
|
||||
// TODO: handle splitscreen
|
||||
// Spectators can switch to freecam. This should be
|
||||
// disabled when they enter the race, or when the level
|
||||
// changes.
|
||||
if (playernum == consoleplayer && !demo.playback)
|
||||
{
|
||||
demo.freecam = false;
|
||||
}
|
||||
}
|
||||
|
||||
void P_AfterPlayerSpawn(INT32 playernum)
|
||||
|
|
@ -12002,12 +12014,15 @@ void P_AfterPlayerSpawn(INT32 playernum)
|
|||
|
||||
p->drawangle = mobj->angle;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
if (p->spectator == false)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (displayplayers[i] == playernum)
|
||||
P_ResetCamera(p, &camera[i]);
|
||||
if (camera[i].chase)
|
||||
{
|
||||
if (displayplayers[i] == playernum)
|
||||
P_ResetCamera(p, &camera[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7735,6 +7735,8 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam)
|
|||
cam->subsector = R_PointInSubsector(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
|
||||
}
|
||||
}
|
||||
|
||||
cam->chase = false; // tell camera to reset its position next tic
|
||||
}
|
||||
|
||||
static void P_InitCamera(void)
|
||||
|
|
|
|||
|
|
@ -729,8 +729,8 @@ void P_Ticker(boolean run)
|
|||
timeinmap = (timeinmap-1) & ~3;
|
||||
G_PreviewRewind(leveltime);
|
||||
}
|
||||
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
|
||||
P_DemoCameraMovement(democam.cam);
|
||||
else
|
||||
P_RunChaseCameras(); // special case: allow freecam to MOVE during pause!
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
301
src/p_user.c
301
src/p_user.c
|
|
@ -1082,6 +1082,15 @@ boolean P_IsDisplayPlayer(player_t *player)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Freecam still techically has a player in
|
||||
// displayplayers. But since the camera is detached, it
|
||||
// would be weird if sounds were heard from that player's
|
||||
// perspective.
|
||||
if (demo.freecam)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++) // DON'T skip P1
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
|
|
@ -2350,45 +2359,6 @@ static void P_UpdatePlayerAngle(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_SpectatorMovement
|
||||
//
|
||||
// Control for spectators in multiplayer
|
||||
//
|
||||
static void P_SpectatorMovement(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
P_UpdatePlayerAngle(player);
|
||||
|
||||
ticruned++;
|
||||
if (!(cmd->flags & TICCMD_RECEIVED))
|
||||
ticmiss++;
|
||||
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
player->mo->z += 32*mapobjectscale;
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
player->mo->z -= 32*mapobjectscale;
|
||||
|
||||
if (!(player->mo->flags & MF_NOCLIPHEIGHT))
|
||||
{
|
||||
if (player->mo->z > player->mo->ceilingz - player->mo->height)
|
||||
player->mo->z = player->mo->ceilingz - player->mo->height;
|
||||
if (player->mo->z < player->mo->floorz)
|
||||
player->mo->z = player->mo->floorz;
|
||||
}
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle, cmd->forwardmove*mapobjectscale);
|
||||
|
||||
// Quake-style flying spectators :D
|
||||
player->mo->momz += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(player->aiming));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_MovePlayer
|
||||
void P_MovePlayer(player_t *player)
|
||||
|
|
@ -2415,7 +2385,6 @@ void P_MovePlayer(player_t *player)
|
|||
if (player->spectator)
|
||||
{
|
||||
player->mo->eflags &= ~MFE_VERTICALFLIP; // deflip...
|
||||
P_SpectatorMovement(player);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2970,184 +2939,87 @@ fixed_t t_cam_dist[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
|||
fixed_t t_cam_height[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
||||
fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
||||
|
||||
// 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
|
||||
// TODO: please just use the normal ticcmd function somehow
|
||||
|
||||
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 forward, axis; //i
|
||||
// these ones used for multiple conditions
|
||||
boolean turnleft, turnright, mouseaiming;
|
||||
boolean invertmouse, lookaxis, usejoystick, kbl;
|
||||
INT32 player_invert;
|
||||
INT32 screen_invert;
|
||||
*/
|
||||
ticcmd_t *cmd = &cameracmd;
|
||||
|
||||
(void)cam;
|
||||
|
||||
if (!demo.playback)
|
||||
return cmd; // empty cmd, no.
|
||||
|
||||
/*
|
||||
kbl = democam.keyboardlook;
|
||||
|
||||
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
|
||||
|
||||
mouseaiming = true;
|
||||
invertmouse = cv_invertmouse.value;
|
||||
lookaxis = cv_lookaxis[0].value;
|
||||
|
||||
usejoystick = true;
|
||||
turnright = PlayerInputDown(1, gc_turnright);
|
||||
turnleft = PlayerInputDown(1, gc_turnleft);
|
||||
|
||||
axis = PlayerJoyAxis(1, AXISTURN);
|
||||
|
||||
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 = 0;
|
||||
|
||||
cmd->turning = 0;
|
||||
|
||||
// let movement keys cancel each other out
|
||||
if (turnright && !(turnleft))
|
||||
{
|
||||
cmd->turning -= KART_FULLTURN;
|
||||
}
|
||||
else if (turnleft && !(turnright))
|
||||
{
|
||||
cmd->turning += KART_FULLTURN;
|
||||
}
|
||||
|
||||
cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
|
||||
|
||||
axis = PlayerJoyAxis(1, AXISMOVE);
|
||||
if (PlayerInputDown(1, gc_a) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
axis = PlayerJoyAxis(1, AXISBRAKE);
|
||||
if (PlayerInputDown(1, gc_brake) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
axis = PlayerJoyAxis(1, AXISAIM);
|
||||
if (PlayerInputDown(1, gc_aimforward) || (usejoystick && axis < 0))
|
||||
forward += MAXPLMOVE;
|
||||
if (PlayerInputDown(1, gc_aimbackward) || (usejoystick && axis > 0))
|
||||
forward -= MAXPLMOVE;
|
||||
|
||||
// fire with any button/key
|
||||
axis = PlayerJoyAxis(1, AXISFIRE);
|
||||
if (PlayerInputDown(1, gc_fire) || (usejoystick && axis > 0))
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
|
||||
// spectator aiming shit, ahhhh...
|
||||
player_invert = invertmouse ? -1 : 1;
|
||||
screen_invert = 1; // nope
|
||||
|
||||
// mouse look stuff (mouse look is not the same as mouse aim)
|
||||
kbl = false;
|
||||
|
||||
// looking up/down
|
||||
cmd->aiming += (mlooky<<19)*player_invert*screen_invert;
|
||||
|
||||
axis = PlayerJoyAxis(1, AXISLOOK);
|
||||
|
||||
// spring back if not using keyboard neither mouselookin'
|
||||
if (!kbl && !lookaxis && !mouseaiming)
|
||||
cmd->aiming = 0;
|
||||
|
||||
if (PlayerInputDown(1, gc_lookup) || (axis < 0))
|
||||
{
|
||||
cmd->aiming += KB_LOOKSPEED * screen_invert;
|
||||
kbl = true;
|
||||
}
|
||||
else if (PlayerInputDown(1, gc_lookdown) || (axis > 0))
|
||||
{
|
||||
cmd->aiming -= KB_LOOKSPEED * screen_invert;
|
||||
kbl = true;
|
||||
}
|
||||
|
||||
if (PlayerInputDown(1, gc_centerview)) // No need to put a spectator limit on this one though :V
|
||||
cmd->aiming = 0;
|
||||
|
||||
cmd->forwardmove += (SINT8)forward;
|
||||
|
||||
if (cmd->forwardmove > MAXPLMOVE)
|
||||
cmd->forwardmove = MAXPLMOVE;
|
||||
else if (cmd->forwardmove < -MAXPLMOVE)
|
||||
cmd->forwardmove = -MAXPLMOVE;
|
||||
|
||||
if (cmd->turning > KART_FULLTURN)
|
||||
cmd->turning = KART_FULLTURN;
|
||||
else if (cmd->turning < -KART_FULLTURN)
|
||||
cmd->turning = -KART_FULLTURN;
|
||||
|
||||
democam.keyboardlook = kbl;
|
||||
*/
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void P_DemoCameraMovement(camera_t *cam)
|
||||
{
|
||||
ticcmd_t *cmd;
|
||||
angle_t thrustangle;
|
||||
mobj_t *awayviewmobj_hack;
|
||||
player_t *lastp;
|
||||
|
||||
// update democam stuff with what we got here:
|
||||
democam.cam = cam;
|
||||
democam.localangle = cam->angle;
|
||||
democam.localaiming = cam->aiming;
|
||||
boolean moving = false;
|
||||
|
||||
// first off we need to get button input
|
||||
cmd = P_CameraCmd(cam);
|
||||
cmd = D_LocalTiccmd(0);
|
||||
|
||||
if (cmd->aiming != 0)
|
||||
{
|
||||
cam->aiming += cmd->aiming << TICCMD_REDUCE;
|
||||
|
||||
cam->reset_aiming = false;
|
||||
}
|
||||
|
||||
cam->aiming += cmd->aiming << TICCMD_REDUCE;
|
||||
cam->angle += cmd->turning << TICCMD_REDUCE;
|
||||
|
||||
democam.localangle += cmd->turning << TICCMD_REDUCE;
|
||||
democam.localaiming += cmd->aiming << TICCMD_REDUCE;
|
||||
|
||||
cam->aiming = G_ClipAimingPitch((INT32 *)&cam->aiming);
|
||||
democam.localaiming = G_ClipAimingPitch((INT32 *)&democam.localaiming);
|
||||
|
||||
// camera movement:
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
cam->z += 32*mapobjectscale;
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
cam->z -= 32*mapobjectscale;
|
||||
if (!democam.button_a_held)
|
||||
{
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
{
|
||||
cam->z += 32*mapobjectscale;
|
||||
moving = true;
|
||||
}
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
{
|
||||
cam->z -= 32*mapobjectscale;
|
||||
moving = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cmd->buttons & (BT_ACCELERATE | BT_DRIFT)) && democam.button_a_held)
|
||||
{
|
||||
democam.button_a_held--;
|
||||
}
|
||||
|
||||
// if you hold item, you will lock on to displayplayer. (The last player you were ""f12-ing"")
|
||||
if (cmd->buttons & BT_ATTACK)
|
||||
if (demo.freecam && cmd->buttons & BT_ATTACK)
|
||||
{
|
||||
lastp = &players[displayplayers[0]]; // Fun fact, I was trying displayplayers[0]->mo as if it was Lua like an absolute idiot.
|
||||
cam->angle = R_PointToAngle2(cam->x, cam->y, lastp->mo->x, lastp->mo->y);
|
||||
cam->aiming = R_PointToAngle2(0, cam->z, R_PointToDist2(cam->x, cam->y, lastp->mo->x, lastp->mo->y), lastp->mo->z + lastp->mo->scale*128*P_MobjFlip(lastp->mo)); // This is still unholy. Aim a bit above their heads.
|
||||
|
||||
cam->reset_aiming = false;
|
||||
}
|
||||
|
||||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
moving = true;
|
||||
}
|
||||
|
||||
// After switching to democam, the vertical angle of
|
||||
// chasecam is inherited. This is intentional because it
|
||||
// creates a smooth transition. However, moving
|
||||
// forward/back will have a slope. So, as long as democam
|
||||
// controls haven't been used to alter the vertical angle,
|
||||
// slowly reset it to flat.
|
||||
if ((cam->reset_aiming && moving) || ((cmd->buttons & BT_DRIFT) && !democam.button_a_held))
|
||||
{
|
||||
INT32 aiming = cam->aiming;
|
||||
INT32 smooth = FixedMul(ANGLE_11hh / 4, FCOS(cam->aiming));
|
||||
|
||||
if (abs(smooth) < abs(aiming))
|
||||
{
|
||||
cam->aiming -= smooth * intsign(aiming);
|
||||
}
|
||||
else
|
||||
{
|
||||
cam->aiming = 0;
|
||||
cam->reset_aiming = false; // completely smoothed out
|
||||
}
|
||||
}
|
||||
|
||||
G_FinalClipAimingPitch((INT32 *)&cam->aiming, NULL, false);
|
||||
|
||||
cam->momx = cam->momy = cam->momz = 0;
|
||||
|
||||
if (cmd->forwardmove != 0)
|
||||
|
|
@ -3156,25 +3028,35 @@ void P_DemoCameraMovement(camera_t *cam)
|
|||
|
||||
cam->x += FixedMul(cmd->forwardmove*mapobjectscale, FINECOSINE(thrustangle));
|
||||
cam->y += FixedMul(cmd->forwardmove*mapobjectscale, FINESINE(thrustangle));
|
||||
cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming));
|
||||
|
||||
if (!cam->reset_aiming)
|
||||
{
|
||||
cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming));
|
||||
}
|
||||
// momentums are useless here, directly add to the coordinates
|
||||
|
||||
// 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.
|
||||
}
|
||||
|
||||
// awayviewmobj hack; this is to prevent us from hearing sounds from the player's perspective
|
||||
|
||||
awayviewmobj_hack = P_SpawnMobj(cam->x, cam->y, cam->z, MT_THOK);
|
||||
awayviewmobj_hack->tics = 2;
|
||||
awayviewmobj_hack->renderflags |= RF_DONTDRAW;
|
||||
|
||||
democam.soundmobj = awayviewmobj_hack;
|
||||
|
||||
// update subsector to avoid crashes;
|
||||
cam->subsector = R_PointInSubsector(cam->x, cam->y);
|
||||
}
|
||||
|
||||
void P_ToggleDemoCamera(void)
|
||||
{
|
||||
if (!demo.freecam) // toggle on
|
||||
{
|
||||
demo.freecam = true;
|
||||
democam.button_a_held = 2;
|
||||
camera[0].reset_aiming = true;
|
||||
}
|
||||
else // toggle off
|
||||
{
|
||||
demo.freecam = false;
|
||||
}
|
||||
}
|
||||
|
||||
void P_ResetCamera(player_t *player, camera_t *thiscam)
|
||||
{
|
||||
tic_t tries = 0;
|
||||
|
|
@ -3211,6 +3093,8 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
|
|||
thiscam->radius = 20*FRACUNIT;
|
||||
thiscam->height = 16*FRACUNIT;
|
||||
|
||||
thiscam->reset_aiming = true;
|
||||
|
||||
while (!P_MoveChaseCamera(player,thiscam,true) && ++tries < 2*TICRATE);
|
||||
}
|
||||
|
||||
|
|
@ -3239,8 +3123,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
thiscam->old_angle = thiscam->angle;
|
||||
thiscam->old_aiming = thiscam->aiming;
|
||||
|
||||
democam.soundmobj = NULL; // reset this each frame, we don't want the game crashing for stupid reasons now do we
|
||||
|
||||
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
|
@ -3249,12 +3131,15 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
|
||||
return true;
|
||||
|
||||
if (demo.freecam)
|
||||
if (demo.freecam || player->spectator)
|
||||
{
|
||||
P_DemoCameraMovement(thiscam);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (paused || P_AutoPause())
|
||||
return true;
|
||||
|
||||
playerScale = FixedDiv(player->mo->scale, mapobjectscale);
|
||||
scaleDiff = playerScale - FRACUNIT;
|
||||
|
||||
|
|
|
|||
21
src/r_fps.c
21
src/r_fps.c
|
|
@ -22,9 +22,6 @@
|
|||
#include "r_state.h"
|
||||
#include "z_zone.h"
|
||||
#include "console.h" // con_startup_loadprogress
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t fpscap_cons_t[] = {
|
||||
#ifdef DEVELOP
|
||||
|
|
@ -117,23 +114,7 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
|
|||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
G_FinalClipAimingPitch((INT32 *)&aimingangle, player, skybox);
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
|
|
|
|||
21
src/r_main.c
21
src/r_main.c
|
|
@ -81,6 +81,7 @@ mobj_t *r_viewmobj;
|
|||
int r_splitscreen;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t rendertimefrac_unpaused;
|
||||
fixed_t renderdeltatics;
|
||||
boolean renderisnewtic;
|
||||
|
||||
|
|
@ -978,7 +979,7 @@ angle_t R_ViewRollAngle(const player_t *player)
|
|||
|
||||
if (cv_tilting.value)
|
||||
{
|
||||
if (!player->spectator)
|
||||
if (!player->spectator && !demo.freecam)
|
||||
{
|
||||
roll += player->tilt;
|
||||
}
|
||||
|
|
@ -1227,7 +1228,7 @@ R_SetupCommonFrame
|
|||
else
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
||||
R_InterpolateView(rendertimefrac);
|
||||
R_InterpolateView(rendertimefrac_unpaused);
|
||||
}
|
||||
|
||||
static void R_SetupAimingFrame(int s)
|
||||
|
|
@ -1265,8 +1266,12 @@ void R_SetupFrame(int s)
|
|||
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1 + s);
|
||||
|
||||
if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
if (player->spectator)
|
||||
{
|
||||
// Free flying spectator uses demo freecam. This
|
||||
// requires chasecam to be enabled.
|
||||
chasecam = true;
|
||||
}
|
||||
|
||||
if (chasecam && (thiscam && !thiscam->chase))
|
||||
{
|
||||
|
|
@ -1292,7 +1297,7 @@ void R_SetupFrame(int s)
|
|||
|
||||
R_SetupCommonFrame(player, r_viewmobj->subsector);
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
else if (chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
r_viewmobj = NULL;
|
||||
|
|
@ -1430,10 +1435,8 @@ boolean R_ViewpointHasChasecam(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN)
|
||||
if (player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || player->spectator)
|
||||
chasecam = true; // force chasecam on
|
||||
else if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
|
||||
return chasecam;
|
||||
}
|
||||
|
|
@ -1446,7 +1449,7 @@ boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox)
|
|||
if (player->awayview.tics || skybox)
|
||||
return chasecam;
|
||||
// use outside cam view
|
||||
else if (!player->spectator && chasecam)
|
||||
else if (chasecam)
|
||||
return true;
|
||||
|
||||
// use the player's eyes view
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ extern size_t validcount, linecount, loopcount, framecount;
|
|||
|
||||
// The fraction of a tic being drawn (for interpolation between two tics)
|
||||
extern fixed_t rendertimefrac;
|
||||
// Same as rendertimefrac but not suspended when the game is paused
|
||||
extern fixed_t rendertimefrac_unpaused;
|
||||
// Evaluated delta tics for this frame (how many tics since the last frame)
|
||||
extern fixed_t renderdeltatics;
|
||||
// The current render is a new logical tic
|
||||
|
|
|
|||
|
|
@ -540,11 +540,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && democam.soundmobj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->awayview.tics)
|
||||
{
|
||||
listenmobj[i] = player->awayview.mobj;
|
||||
|
|
@ -554,7 +549,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
listenmobj[i] = player->mo;
|
||||
}
|
||||
|
||||
if (origin && origin == listenmobj[i])
|
||||
if (origin && origin == listenmobj[i] && !demo.freecam)
|
||||
{
|
||||
itsUs = true;
|
||||
}
|
||||
|
|
@ -827,11 +822,6 @@ void S_UpdateSounds(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && democam.soundmobj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->awayview.tics)
|
||||
{
|
||||
listenmobj[i] = player->awayview.mobj;
|
||||
|
|
@ -898,12 +888,15 @@ void S_UpdateSounds(void)
|
|||
{
|
||||
boolean itsUs = false;
|
||||
|
||||
for (i = r_splitscreen; i >= 0; i--)
|
||||
if (!demo.freecam)
|
||||
{
|
||||
if (c->origin != listenmobj[i])
|
||||
continue;
|
||||
for (i = r_splitscreen; i >= 0; i--)
|
||||
{
|
||||
if (c->origin != listenmobj[i])
|
||||
continue;
|
||||
|
||||
itsUs = true;
|
||||
itsUs = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (itsUs == false)
|
||||
|
|
|
|||
|
|
@ -1171,7 +1171,7 @@ static void ST_overlayDrawer(void)
|
|||
{
|
||||
if (cv_showviewpointtext.value)
|
||||
{
|
||||
if (!demo.title && !P_IsLocalPlayer(stplyr))
|
||||
if (!demo.title && !P_IsLocalPlayer(stplyr) && !demo.freecam)
|
||||
{
|
||||
if (!r_splitscreen)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue