Start replay loading
This commit is contained in:
parent
71aa8156e9
commit
17a371fdca
4 changed files with 169 additions and 16 deletions
2
assets.h
2
assets.h
|
@ -85,7 +85,7 @@ static const char *LCR_internalResourceFile =
|
||||||
" map end "
|
" map end "
|
||||||
|
|
||||||
"#Mmap2;4321 1 :*H1k0J :,s0s0 :fd190 "
|
"#Mmap2;4321 1 :*H1k0J :,s0s0 :fd190 "
|
||||||
"#Rtestrepl;aaa#Rrepl2;"
|
"#Rrep1;testmap;482f70f9 00000188:00c1:0089:0111:00b9:0091:0109:0028:0050:00c1:0093:0030:00d1:0069:0041:0020:0071:0013:0012:0023:0022:0050:0032:0020:0022:0060:0024:00bc:0044"
|
||||||
"#Mmap3;4321 1 :*H1k0J :,s0s0 :fd190 "
|
"#Mmap3;4321 1 :*H1k0J :,s0s0 :fd190 "
|
||||||
"#Mmap4;4321 1 :*H1k0J :,s0s0 :fd190 "
|
"#Mmap4;4321 1 :*H1k0J :,s0s0 :fd190 "
|
||||||
"#Mmap5;4321 1 :*H1k0J :,s0s0 :fd190 "
|
"#Mmap5;4321 1 :*H1k0J :,s0s0 :fd190 "
|
||||||
|
|
125
game.h
125
game.h
|
@ -175,7 +175,11 @@ uint8_t LCR_gameGetNextAudioSample(void);
|
||||||
#define LCR_GAME_STATE_RUN_STARTING 0x01
|
#define LCR_GAME_STATE_RUN_STARTING 0x01
|
||||||
#define LCR_GAME_STATE_RUN 0x02
|
#define LCR_GAME_STATE_RUN 0x02
|
||||||
#define LCR_GAME_STATE_RUN_FINISHED 0x03
|
#define LCR_GAME_STATE_RUN_FINISHED 0x03
|
||||||
#define LCR_GAME_STATE_LOADING_MAP 0x04
|
|
||||||
|
#define LCR_GAME_STATE_LOADING_RUN 0x04
|
||||||
|
#define LCR_GAME_STATE_LOADING_REP1 0x05
|
||||||
|
#define LCR_GAME_STATE_LOADING_REP2 0x06
|
||||||
|
|
||||||
#define LCR_GAME_STATE_END 0xff
|
#define LCR_GAME_STATE_END 0xff
|
||||||
|
|
||||||
// forward decls of pixel drawing functions for the renderer
|
// forward decls of pixel drawing functions for the renderer
|
||||||
|
@ -422,7 +426,7 @@ void LCR_seekResourceByIndex(unsigned int index, char magicNumber)
|
||||||
} while (c);
|
} while (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCR_gameStartRun(unsigned int mapIndex)
|
void LCR_gameLoadMap(unsigned int mapIndex)
|
||||||
{
|
{
|
||||||
char mapName[LCR_MAP_NAME_MAX_LEN];
|
char mapName[LCR_MAP_NAME_MAX_LEN];
|
||||||
|
|
||||||
|
@ -443,7 +447,83 @@ void LCR_gameStartRun(unsigned int mapIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar,mapName);
|
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar,mapName);
|
||||||
LCR_gameSetState(LCR_GAME_STATE_LOADING_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
|
||||||
|
if the replay couldn't be loaded. This function potentially reloads current
|
||||||
|
map!
|
||||||
|
*/
|
||||||
|
unsigned int LCR_gameLoadReplay(unsigned int replayIndex)
|
||||||
|
{
|
||||||
|
uint32_t mapHash;
|
||||||
|
uint16_t nameHash;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
LCR_LOG1("loading replay and map");
|
||||||
|
|
||||||
|
LCR_seekResourceByIndex(replayIndex,'R');
|
||||||
|
|
||||||
|
do // skip name
|
||||||
|
{
|
||||||
|
c = LCR_gameGetNextResourceFileChar();
|
||||||
|
}
|
||||||
|
while (c && c != LCR_RESOURCE_FILE_SEPARATOR2 &&
|
||||||
|
c != LCR_RESOURCE_FILE_SEPARATOR);
|
||||||
|
|
||||||
|
if (!LCR_replayLoadFromStr(LCR_gameGetNextResourceStrChar,
|
||||||
|
&mapHash,&nameHash))
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
// now try to find the map with given nameHash
|
||||||
|
LCR_gameRewindResourceFile();
|
||||||
|
|
||||||
|
unsigned int skipTo = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
unsigned int mapIndex = 0;
|
||||||
|
|
||||||
|
while (1) // find first skipToth map
|
||||||
|
{
|
||||||
|
c = LCR_gameGetNextResourceFileChar();
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return -1;
|
||||||
|
else if (c == 'M')
|
||||||
|
{
|
||||||
|
if (mapIndex >= skipTo &&
|
||||||
|
nameHash == _LCR_simpleStrHash(LCR_gameGetNextResourceStrChar,';'))
|
||||||
|
{
|
||||||
|
LCR_LOG2("map name hash matches");
|
||||||
|
LCR_gameLoadMap(mapIndex);
|
||||||
|
|
||||||
|
if (mapHash == LCR_currentMap.hash)
|
||||||
|
return mapIndex;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LCR_LOG2("map hash doesn't match");
|
||||||
|
// map hash doesn't match
|
||||||
|
skipTo = mapIndex + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (c != LCR_RESOURCE_FILE_SEPARATOR)
|
||||||
|
{
|
||||||
|
if (c == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
c = LCR_gameGetNextResourceFileChar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCR_gameEraseMenuItemNames(void)
|
void LCR_gameEraseMenuItemNames(void)
|
||||||
|
@ -608,6 +688,13 @@ void LCR_gameTimeToStr(uint32_t timeMS, char *str)
|
||||||
str[2] = '\'';
|
str[2] = '\'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _LCR_gameIsLoading(void)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(LCR_game.state == LCR_GAME_STATE_LOADING_RUN) ||
|
||||||
|
(LCR_game.state == LCR_GAME_STATE_LOADING_REP1) ||
|
||||||
|
(LCR_game.state == LCR_GAME_STATE_LOADING_REP2);
|
||||||
|
}
|
||||||
|
|
||||||
void LCR_gameDraw3DView(void)
|
void LCR_gameDraw3DView(void)
|
||||||
{
|
{
|
||||||
|
@ -808,10 +895,31 @@ void LCR_gameHandleInput(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
LCR_gameStartRun(
|
LCR_gameLoadMap(LCR_game.resourceFile.firstItemIndex +
|
||||||
LCR_game.resourceFile.firstItemIndex + LCR_game.menu.selectedItem);
|
LCR_game.menu.selectedItem);
|
||||||
|
LCR_gameSetState(LCR_GAME_STATE_LOADING_RUN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
int mapIndex = LCR_gameLoadReplay(LCR_game.resourceFile.firstItemIndex +
|
||||||
|
LCR_game.menu.selectedItem);
|
||||||
|
|
||||||
|
if (mapIndex < -1)
|
||||||
|
{
|
||||||
|
LCR_LOG1("couldn't load replay");
|
||||||
|
}
|
||||||
|
else if (mapIndex == -1)
|
||||||
|
{
|
||||||
|
LCR_LOG1("couldn't load replay map");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LCR_gameSetState(LCR_GAME_STATE_LOADING_REP1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -901,7 +1009,7 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
LCR_game.keyStates[i] = LCR_keyPressed(i) ?
|
LCR_game.keyStates[i] = LCR_keyPressed(i) ?
|
||||||
(LCR_game.keyStates[i] < 255 ? LCR_game.keyStates[i] + 1 : 255) : 0;
|
(LCR_game.keyStates[i] < 255 ? LCR_game.keyStates[i] + 1 : 255) : 0;
|
||||||
|
|
||||||
if (LCR_game.state == LCR_GAME_STATE_LOADING_MAP)
|
if (_LCR_gameIsLoading())
|
||||||
{
|
{
|
||||||
LCR_rendererLoadMap();
|
LCR_rendererLoadMap();
|
||||||
LCR_gameResetRun(LCR_racing.playingReplay);
|
LCR_gameResetRun(LCR_racing.playingReplay);
|
||||||
|
@ -975,8 +1083,7 @@ LCR_replayOutputStr(_LCR_gameResourceCharWrite);
|
||||||
while (time >= LCR_game.nextRenderFrameTime)
|
while (time >= LCR_game.nextRenderFrameTime)
|
||||||
LCR_game.nextRenderFrameTime += 1000 / LCR_SETTING_FPS;
|
LCR_game.nextRenderFrameTime += 1000 / LCR_SETTING_FPS;
|
||||||
|
|
||||||
if (LCR_game.state == LCR_GAME_STATE_MENU ||
|
if ((LCR_game.state == LCR_GAME_STATE_MENU) || _LCR_gameIsLoading())
|
||||||
LCR_game.state == LCR_GAME_STATE_LOADING_MAP)
|
|
||||||
LCR_rendererDrawMenu(LCR_texts[LCR_TEXTS_TABS
|
LCR_rendererDrawMenu(LCR_texts[LCR_TEXTS_TABS
|
||||||
+ LCR_game.menu.selectedTab],LCR_game.menu.itemNamePtrs,
|
+ LCR_game.menu.selectedTab],LCR_game.menu.itemNamePtrs,
|
||||||
LCR_game.menu.itemCount + 1,LCR_game.menu.selectedItem);
|
LCR_game.menu.itemCount + 1,LCR_game.menu.selectedItem);
|
||||||
|
@ -989,7 +1096,7 @@ LCR_replayOutputStr(_LCR_gameResourceCharWrite);
|
||||||
sleep = tmp < sleep ? tmp : sleep;
|
sleep = tmp < sleep ? tmp : sleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LCR_game.state == LCR_GAME_STATE_LOADING_MAP)
|
if (_LCR_gameIsLoading())
|
||||||
{
|
{
|
||||||
// show the "loading" screen
|
// show the "loading" screen
|
||||||
|
|
||||||
|
|
22
general.h
22
general.h
|
@ -42,4 +42,26 @@ int _LCR_hexDigitVal(char c)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes simple hash of a string represented by a function returning next
|
||||||
|
string character, ending at 0 or endChar. This is intended for simple (but
|
||||||
|
not 100% reliable) string comparison.
|
||||||
|
*/
|
||||||
|
uint16_t _LCR_simpleStrHash(char (*nextChar)(void), char endChar)
|
||||||
|
{
|
||||||
|
uint16_t r = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char c = nextChar();
|
||||||
|
|
||||||
|
if (c == 0 || c == endChar)
|
||||||
|
break;
|
||||||
|
|
||||||
|
r = ((r << 5) | (r >> 11)) + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
36
racing.h
36
racing.h
|
@ -47,8 +47,6 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tinyphysicsengine.h"
|
#include "tinyphysicsengine.h"
|
||||||
|
|
||||||
// TODO: move some of this to constants?
|
|
||||||
|
|
||||||
#define LCR_GRAVITY (LCR_PHYSICS_UNIT / 160)
|
#define LCR_GRAVITY (LCR_PHYSICS_UNIT / 160)
|
||||||
#define LCR_FAN_FORCE 3
|
#define LCR_FAN_FORCE 3
|
||||||
#define LCR_FAN_FORCE_DECREASE 6
|
#define LCR_FAN_FORCE_DECREASE 6
|
||||||
|
@ -174,8 +172,8 @@ void LCR_replayOutputStr(void (*printChar)(char))
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
printChar(_LCR_hexDigit(hash % 16));
|
printChar(_LCR_hexDigit((hash >> 28) % 16));
|
||||||
hash /= 16;
|
hash <<= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
printChar(' ');
|
printChar(' ');
|
||||||
|
@ -204,15 +202,24 @@ void LCR_replayOutputStr(void (*printChar)(char))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads replay from string using provided function that returns next character
|
Reads replay from string using provided function that returns next character
|
||||||
in the string. Returns 1 on success, else 0.
|
in the string. The mapHash and nameHash pointers are optional: if non-zero,
|
||||||
|
they will be filled with the map hash and name hash. Returns 1 on success,
|
||||||
|
else 0.
|
||||||
*/
|
*/
|
||||||
int LCR_replayLoadFromStr(char (*nextChar)(void))
|
int LCR_replayLoadFromStr(char (*nextChar)(void),
|
||||||
|
uint32_t *mapHash, uint16_t *nameHash)
|
||||||
{
|
{
|
||||||
char c = ' ';
|
char c = ' ';
|
||||||
|
|
||||||
LCR_replay.eventCount = 0;
|
LCR_replay.eventCount = 0;
|
||||||
LCR_replay.achievedTime = 0;
|
LCR_replay.achievedTime = 0;
|
||||||
|
|
||||||
|
if (nameHash)
|
||||||
|
*nameHash = _LCR_simpleStrHash(nextChar,';');
|
||||||
|
else
|
||||||
|
_LCR_simpleStrHash(nextChar,';');
|
||||||
|
|
||||||
|
/*
|
||||||
do // map name
|
do // map name
|
||||||
{
|
{
|
||||||
c = nextChar();
|
c = nextChar();
|
||||||
|
@ -220,10 +227,27 @@ int LCR_replayLoadFromStr(char (*nextChar)(void))
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
return 0;
|
return 0;
|
||||||
} while (c != ';');
|
} while (c != ';');
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mapHash)
|
||||||
|
*mapHash = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i) // hash
|
||||||
|
{
|
||||||
|
c = nextChar();
|
||||||
|
|
||||||
|
if (_LCR_hexDigitVal(c) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (mapHash)
|
||||||
|
*mapHash = ((*mapHash) << 4) | _LCR_hexDigitVal(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
for (int i = 0; i < 8; ++i) // hash
|
for (int i = 0; i < 8; ++i) // hash
|
||||||
if (_LCR_hexDigitVal(nextChar()) < 0)
|
if (_LCR_hexDigitVal(nextChar()) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
*/
|
||||||
|
|
||||||
nextChar();
|
nextChar();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue