static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
-#define IS_ANIMATED(g) (graphic_info[g].anim_frames > 1)
+#define IS_ANIMATED(g) (graphic_info[g].anim_frames > 1)
+#define IS_LOOP_SOUND(s) (sound_info[s].loop)
/* ------------------------------------------------------------------------- */
-/* sound definitions */
+/* definition of elements that automatically change to other elements after */
+/* a specified time, eventually calling a function when changing */
/* ------------------------------------------------------------------------- */
-#define SND_ACTION_UNKNOWN 0
-#define SND_ACTION_WAITING 1
-#define SND_ACTION_MOVING 2
-#define SND_ACTION_DIGGING 3
-#define SND_ACTION_COLLECTING 4
-#define SND_ACTION_PASSING 5
-#define SND_ACTION_IMPACT 6
-#define SND_ACTION_PUSHING 7
-#define SND_ACTION_ACTIVATING 8
-#define SND_ACTION_ACTIVE 9
-
-#define NUM_SND_ACTIONS 10
-
-static struct
-{
- char *text;
- int value;
- boolean is_loop;
-} sound_action_properties[] =
-{
- /* insert _all_ loop sound actions here */
- { ".waiting", SND_ACTION_WAITING, TRUE },
- { ".moving", SND_ACTION_MOVING, TRUE }, /* continuos moving */
- { ".active", SND_ACTION_ACTIVE, TRUE },
- { ".growing", SND_ACTION_UNKNOWN, TRUE },
- { ".attacking", SND_ACTION_UNKNOWN, TRUE },
-
- /* other (non-loop) sound actions are optional */
- { ".stepping", SND_ACTION_MOVING, FALSE }, /* discrete moving */
- { ".digging", SND_ACTION_DIGGING, FALSE },
- { ".collecting", SND_ACTION_COLLECTING, FALSE },
- { ".passing", SND_ACTION_PASSING, FALSE },
- { ".impact", SND_ACTION_IMPACT, FALSE },
- { ".pushing", SND_ACTION_PUSHING, FALSE },
- { ".activating", SND_ACTION_ACTIVATING, FALSE },
- { NULL, 0, 0 },
-};
-static int element_action_sound[MAX_NUM_ELEMENTS][NUM_SND_ACTIONS];
-static boolean is_loop_sound[NUM_SOUND_FILES];
-
-#define IS_LOOP_SOUND(x) (is_loop_sound[x])
-
-
-/* -------------------------------------------------------------------------
- definition of elements that automatically change to other elements after
- a specified time, eventually calling a function when changing
- ------------------------------------------------------------------------- */
-
/* forward declaration for changer functions */
static void InitBuggyBase(int x, int y);
static void WarnBuggyBase(int x, int y);
}
-/*
- =============================================================================
- InitGameSound()
- -----------------------------------------------------------------------------
- initialize sound effect lookup table for element actions
- =============================================================================
-*/
-
-void InitGameSound()
-{
- int sound_effect_properties[NUM_SOUND_FILES];
- int i, j;
-
-#if 0
- debug_print_timestamp(0, NULL);
-#endif
-
- /* initialize sound effect for all elements to "no sound" */
- for (i=0; i<MAX_NUM_ELEMENTS; i++)
- for (j=0; j<NUM_SND_ACTIONS; j++)
- element_action_sound[i][j] = -1;
-
- for (i=0; i<NUM_SOUND_FILES; i++)
- {
- int len_effect_text = strlen(sound_files[i].token);
-
- sound_effect_properties[i] = SND_ACTION_UNKNOWN;
- is_loop_sound[i] = FALSE;
-
- /* determine all loop sounds and identify certain sound classes */
-
- for (j=0; sound_action_properties[j].text; j++)
- {
- int len_action_text = strlen(sound_action_properties[j].text);
-
- if (len_action_text < len_effect_text &&
- strcmp(&sound_files[i].token[len_effect_text - len_action_text],
- sound_action_properties[j].text) == 0)
- {
- sound_effect_properties[i] = sound_action_properties[j].value;
-
- if (sound_action_properties[j].is_loop)
- is_loop_sound[i] = TRUE;
- }
- }
-
- /* associate elements and some selected sound actions */
-
- for (j=0; j<MAX_NUM_ELEMENTS; j++)
- {
- if (element_info[j].sound_class_name)
- {
- int len_class_text = strlen(element_info[j].sound_class_name);
-
- if (len_class_text + 1 < len_effect_text &&
- strncmp(sound_files[i].token,
- element_info[j].sound_class_name, len_class_text) == 0 &&
- sound_files[i].token[len_class_text] == '.')
- {
- int sound_action_value = sound_effect_properties[i];
-
- element_action_sound[j][sound_action_value] = i;
- }
- }
- }
- }
-
-#if 0
- debug_print_timestamp(0, "InitGameEngine");
-#endif
-
-#if 0
- /* TEST ONLY */
- {
- int element = EL_SAND;
- int sound_action = SND_ACTION_DIGGING;
- int j = 0;
-
- while (sound_action_properties[j].text)
- {
- if (sound_action_properties[j].value == sound_action)
- printf("element %d, sound action '%s' == %d\n",
- element, sound_action_properties[j].text,
- element_action_sound[element][sound_action]);
- j++;
- }
- }
-#endif
-}
-
-
/*
=============================================================================
InitGameEngine()
ExplodeField[x][y] = EX_NO_EXPLOSION;
GfxFrame[x][y] = 0;
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxAction[x][y] = ACTION_DEFAULT;
}
}
Feld[newx][newy] = EL_BLOCKED;
if (direction == MV_DOWN && CAN_FALL(element))
- GfxAction[x][y] = GFX_ACTION_FALLING;
+ GfxAction[x][y] = ACTION_FALLING;
else
- GfxAction[x][y] = GFX_ACTION_MOVING;
+ GfxAction[x][y] = ACTION_MOVING;
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
Feld[newx][newy] = EL_EMPTY;
MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
- GfxAction[oldx][oldy] = GfxAction[newx][newy] = GFX_ACTION_DEFAULT;
+ GfxAction[oldx][oldy] = GfxAction[newx][newy] = ACTION_DEFAULT;
DrawLevelField(oldx, oldy);
DrawLevelField(newx, newy);
if (checkDrawLevelGraphicAnimation(x, y, el2img(element)))
DrawDynamite(x, y);
- PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE);
+ PlaySoundLevelAction(x, y, ACTION_ACTIVE);
return;
}
if ((element == EL_BOMB ||
element == EL_SP_DISK_ORANGE ||
element == EL_DX_SUPABOMB) &&
- (lastline || object_hit)) /* element is bomb */
+ (lastline || object_hit)) /* element is bomb */
{
Bang(x, y);
return;
if (!lastline && object_hit) /* check which object was hit */
{
if (CAN_CHANGE(element) &&
- (smashed == EL_MAGIC_WALL || smashed == EL_BD_MAGIC_WALL))
+ (smashed == EL_MAGIC_WALL ||
+ smashed == EL_BD_MAGIC_WALL))
{
int xx, yy;
int activated_magic_wall =
SND_BD_MAGIC_WALL_ACTIVATING));
}
- if (IS_PLAYER(x, y+1))
+ if (IS_PLAYER(x, y + 1))
{
KillHeroUnlessProtected(x, y+1);
return;
}
else if (smashed == EL_PENGUIN)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (element == EL_BD_DIAMOND)
{
if (IS_ENEMY(smashed) && IS_BD_ELEMENT(smashed))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
}
- else if ((element == EL_SP_INFOTRON || element == EL_SP_ZONK) &&
- (smashed == EL_SP_SNIKSNAK || smashed == EL_SP_ELECTRON ||
+ else if ((element == EL_SP_INFOTRON ||
+ element == EL_SP_ZONK) &&
+ (smashed == EL_SP_SNIKSNAK ||
+ smashed == EL_SP_ELECTRON ||
smashed == EL_SP_DISK_ORANGE))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (element == EL_ROCK ||
element == EL_BD_ROCK)
{
if (IS_ENEMY(smashed) ||
- smashed == EL_BOMB || smashed == EL_SP_DISK_ORANGE ||
+ smashed == EL_BOMB ||
+ smashed == EL_SP_DISK_ORANGE ||
smashed == EL_DX_SUPABOMB ||
- smashed == EL_SATELLITE || smashed == EL_PIG ||
- smashed == EL_DRAGON || smashed == EL_MOLE)
+ smashed == EL_SATELLITE ||
+ smashed == EL_PIG ||
+ smashed == EL_DRAGON ||
+ smashed == EL_MOLE)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
- else if (!IS_MOVING(x, y+1))
+ else if (!IS_MOVING(x, y + 1))
{
- if (smashed == EL_LAMP || smashed == EL_LAMP_ACTIVE)
+ if (smashed == EL_LAMP ||
+ smashed == EL_LAMP_ACTIVE)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (smashed == EL_NUT)
/* play sound of object that hits the ground */
if (lastline || object_hit)
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_IMPACT);
+ PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
}
void TurnRound(int x, int y)
if (Stop[x][y])
return;
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxAction[x][y] = ACTION_DEFAULT;
if (CAN_FALL(element) && y < lev_fieldy - 1)
{
InitMovingField(x, y, belt_dir);
started_moving = TRUE;
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxAction[x][y] = ACTION_DEFAULT;
}
}
}
if (MovDelay[x][y]) /* element still has to wait some time */
{
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
return;
}
if (DONT_TOUCH(element))
TestIfBadThingTouchesHero(x, y);
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
return;
}
InitMovingField(x, y, MovDir[x][y]);
- PlaySoundLevelAction(x, y, SND_ACTION_MOVING);
+ PlaySoundLevelAction(x, y, ACTION_MOVING);
}
if (MovDir[x][y])
MovDelay[newx][newy] = 0;
GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxAction[x][y] = ACTION_DEFAULT;
#if 0
if (!CAN_MOVE(element))
else /* still moving on */
{
#if 0
- if (GfxAction[x][y] == GFX_ACTION_DEFAULT)
+ if (GfxAction[x][y] == ACTION_DEFAULT)
{
printf("reset GfxAction...\n");
- GfxAction[x][y] = GFX_ACTION_MOVING;
+ GfxAction[x][y] = ACTION_MOVING;
}
#endif
DrawLevelElementAnimation(x, y, element);
if (!(FrameCounter % 2))
- PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE);
+ PlaySoundLevelAction(x, y, ACTION_ACTIVE);
}
}
#endif
ChangeElement(x, y);
#if 1
+ else if (element == EL_EXPLOSION)
+ ; /* drawing of correct explosion animation is handled separately */
else if (IS_ANIMATED(graphic))
DrawLevelGraphicAnimation(x, y, graphic);
#endif
if (IS_BELT_ACTIVE(element))
- PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE);
+ PlaySoundLevelAction(x, y, ACTION_ACTIVE);
if (game.magic_wall_active)
{
case EL_SP_BUGGY_BASE:
case EL_SP_BUGGY_BASE_ACTIVATING:
RemoveField(x, y);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_DIGGING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
break;
case EL_EMERALD:
DrawText(DX_EMERALDS, DY_EMERALDS,
int2str(local_player->gems_still_needed, 3),
FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
break;
case EL_SPEED_PILL:
DrawText(DX_DYNAMITE, DY_DYNAMITE,
int2str(local_player->dynamite, 3),
FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
break;
case EL_DYNABOMB_NR:
player->push_delay_value = (element == EL_SPRING ? 0 : 2 + RND(8));
DrawLevelField(x + dx, y + dy);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
break;
case EL_GATE1:
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PASSING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PASSING);
break;
case EL_SP_PORT1_LEFT:
{
RemoveField(x, y);
Feld[x+dx][y+dy] = element;
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
}
player->push_delay_value = (element == EL_BALLOON ? 0 : 2);
return TRUE;
}
+/* ------------------------------------------------------------------------- */
+/* game sound playing functions */
+/* ------------------------------------------------------------------------- */
+
+static int *loop_sound_frame = NULL;
+static int *loop_sound_volume = NULL;
+
+void InitPlaySoundLevel()
+{
+ int num_sounds = getSoundListSize();
+
+ if (loop_sound_frame != NULL)
+ free(loop_sound_frame);
+
+ if (loop_sound_volume != NULL)
+ free(loop_sound_volume);
+
+ loop_sound_frame = checked_calloc(num_sounds * sizeof(int));
+ loop_sound_volume = checked_calloc(num_sounds * sizeof(int));
+}
+
static void PlaySoundLevel(int x, int y, int nr)
{
- static int loop_sound_frame[NUM_SOUND_FILES];
- static int loop_sound_volume[NUM_SOUND_FILES];
int sx = SCREENX(x), sy = SCREENY(y);
int volume, stereo_position;
int max_distance = 8;
static void PlaySoundLevelElementAction(int x, int y, int element,
int sound_action)
{
- int sound_effect = element_action_sound[element][sound_action];
+ int sound_effect = element_info[element].sound[sound_action];
- if (sound_effect != -1)
+ if (sound_effect != SND_UNDEFINED)
PlaySoundLevel(x, y, sound_effect);
}