#include "audio.h" #include "raylib.h" #include "common.h" #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 // xd #endif #define SAMPLE_RATE 44100 #define DURATION 0.1 // Generate a simple sine wave tone static void play_tone(float frequency, float duration, float volume) { int sample_count = (int)(SAMPLE_RATE * duration); if (sample_count > SAMPLE_RATE) sample_count = SAMPLE_RATE; if (sample_count <= 0) return; // Allocate samples dynamically to avoid shared static buffer corruption float *samples = (float *)MemAlloc(sample_count * sizeof(float)); if (samples == NULL) return; // Generate sine wave for (int i = 0; i < sample_count; i++) { float t = (float)i / SAMPLE_RATE; samples[i] = sinf(2.0f * M_PI * frequency * t) * volume; // Apply simple envelope (fade in/out) float envelope = 1.0f; int fade_samples = SAMPLE_RATE / 20; // 50ms fade if (i < fade_samples) { envelope = (float)i / fade_samples; } else if (i > sample_count - fade_samples) { envelope = (float)(sample_count - i) / fade_samples; } samples[i] *= envelope; } // Create wave from samples Wave wave = {.frameCount = (unsigned int)sample_count, .sampleRate = SAMPLE_RATE, .sampleSize = 32, .channels = 1, .data = samples}; Sound sound = LoadSoundFromWave(wave); PlaySound(sound); UnloadSound(sound); // Free the dynamically allocated buffer MemFree(samples); } void audio_init(void) { // Initialize audio device InitAudioDevice(); } void audio_close(void) { // Close audio device CloseAudioDevice(); } void audio_play_move(void) { // Low blip for movement play_tone(200.0f, 0.05f, 0.3f); } void audio_play_attack(GameState *gs) { // Mid-range hit sound // play_tone(400.0f, 0.1f, 0.5f); int choice = GetRandomValue(1, 3); switch (choice) { case 1: PlaySound(gs->sounds.attack1); break; case 2: PlaySound(gs->sounds.attack2); break; case 3: PlaySound(gs->sounds.attack3); break; default: PlaySound(gs->sounds.attack1); break; } } void audio_play_item_pickup(GameState *gs) { // High-pitched pickup sound PlaySound(gs->sounds.pickup); } void audio_play_enemy_death(GameState *gs) { // Descending death sound play_tone(300.0f, 0.1f, 0.5f); play_tone(150.0f, 0.15f, 0.4f); } void audio_play_player_damage(GameState *gs) { // Harsh damage sound play_tone(150.0f, 0.1f, 0.6f); play_tone(100.0f, 0.1f, 0.4f); } void audio_play_stairs(GameState *gs) { // Ascending stairs sound PlaySound(gs->sounds.staircase); } void audio_play_dodge(GameState *gs) { // High-pitched whoosh // play_tone(900.0f, 0.08f, 0.3f); int choice = GetRandomValue(1, 3); switch (choice) { case 1: PlaySound(gs->sounds.dodge1); break; case 2: PlaySound(gs->sounds.dodge2); break; case 3: PlaySound(gs->sounds.dodge3); break; default: PlaySound(gs->sounds.dodge1); break; } return; } void audio_play_block(GameState *gs) { // Low-then-mid metallic clang play_tone(250.0f, 0.06f, 0.5f); play_tone(350.0f, 0.04f, 0.3f); } void audio_play_crit(GameState *gs) { // Sharp crack with high-pitched follow audio_play_attack(gs); PlaySound(gs->sounds.crit); } void audio_play_proc(void) { // Ascending two-tone proc chime play_tone(500.0f, 0.08f, 0.4f); play_tone(700.0f, 0.1f, 0.35f); }