WIP: splits

This commit is contained in:
Antonio Martinez 2025-08-06 19:51:36 -04:00
parent bf8511c495
commit a11acfaf0e
5 changed files with 151 additions and 22 deletions

View file

@ -350,6 +350,13 @@ typedef enum
khud_exp,
khud_exptimer,
// Splits
khud_splittime,
khud_splitwin,
khud_splittimer,
khud_splitskin,
khud_splitcolor,
NUMKARTHUD
} karthudtype_t;

View file

@ -118,7 +118,7 @@ size_t copy_fixed_buf(void* p, const void* s, size_t n)
static char demoname[MAX_WADPATH];
static savebuffer_t demobuf = {0};
static UINT8 *demotime_p, *demoinfo_p, *demoattack_p;
static UINT8 *demotime_p, *demoinfo_p, *demoattack_p, *demosplits_p;
static UINT16 demoflags;
boolean demosynced = true; // console warning message
@ -2068,6 +2068,13 @@ void G_BeginRecording(void)
demoattack_p = demobuf.p;
WRITEUINT32(demobuf.p, INT32_MAX);
demosplits_p = demobuf.p;
for (i = 0; i < MAXSPLITS; i++)
{
WRITEUINT32(demobuf.p, INT32_MAX);
}
// Save netvar data
CV_SaveDemoVars(&demobuf.p);
@ -2235,10 +2242,59 @@ void srb2::write_current_demo_end_marker()
void G_SetDemoAttackTiming(tic_t time)
{
if (!demo.playback)
if (demo.playback)
return;
*(UINT32 *)demoattack_p = time;
}
void G_SetDemoCheckpointTiming(player_t *player, tic_t time, UINT8 checkpoint)
{
if (demo.playback)
return;
if (checkpoint >= MAXSPLITS || checkpoint < 0)
return;
UINT32 *splits = (UINT32 *)demosplits_p;
splits[checkpoint] = time;
CONS_Printf("%d / %d\n", checkpoint, time);
demoghost *g;
tic_t lowest = INT32_MAX;
UINT32 lowestskin = ((skin_t*)player->mo->skin) - skins;
UINT32 lowestcolor = player->skincolor;
for (g = ghosts; g; g = g->next)
{
if (lowest > g->splits[checkpoint])
{
lowest = g->splits[checkpoint];
lowestskin = ((skin_t*)g->mo->skin)-skins;
lowestcolor = g->mo->color;
}
CONS_Printf("->%d\n", g->splits[checkpoint]);
}
if (lowest != INT32_MAX)
{
player->karthud[khud_splittimer] = 1;
player->karthud[khud_splitskin] = lowestskin;
player->karthud[khud_splitcolor] = lowestcolor;
if (lowest < time)
{
player->karthud[khud_splittime] = time - lowest;
player->karthud[khud_splitwin] = false;
}
else
{
player->karthud[khud_splittime] = lowest - time;
player->karthud[khud_splitwin] = true;
}
}
}
void G_SetDemoTime(UINT32 ptime, UINT32 plap)
{
if (!demo.recording || !demotime_p)
@ -2594,6 +2650,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer)
extrainfo_p = info.buffer + READUINT32(info.p); // The extra UINT32 read is for a blank 4 bytes?
info.p += 4; // attack start
for (i = 0; i < MAXSPLITS; i++)
info.p += 4; // splits
// Pared down version of CV_LoadNetVars to find the kart speed
pdemo->kartspeed = KARTSPEED_NORMAL; // Default to normal speed
@ -3509,7 +3567,13 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
}
p += 4; // Extra data location reference
UINT32 attackstart = READUINT32(p);
tic_t attackstart = READUINT32(p);
UINT8 *splits = p;
for (i = 0; i < MAXSPLITS; i++)
{
p += 4;
}
// net var data
count = READUINT16(p);
@ -3602,6 +3666,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
gh->skinlist = skinlist;
gh->attackstart = attackstart;
std::memcpy(gh->splits, splits, sizeof(tic_t) * MAXSPLITS);
ghosts = gh;
@ -3755,6 +3820,8 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
p += 4; // Extrainfo location marker
p += 4; // Attack start info
for (i = 0; i < MAXSPLITS; i++)
p += 4; // splits
// Ehhhh don't need ghostversion here (?) so I'll reuse the var here
ghostversion = READUINT16(p);

