Output replays

This commit is contained in:
Miloslav Ciz 2025-01-14 13:40:22 +01:00
parent 17c182f474
commit 2dfad249ad
3 changed files with 100 additions and 18 deletions

55
game.h
View file

@ -357,8 +357,8 @@ char LCR_gameGetNextResourceStrChar(void)
}
/**
Seeks to the Nth resource string in the global resource file, after its name,
so that the pure resource string will now be available for reading.
Seeks to the Nth resource string in the global resource file, after the magic
number, so that the name is now available for reading.
*/
void LCR_seekResourceByIndex(unsigned int index, char magicNumber)
{
@ -368,31 +368,45 @@ void LCR_seekResourceByIndex(unsigned int index, char magicNumber)
LCR_gameRewindResourceFile();
while (index)
do
{
c = LCR_gameGetNextResourceFileChar();
if (c == 0)
return;
if (c == magicNumber)
index--;
do
{
if (index)
index--;
else
return;
}
while (c != 0 && c != LCR_RESOURCE_FILE_SEPARATOR)
c = LCR_gameGetNextResourceFileChar();
while (c != LCR_RESOURCE_FILE_SEPARATOR && c != 0);
}
do // skip magic number and name
c = LCR_gameGetNextResourceFileChar();
while (c != LCR_RESOURCE_FILE_SEPARATOR2 &&
c != LCR_RESOURCE_FILE_SEPARATOR && c != 0);
} while (c);
}
void LCR_gameStartRun(unsigned int mapIndex)
{
char mapName[LCR_MAP_NAME_MAX_LEN];
LCR_seekResourceByIndex(mapIndex,'M');
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar);
mapName[0] = 0;
for (int i = 0; i < LCR_MAP_NAME_MAX_LEN; ++i)
{
char c = LCR_gameGetNextResourceFileChar();
if (c == LCR_RESOURCE_FILE_SEPARATOR2 ||
c == LCR_RESOURCE_FILE_SEPARATOR || c == 0)
break;
mapName[i] = c;
mapName[i + 1] = 0;
}
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar,mapName);
LCR_gameSetState(LCR_GAME_STATE_LOADING_MAP);
}
@ -821,6 +835,11 @@ 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;
@ -871,6 +890,8 @@ uint8_t LCR_gameStep(uint32_t time)
LCR_game.state != LCR_GAME_STATE_RUN_FINISHED)
{
LCR_LOG1("finished");
LCR_replayOutputStr(_LCR_gameResourceCharWrite);
LCR_audioPlaySound(LCR_SOUND_CLICK);
LCR_gameSetState(LCR_GAME_STATE_RUN_FINISHED);
}

17
map.h
View file

@ -56,6 +56,8 @@
- last if C7 is set, the block is flipped vertically
*/
#define LCR_MAP_NAME_MAX_LEN 15 /**< Maximum map name length (without
terminating zero. */
#define LCR_BLOCK_START_CHAR ':'
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
@ -153,6 +155,8 @@ struct
uint8_t checkpointCount;
uint32_t hash; ///< Hash of the processed binary map.
char name[LCR_MAP_NAME_MAX_LEN + 1];
} LCR_currentMap;
void LCR_makeMapBlock(uint8_t type, uint8_t x, uint8_t y, uint8_t z,
@ -373,10 +377,21 @@ void _LCR_mapComputeHash(void)
(LCR_currentMap.hash >> 13)) * 113;
}
uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void))
uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name)
{
LCR_LOG0("loading map string");
for (int i = 0; i < LCR_MAP_NAME_MAX_LEN; ++i)
{
LCR_currentMap.name[i] = *name;
LCR_currentMap.name[i + 1] = 0;
if (*name == 0)
break;
name++;
}
char c;
uint8_t prevBlock[LCR_BLOCK_SIZE];

View file

@ -145,6 +145,52 @@ void LCR_replayInitPlaying(void)
LCR_replay.currentFrame = 0;
}
char _LCR_hexDigit(int i)
{
return i < 10 ? '0' + i : ('a' - 10 + i);
}
/**
Outputs current replay using provided character printing function. The string
will be zero terminated.
*/
void LCR_replayOutputStr(void (*printChar)(char))
{
LCR_LOG1("outputting replay");
const char *s = LCR_currentMap.name;
while (*s)
{
printChar(*s);
s++;
}
printChar(';');
uint32_t hash = LCR_currentMap.hash;
for (int i = 0; i < 8; ++i)
{
printChar(_LCR_hexDigit(hash % 16));
hash /= 16;
}
for (int i = 0; i < LCR_replay.eventCount; ++i)
{
uint16_t e = LCR_replay.events[i];
printChar(' ');
for (int j = 0; j < 4; ++j)
{
printChar(_LCR_hexDigit(e % 16));
e /= 16;
}
}
printChar('\n');
}
/**
During playing of a replay returns the next input and shifts to next frame.
*/