Add power-up HUD

- Power-up icons are sorted by time remaining, most to
  least, left to right
This commit is contained in:
James R 2023-06-29 19:10:18 -07:00
parent c01a29c42a
commit 81dab762ff
4 changed files with 135 additions and 0 deletions

View file

@ -1,3 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
powerup.cpp
timer.cpp
)

131
src/hud/powerup.cpp Normal file
View file

@ -0,0 +1,131 @@
#include <algorithm>
#include <functional>
#include <fmt/format.h>
#include "../core/static_vec.hpp"
#include "../doomstat.h"
#include "../g_game.h"
#include "../k_hud.h"
#include "../k_powerup.h"
#include "../p_local.h"
#include "../r_fps.h"
#include "../v_draw.hpp"
using srb2::Draw;
namespace
{
struct Icon
{
kartitems_t powerup;
tic_t time;
Icon() {}
explicit Icon(int k) :
powerup(static_cast<kartitems_t>(k)),
time(K_PowerUpRemaining(stplyr, powerup))
{
}
int letter() const { return 'A' + (powerup - FIRSTPOWERUP); }
bool operator <(const Icon& b) const { return time < b.time; }
bool operator >(const Icon& b) const { return time > b.time; }
};
srb2::StaticVec<Icon, NUMPOWERUPS> get_powerup_list(bool ascending)
{
srb2::StaticVec<Icon, NUMPOWERUPS> v;
for (int k = FIRSTPOWERUP; k < ENDOFPOWERUPS; ++k)
{
Icon ico(k);
if (ico.time)
{
v.push_back(ico);
}
}
if (ascending)
{
std::sort(v.begin(), v.end(), std::less<Icon>());
}
else
{
std::sort(v.begin(), v.end(), std::greater<Icon>());
}
return v;
}
}; // namespace
void K_drawKartPowerUps(void)
{
struct Offsets
{
Draw row;
const char* sprite;
int spr_x;
int spr_y;
int shift_x;
int dir;
};
auto make_offsets = []() -> Offsets
{
auto make_drawer = [](int x, int y, Draw::Font font) -> Draw
{
return Draw(x, y).font(font).align(Draw::Align::kRight);
};
const int viewnum = R_GetViewNumber();
// 1/2P
switch (r_splitscreen)
{
case 0:
return { make_drawer(307, 55, Draw::Font::kZVote), "PWRU", -17, 7, -35, -1 };
case 1:
return { make_drawer(318, viewnum == 0 ? 55 : 155, Draw::Font::kPing), "PWRS", -9, 6, -19, -1 };
}
// 3/4P
int x = 21;
int y = 47;
int dir = 1;
switch (viewnum)
{
case 1:
case 3:
x = 318;
dir = -1;
}
switch (viewnum)
{
case 2:
case 3:
y += 100;
}
return { make_drawer(x, y, Draw::Font::kPing), "PWRS", -9, 5, 19 * dir, dir };
};
Offsets i = make_offsets();
for (const Icon& ico : get_powerup_list(i.dir == -1))
{
i.row.xy(i.spr_x, i.spr_y).patch(fmt::format("{0}{1:c}L{1:c}R", i.sprite, ico.letter()).c_str());
i.row.text("{}", (ico.time + (TICRATE / 2)) / TICRATE);
i.row = i.row.x(i.shift_x);
}
}

View file

@ -5521,6 +5521,8 @@ void K_drawKartHUD(void)
K_drawMiniPing();
}
K_drawKartPowerUps();
if (G_IsPartyLocal(displayplayers[viewnum]) == false && !demo.playback)
{
K_drawDirectorHUD();

View file

@ -40,6 +40,7 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny);
void K_LoadKartHUDGraphics(void);
void K_drawKartHUD(void);
void K_drawKartFreePlay(void);
void K_drawKartPowerUps(void);
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, UINT8 mode);
void K_drawKart2PTimestamp(void);
void K_drawKart4PTimestamp(void);