raze/source/blood/src/controls.cpp

206 lines
6.2 KiB
C++
Raw Normal View History

2019-09-19 22:42:45 +00:00
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "mmulti.h"
2019-09-19 22:42:45 +00:00
#include "view.h"
#include "gamestate.h"
#include "menu.h"
2019-09-19 22:42:45 +00:00
BEGIN_BLD_NS
2019-09-19 22:42:45 +00:00
static const double gTurnSpeed = 92.;
static InputPacket gInput;
static double turnHeldTime;
enum
{
MAXFVEL = 2048,
MAXSVEL = 2048,
MAXHORIZVEL = 32
};
void UpdatePlayerSpriteAngle(PLAYER* pPlayer);
//---------------------------------------------------------------------------
//
// handles movement
//
//---------------------------------------------------------------------------
2019-09-19 22:42:45 +00:00
static void processMovement(ControlInfo* const hidInput)
{
double const scaleAdjust = InputScale();
int const run = !!(gInput.actions & SB_RUN);
int const keyMove = (1 + run) << 10;
InputPacket input = {};
2019-09-19 22:42:45 +00:00
if (buttonMap.ButtonDown(gamefunc_Strafe))
{
input.svel -= xs_CRoundToInt((hidInput->mousex * 32.) + (scaleAdjust * (hidInput->dyaw * keyMove)));
}
else
{
input.q16avel += FloatToFixed(hidInput->mousex + (scaleAdjust * hidInput->dyaw));
}
if (!(gInput.actions & SB_AIMMODE))
{
input.q16horz += FloatToFixed(hidInput->mousey);
}
else
{
input.fvel -= xs_CRoundToInt(hidInput->mousey * 64.);
}
2019-09-19 22:42:45 +00:00
if (!in_mouseflip)
input.q16horz = -input.q16horz;
2019-09-19 22:42:45 +00:00
input.q16horz -= FloatToFixed(scaleAdjust * hidInput->dpitch);
input.svel -= xs_CRoundToInt(scaleAdjust * (hidInput->dx * keyMove));
input.fvel -= xs_CRoundToInt(scaleAdjust * (hidInput->dz * keyMove));
2019-09-19 22:42:45 +00:00
if (buttonMap.ButtonDown(gamefunc_Strafe))
2019-09-19 22:42:45 +00:00
{
if (gInput.svel < keyMove && gInput.svel > -keyMove)
{
if (buttonMap.ButtonDown(gamefunc_Turn_Left))
input.svel += keyMove;
if (buttonMap.ButtonDown(gamefunc_Turn_Right))
input.svel -= keyMove;
}
2019-09-19 22:42:45 +00:00
}
else
{
if (buttonMap.ButtonDown(gamefunc_Turn_Left))
{
turnHeldTime += scaleAdjust * kTicsPerFrame;
input.q16avel -= FloatToFixed(scaleAdjust * (min(12. * turnHeldTime, gTurnSpeed) / 4.));
}
else if (buttonMap.ButtonDown(gamefunc_Turn_Right))
{
turnHeldTime += scaleAdjust * kTicsPerFrame;
input.q16avel += FloatToFixed(scaleAdjust * (min(12. * turnHeldTime, gTurnSpeed) / 4.));
}
else
{
turnHeldTime = 0;
}
2019-09-19 22:42:45 +00:00
}
if (run && turnHeldTime > 24.)
input.q16avel <<= 1;
2019-09-19 22:42:45 +00:00
if (abs(gInput.fvel) < keyMove)
{
if (buttonMap.ButtonDown(gamefunc_Move_Forward))
input.fvel += keyMove;
2020-09-15 05:24:00 +00:00
if (buttonMap.ButtonDown(gamefunc_Move_Backward))
input.fvel -= keyMove;
}
2019-09-19 22:42:45 +00:00
if (abs(gInput.svel) < keyMove)
{
if (buttonMap.ButtonDown(gamefunc_Strafe_Left))
input.svel += keyMove;
if (buttonMap.ButtonDown(gamefunc_Strafe_Right))
input.svel -= keyMove;
}
if (!cl_syncinput && gamestate == GS_LEVEL)
{
PLAYER* pPlayer = &gPlayer[myconnectindex];
// Perform unsynchronised angle/horizon if not dead.
if (gView->pXSprite->health != 0)
{
applylook(&pPlayer->q16ang, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, input.q16avel, &pPlayer->input.actions, scaleAdjust, gView->pXSprite->health == 0, pPlayer->posture != 0);
UpdatePlayerSpriteAngle(pPlayer);
sethorizon(&pPlayer->q16horiz, input.q16horz, &pPlayer->input.actions, scaleAdjust);
}
// Process angle amendments from the game's ticker.
if (pPlayer->angTarget)
{
fixed_t angDelta = getincangleq16(pPlayer->q16ang, pPlayer->angTarget);
pPlayer->q16ang = (pPlayer->q16ang + xs_CRoundToInt(scaleAdjust * angDelta));
if (abs(pPlayer->q16ang - pPlayer->angTarget) < FRACUNIT)
{
pPlayer->q16ang = pPlayer->angTarget;
pPlayer->angTarget = 0;
}
}
else if (pPlayer->angAdjust)
{
pPlayer->q16ang = (pPlayer->q16ang + FloatToFixed(scaleAdjust * pPlayer->angAdjust)) & 0x7FFFFFF;
}
// Process horizon amendments from the game's ticker.
if (pPlayer->horizTarget)
{
fixed_t horizDelta = pPlayer->horizTarget - pPlayer->q16horiz;
pPlayer->q16horiz += xs_CRoundToInt(scaleAdjust * horizDelta);
if (abs(pPlayer->q16horiz - pPlayer->horizTarget) < FRACUNIT)
{
pPlayer->q16horiz = pPlayer->horizTarget;
pPlayer->horizTarget = 0;
}
}
else if (pPlayer->horizAdjust)
{
pPlayer->q16horiz += FloatToFixed(scaleAdjust * pPlayer->horizAdjust);
}
}
gInput.fvel = clamp(gInput.fvel + input.fvel, -MAXFVEL, MAXFVEL);
gInput.svel = clamp(gInput.svel + input.svel, -MAXSVEL, MAXSVEL);
gInput.q16avel += input.q16avel;
gInput.q16horz = clamp(gInput.q16horz + input.q16horz, -IntToFixed(MAXHORIZVEL), IntToFixed(MAXHORIZVEL));
2019-09-19 22:42:45 +00:00
}
void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput)
{
if (paused || M_Active())
{
gInput = {};
return;
}
ApplyGlobalInput(gInput, hidInput);
processMovement(hidInput);
if (packet)
{
*packet = gInput;
gInput = {};
}
}
END_BLD_NS