SW: Further refine turning and optimise horizon adjustment.

- Move DoPlayerTurn() into getinput(). Vehicle code remains external for now.
- Remove horizAdjust boolean and always do horizon code in getinput(). Eliminates single off frame at start of a new level until DoPlayerMove() is called at least once.
This commit is contained in:
Mitchell Richters 2020-04-05 21:37:34 +10:00 committed by Christoph Oelckers
parent 377ba68344
commit 039022d9ac
3 changed files with 192 additions and 237 deletions

View file

@ -2978,6 +2978,7 @@ void getinput(int const playerNum)
#define MAXANGVEL 1024
#define MAXHORIZVEL 256
#define HORIZ_SPEED (16)
#define TURN_SHIFT 2
#define SET_LOC_KEY(bits, sync_num, key_test) SET(bits, ((!!(key_test)) << (sync_num)))
static int32_t turnheldtime;
@ -3245,14 +3246,76 @@ void getinput(int const playerNum)
localInput.svel = clamp(localInput.svel + input.svel, -MAXSVEL, MAXSVEL);
localInput.q16avel = fix16_clamp(fix16_sadd(localInput.q16avel, input.q16avel), fix16_from_int(-MAXANGVEL), fix16_from_int(MAXANGVEL));
localInput.q16horz = fix16_clamp(fix16_sadd(localInput.q16horz, input.q16horz), fix16_from_int(-MAXHORIZVEL), fix16_from_int(MAXHORIZVEL));
if (!TEST(pp->Flags, PF_TURN_180))
{
if (TEST_SYNC_KEY(pp, SK_TURN_180))
{
if (FLAG_KEY_PRESSED(pp, SK_TURN_180))
{
short delta_ang;
FLAG_KEY_RELEASE(pp, SK_TURN_180);
pp->turn180_target = NORM_ANGLE(fix16_to_int(pp->q16ang) + 1024);
// make the first turn in the clockwise direction
// the rest will follow
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
pp->q16ang = fix16_sadd(pp->q16ang, fix16_from_float(scaleAdjustmentToInterval(labs(delta_ang) >> TURN_SHIFT))) & 0x7FFFFFF;
SET(pp->Flags, PF_TURN_180);
}
}
else
{
FLAG_KEY_RESET(pp, SK_TURN_180);
}
}
if (TEST(pp->Flags, PF_TURN_180))
{
short delta_ang;
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
pp->q16ang = fix16_sadd(pp->q16ang, fix16_from_float(scaleAdjustmentToInterval(delta_ang >> TURN_SHIFT))) & 0x7FFFFFF;
sprite[pp->PlayerSprite].ang = fix16_to_int(pp->q16ang);
if (!Prediction)
{
if (pp->PlayerUnderSprite >= 0)
sprite[pp->PlayerUnderSprite].ang = fix16_to_int(pp->q16ang);
}
// get new delta to see how close we are
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
if (labs(delta_ang) < (3<<TURN_SHIFT))
{
pp->q16ang = fix16_from_int(pp->turn180_target);
RESET(pp->Flags, PF_TURN_180);
}
else
return;
}
if (input.q16avel != 0)
{
pp->q16ang = fix16_sadd(pp->q16ang, input.q16avel) & 0x7FFFFFF;
localInput.q16horz = fix16_clamp(fix16_sadd(localInput.q16horz, input.q16horz), fix16_from_int(-MAXHORIZVEL), fix16_from_int(MAXHORIZVEL));
pp->q16horiz = fix16_clamp(fix16_sadd(pp->q16horiz, input.q16horz), fix16_from_int(PLAYER_HORIZ_MAX), fix16_from_int(PLAYER_HORIZ_MAX));
if (pp->horizAdjust)
// update players sprite angle
// NOTE: It's also updated in UpdatePlayerSprite, but needs to be
// here to cover
// all cases.
sprite[pp->PlayerSprite].ang = fix16_to_int(pp->q16ang);
if (!Prediction)
{
int i;
if (pp->PlayerUnderSprite >= 0)
sprite[pp->PlayerUnderSprite].ang = fix16_to_int(pp->q16ang);
}
}
// Fixme: This should probably be made optional.
if (cl_slopetilting)
@ -3342,7 +3405,6 @@ void getinput(int const playerNum)
pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval((HORIZ_SPEED/2))));
}
// this is the unlocked type
if (TEST_SYNC_KEY(pp, SK_LOOK_UP) || TEST_SYNC_KEY(pp, SK_LOOK_DOWN))
{
@ -3358,7 +3420,6 @@ void getinput(int const playerNum)
pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval(HORIZ_SPEED)));
}
if (!TEST(pp->Flags, PF_LOCK_HORIZ))
{
if (!(TEST_SYNC_KEY(pp, SK_LOOK_UP) || TEST_SYNC_KEY(pp, SK_LOOK_DOWN)))
@ -3366,6 +3427,7 @@ void getinput(int const playerNum)
// not pressing the pp->q16horiz keys
if (pp->q16horizbase != fix16_from_int(100))
{
int i;
// move pp->q16horiz back to 100
for (i = 1; i; i--)
@ -3394,16 +3456,6 @@ void getinput(int const playerNum)
// add base and offsets
pp->q16horiz = fix16_clamp((pp->q16horizbase + pp->q16horizoff), fix16_from_int(PLAYER_HORIZ_MIN), fix16_from_int(PLAYER_HORIZ_MAX));
#if 0
if (pp->q16horizbase + pp->q16horizoff < fix16_from_int(PLAYER_HORIZ_MIN))
pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval(HORIZ_SPEED)))
else if (pp->q16horizbase + pp->q16horizoff > fix16_from_int(PLAYER_HORIZ_MAX))
pp->q16horizbase = fix16_ssub(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval(HORIZ_SPEED)))
pp->q16horiz = fix16_clamp((pp->q16horizbase + pp->q16horizoff), fix16_from_int(PLAYER_HORIZ_MIN), fix16_from_int(PLAYER_HORIZ_MAX));
#endif
}
if (!CommEnabled)
{

View file

@ -1065,9 +1065,6 @@ struct PLAYERstruct
int drive_angvel;
int drive_oangvel;
bool horizAdjust;
// scroll 2D mode stuff
int scr_x, scr_y, oscr_x, oscr_y;
int scr_xvect, scr_yvect;

View file

@ -1535,81 +1535,6 @@ DoPlayerCrawlHeight(PLAYERp pp)
pp->posz = pp->posz - (DIV4(diff) + DIV8(diff));
}
void
DoPlayerTurn(PLAYERp pp)
{
#define TURN_SHIFT 2
if (!TEST(pp->Flags, PF_TURN_180))
{
if (TEST_SYNC_KEY(pp, SK_TURN_180))
{
if (FLAG_KEY_PRESSED(pp, SK_TURN_180))
{
short delta_ang;
FLAG_KEY_RELEASE(pp, SK_TURN_180);
pp->turn180_target = NORM_ANGLE(fix16_to_int(pp->q16ang) + 1024);
// make the first turn in the clockwise direction
// the rest will follow
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
pp->q16ang = fix16_sadd(pp->q16ang, fix16_from_int((labs(delta_ang) >> TURN_SHIFT))) & 0x7FFFFFF;
SET(pp->Flags, PF_TURN_180);
}
}
else
{
FLAG_KEY_RESET(pp, SK_TURN_180);
}
}
if (TEST(pp->Flags, PF_TURN_180))
{
short delta_ang;
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
pp->q16ang = fix16_sadd(pp->q16ang, fix16_from_int((delta_ang >> TURN_SHIFT))) & 0x7FFFFFF;
sprite[pp->PlayerSprite].ang = fix16_to_int(pp->q16ang);
if (!Prediction)
{
if (pp->PlayerUnderSprite >= 0)
sprite[pp->PlayerUnderSprite].ang = fix16_to_int(pp->q16ang);
}
// get new delta to see how close we are
delta_ang = GetDeltaAngle(pp->turn180_target, fix16_to_int(pp->q16ang));
if (labs(delta_ang) < (3<<TURN_SHIFT))
{
pp->q16ang = fix16_from_int(pp->turn180_target);
RESET(pp->Flags, PF_TURN_180);
}
else
return;
}
if (pp->input.q16avel != 0)
{
pp->q16ang = fix16_sadd(pp->q16ang, fix16_sdiv(fix16_smul(pp->input.q16avel, fix16_from_int(synctics)), fix16_from_int(32))) & 0x7FFFFFF;
// update players sprite angle
// NOTE: It's also updated in UpdatePlayerSprite, but needs to be
// here to cover
// all cases.
sprite[pp->PlayerSprite].ang = fix16_to_int(pp->q16ang);
if (!Prediction)
{
if (pp->PlayerUnderSprite >= 0)
sprite[pp->PlayerUnderSprite].ang = fix16_to_int(pp->q16ang);
}
}
}
void
DoPlayerTurnBoat(PLAYERp pp)
{
@ -2245,8 +2170,6 @@ DoPlayerMove(PLAYERp pp)
SlipSlope(pp);
DoPlayerTurn(pp);
pp->oldposx = pp->posx;
pp->oldposy = pp->posy;
pp->oldposz = pp->posz;
@ -2349,8 +2272,6 @@ DoPlayerMove(PLAYERp pp)
DoPlayerSetWadeDepth(pp);
pp->horizAdjust = TRUE;
if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA))
{
if (TEST(pp->Flags, PF_FLYING|PF_JUMPING|PF_FALLING))
@ -2556,8 +2477,6 @@ DoPlayerMoveBoat(PLAYERp pp)
OperateSectorObject(pp->sop, fix16_to_int(pp->q16ang), pp->posx, pp->posy);
pp->cursectnum = save_sectnum; // for speed
pp->horizAdjust = TRUE;
}
#if 0
@ -3068,8 +2987,6 @@ DoPlayerMoveTank(PLAYERp pp)
OperateSectorObject(pp->sop, fix16_to_int(pp->q16ang), pp->posx, pp->posy);
pp->cursectnum = save_sectnum; // for speed
pp->horizAdjust = TRUE;
DoTankTreads(pp);
}
@ -3084,8 +3001,6 @@ DoPlayerMoveTurret(PLAYERp pp)
SET(pp->Flags, PF_PLAYER_MOVED);
OperateSectorObject(pp->sop, fix16_to_int(pp->q16ang), pp->sop->xmid, pp->sop->ymid);
pp->horizAdjust = TRUE;
}
void
@ -3661,8 +3576,6 @@ DoPlayerClimb(PLAYERp pp)
sp->z = pp->posz + PLAYER_HEIGHT;
changespritesect(pp->PlayerSprite, pp->cursectnum);
pp->horizAdjust = TRUE;
if (FAF_ConnectArea(pp->cursectnum))
{
updatesectorz(pp->posx, pp->posy, pp->posz, &pp->cursectnum);
@ -6392,13 +6305,6 @@ void DoPlayerDeathFollowKiller(PLAYERp pp)
DoPlayerDeathHoriz(pp, PLAYER_DEATH_HORIZ_UP_VALUE, 4);
//DoPlayerDeathTilt(pp, pp->tilt_dest, 4 * synctics);
// allow turning
if ((TEST(pp->Flags, PF_DEAD_HEAD) && pp->input.q16avel != 0) || TEST(pp->Flags, PF_HEAD_CONTROL))
{
DoPlayerTurn(pp);
return;
}
// follow what killed you if its available
if (pp->Killer > -1)
{