Fix some ghost stuff

This commit is contained in:
Miloslav Ciz 2025-01-22 23:10:40 +01:00
parent bcf692d471
commit dedd5505ec
3 changed files with 20 additions and 11 deletions

View file

@ -1,5 +1,6 @@
=========== GENERAL ============== =========== GENERAL ==============
- ghost visible distance
- test if the replay stretching works - test if the replay stretching works
- replay validation - replay validation
- ghosts: if the replay for the ghost is too long (too many samples for the - ghosts: if the replay for the ghost is too long (too many samples for the

22
game.h
View file

@ -350,7 +350,7 @@ void LCR_gameResetRun(uint8_t replay, uint8_t ghost)
LCR_game.runTimeMS = 0; LCR_game.runTimeMS = 0;
} }
void _LCR_gameGetNthGhostSample(unsigned int n, void LCR_gameGetNthGhostSample(unsigned int n,
LCR_GameUnit position[3], LCR_GameUnit rotation[3]) LCR_GameUnit position[3], LCR_GameUnit rotation[3])
{ {
n *= LCR_GHOST_SAMPLE_SIZE; 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); 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) if (n < LCR_SETTING_GHOST_MAX_SAMPLES - 1)
{ {
LCR_GameUnit carTransform[6]; LCR_GameUnit carTransform[6];
// interpolate: // 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; 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; / 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) void _LCR_gamePrepareGhost(void)
@ -448,7 +457,8 @@ void _LCR_gamePrepareGhost(void)
if (LCR_racing.tick % (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch) if (LCR_racing.tick % (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch)
== 0 || LCR_replayHasFinished()) == 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) for (int i = 0; i < 3; ++i)
{ {
@ -474,10 +484,10 @@ void _LCR_gamePrepareGhost(void)
currentSample[4] = currentSample[4] =
(carTransform[4] & 0x0f) | (carTransform[5] << 4); (carTransform[4] & 0x0f) | (carTransform[5] << 4);
currentSample += LCR_GHOST_SAMPLE_SIZE;
if (LCR_replayHasFinished()) if (LCR_replayHasFinished())
break; break;
currentSample += LCR_GHOST_SAMPLE_SIZE;
} }
LCR_racingStep(0); LCR_racingStep(0);

View file

@ -120,7 +120,7 @@ struct
uint16_t currentEvent; uint16_t currentEvent;
uint16_t currentFrame; uint16_t currentFrame;
uint32_t achievedTime; uint32_t achievedTime;
} LCR_replay; } LCR_replay; // TODO: move inside LCR_racing?
/** /**
Gets times of the run in milliseconds. 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;
// 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 Gets current car transformation intended for rendering, i.e. potentially with
smoothing and interpolation applied to the underlying internal state in the smoothing and interpolation (by LCR_GameUnits) applied to the underlying
physics engine. internal state in the physics engine.
*/ */
void LCR_racingGetCarTransform(LCR_GameUnit position[3], void LCR_racingGetCarTransform(LCR_GameUnit position[3],
LCR_GameUnit rotation[3], LCR_GameUnit interpolationParam) LCR_GameUnit rotation[3], LCR_GameUnit interpolationParam)