Skip to content

Commit

Permalink
HUD scaling via triangle API
Browse files Browse the repository at this point in the history
  • Loading branch information
Toodles2You committed Oct 7, 2024
1 parent e760b9f commit 38ab1a3
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 31 deletions.
2 changes: 2 additions & 0 deletions cl_dll/cdll_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ int DLLEXPORT HUD_Redraw(float time, int intermission)

gHUD.Redraw(time, 0 != intermission);

DrawCrosshair();

return 1;
}

Expand Down
48 changes: 31 additions & 17 deletions cl_dll/cl_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,46 +44,52 @@ inline const char* CVAR_GET_STRING(const char* x) { return gEngfuncs.pfnGetCvarS
inline struct cvar_s* CVAR_CREATE(const char* cv, const char* val, const int flags) { return gEngfuncs.pfnRegisterVariable((char*)cv, (char*)val, flags); }

#define SPR_Load (*gEngfuncs.pfnSPR_Load)
#define SPR_Set (*gEngfuncs.pfnSPR_Set)
void SPR_Set(HSPRITE hPic, int r, int g, int b);
#define SPR_Frames (*gEngfuncs.pfnSPR_Frames)
#define SPR_GetList (*gEngfuncs.pfnSPR_GetList)

// SPR_Draw draws a the current sprite as solid
#define SPR_Draw (*gEngfuncs.pfnSPR_Draw)
void SPR_Draw(int frame, int x, int y, const Rect* prc);
// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent)
#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles)
void SPR_DrawHoles(int frame, int x, int y, const Rect* prc);
// SPR_DrawAdditive adds the sprites RGB values to the background (additive transulency)
#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive)
void SPR_DrawAdditive(int frame, int x, int y, const Rect* prc);

// SPR_EnableScissor sets a clipping rect for HUD sprites. (0,0) is the top-left hand corner of the screen.
#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor)
// SPR_DisableScissor disables the clipping rect
#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor)
//
#define FillRGBA (*gEngfuncs.pfnFillRGBA)
void FillRGBA(int x, int y, int width, int height, int r, int g, int b, int a);


// ScreenHeight returns the height of the screen, in pixels
#define ScreenHeight (gHUD.m_scrinfo.iHeight)
// ScreenWidth returns the width of the screen, in pixels
#define ScreenWidth (gHUD.m_scrinfo.iWidth)
// ScreenHeight returns the reference height of the HUD
#define ScreenHeight (gHUD.m_iConHeight)
// ScreenWidth returns the reference width of the HUD
#define ScreenWidth (gHUD.m_iConWidth)

// RealScreenHeight returns the height of the screen, in pixels
#define RealScreenHeight (gHUD.m_scrinfo.iHeight)
// RealScreenWidth returns the width of the screen, in pixels
#define RealScreenWidth (gHUD.m_scrinfo.iWidth)

#define BASE_XRES 640.f

// use this to project world coordinates to screen coordinates
#define XPROJECT(x) ((1.0f + (x)) * ScreenWidth * 0.5f)
#define YPROJECT(y) ((1.0f - (y)) * ScreenHeight * 0.5f)
#define XPROJECT(x) ((1.0f + (x)) * RealScreenWidth * 0.5f)
#define YPROJECT(y) ((1.0f - (y)) * RealScreenHeight * 0.5f)

#define XRES(x) ((x) * ((float)ScreenWidth / 640))
#define YRES(y) ((y) * ((float)ScreenHeight / 480))
#define XRES_HD(x) ((x) * V_max(1, (float)ScreenWidth / 1280))
#define YRES_HD(y) ((y) * V_max(1, (float)ScreenHeight / 720))
#define XRES(x) ((x) * ((float)RealScreenWidth / 640))
#define YRES(y) ((y) * ((float)RealScreenHeight / 480))
#define XRES_HD(x) ((x) * V_max(1, (float)RealScreenWidth / 1280))
#define YRES_HD(y) ((y) * V_max(1, (float)RealScreenHeight / 720))

#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo)
#define ServerCmd (*gEngfuncs.pfnServerCmd)
#define EngineClientCmd (*gEngfuncs.pfnClientCmd)
#define EngineFilteredClientCmd (*gEngfuncs.pfnFilteredClientCmd)
#define SetCrosshair (*gEngfuncs.pfnSetCrosshair)
void SetCrosshair(HSPRITE hspr, Rect rc, int r, int g, int b);
void DrawCrosshair();
#define AngleVectors (*gEngfuncs.pfnAngleVectors)


Expand All @@ -99,12 +105,20 @@ inline int TextMessageDrawChar(int x, int y, int number, int r, int g, int b)

inline int DrawConsoleString(int x, int y, const char* string)
{
return gEngfuncs.pfnDrawConsoleString(x, y, (char*)string);
const int width = gEngfuncs.pfnDrawConsoleString(
gHUD.m_flOffsetX + gHUD.m_flScaleX * x,
gHUD.m_flOffsetY + gHUD.m_flScaleY * y,
(char*)string);

return (width - gHUD.m_flOffsetX) / gHUD.m_flScaleX;
}

inline void GetConsoleStringSize(const char* string, int* width, int* height)
{
gEngfuncs.pfnDrawConsoleStringLen(string, width, height);

*width = *width / gHUD.m_flScaleX;
*height = *height / gHUD.m_flScaleY;
}

inline int ConsoleStringLen(const char* string)
Expand Down
68 changes: 68 additions & 0 deletions cl_dll/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
#include "demo_api.h"
#include "vgui_ScorePanel.h"

#include "com_model.h"
#include "r_studioint.h"

extern engine_studio_api_t IEngineStudio;

hud_player_info_t g_PlayerInfoList[MAX_PLAYERS_HUD + 1]; // player info from the engine
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS_HUD + 1]; // additional player info sent directly to the client dll

Expand Down Expand Up @@ -86,6 +91,7 @@ cvar_t* cl_rollangle = nullptr;
cvar_t* cl_rollspeed = nullptr;
cvar_t* cl_bobtilt = nullptr;
cvar_t* r_decals = nullptr;
cvar_t* crosshair = nullptr;

void ShutdownInput();

Expand Down Expand Up @@ -336,6 +342,8 @@ void CHud::Init()
cl_rollspeed = CVAR_CREATE("cl_rollspeed", "200", FCVAR_ARCHIVE);
cl_bobtilt = CVAR_CREATE("cl_bobtilt", "0", FCVAR_ARCHIVE);
r_decals = gEngfuncs.pfnGetCvarPointer("r_decals");
m_pCvarScale = CVAR_CREATE("hud_scale", "1", FCVAR_ARCHIVE);
crosshair = gEngfuncs.pfnGetCvarPointer("crosshair");

m_pSpriteList = NULL;

Expand Down Expand Up @@ -423,6 +431,10 @@ void CHud::VidInit()
m_scrinfo.iSize = sizeof(m_scrinfo);
GetScreenInfo(&m_scrinfo);

m_bShouldScale = m_pCvarScale->value != 0.0F;

UpdateScreenInfo();

// ----------
// Load Sprites
// ---------
Expand Down Expand Up @@ -707,3 +719,59 @@ float CHud::GetSensitivity()
{
return m_flMouseSensitivity;
}

bool CHud::ShouldScale()
{
return IEngineStudio.IsHardware() && m_bShouldScale;
}

void CHud::UpdateScreenInfo()
{
m_iScaleValue = m_pCvarScale->value;

if (!ShouldScale())
{
// default values for functions that may still reference them

m_iConWidth = RealScreenWidth;
m_iConHeight = RealScreenHeight;

m_flScaleX = m_flScaleY = 1.0F;
m_flOffsetX = m_flOffsetY = 0.0F;

return;
}

// hud reference size
m_iConWidth = V_min(640, RealScreenWidth);
m_iConHeight = V_min(480, RealScreenHeight);

// set the scaling factor by using the minor axis

if (RealScreenWidth >= RealScreenHeight)
{
// letterbox or widescreen

m_flScaleX = m_flScaleY = RealScreenHeight / (float)ScreenHeight;

// adapt to the real aspect ratio
m_iConWidth = m_iConHeight * (RealScreenWidth / (float)RealScreenHeight);
}
else
{
// portrait (half-life mobile confirmed?!)

m_flScaleX = m_flScaleY = RealScreenWidth / (float)ScreenWidth;

// adapt to the real aspect ratio
m_iConHeight = m_iConWidth * (RealScreenHeight / (float)RealScreenWidth);
}

// keep the reference sizes even
m_iConWidth = (int)(m_iConWidth / 2) * 2;
m_iConHeight = (int)(m_iConHeight / 2) * 2;

// set the scaling offsets
m_flOffsetX = (RealScreenWidth - ScreenWidth * m_flScaleX) / 2.0;
m_flOffsetY = (RealScreenHeight - ScreenHeight * m_flScaleY) / 2.0;
}
13 changes: 13 additions & 0 deletions cl_dll/hud.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,19 @@ class CHud
void AddHudElem(CHudBase* p);

float GetSensitivity();

cvar_t* m_pCvarScale;
int m_iScaleValue;
bool m_bShouldScale;
int m_iConWidth;
int m_iConHeight;
float m_flScaleX;
float m_flScaleY;
float m_flOffsetX;
float m_flOffsetY;

