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.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-09-21 18:59:54 +00:00
|
|
|
|
|
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
#include "compat.h"
|
|
|
|
#include "baselayer.h"
|
2020-02-16 20:31:29 +00:00
|
|
|
#include "mmulti.h"
|
2019-10-25 22:32:49 +00:00
|
|
|
#include "gamecontrol.h"
|
2019-09-19 22:42:45 +00:00
|
|
|
#include "common_game.h"
|
|
|
|
#include "blood.h"
|
|
|
|
#include "controls.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "levels.h"
|
|
|
|
#include "map2d.h"
|
|
|
|
#include "view.h"
|
2019-11-03 19:24:50 +00:00
|
|
|
#include "d_event.h"
|
2020-07-29 21:18:08 +00:00
|
|
|
#include "gamestate.h"
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
BEGIN_BLD_NS
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-05-27 15:22:58 +00:00
|
|
|
GINPUT gInput, gNetInput;
|
2019-09-19 22:42:45 +00:00
|
|
|
bool bSilentAim = false;
|
|
|
|
|
|
|
|
int iTurnCount = 0;
|
2020-08-02 18:44:37 +00:00
|
|
|
static int WeaponToSend;
|
|
|
|
static KEYFLAGS BitsToSend;
|
|
|
|
static USEFLAGS UsesToSend;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
void ctrlInit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ctrlTerm(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t mouseyaxismode = -1;
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
int32_t GetTime(void)
|
|
|
|
{
|
|
|
|
return (int32_t)totalclock;
|
|
|
|
}
|
2019-10-22 21:31:46 +00:00
|
|
|
|
2019-11-03 11:32:58 +00:00
|
|
|
void GameInterface::set_hud_layout(int layout)
|
2019-10-22 21:31:46 +00:00
|
|
|
{
|
2020-01-22 12:53:26 +00:00
|
|
|
layout = clamp(7 - layout, 0, 7); // need to reverse the order because menu sliders always have low values to the left.
|
|
|
|
viewResizeView(layout);
|
2019-10-22 21:31:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
fix16_t gViewLook, gViewAngle;
|
|
|
|
float gViewAngleAdjust;
|
|
|
|
float gViewLookAdjust;
|
|
|
|
int gViewLookRecenter;
|
|
|
|
|
2020-08-03 17:08:49 +00:00
|
|
|
void LocalKeys(void)
|
|
|
|
{
|
|
|
|
bool alt = inputState.AltPressed();
|
|
|
|
bool ctrl = inputState.CtrlPressed();
|
|
|
|
bool shift = inputState.ShiftPressed();
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_Third_Person_View) && !alt && !shift)
|
|
|
|
{
|
|
|
|
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
|
|
|
if (gViewPos > VIEWPOS_0)
|
|
|
|
gViewPos = VIEWPOS_0;
|
|
|
|
else
|
|
|
|
gViewPos = VIEWPOS_1;
|
|
|
|
}
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_See_Coop_View))
|
|
|
|
{
|
|
|
|
buttonMap.ClearButton(gamefunc_See_Coop_View);
|
|
|
|
if (gGameOptions.nGameType == 1)
|
|
|
|
{
|
|
|
|
gViewIndex = connectpoint2[gViewIndex];
|
|
|
|
if (gViewIndex == -1)
|
|
|
|
gViewIndex = connecthead;
|
|
|
|
gView = &gPlayer[gViewIndex];
|
|
|
|
}
|
|
|
|
else if (gGameOptions.nGameType == 3)
|
|
|
|
{
|
|
|
|
int oldViewIndex = gViewIndex;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
gViewIndex = connectpoint2[gViewIndex];
|
|
|
|
if (gViewIndex == -1)
|
|
|
|
gViewIndex = connecthead;
|
|
|
|
if (oldViewIndex == gViewIndex || gMe->teamId == gPlayer[gViewIndex].teamId)
|
|
|
|
break;
|
|
|
|
} while (oldViewIndex != gViewIndex);
|
|
|
|
gView = &gPlayer[gViewIndex];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char key;
|
|
|
|
if ((key = inputState.keyGetScan()) != 0)
|
|
|
|
{
|
|
|
|
if ((alt || shift) && gGameOptions.nGameType > 0 && key >= sc_F1 && key <= sc_F10)
|
|
|
|
{
|
|
|
|
char fk = key - sc_F1;
|
|
|
|
if (alt)
|
|
|
|
{
|
|
|
|
netBroadcastTaunt(myconnectindex, fk);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gPlayerMsg.Set(*CombatMacros[fk]);
|
|
|
|
gPlayerMsg.Send();
|
|
|
|
}
|
|
|
|
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
void ctrlGetInput(void)
|
|
|
|
{
|
2020-05-29 01:20:40 +00:00
|
|
|
int prevPauseState = paused;
|
2019-09-19 22:42:45 +00:00
|
|
|
ControlInfo info;
|
|
|
|
|
2020-05-29 01:20:40 +00:00
|
|
|
static double lastInputTicks;
|
|
|
|
auto const currentHiTicks = timerGetHiTicks();
|
|
|
|
double const elapsedInputTicks = currentHiTicks - lastInputTicks;
|
|
|
|
|
|
|
|
lastInputTicks = currentHiTicks;
|
|
|
|
|
|
|
|
auto scaleAdjustmentToInterval = [=](double x) { return x * kTicsPerSec / (1000.0 / elapsedInputTicks); };
|
|
|
|
|
2020-07-29 21:18:08 +00:00
|
|
|
if (gamestate != GS_LEVEL || System_WantGuiCapture())
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2020-01-30 13:05:34 +00:00
|
|
|
gInput = {};
|
2019-09-19 22:42:45 +00:00
|
|
|
CONTROL_GetInput(&info);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-29 01:20:40 +00:00
|
|
|
updatePauseStatus();
|
|
|
|
if (paused != prevPauseState)
|
|
|
|
{
|
|
|
|
gInput.keyFlags.pause = 1;
|
|
|
|
}
|
2020-01-30 13:05:34 +00:00
|
|
|
|
2020-05-29 01:20:40 +00:00
|
|
|
if (paused)
|
|
|
|
return;
|
2020-01-30 13:05:34 +00:00
|
|
|
|
2020-05-29 01:20:40 +00:00
|
|
|
GINPUT input = {};
|
2020-01-30 13:05:34 +00:00
|
|
|
|
2019-12-05 00:08:35 +00:00
|
|
|
bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming);
|
|
|
|
if (!mouseaim) gInput.keyFlags.lookCenter = 1;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-02-16 20:31:29 +00:00
|
|
|
if (numplayers == 1)
|
|
|
|
{
|
|
|
|
gProfile[myconnectindex].nAutoAim = cl_autoaim;
|
|
|
|
gProfile[myconnectindex].nWeaponSwitch = cl_weaponswitch;
|
|
|
|
}
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
CONTROL_GetInput(&info);
|
|
|
|
|
|
|
|
if (gQuitRequest)
|
|
|
|
gInput.keyFlags.quit = 1;
|
|
|
|
|
2020-08-02 18:44:37 +00:00
|
|
|
gInput.keyFlags.word |= BitsToSend.word;
|
|
|
|
gInput.useFlags.byte |= UsesToSend.byte;
|
|
|
|
gInput.newWeapon = WeaponToSend;
|
|
|
|
|
|
|
|
BitsToSend.word = 0;
|
|
|
|
UsesToSend.byte = 0;
|
|
|
|
WeaponToSend = 0;
|
|
|
|
|
2020-04-11 22:10:39 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Map))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2020-04-11 22:10:39 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Map);
|
2019-09-19 22:42:45 +00:00
|
|
|
viewToggle(gViewMode);
|
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Map_Follow_Mode))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Map_Follow_Mode);
|
2019-09-19 22:42:45 +00:00
|
|
|
gFollowMap = !gFollowMap;
|
|
|
|
gViewMap.FollowMode(gFollowMap);
|
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Shrink_Screen))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
if (gViewMode == 3)
|
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Shrink_Screen);
|
2020-08-02 06:48:23 +00:00
|
|
|
if (!SHIFTS_IS_PRESSED)
|
|
|
|
{
|
|
|
|
G_ChangeHudLayout(-1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hud_scale = hud_scale - 4;
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
if (gViewMode == 2 || gViewMode == 4)
|
|
|
|
{
|
|
|
|
gZoom = ClipLow(gZoom - (gZoom >> 4), 64);
|
|
|
|
gViewMap.nZoom = gZoom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
if (gViewMode == 3)
|
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Enlarge_Screen);
|
2020-08-02 06:48:23 +00:00
|
|
|
if (!SHIFTS_IS_PRESSED)
|
|
|
|
{
|
|
|
|
G_ChangeHudLayout(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hud_scale = hud_scale + 4;
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
if (gViewMode == 2 || gViewMode == 4)
|
|
|
|
{
|
|
|
|
gZoom = ClipHigh(gZoom + (gZoom >> 4), 4096);
|
|
|
|
gViewMap.nZoom = gZoom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Toggle_Crosshair))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Toggle_Crosshair);
|
2019-10-21 21:29:48 +00:00
|
|
|
cl_crosshair = !cl_crosshair;
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-29 01:28:41 +00:00
|
|
|
if (gPlayer[myconnectindex].nextWeapon == 0)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Show_Opponents_Weapon))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Show_Opponents_Weapon);
|
2019-10-27 09:17:46 +00:00
|
|
|
cl_showweapon = (cl_showweapon + 1) & 3;
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Jump))
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.buttonFlags.jump = 1;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Crouch))
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.buttonFlags.crouch = 1;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Fire))
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.buttonFlags.shoot = 1;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Alt_Fire))
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.buttonFlags.shoot2 = 1;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Open))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
buttonMap.ClearButton(gamefunc_Open);
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.keyFlags.action = 1;
|
|
|
|
}
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
gInput.buttonFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Look_Up);
|
|
|
|
gInput.buttonFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Look_Down);
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Look_Down))
|
2019-09-19 22:42:45 +00:00
|
|
|
gInput.keyFlags.lookCenter = 1;
|
|
|
|
else
|
|
|
|
{
|
2020-01-30 13:05:34 +00:00
|
|
|
gInput.buttonFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Aim_Up);
|
|
|
|
gInput.buttonFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Aim_Down);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
int const run = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run));
|
|
|
|
int const run2 = false; // What??? buttonMap.ButtonDown(gamefunc_Run);
|
|
|
|
int const keyMove = (1 + run) << 10;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
gInput.syncFlags.run |= run;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
if (gInput.forward < keyMove && gInput.forward > -keyMove)
|
|
|
|
{
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_Move_Forward))
|
2020-06-24 13:11:42 +00:00
|
|
|
input.forward += keyMove;
|
2020-01-30 13:05:34 +00:00
|
|
|
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_Move_Backward))
|
2020-06-24 13:11:42 +00:00
|
|
|
input.forward -= keyMove;
|
2020-01-30 13:05:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gInput.strafe < keyMove && gInput.strafe > -keyMove)
|
|
|
|
{
|
2020-03-30 22:22:55 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Strafe_Left))
|
2020-01-30 13:05:34 +00:00
|
|
|
input.strafe += keyMove;
|
2020-03-30 22:22:55 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Strafe_Right))
|
2020-01-30 13:05:34 +00:00
|
|
|
input.strafe -= keyMove;
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
char turnLeft = 0, turnRight = 0;
|
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Strafe))
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2020-01-30 13:05:34 +00:00
|
|
|
if (gInput.strafe < keyMove && gInput.strafe > -keyMove)
|
|
|
|
{
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_Turn_Left))
|
|
|
|
input.strafe += keyMove;
|
|
|
|
if (buttonMap.ButtonDown(gamefunc_Turn_Right))
|
|
|
|
input.strafe -= keyMove;
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Turn_Left))
|
2019-09-19 22:42:45 +00:00
|
|
|
turnLeft = 1;
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Turn_Right))
|
2019-09-19 22:42:45 +00:00
|
|
|
turnRight = 1;
|
|
|
|
}
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
static int32_t turnHeldTime;
|
|
|
|
static int32_t lastInputClock; // MED
|
|
|
|
int32_t const elapsedTics = (int32_t)totalclock - lastInputClock;
|
|
|
|
|
2020-06-24 13:11:42 +00:00
|
|
|
// Blood's q16mlook scaling is different from the other games, therefore use the below constant to attenuate
|
|
|
|
// the speed to match the other games.
|
|
|
|
float const mlookScale = 3.25f;
|
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
lastInputClock = (int32_t) totalclock;
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
if (turnLeft || turnRight)
|
2020-01-30 13:05:34 +00:00
|
|
|
turnHeldTime += elapsedTics;
|
2019-09-19 22:42:45 +00:00
|
|
|
else
|
2020-01-30 13:05:34 +00:00
|
|
|
turnHeldTime = 0;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
if (turnLeft)
|
2020-04-13 07:54:47 +00:00
|
|
|
input.q16turn = fix16_ssub(input.q16turn, fix16_from_dbl(scaleAdjustmentToInterval(ClipHigh(12 * turnHeldTime, gTurnSpeed)>>2)));
|
2019-09-19 22:42:45 +00:00
|
|
|
if (turnRight)
|
2020-04-13 07:54:47 +00:00
|
|
|
input.q16turn = fix16_sadd(input.q16turn, fix16_from_dbl(scaleAdjustmentToInterval(ClipHigh(12 * turnHeldTime, gTurnSpeed)>>2)));
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-01-30 13:05:34 +00:00
|
|
|
if ((run2 || run) && turnHeldTime > 24)
|
|
|
|
input.q16turn <<= 1;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-11-04 22:01:50 +00:00
|
|
|
if (buttonMap.ButtonDown(gamefunc_Strafe))
|
2020-06-24 13:11:42 +00:00
|
|
|
{
|
2020-07-05 02:02:33 +00:00
|
|
|
input.strafe -= info.mousex * 32.f;
|
2020-06-24 13:11:42 +00:00
|
|
|
input.strafe -= scaleAdjustmentToInterval(info.dyaw * keyMove);
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
else
|
2020-06-24 13:11:42 +00:00
|
|
|
{
|
2020-07-05 02:02:33 +00:00
|
|
|
input.q16turn = fix16_sadd(input.q16turn, fix16_from_float(info.mousex));
|
2020-06-24 13:11:42 +00:00
|
|
|
input.q16turn = fix16_sadd(input.q16turn, fix16_from_dbl(scaleAdjustmentToInterval(info.dyaw)));
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-06-24 13:11:42 +00:00
|
|
|
input.strafe -= scaleAdjustmentToInterval(info.dx * keyMove);
|
|
|
|
input.forward -= scaleAdjustmentToInterval(info.dz * keyMove);
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-12-05 00:08:35 +00:00
|
|
|
if (mouseaim)
|
2020-07-05 02:02:33 +00:00
|
|
|
input.q16mlook = fix16_sadd(input.q16mlook, fix16_from_float(info.mousey / mlookScale));
|
2019-08-16 04:31:07 +00:00
|
|
|
else
|
2020-07-05 02:02:33 +00:00
|
|
|
input.forward -= info.mousey * 64.f;
|
2019-10-22 22:59:01 +00:00
|
|
|
if (!in_mouseflip)
|
2020-01-30 13:05:34 +00:00
|
|
|
input.q16mlook = -input.q16mlook;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-06-24 13:11:42 +00:00
|
|
|
input.q16mlook = fix16_ssub(input.q16mlook, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch / mlookScale)));
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
if (!gViewMap.bFollowMode && gViewMode == 4)
|
|
|
|
{
|
2020-01-30 13:05:34 +00:00
|
|
|
gViewMap.turn += input.q16turn<<2;
|
|
|
|
gViewMap.forward += input.forward;
|
|
|
|
gViewMap.strafe += input.strafe;
|
|
|
|
input.q16turn = 0;
|
|
|
|
input.forward = 0;
|
|
|
|
input.strafe = 0;
|
|
|
|
}
|
|
|
|
gInput.forward = clamp(gInput.forward + input.forward, -2048, 2048);
|
|
|
|
gInput.strafe = clamp(gInput.strafe + input.strafe, -2048, 2048);
|
|
|
|
gInput.q16turn = fix16_sadd(gInput.q16turn, input.q16turn);
|
2020-03-31 21:30:54 +00:00
|
|
|
gInput.q16mlook = fix16_clamp(fix16_sadd(gInput.q16mlook, input.q16mlook), fix16_from_int(-127)>>2, fix16_from_int(127)>>2);
|
2020-05-29 01:20:40 +00:00
|
|
|
if (gMe && gMe->pXSprite->health != 0 && !paused)
|
2020-01-30 13:05:34 +00:00
|
|
|
{
|
2020-04-01 11:55:36 +00:00
|
|
|
int upAngle = 289;
|
|
|
|
int downAngle = -347;
|
|
|
|
double lookStepUp = 4.0*upAngle/60.0;
|
|
|
|
double lookStepDown = -4.0*downAngle/60.0;
|
2020-04-13 07:54:47 +00:00
|
|
|
gViewAngle = (gViewAngle + input.q16turn + fix16_from_dbl(scaleAdjustmentToInterval(gViewAngleAdjust))) & 0x7ffffff;
|
2020-01-30 13:05:34 +00:00
|
|
|
if (gViewLookRecenter)
|
|
|
|
{
|
|
|
|
if (gViewLook < 0)
|
2020-04-13 07:54:47 +00:00
|
|
|
gViewLook = fix16_min(gViewLook+fix16_from_dbl(scaleAdjustmentToInterval(lookStepDown)), fix16_from_int(0));
|
2020-01-30 13:05:34 +00:00
|
|
|
if (gViewLook > 0)
|
2020-04-13 07:54:47 +00:00
|
|
|
gViewLook = fix16_max(gViewLook-fix16_from_dbl(scaleAdjustmentToInterval(lookStepUp)), fix16_from_int(0));
|
2020-01-30 13:05:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-13 07:54:47 +00:00
|
|
|
gViewLook = fix16_clamp(gViewLook+fix16_from_dbl(scaleAdjustmentToInterval(gViewLookAdjust)), fix16_from_int(downAngle), fix16_from_int(upAngle));
|
2020-01-30 13:05:34 +00:00
|
|
|
}
|
2020-03-31 21:30:54 +00:00
|
|
|
gViewLook = fix16_clamp(gViewLook+(input.q16mlook << 3), fix16_from_int(downAngle), fix16_from_int(upAngle));
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-22 06:39:22 +00:00
|
|
|
|
2020-08-02 18:44:37 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic
|
|
|
|
// registration to only have the commands active when this game module runs.
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static int ccmd_slot(CCmdFuncPtr parm)
|
|
|
|
{
|
|
|
|
if (parm->numparms != 1) return CCMD_SHOWHELP;
|
|
|
|
|
|
|
|
auto slot = atoi(parm->parms[0]);
|
|
|
|
if (slot >= 1 && slot <= 10)
|
|
|
|
{
|
|
|
|
WeaponToSend = slot;
|
|
|
|
return CCMD_OK;
|
|
|
|
}
|
|
|
|
return CCMD_SHOWHELP;
|
|
|
|
}
|
|
|
|
|
|
|
|
void registerinputcommands()
|
|
|
|
{
|
|
|
|
C_RegisterFunction("slot", "slot <weaponslot>: select a weapon from the given slot (1-10)", ccmd_slot);
|
|
|
|
C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.prevWeapon = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.nextWeapon = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("proximitybombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 11; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("remotebombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 12; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("jumpboots", nullptr, [](CCmdFuncPtr)->int { UsesToSend.useJumpBoots = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { UsesToSend.useMedKit = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend.prevItem = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend.nextItem = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("crystalball", nullptr, [](CCmdFuncPtr)->int { UsesToSend.useCrystalBall = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("beastvision", nullptr, [](CCmdFuncPtr)->int { UsesToSend.useBeastVision = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; });
|
|
|
|
C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useItem = 1; return CCMD_OK; });
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is called from ImputState::ClearAllInput and resets all static state being used here.
|
|
|
|
void GameInterface::clearlocalinputstate()
|
|
|
|
{
|
|
|
|
WeaponToSend = 0;
|
|
|
|
BitsToSend.word = 0;
|
|
|
|
UsesToSend.byte = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
END_BLD_NS
|