Commit 3b3cd0e0 authored by Richard Gobeille's avatar Richard Gobeille
Browse files

Duke3d: aim assist for game controllers

A helpful side-effect of this commit is that several of the previous changes to how screen re-centering etc work can now be deterministic again, which somewhat fixes demo recording and playback. For now, recording a demo will limit input to the game tickrate like it did in the old days.
parent a57a6e1a
......@@ -1323,22 +1323,6 @@ static int P_Submerge(int, DukePlayer_t *, int, int);
static int P_Emerge(int, DukePlayer_t *, int, int);
static void P_FinishWaterChange(int, DukePlayer_t *, int, int, int);
static fix16_t P_GetQ16AngleDeltaForTic(DukePlayer_t const *pPlayer)
{
auto oldAngle = pPlayer->oq16ang;
auto newAngle = pPlayer->q16ang;
if (klabs(fix16_sub(oldAngle, newAngle)) < F16(1024))
return fix16_sub(newAngle, oldAngle);
if (newAngle > F16(1024))
newAngle = fix16_sub(newAngle, F16(2048));
if (oldAngle > F16(1024))
oldAngle = fix16_sub(oldAngle, F16(2048));
return fix16_sub(newAngle, oldAngle);
}
ACTOR_STATIC void G_MovePlayers(void)
{
......@@ -1395,13 +1379,6 @@ ACTOR_STATIC void G_MovePlayers(void)
if (G_TileHasActor(sprite[spriteNum].picnum))
A_Execute(spriteNum, P_GetP(pSprite), otherPlayerDist);
thisPlayer.smoothcamera = false;
pPlayer->q16angvel = P_GetQ16AngleDeltaForTic(pPlayer);
pPlayer->oq16ang = pPlayer->q16ang;
pPlayer->oq16horiz = pPlayer->q16horiz;
pPlayer->oq16horizoff = pPlayer->q16horizoff;
if (pPlayer->one_eighty_count < 0)
{
thisPlayer.smoothcamera = true;
......
......@@ -266,7 +266,8 @@ void CONFIG_SetDefaults(void)
ud.config.CheckForUpdates = 1;
ud.config.FXVolume = 255;
ud.config.JoystickAimWeight = 5;
ud.config.JoystickViewLeveling = 1;
ud.config.JoystickViewCentering = 3;
ud.config.JoystickAimAssist = 1;
ud.config.MouseBias = 0;
ud.config.MusicDevice = ASS_AutoDetect;
ud.config.MusicToggle = 1;
......
......@@ -6861,16 +6861,13 @@ MAIN_LOOP_RESTART:
{
do
{
if (g_networkMode != NET_DEDICATED_SERVER)
if (g_networkMode != NET_DEDICATED_SERVER && (myplayer.gm & (MODE_MENU | MODE_DEMO)) == 0)
{
if (!frameJustDrawn)
break;
frameJustDrawn = false;
// is this even useful?
P_GetInput(myconnectindex);
// this is where we fill the input_t struct that is actually processed by P_ProcessInput()
auto const pPlayer = g_player[myconnectindex].ps;
auto const q16ang = fix16_to_int(pPlayer->q16ang);
......
......@@ -214,7 +214,8 @@ typedef struct {
int32_t ShowWeapons;
int32_t MouseBias;
int32_t JoystickAimWeight;
int32_t JoystickViewLeveling;
int32_t JoystickViewCentering;
int32_t JoystickAimAssist;
// JBF 20031211: Store the input settings because
// (currently) mact can't regurgitate them
......
......@@ -99,14 +99,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define SK_INVENTORY 30
#define SK_ESCAPE 31
#define EK_MOVE_FORWARD 0
#define EK_MOVE_BACKWARD 1
#define EK_STRAFE_LEFT 2
#define EK_STRAFE_RIGHT 3
#define EK_TURN_LEFT 4
#define EK_TURN_RIGHT 5
#define EK_ALT_FIRE 6
#define EK_CHAT_MODE 7
#define EK_MOVE_FORWARD 0
#define EK_MOVE_BACKWARD 1
#define EK_STRAFE_LEFT 2
#define EK_STRAFE_RIGHT 3
#define EK_TURN_LEFT 4
#define EK_TURN_RIGHT 5
#define EK_ALT_FIRE 6
#define EK_CHAT_MODE 7
#define EK_GAMEPAD_CENTERING 8
#define EK_GAMEPAD_AIM_ASSIST 9
// rotatesprite flags
#define ROTATE_SPRITE_TRANSLUCENT (BIT(0))
......
......@@ -1609,8 +1609,13 @@ int32_t registerosdcommands(void)
},
{
"in_joystickviewleveling", "automatically level the player view vertically when moving while using a controller",
(void *)&ud.config.JoystickViewLeveling, CVAR_INT, 0, 10
"in_joystickviewcentering", "automatically center the player's view vertically when moving while using a controller",
(void *)&ud.config.JoystickViewCentering, CVAR_INT, 0, 10
},
{
"in_joystickviewleveling", "automatically adjusts the player's view vertically to aim at enemies",
(void *)&ud.config.JoystickAimAssist, CVAR_BOOL, 0, 1
},
{ "in_joystick","use joystick or controller input" CVAR_BOOL_OPTSTR,(void *)&ud.setup.usejoystick, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 },
......
......@@ -1344,7 +1344,7 @@ static int32_t A_ShootHardcoded(int spriteNum, int projecTile, int shootAng, vec
if (playerNum >= 0)
{
// NOTE: j is a SPRITE_INDEX
j = GetAutoAimAng(spriteNum, playerNum, projecTile, 8 << 8, 0 + 2, &startPos, vel, &Zvel, &shootAng);
j = GetAutoAimAng(spriteNum, playerNum, projecTile, ZOFFSET3, 0 + 2, &startPos, vel, &Zvel, &shootAng);
if (j < 0)
Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 81;
......@@ -3012,6 +3012,116 @@ static int P_CheckLockedMovement(int const playerNum)
return 0;
}
void P_UpdateAngles(int const playerNum, input_t const &input)
{
auto &thisPlayer = g_player[playerNum];
auto const pPlayer = thisPlayer.ps;
auto const currentHiTicks = timerGetHiTicks();
double elapsedInputTicks = currentHiTicks - thisPlayer.lastViewUpdate;
if (!thisPlayer.lastViewUpdate)
elapsedInputTicks = 0;
thisPlayer.lastViewUpdate = currentHiTicks;
auto scaleToInterval = [=](double x) { return x * REALGAMETICSPERSEC / (1000.0 / min(elapsedInputTicks, 1000.0)); };
int const movementLocked = P_CheckLockedMovement(playerNum);
if ((movementLocked & IL_NOTHING) != IL_NOTHING)
{
if (!(movementLocked & IL_NOANGLE))
pPlayer->q16ang = fix16_sadd(pPlayer->q16ang, input.q16avel) & 0x7FFFFFF;
if (!(movementLocked & IL_NOHORIZ))
{
float horizAngle = atan2f(pPlayer->q16horiz - F16(100), F16(128)) * (512.f / fPI) + fix16_to_float(input.q16horz);
pPlayer->q16horiz = F16(100) + Blrintf(F16(128) * tanf(horizAngle * (fPI / 512.f)));
}
}
// A horiz diff of 128 equal 45 degrees, so we convert horiz to 1024 angle units
if (thisPlayer.horizAngleAdjust)
{
float const horizAngle
= atan2f(pPlayer->q16horiz - F16(100), F16(128)) * (512.f / fPI) + scaleToInterval(thisPlayer.horizAngleAdjust);
pPlayer->q16horiz = F16(100) + Blrintf(F16(128) * tanf(horizAngle * (fPI / 512.f)));
}
else if (pPlayer->return_to_center > 0 || thisPlayer.horizRecenter)
{
pPlayer->q16horiz = fix16_sadd(pPlayer->q16horiz, fix16_from_float(scaleToInterval(fix16_to_float(F16(66.666) - fix16_sdiv(pPlayer->q16horiz, F16(1.5))))));
if ((!pPlayer->return_to_center && thisPlayer.horizRecenter) || (pPlayer->q16horiz >= F16(99.9) && pPlayer->q16horiz <= F16(100.1)))
{
pPlayer->q16horiz = F16(100);
pPlayer->return_to_center = 0;
thisPlayer.horizRecenter = false;
}
}
int const sectorLotag = pPlayer->cursectnum != -1 ? sector[pPlayer->cursectnum].lotag : 0;
// calculates automatic view angle for playing without a mouse
if (!pPlayer->aim_mode && pPlayer->on_ground && sectorLotag != ST_2_UNDERWATER && (sector[pPlayer->cursectnum].floorstat & 2))
{
// this is some kind of horse shit approximation of where the player is looking, I guess?
vec2_t const adjustedPosition = { pPlayer->pos.x + (sintable[(fix16_to_int(pPlayer->q16ang) + 512) & 2047] >> 5),
pPlayer->pos.y + (sintable[fix16_to_int(pPlayer->q16ang) & 2047] >> 5) };
int16_t currentSector = pPlayer->cursectnum;
updatesector(adjustedPosition.x, adjustedPosition.y, &currentSector);
if (currentSector >= 0)
{
int const slopeZ = yax_getflorzofslope(pPlayer->cursectnum, adjustedPosition);
if ((pPlayer->cursectnum == currentSector) || (klabs(yax_getflorzofslope(currentSector, adjustedPosition) - slopeZ) <= ZOFFSET6))
pPlayer->q16horizoff = fix16_sadd(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(mulscale16(pPlayer->truefz - slopeZ, 160))));
}
}
// view centering only works if there's no input on the right stick (looking/aiming) and the player is moving forward/backward, not strafing
if (pPlayer->aim_mode&AM_CENTERING && !input.q16avel && !input.q16horz && input.fvel)
{
if (pPlayer->q16horiz >= F16(99) && pPlayer->q16horiz <= F16(100))
thisPlayer.horizRecenter = true;
else if (pPlayer->q16horiz < F16(99))
pPlayer->q16horiz = fix16_min(fix16_sadd(pPlayer->q16horiz, fix16_from_float(scaleToInterval(ud.config.JoystickViewCentering))), F16(100));
else if (pPlayer->q16horiz > F16(100))
pPlayer->q16horiz = fix16_max(fix16_ssub(pPlayer->q16horiz, fix16_from_float(scaleToInterval(ud.config.JoystickViewCentering))), F16(100));
}
int32_t Zvel, shootAng;
// FIXME
if (pPlayer->aim_mode&AM_AIMASSIST && GetAutoAimAng(pPlayer->i, playerNum, 0, ZOFFSET3, 0 + 2, &pPlayer->pos, 256, &Zvel, &shootAng) != -1)
{
if (pPlayer->q16horiz == F16(100))
{
fix16_t const f = F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff;
fix16_t const target = Blrintf(F16(128) * tanf((Zvel / 32.f) * (fPI / 512.f)));
fix16_t const scaled = fix16_from_float(scaleToInterval(1.5));
if (f > target + scaled)
pPlayer->q16horizoff = fix16_sadd(pPlayer->q16horizoff, scaled);
else if (f < target - scaled)
pPlayer->q16horizoff = fix16_ssub(pPlayer->q16horizoff, scaled);
}
}
else if (pPlayer->q16horizoff > F16(1))
pPlayer->q16horizoff = fix16_ssub(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(fix16_to_float((pPlayer->q16horizoff >> 3) + fix16_one))));
else if (pPlayer->q16horizoff < F16(-1))
pPlayer->q16horizoff = fix16_sadd(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(fix16_to_float((-pPlayer->q16horizoff >> 3) + fix16_one))));
else if (pPlayer->q16horizoff >= F16(-1) && pPlayer->q16horizoff <= F16(1))
pPlayer->q16horizoff = 0;
if (thisPlayer.horizSkew)
pPlayer->q16horiz = fix16_sadd(pPlayer->q16horiz, fix16_from_float(scaleToInterval(thisPlayer.horizSkew)));
pPlayer->q16horiz = fix16_clamp(pPlayer->q16horiz, F16(HORIZ_MIN), F16(HORIZ_MAX));
pPlayer->q16horizoff = fix16_clamp(pPlayer->q16horizoff, F16(HORIZ_MIN), F16(HORIZ_MAX));
}
void P_GetInput(int const playerNum)
{
auto &thisPlayer = g_player[playerNum];
......@@ -3023,6 +3133,7 @@ void P_GetInput(int const playerNum)
if (!(pPlayer->gm&MODE_MENU))
CONTROL_GetInput(&info);
thisPlayer.lastViewUpdate = 0;
localInput = {};
localInput.bits = (((int32_t)g_gameQuit) << SK_GAMEQUIT);
localInput.extbits |= BIT(EK_CHAT_MODE);
......@@ -3031,7 +3142,7 @@ void P_GetInput(int const playerNum)
}
CONTROL_ProcessBinds();
if (ud.mouseaiming)
g_myAimMode = BUTTON(gamefunc_Mouse_Aiming);
else
......@@ -3066,18 +3177,18 @@ void P_GetInput(int const playerNum)
if (absyaw > abspitch)
{
if (info.dpitch > 0)
info.dpitch = max(0, info.dpitch - tabledivide32_noinline(absyaw - abspitch, 11 - ud.config.JoystickAimWeight));
info.dpitch = max(0, info.dpitch - tabledivide32_noinline(absyaw - abspitch, 8 - ud.config.JoystickAimWeight));
else if (info.dpitch < 0)
info.dpitch = min(0, info.dpitch + tabledivide32_noinline(absyaw - abspitch, 11 - ud.config.JoystickAimWeight));
info.dpitch = min(0, info.dpitch + tabledivide32_noinline(absyaw - abspitch, 8 - ud.config.JoystickAimWeight));
//OSD_Printf("pitch %d -> %d\n",origpitch, info.dpitch);
}
else if (abspitch > absyaw)
{
if (info.dyaw > 0)
info.dyaw = max(0, info.dyaw - tabledivide32_noinline(abspitch - absyaw, 11 - ud.config.JoystickAimWeight));
info.dyaw = max(0, info.dyaw - tabledivide32_noinline(abspitch - absyaw, 8 - ud.config.JoystickAimWeight));
else if (info.dyaw < 0)
info.dyaw = min(0, info.dyaw + tabledivide32_noinline(abspitch - absyaw, 11 - ud.config.JoystickAimWeight));
info.dyaw = min(0, info.dyaw + tabledivide32_noinline(abspitch - absyaw, 8 - ud.config.JoystickAimWeight));
//OSD_Printf("yaw %d -> %d\n",origyaw, info.dyaw);
}
......@@ -3127,17 +3238,7 @@ void P_GetInput(int const playerNum)
input.q16horz = fix16_ssub(input.q16horz, fix16_from_float(scaleToInterval(info.dpitch * 16.0 / analogExtent)));
input.svel -= lrint(scaleToInterval(info.dx * keyMove / analogExtent));
input.fvel -= lrint(scaleToInterval(info.dz * keyMove / analogExtent));
if (ud.config.JoystickViewLeveling && !input.q16avel && !input.q16horz && input.fvel && CONTROL_LastSeenInput == LastSeenInput::Joystick)
{
if (pPlayer->q16horiz >= F16(99) && pPlayer->q16horiz <= F16(100))
thisPlayer.horizRecenter = true;
else if (pPlayer->q16horiz < F16(99))
input.q16horz = fix16_add(input.q16horz, fix16_from_float(scaleToInterval(ud.config.JoystickViewLeveling)));
else if (pPlayer->q16horiz > F16(100))
input.q16horz = fix16_sub(input.q16horz, fix16_from_float(scaleToInterval(ud.config.JoystickViewLeveling)));
}
if (BUTTON(gamefunc_Strafe))
{
if (!localInput.svel)
......@@ -3284,6 +3385,12 @@ void P_GetInput(int const playerNum)
localInput.extbits |= BUTTON(gamefunc_Turn_Right) << EK_TURN_RIGHT;
localInput.extbits |= BUTTON(gamefunc_Alt_Fire) << EK_ALT_FIRE;
if (CONTROL_LastSeenInput == LastSeenInput::Joystick)
{
localInput.extbits |= (!!ud.config.JoystickViewCentering) << EK_GAMEPAD_CENTERING;
localInput.extbits |= (!!ud.config.JoystickAimAssist) << EK_GAMEPAD_AIM_ASSIST;
}
int const movementLocked = P_CheckLockedMovement(playerNum);
if ((ud.scrollmode && ud.overhead_on) || (movementLocked & IL_NOTHING) == IL_NOTHING)
......@@ -3306,78 +3413,17 @@ void P_GetInput(int const playerNum)
}
if (!(movementLocked & IL_NOANGLE))
{
localInput.q16avel = fix16_sadd(localInput.q16avel, input.q16avel);
pPlayer->q16ang = fix16_sadd(pPlayer->q16ang, input.q16avel) & 0x7FFFFFF;
}
if (!(movementLocked & IL_NOHORIZ))
{
float horizAngle = atan2f(localInput.q16horz, F16(128)) * (512.f / fPI) + fix16_to_float(input.q16horz);
localInput.q16horz = fix16_clamp(Blrintf(F16(128) * tanf(horizAngle * (fPI / 512.f))), F16(-MAXHORIZVEL), F16(MAXHORIZVEL));
horizAngle = atan2f(pPlayer->q16horiz - F16(100), F16(128)) * (512.f / fPI) + fix16_to_float(input.q16horz);
pPlayer->q16horiz = F16(100) + Blrintf(F16(128) * tanf(horizAngle * (fPI / 512.f)));
}
}
// A horiz diff of 128 equal 45 degrees, so we convert horiz to 1024 angle units
if (thisPlayer.horizAngleAdjust)
{
float const horizAngle
= atan2f(pPlayer->q16horiz - F16(100), F16(128)) * (512.f / fPI) + scaleToInterval(thisPlayer.horizAngleAdjust);
pPlayer->q16horiz = F16(100) + Blrintf(F16(128) * tanf(horizAngle * (fPI / 512.f)));
}
else if (pPlayer->return_to_center > 0 || thisPlayer.horizRecenter)
{
pPlayer->q16horiz = fix16_sadd(pPlayer->q16horiz, fix16_from_float(scaleToInterval(fix16_to_float(F16(66.666) - fix16_sdiv(pPlayer->q16horiz, F16(1.5))))));
if ((!pPlayer->return_to_center && thisPlayer.horizRecenter) || (pPlayer->q16horiz >= F16(99.9) && pPlayer->q16horiz <= F16(100.1)))
{
pPlayer->q16horiz = F16(100);
pPlayer->return_to_center = 0;
thisPlayer.horizRecenter = false;
}
if (pPlayer->q16horizoff >= F16(-0.1) && pPlayer->q16horizoff <= F16(0.1))
pPlayer->q16horizoff = 0;
}
// calculates automatic view angle for playing without a mouse
if (!pPlayer->aim_mode && pPlayer->on_ground && sectorLotag != ST_2_UNDERWATER && (sector[pPlayer->cursectnum].floorstat & 2))
{
// this is some kind of horse shit approximation of where the player is looking, I guess?
vec2_t const adjustedPosition = { pPlayer->pos.x + (sintable[(fix16_to_int(pPlayer->q16ang) + 512) & 2047] >> 5),
pPlayer->pos.y + (sintable[fix16_to_int(pPlayer->q16ang) & 2047] >> 5) };
int16_t currentSector = pPlayer->cursectnum;
updatesector(adjustedPosition.x, adjustedPosition.y, &currentSector);
if (currentSector >= 0)
{
int const slopeZ = getflorzofslope(pPlayer->cursectnum, adjustedPosition.x, adjustedPosition.y);
if ((pPlayer->cursectnum == currentSector) || (klabs(getflorzofslope(currentSector, adjustedPosition.x, adjustedPosition.y) - slopeZ) <= ZOFFSET6))
pPlayer->q16horizoff = fix16_sadd(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(mulscale16(pPlayer->truefz - slopeZ, 160))));
}
}
if (pPlayer->q16horizoff > 0)
{
pPlayer->q16horizoff = fix16_ssub(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(fix16_to_float((pPlayer->q16horizoff >> 3) + fix16_one))));
pPlayer->q16horizoff = fix16_max(pPlayer->q16horizoff, 0);
}
else if (pPlayer->q16horizoff < 0)
{
pPlayer->q16horizoff = fix16_sadd(pPlayer->q16horizoff, fix16_from_float(scaleToInterval(fix16_to_float((-pPlayer->q16horizoff >> 3) + fix16_one))));
pPlayer->q16horizoff = fix16_min(pPlayer->q16horizoff, 0);
}
if (thisPlayer.horizSkew)
pPlayer->q16horiz = fix16_sadd(pPlayer->q16horiz, fix16_from_float(scaleToInterval(thisPlayer.horizSkew)));
pPlayer->q16horiz = fix16_clamp(pPlayer->q16horiz, F16(HORIZ_MIN), F16(HORIZ_MAX));
pPlayer->q16horizoff = fix16_clamp(pPlayer->q16horizoff, F16(HORIZ_MIN), F16(HORIZ_MAX));
if (!ud.recstat)
P_UpdateAngles(playerNum, input);
}
static int32_t P_DoCounters(int playerNum)
......@@ -4868,6 +4914,24 @@ static void P_ClampZ(DukePlayer_t* const pPlayer, int const sectorLotag, int32_t
pPlayer->pos.z = floorZ - PMINHEIGHT;
}
static fix16_t P_GetQ16AngleDeltaForTic(DukePlayer_t const *pPlayer)
{
auto oldAngle = pPlayer->oq16ang;
auto newAngle = pPlayer->q16ang;
if (klabs(fix16_sub(oldAngle, newAngle)) < F16(1024))
return fix16_sub(newAngle, oldAngle);
if (newAngle > F16(1024))
newAngle = fix16_sub(newAngle, F16(2048));
if (oldAngle > F16(1024))
oldAngle = fix16_sub(oldAngle, F16(2048));
return fix16_sub(newAngle, oldAngle);
}
#define GETZRANGECLIPDISTOFFSET 16
void P_ProcessInput(int playerNum)
......@@ -4877,10 +4941,29 @@ void P_ProcessInput(int playerNum)
if (thisPlayer.playerquitflag == 0)
return;
thisPlayer.horizAngleAdjust = 0;
thisPlayer.horizSkew = 0;
thisPlayer.smoothcamera = false;
auto const pPlayer = thisPlayer.ps;
if (pPlayer->newowner < 0)
{
pPlayer->q16angvel = P_GetQ16AngleDeltaForTic(pPlayer);
pPlayer->oq16ang = pPlayer->q16ang;
pPlayer->oq16horiz = pPlayer->q16horiz;
pPlayer->oq16horizoff = pPlayer->q16horizoff;
}
if (ud.recstat || pPlayer->gm & MODE_DEMO)
{
thisPlayer.smoothcamera = true;
P_UpdateAngles(playerNum, thisPlayer.input);
}
// these are used in P_UpdateAngles() and can only be reset after calling it
thisPlayer.horizAngleAdjust = 0;
thisPlayer.horizSkew = 0;
auto const pSprite = &sprite[pPlayer->i];
++pPlayer->player_par;
......
......@@ -154,6 +154,10 @@ enum playeraction_t {
pfacing = 0x00010000
};
#define AM_MOUSE 1
#define AM_CENTERING 2
#define AM_AIMASSIST 4
typedef struct {
vec3_t pos;
int16_t ang, sect;
......@@ -267,6 +271,8 @@ typedef struct
int horizAngleAdjust;
int horizSkew;
double lastViewUpdate;
int32_t netsynctime;
int32_t pcolor, pteam;
int16_t ping;
......@@ -381,6 +387,7 @@ static inline void P_PalFrom(DukePlayer_t *pPlayer, uint8_t f, uint8_t r, uint8_
void P_AddKills(DukePlayer_t * pPlayer, uint16_t kills);
int32_t A_GetHitscanRange(int spriteNum);
void P_GetInput(int playerNum);
void P_UpdateAngles(int const playerNum, input_t const &input);
void P_AddAmmo(DukePlayer_t * pPlayer, int weaponNum, int addAmount);
void P_AddWeapon(DukePlayer_t *pPlayer, int weaponNum, int switchWeapon);
void P_CheckWeapon(DukePlayer_t *pPlayer);
......
......@@ -1687,12 +1687,15 @@ void G_ClearFIFO(void)
for (int p = 0; p < MAXPLAYERS; ++p)
{
g_player[p].input = {};
g_player[p].vote = 0;
g_player[p].gotvote = 0;
auto &player = g_player[p];
g_player[p].horizSkew = 0;
g_player[p].horizAngleAdjust = 0;
player.input = {};
player.vote = 0;
player.gotvote = 0;
player.horizSkew = 0;
player.horizAngleAdjust = 0;
player.lastViewUpdate = 0;
}
}
......
......@@ -2606,7 +2606,8 @@ void P_HandleSharedKeys(int playerNum)
if (pPlayer->cheat_phase == 1) return;
uint32_t playerBits = g_player[playerNum].input.bits, weaponNum;
uint32_t playerBits = g_player[playerNum].input.bits;
uint32_t const extBits = g_player[playerNum].input.extbits;
// 1<<0 = jump
// 1<<1 = crouch
......@@ -2641,7 +2642,10 @@ void P_HandleSharedKeys(int playerNum)
int const aimMode = pPlayer->aim_mode;
pPlayer->aim_mode = (playerBits>>SK_AIMMODE)&1;
if (pPlayer->aim_mode < aimMode)
pPlayer->aim_mode |= ((extBits>>EK_GAMEPAD_CENTERING)&1)<<1;
pPlayer->aim_mode |= ((extBits>>EK_GAMEPAD_AIM_ASSIST)&1)<<2;
if (pPlayer->aim_mode < (aimMode & 3))
pPlayer->return_to_center = 9;
if (TEST_SYNC_KEY(playerBits, SK_QUICK_KICK) && pPlayer->quick_kick == 0)
......@@ -2655,7 +2659,7 @@ void P_HandleSharedKeys(int playerNum)
}
}
weaponNum = playerBits & ((15u<<SK_WEAPON_BITS)|BIT(SK_STEROIDS)|BIT(SK_NIGHTVISION)|BIT(SK_MEDKIT)|BIT(SK_QUICK_KICK)| \
uint32_t weaponNum = playerBits & ((15u<<SK_WEAPON_BITS)|BIT(SK_STEROIDS)|BIT(SK_NIGHTVISION)|BIT(SK_MEDKIT)|BIT(SK_QUICK_KICK)| \
BIT(SK_HOLSTER)|BIT(SK_INV_LEFT)|BIT(SK_PAUSE)|BIT(SK_HOLODUKE)|BIT(SK_JETPACK)|BIT(SK_INV_RIGHT)| \
BIT(SK_TURNAROUND)|BIT(SK_OPEN)|BIT(SK_INVENTORY)|BIT(SK_ESCAPE));
playerBits = weaponNum & ~pPlayer->interface_toggle;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment