Skip to content

Commit

Permalink
Client: Check that sprites are loaded from hud.txt (#222)
Browse files Browse the repository at this point in the history
Resolves #222
  • Loading branch information
tmp64 committed May 18, 2024
1 parent f52e560 commit c0b642a
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 46 deletions.
15 changes: 13 additions & 2 deletions src/game/client/cdll_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,7 @@ int CL_DLLEXPORT Initialize(cl_enginefunc_t *pEnginefuncs, int iVersion)

if (bIsInitialized)
{
GetSDL()->ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "BugfixedHL Fatal Error", "The engine failed to unload client library during restart.");
std::abort();
HUD_FatalError("The engine failed to unload client library during restart.");
return 0;
}

Expand Down Expand Up @@ -508,6 +507,18 @@ extern "C" void CL_DLLEXPORT F(void *pv)
*pcldll_func = cldll_func;
}

void HUD_FatalError(const char *fmt, ...)
{
char buf[4096];
va_list va;
va_start(va, fmt);
vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va);

GetSDL()->ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "BugfixedHL Fatal Error", buf);
std::abort();
}

//-----------------------------------------------------------------------------
// Purpose: Exports functions that are used by the gameUI for UI dialogs
//-----------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions src/game/client/cl_dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ typedef float vec_t;
#include "cdll_dll.h"

extern cl_enginefunc_t gEngfuncs;

//! Causes a fatal client error. Shows a dialog and crashes the game.
//! @param fmt Printf arguments.
[[noreturn]] void HUD_FatalError(const char *fmt, ...);
106 changes: 62 additions & 44 deletions src/game/client/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ static int GetHudSize(const SCREENINFO &screenInfo, EHudScale maxScale)
return fallbackInfo.iRes;
}

static int CountSpritesOfRes(const client_sprite_t* pSpriteList, int nTotalCount, int iRes)
{
int count = 0;

for (int i = 0; i < nTotalCount; i++)
{
if (pSpriteList[i].iRes == iRes)
count++;
}

return count;
}

CHud::CHud()
{
}
Expand Down Expand Up @@ -441,56 +454,58 @@ void CHud::VidInit(void)
// we need to load the hud.txt, and all sprites within
m_pSpriteList = SPR_GetList("sprites/hud.txt", &m_iSpriteCountAllRes);

if (m_pSpriteList)
{
// count the number of sprites of the appropriate res
m_iSpriteCount = 0;
client_sprite_t *p = m_pSpriteList;
int j;
for (j = 0; j < m_iSpriteCountAllRes; j++)
{
if (p->iRes == m_iRes)
m_iSpriteCount++;
p++;
}
if (!m_pSpriteList)
HUD_FatalError("Failed to load sprites/hud.txt.\nYour game is corrupted.");

// allocated memory for sprite handle arrays
m_rghSprites.resize(m_iSpriteCount);
m_rgrcRects.resize(m_iSpriteCount);
m_rgszSpriteNames.resize(m_iSpriteCount);
m_rgSpritePaths.resize(m_iSpriteCount);
// count the number of sprites of the appropriate res
m_iSpriteCount = CountSpritesOfRes(m_pSpriteList, m_iSpriteCountAllRes, m_iRes);

p = m_pSpriteList;
int index = 0;
for (j = 0; j < m_iSpriteCountAllRes; j++)
{
if (p->iRes == m_iRes)
{
char sz[256];
sprintf(sz, "sprites/%s.spr", p->szSprite);
m_rghSprites[index] = SPR_Load(sz);
m_rgrcRects[index] = p->rc;
Q_strncpy(m_rgszSpriteNames[index].name, p->szName, MAX_SPRITE_NAME_LENGTH);
m_rgSpritePaths[index] = sz;

index++;
}
if (m_iSpriteCount == 0)
{
Warning("Found no sprites with resolution of %d. Defaulting to %d.\n", m_iRes, HUD_FALLBACK_RES);
m_iRes = HUD_FALLBACK_RES;
m_iSpriteCount = CountSpritesOfRes(m_pSpriteList, m_iSpriteCountAllRes, m_iRes);
}

p++;
}
if (m_iSpriteCount == 0)
HUD_FatalError("Failed to find sprites with resolution of %d in sprites/hud.txt.\nYour game is corrupted.", m_iRes);

// allocated memory for sprite handle arrays
m_rghSprites.resize(m_iSpriteCount);
m_rgrcRects.resize(m_iSpriteCount);
m_rgszSpriteNames.resize(m_iSpriteCount);
m_rgSpritePaths.resize(m_iSpriteCount);

// Add AG CTF sprites on non-AG clients
// AG has them in hud.txt
if (!IsAG())
client_sprite_t *p = m_pSpriteList;
int index = 0;
for (int j = 0; j < m_iSpriteCountAllRes; j++)
{
if (p->iRes == m_iRes)
{
AddSprite(client_sprite_t { "item_flag_team1", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "item_flag_team2", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_home", "ag_ctf", 0, 640, wrect_t { 0, 40, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_stolen", "ag_ctf", 0, 640, wrect_t { 40, 80, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_lost", "ag_ctf", 0, 640, wrect_t { 80, 120, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_carry", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_score", "ag_ctf_score", 0, 640, wrect_t { 0, 16, 0, 16 } });
char sz[256];
sprintf(sz, "sprites/%s.spr", p->szSprite);
m_rghSprites[index] = SPR_Load(sz);
m_rgrcRects[index] = p->rc;
Q_strncpy(m_rgszSpriteNames[index].name, p->szName, MAX_SPRITE_NAME_LENGTH);
m_rgSpritePaths[index] = sz;

index++;
}

p++;
}

// Add AG CTF sprites on non-AG clients
// AG has them in hud.txt
if (!IsAG())
{
AddSprite(client_sprite_t { "item_flag_team1", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "item_flag_team2", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_home", "ag_ctf", 0, 640, wrect_t { 0, 40, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_stolen", "ag_ctf", 0, 640, wrect_t { 40, 80, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_lost", "ag_ctf", 0, 640, wrect_t { 80, 120, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_carry", "ag_ctf", 0, 640, wrect_t { 120, 160, 0, 40 } });
AddSprite(client_sprite_t { "icon_ctf_score", "ag_ctf_score", 0, 640, wrect_t { 0, 16, 0, 16 } });
}
}
else
Expand All @@ -511,6 +526,9 @@ void CHud::VidInit(void)
// assumption: number_1, number_2, etc, are all listed and loaded sequentially
m_HUD_number_0 = GetSpriteIndex("number_0");

if (m_HUD_number_0 == -1)
HUD_FatalError("Failed to find sprite 'number_0' in the sprite list.\nYour game is corrupted.");

m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top;

for (CHudElem *i : m_HudList)
Expand Down

0 comments on commit c0b642a

Please sign in to comment.