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 " | ||||
| 
 | ||||
|   "#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 " | ||||
|   "#Mmap4;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          0x02 | ||||
| #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 | ||||
| 
 | ||||
| // forward decls of pixel drawing functions for the renderer
 | ||||
|  | @ -422,7 +426,7 @@ void LCR_seekResourceByIndex(unsigned int index, char magicNumber) | |||
|   } while (c); | ||||
| } | ||||
| 
 | ||||
| void LCR_gameStartRun(unsigned int mapIndex) | ||||
| void LCR_gameLoadMap(unsigned int mapIndex) | ||||
| { | ||||
|   char mapName[LCR_MAP_NAME_MAX_LEN]; | ||||
| 
 | ||||
|  | @ -443,7 +447,83 @@ void LCR_gameStartRun(unsigned int mapIndex) | |||
|   } | ||||
| 
 | ||||
|   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) | ||||
|  | @ -608,6 +688,13 @@ void LCR_gameTimeToStr(uint32_t timeMS, char *str) | |||
|   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) | ||||
| { | ||||
|  | @ -808,10 +895,31 @@ void LCR_gameHandleInput(void) | |||
|             break; | ||||
| 
 | ||||
|           case 1: | ||||
|             LCR_gameStartRun( | ||||
|               LCR_game.resourceFile.firstItemIndex + LCR_game.menu.selectedItem); | ||||
|             LCR_gameLoadMap(LCR_game.resourceFile.firstItemIndex + | ||||
|               LCR_game.menu.selectedItem); | ||||
|             LCR_gameSetState(LCR_GAME_STATE_LOADING_RUN); | ||||
|             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; | ||||
|         } | ||||
|       } | ||||
|  | @ -901,7 +1009,7 @@ uint8_t LCR_gameStep(uint32_t time) | |||
|     LCR_game.keyStates[i] = LCR_keyPressed(i) ? | ||||
|       (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_gameResetRun(LCR_racing.playingReplay); | ||||
|  | @ -975,8 +1083,7 @@ LCR_replayOutputStr(_LCR_gameResourceCharWrite); | |||
|     while (time >= LCR_game.nextRenderFrameTime) | ||||
|       LCR_game.nextRenderFrameTime += 1000 / LCR_SETTING_FPS; | ||||
| 
 | ||||
|     if (LCR_game.state == LCR_GAME_STATE_MENU || | ||||
|       LCR_game.state == LCR_GAME_STATE_LOADING_MAP) | ||||
|     if ((LCR_game.state == LCR_GAME_STATE_MENU) || _LCR_gameIsLoading()) | ||||
|       LCR_rendererDrawMenu(LCR_texts[LCR_TEXTS_TABS | ||||
|         + LCR_game.menu.selectedTab],LCR_game.menu.itemNamePtrs, | ||||
|         LCR_game.menu.itemCount + 1,LCR_game.menu.selectedItem); | ||||
|  | @ -989,7 +1096,7 @@ LCR_replayOutputStr(_LCR_gameResourceCharWrite); | |||
|     sleep = tmp < sleep ? tmp : sleep;  | ||||
|   } | ||||
| 
 | ||||
|   if (LCR_game.state == LCR_GAME_STATE_LOADING_MAP) | ||||
|   if (_LCR_gameIsLoading()) | ||||
|   { | ||||
|     // show the "loading" screen
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										22
									
								
								general.h
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								general.h
									
										
									
									
									
								
							|  | @ -42,4 +42,26 @@ int _LCR_hexDigitVal(char c) | |||
|   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
 | ||||
|  |  | |||
							
								
								
									
										36
									
								
								racing.h
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								racing.h
									
										
									
									
									
								
							|  | @ -47,8 +47,6 @@ typedef int32_t LCR_GameUnit;  ///< abstract game unit | |||
| #include "map.h" | ||||
| #include "tinyphysicsengine.h" | ||||
| 
 | ||||
| // TODO: move some of this to constants?
 | ||||
| 
 | ||||
| #define LCR_GRAVITY (LCR_PHYSICS_UNIT / 160) | ||||
| #define LCR_FAN_FORCE 3 | ||||
| #define LCR_FAN_FORCE_DECREASE 6 | ||||
|  | @ -174,8 +172,8 @@ void LCR_replayOutputStr(void (*printChar)(char)) | |||
| 
 | ||||
|   for (int i = 0; i < 8; ++i) | ||||
|   { | ||||
|     printChar(_LCR_hexDigit(hash % 16)); | ||||
|     hash /= 16; | ||||
|     printChar(_LCR_hexDigit((hash >> 28) % 16)); | ||||
|     hash <<= 4; | ||||
|   } | ||||
| 
 | ||||
|   printChar(' '); | ||||
|  | @ -204,15 +202,24 @@ void LCR_replayOutputStr(void (*printChar)(char)) | |||
| 
 | ||||
| /**
 | ||||
|   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 = ' '; | ||||
| 
 | ||||
|   LCR_replay.eventCount = 0; | ||||
|   LCR_replay.achievedTime = 0; | ||||
| 
 | ||||
| if (nameHash) | ||||
|   *nameHash = _LCR_simpleStrHash(nextChar,';'); | ||||
| else | ||||
|   _LCR_simpleStrHash(nextChar,';'); | ||||
| 
 | ||||
| /*
 | ||||
|   do // map name
 | ||||
|   { | ||||
|     c = nextChar(); | ||||
|  | @ -220,10 +227,27 @@ int LCR_replayLoadFromStr(char (*nextChar)(void)) | |||
|     if (c == 0) | ||||
|       return 0; | ||||
|   } 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
 | ||||
|     if (_LCR_hexDigitVal(nextChar()) < 0) | ||||
|       return 0; | ||||
| */ | ||||
| 
 | ||||
|   nextChar(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue