mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
257 lines
6.9 KiB
C++
257 lines
6.9 KiB
C++
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2024 by Kart Krew.
|
|
// Copyright (C) 2020 by Sonic Team Junior.
|
|
// Copyright (C) 2000 by DooM Legacy Team.
|
|
// Copyright (C) 1996 by id Software, Inc.
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
/// \file g_demo.h
|
|
/// \brief Demo recording and playback
|
|
|
|
#ifndef __G_DEMO__
|
|
#define __G_DEMO__
|
|
|
|
#include "doomdef.h"
|
|
#include "doomstat.h"
|
|
#include "d_event.h"
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
// Modern json formats
|
|
namespace srb2
|
|
{
|
|
struct StandingJson
|
|
{
|
|
uint8_t ranking;
|
|
std::string name;
|
|
uint8_t demoskin;
|
|
std::string skincolor;
|
|
uint32_t timeorscore;
|
|
|
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
|
StandingJson,
|
|
ranking,
|
|
name,
|
|
demoskin,
|
|
skincolor,
|
|
timeorscore
|
|
)
|
|
};
|
|
struct StandingsJson
|
|
{
|
|
std::vector<StandingJson> standings;
|
|
|
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(StandingsJson, standings)
|
|
};
|
|
|
|
void write_current_demo_standings(const StandingsJson& standings);
|
|
void write_current_demo_end_marker();
|
|
|
|
} // namespace srb2
|
|
|
|
extern "C" {
|
|
#endif
|
|
|
|
// ======================================
|
|
// DEMO playback/recording related stuff.
|
|
// ======================================
|
|
|
|
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality;
|
|
|
|
extern tic_t demostarttime;
|
|
|
|
struct democharlist_t {
|
|
char name[SKINNAMESIZE+1];
|
|
UINT32 namehash;
|
|
UINT8 mapping; // No, this isn't about levels. It maps to loaded character ID.
|
|
UINT8 kartspeed;
|
|
UINT8 kartweight;
|
|
UINT32 flags;
|
|
boolean unlockrequired;
|
|
};
|
|
|
|
// Publicly-accessible demo vars
|
|
struct demovars_s {
|
|
char titlename[65];
|
|
boolean recording, playback, timing;
|
|
UINT16 version; // Current file format of the demo being played
|
|
UINT8 attract; // Attract demo can be cancelled by any key
|
|
boolean rewinding; // Rewind in progress
|
|
|
|
boolean loadfiles, ignorefiles; // Demo file loading options
|
|
boolean quitafterplaying; // quit after playing a demo from cmdline
|
|
boolean deferstart; // don't start playing demo right away
|
|
boolean netgame; // multiplayer netgame
|
|
boolean waitingfortally; // demo ended but we're keeping the level open for the tally to finish
|
|
|
|
tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going
|
|
boolean willsave;
|
|
|
|
boolean freecam;
|
|
|
|
UINT8 numskins;
|
|
democharlist_t *skinlist;
|
|
UINT8 currentskinid[MAXPLAYERS];
|
|
|
|
const savebuffer_t *buffer; // debug, valid only if recording or playback
|
|
};
|
|
|
|
extern struct demovars_s demo;
|
|
|
|
typedef enum {
|
|
MD_NOTLOADED,
|
|
MD_LOADED,
|
|
MD_SUBDIR,
|
|
MD_OUTDATED,
|
|
MD_INVALID
|
|
} menudemotype_e;
|
|
|
|
struct menudemo_t {
|
|
char filepath[1023 + 256]; // see M_PrepReplayList and sizeof menupath
|
|
menudemotype_e type;
|
|
|
|
char title[65]; // Null-terminated for string prints
|
|
UINT16 map;
|
|
UINT8 addonstatus; // What do we need to do addon-wise to play this demo?
|
|
INT16 gametype;
|
|
SINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk
|
|
UINT8 numlaps;
|
|
UINT8 gp;
|
|
|
|
struct {
|
|
UINT8 ranking;
|
|
char name[MAXPLAYERNAME+1];
|
|
UINT8 skin, color;
|
|
UINT32 timeorscore;
|
|
} standings[MAXPLAYERS];
|
|
};
|
|
|
|
|
|
// Only called by startup code.
|
|
void G_RecordDemo(const char *name);
|
|
void G_BeginRecording(void);
|
|
|
|
// Only called by shutdown code.
|
|
void G_SetDemoTime(UINT32 ptime, UINT32 plap);
|
|
UINT8 G_CmpDemoTime(char *oldname, char *newname);
|
|
|
|
typedef enum
|
|
{
|
|
GHC_NORMAL = 0,
|
|
GHC_INVINCIBLE,
|
|
GHC_SUPER
|
|
} ghostcolor_t;
|
|
|
|
extern UINT8 demo_extradata[MAXPLAYERS];
|
|
extern UINT8 demo_writerng;
|
|
|
|
#define DXD_JOINDATA 0x01 // join-specific data
|
|
#define DXD_PLAYSTATE 0x02 // state changed between playing, spectating, or not in-game
|
|
#define DXD_SKIN 0x04 // skin changed
|
|
#define DXD_NAME 0x08 // name changed
|
|
#define DXD_COLOR 0x10 // color changed
|
|
#define DXD_FOLLOWER 0x20 // follower was changed
|
|
#define DXD_START 0x40 // Crossed the line in TA
|
|
|
|
#define DXD_ADDPLAYER (DXD_JOINDATA|DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER)
|
|
|
|
#define DXD_WEAPONPREF 0x80 // netsynced playsim settings were changed
|
|
|
|
#define DXD_PST_PLAYING 0x01
|
|
#define DXD_PST_SPECTATING 0x02
|
|
#define DXD_PST_LEFT 0x03
|
|
|
|
// Record/playback tics
|
|
void G_ReadDemoExtraData(void);
|
|
void G_WriteDemoExtraData(void);
|
|
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
|
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
|
void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
|
|
void G_GhostAddFlip(INT32 playernum);
|
|
void G_GhostAddScale(INT32 playernum, fixed_t scale);
|
|
void G_GhostAddHit(INT32 playernum, mobj_t *victim);
|
|
void G_WriteAllGhostTics(void);
|
|
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
|
|
void G_ConsAllGhostTics(void);
|
|
void G_ConsGhostTic(INT32 playernum);
|
|
void G_GhostTicker(void);
|
|
|
|
void G_InitDemoRewind(void);
|
|
void G_StoreRewindInfo(void);
|
|
void G_PreviewRewind(tic_t previewtime);
|
|
void G_ConfirmRewind(tic_t rewindtime);
|
|
|
|
struct DemoBufferSizes
|
|
{
|
|
size_t player_name;
|
|
size_t skin_name;
|
|
size_t color_name;
|
|
};
|
|
|
|
// Your naming conventions are stupid and useless.
|
|
// There is no conflict here.
|
|
struct demoghost {
|
|
UINT8 checksum[16];
|
|
UINT8 *buffer, *p, color;
|
|
UINT8 fadein;
|
|
UINT16 version;
|
|
UINT8 numskins;
|
|
boolean linecrossed;
|
|
boolean done;
|
|
democharlist_t *skinlist;
|
|
mobj_t oldmo, *mo;
|
|
struct DemoBufferSizes sizes;
|
|
struct demoghost *next;
|
|
};
|
|
extern demoghost *ghosts;
|
|
|
|
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
|
#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart.
|
|
#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order.
|
|
#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not.
|
|
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
|
|
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
|
|
#define DFILE_ERROR_CORRUPT 0x06 // Demo file is corrupted
|
|
|
|
void G_DeferedPlayDemo(const char *demo);
|
|
void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum);
|
|
#define G_DoPlayDemo(defdemoname) G_DoPlayDemoEx(defdemoname, LUMPERROR)
|
|
void G_TimeDemo(const char *name);
|
|
void G_AddGhost(savebuffer_t *buffer, const char *defdemoname);
|
|
staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer);
|
|
void G_FreeGhosts(void);
|
|
void G_DoneLevelLoad(void);
|
|
|
|
void G_StopDemo(void);
|
|
boolean G_CheckDemoStatus(void);
|
|
|
|
void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer);
|
|
void G_DeferedPlayDemo(const char *demo);
|
|
|
|
void G_SaveDemo(void);
|
|
|
|
boolean G_CheckDemoTitleEntry(void);
|
|
|
|
typedef enum
|
|
{
|
|
DEMO_ATTRACT_OFF = 0,
|
|
DEMO_ATTRACT_TITLE,
|
|
DEMO_ATTRACT_CREDITS
|
|
} demoAttractMode_t;
|
|
|
|
void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#endif // __G_DEMO__
|