Add drifts

This commit is contained in:
Miloslav Ciz 2024-12-10 16:17:52 +01:00
parent b5cfda8253
commit c145933004
4 changed files with 58 additions and 5 deletions

View file

@ -1,5 +1,25 @@
# HIGH WORK IN PROGRESS, NOT USABLE YET
But looks nice already, feel free to experiment and have fun.
The following is a draft of readme that will eventually be published, it may contain information that is not yet true but is expected to become true once the project is finished.
# Licar # Licar
![](assets/logo.png) ![](assets/logo.png)
WIP racing game WIP racing game
**Cheating in this game is allowed.** Just drive and have fun, try to find the best solution to each map by any means you judge fun enough.
## Why This Game Is Special
- **Everything is written in KISS/suckless C99 from scratch**. The whole project, including the physics engine, rendering engine, game logic and assets embedded in source code have TODO lines of code in totas.
- It has **custom 3D physics engine** (tinyphysicsengine) written from scratch, implemented in a single header file, using no GPU or floating point.
- It has **custom 3D software rendering engine** (small3dlib) written from scratch, implemented in a single header file, using no GPU or floating point.
- It **doesn't use floating point at all**, everything is done using fixed point.
- It **doesn't have any dependency libraries, not even the C standard library**, everything is written from scratch for maximum portability. Libraries such as SDL are used for frontends, but they are never an inherent part of the project, they can be basically drop in replaced with a similar library.
- **No build system** is used, everything is in a **single compilation unit**, to build the game only a single compiler invocation is needed.
- It is **extremely portable and future proof** thanks to having no dependencies besides C99 compiler.
- It is **extremely moddable and hackable**, the code is relatively simple and well commented, written to encourage hacking. There are no obstacles such as DRM, anti-cheating, obfuscation etc.
- It is **absolute and completely public domain free software with ZERO conditions on use** under CC0, it is legally more free that most "FOSS" software, there is no copyleft or credit requirement, you can do ABSOLUTELY anything you want with the project. This is a **selfless project aiming for no benefit of the creator** (include any non-finacial benefit as well), this is made purely to bring more good to the world without gaining any advantage for self.

View file

@ -39,6 +39,8 @@
=========== HANDLED ============== =========== HANDLED ==============
- drifting: passing some upper threshold on steering force should reduce
steering friction until reaching some some lower threshold again probably
- EFFICINT MAP DRAWING: - EFFICINT MAP DRAWING:
- map will be subdivided into subblocks (probably 16x16x16 or 8x8x8), only - map will be subdivided into subblocks (probably 16x16x16 or 8x8x8), only
nearest subblocks (and possibly only those in viewing direction will be nearest subblocks (and possibly only those in viewing direction will be

4
map.h
View file

@ -95,6 +95,10 @@
#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 ''
#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

View file

@ -40,10 +40,14 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_CAR_STEER_SPEED (LCR_GAME_UNIT / 17) #define LCR_CAR_STEER_SPEED (LCR_GAME_UNIT / 17)
#define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2) #define LCR_CAR_STEER_MAX (LCR_GAME_UNIT / 2)
#define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 4)
#define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 200)
// 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
#define LCR_CAR_DRIFT_FACTOR 2 ///< only affects steering friction
#define LCR_CAR_JOINTS 5 #define LCR_CAR_JOINTS 5
#define LCR_CAR_CONNECTIONS 10 #define LCR_CAR_CONNECTIONS 10
@ -62,10 +66,10 @@ struct
TPE_Vec3 carPositions[2]; ///* Current and previous position in game units. TPE_Vec3 carPositions[2]; ///* Current and previous position in game units.
TPE_Vec3 carRotations[2]; ///* Current and previous rotation in game units. TPE_Vec3 carRotations[2]; ///* Current and previous rotation in game units.
uint8_t carDrifting; ///* Whether or not the car is currently in drift.
TPE_Vec3 carOKPositions[LCR_CAR_JOINTS];
TPE_Vec3 carOKPositions[LCR_CAR_JOINTS]; uint8_t carNotOKCount;
uint8_t carNotOKCount;
LCR_GameUnit wheelRotation; LCR_GameUnit wheelRotation;
@ -74,9 +78,9 @@ uint8_t carNotOKCount;
LCR_GameUnit carSpeed; ///* Signed speed (negative if backwards) LCR_GameUnit carSpeed; ///* Signed speed (negative if backwards)
} LCR_racing; } LCR_racing;
TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d) TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d)
{ {
v.x /= d; v.y /= d; v.z /= d; v.x /= d; v.y /= d; v.z /= d;
@ -431,6 +435,7 @@ void LCR_racingRestart(void)
LCR_racing.wheelRotation = 0; LCR_racing.wheelRotation = 0;
LCR_racing.wheelSteer = 0; LCR_racing.wheelSteer = 0;
LCR_racing.carSpeed = 0; LCR_racing.carSpeed = 0;
LCR_racing.carDrifting = 0;
LCR_racing.carPositions[0] = TPE_vec3(0,0,0); LCR_racing.carPositions[0] = TPE_vec3(0,0,0);
LCR_racing.carPositions[1] = LCR_racing.carPositions[0]; LCR_racing.carPositions[1] = LCR_racing.carPositions[0];
@ -782,6 +787,8 @@ printf("------\n");
} }
} }
TPE_Unit driftFriction = 0; // average wheel friction (absolute value)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
if (LCR_racing.wheelCollisions & (0x01 << i)) // wheel on ground? if (LCR_racing.wheelCollisions & (0x01 << i)) // wheel on ground?
{ {
@ -807,7 +814,12 @@ printf("------\n");
determined by the dot product (angle) of the axis and velocity */ determined by the dot product (angle) of the axis and velocity */
TPE_Vec3 fric = TPE_vec3Times(ja,(TPE_vec3Dot(ja,jv) * TPE_Vec3 fric = TPE_vec3Times(ja,(TPE_vec3Dot(ja,jv) *
_LCR_applyMaterialFactor(LCR_CAR_STEER_FRICTION,groundMat)) / TPE_F); _LCR_applyMaterialFactor(
LCR_racing.carDrifting ?
(LCR_CAR_STEER_FRICTION * LCR_CAR_DRIFT_FACTOR) / 8 :
LCR_CAR_STEER_FRICTION,groundMat)) / TPE_F);
driftFriction += TPE_vec3Len(fric);
jv = TPE_vec3Minus(jv,fric); // subtract the friction jv = TPE_vec3Minus(jv,fric); // subtract the friction
@ -816,6 +828,21 @@ printf("------\n");
LCR_racing.carBody.joints[i].velocity[2] = jv.z; LCR_racing.carBody.joints[i].velocity[2] = jv.z;
} }
driftFriction /= 4;
if ((!LCR_racing.carDrifting) &&
driftFriction > LCR_CAR_DRIFT_THRESHOLD_1)
{
LCR_LOG1("drift start");
LCR_racing.carDrifting = 1;
}
else if (LCR_racing.carDrifting &&
driftFriction < LCR_CAR_DRIFT_THRESHOLD_0)
{
LCR_LOG1("drift end");
LCR_racing.carDrifting = 0;
}
/* The following fixes "sticking to a wall" issue by adding a small spin /* The following fixes "sticking to a wall" issue by adding a small spin
to the car when trying to steer at very small velocity. */ to the car when trying to steer at very small velocity. */
if (steering && if (steering &&