Compare commits
4 commits
41f9d3f886
...
74013219e5
Author | SHA1 | Date | |
---|---|---|---|
74013219e5 | |||
60cf16c8de | |||
57097c57bb | |||
f0d8521e90 |
6 changed files with 676 additions and 602 deletions
14
TODO.txt
14
TODO.txt
|
@ -2,10 +2,8 @@ fuck issue trackers :D
|
||||||
|
|
||||||
=========== GENERAL ==============
|
=========== GENERAL ==============
|
||||||
|
|
||||||
- check again the target times for maps
|
- controller supports? analog input could be "tapping" the keys with varying
|
||||||
- remake TM maps in the third party repo
|
frequency
|
||||||
- make reverse maps
|
|
||||||
- ghost color
|
|
||||||
- frontends:
|
- frontends:
|
||||||
- auto test frontend, with no I/O, that will just internally run a series of
|
- auto test frontend, with no I/O, that will just internally run a series of
|
||||||
inputs and check if the output is as expected
|
inputs and check if the output is as expected
|
||||||
|
@ -46,6 +44,12 @@ fuck issue trackers :D
|
||||||
=========== HANDLED ==============
|
=========== HANDLED ==============
|
||||||
|
|
||||||
- should drifting make a sound? NO NEED
|
- should drifting make a sound? NO NEED
|
||||||
|
- menu: key repeat?
|
||||||
|
- replay validation? maybe yes?
|
||||||
|
- ghost color
|
||||||
|
- make reverse maps
|
||||||
|
- remake TM maps in the third party repo
|
||||||
|
- check again the target times for maps
|
||||||
- redo the menu effect somehow
|
- redo the menu effect somehow
|
||||||
- press forward map??? :-D only when physics is frozen
|
- press forward map??? :-D only when physics is frozen
|
||||||
- devtest map, internal camera: reversing at start makes the car face completely
|
- devtest map, internal camera: reversing at start makes the car face completely
|
||||||
|
@ -69,8 +73,6 @@ fuck issue trackers :D
|
||||||
again (reshape iterations, tension, ...); seem acceptable now maybe?
|
again (reshape iterations, tension, ...); seem acceptable now maybe?
|
||||||
- in tiny resolution the sky jumps when rotating
|
- in tiny resolution the sky jumps when rotating
|
||||||
- car particles seem too big in low res
|
- car particles seem too big in low res
|
||||||
- replay validation? MAYBE NOT, make a separate tool if needed, shouldn't likely
|
|
||||||
be part of the game
|
|
||||||
- at high resolution (like 1920) buggy triangles sometimes appeard, tried to
|
- at high resolution (like 1920) buggy triangles sometimes appeard, tried to
|
||||||
fix this in S3L now but needs to be tested
|
fix this in S3L now but needs to be tested
|
||||||
- shift the car texture a bit to align the wheels? KINDA DOESN'T GETT BETTER NOW
|
- shift the car texture a bit to align the wheels? KINDA DOESN'T GETT BETTER NOW
|
||||||
|
|
|
@ -29,7 +29,7 @@ const char *part1 = // big maps
|
||||||
":=C0j:f347"
|
":=C0j:f347"
|
||||||
":=H0q2:f42c"
|
":=H0q2:f42c"
|
||||||
":xB2k:f625" // start hole
|
":xB2k:f625" // start hole
|
||||||
":uB2o:uF2oJ :uB2kL :uF2kI" // curved corners in start
|
":uB2o:uF2oJ:uB2kL:uF2kI" // curved corners in start
|
||||||
":]G2kL:]G2oL" // decorative ramps near start
|
":]G2kL:]G2oL" // decorative ramps near start
|
||||||
":-w29:f41e"
|
":-w29:f41e"
|
||||||
":xH0r:f35b" // hole
|
":xH0r:f35b" // hole
|
||||||
|
@ -92,7 +92,7 @@ const char *part1 = // big maps
|
||||||
":xA1I:f912:xf0n:f715"
|
":xA1I:f912:xf0n:f715"
|
||||||
":xf0s:fc1a:xC0B:f419"
|
":xf0s:fc1a:xC0B:f419"
|
||||||
":xL0n:f32c:xf0N:fg23"
|
":xL0n:f32c:xf0N:fg23"
|
||||||
":-r1s:f418:=i0h2 :f63a"
|
":-r1s:f418:=i0h2:f63a"
|
||||||
":^n2m2L:f114:^l2q2I:f211:vn2q2J:An0q2L:f121:=l0m:m335"
|
":^n2m2L:f114:^l2q2I:f211:vn2q2J:An0q2L:f121:=l0m:m335"
|
||||||
":=n0q2:'n0C2L:f116:'o0C2J:f116"
|
":=n0q2:'n0C2L:f116:'o0C2J:f116"
|
||||||
":'l1I2L:f115:-m1I2:f215:'o1I2J:f115"
|
":'l1I2L:f115:-m1I2:f215:'o1I2J:f115"
|
||||||
|
@ -122,7 +122,7 @@ const char *part1 = // big maps
|
||||||
":<ubrJ:]uarL-:|u9rL-:|tarJ:]t9rJ"
|
":<ubrJ:]uarL-:|u9rL-:|tarJ:]t9rJ"
|
||||||
":=t8r:<u5rJ-:]u6rL:|u7rL:|t6rJ-:]t7rJ-"
|
":=t8r:<u5rJ-:]u6rL:|u7rL:|t6rJ-:]t7rJ-"
|
||||||
":<g1G2:f511:'g1H2:f511" // ramp left
|
":<g1G2:f511:'g1H2:f511" // ramp left
|
||||||
":<J1G2 :f511 :'J1H2 :f511" // ramp right
|
":<J1G2:f511:'J1H2:f511" // ramp right
|
||||||
// details:
|
// details:
|
||||||
":vw1F1:f131:vx1F1|:f131:vw1E1L:f131:vx1E1|J:f131" // tree
|
":vw1F1:f131:vx1F1|:f131:vw1E1L:f131:vx1E1|J:f131" // tree
|
||||||
":~m1D2:~q1E2:~z2I2:~v2M2:~E2K2:~q1o2:~u1p2:~G1z:~H1E" // bumps
|
":~m1D2:~q1E2:~z2I2:~v2M2:~E2K2:~q1o2:~u1p2:~G1z:~H1E" // bumps
|
||||||
|
@ -142,7 +142,7 @@ const char *part1 = // big maps
|
||||||
":*qrt:!o1y:!o1z:+Wsz"
|
":*qrt:!o1y:!o1z:+Wsz"
|
||||||
// start box:
|
// start box:
|
||||||
":=mqr:f96d:xnrs:f74b:^mvrJ:f11d:^uvrL:f11d"
|
":=mqr:f96d:xnrs:f74b:^mvrJ:f11d:^uvrL:f11d"
|
||||||
":~ouz3- :~suz3- :~ouw3- :~suw3-" // lights
|
":~ouz3-:~suz3-:~ouw3-:~suw3-" // lights
|
||||||
":^utuI-:^utv-:^utzI-:^utA-"
|
":^utuI-:^utv-:^utzI-:^utA-"
|
||||||
":'ustI:-usu:-usv:'usw"
|
":'ustI:-usu:-usv:'usw"
|
||||||
":'usyI:-usz:-usA:'usB"
|
":'usyI:-usz:-usA:'usB"
|
||||||
|
@ -390,7 +390,7 @@ const char *part2 = // small maps
|
||||||
- 1536 (0x600) triangles */
|
- 1536 (0x600) triangles */
|
||||||
|
|
||||||
// TINY MAP 1:
|
// TINY MAP 1:
|
||||||
"#MLCtiny1;330 0 :*G1b:+n9H:!I1H"
|
"#MLCtiny1;330 0:*G1b:+n9H:!I1H"
|
||||||
// start
|
// start
|
||||||
":=E0b:f61i"
|
":=E0b:f61i"
|
||||||
":^D1bJ:f11i:^J1bL:f11i"
|
":^D1bJ:f11i:^J1bL:f11i"
|
||||||
|
|
3
data
3
data
|
@ -53,7 +53,6 @@ details
|
||||||
:=h0h2 :fl12 :f11o :=B0i2 :f11m :=m0n2 :fb12
|
:=h0h2 :fl12 :f11o :=B0i2 :f11m :=m0n2 :fb12
|
||||||
:*n1EI :!n1F :+p1r :+y1l :+y3I :+k1l
|
:*n1EI :!n1F :+p1r :+y1l :+y3I :+k1l
|
||||||
#MLCbonus2;1309 1
|
#MLCbonus2;1309 1
|
||||||
|
|
||||||
:*B1lJ
|
:*B1lJ
|
||||||
:^y0oI :f611
|
:^y0oI :f611
|
||||||
:=w0k :f814 :=w0o :f2a1 :=y6c :f21d
|
:=w0k :f814 :=w0o :f2a1 :=y6c :f21d
|
||||||
|
@ -130,7 +129,6 @@ details
|
||||||
:]h0gI :}g0gI :|g1gI :f211 :|g3gI- :f211 :]g4gI- :f211 :;g0fJ :f251
|
:]h0gI :}g0gI :|g1gI :f211 :|g3gI- :f211 :]g4gI- :f211 :;g0fJ :f251
|
||||||
:-e5g :f413 :|g0hL
|
:-e5g :f413 :|g0hL
|
||||||
:+018 :f213 :!v05 :f311
|
:+018 :f213 :!v05 :f311
|
||||||
#Mempty;594 0
|
|
||||||
#MLCpressforw1;594 0
|
#MLCpressforw1;594 0
|
||||||
:*cac
|
:*cac
|
||||||
press forward map, blocks go in the direction that car travels
|
press forward map, blocks go in the direction that car travels
|
||||||
|
@ -208,4 +206,3 @@ air path
|
||||||
#Rdrummy LCbonus1 13'16;00LCbonus1;999b1acd 0000399:0001:0089:0051:0079:0021:0093:0031:0089:0031:0119:0091:0053:00f1:01a3:00d1:0099:0201:0073:0051:0063:0051:0059:0051:00d9:00b1:0089:0041:00a3:0031:02b9:0048:0020:0081:0149:00c1:0059:0031:0113:0051:0019:0078:0099:0041
|
#Rdrummy LCbonus1 13'16;00LCbonus1;999b1acd 0000399:0001:0089:0051:0079:0021:0093:0031:0089:0031:0119:0091:0053:00f1:01a3:00d1:0099:0201:0073:0051:0063:0051:0059:0051:00d9:00b1:0089:0041:00a3:0031:02b9:0048:0020:0081:0149:00c1:0059:0031:0113:0051:0019:0078:0099:0041
|
||||||
#Rdrummy LCbonus2 24'18;00LCbonus2;288d28fe 0000733:0001:0153:00d1:0023:0081:00d3:0041:0023:00a9:0128:0034:0036:00e4:005c:0054:0096:0044:007c:0024:0146:0112:0018:0029:00f1:0063:0061:00c3:0031:00c3:0031:0025:0031:0039:0081:0033:01d1:0083:0081:0073:0031:00e3:0071:00f9:0051:01b9:00c4:0040:0028:0069:0021:0043:00e1:0090:0046:00b0:0031:0043:0070:0024:0026:00e0:0018:0049:0018:0039:01a1:0039:0051:0049:0048:001c:0098:0050:0011:0039:0061:00d9:0041:00a9:0018:00c9:00e1:0083:0042:0010:0042:0093:00b1:0170:0022:0016:0042:0083:0141:0013:0021:0059:0041:0053
|
#Rdrummy LCbonus2 24'18;00LCbonus2;288d28fe 0000733:0001:0153:00d1:0023:0081:00d3:0041:0023:00a9:0128:0034:0036:00e4:005c:0054:0096:0044:007c:0024:0146:0112:0018:0029:00f1:0063:0061:00c3:0031:00c3:0031:0025:0031:0039:0081:0033:01d1:0083:0081:0073:0031:00e3:0071:00f9:0051:01b9:00c4:0040:0028:0069:0021:0043:00e1:0090:0046:00b0:0031:0043:0070:0024:0026:00e0:0018:0049:0018:0039:01a1:0039:0051:0049:0048:001c:0098:0050:0011:0039:0061:00d9:0041:00a9:0018:00c9:00e1:0083:0042:0010:0042:0093:00b1:0170:0022:0016:0042:0083:0141:0013:0021:0059:0041:0053
|
||||||
#Rdrummy LCpressforw1 21'31;00LCpressforw1;6363b43d 0000599:0001
|
#Rdrummy LCpressforw1 21'31;00LCpressforw1;6363b43d 0000599:0001
|
||||||
|
|
||||||
|
|
56
game.h
56
game.h
|
@ -853,8 +853,8 @@ uint8_t LCR_gameLoadMap(unsigned int mapIndex)
|
||||||
/**
|
/**
|
||||||
Loads replay by its index, returns index of a map for the replay (and the map
|
Loads replay by its index, returns index of a map for the replay (and the map
|
||||||
will be loaded as with LCR_mapLoadFromStr) or -1 if the map wasn't found or -2
|
will be loaded as with LCR_mapLoadFromStr) or -1 if the map wasn't found or -2
|
||||||
if the replay couldn't be loaded. This function potentially reloads current
|
if the replay couldn't be loaded or -3 if the replay is invalid. This function
|
||||||
map!
|
potentially reloads current map!
|
||||||
*/
|
*/
|
||||||
unsigned int LCR_gameLoadReplay(unsigned int replayIndex)
|
unsigned int LCR_gameLoadReplay(unsigned int replayIndex)
|
||||||
{
|
{
|
||||||
|
@ -900,7 +900,7 @@ unsigned int LCR_gameLoadReplay(unsigned int replayIndex)
|
||||||
LCR_LOG2("map name hash matches");
|
LCR_LOG2("map name hash matches");
|
||||||
|
|
||||||
if (LCR_gameLoadMap(mapIndex) && mapHash == LCR_currentMap.hash)
|
if (LCR_gameLoadMap(mapIndex) && mapHash == LCR_currentMap.hash)
|
||||||
return mapIndex;
|
return LCR_replayValidate() ? mapIndex : -3;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LCR_LOG2("bad map");
|
LCR_LOG2("bad map");
|
||||||
|
@ -1243,10 +1243,10 @@ void LCR_gameDraw3DView(void)
|
||||||
LCR_GameUnit carTransform[6];
|
LCR_GameUnit carTransform[6];
|
||||||
|
|
||||||
LCR_GameUnit physicsInterpolationParam =
|
LCR_GameUnit physicsInterpolationParam =
|
||||||
!(LCR_racing.playingReplay && LCR_replayHasFinished()) ?
|
!(LCR_racing.replay.on && LCR_replayHasFinished()) ?
|
||||||
LCR_GAME_UNIT -
|
LCR_GAME_UNIT -
|
||||||
((LCR_game.nextRacingTickTime - LCR_game.time) * LCR_GAME_UNIT)
|
((LCR_game.nextRacingTickTime - LCR_game.time) * LCR_GAME_UNIT)
|
||||||
/ LCR_RACING_TICK_MS
|
/ LCR_RACING_TICK_MS_RT
|
||||||
: LCR_GAME_UNIT / 2;
|
: LCR_GAME_UNIT / 2;
|
||||||
|
|
||||||
LCR_racingGetCarTransform(carTransform,carTransform + 3,
|
LCR_racingGetCarTransform(carTransform,carTransform + 3,
|
||||||
|
@ -1353,7 +1353,8 @@ void LCR_gameSaveReplay(void)
|
||||||
|
|
||||||
LCR_gameTimeToStr(LCR_timeTicksToMS(LCR_game.runTime),str);
|
LCR_gameTimeToStr(LCR_timeTicksToMS(LCR_game.runTime),str);
|
||||||
|
|
||||||
for (int i = 0; i < LCR_MAP_NAME_MAX_LEN; ++i)
|
for (int i = (str[0] == '0' && str[1] == '0' ? 3 : 0);
|
||||||
|
i < LCR_MAP_NAME_MAX_LEN; ++i)
|
||||||
if (str[i])
|
if (str[i])
|
||||||
_LCR_gameDataCharWrite(str[i]);
|
_LCR_gameDataCharWrite(str[i]);
|
||||||
else
|
else
|
||||||
|
@ -1365,6 +1366,17 @@ void LCR_gameSaveReplay(void)
|
||||||
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_SAVED]);
|
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_SAVED]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if given key is either immediately pressed or repeated after being
|
||||||
|
held for some time.
|
||||||
|
*/
|
||||||
|
uint8_t LCR_gameKeyActive(uint8_t key)
|
||||||
|
{
|
||||||
|
return LCR_game.keyStates[key] == 1 ||
|
||||||
|
(LCR_game.keyStates[key] >= (1200 / LCR_SETTING_FPS)
|
||||||
|
&& ((LCR_game.frame & 0x03) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Helper subroutine, handles user input during main loop frame, EXCEPT for the
|
Helper subroutine, handles user input during main loop frame, EXCEPT for the
|
||||||
driving input (that is handled in the loop itself).
|
driving input (that is handled in the loop itself).
|
||||||
|
@ -1387,7 +1399,7 @@ void LCR_gameHandleInput(void)
|
||||||
LCR_currentMap.targetTime = LCR_game.runTime;
|
LCR_currentMap.targetTime = LCR_game.runTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCR_gameResetRun(LCR_racing.playingReplay,LCR_game.ghost.active);
|
LCR_gameResetRun(LCR_racing.replay.on,LCR_game.ghost.active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (LCR_game.state == LCR_GAME_STATE_RUN_STARTING)
|
else if (LCR_game.state == LCR_GAME_STATE_RUN_STARTING)
|
||||||
|
@ -1447,7 +1459,7 @@ void LCR_gameHandleInput(void)
|
||||||
LCR_rendererMoveCamera(offsets,offsets + 3);
|
LCR_rendererMoveCamera(offsets,offsets + 3);
|
||||||
}
|
}
|
||||||
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
|
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
|
||||||
LCR_gameResetRun(LCR_racing.playingReplay,LCR_game.ghost.active);
|
LCR_gameResetRun(LCR_racing.replay.on,LCR_game.ghost.active);
|
||||||
}
|
}
|
||||||
else // LCR_GAME_STATE_MENU
|
else // LCR_GAME_STATE_MENU
|
||||||
{
|
{
|
||||||
|
@ -1469,7 +1481,7 @@ void LCR_gameHandleInput(void)
|
||||||
LCR_game.menu.selectedItem = 0;
|
LCR_game.menu.selectedItem = 0;
|
||||||
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
||||||
}
|
}
|
||||||
else if (LCR_game.keyStates[LCR_KEY_UP] == 1)
|
else if (LCR_gameKeyActive(LCR_KEY_UP))
|
||||||
{
|
{
|
||||||
LCR_LOG1("menu item up");
|
LCR_LOG1("menu item up");
|
||||||
|
|
||||||
|
@ -1486,7 +1498,7 @@ void LCR_gameHandleInput(void)
|
||||||
scrolled = -1;
|
scrolled = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (LCR_game.keyStates[LCR_KEY_DOWN] == 1)
|
else if (LCR_gameKeyActive(LCR_KEY_DOWN))
|
||||||
{
|
{
|
||||||
LCR_LOG1("menu item down");
|
LCR_LOG1("menu item down");
|
||||||
|
|
||||||
|
@ -1548,7 +1560,7 @@ void LCR_gameHandleInput(void)
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
if (LCR_game.statePrev == LCR_GAME_STATE_RUN_FINISHED &&
|
if (LCR_game.statePrev == LCR_GAME_STATE_RUN_FINISHED &&
|
||||||
!LCR_racing.playingReplay)
|
!LCR_racing.replay.on)
|
||||||
LCR_gameSaveReplay();
|
LCR_gameSaveReplay();
|
||||||
else
|
else
|
||||||
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_FAIL]);
|
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_FAIL]);
|
||||||
|
@ -1718,12 +1730,12 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
LCR_LOG1_NUM(LCR_game.runTime);
|
LCR_LOG1_NUM(LCR_game.runTime);
|
||||||
|
|
||||||
if (LCR_game.runTime <= LCR_currentMap.targetTime &&
|
if (LCR_game.runTime <= LCR_currentMap.targetTime &&
|
||||||
!LCR_racing.playingReplay)
|
!LCR_racing.replay.on)
|
||||||
{
|
{
|
||||||
LCR_gameSaveReplay();
|
LCR_gameSaveReplay();
|
||||||
|
|
||||||
if (!LCR_game.mapBeaten && !LCR_game.ghost.active &&
|
if (!LCR_game.mapBeaten && !LCR_game.ghost.active &&
|
||||||
!LCR_racing.playingReplay)
|
!LCR_racing.replay.on)
|
||||||
{
|
{
|
||||||
LCR_LOG1("map beaten");
|
LCR_LOG1("map beaten");
|
||||||
LCR_game.mapBeaten = 1;
|
LCR_game.mapBeaten = 1;
|
||||||
|
@ -1770,11 +1782,9 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
if (LCR_game.state != LCR_GAME_STATE_RUN_FINISHED)
|
if (LCR_game.state != LCR_GAME_STATE_RUN_FINISHED)
|
||||||
LCR_game.runTime = LCR_racing.tick;
|
LCR_game.runTime = LCR_racing.tick;
|
||||||
|
|
||||||
LCR_game.nextRacingTickTime += LCR_RACING_TICK_MS;
|
LCR_game.nextRacingTickTime += LCR_RACING_TICK_MS_RT;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep = (3 * (LCR_game.nextRacingTickTime - time)) / 4;
|
|
||||||
|
|
||||||
// handle rendering:
|
// handle rendering:
|
||||||
if (time >= LCR_game.nextRenderFrameTime ||
|
if (time >= LCR_game.nextRenderFrameTime ||
|
||||||
LCR_game.state == LCR_GAME_STATE_LOADING)
|
LCR_game.state == LCR_GAME_STATE_LOADING)
|
||||||
|
@ -1810,11 +1820,6 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
LCR_game.renderFramesMeasured++;
|
LCR_game.renderFramesMeasured++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t tmp = (3 * (LCR_game.nextRenderFrameTime - time)) / 4;
|
|
||||||
sleep = tmp < sleep ? tmp : sleep;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LCR_game.state == LCR_GAME_STATE_LOADING)
|
if (LCR_game.state == LCR_GAME_STATE_LOADING)
|
||||||
{
|
{
|
||||||
|
@ -1825,6 +1830,15 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
LCR_gameDrawPopupMessage();
|
LCR_gameDrawPopupMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LCR_game.nextRacingTickTime > time)
|
||||||
|
sleep = LCR_game.nextRenderFrameTime - time;
|
||||||
|
|
||||||
|
if (LCR_game.nextRenderFrameTime > time &&
|
||||||
|
LCR_game.nextRenderFrameTime - time < sleep)
|
||||||
|
sleep = LCR_game.nextRenderFrameTime - time;
|
||||||
|
|
||||||
|
sleep = (sleep * 3) / 4;
|
||||||
|
|
||||||
if (sleep)
|
if (sleep)
|
||||||
LCR_sleep(sleep);
|
LCR_sleep(sleep);
|
||||||
else
|
else
|
||||||
|
|
86
racing.h
86
racing.h
|
@ -56,7 +56,10 @@ typedef int32_t LCR_GameUnit; ///< Abstract game unit.
|
||||||
|
|
||||||
#define LCR_RACING_FPS 30 /**< Physics FPS, i.e. the number of
|
#define LCR_RACING_FPS 30 /**< Physics FPS, i.e. the number of
|
||||||
physics ticks per second. */
|
physics ticks per second. */
|
||||||
#define LCR_RACING_TICK_MS \
|
|
||||||
|
#define LCR_RACING_TICK_MS (1000 / LCR_RACING_FPS)
|
||||||
|
|
||||||
|
#define LCR_RACING_TICK_MS_RT \
|
||||||
(100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER))
|
(100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER))
|
||||||
|
|
||||||
#define LCR_RACING_VERSION1 '0' ///< First part of physics eng. version.
|
#define LCR_RACING_VERSION1 '0' ///< First part of physics eng. version.
|
||||||
|
@ -168,10 +171,9 @@ struct
|
||||||
|
|
||||||
uint16_t crashState;
|
uint16_t crashState;
|
||||||
|
|
||||||
uint8_t playingReplay;
|
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
uint8_t on; ///< Currently playing replay?
|
||||||
uint16_t eventCount;
|
uint16_t eventCount;
|
||||||
uint16_t events[LCR_SETTING_REPLAY_MAX_SIZE];
|
uint16_t events[LCR_SETTING_REPLAY_MAX_SIZE];
|
||||||
|
|
||||||
|
@ -376,7 +378,7 @@ int LCR_replayHasFinished(void)
|
||||||
for (int i = 0; i < LCR_racing.replay.eventCount; ++i)
|
for (int i = 0; i < LCR_racing.replay.eventCount; ++i)
|
||||||
totalTime += LCR_racing.replay.events[i] >> 4;
|
totalTime += LCR_racing.replay.events[i] >> 4;
|
||||||
|
|
||||||
return totalTime >= LCR_racing.replay.achievedTime;
|
return totalTime > LCR_racing.replay.achievedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LCR_racing.replay.currentEvent > LCR_racing.replay.eventCount;
|
return LCR_racing.replay.currentEvent > LCR_racing.replay.eventCount;
|
||||||
|
@ -445,7 +447,8 @@ int LCR_replayRecordEvent(uint32_t frame, uint8_t input)
|
||||||
|
|
||||||
frame -= previousFrame; // convert to offset
|
frame -= previousFrame; // convert to offset
|
||||||
|
|
||||||
while (frame > 4095 && LCR_racing.replay.eventCount < LCR_SETTING_REPLAY_MAX_SIZE)
|
while (frame > 4095 && LCR_racing.replay.eventCount <
|
||||||
|
LCR_SETTING_REPLAY_MAX_SIZE)
|
||||||
{
|
{
|
||||||
// add intermediate events
|
// add intermediate events
|
||||||
frame -= 4095;
|
frame -= 4095;
|
||||||
|
@ -982,7 +985,7 @@ void LCR_racingRestart(uint8_t replay)
|
||||||
LCR_racing.tick = 0;
|
LCR_racing.tick = 0;
|
||||||
LCR_racing.fanForce = 0;
|
LCR_racing.fanForce = 0;
|
||||||
|
|
||||||
LCR_racing.playingReplay = replay;
|
LCR_racing.replay.on = replay;
|
||||||
|
|
||||||
TPE_bodyActivate(&(LCR_racing.carBody));
|
TPE_bodyActivate(&(LCR_racing.carBody));
|
||||||
LCR_racing.wheelCollisions = 0;
|
LCR_racing.wheelCollisions = 0;
|
||||||
|
@ -1066,7 +1069,7 @@ void LCR_racingInit(void)
|
||||||
TPE_worldInit(&(LCR_racing.physicsWorld),
|
TPE_worldInit(&(LCR_racing.physicsWorld),
|
||||||
&(LCR_racing.carBody),1,_LCR_racingEnvironmentFunction);
|
&(LCR_racing.carBody),1,_LCR_racingEnvironmentFunction);
|
||||||
|
|
||||||
LCR_racing.playingReplay = 0;
|
LCR_racing.replay.on = 0;
|
||||||
LCR_racing.physicsWorld.collisionCallback = _LCR_racingCollisionHandler;
|
LCR_racing.physicsWorld.collisionCallback = _LCR_racingCollisionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,8 +1205,9 @@ int _LCR_racingCarShapeOK(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Updates the racing physics world, call every LCR_RACING_TICK_MS milliseconds.
|
Updates the racing physics world, call every LCR_RACING_TICK_MS_RT
|
||||||
Returns a set of events (logically ORed) that occured during this step.
|
milliseconds. Returns a set of events (logically ORed) that occured during
|
||||||
|
this step.
|
||||||
*/
|
*/
|
||||||
uint32_t LCR_racingStep(unsigned int input)
|
uint32_t LCR_racingStep(unsigned int input)
|
||||||
{
|
{
|
||||||
|
@ -1217,7 +1221,7 @@ uint32_t LCR_racingStep(unsigned int input)
|
||||||
|
|
||||||
LCR_racing.groundMaterial = LCR_BLOCK_MATERIAL_CONCRETE;
|
LCR_racing.groundMaterial = LCR_BLOCK_MATERIAL_CONCRETE;
|
||||||
|
|
||||||
if (LCR_racing.playingReplay)
|
if (LCR_racing.replay.on)
|
||||||
{
|
{
|
||||||
if (LCR_racing.tick == 0)
|
if (LCR_racing.tick == 0)
|
||||||
LCR_replayInitPlaying();
|
LCR_replayInitPlaying();
|
||||||
|
@ -1637,7 +1641,7 @@ uint32_t LCR_racingStep(unsigned int input)
|
||||||
{
|
{
|
||||||
result |= LCR_RACING_EVENT_FINISHED;
|
result |= LCR_RACING_EVENT_FINISHED;
|
||||||
|
|
||||||
if (!LCR_racing.playingReplay)
|
if (!LCR_racing.replay.on)
|
||||||
LCR_replayRecordEvent(LCR_racing.tick,LCR_REPLAY_EVENT_END);
|
LCR_replayRecordEvent(LCR_racing.tick,LCR_REPLAY_EVENT_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1677,5 +1681,63 @@ void LCR_physicsDebugDraw(LCR_GameUnit camPos[3], LCR_GameUnit camRot[2],
|
||||||
cPos,cRot,cView,16,LCR_PHYSICS_UNIT / 4,LCR_racing.tick * 4);
|
cPos,cRot,cView,16,LCR_PHYSICS_UNIT / 4,LCR_racing.tick * 4);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Validates replay, i.e. checks if it finishes and whether its achieved time
|
||||||
|
agrees with the stored time. The function can only be called when both the
|
||||||
|
replay and the correct map are loaded. The loaded replay's playing position
|
||||||
|
will be reset after this function returns.
|
||||||
|
*/
|
||||||
|
int LCR_replayValidate(void)
|
||||||
|
{
|
||||||
|
LCR_LOG1("validating replay");
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
LCR_racingRestart(1);
|
||||||
|
|
||||||
|
while (LCR_racing.tick < 0x00f00000 // no infinite loops
|
||||||
|
&& LCR_racing.tick <= LCR_racing.replay.achievedTime)
|
||||||
|
{
|
||||||
|
int coords[3];
|
||||||
|
|
||||||
|
LCR_racingStep(0);
|
||||||
|
LCR_racingGetCarBlockCoords(coords);
|
||||||
|
|
||||||
|
coords[0] = LCR_mapGetBlockAt(coords[0],coords[1],coords[2]);
|
||||||
|
|
||||||
|
if (coords[0] && LCR_currentMap.blocks[coords[0] * LCR_BLOCK_SIZE] ==
|
||||||
|
LCR_BLOCK_FINISH)
|
||||||
|
{
|
||||||
|
uint8_t allCPsTaken = 1; // reuse as variable
|
||||||
|
|
||||||
|
for (int i = 0; i < LCR_currentMap.blockCount; ++i)
|
||||||
|
if (LCR_currentMap.blocks[i * LCR_BLOCK_SIZE] == LCR_BLOCK_CHECKPOINT_0)
|
||||||
|
{
|
||||||
|
allCPsTaken = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCPsTaken)
|
||||||
|
{
|
||||||
|
result = LCR_racing.tick == (LCR_racing.replay.achievedTime + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
LCR_LOG1("replay valid");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LCR_LOG1("replay invalid!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LCR_racingRestart(1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue