Start engine sound

This commit is contained in:
Miloslav Ciz 2024-12-23 22:50:07 +01:00
parent d0db60c02a
commit e6c5283bf4
6 changed files with 128 additions and 3 deletions

BIN
assets/licar.mid Normal file

Binary file not shown.

BIN
assets/licar.mmpz Normal file

Binary file not shown.

82
audio.h Normal file
View file

@ -0,0 +1,82 @@
/**
audio: this file implements the audio system.
*/
#ifndef _LCR_AUDIO
#define _LCR_AUDIO
#define LCR_SOUND_NONE 0
#define LCR_SOUND_CLICK 1
#define LCR_SOUND_CRASH 2
#define LCR_SOUND_ACCELERATOR 3
#define LCR_AUDIO_MIN_RPM 128
#define LCR_AUDIO_MAX_RPM 2048
struct
{
uint32_t frame;
uint8_t soundPlayed;
uint16_t soundPlayedSample;
uint32_t noise;
int engineIntensity;
int engineOsc;
} LCR_audio;
void LCR_audioInit(void)
{
LCR_LOG0("initializing audio");
LCR_audio.frame = 0;
LCR_audio.soundPlayed = LCR_SOUND_NONE;
LCR_audio.soundPlayedSample = 0;
LCR_audio.noise = 0;
LCR_audio.engineOsc = 0;
LCR_audio.engineIntensity = 0;
}
void LCR_audioSetEngineIntensity(uint8_t value)
{
LCR_audio.engineIntensity = value;
}
void LCR_audioPlaySound(uint8_t sound)
{
LCR_audio.soundPlayed = sound;
LCR_audio.soundPlayedSample = 0;
}
uint8_t _LCR_audioNoise(void)
{
LCR_audio.noise = LCR_audio.noise * 32310901 + 37;
return LCR_audio.noise >> 16;
}
uint8_t LCR_audioGetNextSample(void)
{
unsigned char result = 128;
if (LCR_audio.engineIntensity > 5)
{
LCR_audio.engineOsc +=
((_LCR_audioNoise() % 256) <
(30 + LCR_audio.engineIntensity));
result += LCR_audio.engineOsc;
}
LCR_audio.frame++;
return result;
}
#endif // guard

View file

@ -26,7 +26,11 @@ void audioFillCallback(void *userdata, uint8_t *s, int l)
rewind(musicFile); rewind(musicFile);
} }
s[i] = byte; // s[i] = byte;
s[i] = byte / 2 + LCR_gameGetNextAudioSample() / 2;
} }
} }

38
game.h
View file

@ -42,6 +42,11 @@
- Implement the below described functions according to their description. - Implement the below described functions according to their description.
- Implement the main program and game loop. - Implement the main program and game loop.
- Call the below described functions as described. - Call the below described functions as described.
- If you want to support music, make your frontend play music from the "music"
file in assets. It is in raw format, storing 8bit unsigned samples at 8000
Hz. Use the LCR_gameGetMusicVolume to check what the music volume is. If you
don't support music, set LCR_SETTING_MUSIC to 0 in your frontend code so
that the game knows music is disabled.
*/ */
/** /**
@ -93,6 +98,16 @@ void LCR_gameEnd(void);
*/ */
uint8_t LCR_gameStep(uint32_t timeMs); uint8_t LCR_gameStep(uint32_t timeMs);
/**
Gets the current music volume;
*/
uint8_t LCR_gameGetMusicVolume(void);
/**
Gets next audio sample (unsigned 8bit samples, 8 KHz).
*/
uint8_t LCR_gameGetNextAudioSample(void);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#define LCR_LOG0(s) ; #define LCR_LOG0(s) ;
@ -133,8 +148,19 @@ struct
uint8_t debugDraw; uint8_t debugDraw;
uint8_t checkpointsTaken; uint8_t checkpointsTaken;
uint32_t runTime; uint32_t runTime;
uint8_t musicVolume;
} LCR_game; } LCR_game;
uint8_t LCR_gameGetMusicVolume(void)
{
#if LCR_SETTING_MUSIC
return LCR_game.musicVolume;
#else
return 0;
#endif
}
void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y, void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y,
uint16_t color); uint16_t color);
@ -149,6 +175,7 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y,
#include "racing.h" #include "racing.h"
#include "assets.h" #include "assets.h"
#include "renderer.h" #include "renderer.h"
#include "audio.h"
uint8_t LCR_keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states uint8_t LCR_keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
during a single frame, holds during a single frame, holds
@ -219,12 +246,12 @@ void LCR_gameInit(void)
LCR_rendererInit(); LCR_rendererInit();
LCR_racingInit(); LCR_racingInit();
LCR_audioInit();
LCR_game.musicVolume = 255;
LCR_game.nextRenderFrameTime = 0; LCR_game.nextRenderFrameTime = 0;
LCR_game.nextRacingTickTime = 0; LCR_game.nextRacingTickTime = 0;
LCR_game.controlMode = LCR_CONTROL_MODE_FREECAM; LCR_game.controlMode = LCR_CONTROL_MODE_FREECAM;
LCR_gameStartRun(LCR_maps[0]); LCR_gameStartRun(LCR_maps[0]);
} }
@ -369,6 +396,8 @@ LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT -
int val = LCR_carSpeedKMH(); int val = LCR_carSpeedKMH();
LCR_audioSetEngineIntensity(val < 256 ? val : 255);
if (val < 5) // don't show tiny oscillations when still if (val < 5) // don't show tiny oscillations when still
val = 0; val = 0;
@ -424,4 +453,9 @@ LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT -
return 1; return 1;
} }
uint8_t LCR_gameGetNextAudioSample(void)
{
return LCR_audioGetNextSample();
}
#endif // guard #endif // guard

View file

@ -172,4 +172,9 @@
#define LCR_SETTING_POTATO_GRAPHICS 0 #define LCR_SETTING_POTATO_GRAPHICS 0
#endif #endif
#ifndef LCR_SETTING_MUSIC
/** Whether to enable in game music. */
#define LCR_SETTING_MUSIC 1
#endif
#endif // guard #endif // guard