From dedd5505ecb93eb51ec470d89f962b9bb6813cb2 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Wed, 22 Jan 2025 23:10:40 +0100 Subject: [PATCH] Fix some ghost stuff --- TODO.txt | 1 + game.h | 22 ++++++++++++++++------ racing.h | 8 +++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/TODO.txt b/TODO.txt index 6ba6875..cbbd781 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,6 @@ =========== GENERAL ============== +- ghost visible distance - test if the replay stretching works - replay validation - ghosts: if the replay for the ghost is too long (too many samples for the diff --git a/game.h b/game.h index 3cd3964..e764853 100644 --- a/game.h +++ b/game.h @@ -350,7 +350,7 @@ void LCR_gameResetRun(uint8_t replay, uint8_t ghost) LCR_game.runTimeMS = 0; } -void _LCR_gameGetNthGhostSample(unsigned int n, +void LCR_gameGetNthGhostSample(unsigned int n, LCR_GameUnit position[3], LCR_GameUnit rotation[3]) { n *= LCR_GHOST_SAMPLE_SIZE; @@ -392,14 +392,14 @@ void LCR_gameGhostGetTransform(uint32_t frame, { unsigned int n = ((frame >> LCR_game.ghost.stretch) / LCR_SETTING_GHOST_STEP); - _LCR_gameGetNthGhostSample(n % 64,position,rotation); + LCR_gameGetNthGhostSample(n,position,rotation); if (n < LCR_SETTING_GHOST_MAX_SAMPLES - 1) { LCR_GameUnit carTransform[6]; // interpolate: - _LCR_gameGetNthGhostSample((n % 64) + 1,carTransform,carTransform + 3); + LCR_gameGetNthGhostSample(n + 1,carTransform,carTransform + 3); n = (frame >> LCR_game.ghost.stretch) % LCR_SETTING_GHOST_STEP; @@ -422,6 +422,15 @@ void LCR_gameGhostGetTransform(uint32_t frame, / LCR_SETTING_GHOST_STEP)) % LCR_GAME_UNIT; } } + + /* Small hack: at the beginning the ghost can be seen misaligned with the + real car due to its quantized position, here we gradually snap it to the + nearest 1/8th of a block (which should hit the start position) during the + first 16 frames. */ + if (LCR_racing.tick < 16) + for (int i = 0; i < 3; ++i) + position[i] = position[i] + (LCR_racing.tick * (position[i] - + ((position[i] + LCR_GAME_UNIT / 8) / (LCR_GAME_UNIT / 4)))) / 16; } void _LCR_gamePrepareGhost(void) @@ -448,7 +457,8 @@ void _LCR_gamePrepareGhost(void) if (LCR_racing.tick % (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch) == 0 || LCR_replayHasFinished()) { - LCR_racingGetCarTransform(carTransform,carTransform + 3,0); + LCR_racingGetCarTransform(carTransform,carTransform + 3, + LCR_GAME_UNIT / 2); for (int i = 0; i < 3; ++i) { @@ -474,10 +484,10 @@ void _LCR_gamePrepareGhost(void) currentSample[4] = (carTransform[4] & 0x0f) | (carTransform[5] << 4); + currentSample += LCR_GHOST_SAMPLE_SIZE; + if (LCR_replayHasFinished()) break; - - currentSample += LCR_GHOST_SAMPLE_SIZE; } LCR_racingStep(0); diff --git a/racing.h b/racing.h index e96d915..f600074 100644 --- a/racing.h +++ b/racing.h @@ -120,7 +120,7 @@ struct uint16_t currentEvent; uint16_t currentFrame; uint32_t achievedTime; -} LCR_replay; +} LCR_replay; // TODO: move inside LCR_racing? /** Gets times of the run in milliseconds. @@ -326,8 +326,6 @@ int LCR_replayHasFinished(void) } return LCR_replay.currentEvent > LCR_replay.eventCount; - -// return LCR_replay.currentEvent >= LCR_replay.eventCount; } /** @@ -957,8 +955,8 @@ void LCR_racingInit(void) /** Gets current car transformation intended for rendering, i.e. potentially with - smoothing and interpolation applied to the underlying internal state in the - physics engine. + smoothing and interpolation (by LCR_GameUnits) applied to the underlying + internal state in the physics engine. */ void LCR_racingGetCarTransform(LCR_GameUnit position[3], LCR_GameUnit rotation[3], LCR_GameUnit interpolationParam)