Fix physics bug

This commit is contained in:
Miloslav Ciz 2025-04-28 18:27:32 +02:00
parent 9dfbeae0d4
commit 5e73098460
4 changed files with 49 additions and 47 deletions

View file

@ -47,14 +47,15 @@ fuck issue trackers :D
- immediately after starting the map countdown seems to be lower (seems to - immediately after starting the map countdown seems to be lower (seems to
perhaps be caused by nextPhysicsFrameTime, look into it) perhaps be caused by nextPhysicsFrameTime, look into it)
- seems like there might be a bug in physics env function, despite it being
impossible in theory, car gets stuck after fast drive into a wall, with its
shape staying OK, but wheel being inside a block somehow, maybe there are
tiny spaces between blocks or some blocks are not checked -- resolve
=========== HANDLED ============== =========== HANDLED ==============
- should drifting make a sound? NO NEED - should drifting make a sound? NO NEED
- seems like there might be a bug in physics env function, despite it being
impossible in theory, car gets stuck after fast drive into a wall, with its
shape staying OK, but wheel being inside a block somehow, maybe there are
tiny spaces between blocks or some blocks are not checked -- resolve
[4 4 63] [5 5 64] [5 4 63] [4 5 64] [4 5 63] [5 4 64] [5 5 63] [4 4 64]
- Managed to get the car stuck in non-rotating state, then after a while get - Managed to get the car stuck in non-rotating state, then after a while get
it back by crashing. MAY BE FIXED NOW, watch if it still happens it back by crashing. MAY BE FIXED NOW, watch if it still happens
- After adding the non-rotating physics feature, the car now gets funny when - After adding the non-rotating physics feature, the car now gets funny when

59
game.h
View file

@ -1257,47 +1257,38 @@ void LCR_gameDraw3DView(void)
// GUI/HUD: // GUI/HUD:
char str[10]; char str[10];
int val = LCR_carSpeedKMH();
switch (LCR_game.state) if (val < 5) // don't show tiny oscillations when still
{ val = 0;
default:
{
int val = LCR_carSpeedKMH();
if (val < 5) // don't show tiny oscillations when still str[0] = val >= 100 ? '0' + (val / 100) % 10 : ' ';
val = 0; str[1] = val >= 10 ? '0' + (val / 10) % 10 : ' ';
str[2] = '0' + val % 10;
str[3] = 0;
str[0] = val >= 100 ? '0' + (val / 100) % 10 : ' '; LCR_rendererDrawText(str,LCR_EFFECTIVE_RESOLUTION_X -
str[1] = val >= 10 ? '0' + (val / 10) % 10 : ' '; LCR_rendererComputeTextWidth(str,2) - LCR_GUI_GAP,
str[2] = '0' + val % 10; LCR_EFFECTIVE_RESOLUTION_Y - LCR_rendererComputeTextHeight(2) -
str[3] = 0; LCR_GUI_GAP,0,2);
LCR_rendererDrawText(str,LCR_EFFECTIVE_RESOLUTION_X - LCR_gameTimeToStr(LCR_timeTicksToMS(LCR_game.runTime),str);
LCR_rendererComputeTextWidth(str,2) - LCR_GUI_GAP,
LCR_EFFECTIVE_RESOLUTION_Y - LCR_rendererComputeTextHeight(2) -
LCR_GUI_GAP,0,2);
LCR_gameTimeToStr(LCR_timeTicksToMS(LCR_game.runTime),str); if (LCR_game.state != LCR_GAME_STATE_RUN_FINISHED)
LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 3 * LCR_GUI_GAP,0,2);
else
LCR_rendererDrawText(str,((LCR_EFFECTIVE_RESOLUTION_X -
LCR_rendererComputeTextWidth(str,4)) / 2),
LCR_EFFECTIVE_RESOLUTION_Y / 2,
LCR_game.runTime <= LCR_currentMap.targetTime ?
LCR_CONVERT_COLOR(0x0700) : LCR_CONVERT_COLOR(0x4208),4);
if (LCR_game.state != LCR_GAME_STATE_RUN_FINISHED) LCR_gameTimeToStr(LCR_currentMap.targetTime * LCR_RACING_TICK_MS,str);
LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 3 * LCR_GUI_GAP,0,2);
else
LCR_rendererDrawText(str,((LCR_EFFECTIVE_RESOLUTION_X -
LCR_rendererComputeTextWidth(str,4)) / 2),
LCR_EFFECTIVE_RESOLUTION_Y / 2,
LCR_game.runTime <= LCR_currentMap.targetTime ?
LCR_CONVERT_COLOR(0x0700) : LCR_CONVERT_COLOR(0x4208),4);
LCR_gameTimeToStr(LCR_currentMap.targetTime * LCR_RACING_TICK_MS,str); LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - LCR_GUI_GAP,
LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y - LCR_CONVERT_COLOR(0x4208),2);
LCR_rendererComputeTextHeight(2) - LCR_GUI_GAP,
LCR_CONVERT_COLOR(0x4208),2);
break;
}
}
} }
void LCR_gameSaveReplay(void) void LCR_gameSaveReplay(void)

