Add replay loading

This commit is contained in:
Miloslav Ciz 2025-01-15 23:08:31 +01:00
parent 9485a7cd95
commit 8040d6755f
3 changed files with 85 additions and 13 deletions

14
game.h
View file

@ -666,6 +666,11 @@ void LCR_gameDraw3DView(void)
}
}
void _LCR_gameResourceCharWrite(char c)
{ // TODO
printf("%c",c);
}
/**
Helper subroutine, handles user input during main loop frame, EXCEPT for the
driving input (that is handled in the loop itself).
@ -791,8 +796,8 @@ void LCR_gameHandleInput(void)
case LCR_GAME_STATE_RUN_FINISHED:
if (LCR_game.keyStates[LCR_KEY_A] == 1)
//LCR_gameResetRun(LCR_racing.playingReplay);
LCR_gameResetRun(1);
// LCR_gameResetRun(LCR_racing.playingReplay);
LCR_gameResetRun(1);
break;
@ -858,11 +863,6 @@ void LCR_gameHandleInput(void)
LCR_game.menu.selectedTab == 1 ? 'M' : 'R');
}
void _LCR_gameResourceCharWrite(char c)
{
printf("%c",c);
}
uint8_t LCR_gameStep(uint32_t time)
{
uint32_t sleep = 0;

View file

@ -53,4 +53,15 @@ char _LCR_hexDigit(int i)
return i < 10 ? '0' + i : ('a' - 10 + i);
}
int _LCR_hexDigitVal(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return -1;
}
#endif // guard

View file

@ -16,11 +16,12 @@
- Replay text format: first there is the name of the map terminated by ';',
then hexadecimal hash of the map follows (exactly 8 characters), then
blank character follows, then achieved time as a series of decimal digits
expressing the number of milliseconds, then a non-decimal character follows,
then the replay data, i.e. the series of 16 bit words in hexadecimal. The
blocks (but nothing else) may be preceeded or followed by blank characters.
All hexadecimal letters must be lowercase. The word 00000000 may optinally
be used to terminate the replay, the rest of the string will be ignored.
expressing the number of milliseconds, then the replay data, i.e. the series
of 16 bit words in hexadecimal, each preceded by ':'. The events (but
nothing else) may otherwise be preceeded or followed by other characters
(possible comments). All hexadecimal letters must be lowercase. The word
00000000 may optinally be used to terminate the replay, the rest of the
string will be ignored.
*/
typedef int32_t LCR_GameUnit; ///< abstract game unit
@ -189,7 +190,7 @@ void LCR_replayOutputStr(void (*printChar)(char))
for (int i = 0; i < LCR_replay.eventCount; ++i)
{
uint16_t e = LCR_replay.events[i];
printChar(' ');
printChar(':');
for (int j = 0; j < 4; ++j)
{
@ -201,6 +202,66 @@ void LCR_replayOutputStr(void (*printChar)(char))
printChar('\n');
}
/**
Reads replay from string using provided function that returns next character
in the string. Returns 1 on success, else 0.
*/
int LCR_replayLoadFromStr(char (*nextChar)(void))
{
char c = ' ';
LCR_replay.eventCount = 0;
LCR_replay.achievedTime = 0;
do // map name
{
c = nextChar();
if (c == 0)
return 0;
} while (c != ';');
for (int i = 0; i < 8; ++i) // hash
if (_LCR_hexDigitVal(nextChar()) < 0)
return 0;
nextChar();
while (1) // time
{
c = nextChar();
if (c < '0' || c > '9')
break;
LCR_replay.achievedTime = LCR_replay.achievedTime * 10 + c - '0';
}
while (c != 0) // events
{
if (c == ':')
{
uint16_t e = 0;
for (int i = 0; i < 4; ++i)
e = (e << 4) | _LCR_hexDigitVal(nextChar());
if (e == 0)
break;
if (LCR_replay.eventCount >= LCR_SETTING_REPLAY_MAX_SIZE)
return 0;
LCR_replay.events[LCR_replay.eventCount] = e;
LCR_replay.eventCount++;
}
c = nextChar();
}
return 1;
}
/**
During playing of a replay returns the next input and shifts to next frame.
*/