From 89da5098061d38138c317e25941809a1456e60ea Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sun, 8 Jun 2025 15:33:43 +0200 Subject: [PATCH] Add new records plus comments --- TODO.txt | 8 ++++-- assets.h | 15 +++++----- data | 3 +- game.h | 14 ++++----- general.h | 19 ++++++------ racing.h | 84 ++++++++++++++++++++++++++++++------------------------ renderer.h | 6 ++++ settings.h | 2 +- 8 files changed, 82 insertions(+), 69 deletions(-) diff --git a/TODO.txt b/TODO.txt index 759f587..a42dd7b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -12,7 +12,6 @@ fuck issue trackers :D - Nibble, should hopefully be powerful enough. - ESPboy? - linux framebuffer? -- press forward map??? :-D only when physics is frozen - make some kinda repo for world record runs? how will they submit it? - final tests: - very long replay DID 1x @@ -23,16 +22,18 @@ fuck issue trackers :D - different platforms - error handling (bad map format, bad replay format, items in data file, ...) - valgrind, cppcheck, different compilers, optimization levels, ... - - play replay from one platform on another + - play replay from one platform on another KINDA DID - profiling - gigantic map that fails to fit in RAM - replay stretching DID 1x - - play all maps a lot + - play all maps a lot DOING - correct saving of replays etc. - empty and large data file - FPS on each platform - try to use the racing module by itself - spellcheck comments + - test a map without any CPs where the car starts at finish + - just read through the code and eyeball it =========== BUGS ================= @@ -42,6 +43,7 @@ fuck issue trackers :D =========== HANDLED ============== - should drifting make a sound? NO NEED +- press forward map??? :-D only when physics is frozen - devtest map, internal camera: reversing at start makes the car face completely downwards which bugs the camera rotation! the shadow model too - particles in free camera mode are very big if far away from the car (maybe diff --git a/assets.h b/assets.h index a4f5fd2..724d44c 100644 --- a/assets.h +++ b/assets.h @@ -5,9 +5,11 @@ Licar: assets - This file holds assets, resources and other bigger pieces of data that are to - be compiled right into the executable. This is so that for a minimal version - of the game a filesystem is not required. + This file holds assets and other bigger pieces of data that are to be compiled + right into the executable. This is so that for a minimal version of the game a + filesystem is not required, all data will be embedded in the program. On + platforms supporting files additional data (maps, replays, ...) can still be + supplied via the external data file. NOTES: - All images are 64x64, stored in an indexed mode (8bits pery pixel), the @@ -15,9 +17,8 @@ takes 512 bytes, then 64x64 bytes follow). - Each sky (background) image is composed of 4 regular images so they have higher resolution. The partial images are stored in the above format, one - sky part consists of interleaved lines, so it effectively stores a - 128x32 strip (instead of 64x64 square) -- this is convenient for drawing - the sky. + sky part consists of interlaced lines, so it effectively stores a 128x32 + strip (instead of 64x64 square) -- this is convenient for drawing the sky. */ #include "general.h" @@ -64,8 +65,6 @@ static const char *LCR_texts[] = " -M load the last map in the data file\n" \ " -R load the last replay in the data file\n" -// TODO: define string for CLI arguments for frontends? - static const char LCR_internalDataFile[] = { // data generated by make_internal_data_file.c: diff --git a/data b/data index 6f97826..295f3ec 100644 --- a/data +++ b/data @@ -204,6 +204,7 @@ air path #RLCtiny3 00'11'748;00LCtiny3;df0bd8ce 0000356:0001:0083:0031:01e3:0031:00b9:0041:00f9:0021:0109:0011:02b3:0031:0079:00e1:0069:0191:0279:0041:0089:0031:0149:0021:0083:0031:03e3:0031 #RLCtiny4 00'04'785;00LCtiny4;f999f0ec 0000145:0003:01b1:0039:01d1:00e9:0031:0259:0021:0139:0021:0029:0021 #RLCtiny5 00'08'514;00LCtiny5;5c14d8b6 0000258:0001:0179:0031:0059:0041:0019:0051:0029:0041:0029:0031:0069:0031:0049:0021:0079:0031:0039:0021:0053:0181:00d3:0011:0069:0051:00b3:0081:0013:0041:0023:0051:00c3:0041:0033:0031:0145:0021:0163:0021 -#RLCbonus1 00'13'629;00LCbonus1;999b1acd 0000413:0001:00d9:0051:0113:0031:0069:0021:00a9:0031:0049:0041:0039:0051:0043:0121:0053:0061:0083:0021:0083:0041:0079:01b1:0059:0041:0049:0021:00e9:0031:0063:0041:0169:00c1:03e9:0038:0020:0081:0119:00b1:00c9:0041:0079:0041:0039:0051:0039:0058:0179:0031 +#RLCbonus1 00'13'167;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 #RLCbonus2 00'24'189;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 #RLCpressforw1 00'21'318;00LCpressforw1;6363b43d 0000599:0001 + diff --git a/game.h b/game.h index 7d9ef2f..ce72fe2 100644 --- a/game.h +++ b/game.h @@ -8,14 +8,11 @@ This file implements the backend of a complete, actually playable game with 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 - 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 + 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 - collision with 3rd party identifiers. - UNITS: There are various kinds of units used to ensure independence of the modules. Here is a summary: @@ -65,6 +62,7 @@ /* FOR FRONTENDS (porting to other platforms): + - Implement the frontend functions given below according to their description. - Implement the main program and game loop. - Call some of the frontend funtions given below in your main program in @@ -376,9 +374,9 @@ struct uint8_t samples[LCR_SETTING_GHOST_MAX_SAMPLES * LCR_GHOST_SAMPLE_SIZE]; /**< Samples, each 5 bytes: 9 bits for X and Z, 10 for Y, 4 for each rotation component. */ - uint8_t stretch; /**< Stretch of the base sample step, as a bit shift - (i.e. 1 means the step will be 2x as long etc.). This - is to allow ghosts for even long replays. */ + uint8_t stretch; /**< Stretch of the base sample step, as a bit shift (i.e. + 1 means the step will be 2x as long etc.). This is to + allow ghosts for even long replays. */ int16_t offset[3]; ///< Small correcting position offset. } ghost; #endif diff --git a/general.h b/general.h index e6b711e..1bf801f 100644 --- a/general.h +++ b/general.h @@ -6,12 +6,19 @@ Licar: general This file holds general definitions used by all modules. + + All Licar code uses LCR_ (or _LCR_) prefix as a kind of namespace preventing + collision with 3rd party identifiers. */ #include #include "settings.h" -#define _LCR_MODULE_NAME "general" +#ifdef LCR_MODULE_NAME + #undef LCR_MODULE_NAME +#endif + +#define LCR_MODULE_NAME "general" ///< Used by logging functions. #ifndef LCR_LOG0 #define LCR_LOG0(s) ; @@ -37,14 +44,6 @@ #define LCR_LOG2_NUM(x) ; #endif -// constants (not supposed to be changed, doing so may break stuff): - -#define LCR_EFFECTIVE_RESOLUTION_X \ - (LCR_SETTING_RESOLUTION_X / LCR_SETTING_RESOLUTION_SUBDIVIDE) - -#define LCR_EFFECTIVE_RESOLUTION_Y \ - (LCR_SETTING_RESOLUTION_Y / LCR_SETTING_RESOLUTION_SUBDIVIDE) - #if LCR_SETTING_332_COLOR #define LCR_CONVERT_COLOR(c) \ (((c & 0xe000) >> 8) | ((c & 0x0700) >> 6) | ((c & 0x001f) >> 3)) @@ -113,5 +112,5 @@ char _LCR_triangleWinding(int x0, int y0, int x1, int y1, int x2, int y2) return x0 != 0 ? (x0 > 0 ? 1 : -1) : 0; } -#undef _LCR_MODULE_NAME +#undef LCR_MODULE_NAME #endif // guard diff --git a/racing.h b/racing.h index 83ca247..bcc47a3 100644 --- a/racing.h +++ b/racing.h @@ -5,62 +5,64 @@ Licar: racing module - This implements the racing physics and logic as well as replays and other - related stuff. It's possible to use this module alone if one wants to - implement a program that doesn't need graphics, I/O etc. + This file implements the racing physics and logic as well as replays and other + stuff related to racing itself. It's possible to use this module alone if one + wants to implement a program that doesn't need graphics, I/O etc. Some comments: - - This module uses tinyphysicsengine, a small and simple physics engine that - uses "balls and springs" to model bodies (here the car) and kind of - "signed distance functions" to model environment (the map). The car is - strictly a soft body, but it's very "stiff" so that it behaves almost like - a rigid body. + + - This module uses tinyphysicsengine (TPE), a small and simple physics engine + that uses "balls and springs" to model bodies (here the car) and kind of + "signed distance functions" to model the static environment (the map). The + car is strictly a soft body, but it's very "stiff" so that it behaves almost + like a rigid body. The car body consists of 5 joints (4 wheels and the + body), the top down views looks like this: + + front + (2)---(3) r + l |\ /| i + e | (4) | g + f |/ \| h + t (0)---(1) t + rear + - Replays are internally stored as follows: the replay consists of 16 bit words representing changes in input at specific frame. In lowest 4 bits the new input state is recorded, the remaining 12 bits record physics frame offset against the previous input change. If the 12 bits don't suffice 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 + ticks), there must simply be inserted an extra word that just copies the current input state. - Replay text format: first there are two characters saying the physics engine version, then immediately the name of the map terminated by ';', then hexadecimal hash of the map follows (exactly 8 characters), then blank character follows, then achieved time as a series of decimal digits - expressing the physics frame at which the run finished, then the replay - data, i.e. the series of 16 bit words in hexadecimal, each preceded by ':'. - The events (but nothing else) may otherwise be preceeded or followed by - other characters (possible comments). All hexadecimal letters must be - lowercase. The word 00000000 may optinally be used to terminate the replay, - the rest of the string will be ignored. + expressing the physics tick at which the run finished, then the replay data, + i.e. the series of 16 bit words in hexadecimal, each preceded by ':'. The + events (but nothing else) may otherwise be preceded or followed by other + characters (possible comments). All hexadecimal letters must be lowercase. + The word 00000000 may optinally be used to terminate the replay, 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. - - The physics car body has joints numbered like this: - - front - l (2)---(3) r - e |\ /| i - f | (4) | g - t |/ \| h - (0)---(1) t - rear + 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. #define LCR_RACING_FPS 30 /**< Physics FPS, i.e. the number of physics ticks per second. */ #define LCR_RACING_TICK_MS \ (100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER)) -#define LCR_RACING_VERSION1 '0' ///< first part of physics eng. version -#define LCR_RACING_VERSION2 '0' ///< second part of physics eng. version +#define LCR_RACING_VERSION1 '0' ///< First part of physics eng. version. +#define LCR_RACING_VERSION2 '0' ///< Second part of physics eng. version. -#define LCR_GAME_UNIT 2048 ///< length of map square in LCR_GameUnits +#define LCR_GAME_UNIT 2048 ///< Length of map square in LCR_GameUnits. #define LCR_RACING_INPUT_FORW 0x01 #define LCR_RACING_INPUT_RIGHT 0x02 @@ -74,7 +76,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_RACING_EVENT_ACCELERATOR 0x0010 #define LCR_RACING_EVENT_FAN 0x0020 -#define LCR_PHYSICS_UNIT 4096 ///< len. of square for phys. engine +#define LCR_PHYSICS_UNIT 4096 ///< Len. of square for phys. engine. /* The combination of values TPE_RESHAPE_TENSION_LIMIT and TPE_RESHAPE_ITERATIONS has crucial effect on the bugginess and feel of car @@ -95,6 +97,12 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_MODULE_NAME "race" +/* + What follows are carefully chosen and tuned physics constants, don't change + them unless with a very good reason, as replay compatibility will be broken + and bugs may start to appear. If physics changes, LCR_RACING_VERSION1 and + LCR_RACING_VERSION2 must be changed to indicate the change. +*/ #define LCR_GRAVITY (LCR_PHYSICS_UNIT / 160) #define LCR_FAN_FORCE 4 #define LCR_FAN_FORCE_DECREASE 6 @@ -107,8 +115,8 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 9) #define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2) -#define LCR_CAR_STEER_SPEED 50 ///< 0 to 64, lower is faster -#define LCR_CAR_STEER_SLOWDOWN 64 ///< slows down steering at higher speeds +#define LCR_CAR_STEER_SPEED 50 ///< 0 to 64, lower is faster. +#define LCR_CAR_STEER_SLOWDOWN 64 ///< Slows down steering at higher speeds. #define LCR_CAR_ACCELERATOR_FACTOR 2 #define LCR_CAR_WHEEL_AIR_ROTATION_SPEED (LCR_GAME_UNIT / 32) @@ -121,7 +129,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_GRASS_FACTOR 5 #define LCR_CAR_DIRT_FACTOR 3 #define LCR_CAR_ICE_FACTOR 1 -#define LCR_CAR_DRIFT_FACTOR 2 ///< only affects steering friction +#define LCR_CAR_DRIFT_FACTOR 2 ///< Only affects steering friction. #define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 10) #define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 227) @@ -129,7 +137,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_JOINTS 5 #define LCR_CAR_CONNECTIONS 10 -#define LCR_REPLAY_EVENT_END 0xff ///< special event fed to replay at the end +#define LCR_REPLAY_EVENT_END 0xff ///< Special event fed to replay at the end. struct { @@ -964,7 +972,7 @@ void _LCR_racingUpdateCarPosRot(void) } /** - Initializes new run. + Initializes a new run. */ void LCR_racingRestart(uint8_t replay) { diff --git a/renderer.h b/renderer.h index 0978398..8d7df97 100644 --- a/renderer.h +++ b/renderer.h @@ -26,6 +26,12 @@ rasterized pixel. */ +#define LCR_EFFECTIVE_RESOLUTION_X \ + (LCR_SETTING_RESOLUTION_X / LCR_SETTING_RESOLUTION_SUBDIVIDE) + +#define LCR_EFFECTIVE_RESOLUTION_Y \ + (LCR_SETTING_RESOLUTION_Y / LCR_SETTING_RESOLUTION_SUBDIVIDE) + #define S3L_RESOLUTION_X LCR_EFFECTIVE_RESOLUTION_X #define S3L_RESOLUTION_Y LCR_EFFECTIVE_RESOLUTION_Y #define S3L_PIXEL_FUNCTION _LCR_pixelFunc3D diff --git a/settings.h b/settings.h index 3d564b6..dd54756 100644 --- a/settings.h +++ b/settings.h @@ -5,7 +5,7 @@ Licar: settings - Compile times settings file for all modules, values here may be changed by the + Compile time settings file for all modules, values here may be changed by the user or overriden by frontend before compilation. */