Add new records plus comments

This commit is contained in:
Miloslav Ciz 2025-06-08 15:33:43 +02:00
parent 8d9abb6eda
commit 89da509806
8 changed files with 82 additions and 69 deletions

View file

@ -12,7 +12,6 @@ fuck issue trackers :D
- Nibble, should hopefully be powerful enough. - Nibble, should hopefully be powerful enough.
- ESPboy? - ESPboy?
- linux framebuffer? - linux framebuffer?
- press forward map??? :-D only when physics is frozen
- make some kinda repo for world record runs? how will they submit it? - make some kinda repo for world record runs? how will they submit it?
- final tests: - final tests:
- very long replay DID 1x - very long replay DID 1x
@ -23,16 +22,18 @@ fuck issue trackers :D
- different platforms - different platforms
- error handling (bad map format, bad replay format, items in data file, ...) - error handling (bad map format, bad replay format, items in data file, ...)
- valgrind, cppcheck, different compilers, optimization levels, ... - valgrind, cppcheck, different compilers, optimization levels, ...
- play replay from one platform on another - play replay from one platform on another KINDA DID
- profiling - profiling
- gigantic map that fails to fit in RAM - gigantic map that fails to fit in RAM
- replay stretching DID 1x - replay stretching DID 1x
- play all maps a lot - play all maps a lot DOING
- correct saving of replays etc. - correct saving of replays etc.
- empty and large data file - empty and large data file
- FPS on each platform - FPS on each platform
- try to use the racing module by itself - try to use the racing module by itself
- spellcheck comments - spellcheck comments
- test a map without any CPs where the car starts at finish
- just read through the code and eyeball it
=========== BUGS ================= =========== BUGS =================
@ -42,6 +43,7 @@ fuck issue trackers :D
=========== HANDLED ============== =========== HANDLED ==============
- should drifting make a sound? NO NEED - 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 - devtest map, internal camera: reversing at start makes the car face completely
downwards which bugs the camera rotation! the shadow model too 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 - particles in free camera mode are very big if far away from the car (maybe

View file

@ -5,9 +5,11 @@
Licar: assets Licar: assets
This file holds assets, resources and other bigger pieces of data that are to This file holds assets and other bigger pieces of data that are to be compiled
be compiled right into the executable. This is so that for a minimal version right into the executable. This is so that for a minimal version of the game a
of the game a filesystem is not required. 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: NOTES:
- All images are 64x64, stored in an indexed mode (8bits pery pixel), the - All images are 64x64, stored in an indexed mode (8bits pery pixel), the
@ -15,9 +17,8 @@
takes 512 bytes, then 64x64 bytes follow). takes 512 bytes, then 64x64 bytes follow).
- Each sky (background) image is composed of 4 regular images so they have - 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 higher resolution. The partial images are stored in the above format, one
sky part consists of interleaved lines, so it effectively stores a sky part consists of interlaced lines, so it effectively stores a 128x32
128x32 strip (instead of 64x64 square) -- this is convenient for drawing strip (instead of 64x64 square) -- this is convenient for drawing the sky.
the sky.
*/ */
#include "general.h" #include "general.h"
@ -64,8 +65,6 @@ static const char *LCR_texts[] =
" -M load the last map in the data file\n" \ " -M load the last map in the data file\n" \
" -R load the last replay 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[] = static const char LCR_internalDataFile[] =
{ {
// data generated by make_internal_data_file.c: // data generated by make_internal_data_file.c:

3
data
View file

@ -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 #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 #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 #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 #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 #RLCpressforw1 00'21'318;00LCpressforw1;6363b43d 0000599:0001

14
game.h
View file

@ -8,14 +8,11 @@
This file implements the backend of a complete, actually playable game with 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 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
This module (with the help of other modules) will perform all the computations module (with the help of other modules) will perform all the computations
(physics, graphics, audio, ...) and only use the frontend's quite primitive (physics, graphics, audio, ...) and only use the frontend's quite primitive
functions to actually present the results to the user. 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 UNITS: There are various kinds of units used to ensure independence of the
modules. Here is a summary: modules. Here is a summary:
@ -65,6 +62,7 @@
/* /*
FOR FRONTENDS (porting to other platforms): FOR FRONTENDS (porting to other platforms):
- Implement the frontend functions given below 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 some of the frontend funtions given below in your main program in - 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]; 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, /**< Samples, each 5 bytes: 9 bits for X and Z, 10 for Y,
4 for each rotation component. */ 4 for each rotation component. */
uint8_t stretch; /**< Stretch of the base sample step, as a bit shift uint8_t stretch; /**< Stretch of the base sample step, as a bit shift (i.e.
(i.e. 1 means the step will be 2x as long etc.). This 1 means the step will be 2x as long etc.). This is to
is to allow ghosts for even long replays. */ allow ghosts for even long replays. */
int16_t offset[3]; ///< Small correcting position offset. int16_t offset[3]; ///< Small correcting position offset.
} ghost; } ghost;
#endif #endif

View file