25
map.h
View file

@ -136,9 +136,9 @@
/** /**
Cache for accelerating LCR_mapGetBlockAtFast, consists of 8 2-item records, Cache for accelerating LCR_mapGetBlockAtFast, consists of 8 2-item records,
the first record item stores block coord number, the second one stores the the first record item stores block coord number, the second one stores the
value returned by LCR_mapGetBlockAtFast (-1 is 0xffffffff). The record index value returned by LCR_mapGetBlockAtFast (-1 is 0xffffffff, unknown is
depends on the block coords: lowest bit is x % 2, middle bit y % 2, highest 0xfffffffe). The record index depends on the block coords: lowest bit is x %
one z % 2. 2, middle bit y % 2, highest one z % 2.
*/ */
uint32_t _LCR_mapBlockCache[LCR_MAP_BLOCK_CACHE_SIZE]; uint32_t _LCR_mapBlockCache[LCR_MAP_BLOCK_CACHE_SIZE];
@ -160,6 +160,9 @@ struct
void LCR_makeMapBlock(uint8_t type, uint8_t x, uint8_t y, uint8_t z, void LCR_makeMapBlock(uint8_t type, uint8_t x, uint8_t y, uint8_t z,
uint8_t material, uint8_t transform, uint8_t block[LCR_BLOCK_SIZE]) uint8_t material, uint8_t transform, uint8_t block[LCR_BLOCK_SIZE])
{ {
x &= 0x3f;
y &= 0x3f;
z &= 0x3f;
block[0] = type; block[0] = type;
block[1] = x | (y << 6); block[1] = x | (y << 6);
block[2] = (y >> 2) | (z << 4); block[2] = (y >> 2) | (z << 4);
@ -409,13 +412,19 @@ int LCR_mapGetBlockAtFast(uint8_t x, uint8_t y, uint8_t z,
{ {
// binary search (the blocks are sorted) // binary search (the blocks are sorted)
if ((x >= 64) | (y >= 64) | (z >= 64))
return -1;
uint32_t n = LCR_mapBlockCoordsToCoordNumber(x,y,z); uint32_t n = LCR_mapBlockCoordsToCoordNumber(x,y,z);
uint8_t cacheIndex = 2 * ((x % 2) | ((y % 2) << 1) | ((z % 2) << 2)); uint8_t cacheIndex = 2 * ((x % 2) | ((y % 2) << 1) | ((z % 2) << 2));
if (_LCR_mapBlockCache[cacheIndex] == n) if (_LCR_mapBlockCache[cacheIndex] == n)
return switch (_LCR_mapBlockCache[cacheIndex + 1])
(_LCR_mapBlockCache[cacheIndex + 1] != 0xffffffff) ? {
((int) _LCR_mapBlockCache[cacheIndex + 1]) : -1; case 0xffffffff: return -1; break;
case 0xfffffffe: break;
default: return ((int) _LCR_mapBlockCache[cacheIndex + 1]); break;
}
_LCR_mapBlockCache[cacheIndex] = n; _LCR_mapBlockCache[cacheIndex] = n;
@ -710,7 +719,7 @@ uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name)
LCR_LOG2("clearing map block cache") LCR_LOG2("clearing map block cache")
for (int i = 0; i < LCR_MAP_BLOCK_CACHE_SIZE; ++i) for (int i = 0; i < LCR_MAP_BLOCK_CACHE_SIZE; ++i)
_LCR_mapBlockCache[i] = 0xffffffff; _LCR_mapBlockCache[i] = 0xfffffffe;
_LCR_mapComputeHash(); _LCR_mapComputeHash();

View file

@ -81,6 +81,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_CAR_STEER_FRICTION ((3 * TPE_F) / 4) #define LCR_CAR_STEER_FRICTION ((3 * TPE_F) / 4)
#define LCR_CAR_ELASTICITY (TPE_F / 64) #define LCR_CAR_ELASTICITY (TPE_F / 64)
#define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 9) #define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 9)
#define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2) #define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2)
#define LCR_CAR_STEER_SPEED 50 ///< 0 to 64, lower is faster #define LCR_CAR_STEER_SPEED 50 ///< 0 to 64, lower is faster
#define LCR_CAR_STEER_SLOWDOWN 64 ///< slows down steering at higher speeds #define LCR_CAR_STEER_SLOWDOWN 64 ///< slows down steering at higher speeds
@ -810,7 +811,7 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
for (uint8_t i = 0; i < 8; ++i) for (uint8_t i = 0; i < 8; ++i)
{ {
/* Black magic: here we make it so that we the lowest coord numbers /* Black magic: here we make it so that we check the lowest coord numbers
(0,0,0), then the highest (1,1,1), then second lowest (1,0,0), then (0,0,0), then the highest (1,1,1), then second lowest (1,0,0), then
second highest (0,1,1) etc. This way we are narrowing the range (start, second highest (0,1,1) etc. This way we are narrowing the range (start,
end) for the binary search. */ end) for the binary search. */