diff --git a/TODO.txt b/TODO.txt index e413072..f777fc7 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 diff --git a/data b/data index 3d6513b..d6de95e 100644 --- a/data +++ b/data @@ -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; diff --git a/game.h b/game.h index b875875..bc89ed8 100644 --- a/game.h +++ b/game.h @@ -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++; diff --git a/racing.h b/racing.h index bf0580a..947546f 100644 --- a/racing.h +++ b/racing.h @@ -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,10 +1151,11 @@ 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) { @@ -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); diff --git a/renderer.h b/renderer.h index eef6a74..a9c28d2 100644 --- a/renderer.h +++ b/renderer.h @@ -112,51 +112,24 @@ 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)"); } diff --git a/settings.h b/settings.h index 95d6dbb..39cdf70 100644 --- a/settings.h +++ b/settings.h @@ -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