* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <glib.h>
-
#include "main_bd.h"
typedef enum _sound_flag
{
GD_SP_LOOPED = 1 << 0,
- GD_SP_FORCE = 1 << 1, /* force restart, regardless of precedence level */
+ GD_SP_FORCE = 1 << 1, // force restart, regardless of precedence level
} GdSoundFlag;
typedef struct _sound_property
{
GdSound sound;
- int channel; /* channel this sound is played on. */
- int precedence; /* greater numbers will have precedence. */
+ int channel; // channel this sound is played on.
+ int precedence; // greater numbers will have precedence.
int flags;
} SoundProperty;
static SoundProperty sound_flags[] =
{
- { 0, GD_S_NONE, 0, 0 },
-
- /* channel 1 sounds. */
- /* CHANNEL 1 SOUNDS ARE ALWAYS RESTARTED, so no need for GD_SP_FORCE flag. */
- { GD_S_STONE, 1, 10 },
- /* nut falling is relatively silent, so low precedence. */
- { GD_S_NUT, 1, 8 },
- /* higher precedence than a stone bouncing. */
- { GD_S_NUT_CRACKING, 1, 12 },
- /* sligthly lower precedence, as stones and diamonds should be "louder" */
- { GD_S_DIRT_BALL, 1, 8 },
- { GD_S_NITRO_PACK, 1, 10 },
- { GD_S_FALLING_WALL, 1, 10 },
- { GD_S_EXPANDING_WALL, 1, 10 },
- { GD_S_WALL_REAPPEARING, 1, 9 },
- { GD_S_DIAMOND_RANDOM, 1, 10 },
- { GD_S_DIAMOND_1, 1, 10 },
- { GD_S_DIAMOND_2, 1, 10 },
- { GD_S_DIAMOND_3, 1, 10 },
- { GD_S_DIAMOND_4, 1, 10 },
- { GD_S_DIAMOND_5, 1, 10 },
- { GD_S_DIAMOND_6, 1, 10 },
- { GD_S_DIAMOND_7, 1, 10 },
- { GD_S_DIAMOND_8, 1, 10 },
- /* diamond collect sound has precedence over everything. */
- { GD_S_DIAMOND_COLLECTING, 1, 100 },
-
- /* collect sounds have higher precedence than falling sounds and the like. */
- { GD_S_SKELETON_COLLECTING, 1, 100 },
- { GD_S_PNEUMATIC_COLLECTING, 1, 50 },
- { GD_S_BOMB_COLLECTING, 1, 50 },
- { GD_S_CLOCK_COLLECTING, 1, 50 },
- { GD_S_SWEET_COLLECTING, 1, 50 },
- { GD_S_KEY_COLLECTING, 1, 50 },
- { GD_S_DIAMOND_KEY_COLLECTING, 1, 50 },
- { GD_S_SLIME, 1, 5 }, /* slime has lower precedence than diamond and stone falling sounds. */
- { GD_S_LAVA, 1, 5 }, /* lava has low precedence, too. */
- { GD_S_REPLICATOR, 1, 5 },
- { GD_S_ACID_SPREADING, 1, 3 }, /* same for acid, even lower. */
- { GD_S_BLADDER_MOVING, 1, 5 }, /* same for bladder. */
- { GD_S_BLADDER_CONVERTING, 1, 8 },
- { GD_S_BLADDER_SPENDER, 1, 8 },
- { GD_S_BITER_EATING, 1, 3 }, /* very low precedence. biters tend to produce too much sound. */
-
- /* channel2 sounds. */
- { GD_S_DOOR_OPENING, 2, 10 },
- { GD_S_DIRT_WALKING, 2, 10 },
- { GD_S_EMPTY_WALKING, 2, 10 },
- { GD_S_STIRRING, 2, 10 },
- { GD_S_BOX_PUSHING, 2, 10 },
- { GD_S_TELEPORTER, 2, 10 },
- { GD_S_TIMEOUT_10, 2, 20 }, /* timeout sounds have increasing precedence so they are always started */
- { GD_S_TIMEOUT_9, 2, 21 }, /* timeout sounds are examples which do not need "force restart" flag. */
- { GD_S_TIMEOUT_8, 2, 22 },
- { GD_S_TIMEOUT_7, 2, 23 },
- { GD_S_TIMEOUT_6, 2, 24 },
- { GD_S_TIMEOUT_5, 2, 25 },
- { GD_S_TIMEOUT_4, 2, 26 },
- { GD_S_TIMEOUT_3, 2, 27 },
- { GD_S_TIMEOUT_2, 2, 28 },
- { GD_S_TIMEOUT_1, 2, 29 },
- { GD_S_TIMEOUT_0, 2, 150, GD_SP_FORCE },
- { GD_S_EXPLODING, 2, 100, GD_SP_FORCE },
- { GD_S_BOMB_EXPLODING, 2, 100, GD_SP_FORCE },
- { GD_S_GHOST_EXPLODING, 2, 100, GD_SP_FORCE },
- { GD_S_VOODOO_EXPLODING, 2, 100, GD_SP_FORCE },
- { GD_S_NITRO_PACK_EXPLODING, 2, 100, GD_SP_FORCE },
- { GD_S_BOMB_PLACING, 2, 10 },
- { GD_S_FINISHED, 2, 15, GD_SP_FORCE | GD_SP_LOOPED }, /* precedence larger than normal, but smaller than timeout sounds */
- { GD_S_SWITCH_BITER, 2, 10 },
- { GD_S_SWITCH_CREATURES, 2, 10 },
- { GD_S_SWITCH_GRAVITY, 2, 10 },
- { GD_S_SWITCH_EXPANDING, 2, 10 },
- { GD_S_SWITCH_CONVEYOR, 2, 10 },
- { GD_S_SWITCH_REPLICATOR, 2, 10 },
-
- /* channel 3 sounds. */
- { GD_S_AMOEBA, 3, 30, GD_SP_LOOPED },
- { GD_S_AMOEBA_MAGIC, 3, 40, GD_SP_LOOPED },
- { GD_S_MAGIC_WALL, 3, 35, GD_SP_LOOPED },
- { GD_S_COVERING, 3, 100, GD_SP_LOOPED },
- { GD_S_PNEUMATIC_HAMMER, 3, 50, GD_SP_LOOPED },
- { GD_S_WATER, 3, 20, GD_SP_LOOPED },
- { GD_S_CRACKING, 3, 150 },
- { GD_S_GRAVITY_CHANGING, 3, 60 },
-
- /* other sounds */
- /* the bonus life sound has nothing to do with the cave. */
- /* playing on channel 4. */
- { GD_S_BONUS_LIFE, 4, 0 },
+ { 0, GD_S_NONE, 0, 0 },
+
+ // channel 1 sounds.
+ // CHANNEL 1 SOUNDS ARE ALWAYS RESTARTED, so no need for GD_SP_FORCE flag.
+ { GD_S_STONE_PUSHING, 1, 10 },
+ { GD_S_STONE_FALLING, 1, 10 },
+ { GD_S_STONE_IMPACT, 1, 10 },
+ { GD_S_MEGA_STONE_PUSHING, 1, 10 },
+ { GD_S_MEGA_STONE_FALLING, 1, 10 },
+ { GD_S_MEGA_STONE_IMPACT, 1, 10 },
+ { GD_S_FLYING_STONE_PUSHING, 1, 10 },
+ { GD_S_FLYING_STONE_FALLING, 1, 10 },
+ { GD_S_FLYING_STONE_IMPACT, 1, 10 },
+ { GD_S_WAITING_STONE_PUSHING, 1, 10 },
+ { GD_S_CHASING_STONE_PUSHING, 1, 10 },
+ // nut falling is relatively silent, so low precedence.
+ { GD_S_NUT_PUSHING, 1, 8 },
+ { GD_S_NUT_FALLING, 1, 8 },
+ { GD_S_NUT_IMPACT, 1, 8 },
+ // higher precedence than a stone bouncing.
+ { GD_S_NUT_CRACKING, 1, 12 },
+ // sligthly lower precedence, as stones and diamonds should be "louder"
+ { GD_S_DIRT_BALL_FALLING, 1, 8 },
+ { GD_S_DIRT_BALL_IMPACT, 1, 8 },
+ { GD_S_DIRT_LOOSE_FALLING, 1, 8 },
+ { GD_S_DIRT_LOOSE_IMPACT, 1, 8 },
+ { GD_S_NITRO_PACK_PUSHING, 1, 10 },
+ { GD_S_NITRO_PACK_FALLING, 1, 10 },
+ { GD_S_NITRO_PACK_IMPACT, 1, 10 },
+ { GD_S_FALLING_WALL_FALLING, 1, 10 },
+ { GD_S_FALLING_WALL_IMPACT, 1, 10 },
+ { GD_S_EXPANDING_WALL, 1, 10 },
+ { GD_S_WALL_REAPPEARING, 1, 9 },
+ { GD_S_DIAMOND_FALLING_RANDOM, 1, 10 },
+ { GD_S_DIAMOND_FALLING_1, 1, 10 },
+ { GD_S_DIAMOND_FALLING_2, 1, 10 },
+ { GD_S_DIAMOND_FALLING_3, 1, 10 },
+ { GD_S_DIAMOND_FALLING_4, 1, 10 },
+ { GD_S_DIAMOND_FALLING_5, 1, 10 },
+ { GD_S_DIAMOND_FALLING_6, 1, 10 },
+ { GD_S_DIAMOND_FALLING_7, 1, 10 },
+ { GD_S_DIAMOND_FALLING_8, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_RANDOM, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_1, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_2, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_3, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_4, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_5, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_6, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_7, 1, 10 },
+ { GD_S_DIAMOND_IMPACT_8, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_RANDOM, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_1, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_2, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_3, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_4, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_5, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_6, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_7, 1, 10 },
+ { GD_S_FLYING_DIAMOND_FALLING_8, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_RANDOM, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_1, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_2, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_3, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_4, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_5, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_6, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_7, 1, 10 },
+ { GD_S_FLYING_DIAMOND_IMPACT_8, 1, 10 },
+ // diamond collect sound has precedence over everything.
+ { GD_S_DIAMOND_COLLECTING, 1, 100 },
+ { GD_S_FLYING_DIAMOND_COLLECTING, 1, 100 },
+
+ // collect sounds have higher precedence than falling sounds and the like.
+ { GD_S_SKELETON_COLLECTING, 1, 100 },
+ { GD_S_PNEUMATIC_COLLECTING, 1, 50 },
+ { GD_S_BOMB_COLLECTING, 1, 50 },
+ { GD_S_CLOCK_COLLECTING, 1, 50 },
+ { GD_S_SWEET_COLLECTING, 1, 50 },
+ { GD_S_KEY_COLLECTING, 1, 50 },
+ { GD_S_DIAMOND_KEY_COLLECTING, 1, 50 },
+ // slime has lower precedence than diamond and stone falling sounds.
+ { GD_S_SLIME, 1, 5 },
+ // lava has low precedence, too.
+ { GD_S_LAVA, 1, 5 },
+ { GD_S_REPLICATOR, 1, 5 },
+ // same for acid, even lower.
+ { GD_S_ACID_SPREADING, 1, 3 },
+ // same for bladder.
+ { GD_S_BLADDER_MOVING, 1, 5 },
+ { GD_S_BLADDER_PUSHING, 1, 5 },
+ { GD_S_BLADDER_CONVERTING, 1, 8 },
+ { GD_S_BLADDER_SPENDER, 1, 8 },
+ // very low precedence. biters tend to produce too much sound.
+ { GD_S_BITER_EATING, 1, 3 },
+
+ // channel2 sounds.
+ { GD_S_DOOR_OPENING, 2, 10 },
+ { GD_S_DIRT_WALKING, 2, 10 },
+ { GD_S_EMPTY_WALKING, 2, 10 },
+ { GD_S_STIRRING, 2, 10 },
+ { GD_S_BOX_PUSHING, 2, 10 },
+ { GD_S_TELEPORTER, 2, 10 },
+ // timeout sounds have increasing precedence so they are always started
+ { GD_S_TIMEOUT_10, 2, 20 },
+ // timeout sounds are examples which do not need "force restart" flag.
+ { GD_S_TIMEOUT_9, 2, 21 },
+ { GD_S_TIMEOUT_8, 2, 22 },
+ { GD_S_TIMEOUT_7, 2, 23 },
+ { GD_S_TIMEOUT_6, 2, 24 },
+ { GD_S_TIMEOUT_5, 2, 25 },
+ { GD_S_TIMEOUT_4, 2, 26 },
+ { GD_S_TIMEOUT_3, 2, 27 },
+ { GD_S_TIMEOUT_2, 2, 28 },
+ { GD_S_TIMEOUT_1, 2, 29 },
+ { GD_S_TIMEOUT_0, 2, 150, GD_SP_FORCE },
+ { GD_S_EXPLODING, 2, 100, GD_SP_FORCE },
+ { GD_S_BOMB_EXPLODING, 2, 100, GD_SP_FORCE },
+ { GD_S_GHOST_EXPLODING, 2, 100, GD_SP_FORCE },
+ { GD_S_VOODOO_EXPLODING, 2, 100, GD_SP_FORCE },
+ { GD_S_NITRO_PACK_EXPLODING, 2, 100, GD_SP_FORCE },
+ { GD_S_BOMB_PLACING, 2, 10 },
+ // precedence larger than normal, but smaller than timeout sounds
+ { GD_S_FINISHED, 2, 15, GD_SP_FORCE | GD_SP_LOOPED },
+ { GD_S_SWITCH_BITER, 2, 10 },
+ { GD_S_SWITCH_CREATURES, 2, 10 },
+ { GD_S_SWITCH_GRAVITY, 2, 10 },
+ { GD_S_SWITCH_EXPANDING, 2, 10 },
+ { GD_S_SWITCH_CONVEYOR, 2, 10 },
+ { GD_S_SWITCH_REPLICATOR, 2, 10 },
+
+ // channel 3 sounds.
+ { GD_S_AMOEBA, 3, 30, GD_SP_LOOPED },
+ { GD_S_AMOEBA_MAGIC, 3, 40, GD_SP_LOOPED },
+ { GD_S_MAGIC_WALL, 3, 35, GD_SP_LOOPED },
+ { GD_S_COVERING, 3, 100, GD_SP_LOOPED },
+ { GD_S_PNEUMATIC_HAMMER, 3, 50, GD_SP_LOOPED },
+ { GD_S_WATER, 3, 20, GD_SP_LOOPED },
+ { GD_S_CRACKING, 3, 150 },
+ { GD_S_GRAVITY_CHANGING, 3, 60 },
+
+ // other sounds
+ // the bonus life sound has nothing to do with the cave.
+ // playing on channel 4.
+ { GD_S_BONUS_LIFE, 4, 0 },
};
struct GdSoundInfo
static void play_sound(int channel, GdSound sound)
{
- /* channel 1 and channel 4 are used alternating */
- /* channel 2 and channel 5 are used alternating */
- static const GdSound diamond_sounds[] =
+ // channel 1 and channel 4 are used alternating
+ // channel 2 and channel 5 are used alternating
+ static const GdSound diamond_falling_sounds[] =
+ {
+ GD_S_DIAMOND_FALLING_1,
+ GD_S_DIAMOND_FALLING_2,
+ GD_S_DIAMOND_FALLING_3,
+ GD_S_DIAMOND_FALLING_4,
+ GD_S_DIAMOND_FALLING_5,
+ GD_S_DIAMOND_FALLING_6,
+ GD_S_DIAMOND_FALLING_7,
+ GD_S_DIAMOND_FALLING_8,
+ };
+ static const GdSound diamond_impact_sounds[] =
+ {
+ GD_S_DIAMOND_IMPACT_1,
+ GD_S_DIAMOND_IMPACT_2,
+ GD_S_DIAMOND_IMPACT_3,
+ GD_S_DIAMOND_IMPACT_4,
+ GD_S_DIAMOND_IMPACT_5,
+ GD_S_DIAMOND_IMPACT_6,
+ GD_S_DIAMOND_IMPACT_7,
+ GD_S_DIAMOND_IMPACT_8,
+ };
+ static const GdSound flying_diamond_falling_sounds[] =
+ {
+ GD_S_FLYING_DIAMOND_FALLING_1,
+ GD_S_FLYING_DIAMOND_FALLING_2,
+ GD_S_FLYING_DIAMOND_FALLING_3,
+ GD_S_FLYING_DIAMOND_FALLING_4,
+ GD_S_FLYING_DIAMOND_FALLING_5,
+ GD_S_FLYING_DIAMOND_FALLING_6,
+ GD_S_FLYING_DIAMOND_FALLING_7,
+ GD_S_FLYING_DIAMOND_FALLING_8,
+ };
+ static const GdSound flying_diamond_impact_sounds[] =
{
- GD_S_DIAMOND_1,
- GD_S_DIAMOND_2,
- GD_S_DIAMOND_3,
- GD_S_DIAMOND_4,
- GD_S_DIAMOND_5,
- GD_S_DIAMOND_6,
- GD_S_DIAMOND_7,
- GD_S_DIAMOND_8,
+ GD_S_FLYING_DIAMOND_IMPACT_1,
+ GD_S_FLYING_DIAMOND_IMPACT_2,
+ GD_S_FLYING_DIAMOND_IMPACT_3,
+ GD_S_FLYING_DIAMOND_IMPACT_4,
+ GD_S_FLYING_DIAMOND_IMPACT_5,
+ GD_S_FLYING_DIAMOND_IMPACT_6,
+ GD_S_FLYING_DIAMOND_IMPACT_7,
+ GD_S_FLYING_DIAMOND_IMPACT_8,
};
if (sound == GD_S_NONE)
return;
- /* change diamond falling random to a selected diamond falling sound. */
- if (sound == GD_S_DIAMOND_RANDOM)
- sound = diamond_sounds[g_random_int_range(0, G_N_ELEMENTS(diamond_sounds))];
+ // change diamond falling random to a selected diamond falling sound.
+ if (sound == GD_S_DIAMOND_FALLING_RANDOM)
+ sound = diamond_falling_sounds[gd_random_int_range(0, 8)];
+ else if (sound == GD_S_DIAMOND_IMPACT_RANDOM)
+ sound = diamond_impact_sounds[gd_random_int_range(0, 8)];
+ else if (sound == GD_S_FLYING_DIAMOND_FALLING_RANDOM)
+ sound = flying_diamond_falling_sounds[gd_random_int_range(0, 8)];
+ else if (sound == GD_S_FLYING_DIAMOND_IMPACT_RANDOM)
+ sound = flying_diamond_impact_sounds[gd_random_int_range(0, 8)];
- /* channel 1 may have been changed to channel 4 above. */
+ // channel 1 may have been changed to channel 4 above.
if (!gd_sound_is_looped(sound))
halt_channel(channel);
{
int i;
- /* stop all sounds. */
- for (i = 0; i < G_N_ELEMENTS(snd_playing); i++)
+ // stop all sounds.
+ for (i = 0; i < ARRAY_SIZE(snd_playing); i++)
halt_channel(i);
}
static void play_sounds(GdSound sound1, GdSound sound2, GdSound sound3)
{
- /* CHANNEL 1 is for small sounds */
+ // CHANNEL 1 is for small sounds
if (sound1 != GD_S_NONE)
{
- /* start new sound if higher or same precedence than the one currently playing */
+ // start new sound if higher or same precedence than the one currently playing
if (gd_sound_get_precedence(sound1) >= gd_sound_get_precedence(sound_playing(1)))
play_sound(1, sound1);
}
else
{
- /* only interrupt looped sounds. non-looped sounds will go away automatically. */
+ // only interrupt looped sounds. non-looped sounds will go away automatically.
if (gd_sound_is_looped(sound_playing(1)))
halt_channel(1);
}
- /* CHANNEL 2 is for walking, explosions */
- /* if no sound requested, do nothing. */
+ // CHANNEL 2 is for walking, explosions
+ // if no sound requested, do nothing.
if (sound2 != GD_S_NONE)
{
boolean play = FALSE;
- /* always start if not currently playing a sound. */
+ // always start if not currently playing a sound.
if (sound_playing(2) == GD_S_NONE ||
gd_sound_force_start(sound2) ||
gd_sound_get_precedence(sound2) > gd_sound_get_precedence(sound_playing(2)))
play = TRUE;
- /* if figured out to play: do it. */
- /* (if the requested sound is looped, this is required to continue playing it) */
+ // if figured out to play: do it.
+ // (if the requested sound is looped, this is required to continue playing it)
if (play)
play_sound(2, sound2);
}
else
{
- /* only interrupt looped sounds. non-looped sounds will go away automatically. */
+ // only interrupt looped sounds. non-looped sounds will go away automatically.
if (gd_sound_is_looped(sound_playing(2)))
halt_channel(2);
}
- /* CHANNEL 3 is for crack sound, amoeba and magic wall. */
+ // CHANNEL 3 is for crack sound, amoeba and magic wall.
if (sound3 != GD_S_NONE)
{
boolean play = TRUE;
- /* if requests a non-looped sound, play that immediately.
- that can be a crack sound, gravity change, new life, ... */
- /* do not interrupt the previous sound, if it is non-looped.
- later calls of this function will probably contain the same sound3,
- and then it will be set. */
+ // if requests a non-looped sound, play that immediately.
+ // that can be a crack sound, gravity change, new life, ...
+
+ // do not interrupt the previous sound, if it is non-looped.
+ // later calls of this function will probably contain the same sound3,
+ // and then it will be set.
if (!gd_sound_is_looped(sound_playing(3)) &&
gd_sound_is_looped(sound3) &&
sound_playing(3) != GD_S_NONE)
play = FALSE;
- /* if figured out to play: do it. */
+ // if figured out to play: do it.
if (play)
play_sound(3, sound3);
}
else
{
- /* sound3 = none, so interrupt sound requested. */
- /* only interrupt looped sounds. non-looped sounds will go away automatically. */
+ // sound3 = none, so interrupt sound requested.
+ // only interrupt looped sounds. non-looped sounds will go away automatically.
if (gd_sound_is_looped(sound_playing(3)))
halt_channel(3);
}
si->sound = sound;
}
-/* plays sound in a cave */
+// plays sound in a cave
void gd_sound_play(GdCave *cave, GdSound sound, GdElement element, int x, int y)
{
if (sound == GD_S_NONE)