From a22676a142a724a5e276c6771156e7d84190a643 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 11 Feb 2024 01:30:11 +0100 Subject: [PATCH] added support for native sounds of Boulder Dash game engine --- src/conf_snd.c | 28 ++++- src/game.c | 235 +++++++++++++++++++++++++++++++++++++++- src/game_bd/import_bd.h | 4 + 3 files changed, 261 insertions(+), 6 deletions(-) diff --git a/src/conf_snd.c b/src/conf_snd.c index 64fda496..0edf6181 100644 --- a/src/conf_snd.c +++ b/src/conf_snd.c @@ -284,16 +284,42 @@ struct ConfigInfo sound_config[] = { "[mm_steel_lock].exploding", "whoosh.wav" }, { "[mm_wooden_lock].exploding", "whoosh.wav" }, - // sounds not associated to game elements (used for menu screens etc.) + + // ========================================================================== + // sound definitions not associated with game elements (menu screens etc.) + // ========================================================================== + // keyword to stop parser: "NO_MORE_ELEMENT_SOUNDS" <-- do not change! + // sounds for Boulder Dash style elements and actions + { "bd_diamond.impact.RANDOM_1", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_2", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_3", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_4", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_5", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_6", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_7", UNDEFINED_FILENAME }, + { "bd_diamond.impact.RANDOM_8", UNDEFINED_FILENAME }, + // sounds for other game actions { "game.starting", UNDEFINED_FILENAME }, { "game.leveltime_charging", "fuel.wav" }, { "game.health_charging", "warnton.wav" }, { "game.running_out_of_time", "gong.wav" }, + { "game.running_out_of_time_10", UNDEFINED_FILENAME }, + { "game.running_out_of_time_9", UNDEFINED_FILENAME }, + { "game.running_out_of_time_8", UNDEFINED_FILENAME }, + { "game.running_out_of_time_7", UNDEFINED_FILENAME }, + { "game.running_out_of_time_6", UNDEFINED_FILENAME }, + { "game.running_out_of_time_5", UNDEFINED_FILENAME }, + { "game.running_out_of_time_4", UNDEFINED_FILENAME }, + { "game.running_out_of_time_3", UNDEFINED_FILENAME }, + { "game.running_out_of_time_2", UNDEFINED_FILENAME }, + { "game.running_out_of_time_1", UNDEFINED_FILENAME }, + { "game.running_out_of_time_0", UNDEFINED_FILENAME }, { "game.leveltime_bonus", "sirr.wav" }, { "game.health_bonus", "sirr.wav" }, + { "game.timeout", UNDEFINED_FILENAME }, { "game.losing", UNDEFINED_FILENAME }, { "game.winning", UNDEFINED_FILENAME }, { "game.sokoban_solving", "buing.wav" }, diff --git a/src/game.c b/src/game.c index e6e78cbf..0dc8e067 100644 --- a/src/game.c +++ b/src/game.c @@ -15287,15 +15287,15 @@ void InitPlayLevelSound(void) loop_sound_volume = checked_calloc(num_sounds * sizeof(int)); } -static void PlayLevelSound(int x, int y, int nr) +static void PlayLevelSoundExt(int x, int y, int nr, boolean is_loop_sound) { int sx = SCREENX(x), sy = SCREENY(y); int volume, stereo_position; int max_distance = 8; - int type = (IS_LOOP_SOUND(nr) ? SND_CTRL_PLAY_LOOP : SND_CTRL_PLAY_SOUND); + int type = (is_loop_sound ? SND_CTRL_PLAY_LOOP : SND_CTRL_PLAY_SOUND); - if ((!setup.sound_simple && !IS_LOOP_SOUND(nr)) || - (!setup.sound_loops && IS_LOOP_SOUND(nr))) + if ((!setup.sound_simple && !is_loop_sound) || + (!setup.sound_loops && is_loop_sound)) return; if (!IN_LEV_FIELD(x, y) || @@ -15317,7 +15317,7 @@ static void PlayLevelSound(int x, int y, int nr) (sx + max_distance) * SOUND_MAX_LEFT2RIGHT / (SCR_FIELDX + 2 * max_distance)); - if (IS_LOOP_SOUND(nr)) + if (is_loop_sound) { /* This assures that quieter loop sounds do not overwrite louder ones, while restarting sound volume comparison with each new game frame. */ @@ -15332,6 +15332,11 @@ static void PlayLevelSound(int x, int y, int nr) PlaySoundExt(nr, volume, stereo_position, type); } +static void PlayLevelSound(int x, int y, int nr) +{ + PlayLevelSoundExt(x, y, nr, IS_LOOP_SOUND(nr)); +} + static void PlayLevelSoundNearest(int x, int y, int sound_action) { PlayLevelSound(x < LEVELX(BX1) ? LEVELX(BX1) : @@ -15420,6 +15425,226 @@ static void PlayLevelMusic(void) PlayMusicLoop(music_nr); } +static int getSoundAction_BD(int sample) +{ + switch (sample) + { + case GD_S_STONE: + case GD_S_NUT: + case GD_S_DIRT_BALL: + case GD_S_NITRO: + case GD_S_FALLING_WALL: + return ACTION_IMPACT; + + case GD_S_NUT_CRACK: + return ACTION_BREAKING; + + case GD_S_EXPANDING_WALL: + case GD_S_WALL_REAPPEAR: + case GD_S_SLIME: + case GD_S_LAVA: + case GD_S_ACID_SPREAD: + return ACTION_GROWING; + + case GD_S_DIAMOND_COLLECT: + case GD_S_SKELETON_COLLECT: + case GD_S_PNEUMATIC_COLLECT: + case GD_S_BOMB_COLLECT: + case GD_S_CLOCK_COLLECT: + case GD_S_SWEET_COLLECT: + case GD_S_KEY_COLLECT: + case GD_S_DIAMOND_KEY_COLLECT: + return ACTION_COLLECTING; + + case GD_S_BOMB_PLACE: + case GD_S_REPLICATOR: + return ACTION_DROPPING; + + case GD_S_BLADDER_MOVE: + return ACTION_MOVING; + + case GD_S_BLADDER_SPENDER: + case GD_S_BLADDER_CONVERT: + case GD_S_GRAVITY_CHANGE: + return ACTION_CHANGING; + + case GD_S_BITER_EAT: + return ACTION_EATING; + + case GD_S_DOOR_OPEN: + case GD_S_CRACK: + return ACTION_OPENING; + + case GD_S_WALK_EARTH: + return ACTION_DIGGING; + + case GD_S_WALK_EMPTY: + return ACTION_WALKING; + + case GD_S_SWITCH_BITER: + case GD_S_SWITCH_CREATURES: + case GD_S_SWITCH_GRAVITY: + case GD_S_SWITCH_EXPANDING: + case GD_S_SWITCH_CONVEYOR: + case GD_S_SWITCH_REPLICATOR: + case GD_S_STIRRING: + return ACTION_ACTIVATING; + + case GD_S_BOX_PUSH: + return ACTION_PUSHING; + + case GD_S_TELEPORTER: + return ACTION_PASSING; + + case GD_S_EXPLOSION: + case GD_S_BOMB_EXPLOSION: + case GD_S_GHOST_EXPLOSION: + case GD_S_VOODOO_EXPLOSION: + case GD_S_NITRO_EXPLOSION: + return ACTION_EXPLODING; + + case GD_S_COVER: + case GD_S_AMOEBA: + case GD_S_AMOEBA_MAGIC: + case GD_S_MAGIC_WALL: + case GD_S_PNEUMATIC_HAMMER: + case GD_S_WATER: + return ACTION_ACTIVE; + + case GD_S_DIAMOND_RANDOM: + case GD_S_DIAMOND_1: + case GD_S_DIAMOND_2: + case GD_S_DIAMOND_3: + case GD_S_DIAMOND_4: + case GD_S_DIAMOND_5: + case GD_S_DIAMOND_6: + case GD_S_DIAMOND_7: + case GD_S_DIAMOND_8: + case GD_S_TIMEOUT_0: + case GD_S_TIMEOUT_1: + case GD_S_TIMEOUT_2: + case GD_S_TIMEOUT_3: + case GD_S_TIMEOUT_4: + case GD_S_TIMEOUT_5: + case GD_S_TIMEOUT_6: + case GD_S_TIMEOUT_7: + case GD_S_TIMEOUT_8: + case GD_S_TIMEOUT_9: + case GD_S_TIMEOUT_10: + case GD_S_BONUS_LIFE: + // kludge to prevent playing as loop sound + return ACTION_OTHER; + + case GD_S_FINISHED: + return ACTION_DEFAULT; + + default: + return ACTION_DEFAULT; + } +} + +static int getSoundEffect_BD(int element_bd, int sample) +{ + int sound_action = getSoundAction_BD(sample); + int sound_effect = element_info[SND_ELEMENT(element_bd)].sound[sound_action]; + int nr; + + // standard sounds + if (sound_action != ACTION_OTHER && + sound_action != ACTION_DEFAULT) + return sound_effect; + + // special sounds + switch (sample) + { + case GD_S_DIAMOND_RANDOM: + nr = GetSimpleRandom(8); + sound_effect = SND_BD_DIAMOND_IMPACT_RANDOM_1 + nr; + break; + + case GD_S_DIAMOND_1: + case GD_S_DIAMOND_2: + case GD_S_DIAMOND_3: + case GD_S_DIAMOND_4: + case GD_S_DIAMOND_5: + case GD_S_DIAMOND_6: + case GD_S_DIAMOND_7: + case GD_S_DIAMOND_8: + nr = sample - GD_S_DIAMOND_1; + sound_effect = SND_BD_DIAMOND_IMPACT_RANDOM_1 + nr; + break; + + case GD_S_TIMEOUT_0: + case GD_S_TIMEOUT_1: + case GD_S_TIMEOUT_2: + case GD_S_TIMEOUT_3: + case GD_S_TIMEOUT_4: + case GD_S_TIMEOUT_5: + case GD_S_TIMEOUT_6: + case GD_S_TIMEOUT_7: + case GD_S_TIMEOUT_8: + case GD_S_TIMEOUT_9: + case GD_S_TIMEOUT_10: + nr = sample - GD_S_TIMEOUT_0; + sound_effect = SND_GAME_RUNNING_OUT_OF_TIME_0 + nr; + + if (getSoundInfoEntryFilename(sound_effect) == NULL && sample != GD_S_TIMEOUT_0) + sound_effect = SND_GAME_RUNNING_OUT_OF_TIME; + break; + + case GD_S_FINISHED: + sound_effect = SND_GAME_LEVELTIME_BONUS; + break; + + case GD_S_BONUS_LIFE: + sound_effect = SND_GAME_HEALTH_BONUS; + break; + + default: + sound_effect = SND_UNDEFINED; + break; + } + + return sound_effect; +} + +void PlayLevelSound_BD(int xx, int yy, int element_bd, int sample) +{ + int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int sound_effect = getSoundEffect_BD(element, sample); + int sound_action = getSoundAction_BD(sample); + boolean is_loop_sound = IS_LOOP_SOUND(sound_effect); + int offset = 0; + int x = xx - offset; + int y = yy - offset; + + if (sound_action == ACTION_OTHER) + is_loop_sound = FALSE; + + if (sound_effect != SND_UNDEFINED) + PlayLevelSoundExt(x, y, sound_effect, is_loop_sound); +} + +void StopSound_BD(int element_bd, int sample) +{ + int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int sound_effect = getSoundEffect_BD(element, sample); + + if (sound_effect != SND_UNDEFINED) + StopSound(sound_effect); +} + +boolean isSoundPlaying_BD(int element_bd, int sample) +{ + int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int sound_effect = getSoundEffect_BD(element, sample); + + if (sound_effect != SND_UNDEFINED) + return isSoundPlaying(sound_effect); + + return FALSE; +} + void PlayLevelSound_EM(int xx, int yy, int element_em, int sample) { int element = (element_em > -1 ? map_element_EM_to_RND_game(element_em) : 0); diff --git a/src/game_bd/import_bd.h b/src/game_bd/import_bd.h index 64b256c0..cccee3a4 100644 --- a/src/game_bd/import_bd.h +++ b/src/game_bd/import_bd.h @@ -22,4 +22,8 @@ // functions and definitions exported from main program to game_bd // ============================================================================ +void PlayLevelSound_BD(int, int, int, int); +void StopSound_BD(int, int); +boolean isSoundPlaying_BD(int, int); + #endif // IMPORT_BD_H -- 2.34.1