Add particles

This commit is contained in:
Miloslav Ciz 2025-04-20 19:38:13 +02:00
parent 06c1d1c42e
commit d905718bab
6 changed files with 105 additions and 51 deletions

View file

@ -1,7 +1,5 @@
=========== GENERAL ==============
- add simple particle effects for grass/dirt/drift? Can be just a few squares
animated from the projected backwheels.
- fix the ramp map again due to new physics
- keyboard ghosting is an issue, particularly when initiating drift with brake
(arrow keys must be used with S for braking for left drift to work) -- think
@ -78,6 +76,8 @@
=========== HANDLED ==============
- MAP4: one triangle in top section is missing!
- add simple particle effects for grass/dirt/drift? Can be just a few squares
animated from the projected backwheels.
- FPS logging for optim
- the pinch collision test seems to sometimes stop the car e.g. after falling
from bigger height or when running into ramp at high speed (or not?) - FIX

2
data
View file

@ -133,3 +133,5 @@ details
:+018 :f213 :!v05 :f311
#RLC1;00LC1;8bd6e314 0000475:0011:0199:0041:00a9:0051:0029:0091:0049:0041:0049:0041:0249:0091:0015:0031:0019:01a1:0049:0041:0119:0031:0069:0041:0049:0041:0059:0031:00d9:0031:00f9:0021:0155:0041:01d3:0061:0113:00f1:0043:00c1:0083:0051:0203:0021:0513:0031
#RLC1;00LC1;8bd6e314 0000455:0011:0169:0041:00a9:0031:0049:00a1:0059:0051:0059:0031:01e9:0071:0045:0039:00e1:0019:00d1:0079:0041:0049:0021:0049:0031:0039:0031:0069:0071:0029:0041:00c3:0041:00e9:0021:0145:0041:0253:01b1:00b3:0051:00a9:0071:0073:0031:00a3:0021:03b3:0031:00a9:0021:0073:0021
#RLCtiny5;00LCtiny5;5c14d8b6 0000306:00a1:0083:0041:0019:0051:0049:0041:0029:00a1:00c9:0051:0073:00e1:0019:00e1:0013:0211:0049:0051:0033:0051:0039:00c1:0023:00f1:0049:0041:0033:0071:0013:0041:0053:0061:0093:0041:0043:0041:0175:0041:00a3:0041:00b9:0021
#BLCtiny5;

14
game.h
View file

@ -1621,6 +1621,20 @@ uint8_t LCR_gameStep(uint32_t time)
uint32_t events = paused ? 0 : LCR_racingStep(input);
#if LCR_SETTING_PARTICLES
LCR_rendererSetParticles(0);
if (LCR_racingGetCarSpeedUnsigned() > 60)
{
if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_GRASS)
LCR_rendererSetParticles(0x538a);
else if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_DIRT)
LCR_rendererSetParticles(0x8c2b);
else if (LCR_racingCarIsDrifting())
LCR_rendererSetParticles(0x4208);
}
#endif
#ifdef LCR_FPS_GET_MS
LCR_game.physicsFrameMS += LCR_FPS_GET_MS - frameTime;
LCR_game.physicsFramesMeasured++;

View file

@ -127,6 +127,8 @@ struct
LCR_GameUnit carSpeeds[2]; /**< Signed speed in game units per tick (negative
if backwards) and its previous value. */
uint8_t groundMaterial; ///< Material currently under car wheels.
uint16_t crashState;
uint8_t playingReplay;
@ -154,6 +156,16 @@ TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d)
return v;
}
static inline int LCR_racingCarIsDrifting(void)
{
return LCR_racing.carDrifting;
}
static inline uint8_t LCR_racingCurrentGroundMaterial(void)
{
return LCR_racing.groundMaterial;
}
/**
Initializes replay for recording.
*/
@ -1139,11 +1151,12 @@ uint32_t LCR_racingStep(unsigned int input)
uint32_t result = 0;
TPE_Vec3 carForw, carRight, carUp, carVel;
uint8_t groundMat = LCR_BLOCK_MATERIAL_CONCRETE; // material under wheels
uint8_t onAccel = 0; // standing on accelerator?
int groundBlockIndex = -1;
TPE_Unit driftFriction = 0; // average wheel friction (absolute value)
LCR_racing.groundMaterial = LCR_BLOCK_MATERIAL_CONCRETE;
if (LCR_racing.playingReplay)
{
if (LCR_racing.tick == 0)
@ -1233,13 +1246,13 @@ uint32_t LCR_racingStep(unsigned int input)
result |= LCR_RACING_EVENT_FAN;
}
groundMat = LCR_mapBlockGetMaterial(
LCR_racing.groundMaterial = LCR_mapBlockGetMaterial(
LCR_currentMap.blocks + groundBlockIndex * LCR_BLOCK_SIZE);
}
}
LCR_racing.carBody.friction =
_LCR_applyMaterialFactor(LCR_CAR_FORWARD_FRICTION,groundMat);
_LCR_applyMaterialFactor(LCR_CAR_FORWARD_FRICTION,LCR_racing.groundMaterial);
if (onAccel)
{
@ -1309,13 +1322,15 @@ uint32_t LCR_racingStep(unsigned int input)
{
if (input & LCR_RACING_INPUT_FORW)
{
_LCR_racingWheelAccelerate(0,carForw,groundMat,onAccel);
_LCR_racingWheelAccelerate(1,carForw,groundMat,onAccel);
_LCR_racingWheelAccelerate(0,carForw,LCR_racing.groundMaterial,onAccel);
_LCR_racingWheelAccelerate(1,carForw,LCR_racing.groundMaterial,onAccel);
}
else if (input & LCR_RACING_INPUT_BACK)
{
_LCR_racingWheelAccelerate(0,TPE_vec3TimesPlain(carForw,-1),groundMat,onAccel);
_LCR_racingWheelAccelerate(1,TPE_vec3TimesPlain(carForw,-1),groundMat,onAccel);
_LCR_racingWheelAccelerate(0,TPE_vec3TimesPlain(carForw,-1),
LCR_racing.groundMaterial,onAccel);
_LCR_racingWheelAccelerate(1,TPE_vec3TimesPlain(carForw,-1),
LCR_racing.groundMaterial,onAccel);
}
}
@ -1347,7 +1362,7 @@ uint32_t LCR_racingStep(unsigned int input)
_LCR_applyMaterialFactor(
LCR_racing.carDrifting ?
(LCR_CAR_STEER_FRICTION * LCR_CAR_DRIFT_FACTOR) / 8 :
LCR_CAR_STEER_FRICTION,groundMat)) / TPE_F);
LCR_CAR_STEER_FRICTION,LCR_racing.groundMaterial)) / TPE_F);
driftFriction += TPE_vec3Len(fric);

