X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=f84bb354c21a94d17961603dc24f6b7c7afb7e18;hb=ff2510f5098b545a03965c6b95296eec6885a4fb;hp=901a7fcf427d8f7d75c4d9adba0b226a486cc553;hpb=38c26472a6e9f0f037ddfe535d3919c00772b26f;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 901a7fcf..f84bb354 100644 --- a/src/game.c +++ b/src/game.c @@ -89,6 +89,8 @@ #define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value)) #define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value)) +#define INIT_GFX_RANDOM() (SimpleRND(1000000)) + /* game button identifiers */ #define GAME_CTRL_ID_STOP 0 #define GAME_CTRL_ID_PAUSE 1 @@ -100,6 +102,8 @@ #define NUM_GAME_BUTTONS 6 /* forward declaration for internal use */ +static void ResetGfxAnimation(int, int); + static void InitBeltMovement(void); static void CloseAllOpenTimegates(void); static void CheckGravityMovement(struct PlayerInfo *); @@ -115,61 +119,12 @@ static void HandleGameButtons(struct GadgetInfo *); static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; -#define IS_ANIMATED(g) (new_graphic_info[g].anim_frames > 1) - /* ------------------------------------------------------------------------- */ -/* 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); @@ -207,6 +162,9 @@ static struct ChangingElementInfo changing_element_list[] = { EL_TIMEGATE_OPENING, EL_TIMEGATE_OPEN, 29, NULL, NULL, NULL }, { EL_TIMEGATE_CLOSING, EL_TIMEGATE_CLOSED, 29, NULL, NULL, NULL }, + { EL_ACID_SPLASH_LEFT, EL_EMPTY, 8, NULL, NULL, NULL }, + { EL_ACID_SPLASH_RIGHT, EL_EMPTY, 8, NULL, NULL, NULL }, + { EL_SP_BUGGY_BASE, EL_SP_BUGGY_BASE_ACTIVATING, 0, InitBuggyBase, NULL, NULL }, { EL_SP_BUGGY_BASE_ACTIVATING,EL_SP_BUGGY_BASE_ACTIVE, 0, @@ -233,60 +191,6 @@ static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS]; #define IS_AUTO_CHANGING(e) (changing_element[e].base_element != EL_UNDEFINED) - -#ifdef DEBUG -#if 0 -static unsigned int getStateCheckSum(int counter) -{ - int x, y; - unsigned int mult = 1; - unsigned int checksum = 0; - /* - static short lastFeld[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; - */ - static boolean first_game = TRUE; - - for (y=0; y ANIM_DELAY(graphic)) + GfxRandom[x][y] = INIT_GFX_RANDOM(); +} + +static void ResetGfxAnimation(int x, int y) +{ + ResetRandomAnimationValue(x, y); + + GfxFrame[x][y] = 0; + GfxAction[x][y] = ACTION_DEFAULT; + +#if 0 + if (Feld[x][y] == EL_ROCK) + printf("ResetGfxAnimation: EL_ROCK [%d, %d]\n", + JustStopped[x][y], MovDir[x][y]); +#endif +} + void InitMovingField(int x, int y, int direction) { int element = Feld[x][y]; @@ -1445,18 +1284,21 @@ void InitMovingField(int x, int y, int direction) int newy = y + (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); if (!JustStopped[x][y] || direction != MovDir[x][y]) - GfxFrame[x][y] = 0; + ResetGfxAnimation(x, y); - MovDir[x][y] = direction; - MovDir[newx][newy] = direction; + MovDir[newx][newy] = MovDir[x][y] = direction; if (Feld[newx][newy] == EL_EMPTY) 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; + + GfxFrame[newx][newy] = GfxFrame[x][y]; + GfxAction[newx][newy] = GfxAction[x][y]; + GfxRandom[newx][newy] = GfxRandom[x][y]; } void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y) @@ -1567,7 +1409,7 @@ void RemoveMovingField(int x, int 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); @@ -1597,18 +1439,16 @@ void DrawDynamite(int x, int y) void CheckDynamite(int x, int y) { - int element = Feld[x][y]; - if (MovDelay[x][y] != 0) /* dynamite is still waiting to explode */ { MovDelay[x][y]--; if (MovDelay[x][y] != 0) { - if (checkDrawLevelGraphicAnimation(x, y, el2img(element))) - DrawDynamite(x, y); + DrawDynamite(x, y); - PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE); + /* !!! correct: "PlaySoundLevelActionIfLoop" etc. !!! */ + PlaySoundLevelAction(x, y, ACTION_ACTIVE); return; } @@ -1939,27 +1779,27 @@ void Bang(int x, int y) } } -void Blurb(int x, int y) +void SplashAcid(int x, int y) { int element = Feld[x][y]; if (element != EL_ACID_SPLASH_LEFT && - element != EL_ACID_SPLASH_RIGHT) /* start */ + element != EL_ACID_SPLASH_RIGHT) { PlaySoundLevel(x, y, SND_ACID_SPLASHING); + if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) && (!IN_LEV_FIELD(x-1, y-1) || !CAN_FALL(MovingOrBlocked2Element(x-1, y-1)))) - { Feld[x-1][y] = EL_ACID_SPLASH_LEFT; - } + if (IN_LEV_FIELD(x+1, y) && IS_FREE(x+1, y) && (!IN_LEV_FIELD(x+1, y-1) || !CAN_FALL(MovingOrBlocked2Element(x+1, y-1)))) - { Feld[x+1][y] = EL_ACID_SPLASH_RIGHT; - } } + +#if 0 else /* go on */ { int graphic = (element == EL_ACID_SPLASH_LEFT ? @@ -1986,6 +1826,7 @@ void Blurb(int x, int y) } } } +#endif } static void InitBeltMovement() @@ -2018,9 +1859,9 @@ static void InitBeltMovement() int graphic = el2img(element); if (game.belt_dir[i] == MV_LEFT) - new_graphic_info[graphic].anim_mode &= ~ANIM_REVERSE; + graphic_info[graphic].anim_mode &= ~ANIM_REVERSE; else - new_graphic_info[graphic].anim_mode |= ANIM_REVERSE; + graphic_info[graphic].anim_mode |= ANIM_REVERSE; } } @@ -2102,9 +1943,9 @@ static void ToggleBeltSwitch(int x, int y) int graphic = el2img(element); if (belt_dir == MV_LEFT) - new_graphic_info[graphic].anim_mode &= ~ANIM_REVERSE; + graphic_info[graphic].anim_mode &= ~ANIM_REVERSE; else - new_graphic_info[graphic].anim_mode |= ANIM_REVERSE; + graphic_info[graphic].anim_mode |= ANIM_REVERSE; } for (yy=0; yygems_still_needed > 0 || @@ -4293,169 +4044,6 @@ void CheckExitSP(int x, int y) PlaySoundLevelNearest(x, y, SND_SP_EXIT_OPENING); } -#if 1 -void AusgangstuerOeffnen(int x, int y) -{ - int delay = 6; - - if (!MovDelay[x][y]) /* next animation frame */ - MovDelay[x][y] = 5 * delay; - - if (MovDelay[x][y]) /* wait some time before next frame */ - { - int tuer; - - MovDelay[x][y]--; - tuer = MovDelay[x][y] / delay; - - if (!(MovDelay[x][y] % delay)) - { - if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) - { - int frame = getGraphicAnimationFrame(IMG_EXIT_OPENING, - 29 - MovDelay[x][y]); - - DrawGraphic(SCREENX(x), SCREENY(y), IMG_EXIT_OPENING, frame); - } - } - - if (MovDelay[x][y]) - return; - } - - Feld[x][y] = EL_EXIT_OPEN; - DrawLevelField(x, y); -} -#endif - -#if 1 -void OpenSwitchgate(int x, int y) -{ - int delay = 6; - - if (!MovDelay[x][y]) /* next animation frame */ - MovDelay[x][y] = 5 * delay; - - if (MovDelay[x][y]) /* wait some time before next frame */ - { - MovDelay[x][y]--; - - if (!(MovDelay[x][y] % delay)) - { - if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) - { - int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_OPENING, - 29 - MovDelay[x][y]); - - DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_OPENING, frame); - } - } - - if (MovDelay[x][y]) - return; - } - - Feld[x][y] = EL_SWITCHGATE_OPEN; - DrawLevelField(x, y); -} -#endif - -#if 1 -void CloseSwitchgate(int x, int y) -{ - int delay = 6; - - if (!MovDelay[x][y]) /* next animation frame */ - MovDelay[x][y] = 5 * delay; - - if (MovDelay[x][y]) /* wait some time before next frame */ - { - MovDelay[x][y]--; - - if (!(MovDelay[x][y] % delay)) - { - if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) - { - int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_CLOSING, - 29 - MovDelay[x][y]); - - DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_CLOSING, frame); - } - } - - if (MovDelay[x][y]) - return; - } - - Feld[x][y] = EL_SWITCHGATE_CLOSED; - DrawLevelField(x, y); -} -#endif - -#if 1 -void OpenTimegate(int x, int y) -{ - int delay = 6; - - if (!MovDelay[x][y]) /* next animation frame */ - MovDelay[x][y] = 5 * delay; - - if (MovDelay[x][y]) /* wait some time before next frame */ - { - MovDelay[x][y]--; - - if (!(MovDelay[x][y] % delay)) - { - if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) - { - int frame = getGraphicAnimationFrame(IMG_TIMEGATE_OPENING, - 29 - MovDelay[x][y]); - - DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_OPENING, frame); - } - } - - if (MovDelay[x][y]) - return; - } - - Feld[x][y] = EL_TIMEGATE_OPEN; - DrawLevelField(x, y); -} -#endif - -#if 1 -void CloseTimegate(int x, int y) -{ - int delay = 6; - - if (!MovDelay[x][y]) /* next animation frame */ - MovDelay[x][y] = 5 * delay; - - if (MovDelay[x][y]) /* wait some time before next frame */ - { - MovDelay[x][y]--; - - if (!(MovDelay[x][y] % delay)) - { - if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) - { - int frame = getGraphicAnimationFrame(IMG_TIMEGATE_CLOSING, - 29 - MovDelay[x][y]); - - DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_CLOSING, frame); - } - } - - if (MovDelay[x][y]) - return; - } - - Feld[x][y] = EL_TIMEGATE_CLOSED; - DrawLevelField(x, y); -} -#endif - static void CloseAllOpenTimegates() { int x, y; @@ -4764,79 +4352,6 @@ static void WarnBuggyBase(int x, int y) } } -#if 1 -void CheckBuggyBase(int x, int y) -{ - int element = Feld[x][y]; - - if (element == EL_SP_BUGGY_BASE) - { - if (MovDelay[x][y] == 0) /* wait some time before activating base */ - { - GfxFrame[x][y] = 0; - - InitBuggyBase(x, y); - } - - MovDelay[x][y]--; - - if (MovDelay[x][y] != 0) - { - DrawLevelElementAnimation(x, y, element); - } - else - { - Feld[x][y] = EL_SP_BUGGY_BASE_ACTIVATING; - DrawLevelField(x, y); - } - } - else if (element == EL_SP_BUGGY_BASE_ACTIVATING) - { - if (MovDelay[x][y] == 0) /* display activation warning of buggy base */ - { - GfxFrame[x][y] = 0; - - InitBuggyBase(x, y); - } - - MovDelay[x][y]--; - - if (MovDelay[x][y] != 0) - { - DrawLevelElementAnimation(x, y, element); - } - else - { - Feld[x][y] = EL_SP_BUGGY_BASE_ACTIVE; - DrawLevelField(x, y); - } - } - else if (element == EL_SP_BUGGY_BASE_ACTIVE) - { - if (MovDelay[x][y] == 0) /* start activating buggy base */ - { - GfxFrame[x][y] = 0; - - InitBuggyBase(x, y); - } - - MovDelay[x][y]--; - - if (MovDelay[x][y] != 0) - { - DrawLevelElementAnimation(x, y, element); - - WarnBuggyBase(x, y); - } - else - { - Feld[x][y] = EL_SP_BUGGY_BASE; - DrawLevelField(x, y); - } - } -} -#endif - static void InitTrap(int x, int y) { MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND); @@ -4851,76 +4366,10 @@ static void ChangeActiveTrap(int x, int y) { int graphic = IMG_TRAP_ACTIVE; - /* if animation frame already drawn, correct crumbled sand border */ - if (IS_ANIMATED(graphic)) - if (checkDrawLevelGraphicAnimation(x, y, graphic)) - DrawCrumbledSand(SCREENX(x), SCREENY(y)); -} - -#if 1 -void CheckTrap(int x, int y) -{ - int element = Feld[x][y]; - - if (element == EL_TRAP) - { - if (MovDelay[x][y] == 0) /* wait some time before activating trap */ - MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND); - - MovDelay[x][y]--; - - if (MovDelay[x][y] != 0) - { - /* do nothing while waiting */ - } - else - { - Feld[x][y] = EL_TRAP_ACTIVE; - PlaySoundLevel(x, y, SND_TRAP_ACTIVATING); - } - } - else if (element == EL_TRAP_ACTIVE) - { - int delay = 4; - int num_frames = 8; - - if (MovDelay[x][y] == 0) /* start activating trap */ - { - MovDelay[x][y] = num_frames * delay; - GfxFrame[x][y] = 0; - } - - MovDelay[x][y]--; - - if (MovDelay[x][y] != 0) - { - if (DrawLevelElementAnimation(x, y, element)) - DrawCrumbledSand(SCREENX(x), SCREENY(y)); - } - else - { - Feld[x][y] = EL_TRAP; - DrawLevelField(x, y); - } - } -} -#endif - -#if 1 -static void DrawBeltAnimation(int x, int y, int element) -{ - int belt_nr = getBeltNrFromBeltActiveElement(element); - int belt_dir = game.belt_dir[belt_nr]; - - if (belt_dir != MV_NO_MOVING) - { - DrawLevelElementAnimation(x, y, element); - - if (!(FrameCounter % 2)) - PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE); - } + /* if new animation frame was drawn, correct crumbled sand border */ + if (IS_NEW_FRAME(GfxFrame[x][y], graphic)) + DrawCrumbledSand(SCREENX(x), SCREENY(y)); } -#endif static void ChangeElement(int x, int y) { @@ -4929,7 +4378,8 @@ static void ChangeElement(int x, int y) if (MovDelay[x][y] == 0) /* initialize element change */ { MovDelay[x][y] = changing_element[element].change_delay + 1; - GfxFrame[x][y] = 0; + + ResetGfxAnimation(x, y); if (changing_element[element].pre_change_function) changing_element[element].pre_change_function(x, y); @@ -4940,7 +4390,7 @@ static void ChangeElement(int x, int y) if (MovDelay[x][y] != 0) /* continue element change */ { if (IS_ANIMATED(el2img(element))) - DrawLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); if (changing_element[element].change_function) changing_element[element].change_function(x, y); @@ -4948,7 +4398,8 @@ static void ChangeElement(int x, int y) else /* finish element change */ { Feld[x][y] = changing_element[element].next_element; - GfxFrame[x][y] = 0; + + ResetGfxAnimation(x, y); DrawLevelField(x, y); @@ -5102,7 +4553,7 @@ void GameActions() { static unsigned long action_delay = 0; unsigned long action_delay_value; - int sieb_x = 0, sieb_y = 0; + int magic_wall_x = 0, magic_wall_y = 0; int i, x, y, element, graphic; byte *recorded_player_action; byte summarized_player_action = 0; @@ -5240,12 +4691,23 @@ void GameActions() element = Feld[x][y]; graphic = el2img(element); +#if 1 + if (graphic_info[graphic].anim_global_sync) + GfxFrame[x][y] = FrameCounter; +#endif + + if (ANIM_MODE(graphic) == ANIM_RANDOM && + IS_NEW_FRAME(GfxFrame[x][y], graphic)) + ResetRandomAnimationValue(x, y); + + SetRandomAnimationValue(x, y); + if (IS_INACTIVE(element)) { #if 1 if (IS_ANIMATED(graphic)) - DrawLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif continue; @@ -5255,18 +4717,10 @@ void GameActions() { StartMoving(x, y); -#if 1 -#if 0 - if (Feld[x][y] == EL_EMERALD && - IS_ANIMATED(graphic) && - !IS_MOVING(x, y)) - DrawLevelGraphicAnimation(x, y, graphic); -#else if (IS_ANIMATED(graphic) && - !IS_MOVING(x, y)) - DrawLevelGraphicAnimation(x, y, graphic); -#endif -#endif + !IS_MOVING(x, y) && + !Stop[x][y]) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); if (IS_GEM(element) || element == EL_SP_INFOTRON) EdelsteinFunkeln(x, y); @@ -5282,7 +4736,7 @@ void GameActions() element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY) && IS_ANIMATED(graphic)) - DrawLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif else if (IS_MOVING(x, y)) @@ -5311,9 +4765,11 @@ void GameActions() else if (element == EL_TIMEGATE_SWITCH_ACTIVE) TimegateWheel(x, y); #endif +#if 0 else if (element == EL_ACID_SPLASH_LEFT || element == EL_ACID_SPLASH_RIGHT) - Blurb(x, y); + SplashAcid(x, y); +#endif #if 0 else if (element == EL_NUT_CRACKING) NussKnacken(x, y); @@ -5361,38 +4817,30 @@ void GameActions() 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); + DrawLevelGraphicAnimationIfNeeded(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) { - boolean sieb = FALSE; int jx = local_player->jx, jy = local_player->jy; - if (element == EL_MAGIC_WALL_FULL || - element == EL_MAGIC_WALL_ACTIVE || - element == EL_MAGIC_WALL_EMPTYING) - { - SiebAktivieren(x, y, 1); - sieb = TRUE; - } - else if (element == EL_BD_MAGIC_WALL_FULL || - element == EL_BD_MAGIC_WALL_ACTIVE || - element == EL_BD_MAGIC_WALL_EMPTYING) - { - SiebAktivieren(x, y, 2); - sieb = TRUE; - } - /* play the element sound at the position nearest to the player */ - if (sieb && ABS(x-jx)+ABS(y-jy) < ABS(sieb_x-jx)+ABS(sieb_y-jy)) + if ((element == EL_MAGIC_WALL_FULL || + element == EL_MAGIC_WALL_ACTIVE || + element == EL_MAGIC_WALL_EMPTYING || + element == EL_BD_MAGIC_WALL_FULL || + element == EL_BD_MAGIC_WALL_ACTIVE || + element == EL_BD_MAGIC_WALL_EMPTYING) && + ABS(x-jx) + ABS(y-jy) < ABS(magic_wall_x-jx) + ABS(magic_wall_y-jy)) { - sieb_x = x; - sieb_y = y; + magic_wall_x = x; + magic_wall_y = y; } } } @@ -5460,14 +4908,14 @@ void GameActions() { if (!(game.magic_wall_time_left % 4)) { - int element = Feld[sieb_x][sieb_y]; + int element = Feld[magic_wall_x][magic_wall_y]; if (element == EL_BD_MAGIC_WALL_FULL || element == EL_BD_MAGIC_WALL_ACTIVE || element == EL_BD_MAGIC_WALL_EMPTYING) - PlaySoundLevel(sieb_x, sieb_y, SND_BD_MAGIC_WALL_ACTIVE); + PlaySoundLevel(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE); else - PlaySoundLevel(sieb_x, sieb_y, SND_MAGIC_WALL_ACTIVE); + PlaySoundLevel(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE); } if (game.magic_wall_time_left > 0) @@ -5716,7 +5164,7 @@ boolean MoveFigureOneStep(struct PlayerInfo *player, { if (element == EL_ACID && dx == 0 && dy == 1) { - Blurb(jx, jy); + SplashAcid(jx, jy); Feld[jx][jy] = EL_PLAYER1; InitMovingField(jx, jy, MV_DOWN); Store[jx][jy] = EL_ACID; @@ -6367,7 +5815,7 @@ int DigField(struct PlayerInfo *player, 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: @@ -6389,7 +5837,7 @@ int DigField(struct PlayerInfo *player, 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: @@ -6434,7 +5882,7 @@ int DigField(struct PlayerInfo *player, 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: @@ -6656,7 +6104,7 @@ int DigField(struct PlayerInfo *player, 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: @@ -6716,7 +6164,7 @@ int DigField(struct PlayerInfo *player, 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: @@ -6914,7 +6362,7 @@ int DigField(struct PlayerInfo *player, { 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); @@ -7002,7 +6450,8 @@ boolean PlaceBomb(struct PlayerInfo *player) Store[jx][jy] = element; MovDelay[jx][jy] = 96; - GfxFrame[jx][jy] = 0; + + ResetGfxAnimation(jx, jy); if (player->dynamite) { @@ -7036,10 +6485,29 @@ boolean PlaceBomb(struct PlayerInfo *player) 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; @@ -7100,9 +6568,9 @@ static void PlaySoundLevelAction(int x, int y, int sound_action) 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); } @@ -7249,7 +6717,7 @@ void CreateGameButtons() for (i=0; i