Start ghost

This commit is contained in:
Miloslav Ciz 2025-01-21 22:46:56 +01:00
parent c0f5e5cf5b
commit 0a91d5f54e
4 changed files with 105 additions and 9 deletions

72
game.h
View file

@ -211,6 +211,12 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y,
#define LCR_MENU_MAX_ITEMS 9 // don't change
#define LCR_RESOURCE_ITEM_CHUNK (LCR_MENU_MAX_ITEMS - 1)
#define LCR_MENU_TABS 4
#if LCR_SETTING_GHOST_MAX_SAMPLES == 0
#undef LCR_MENU_TABS
#define LCR_MENU_TABS 3
#endif
#define LCR_MENU_STRING_SIZE 16
#define LCR_RESOURCE_FILE_SEPARATOR '#'
@ -266,6 +272,23 @@ struct
unsigned int firstItemIndex;
unsigned int itemsTotal;
} dataFile;
#define LCR_GHOST_SAMPLE_SIZE 5
#if LCR_SETTING_GHOST_MAX_SAMPLES != 0
struct
{
uint8_t samples[LCR_SETTING_GHOST_MAX_SAMPLES * LCR_GHOST_SAMPLE_SIZE];
/**< Samples, each 5 bytes: 9 bits for X and Z, 10 for Z,
4 for each rotation component. */
uint8_t stretch; /**< Stretch of the base sample step, as a bit shift
(i.e. 1 means the step will be 2x as long etc.). This
is to allow ghosts for even long replays. */
const uint8_t *currentSample;
uint16_t nextSampleIn;
} ghost;
#endif
} LCR_game;
uint8_t LCR_gameMusicOn(void)
@ -314,13 +337,6 @@ void LCR_gameSetState(uint8_t state)
LCR_game.stateStartTime = LCR_game.time;
}
LCR_GameUnit LCR_carSpeedKMH(void)
{
return // we use 28/8 as an approximation of 3.6 to convers MPS to KMH
(28 * LCR_SETTING_CMS_PER_BLOCK * LCR_racingGetCarSpeedUnsigned() *
LCR_RACING_FPS) / (800 * LCR_GAME_UNIT);
}
void LCR_gameResetRun(uint8_t replay)
{
LCR_GameUnit carTransform[6];
@ -336,6 +352,42 @@ void LCR_gameResetRun(uint8_t replay)
LCR_game.runTimeMS = 0;
}
void _LCR_gamePrepareGhost(void)
{
LCR_GameUnit carTransform[6];
LCR_LOG1("preparing ghost");
LCR_gameResetRun(1);
LCR_game.ghost.stretch = 0;
while (((int) LCR_replay.achievedTime) >
(LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch) *
LCR_SETTING_GHOST_MAX_SAMPLES)
{
LCR_LOG2("stretching replay step");
LCR_game.ghost.stretch++;
}
while (!LCR_replayHasFinished())
{
if (LCR_racing.tick % (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch)
== 0)
{
LCR_racingGetCarTransform(carTransform,carTransform + 3,0);
}
LCR_racingStep(0);
}
}
LCR_GameUnit LCR_carSpeedKMH(void)
{
return // we use 28/8 as an approximation of 3.6 to convers MPS to KMH
(28 * LCR_SETTING_CMS_PER_BLOCK * LCR_racingGetCarSpeedUnsigned() *
LCR_RACING_FPS) / (800 * LCR_GAME_UNIT);
}
/**
Rewinds the global data file reading head to the beginning.
*/
@ -1014,6 +1066,12 @@ uint8_t LCR_gameStep(uint32_t time)
if (_LCR_gameIsLoading())
{
LCR_rendererLoadMap();
if (LCR_game.state == LCR_GAME_STATE_LOADING_REP2)
{
_LCR_gamePrepareGhost();
}
LCR_gameResetRun(
LCR_game.state == LCR_GAME_STATE_LOADING_REP1);
}