View file

@ -112,50 +112,23 @@ struct
unsigned int flatAndTransparent; /**< If non-zero, transparent (dithered)
polygons will be drawn without texture,
with color stored in this variable. */
#if LCR_SETTING_PARTICLES
uint16_t particleColor; /**< 0x0000 means no particles active. */
#endif
} LCR_renderer;
void aaa(void)
/**
Sets particle effects drawn around wheels. The parameter says particle color,
0x0000 turns particles off.
*/
void LCR_rendererSetParticles(uint16_t color)
{
printf("BAD TRIS (%d):\n",LCR_renderer.mapModel.triangleCount);
for (int i = 0; i < LCR_renderer.mapModel.triangleCount; ++i)
{
TPE_Unit sss =
TPE_max(
TPE_abs(LCR_renderer.mapModel.vertices[
LCR_renderer.mapModel.triangles[i * 3] * 3] -
LCR_renderer.mapModel.vertices[
LCR_renderer.mapModel.triangles[i * 3 + 1] * 3]),
TPE_abs(LCR_renderer.mapModel.vertices[
LCR_renderer.mapModel.triangles[i * 3 + 1] * 3] -
LCR_renderer.mapModel.vertices[
LCR_renderer.mapModel.triangles[i * 3 + 2] * 3])
);
if (sss > LCR_RENDERER_UNIT * 2)
printf(" - %d (%d %d %d, %d %d %d, %d %d %d) %d %d %d\n",i,
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i]],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i] + 1],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i] + 2],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 1]],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 1] + 1],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 1] + 2],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 2]],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 2] + 1],
LCR_renderer.mapModel.vertices[LCR_renderer.mapModel.triangles[3 * i + 2] + 2],
LCR_renderer.mapModel.triangles[3 * i],
LCR_renderer.mapModel.triangles[3 * i + 1],
LCR_renderer.mapModel.triangles[3 * i + 2]
);
#if LCR_SETTING_PARTICLES
LCR_renderer.particleColor = color;
#else
return;
#endif
}
}
void _LCR_rendererSetModelTransform(S3L_Model3D *model,
LCR_GameUnit position[3], LCR_GameUnit rotation[3])
@ -2100,6 +2073,51 @@ void LCR_rendererDraw3D(void)
LCR_renderer.frame++;
#if LCR_SETTING_PARTICLES
if (LCR_renderer.particleColor)
{
S3L_Vec4 p, r, s;
S3L_rotationToDirections(LCR_renderer.carModel->transform.rotation,
LCR_RENDERER_UNIT / 2,&p,&r,0);
#define LCR_PARTICLE_SIZE (16 << (LCR_EFFECTIVE_RESOLUTION_X / 640))
p.w = LCR_PARTICLE_SIZE;
r.x /= 2;
r.y /= 2;
r.z /= 2;
S3L_vec3Add(&p,LCR_renderer.carModel->transform.translation);
for (int i = 0; i < 2; ++i) // for both wheels
{
S3L_vec3Add(&p,r);
S3L_project3DPointToScreen(p,LCR_renderer.scene.camera,&s);
if (s.w > 0)
for (int j = 0; j < 4; ++j) // 4 particles
{
int pSize =
((LCR_renderer.frame + 4 * j) << 2) % (2 * LCR_PARTICLE_SIZE);
LCR_rendererDrawRect(
s.x - pSize / 2 + ((j % 2) ? -1 * pSize : pSize),
s.y - pSize / 2 + ((j / 2) ? -1 * pSize : pSize),
pSize,pSize,LCR_renderer.particleColor,1);
}
r.x *= -2;
r.y *= -2;
r.z *= -2;
}
}
#undef LCR_PARTICLE_SIZE
#endif
LCR_LOG2("3D rendering (end)");
LCR_LOG2("rendering frame (end)");
}

View file

@ -221,7 +221,7 @@
#ifndef LCR_SETTING_CAR_RENDER_DISTANCE
/** Distance in blocks at which player and ghost car will be seen. */
#define LCR_SETTING_CAR_RENDER_DISTANCE 25
#define LCR_SETTING_CAR_RENDER_DISTANCE 30
#endif
#ifndef LCR_SETTING_CRASH_SOUNDS
@ -241,6 +241,11 @@
#define LCR_SETTING_CAR_TINT 0x07
#endif
#ifndef LCR_SETTING_PARTICLES
/** Can turn particle effects on/off. */
#define LCR_SETTING_PARTICLES 1
#endif
#ifndef LCR_SETTING_ONLY_SMALL_MAPS
/** Turning this on will only include the small maps in the internal data
file. This option exists for weak devices that couldn't handle big maps