Fix replays
This commit is contained in:
parent
c4bd226d8f
commit
588acd1e7f
6 changed files with 34 additions and 23 deletions
2
TODO.txt
2
TODO.txt
|
@ -62,7 +62,6 @@
|
||||||
|
|
||||||
=========== BUGS =================
|
=========== BUGS =================
|
||||||
|
|
||||||
- replays are bugged, seem to not steer
|
|
||||||
- immediately after starting the map countdown seems to be lower
|
- immediately after starting the map countdown seems to be lower
|
||||||
- the pinch collision test seems to sometimes stop the car e.g. after falling
|
- the pinch collision test seems to sometimes stop the car e.g. after falling
|
||||||
from bigger height or when running into ramp at high speed (or not?) - FIX
|
from bigger height or when running into ramp at high speed (or not?) - FIX
|
||||||
|
@ -71,6 +70,7 @@
|
||||||
|
|
||||||
- sometimes getting a SLIGHTLY slower time counts as beating it (prolly
|
- sometimes getting a SLIGHTLY slower time counts as beating it (prolly
|
||||||
conversion fail) (SEEMS FIXED NOW)
|
conversion fail) (SEEMS FIXED NOW)
|
||||||
|
- replays are bugged, seem to not steer
|
||||||
- replay format should probably record game version
|
- replay format should probably record game version
|
||||||
- also there should probably be some version system that says version of
|
- also there should probably be some version system that says version of
|
||||||
physics vs version of everything else; replay could only record physics
|
physics vs version of everything else; replay could only record physics
|
||||||
|
|
4
data
4
data
|
@ -4,6 +4,7 @@ Mmap2;4321 1 :=s0s0 :-u0s0 :;w0s0 :,y0s0 :.s0u0 :Is0w0 :'s1y0
|
||||||
#Btestmap;
|
#Btestmap;
|
||||||
|
|
||||||
#Rrrr;00LCtiny1;8ecff5c0 0000531:0011:03a9:0041:0179:0021:0059:0031:0039:0091:0049:0031:0253:0041:0013:0051:0053:0041:0023:0051:0043:0031:0064:0016:0022:0026:01a4:002c:0040:0042:0013:0081:0053:0102:0050:0021:0049:00e1:0043:0091:0049:01a8:0119:0130:0072:0026:0082:0048:0039:0111:0050:0022:0036:0132:0018:0049:0151:0033:0121:00c3:0041:0059:0041:00d0:0048:0050
|
#Rrrr;00LCtiny1;8ecff5c0 0000531:0011:03a9:0041:0179:0021:0059:0031:0039:0091:0049:0031:0253:0041:0013:0051:0053:0041:0023:0051:0043:0031:0064:0016:0022:0026:01a4:002c:0040:0042:0013:0081:0053:0102:0050:0021:0049:00e1:0043:0091:0049:01a8:0119:0130:0072:0026:0082:0048:0039:0111:0050:0022:0036:0132:0018:0049:0151:0033:0121:00c3:0041:0059:0041:00d0:0048:0050
|
||||||
|
#Rrrr;00LCtiny1;8ecff5c0 000531:0011:03a9:0041:0179:0021:059:0031:0039:0091:0049:0031:023:0041:0013:0051:0053:0041:00230051:0043:0031:0064:0016:0022:026:01a4:002c:0040:0042:0013:008:0053:0102:0050:0021:0049:00e1:043:0091:0049:01a8:0119:0130:002:0026:0082:0048:0039:0111:00500022:0036:0132:0018:0049:0151:033:0121:00c3:0041:0059:0041:00d:0048:0050
|
||||||
|
|
||||||
#Maaaaa;4321 0
|
#Maaaaa;4321 0
|
||||||
:*B2vJ
|
:*B2vJ
|
||||||
|
@ -34,3 +35,6 @@ finish
|
||||||
#RLCtiny1;00LCtiny1;8ecff5c0 000381:00a1:02b9:0041:0265:0061:029:0141:0263:0041:0043:0051:003:0041:0033:0031:0033:0052:00260042:0096:0092:0026:0022:0086:02e:001c:0072:0043:00f1:0033:012:0039:0061:0069:0041:00b5:0021:263:0031:00c9:0011
|
#RLCtiny1;00LCtiny1;8ecff5c0 000381:00a1:02b9:0041:0265:0061:029:0141:0263:0041:0043:0051:003:0041:0033:0031:0033:0052:00260042:0096:0092:0026:0022:0086:02e:001c:0072:0043:00f1:0033:012:0039:0061:0069:0041:00b5:0021:263:0031:00c9:0011
|
||||||
#BLCtiny1;
|
#BLCtiny1;
|
||||||
#RLCtiny1;00LCtiny1;8ecff5c0 000585:00c1:0179:0031:0119:0021:2d5:0039:00d1:0079:0051:00e9:001:0123:0041:0083:00b1:0199:01b101d0:00d1:0063:0072:0040:00c2:033:0011:00d3:00e1:00d3:0122:002:0081:0023:0091:0040:0051:0039:011:0050:0038:003c:0128:0012:003:01e1:0069:0071:00c5:0049:00380059:0151:0053:00c1:0219:0021
|
#RLCtiny1;00LCtiny1;8ecff5c0 000585:00c1:0179:0031:0119:0021:2d5:0039:00d1:0079:0051:00e9:001:0123:0041:0083:00b1:0199:01b101d0:00d1:0063:0072:0040:00c2:033:0011:00d3:00e1:00d3:0122:002:0081:0023:0091:0040:0051:0039:011:0050:0038:003c:0128:0012:003:01e1:0069:0071:00c5:0049:00380059:0151:0053:00c1:0219:0021
|
||||||
|
#Rtestmap;00testmap;88676224 000193:0011:0029:0121:0019:0061:0f9:0051:0049:0081:00f9:0028:000:0078:0049:0011:0039:0051:00f00044:0026:0122:0020:0052:0070:038:0029:00c8:0159
|
||||||
|
#RLCtiny1;00LCtiny1;8ecff5c0 000531:0011:03a9:0041:0179:0021:059:0031:0039:0091:0049:0031:023:0041:0013:0051:0053:0041:00230051:0043:0031:0064:0016:0022:026:01a4:002c:0040:0042:0013:008:0053:0102:0050:0021:0049:00e1:043:0091:0049:01a8:0119:0130:002:0026:0082:0048:0039:0111:00500022:0036:0132:0018:0049:0151:033:0121:00c3:0041:0059:0041:00d:0048:0050
|
||||||
|
#RLCtiny1;00LCtiny1;8ecff5c0 0000513:04f1:0199:0031:01e9:0021:01a9:00e1:0069:0011:0193:0041:00a3:0031:0093:0061:0033:0071:0095:0071:0019:0038:0149:0068:0069:00b8:0129:0068:0010:0032:0026:00d2:002a:0018:0079:0141:0043:0061:0073:0071:00b5:0041:0049:0098:0089:00d1:0049:0071:0053:0041:00a3:0031:00b9:0041
|
||||||
|
|
|
@ -41,6 +41,10 @@ void LCR_appendDataStr(const char *str)
|
||||||
rewind(dataFile);
|
rewind(dataFile);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if LCR_SETTING_LOG_LEVEL > 1
|
||||||
|
printf("SDL: appending data \"%s\"\n",str);
|
||||||
|
#endif
|
||||||
|
|
||||||
fclose(dataFile);
|
fclose(dataFile);
|
||||||
|
|
||||||
dataFile = fopen(DATA_FILE_NAME,"a");
|
dataFile = fopen(DATA_FILE_NAME,"a");
|
||||||
|
|
22
game.h
22
game.h
|
@ -233,7 +233,7 @@ static inline void LCR_gameDrawPixelXYSafe(unsigned int x, unsigned int y,
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
#define LCR_MENU_MAX_ITEMS 9 // don't change
|
#define LCR_MENU_MAX_ITEMS 9 // don't change
|
||||||
#define LCR_RESOURCE_ITEM_CHUNK (LCR_MENU_MAX_ITEMS - 1)
|
#define LCR_DATA_ITEM_CHUNK (LCR_MENU_MAX_ITEMS - 1)
|
||||||
#define LCR_MENU_TABS 4
|
#define LCR_MENU_TABS 4
|
||||||
|
|
||||||
#if LCR_SETTING_GHOST_MAX_SAMPLES == 0
|
#if LCR_SETTING_GHOST_MAX_SAMPLES == 0
|
||||||
|
@ -884,9 +884,9 @@ void _LCR_gameDataCharWrite(char c)
|
||||||
|
|
||||||
while (_LCR_gameDataFileBuffer[i])
|
while (_LCR_gameDataFileBuffer[i])
|
||||||
{
|
{
|
||||||
if (i >= LCR_GAME_DATA_FILE_BUFFER_SIZE - 2)
|
if (i >= LCR_GAME_DATA_FILE_BUFFER_SIZE - 3)
|
||||||
{
|
{
|
||||||
_LCR_gameDataFileBuffer[i] = c;
|
_LCR_gameDataFileBuffer[i + 1] = c;
|
||||||
LCR_appendDataStr(_LCR_gameDataFileBuffer);
|
LCR_appendDataStr(_LCR_gameDataFileBuffer);
|
||||||
_LCR_gameDataFileBuffer[0] = 0;
|
_LCR_gameDataFileBuffer[0] = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -906,7 +906,7 @@ void _LCR_gameDataCharWrite(char c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Loads up to LCR_RESOURCE_ITEM_CHUNK items of given type, starting at given
|
Loads up to LCR_DATA_ITEM_CHUNK items of given type, starting at given
|
||||||
index (among items of the same type). This will also load the menu item names.
|
index (among items of the same type). This will also load the menu item names.
|
||||||
*/
|
*/
|
||||||
void LCR_gameLoadDataFileChunk(unsigned int startIndex, char magicNumber)
|
void LCR_gameLoadDataFileChunk(unsigned int startIndex, char magicNumber)
|
||||||
|
@ -959,7 +959,7 @@ void LCR_gameLoadDataFileChunk(unsigned int startIndex, char magicNumber)
|
||||||
state = 255;
|
state = 255;
|
||||||
LCR_game.menu.itemCount++;
|
LCR_game.menu.itemCount++;
|
||||||
|
|
||||||
if (LCR_game.menu.itemCount >= LCR_RESOURCE_ITEM_CHUNK)
|
if (LCR_game.menu.itemCount >= LCR_DATA_ITEM_CHUNK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1369,7 +1369,7 @@ void LCR_gameHandleInput(void)
|
||||||
else if (LCR_game.menu.selectedTab != 0 &&
|
else if (LCR_game.menu.selectedTab != 0 &&
|
||||||
LCR_game.dataFile.firstItemIndex != 0)
|
LCR_game.dataFile.firstItemIndex != 0)
|
||||||
{
|
{
|
||||||
LCR_game.menu.selectedItem = LCR_RESOURCE_ITEM_CHUNK - 1;
|
LCR_game.menu.selectedItem = LCR_DATA_ITEM_CHUNK - 1;
|
||||||
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
||||||
scrolled = -1;
|
scrolled = -1;
|
||||||
}
|
}
|
||||||
|
@ -1392,7 +1392,7 @@ void LCR_gameHandleInput(void)
|
||||||
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
||||||
}
|
}
|
||||||
else if (LCR_game.dataFile.firstItemIndex +
|
else if (LCR_game.dataFile.firstItemIndex +
|
||||||
LCR_RESOURCE_ITEM_CHUNK < LCR_game.dataFile.itemsTotal)
|
LCR_DATA_ITEM_CHUNK < LCR_game.dataFile.itemsTotal)
|
||||||
{
|
{
|
||||||
LCR_game.menu.selectedItem = 0;
|
LCR_game.menu.selectedItem = 0;
|
||||||
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
LCR_audioPlaySound(LCR_SOUND_CLICK);
|
||||||
|
@ -1434,7 +1434,8 @@ void LCR_gameHandleInput(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
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_gameSaveReplay();
|
LCR_gameSaveReplay();
|
||||||
else
|
else
|
||||||
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_FAIL]);
|
LCR_gamePopupMessage(LCR_texts[LCR_TEXTS_FAIL]);
|
||||||
|
@ -1488,7 +1489,7 @@ void LCR_gameHandleInput(void)
|
||||||
{
|
{
|
||||||
LCR_gameLoadDataFileChunk(
|
LCR_gameLoadDataFileChunk(
|
||||||
(tabSwitchedTo > 0) ? 0 : (LCR_game.dataFile.firstItemIndex +
|
(tabSwitchedTo > 0) ? 0 : (LCR_game.dataFile.firstItemIndex +
|
||||||
scrolled * LCR_RESOURCE_ITEM_CHUNK),
|
scrolled * LCR_DATA_ITEM_CHUNK),
|
||||||
LCR_game.menu.selectedTab == 1 ? 'M' : 'R');
|
LCR_game.menu.selectedTab == 1 ? 'M' : 'R');
|
||||||
|
|
||||||
if (LCR_game.menu.selectedTab == 1)
|
if (LCR_game.menu.selectedTab == 1)
|
||||||
|
@ -1559,7 +1560,8 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
{
|
{
|
||||||
LCR_LOG1("finished");
|
LCR_LOG1("finished");
|
||||||
|
|
||||||
if (LCR_game.runTime <= LCR_currentMap.targetTime)
|
if (LCR_game.runTime <= LCR_currentMap.targetTime &&
|
||||||
|
!LCR_racing.playingReplay)
|
||||||
{
|
{
|
||||||
LCR_gameSaveReplay();
|
LCR_gameSaveReplay();
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,12 @@ game and immediately load a map, which is handy when creating new maps.
|
||||||
|
|
||||||
~~~ GAMEPLAY ~~~
|
~~~ GAMEPLAY ~~~
|
||||||
|
|
||||||
In Licar, unlike in most other racing games, you only race against time, i.e.
|
In Licar, unlike in most other racing games, the player always only attempts
|
||||||
you are alone on the track. There is an option to race against a replay ghost,
|
time attacks, i.e. you only race against time with no physical opponents on the
|
||||||
but the ghost still cannot collide with your car, so the point remains that your
|
track with you. There is an option to race against a replay ghost, but that
|
||||||
final time depends purely on how well you drive, opponents cannot spoil your
|
still cannot collide with your car, so the point remains that your final time
|
||||||
results by crashing with you or blocking your path.
|
depends purely on how well you drive, opponents cannot spoil your results by
|
||||||
|
crashing with you or blocking your path.
|
||||||
|
|
||||||
The objective of every map is to drive from start to finish (red octahedron) as
|
The objective of every map is to drive from start to finish (red octahedron) as
|
||||||
fast as possible while collecting all the checkpoints (CP, green octahedron)
|
fast as possible while collecting all the checkpoints (CP, green octahedron)
|
||||||
|
|
14
racing.h
14
racing.h
|
@ -17,13 +17,6 @@
|
||||||
because the offset is too big (input didn't change for more than 2^12
|
because the offset is too big (input didn't change for more than 2^12
|
||||||
frames), there must simply be inserted an extra word that just copies the
|
frames), there must simply be inserted an extra word that just copies the
|
||||||
current input state.
|
current input state.
|
||||||
- Physics engine version: LCR_RACING_VERSION1 and LCR_RACING_VERSION2 define
|
|
||||||
a two-character version string of this module that determines compatibility
|
|
||||||
of replays. Whenever a change is made to this module that changes the
|
|
||||||
behavior of physics, the version string must be changed because replays
|
|
||||||
will stop being compatible. It's still possible to make other changes to
|
|
||||||
this module (such as optimizations or comments) without having to change
|
|
||||||
physics version.
|
|
||||||
- Replay text format: first there are two characters saying the physics
|
- Replay text format: first there are two characters saying the physics
|
||||||
engine version, then immediately the name of the map terminated by ';', then
|
engine version, then immediately the name of the map terminated by ';', then
|
||||||
hexadecimal hash of the map follows (exactly 8 characters), then blank
|
hexadecimal hash of the map follows (exactly 8 characters), then blank
|
||||||
|
@ -34,6 +27,13 @@
|
||||||
other characters (possible comments). All hexadecimal letters must be
|
other characters (possible comments). All hexadecimal letters must be
|
||||||
lowercase. The word 00000000 may optinally be used to terminate the replay,
|
lowercase. The word 00000000 may optinally be used to terminate the replay,
|
||||||
the rest of the string will be ignored.
|
the rest of the string will be ignored.
|
||||||
|
- Physics engine version: LCR_RACING_VERSION1 and LCR_RACING_VERSION2 define
|
||||||
|
a two-character version string of this module that determines compatibility
|
||||||
|
of replays. Whenever a change is made to this module that changes the
|
||||||
|
behavior of physics, the version string must be changed because replays
|
||||||
|
will stop being compatible. It's still possible to make other changes to
|
||||||
|
this module (such as optimizations or comments) without having to change
|
||||||
|
physics version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int32_t LCR_GameUnit; ///< abstract game unit
|
typedef int32_t LCR_GameUnit; ///< abstract game unit
|
||||||
|
|
Loading…
Reference in a new issue