Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client: Added strafing HUD #117

Merged
merged 1 commit into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/game/client/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#include "hud/speedometer.h"
#include "hud/jumpspeed.h"
#include "hud/timer.h"
#include "hud/strafeguide.h"

// Adrenaline Gamer HUD Elements
#include "hud/ag/ag_countdown.h"
Expand Down Expand Up @@ -283,6 +284,7 @@ void CHud::Init(void)
RegisterHudElem<CHudSpeedometer>();
RegisterHudElem<CHudJumpspeed>();
RegisterHudElem<CHudTimer>();
RegisterHudElem<CHudStrafeGuide>();

if (CHudRenderer::Get().IsAvailable())
{
Expand Down
2 changes: 2 additions & 0 deletions src/game/client/hud/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ add_sources(
status_icons.h
statusbar.cpp
statusbar.h
strafeguide.cpp
strafeguide.h
text_message.cpp
text_message.h
timer.cpp
Expand Down
167 changes: 167 additions & 0 deletions src/game/client/hud/strafeguide.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#include <cmath>
#include <complex>
#include "hud.h"
#include "cl_util.h"
#include "pm_defs.h"
#include "pm_movevars.h"
#include "strafeguide.h"

enum border {
RED_GREEN,
GREEN_WHITE,
WHITE_GREEN,
GREEN_RED
};

ConVar hud_strafeguide("hud_strafeguide", "0", FCVAR_BHL_ARCHIVE, "Enable strafing HUD");
ConVar hud_strafeguide_zoom("hud_strafeguide_zoom", "1", FCVAR_BHL_ARCHIVE, "Changes zoom for the strafing HUD");
ConVar hud_strafeguide_height("hud_strafeguide_height", "0", FCVAR_BHL_ARCHIVE, "Changes height for the strafing HUD");
ConVar hud_strafeguide_size("hud_strafeguide_size", "0", FCVAR_BHL_ARCHIVE, "Changes size for the strafing HUD");

DEFINE_HUD_ELEM(CHudStrafeGuide);

void CHudStrafeGuide::Init()
{
m_iFlags = HUD_ACTIVE;
}

void CHudStrafeGuide::VidInit()
{
}

void CHudStrafeGuide::Draw(float time)
{
if ((gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH) || gEngfuncs.IsSpectateOnly())
return;

if (!hud_strafeguide.GetBool())
return;

double fov = default_fov.GetFloat() / 180 * M_PI / 2;
double zoom = hud_strafeguide_zoom.GetFloat();

int size = gHUD.m_iFontHeight;
int height = ScreenHeight / 2 - 2*size;

if (hud_strafeguide_size.GetBool())
size = hud_strafeguide_size.GetFloat();

if (hud_strafeguide_height.GetBool())
height = hud_strafeguide_height.GetFloat();

for (int i = 0; i < 4; ++i) {
int r, g, b;
switch (i) {
case RED_GREEN: case WHITE_GREEN:
r = 0; g = 255; b = 0; break;
case GREEN_WHITE:
r = 255; g = 255; b = 255; break;
case GREEN_RED:
r = 255; g = 0; b = 0; break;
}

double boxLeftBase = -angles[i];
double boxRightBase = -angles[(i+1)%4];

if (std::abs(boxLeftBase - boxRightBase) < 1e-10)
continue;
if (boxLeftBase >= boxRightBase)
boxRightBase += 2 * M_PI;
if (std::abs(boxLeftBase - boxRightBase) < 1e-10)
continue;

for (int iCopy = -8; iCopy <= 8; ++iCopy) {
double boxLeft = boxLeftBase + iCopy * 2 * M_PI;
double boxRight = boxRightBase + iCopy * 2 * M_PI;
boxLeft *= zoom;
boxRight *= zoom;

if (std::abs(boxLeft) > fov && std::abs(boxRight) > fov && boxRight * boxLeft > 0)
continue;

boxLeft = boxLeft > fov ? fov : boxLeft < -fov ? -fov : boxLeft;
boxRight = boxRight > fov ? fov : boxRight < -fov ? -fov : boxRight;

boxLeft = std::tan(boxLeft) / std::tan(fov);
boxRight = std::tan(boxRight) / std::tan(fov);

int boxLeftI = boxLeft / 1 * ScreenWidth / 2;
int boxRightI = boxRight/ 1 * ScreenWidth / 2;
boxLeftI += ScreenWidth / 2;
boxRightI += ScreenWidth / 2;

FillRGBA(boxLeftI, height, boxRightI-boxLeftI, size, r, g, b, 60);
}
}
}

static double angleReduce(double a)
{
double tmp = std::fmod(a, 2*M_PI);
if (tmp < 0) tmp += 2*M_PI;
if (tmp > M_PI) tmp -= 2*M_PI;
return tmp;
}

void CHudStrafeGuide::Update(struct ref_params_s *pparams)
{
double frameTime = pparams->frametime;
auto input = std::complex<double>(pparams->cmd->forwardmove, pparams->cmd->sidemove);
double viewAngle = pparams->viewangles[1] / 180 * M_PI;

if (std::norm(input) == 0) {
for (int i = 0; i < 4; ++i) {
if (i < 2)
angles[i] = M_PI;
else
angles[i] = -M_PI;
}
return;
}

std::complex<double> velocity = lastSimvel;
lastSimvel = std::complex<double>(pparams->simvel[0], pparams->simvel[1]);

bool onground = pparams->onground;
double accelCoeff = onground ? pparams->movevars->accelerate : pparams->movevars->airaccelerate;
//TODO: grab the entity friction from somewhere. pparams->movevars->friction is sv_friction
//just use the default 1 for now
double frictionCoeff = 1;

double inputAbs = std::abs(input);
if (onground)
inputAbs = std::min<double>(inputAbs, pparams->movevars->maxspeed);
else
inputAbs = std::min<double>(inputAbs, 30);

input *= inputAbs / std::abs(input);

double uncappedAccel = accelCoeff * frictionCoeff * inputAbs * frameTime;
double velocityAbs = std::abs(velocity);

if (uncappedAccel >= 2 * velocityAbs)
angles[RED_GREEN] = M_PI;
else
angles[RED_GREEN] = std::acos(-uncappedAccel / velocityAbs / 2);

if (velocityAbs <= inputAbs)
angles[GREEN_WHITE] = 0;
else
angles[GREEN_WHITE] = std::acos(inputAbs / velocityAbs);

angles[GREEN_RED] = -angles[RED_GREEN];
angles[WHITE_GREEN] = -angles[GREEN_WHITE];

double inputAngle = std::log(input).imag();
double velocityAngle;

if (velocityAbs == 0)
velocityAngle = 0;
else
velocityAngle = std::log(velocity).imag();

for (int i = 0; i < 4; ++i) {
angles[i] += velocityAngle + inputAngle - viewAngle;
angles[i] = angleReduce(angles[i]);
}
}
21 changes: 21 additions & 0 deletions src/game/client/hud/strafeguide.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef HUD_STRAFEGUIDE_H
#define HUD_STRAFEGUIDE_H
#include "base.h"
#include <complex>

class CHudStrafeGuide : public CHudElemBase<CHudStrafeGuide>
{
public:
virtual void Init();
virtual void VidInit();
virtual void Draw(float time);

void Update(struct ref_params_s *ppmove);

private:
double angles[6] = {0.};

std::complex<double> lastSimvel = 0.;
};

#endif
2 changes: 2 additions & 0 deletions src/game/client/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "hud/spectator.h"
#include "hud/speedometer.h"
#include "hud/jumpspeed.h"
#include "hud/strafeguide.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
Expand Down Expand Up @@ -1677,6 +1678,7 @@ void CL_DLLEXPORT V_CalcRefdef(struct ref_params_s *pparams)
{
CHudSpeedometer::Get()->UpdateSpeed(pparams->simvel);
CHudJumpspeed::Get()->UpdateSpeed(pparams->simvel);
CHudStrafeGuide::Get()->Update(pparams);

// intermission / finale rendering
if (pparams->intermission)
Expand Down