@ -6,12 +6,19 @@
Licar: general Licar: general
This file holds general definitions used by all modules. 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 <stdint.h> #include <stdint.h>
#include "settings.h" #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 #ifndef LCR_LOG0
#define LCR_LOG0(s) ; #define LCR_LOG0(s) ;
@ -37,14 +44,6 @@
#define LCR_LOG2_NUM(x) ; #define LCR_LOG2_NUM(x) ;
#endif #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 #if LCR_SETTING_332_COLOR
#define LCR_CONVERT_COLOR(c) \ #define LCR_CONVERT_COLOR(c) \
(((c & 0xe000) >> 8) | ((c & 0x0700) >> 6) | ((c & 0x001f) >> 3)) (((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; return x0 != 0 ? (x0 > 0 ? 1 : -1) : 0;
} }
#undef _LCR_MODULE_NAME #undef LCR_MODULE_NAME
#endif // guard #endif // guard

View file

@ -5,62 +5,64 @@
Licar: racing module Licar: racing module
This implements the racing physics and logic as well as replays and other This file 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 stuff related to racing itself. It's possible to use this module alone if one
implement a program that doesn't need graphics, I/O etc. wants to implement a program that doesn't need graphics, I/O etc.
Some comments: 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 - This module uses tinyphysicsengine (TPE), a small and simple physics engine
"signed distance functions" to model environment (the map). The car is that uses "balls and springs" to model bodies (here the car) and kind of
strictly a soft body, but it's very "stiff" so that it behaves almost like "signed distance functions" to model the static environment (the map). The
a rigid body. 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 - 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 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 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 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 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. current input state.
- 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
character follows, then achieved time as a series of decimal digits character follows, then achieved time as a series of decimal digits
expressing the physics frame at which the run finished, then the replay expressing the physics tick at which the run finished, then the replay data,
data, i.e. the series of 16 bit words in hexadecimal, each preceded by ':'. i.e. the series of 16 bit words in hexadecimal, each preceded by ':'. The
The events (but nothing else) may otherwise be preceeded or followed by events (but nothing else) may otherwise be preceded or followed by other
other characters (possible comments). All hexadecimal letters must be characters (possible comments). All hexadecimal letters must be lowercase.
lowercase. The word 00000000 may optinally be used to terminate the replay, The word 00000000 may optinally be used to terminate the replay, the rest of
the rest of the string will be ignored. the string will be ignored.
- Physics engine version: LCR_RACING_VERSION1 and LCR_RACING_VERSION2 define - Physics engine version: LCR_RACING_VERSION1 and LCR_RACING_VERSION2 define
a two-character version string of this module that determines compatibility a two-character version string of this module that determines compatibility
of replays. Whenever a change is made to this module that changes the of replays. Whenever a change is made to this module that changes the
behavior of physics, the version string must be changed because replays behavior of physics, the version string must be changed because replays will
will stop being compatible. It's still possible to make other changes to stop being compatible. It's still possible to make other changes to this
this module (such as optimizations or comments) without having to change module (such as optimizations or comments) without having to change physics
physics version. 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
*/ */
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 #define LCR_RACING_FPS 30 /**< Physics FPS, i.e. the number of
physics ticks per second. */ physics ticks per second. */
#define LCR_RACING_TICK_MS \ #define LCR_RACING_TICK_MS \
(100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER)) (100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER))
#define LCR_RACING_VERSION1 '0' ///< first 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_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_FORW 0x01
#define LCR_RACING_INPUT_RIGHT 0x02 #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_ACCELERATOR 0x0010
#define LCR_RACING_EVENT_FAN 0x0020 #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 /* The combination of values TPE_RESHAPE_TENSION_LIMIT and
TPE_RESHAPE_ITERATIONS has crucial effect on the bugginess and feel of car 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" #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_GRAVITY (LCR_PHYSICS_UNIT / 160)
#define LCR_FAN_FORCE 4 #define LCR_FAN_FORCE 4
#define LCR_FAN_FORCE_DECREASE 6 #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_ACCELERATION (LCR_PHYSICS_UNIT / 9)
#define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2) #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_SPEED 50 ///< 0 to 64, lower is faster.
#define LCR_CAR_STEER_SLOWDOWN 64 ///< slows down steering at higher speeds #define LCR_CAR_STEER_SLOWDOWN 64 ///< Slows down steering at higher speeds.
#define LCR_CAR_ACCELERATOR_FACTOR 2 #define LCR_CAR_ACCELERATOR_FACTOR 2
#define LCR_CAR_WHEEL_AIR_ROTATION_SPEED (LCR_GAME_UNIT / 32) #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_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
#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_1 (LCR_GAME_UNIT / 10)
#define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 227) #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_JOINTS 5
#define LCR_CAR_CONNECTIONS 10 #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 struct
{ {
@ -964,7 +972,7 @@ void _LCR_racingUpdateCarPosRot(void)
} }
/** /**
Initializes new run. Initializes a new run.
*/ */
void LCR_racingRestart(uint8_t replay) void LCR_racingRestart(uint8_t replay)
{ {

View file

@ -26,6 +26,12 @@
rasterized pixel. 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_X LCR_EFFECTIVE_RESOLUTION_X
#define S3L_RESOLUTION_Y LCR_EFFECTIVE_RESOLUTION_Y #define S3L_RESOLUTION_Y LCR_EFFECTIVE_RESOLUTION_Y
#define S3L_PIXEL_FUNCTION _LCR_pixelFunc3D #define S3L_PIXEL_FUNCTION _LCR_pixelFunc3D

View file

@ -5,7 +5,7 @@
Licar: settings 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. user or overriden by frontend before compilation.
*/ */