Clean
This commit is contained in:
		
							parent
							
								
									e695921c5c
								
							
						
					
					
						commit
						6986028e33
					
				
					 4 changed files with 171 additions and 155 deletions
				
			
		
							
								
								
									
										22
									
								
								audio.h
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								audio.h
									
										
									
									
									
								
							|  | @ -1,5 +1,10 @@ | ||||||
| /**
 | /*
 | ||||||
|   audio: this file implements the audio system. |   Licar audio | ||||||
|  | 
 | ||||||
|  |   This file implements the audio system. The module only computes audio samples | ||||||
|  |   (playing them must be done by the frontend). The audio format is 8bit, 8 KHz | ||||||
|  |   mono. This module does NOT deal with music (music is stored in a separate | ||||||
|  |   file, left to be optionally loaded and played by the frontend). | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #ifndef _LCR_AUDIO | #ifndef _LCR_AUDIO | ||||||
|  | @ -26,6 +31,9 @@ struct | ||||||
|   int engineInc; |   int engineInc; | ||||||
| } LCR_audio; | } LCR_audio; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |   Initializes the audio system, only call once. | ||||||
|  | */ | ||||||
| void LCR_audioInit(void) | void LCR_audioInit(void) | ||||||
| { | { | ||||||
|   LCR_LOG0("initializing audio"); |   LCR_LOG0("initializing audio"); | ||||||
|  | @ -40,11 +48,18 @@ void LCR_audioInit(void) | ||||||
|   LCR_audio.engineIntensity = 0; |   LCR_audio.engineIntensity = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |   Sets the intensity of car engine sound that's constantly played (unless when | ||||||
|  |   intensitiy has been set to 0). Maximum value is 255. | ||||||
|  | */ | ||||||
| void LCR_audioSetEngineIntensity(uint8_t value) | void LCR_audioSetEngineIntensity(uint8_t value) | ||||||
| { | { | ||||||
|   LCR_audio.engineIntensity = value; |   LCR_audio.engineIntensity = value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |   Tells the audio system to play certain sound (see the sound constants). | ||||||
|  | */ | ||||||
| void LCR_audioPlaySound(uint8_t sound) | void LCR_audioPlaySound(uint8_t sound) | ||||||
| { | { | ||||||
|   LCR_LOG2("playing sound"); |   LCR_LOG2("playing sound"); | ||||||
|  | @ -58,6 +73,9 @@ uint8_t _LCR_audioNoise(void) | ||||||
|   return LCR_audio.noise >> 16; |   return LCR_audio.noise >> 16; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |   Gets the next audio sample. | ||||||
|  | */ | ||||||
| uint8_t LCR_audioGetNextSample(void) | uint8_t LCR_audioGetNextSample(void) | ||||||
| { | { | ||||||
|   unsigned char result = 128; |   unsigned char result = 128; | ||||||
|  |  | ||||||
							
								
								
									
										96
									
								
								game.h
									
										
									
									
									
								
							
							
						
						
									
										96
									
								
								game.h
									
										
									
									
									
								
							|  | @ -8,6 +8,9 @@ | ||||||
|   graphics, sound etc., and is meant to be included and used by specific |   graphics, sound etc., and is meant to be included and used by specific | ||||||
|   frontends (which will handle each platform's hardware details and I/O). See |   frontends (which will handle each platform's hardware details and I/O). See | ||||||
|   the frontend info below for help with porting the game to a new platform. |   the frontend info below for help with porting the game to a new platform. | ||||||
|  |   This module (with the help of other modules) will perform all the computations | ||||||
|  |   (physics, graphics, audio, ...) and only use the frontend's quite primitive | ||||||
|  |   functions to actually present the results to the user. | ||||||
| 
 | 
 | ||||||
|   The code uses LCR_ (or _LCR) prefix as a kind of namespace preventing |   The code uses LCR_ (or _LCR) prefix as a kind of namespace preventing | ||||||
|   collision with 3rd party identifiers. |   collision with 3rd party identifiers. | ||||||
|  | @ -59,19 +62,21 @@ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|   FOR FRONTENDS (porting to other platforms): |   FOR FRONTENDS (porting to other platforms): | ||||||
|   - Implement the below described functions according to their description. |   - Implement the frontend functions given below according to their description. | ||||||
|   - Implement the main program and game loop. |   - Implement the main program and game loop. | ||||||
|   - Call the below described functions as described. |   - Call some of the frontend funtions given below in your main program in | ||||||
|   - If you want to support music, make your frontend play music from the "music" |     places as described in the description of the function. | ||||||
|     file in assets. It is in raw format, storing 8bit unsigned samples at 8000 |   - If you want to support music, make your code load and play the "music" | ||||||
|     Hz. Use the LCR_gameMusicOn to check what the music volume is. If you |     file in the asset directory. It is in raw format, storing 8bit unsigned | ||||||
|     don't support music, set LCR_SETTING_MUSIC to 0 in your frontend code so |     samples at 8 KHz mono. Use the LCR_gameMusicOn function to check whether the | ||||||
|     that the game knows music is disabled. |     music is currently enabled (if not, stop playing it). If you don't want to | ||||||
|  |     support music, set LCR_SETTING_MUSIC to 0 in your frontend code (before | ||||||
|  |     including this module) so that the game knows music is disabled. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Implement this in your frontend. Returns 1 if given key is pressed or 0 |   Implement this in your frontend. Returns 1 if given key (see LCR_KEY_* | ||||||
|   otherwise. |   constants) is pressed or 0 otherwise. | ||||||
| */ | */ | ||||||
| uint8_t LCR_keyPressed(uint8_t key); | uint8_t LCR_keyPressed(uint8_t key); | ||||||
| 
 | 
 | ||||||
|  | @ -87,35 +92,40 @@ void LCR_sleep(uint16_t timeMs); | ||||||
|   to the screen back buffer (i.e. NOT directly to screen, back buffer shall |   to the screen back buffer (i.e. NOT directly to screen, back buffer shall | ||||||
|   only be copied to front buffer once the LCR_gameStep function finishes all |   only be copied to front buffer once the LCR_gameStep function finishes all | ||||||
|   rendering). This function should NOT check for out-of-screen coordinates, this |   rendering). This function should NOT check for out-of-screen coordinates, this | ||||||
|   is handled by the game internals and out-of-screen pixels will never be drawn. |   is handled by the game internals and out-of-screen pixels will never be drawn | ||||||
|   The color value depends on game settings but is normally an RGB565 value. |   (your code unnecessarily checking it again would likely slow down rendering a | ||||||
|  |   lot, as drawing pixels is a bottleneck). The color value depends on game | ||||||
|  |   settings but is normally an RGB565 value. The index parameter says the | ||||||
|  |   coordinate at which to write the pixel, assuming the pixels are stored by | ||||||
|  |   rows, from top to bottom. | ||||||
| */ | */ | ||||||
| void LCR_drawPixel(unsigned long index, uint16_t color); | void LCR_drawPixel(unsigned long index, uint16_t color); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Implement this in your frontend. This function will be called to log what the |   Implement this in your frontend. This function will be called to log what the | ||||||
|   program is doing. If you want to ignore logging, simply make the function do |   program is doing. Typically this function should print the string to console. | ||||||
|   nothing. |   If you want to ignore logging, simply make the function do nothing. | ||||||
| */ | */ | ||||||
| void LCR_log(const char *str); | void LCR_log(const char *str); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Implement this in your frontend. This function serves for loading optional |   Implement this in your frontend. This function serves for loading optional | ||||||
|   data file that allows to add more maps, replays etc. If your frontend |   data file that allows adding more maps, replays etc. If your frontend won't | ||||||
|   won't support this, just make the function return 0. Otherwise it must return |   support this, just make the function return 0. Otherwise it must return | ||||||
|   characters from the data file one by one; after reaching the end of file |   characters from the data file one by one; after reaching the end of file 0 | ||||||
|   0 must be returned and the reading position will be reset to start again. |   must be returned and the reading position will be reset to start from | ||||||
|  |   beginning again. | ||||||
| */ | */ | ||||||
| char LCR_getNextDataFileChar(void); | char LCR_getNextDataFileChar(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Implement this in your frontend. This serves to store data in the optional |   Implement this in your frontend. This serves to store data in the optional | ||||||
|   data file, e.g. replays. If your frontend doesn't support this (e.g. |   data file (e.g. replays and info about beaten maps). If your frontend doesn't | ||||||
|   because the file is read only), the function may ignore the append, but if |   support this (e.g. because the file is read only), the function may ignore the | ||||||
|   the file is otherwise supported, a rewind of the read position must still be |   append, but if the file is otherwise supported, a rewind of the read position | ||||||
|   done. If appending is supported, the function must append the provided string |   must still be performed. If appending is supported, the function must append | ||||||
|   to the data file AND then reset the data file reading position back to |   the provided string to the data file AND then reset the data file reading | ||||||
|   the start. |   position back to the start. | ||||||
| */ | */ | ||||||
| void LCR_appendDataStr(const char *str); | void LCR_appendDataStr(const char *str); | ||||||
| 
 | 
 | ||||||
|  | @ -134,18 +144,22 @@ void LCR_gameEnd(void); | ||||||
|   Call this function in your frontend repeatedly inside the main loop, pass the |   Call this function in your frontend repeatedly inside the main loop, pass the | ||||||
|   current time as the number of milliseconds since program start. This function |   current time as the number of milliseconds since program start. This function | ||||||
|   will perform the game step AND other things such as checking the input states, |   will perform the game step AND other things such as checking the input states, | ||||||
|   rendering or sleeping (all using the above functions you should implement). |   rendering or sleeping (all using the above described functions you should | ||||||
|   Returns 0 if program should end, otherwise 1. |   implement). Returns 0 if program should end, otherwise 1. | ||||||
| */ | */ | ||||||
| uint8_t LCR_gameStep(uint32_t timeMs); | uint8_t LCR_gameStep(uint32_t timeMs); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Gets the current music volume; |   Returns 1 if music is currently on, else 0. If your frontend supports music, | ||||||
|  |   use this function at each frame to know whether you should start/stop playing | ||||||
|  |   music. Otherwise ignore this. | ||||||
| */ | */ | ||||||
| uint8_t LCR_gameMusicOn(void); | uint8_t LCR_gameMusicOn(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Gets next audio sample (unsigned 8bit samples, 8 KHz). |   Gets the next audio sample (unsigned 8bit samples, 8 KHz mono). If your | ||||||
|  |   frontend supports sound, call this continuously and play the stream of | ||||||
|  |   samples, otherwise ignore this. | ||||||
| */ | */ | ||||||
| uint8_t LCR_gameGetNextAudioSample(void); | uint8_t LCR_gameGetNextAudioSample(void); | ||||||
| 
 | 
 | ||||||
|  | @ -187,7 +201,7 @@ uint8_t LCR_gameGetNextAudioSample(void); | ||||||
| // forward decls of pixel drawing functions for the renderer
 | // forward decls of pixel drawing functions for the renderer
 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Internal pixel drawing function that draws pixel at specified screen coords |   Internal pixel drawing function that puts a pixel at specified screen coords | ||||||
|   without checking for safety (it's faster but can only be done if we know for |   without checking for safety (it's faster but can only be done if we know for | ||||||
|   sure we're not drawing outside the screen). |   sure we're not drawing outside the screen). | ||||||
| */ | */ | ||||||
|  | @ -213,7 +227,7 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, | ||||||
| 
 | 
 | ||||||
| #if LCR_SETTING_GHOST_MAX_SAMPLES == 0 | #if LCR_SETTING_GHOST_MAX_SAMPLES == 0 | ||||||
|   #undef LCR_MENU_TABS |   #undef LCR_MENU_TABS | ||||||
|   #define LCR_MENU_TABS 3 |   #define LCR_MENU_TABS 3 // no ghosts => remove the tab for ghosts
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define LCR_MENU_STRING_SIZE 16 | #define LCR_MENU_STRING_SIZE 16 | ||||||
|  | @ -241,18 +255,17 @@ struct | ||||||
| { | { | ||||||
|   uint8_t state; |   uint8_t state; | ||||||
|   uint32_t stateStartTime; |   uint32_t stateStartTime; | ||||||
|   uint32_t time; |   uint32_t time;                     ///< Current frame's time.
 | ||||||
|   uint32_t frame; |   uint32_t frame;                    ///< Current frame number.
 | ||||||
|   uint32_t nextRenderFrameTime; |   uint32_t nextRenderFrameTime;      ///< At which frame to render next frame.
 | ||||||
|   uint32_t nextRacingTickTime; |   uint32_t nextRacingTickTime;       ///< When to simulate next physics tick.
 | ||||||
|   uint8_t cameraMode; |   uint8_t cameraMode; | ||||||
|   uint8_t debugDraw; |  | ||||||
|   uint8_t musicOn; |   uint8_t musicOn; | ||||||
|   uint8_t keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
 |   uint8_t keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
 | ||||||
|                                           during a single frame, hold number of |                                           during a single frame, hold number of | ||||||
|                                           frames for which the key has been |                                           frames for which the key has been | ||||||
|                                           continuously held. */  |                                           continuously held. */  | ||||||
|   uint32_t runTimeMS;                /**< Current time of the run */ |   uint32_t runTimeMS;                ///< Current time of the run
 | ||||||
| 
 | 
 | ||||||
|   struct |   struct | ||||||
|   { |   { | ||||||
|  | @ -260,14 +273,14 @@ struct | ||||||
|     uint8_t selectedItem; |     uint8_t selectedItem; | ||||||
|     uint8_t itemCount; |     uint8_t itemCount; | ||||||
|     char itemNames[LCR_MENU_MAX_ITEMS][LCR_MENU_STRING_SIZE]; |     char itemNames[LCR_MENU_MAX_ITEMS][LCR_MENU_STRING_SIZE]; | ||||||
|     const char *itemNamePtrs[LCR_MENU_MAX_ITEMS]; ///< helper array
 |     const char *itemNamePtrs[LCR_MENU_MAX_ITEMS]; ///< Helper array.
 | ||||||
|   } menu; |   } menu; | ||||||
| 
 | 
 | ||||||
|   struct |   struct | ||||||
|   { |   { | ||||||
|     int state;        ///< -1 if reading external res. f., else pos.
 |     int state;            ///< -1 if reading external data f., else pos.
 | ||||||
| 
 | 
 | ||||||
|     // indices and counts are among the data of the same type
 |     // Indices and counts are among the data of the same type.
 | ||||||
|     unsigned int firstItemIndex; |     unsigned int firstItemIndex; | ||||||
|     unsigned int itemsTotal; |     unsigned int itemsTotal; | ||||||
|   } dataFile; |   } dataFile; | ||||||
|  | @ -286,7 +299,6 @@ struct | ||||||
|                            is to allow ghosts for even long replays. */ |                            is to allow ghosts for even long replays. */ | ||||||
|   } ghost; |   } ghost; | ||||||
| #endif | #endif | ||||||
| 
 |  | ||||||
| } LCR_game; | } LCR_game; | ||||||
| 
 | 
 | ||||||
| uint8_t LCR_gameMusicOn(void) | uint8_t LCR_gameMusicOn(void) | ||||||
|  | @ -448,7 +460,7 @@ void _LCR_gamePrepareGhost(void) | ||||||
| 
 | 
 | ||||||
|   LCR_game.ghost.stretch = 0; |   LCR_game.ghost.stretch = 0; | ||||||
| 
 | 
 | ||||||
|   while (((int) LCR_replay.achievedTime) > |   while (((int) LCR_racing.replay.achievedTime) > | ||||||
|     (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch) * |     (LCR_SETTING_GHOST_STEP << LCR_game.ghost.stretch) * | ||||||
|     LCR_SETTING_GHOST_MAX_SAMPLES) |     LCR_SETTING_GHOST_MAX_SAMPLES) | ||||||
|   { |   { | ||||||
|  | @ -780,7 +792,7 @@ void LCR_gameInit(int argc, const char **argv) | ||||||
|   LCR_game.menu.selectedItem = 0; |   LCR_game.menu.selectedItem = 0; | ||||||
| 
 | 
 | ||||||
|   LCR_game.frame = 0; |   LCR_game.frame = 0; | ||||||
|   LCR_game.musicOn = 1; |   LCR_game.musicOn = LCR_SETTING_MUSIC; | ||||||
|   LCR_game.nextRenderFrameTime = 0; |   LCR_game.nextRenderFrameTime = 0; | ||||||
|   LCR_game.nextRacingTickTime = 0; |   LCR_game.nextRacingTickTime = 0; | ||||||
|   LCR_game.cameraMode = LCR_CAMERA_MODE_DRIVE; |   LCR_game.cameraMode = LCR_CAMERA_MODE_DRIVE; | ||||||
|  | @ -1176,9 +1188,11 @@ void LCR_gameHandleInput(void) | ||||||
|                 LCR_rendererCameraReset(); |                 LCR_rendererCameraReset(); | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|  | #if LCR_SETTING_MUSIC | ||||||
|               case 1: |               case 1: | ||||||
|                 LCR_game.musicOn = !LCR_game.musicOn; |                 LCR_game.musicOn = !LCR_game.musicOn; | ||||||
|                 break; |                 break; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|               case 2: |               case 2: | ||||||
|                 LCR_audio.on = !LCR_audio.on; |                 LCR_audio.on = !LCR_audio.on; | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								map.h
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								map.h
									
										
									
									
									
								
							|  | @ -94,7 +94,7 @@ | ||||||
| #define LCR_BLOCK_RAMP_34           '/'  ///< plain ramp, 3/4 size
 | #define LCR_BLOCK_RAMP_34           '/'  ///< plain ramp, 3/4 size
 | ||||||
| #define LCR_BLOCK_RAMP_12           '<'  ///< plain ramp, 1/2 size
 | #define LCR_BLOCK_RAMP_12           '<'  ///< plain ramp, 1/2 size
 | ||||||
| #define LCR_BLOCK_RAMP_14           '_'  ///< plain ramp, 1/4 size
 | #define LCR_BLOCK_RAMP_14           '_'  ///< plain ramp, 1/4 size
 | ||||||
| #define LCR_BLOCK_RAMP_CORNER       'v'  ///< corner of ramp
 | #define LCR_BLOCK_RAMP_CORNER       'v'  ///< corner of a ramp
 | ||||||
| #define LCR_BLOCK_RAMP_CURVED_PLAT  ']'  ///< curved ramp with top platgform
 | #define LCR_BLOCK_RAMP_CURVED_PLAT  ']'  ///< curved ramp with top platgform
 | ||||||
| #define LCR_BLOCK_RAMP_CURVED       ')'  ///< curv. ramp without top platf.
 | #define LCR_BLOCK_RAMP_CURVED       ')'  ///< curv. ramp without top platf.
 | ||||||
| #define LCR_BLOCK_RAMP_CURVED_WALL  '}'  ///< curved ramp plus small wall
 | #define LCR_BLOCK_RAMP_CURVED_WALL  '}'  ///< curved ramp plus small wall
 | ||||||
|  | @ -103,6 +103,8 @@ | ||||||
| #define LCR_BLOCK_CORNER_12         '\\' ///< diagonal corner (1/2 wide)
 | #define LCR_BLOCK_CORNER_12         '\\' ///< diagonal corner (1/2 wide)
 | ||||||
| #define LCR_BLOCK_HILL              '('  ///< curved "hill"
 | #define LCR_BLOCK_HILL              '('  ///< curved "hill"
 | ||||||
| #define LCR_BLOCK_BUMP              '~'  ///< small bump on the road
 | #define LCR_BLOCK_BUMP              '~'  ///< small bump on the road
 | ||||||
|  | #define LCR_BLOCK_CORNER_CONVEX     'n'  ///< curved corner (convex)
 | ||||||
|  | #define LCR_BLOCK_CORNER_CONCAVE    'l'  ///< curved corner (concave)
 | ||||||
| 
 | 
 | ||||||
| #define LCR_BLOCK_FULL_ACCEL        '>' | #define LCR_BLOCK_FULL_ACCEL        '>' | ||||||
| #define LCR_BLOCK_BOTTOM_ACCEL      'z' | #define LCR_BLOCK_BOTTOM_ACCEL      'z' | ||||||
|  | @ -111,9 +113,6 @@ | ||||||
| #define LCR_BLOCK_FULL_FAN          'o' | #define LCR_BLOCK_FULL_FAN          'o' | ||||||
| #define LCR_BLOCK_RAMP_FAN          'V' | #define LCR_BLOCK_RAMP_FAN          'V' | ||||||
| 
 | 
 | ||||||
| #define LCR_BLOCK_CORNER_CONVEX     'n' |  | ||||||
| #define LCR_BLOCK_CORNER_CONCAVE    'l' |  | ||||||
| 
 |  | ||||||
| #define LCR_BLOCK_CHECKPOINT_0      '+'  ///< checkpoint, not taken
 | #define LCR_BLOCK_CHECKPOINT_0      '+'  ///< checkpoint, not taken
 | ||||||
| #define LCR_BLOCK_CHECKPOINT_1      '\'' ///< checkpoint, taken
 | #define LCR_BLOCK_CHECKPOINT_1      '\'' ///< checkpoint, taken
 | ||||||
| 
 | 
 | ||||||
|  | @ -131,15 +130,10 @@ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|   TODO: |   TODO: | ||||||
|   - ramp corner??? |  | ||||||
|   - curved corner? |  | ||||||
|   - curved out corner? |  | ||||||
|   - curved "hill" |  | ||||||
|   - bumpy road |  | ||||||
|   - bigger structures like a loop, sloped road etc? |   - bigger structures like a loop, sloped road etc? | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #define LCR_MAP_BLOCK_CACHE_SIZE (8 * 2)   /// do not change
 | #define LCR_MAP_BLOCK_CACHE_SIZE (8 * 2) ///< Do not change.
 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Cache for accelerating LCR_mapGetBlockAtFast, consists of 8 2-item records, |   Cache for accelerating LCR_mapGetBlockAtFast, consists of 8 2-item records, | ||||||
|  | @ -249,7 +243,7 @@ void LCR_rampGetDimensions(uint8_t rampType, uint8_t *height4ths, | ||||||
| 
 | 
 | ||||||
| uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) | uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) | ||||||
| { | { | ||||||
|   // binary search the block:
 |   // Binary search the block:
 | ||||||
| 
 | 
 | ||||||
|   uint16_t a = 0, b = LCR_currentMap.blockCount - 1; |   uint16_t a = 0, b = LCR_currentMap.blockCount - 1; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										136
									
								
								racing.h
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								racing.h
									
										
									
									
									
								
							|  | @ -69,7 +69,7 @@ typedef int32_t LCR_GameUnit;  ///< abstract game unit | ||||||
| #define LCR_CAR_CRASH_SPEED_SMALL 400 | #define LCR_CAR_CRASH_SPEED_SMALL 400 | ||||||
| #define LCR_CAR_CRASH_SPEED_BIG 800 | #define LCR_CAR_CRASH_SPEED_BIG 800 | ||||||
| 
 | 
 | ||||||
| // multipliers (in 8ths) of friction and acceleration on concrete:
 | // Multipliers (in 8ths) of friction and acceleration on concrete:
 | ||||||
| #define LCR_CAR_GRASS_FACTOR 5 | #define LCR_CAR_GRASS_FACTOR 5 | ||||||
| #define LCR_CAR_DIRT_FACTOR  3 | #define LCR_CAR_DIRT_FACTOR  3 | ||||||
| #define LCR_CAR_ICE_FACTOR   1 | #define LCR_CAR_ICE_FACTOR   1 | ||||||
|  | @ -87,7 +87,7 @@ struct | ||||||
|   TPE_Joint carJoints[LCR_CAR_JOINTS]; |   TPE_Joint carJoints[LCR_CAR_JOINTS]; | ||||||
|   TPE_Connection carConnections[LCR_CAR_CONNECTIONS]; |   TPE_Connection carConnections[LCR_CAR_CONNECTIONS]; | ||||||
| 
 | 
 | ||||||
|   uint32_t tick; |   uint32_t tick;             ///< Physics tick (frame) number.
 | ||||||
|   uint8_t wheelCollisions;   /**< In individual bits records for each car wheel
 |   uint8_t wheelCollisions;   /**< In individual bits records for each car wheel
 | ||||||
|                                   whether it's currently touching the ground. |                                   whether it's currently touching the ground. | ||||||
|                                   Lower bits record current collisions, higher |                                   Lower bits record current collisions, higher | ||||||
|  | @ -111,7 +111,6 @@ struct | ||||||
|   uint16_t crashState; |   uint16_t crashState; | ||||||
| 
 | 
 | ||||||
|   uint8_t playingReplay; |   uint8_t playingReplay; | ||||||
| } LCR_racing; |  | ||||||
| 
 | 
 | ||||||
|   struct |   struct | ||||||
|   { |   { | ||||||
|  | @ -122,7 +121,8 @@ struct | ||||||
|     uint16_t currentEvent; |     uint16_t currentEvent; | ||||||
|     uint16_t currentFrame; |     uint16_t currentFrame; | ||||||
|     uint32_t achievedTime; |     uint32_t achievedTime; | ||||||
| } LCR_replay; // TODO: move inside LCR_racing?
 |   } replay; | ||||||
|  | } LCR_racing; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Gets times of the run in milliseconds. |   Gets times of the run in milliseconds. | ||||||
|  | @ -144,15 +144,15 @@ TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d) | ||||||
| void LCR_replayInitRecording(void) | void LCR_replayInitRecording(void) | ||||||
| { | { | ||||||
|   LCR_LOG1("initializing replay recording"); |   LCR_LOG1("initializing replay recording"); | ||||||
|   LCR_replay.eventCount = 0; |   LCR_racing.replay.eventCount = 0; | ||||||
|   LCR_replay.achievedTime = 0; |   LCR_racing.replay.achievedTime = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LCR_replayInitPlaying(void) | void LCR_replayInitPlaying(void) | ||||||
| { | { | ||||||
|   LCR_LOG1("initializing replay playing"); |   LCR_LOG1("initializing replay playing"); | ||||||
|   LCR_replay.currentEvent = 0; |   LCR_racing.replay.currentEvent = 0; | ||||||
|   LCR_replay.currentFrame = 0; |   LCR_racing.replay.currentFrame = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -185,14 +185,16 @@ void LCR_replayOutputStr(void (*printChar)(char)) | ||||||
| 
 | 
 | ||||||
|   // 8 decimal digits are enough to record 24 hours
 |   // 8 decimal digits are enough to record 24 hours
 | ||||||
| 
 | 
 | ||||||
| #define PUTD(order) printChar('0' + (LCR_replay.achievedTime / order) % 10); | #define PUTD(order) \ | ||||||
|  |   printChar('0' + (LCR_racing.replay.achievedTime / order) % 10); | ||||||
|  | 
 | ||||||
|   PUTD(10000000) PUTD(1000000) PUTD(100000) PUTD(10000) |   PUTD(10000000) PUTD(1000000) PUTD(100000) PUTD(10000) | ||||||
|   PUTD(1000) PUTD(100) PUTD(10) PUTD(1) |   PUTD(1000) PUTD(100) PUTD(10) PUTD(1) | ||||||
| #undef PUTD | #undef PUTD | ||||||
| 
 | 
 | ||||||
|   for (int i = 0; i < LCR_replay.eventCount; ++i) |   for (int i = 0; i < LCR_racing.replay.eventCount; ++i) | ||||||
|   { |   { | ||||||
|     uint16_t e = LCR_replay.events[i]; |     uint16_t e = LCR_racing.replay.events[i]; | ||||||
|     printChar(':'); |     printChar(':'); | ||||||
| 
 | 
 | ||||||
|     for (int j = 0; j < 4; ++j) |     for (int j = 0; j < 4; ++j) | ||||||
|  | @ -208,32 +210,22 @@ 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. The mapHash and nameHash pointers are optional: if non-zero, |   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, |   the memory they point to will be filled with the map hash and name hash. | ||||||
|   else 0. |   Returns 1 on success, else 0. | ||||||
| */ | */ | ||||||
| int LCR_replayLoadFromStr(char (*nextChar)(void), | int LCR_replayLoadFromStr(char (*nextChar)(void), | ||||||
|   uint32_t *mapHash, uint16_t *nameHash) |   uint32_t *mapHash, uint16_t *nameHash) | ||||||
| { | { | ||||||
|   char c = ' '; |   char c = ' '; | ||||||
| 
 | 
 | ||||||
|   LCR_replay.eventCount = 0; |   LCR_racing.replay.eventCount = 0; | ||||||
|   LCR_replay.achievedTime = 0; |   LCR_racing.replay.achievedTime = 0; | ||||||
| 
 | 
 | ||||||
|   if (nameHash) |   if (nameHash) | ||||||
|     *nameHash = _LCR_simpleStrHash(nextChar,';'); |     *nameHash = _LCR_simpleStrHash(nextChar,';'); | ||||||
|   else |   else | ||||||
|     _LCR_simpleStrHash(nextChar,';'); |     _LCR_simpleStrHash(nextChar,';'); | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|   do // map name
 |  | ||||||
|   { |  | ||||||
|     c = nextChar(); |  | ||||||
| 
 |  | ||||||
|     if (c == 0) |  | ||||||
|       return 0; |  | ||||||
|   } while (c != ';'); |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
|   if (mapHash) |   if (mapHash) | ||||||
|     *mapHash = 0; |     *mapHash = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -248,12 +240,6 @@ for (int i = 0; i < 8; ++i) // hash | ||||||
|       *mapHash = ((*mapHash) << 4) | _LCR_hexDigitVal(c); |       *mapHash = ((*mapHash) << 4) | _LCR_hexDigitVal(c); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|   for (int i = 0; i < 8; ++i) // hash
 |  | ||||||
|     if (_LCR_hexDigitVal(nextChar()) < 0) |  | ||||||
|       return 0; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
|   nextChar(); |   nextChar(); | ||||||
| 
 | 
 | ||||||
|   while (1) // time
 |   while (1) // time
 | ||||||
|  | @ -263,7 +249,8 @@ for (int i = 0; i < 8; ++i) // hash | ||||||
|     if (c < '0' || c > '9') |     if (c < '0' || c > '9') | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|     LCR_replay.achievedTime = LCR_replay.achievedTime * 10 + c - '0'; |     LCR_racing.replay.achievedTime =  | ||||||
|  |       LCR_racing.replay.achievedTime * 10 + c - '0'; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   while (c != 0) // events
 |   while (c != 0) // events
 | ||||||
|  | @ -278,11 +265,11 @@ for (int i = 0; i < 8; ++i) // hash | ||||||
|       if (e == 0) |       if (e == 0) | ||||||
|         break; |         break; | ||||||
|        |        | ||||||
|       if (LCR_replay.eventCount >= LCR_SETTING_REPLAY_MAX_SIZE) |       if (LCR_racing.replay.eventCount >= LCR_SETTING_REPLAY_MAX_SIZE) | ||||||
|         return 0; |         return 0; | ||||||
| 
 | 
 | ||||||
|       LCR_replay.events[LCR_replay.eventCount] = e; |       LCR_racing.replay.events[LCR_racing.replay.eventCount] = e; | ||||||
|       LCR_replay.eventCount++; |       LCR_racing.replay.eventCount++; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     c = nextChar(); |     c = nextChar(); | ||||||
|  | @ -292,60 +279,61 @@ for (int i = 0; i < 8; ++i) // hash | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   During playing of a replay returns the next input and shifts to next frame. |   When playing back a replay this function returns the next recorded input and | ||||||
|  |   shifts to the next frame. | ||||||
| */ | */ | ||||||
| uint8_t LCR_replayGetNextInput(void) | uint8_t LCR_replayGetNextInput(void) | ||||||
| { | { | ||||||
|   if (LCR_replay.currentEvent >= LCR_replay.eventCount) |   if (LCR_racing.replay.currentEvent >= LCR_racing.replay.eventCount) | ||||||
|   { |   { | ||||||
|     LCR_replay.currentFrame++; // has to be here
 |     LCR_racing.replay.currentFrame++; // has to be here
 | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (LCR_replay.currentFrame == |   if (LCR_racing.replay.currentFrame == | ||||||
|     (LCR_replay.events[LCR_replay.currentEvent] >> 4)) |     (LCR_racing.replay.events[LCR_racing.replay.currentEvent] >> 4)) | ||||||
|   { |   { | ||||||
|     LCR_replay.currentEvent++; |     LCR_racing.replay.currentEvent++; | ||||||
|     LCR_replay.currentFrame = 0; |     LCR_racing.replay.currentFrame = 0; | ||||||
|   } |   } | ||||||
|   |   | ||||||
|   LCR_replay.currentFrame++; |   LCR_racing.replay.currentFrame++; | ||||||
| 
 | 
 | ||||||
|   return LCR_replay.currentEvent ? |   return LCR_racing.replay.currentEvent ? | ||||||
|     (LCR_replay.events[LCR_replay.currentEvent - 1] & 0x0f) : 0; |     (LCR_racing.replay.events[LCR_racing.replay.currentEvent - 1] & 0x0f) : 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int LCR_replayHasFinished(void) | int LCR_replayHasFinished(void) | ||||||
| { | { | ||||||
|   if (LCR_replay.currentEvent == LCR_replay.eventCount) |   if (LCR_racing.replay.currentEvent == LCR_racing.replay.eventCount) | ||||||
|   { |   { | ||||||
|     uint32_t totalTime = LCR_replay.currentFrame; |     uint32_t totalTime = LCR_racing.replay.currentFrame; | ||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < LCR_replay.eventCount; ++i) |     for (int i = 0; i < LCR_racing.replay.eventCount; ++i) | ||||||
|       totalTime += LCR_replay.events[i] >> 4; |       totalTime += LCR_racing.replay.events[i] >> 4; | ||||||
| 
 | 
 | ||||||
|     return totalTime >= LCR_replay.achievedTime; |     return totalTime >= LCR_racing.replay.achievedTime; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return LCR_replay.currentEvent > LCR_replay.eventCount; |   return LCR_racing.replay.currentEvent > LCR_racing.replay.eventCount; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Records another input event. Returns 1 on success, or 0 if the event couldn't |   Records another input event into a replay. Returns 1 on success, or 0 if the | ||||||
|   be recorded. The event is only added if necessary, i.e. this function can |   event couldn't be recorded. The event is only added if necessary, i.e. this | ||||||
|   (and must) be called every frame without worrying about inflating its size. |   function can, and MUST, be called every frame without worrying about inflating | ||||||
|   When the run ends, the LCR_REPLAY_EVENT_END has to be fed! |   its size. When the run ends, the LCR_REPLAY_EVENT_END has to be fed! | ||||||
| */ | */ | ||||||
| int LCR_replayRecordEvent(uint32_t frame, uint8_t input) | int LCR_replayRecordEvent(uint32_t frame, uint8_t input) | ||||||
| { | { | ||||||
|   LCR_LOG2("recording replay event"); |   LCR_LOG2("recording replay event"); | ||||||
| 
 | 
 | ||||||
|   if (LCR_replay.achievedTime) |   if (LCR_racing.replay.achievedTime) | ||||||
|     return 1; // already finished
 |     return 1; // already finished
 | ||||||
| 
 | 
 | ||||||
|   if (input == LCR_REPLAY_EVENT_END) |   if (input == LCR_REPLAY_EVENT_END) | ||||||
|   { |   { | ||||||
|     LCR_replay.achievedTime = frame; |     LCR_racing.replay.achievedTime = frame; | ||||||
|     LCR_LOG1("replay recording finished"); |     LCR_LOG1("replay recording finished"); | ||||||
|     return 1; |     return 1; | ||||||
|   } |   } | ||||||
|  | @ -354,10 +342,10 @@ int LCR_replayRecordEvent(uint32_t frame, uint8_t input) | ||||||
|   uint8_t previousInput = 0; |   uint8_t previousInput = 0; | ||||||
|   uint32_t previousFrame = 0; |   uint32_t previousFrame = 0; | ||||||
| 
 | 
 | ||||||
|   for (int i = 0; i < LCR_replay.eventCount; ++i) |   for (int i = 0; i < LCR_racing.replay.eventCount; ++i) | ||||||
|   { |   { | ||||||
|     previousInput = LCR_replay.events[i] & 0x0f; |     previousInput = LCR_racing.replay.events[i] & 0x0f; | ||||||
|     previousFrame += LCR_replay.events[i] >> 4; |     previousFrame += LCR_racing.replay.events[i] >> 4; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (input == previousInput) |   if (input == previousInput) | ||||||
|  | @ -368,30 +356,30 @@ int LCR_replayRecordEvent(uint32_t frame, uint8_t input) | ||||||
| 
 | 
 | ||||||
|   frame -= previousFrame; // convert to offset
 |   frame -= previousFrame; // convert to offset
 | ||||||
| 
 | 
 | ||||||
|   while (frame > 4095 && LCR_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; | ||||||
|     previousFrame += 4095; |     previousFrame += 4095; | ||||||
| 
 | 
 | ||||||
|     LCR_replay.events[LCR_replay.eventCount] = |     LCR_racing.replay.events[LCR_racing.replay.eventCount] = | ||||||
|       (previousFrame << 4) | previousInput; |       (previousFrame << 4) | previousInput; | ||||||
|     LCR_replay.eventCount++; |     LCR_racing.replay.eventCount++; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (LCR_replay.eventCount >= LCR_SETTING_REPLAY_MAX_SIZE) |   if (LCR_racing.replay.eventCount >= LCR_SETTING_REPLAY_MAX_SIZE) | ||||||
|     return 0; |     return 0; | ||||||
| 
 | 
 | ||||||
|   LCR_replay.events[LCR_replay.eventCount] = (frame << 4) | (input & 0x0f); |   LCR_racing.replay.events[LCR_racing.replay.eventCount] = (frame << 4) | (input & 0x0f); | ||||||
|   LCR_replay.eventCount++; |   LCR_racing.replay.eventCount++; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Helper function for _LCR_racingEnvironmentFunction, returns closest point |   Helper function for _LCR_racingEnvironmentFunction, returns closest point on | ||||||
|   on a map block placed at coordinate origin. |   a map block placed at coordinate origin. | ||||||
| */ | */ | ||||||
| TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) | TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) | ||||||
| { | { | ||||||
|  | @ -691,8 +679,8 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   For tinyphysicsengine, function that defines the shape of physics world, |   For tinyphysicsengine, function that defines the shape of the static physics | ||||||
|   returns closest point to any given point in space. |   world, returns closest point to any given point in space. | ||||||
| */ | */ | ||||||
| TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) | TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) | ||||||
| { | { | ||||||
|  | @ -795,10 +783,10 @@ LCR_GameUnit LCR_racingGetCarSpeedSigned(void) | ||||||
| uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2, | uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2, | ||||||
|   uint16_t j2, TPE_Vec3 p) |   uint16_t j2, TPE_Vec3 p) | ||||||
| { | { | ||||||
|   // check which wheels are touching the ground.
 |  | ||||||
| 
 |  | ||||||
| #if LCR_SETTING_CRASH_SOUNDS | #if LCR_SETTING_CRASH_SOUNDS | ||||||
|   TPE_Unit speed = TPE_vec3Len( // detect crashes
 |   // Detect crashes:
 | ||||||
|  | 
 | ||||||
|  |   TPE_Unit speed = TPE_vec3Len( | ||||||
|       TPE_vec3Project( |       TPE_vec3Project( | ||||||
|         TPE_vec3( |         TPE_vec3( | ||||||
|           LCR_racing.carBody.joints[j1].velocity[0], |           LCR_racing.carBody.joints[j1].velocity[0], | ||||||
|  | @ -811,6 +799,8 @@ uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2, | ||||||
|     (speed >= LCR_CAR_CRASH_SPEED_SMALL); |     (speed >= LCR_CAR_CRASH_SPEED_SMALL); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |   // Check which wheels are touching the ground:
 | ||||||
|  | 
 | ||||||
|   if (j1 < 4) // wheel joint?
 |   if (j1 < 4) // wheel joint?
 | ||||||
|     LCR_racing.wheelCollisions |= 0x01 << j1; |     LCR_racing.wheelCollisions |= 0x01 << j1; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue