diff --git a/audio.h b/audio.h index 062e9b0..4ef3828 100644 --- a/audio.h +++ b/audio.h @@ -7,11 +7,12 @@ #define LCR_SOUND_NONE 0 #define LCR_SOUND_CLICK 1 -#define LCR_SOUND_CRASH 2 -#define LCR_SOUND_ACCELERATOR 3 +#define LCR_SOUND_CRASH_SMALL 2 +#define LCR_SOUND_CRASH_BIG 3 +#define LCR_SOUND_ACCELERATOR 4 + +#define LCR_AUDIO_CRASH_LEN 2048 -#define LCR_AUDIO_MIN_RPM 128 -#define LCR_AUDIO_MAX_RPM 2048 struct { @@ -25,8 +26,6 @@ int engineIntensity; int engineOsc; int engineInc; - - } LCR_audio; void LCR_audioInit(void) @@ -53,6 +52,7 @@ void LCR_audioSetEngineIntensity(uint8_t value) void LCR_audioPlaySound(uint8_t sound) { + LCR_LOG2("playing sound"); LCR_audio.soundPlayed = sound; LCR_audio.soundPlayedSample = 0; } @@ -68,23 +68,49 @@ uint8_t LCR_audioGetNextSample(void) { unsigned char result = 128; - //if (LCR_audio.engineIntensity) - { - LCR_audio.engineOsc += - LCR_audio.engineInc ? - (((_LCR_audioNoise() % 256) < - (10 + LCR_audio.engineIntensity))) : -31; +switch (LCR_audio.soundPlayed) +{ + case LCR_SOUND_CRASH_SMALL: + result += (LCR_AUDIO_CRASH_LEN - LCR_audio.soundPlayedSample) * + (_LCR_audioNoise() / 16) / LCR_AUDIO_CRASH_LEN; - if (LCR_audio.engineInc && LCR_audio.engineOsc > - (90 + (LCR_audio.engineIntensity / 8))) - LCR_audio.engineInc = 0; - else if ((!LCR_audio.engineInc) && LCR_audio.engineOsc < 10) - LCR_audio.engineInc = 1; + if (LCR_audio.soundPlayedSample >= LCR_AUDIO_CRASH_LEN) + LCR_audio.soundPlayed = LCR_SOUND_NONE; - result += - LCR_audio.engineIntensity < 20 ? - LCR_audio.engineOsc / 2 : LCR_audio.engineOsc; - } + break; + + case LCR_SOUND_CRASH_BIG: + result += ((LCR_AUDIO_CRASH_LEN * 2) - LCR_audio.soundPlayedSample) * + (_LCR_audioNoise() / 8) / (2 * LCR_AUDIO_CRASH_LEN); + + if (LCR_audio.soundPlayedSample >= 2 * LCR_AUDIO_CRASH_LEN) + LCR_audio.soundPlayed = LCR_SOUND_NONE; + + break; + + default: + break; +} + +if (LCR_audio.soundPlayed != LCR_SOUND_NONE) + LCR_audio.soundPlayedSample++; +else +{ + LCR_audio.engineOsc += + LCR_audio.engineInc ? + (((_LCR_audioNoise() % 256) < + (10 + LCR_audio.engineIntensity))) : -31; + + if (LCR_audio.engineInc && LCR_audio.engineOsc > + (90 + (LCR_audio.engineIntensity / 8))) + LCR_audio.engineInc = 0; + else if ((!LCR_audio.engineInc) && LCR_audio.engineOsc < 10) + LCR_audio.engineInc = 1; + + result += + LCR_audio.engineIntensity < 20 ? + LCR_audio.engineOsc / 2 : LCR_audio.engineOsc; +} LCR_audio.frame++; diff --git a/frontend_sdl.c b/frontend_sdl.c index ce744d8..4388d3f 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -29,6 +29,7 @@ void audioFillCallback(void *userdata, uint8_t *s, int l) // s[i] = byte; s[i] = byte / 2 + LCR_gameGetNextAudioSample() / 2; +//s[i] = LCR_gameGetNextAudioSample(); } diff --git a/game.h b/game.h index b94a753..11ec2ef 100644 --- a/game.h +++ b/game.h @@ -146,8 +146,6 @@ struct uint32_t nextRacingTickTime; uint8_t controlMode; uint8_t debugDraw; - uint32_t runTime; - uint8_t musicVolume; } LCR_game; @@ -224,7 +222,6 @@ void LCR_gameResetRun(void) LCR_rendererSetCarTransform(carTransform,carTransform + 3); LCR_rendererCameraReset(); LCR_gameSetState(LCR_GAME_STATE_RUN_STARTING); - LCR_game.runTime = 0; } void LCR_gameStartRun(const char *mapStr) @@ -305,7 +302,17 @@ uint8_t LCR_gameStep(uint32_t time) LCR_LOG1("finished"); } - LCR_game.runTime++; + if (events & LCR_RACING_EVENT_CRASH_SMALL) + { + LCR_audioPlaySound(LCR_SOUND_CRASH_SMALL); + LCR_LOG1("crash (small)"); + } + else if (events & LCR_RACING_EVENT_CRASH_BIG) + { + LCR_audioPlaySound(LCR_SOUND_CRASH_BIG); + LCR_LOG1("crash (big)"); + } + LCR_game.nextRacingTickTime += LCR_RACING_TICK_MS; } @@ -391,7 +398,7 @@ LCR_audioSetEngineIntensity((2 * val) < 256 ? (2 * val) : 255); LCR_EFFECTIVE_RESOLUTION_Y - LCR_rendererComputeTextHeight(2) - 20,0,2); - val = ((LCR_game.runTime * LCR_RACING_TICK_MS)) / 1000; // seconds + val = LCR_racingGetRunTimeMS() / 1000; // seconds str[3] = '0' + (val % 60) / 10; str[4] = '0' + val % 10; diff --git a/racing.h b/racing.h index fb56748..ba46ed6 100644 --- a/racing.h +++ b/racing.h @@ -45,6 +45,8 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 4) #define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 200) +#define LCR_CAR_CRASH_SPEED_THRESHOLD 25 + // multipliers (in 8ths) of friction and acceleration on concrete: #define LCR_CAR_GRASS_FACTOR 5 #define LCR_CAR_DIRT_FACTOR 3 @@ -62,27 +64,35 @@ struct TPE_Connection carConnections[LCR_CAR_CONNECTIONS]; uint32_t tick; - uint8_t wheelCollisions; /**< In individual bits records for each car wheel - whether it's currently touching the ground. - Lower bits record current collisions, higher - bits the previous state (for averaging). */ + uint8_t wheelCollisions; /**< In individual bits records for each car wheel + whether it's currently touching the ground. + Lower bits record current collisions, higher + bits the previous state (for averaging). */ - TPE_Vec3 carPositions[2]; ///< Current and previous position 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 carPositions[2]; ///< Current and previous position 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_Unit fanForce; ///< Upwards acceleration caused by a fan. - LCR_GameUnit wheelAngle; ///< Current wheel angle, 0 to LCR_GAME_UNIT. - LCR_GameUnit wheelSteer; ///< Left/right steer with LCR_CAR_STEER_MAX bounds. + TPE_Unit fanForce; ///< Upwards acceleration caused by a fan. + LCR_GameUnit wheelAngle; ///< Current wheel angle, 0 to LCR_GAME_UNIT. + LCR_GameUnit wheelSteer; ///< Left/right steer, LCR_CAR_STEER_MAX bounds. - LCR_GameUnit carSpeed; /**< Signed speed in game units per tick (negative - if backwards) */ + LCR_GameUnit carSpeeds[2]; /**< Signed speed in game units per tick (negative + if backwards) and its previous value. */ // for fixing physics bugs: TPE_Vec3 carOKPositions[LCR_CAR_JOINTS]; uint8_t carNotOKCount; } LCR_racing; +/** + Gets times of the run in milliseconds. +*/ +uint32_t LCR_racingGetRunTimeMS() +{ + return LCR_racing.tick * LCR_RACING_TICK_MS; +} + TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d) { v.x /= d; v.y /= d; v.z /= d; @@ -483,13 +493,13 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) LCR_GameUnit LCR_racingGetCarSpeedUnsigned(void) { - return LCR_racing.carSpeed >= 0 ? LCR_racing.carSpeed : - (-1 * LCR_racing.carSpeed); + return LCR_racing.carSpeeds[0] >= 0 ? LCR_racing.carSpeeds[0] : + (-1 * LCR_racing.carSpeeds[0]); } LCR_GameUnit LCR_racingGetCarSpeedSigned(void) { - return LCR_racing.carSpeed; + return LCR_racing.carSpeeds[0]; } uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2, @@ -569,7 +579,8 @@ void LCR_racingRestart(void) LCR_racing.wheelAngle = 0; LCR_racing.wheelSteer = 0; - LCR_racing.carSpeed = 0; + LCR_racing.carSpeeds[0] = 0; + LCR_racing.carSpeeds[1] = 0; LCR_racing.carDrifting = 0; // make the car body: @@ -874,8 +885,8 @@ uint32_t LCR_racingStep(unsigned int input) if(!(input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK))) LCR_racing.carBody.friction *= LCR_CAR_STAND_FRICTION_MULTIPLIER; else if ( - ((input & LCR_RACING_INPUT_FORW) && (LCR_racing.carSpeed < 0)) || - ((input & LCR_RACING_INPUT_BACK) && (LCR_racing.carSpeed > 0))) + ((input & LCR_RACING_INPUT_FORW) && (LCR_racing.carSpeeds[0] < 0)) || + ((input & LCR_RACING_INPUT_BACK) && (LCR_racing.carSpeeds[0] > 0))) LCR_racing.carBody.friction *= 2 * LCR_CAR_STAND_FRICTION_MULTIPLIER; if (input) @@ -1066,11 +1077,23 @@ uint32_t LCR_racingStep(unsigned int input) TPE_worldStep(&(LCR_racing.physicsWorld)); LCR_LOG2("stepping physics engine done"); - LCR_racing.carSpeed = (TPE_vec3Len(carVel) * LCR_GAME_UNIT) + int speedDiff = LCR_racing.carSpeeds[0] - LCR_racing.carSpeeds[1]; + + LCR_racing.carSpeeds[1] = LCR_racing.carSpeeds[0]; + + LCR_racing.carSpeeds[0] = (TPE_vec3Len(carVel) * LCR_GAME_UNIT) / LCR_PHYSICS_UNIT; if (TPE_vec3Dot(carVel,carForw) < 0) - LCR_racing.carSpeed *= -1; + LCR_racing.carSpeeds[0] *= -1; + + else if (speedDiff < -1 * LCR_CAR_CRASH_SPEED_THRESHOLD) + { + result |= (speedDiff < -2 * LCR_CAR_CRASH_SPEED_THRESHOLD) ? + LCR_RACING_EVENT_CRASH_BIG : LCR_RACING_EVENT_CRASH_SMALL; + + LCR_racing.carSpeeds[1] = 0; // prevent several crash events in a row + } _LCR_racingUpdateCarPosRot();