View file

@ -168,6 +168,8 @@ extern UINT8 demo_writerng;
#define DXD_PST_SPECTATING 0x02
#define DXD_PST_LEFT 0x03
#define MAXSPLITS (200)
boolean G_CompatLevel(UINT16 level);
// Record/playback tics
@ -203,6 +205,7 @@ struct demoghost {
UINT16 version;
UINT8 numskins;
tic_t attackstart;
tic_t splits[MAXSPLITS];
boolean done;
democharlist_t *skinlist;
mobj_t oldmo, *mo;
@ -238,6 +241,7 @@ void G_SaveDemo(void);
void G_ResetDemoRecording(void);
void G_SetDemoAttackTiming(tic_t time);
void G_SetDemoCheckpointTiming(player_t *player, tic_t time, UINT8 checkpoint);
boolean G_CheckDemoTitleEntry(void);

View file

@ -7758,9 +7758,48 @@ void K_drawKartHUD(void)
using srb2::Draw;
Draw::TextElement text = Draw::TextElement().parse("<z> Restart");
Draw(BASEVIDWIDTH - 19, 2)
.flags(flags | V_YELLOWMAP)
.flags(flags | V_ORANGEMAP)
.align(Draw::Align::kRight)
.text(text.string());
boolean debug_alwaysdraw = false;
if (stplyr->karthud[khud_splittimer] || debug_alwaysdraw)
{
tic_t split = stplyr->karthud[khud_splittime];
UINT32 skin = stplyr->karthud[khud_splitskin];
UINT32 color = stplyr->karthud[khud_splitcolor];
boolean ahead = stplyr->karthud[khud_splitwin];
// debug
if (!stplyr->karthud[khud_splittimer])
{
ahead = !!((leveltime/17)%2);
split = leveltime;
skin = stplyr->skin;
color = stplyr->skincolor;
}
UINT8 *skincolor = R_GetTranslationColormap(skin, static_cast<skincolornum_t>(color), GTC_CACHE);
UINT8 textcolor = ahead ? SKINCOLOR_SAPPHIRE : SKINCOLOR_KETCHUP;
Draw row = Draw(BASEVIDWIDTH/2, BASEVIDHEIGHT/4).align(Draw::Align::kCenter)
.font(Draw::Font::kThinTimer).flags(V_30TRANS);
// vibes offset
row.x(-32).colormap(skincolor).patch(R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap);
Draw::TextElement text = Draw::TextElement(
std::string(ahead ? "-" : "+") + "{:02}'{:02}\"{:02}",
G_TicsToMinutes(split, true),
G_TicsToSeconds(split),
G_TicsToCentiseconds(split)
);
// vibes offset TWO
row.colormap(textcolor).colorize(textcolor).x(8).text(text);
}
}
else
{

View file

@ -4422,6 +4422,11 @@ void K_CheckpointCrossAward(player_t *player)
if (gametype != GT_RACE)
return;
if (!demo.playback && G_TimeAttackStart())
{
G_SetDemoCheckpointTiming(player, leveltime, player->gradingpointnum);
}
player->gradingfactor += K_GetGradingFactorAdjustment(player);
player->gradingpointnum++;
player->exp = K_GetEXP(player);
@ -9039,6 +9044,13 @@ void K_KartPlayerHUDUpdate(player_t *player)
if (player->karthud[khud_trickcool])
player->karthud[khud_trickcool]--;
if (player->karthud[khud_splittimer])
{
player->karthud[khud_splittimer]++;
if (player->karthud[khud_splittimer] > 2*TICRATE)
player->karthud[khud_splittimer] = 0;
}
if (player->positiondelay)
player->positiondelay--;