bool ShouldScale();
void UpdateScreenInfo();
};

extern CHud gHUD;
Expand Down
19 changes: 17 additions & 2 deletions cl_dll/hud_redraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ void CHud::Think()
m_scrinfo.iSize = sizeof(m_scrinfo);
GetScreenInfo(&m_scrinfo);

if (m_iScaleValue != (int)m_pCvarScale->value)
{
UpdateScreenInfo();
}

int newfov;
HUDLIST* pList = m_pHudList;

Expand Down Expand Up @@ -215,7 +220,12 @@ void ScaleColors(int& r, int& g, int& b, int a)

int CHud::DrawHudString(int xpos, int ypos, int iMaxX, const char* szIt, int r, int g, int b)
{
return xpos + gEngfuncs.pfnDrawString(xpos, ypos, szIt, r, g, b);
const int width = gEngfuncs.pfnDrawString(
m_flOffsetX + m_flScaleX * xpos,
m_flOffsetY + m_flScaleY * ypos,
szIt, r, g, b);

return xpos + (width - m_flOffsetX) / m_flScaleX;
}

int CHud::DrawHudNumberString(int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b)
Expand All @@ -228,7 +238,12 @@ int CHud::DrawHudNumberString(int xpos, int ypos, int iMinX, int iNumber, int r,
// draws a string from right to left (right-aligned)
int CHud::DrawHudStringReverse(int xpos, int ypos, int iMinX, const char* szString, int r, int g, int b)
{
return xpos - gEngfuncs.pfnDrawStringReverse(xpos, ypos, szString, r, g, b);
const int width = gEngfuncs.pfnDrawStringReverse(
m_flOffsetX + m_flScaleX * xpos,
m_flOffsetY + m_flScaleY * ypos,
szString, r, g, b);

return xpos + (width - m_flOffsetX) / m_flScaleX;
}

int CHud::DrawHudNumber(int x, int y, int iFlags, int iNumber, int r, int g, int b)
Expand Down
24 changes: 12 additions & 12 deletions cl_dll/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,18 @@ int CHudMessage::XPosition(float x, int width, int totalWidth)

if (x == -1)
{
xPos = (ScreenWidth - width) / 2;
xPos = (RealScreenWidth - width) / 2;
}
else
{
if (x < 0)
xPos = (1.0 + x) * ScreenWidth - totalWidth; // Alight right
xPos = (1.0 + x) * RealScreenWidth - totalWidth; // Alight right
else
xPos = x * ScreenWidth;
xPos = x * RealScreenWidth;
}

if (xPos + width > ScreenWidth)
xPos = ScreenWidth - width;
if (xPos + width > RealScreenWidth)
xPos = RealScreenWidth - width;
else if (xPos < 0)
xPos = 0;

Expand All @@ -120,18 +120,18 @@ int CHudMessage::YPosition(float y, int height)
int yPos;

if (y == -1) // Centered?
yPos = (ScreenHeight - height) * 0.5;
yPos = (RealScreenHeight - height) * 0.5;
else
{
// Alight bottom?
if (y < 0)
yPos = (1.0 + y) * ScreenHeight - height; // Alight bottom
yPos = (1.0 + y) * RealScreenHeight - height; // Alight bottom
else // align top
yPos = y * ScreenHeight;
yPos = y * RealScreenHeight;
}

if (yPos + height > ScreenHeight)
yPos = ScreenHeight - height;
if (yPos + height > RealScreenHeight)
yPos = RealScreenHeight - height;
else if (yPos < 0)
yPos = 0;

Expand Down Expand Up @@ -196,7 +196,7 @@ void CHudMessage::MessageScanNextChar()

if (m_parms.pMessage->effect == 1 && m_parms.charTime != 0)
{
if (m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]) <= ScreenWidth)
if (m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]) <= RealScreenWidth)
TextMessageDrawChar(m_parms.x, m_parms.y, m_parms.text, m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2);
}
}
Expand Down Expand Up @@ -305,7 +305,7 @@ void CHudMessage::MessageDrawScan(client_textmessage_t* pMessage, float time)
int next = m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text];
MessageScanNextChar();

if (m_parms.x >= 0 && m_parms.y >= 0 && next <= ScreenWidth)
if (m_parms.x >= 0 && m_parms.y >= 0 && next <= RealScreenWidth)
TextMessageDrawChar(m_parms.x, m_parms.y, m_parms.text, m_parms.r, m_parms.g, m_parms.b);
m_parms.x = next;
}
Expand Down
Loading

0 comments on commit 38ab1a3

Please sign in to comment.