X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=1ddc793700ca7baa57e99ad01ce242fa9fc44420;hb=92989af5d5884cbc8a1a9a62c9d05e109eaf78d0;hp=3bb6aa59dde50c6492f5a797839b4fbdbc97267e;hpb=30cc9a5cf3f338d51fd1bd45a2c3af22c416cd03;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 3bb6aa59..1ddc7937 100644 --- a/src/game.c +++ b/src/game.c @@ -182,12 +182,13 @@ static boolean CheckTriggeredElementChange(int, int, int, int); static boolean CheckElementSideChange(int, int, int, int, int, int); static boolean CheckElementChange(int, int, int, int); -static void PlaySoundLevel(int, int, int); -static void PlaySoundLevelNearest(int, int, int); -static void PlaySoundLevelAction(int, int, int); -static void PlaySoundLevelElementAction(int, int, int, int); -static void PlaySoundLevelActionIfLoop(int, int, int); -static void StopSoundLevelActionIfLoop(int, int, int); +static void PlayLevelSound(int, int, int); +static void PlayLevelSoundNearest(int, int, int); +static void PlayLevelSoundAction(int, int, int); +static void PlayLevelSoundElementAction(int, int, int, int); +static void PlayLevelSoundActionIfLoop(int, int, int); +static void StopLevelSoundActionIfLoop(int, int, int); +static void PlayLevelMusic(); static void MapGameButtons(); static void HandleGameButtons(struct GadgetInfo *); @@ -679,7 +680,7 @@ static void InitField(int x, int y, boolean init_game) case EL_PIG: case EL_DRAGON: - MovDir[x][y] = 1 << RND(4); + GfxDir[x][y] = MovDir[x][y] = 1 << RND(4); break; #if 0 @@ -1150,9 +1151,10 @@ void InitGame() ExplodeField[x][y] = EX_NO_EXPLOSION; GfxFrame[x][y] = 0; - GfxAction[x][y] = ACTION_DEFAULT; GfxRandom[x][y] = INIT_GFX_RANDOM(); GfxElement[x][y] = EL_UNDEFINED; + GfxAction[x][y] = ACTION_DEFAULT; + GfxDir[x][y] = MV_NO_MOVING; } } @@ -1448,8 +1450,9 @@ void InitGame() OpenDoor(DOOR_OPEN_ALL); PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE); + if (setup.sound_music) - PlayMusic(level_nr); + PlayLevelMusic(); KeyboardAutoRepeatOffUnlessAutoplay(); @@ -1459,6 +1462,10 @@ void InitGame() printf("Player %d %sactive.\n", i + 1, (stored_player[i].active ? "" : "not ")); } + +#if 0 + printf("::: starting game [%d]\n", FrameCounter); +#endif } void InitMovDir(int x, int y) @@ -1604,6 +1611,8 @@ void InitMovDir(int x, int y) } break; } + + GfxDir[x][y] = MovDir[x][y]; } void InitAmoebaNr(int x, int y) @@ -1710,7 +1719,7 @@ void GameWon() Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : EL_SP_EXIT_CLOSING); - PlaySoundLevelElementAction(ExitX, ExitY, element, ACTION_CLOSING); + PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); } /* Hero disappears */ @@ -1848,6 +1857,7 @@ static void ResetGfxAnimation(int x, int y) { GfxFrame[x][y] = 0; GfxAction[x][y] = ACTION_DEFAULT; + GfxDir[x][y] = MovDir[x][y]; } void InitMovingField(int x, int y, int direction) @@ -1862,6 +1872,7 @@ void InitMovingField(int x, int y, int direction) ResetGfxAnimation(x, y); MovDir[newx][newy] = MovDir[x][y] = direction; + GfxDir[x][y] = direction; if (Feld[newx][newy] == EL_EMPTY) Feld[newx][newy] = EL_BLOCKED; @@ -1872,8 +1883,9 @@ void InitMovingField(int x, int y, int direction) GfxAction[x][y] = ACTION_MOVING; GfxFrame[newx][newy] = GfxFrame[x][y]; - GfxAction[newx][newy] = GfxAction[x][y]; GfxRandom[newx][newy] = GfxRandom[x][y]; + GfxAction[newx][newy] = GfxAction[x][y]; + GfxDir[newx][newy] = GfxDir[x][y]; } void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y) @@ -1957,6 +1969,7 @@ static void RemoveField(int x, int y) GfxElement[x][y] = EL_UNDEFINED; GfxAction[x][y] = ACTION_DEFAULT; + GfxDir[x][y] = MV_NO_MOVING; } void RemoveMovingField(int x, int y) @@ -2043,14 +2056,14 @@ void CheckDynamite(int x, int y) if (MovDelay[x][y] != 0) { DrawDynamite(x, y); - PlaySoundLevelActionIfLoop(x, y, ACTION_ACTIVE); + PlayLevelSoundActionIfLoop(x, y, ACTION_ACTIVE); return; } } #if 1 - StopSoundLevelActionIfLoop(x, y, ACTION_ACTIVE); + StopLevelSoundActionIfLoop(x, y, ACTION_ACTIVE); #else if (Feld[x][y] == EL_DYNAMITE_ACTIVE || Feld[x][y] == EL_SP_DISK_RED_ACTIVE) @@ -2163,7 +2176,7 @@ void Explode(int ex, int ey, int phase, int mode) #endif if (mode == EX_NORMAL || mode == EX_CENTER) - PlaySoundLevelAction(ex, ey, ACTION_EXPLODING); + PlayLevelSoundAction(ex, ey, ACTION_EXPLODING); /* remove things displayed in background while burning dynamite */ if (Back[ex][ey] != EL_EMPTY && !IS_INDESTRUCTIBLE(Back[ex][ey])) @@ -2334,6 +2347,7 @@ void Explode(int ex, int ey, int phase, int mode) RemoveField(x, y); #else MovDir[x][y] = MovPos[x][y] = 0; + GfxDir[x][y] = MovDir[x][y]; AmoebaNr[x][y] = 0; #endif #endif @@ -2422,6 +2436,7 @@ void Explode(int ex, int ey, int phase, int mode) Back[x][y] = 0; MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; + GfxDir[x][y] = MV_NO_MOVING; ChangeDelay[x][y] = 0; ChangePage[x][y] = -1; @@ -2546,12 +2561,12 @@ void Bang(int x, int y) #if 0 #if 1 - PlaySoundLevelAction(x, y, ACTION_EXPLODING); + PlayLevelSoundAction(x, y, ACTION_EXPLODING); #else if (game.emulation == EMU_SUPAPLEX) - PlaySoundLevel(x, y, SND_SP_ELEMENT_EXPLODING); + PlayLevelSound(x, y, SND_SP_ELEMENT_EXPLODING); else - PlaySoundLevel(x, y, SND_ELEMENT_EXPLODING); + PlayLevelSound(x, y, SND_ELEMENT_EXPLODING); #endif #endif @@ -2609,7 +2624,7 @@ void SplashAcid(int x, int y) if (element != EL_ACID_SPLASH_LEFT && element != EL_ACID_SPLASH_RIGHT) { - PlaySoundLevel(x, y, SND_ACID_SPLASHING); + PlayLevelSound(x, y, SND_ACID_SPLASHING); if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) && (!IN_LEV_FIELD(x-1, y-1) || @@ -2809,9 +2824,9 @@ static void ToggleSwitchgateSwitch(int x, int y) { Feld[xx][yy] = EL_SWITCHGATE_CLOSING; #if 1 - PlaySoundLevelAction(xx, yy, ACTION_CLOSING); + PlayLevelSoundAction(xx, yy, ACTION_CLOSING); #else - PlaySoundLevel(xx, yy, SND_SWITCHGATE_CLOSING); + PlayLevelSound(xx, yy, SND_SWITCHGATE_CLOSING); #endif } else if (element == EL_SWITCHGATE_CLOSED || @@ -2819,9 +2834,9 @@ static void ToggleSwitchgateSwitch(int x, int y) { Feld[xx][yy] = EL_SWITCHGATE_OPENING; #if 1 - PlaySoundLevelAction(xx, yy, ACTION_OPENING); + PlayLevelSoundAction(xx, yy, ACTION_OPENING); #else - PlaySoundLevel(xx, yy, SND_SWITCHGATE_OPENING); + PlayLevelSound(xx, yy, SND_SWITCHGATE_OPENING); #endif } } @@ -2915,7 +2930,7 @@ static void ActivateTimegateSwitch(int x, int y) element == EL_TIMEGATE_CLOSING) { Feld[xx][yy] = EL_TIMEGATE_OPENING; - PlaySoundLevel(xx, yy, SND_TIMEGATE_OPENING); + PlayLevelSound(xx, yy, SND_TIMEGATE_OPENING); } /* @@ -3005,12 +3020,12 @@ void Impact(int x, int y) else if (impact && element == EL_PEARL) { Feld[x][y] = EL_PEARL_BREAKING; - PlaySoundLevel(x, y, SND_PEARL_BREAKING); + PlayLevelSound(x, y, SND_PEARL_BREAKING); return; } else if (impact && CheckElementChange(x, y, element, CE_IMPACT)) { - PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT); + PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT); return; } @@ -3051,7 +3066,7 @@ void Impact(int x, int y) game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND; game.magic_wall_active = TRUE; - PlaySoundLevel(x, y, (smashed == EL_MAGIC_WALL ? + PlayLevelSound(x, y, (smashed == EL_MAGIC_WALL ? SND_MAGIC_WALL_ACTIVATING : SND_BD_MAGIC_WALL_ACTIVATING)); } @@ -3115,20 +3130,20 @@ void Impact(int x, int y) else if (smashed == EL_NUT) { Feld[x][y + 1] = EL_NUT_BREAKING; - PlaySoundLevel(x, y, SND_NUT_BREAKING); + PlayLevelSound(x, y, SND_NUT_BREAKING); RaiseScoreElement(EL_NUT); return; } else if (smashed == EL_PEARL) { Feld[x][y + 1] = EL_PEARL_BREAKING; - PlaySoundLevel(x, y, SND_PEARL_BREAKING); + PlayLevelSound(x, y, SND_PEARL_BREAKING); return; } else if (smashed == EL_DIAMOND) { Feld[x][y + 1] = EL_DIAMOND_BREAKING; - PlaySoundLevel(x, y, SND_DIAMOND_BREAKING); + PlayLevelSound(x, y, SND_DIAMOND_BREAKING); return; } else if (IS_BELT_SWITCH(smashed)) @@ -3168,19 +3183,19 @@ void Impact(int x, int y) Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)) { if (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE) - PlaySoundLevel(x, y, SND_MAGIC_WALL_FILLING); + PlayLevelSound(x, y, SND_MAGIC_WALL_FILLING); else if (Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE) - PlaySoundLevel(x, y, SND_BD_MAGIC_WALL_FILLING); + PlayLevelSound(x, y, SND_BD_MAGIC_WALL_FILLING); return; } /* play sound of object that hits the ground */ if (lastline || object_hit) - PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT); + PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT); } -void TurnRound(int x, int y) +inline static void TurnRoundExt(int x, int y) { static struct { @@ -3379,6 +3394,11 @@ void TurnRound(int x, int y) int rnd_value = 24; int rnd = RND(rnd_value); +#if 0 + if (FrameCounter < 1 && x == 0 && y == 29) + printf(":2: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); +#endif + if (can_move_on && rnd > rnd_value / 8) MovDir[x][y] = old_move_dir; else if (can_turn_left && can_turn_right) @@ -3393,8 +3413,25 @@ void TurnRound(int x, int y) xx = x + move_xy[MovDir[x][y]].x; yy = y + move_xy[MovDir[x][y]].y; +#if 0 + if (FrameCounter < 1 && x == 0 && y == 29) + printf(":3: %d/%d: %d (%d/%d: %d) [%d]\n", x, y, MovDir[x][y], + xx, yy, Feld[xx][yy], + FrameCounter); +#endif + +#if 1 + if (!IN_LEV_FIELD_AND_IS_FREE(xx, yy)) + MovDir[x][y] = old_move_dir; +#else if (!IS_FREE(xx, yy)) MovDir[x][y] = old_move_dir; +#endif + +#if 0 + if (FrameCounter < 1 && x == 0 && y == 29) + printf(":4: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); +#endif MovDelay[x][y] = 0; } @@ -3720,6 +3757,32 @@ void TurnRound(int x, int y) } } +static void TurnRound(int x, int y) +{ + int direction = MovDir[x][y]; + +#if 0 + GfxDir[x][y] = MovDir[x][y]; +#endif + + TurnRoundExt(x, y); + +#if 1 + GfxDir[x][y] = MovDir[x][y]; +#endif + + if (direction != MovDir[x][y]) + GfxFrame[x][y] = 0; + +#if 1 + if (MovDelay[x][y]) + GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_BIT(direction); +#else + if (MovDelay[x][y]) + GfxAction[x][y] = ACTION_WAITING; +#endif +} + static boolean JustBeingPushed(int x, int y) { int i; @@ -3750,9 +3813,14 @@ void StartMoving(int x, int y) if (Stop[x][y]) return; +#if 1 + if (MovDelay[x][y] == 0) + GfxAction[x][y] = ACTION_DEFAULT; +#else /* !!! this should be handled more generic (not only for mole) !!! */ if (element != EL_MOLE && GfxAction[x][y] != ACTION_DIGGING) GfxAction[x][y] = ACTION_DEFAULT; +#endif if (CAN_FALL(element) && y < lev_fieldy - 1) { @@ -3771,9 +3839,9 @@ void StartMoving(int x, int y) Feld[x][y] = EL_QUICKSAND_EMPTYING; Store[x][y] = EL_ROCK; #if 1 - PlaySoundLevelAction(x, y, ACTION_EMPTYING); + PlayLevelSoundAction(x, y, ACTION_EMPTYING); #else - PlaySoundLevel(x, y, SND_QUICKSAND_EMPTYING); + PlayLevelSound(x, y, SND_QUICKSAND_EMPTYING); #endif } else if (Feld[x][y + 1] == EL_QUICKSAND_EMPTY) @@ -3793,9 +3861,9 @@ void StartMoving(int x, int y) Store[x][y + 1] = Store[x][y]; Store[x][y] = 0; #if 1 - PlaySoundLevelAction(x, y, ACTION_FILLING); + PlayLevelSoundAction(x, y, ACTION_FILLING); #else - PlaySoundLevel(x, y, SND_QUICKSAND_FILLING); + PlayLevelSound(x, y, SND_QUICKSAND_FILLING); #endif } } @@ -3808,9 +3876,9 @@ void StartMoving(int x, int y) Feld[x][y] = EL_QUICKSAND_FILLING; Store[x][y] = element; #if 1 - PlaySoundLevelAction(x, y, ACTION_FILLING); + PlayLevelSoundAction(x, y, ACTION_FILLING); #else - PlaySoundLevel(x, y, SND_QUICKSAND_FILLING); + PlayLevelSound(x, y, SND_QUICKSAND_FILLING); #endif } else if (element == EL_MAGIC_WALL_FULL) @@ -4054,6 +4122,11 @@ void StartMoving(int x, int y) #endif #endif +#if 0 + if (FrameCounter < 1 && x == 0 && y == 29) + printf(":1: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); +#endif + if (!MovDelay[x][y]) /* start new movement phase */ { /* all objects that can change their move direction after each step @@ -4068,6 +4141,11 @@ void StartMoving(int x, int y) { TurnRound(x, y); +#if 0 + if (FrameCounter < 1 && x == 0 && y == 29) + printf(":9: %d: %d [%d]\n", y, MovDir[x][y], FrameCounter); +#endif + if (MovDelay[x][y] && (element == EL_BUG || element == EL_SPACESHIP || element == EL_SP_SNIKSNAK || @@ -4096,7 +4174,13 @@ void StartMoving(int x, int y) /* !!! PLACE THIS SOMEWHERE AFTER "TurnRound()" !!! */ ResetGfxAnimation(x, y); #endif + +#if 0 + if (GfxAction[x][y] != ACTION_WAITING) + printf("::: %d: %d != ACTION_WAITING\n", element, GfxAction[x][y]); + GfxAction[x][y] = ACTION_WAITING; +#endif } if (element == EL_ROBOT || @@ -4111,7 +4195,7 @@ void StartMoving(int x, int y) #else DrawLevelElementAnimationIfNeeded(x, y, element); #endif - PlaySoundLevelAction(x, y, ACTION_WAITING); + PlayLevelSoundAction(x, y, ACTION_WAITING); } else if (element == EL_SP_ELECTRON) DrawLevelElementAnimationIfNeeded(x, y, element); @@ -4138,7 +4222,7 @@ void StartMoving(int x, int y) else DrawLevelField(x, y); - PlaySoundLevelActionIfLoop(x, y, ACTION_ATTACKING); + PlayLevelSoundActionIfLoop(x, y, ACTION_ATTACKING); for (i=1; i <= 3; i++) { @@ -4178,15 +4262,17 @@ void StartMoving(int x, int y) if (MovDelay[x][y]) /* element still has to wait some time */ { - PlaySoundLevelAction(x, y, ACTION_WAITING); + PlayLevelSoundAction(x, y, ACTION_WAITING); return; } +#if 0 /* special case of "moving" animation of waiting elements (FIX THIS !!!); for all other elements GfxAction will be set by InitMovingField() */ if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY) GfxAction[x][y] = ACTION_MOVING; +#endif } /* now make next step */ @@ -4226,7 +4312,7 @@ void StartMoving(int x, int y) Feld[x][y] = EL_EMPTY; DrawLevelField(x, y); - PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING); + PlayLevelSound(newx, newy, SND_PENGUIN_PASSING); if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy))) DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0); @@ -4242,7 +4328,7 @@ void StartMoving(int x, int y) if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING) DrawLevelField(newx, newy); else - MovDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING; } else if (!IS_FREE(newx, newy)) { @@ -4267,7 +4353,7 @@ void StartMoving(int x, int y) DrawLevelField(newx, newy); } - PlaySoundLevel(x, y, SND_PIG_DIGGING); + PlayLevelSound(x, y, SND_PIG_DIGGING); } else if (!IS_FREE(newx, newy)) { @@ -4316,7 +4402,7 @@ void StartMoving(int x, int y) else DrawLevelField(x, y); - PlaySoundLevel(x, y, SND_DRAGON_ATTACKING); + PlayLevelSound(x, y, SND_DRAGON_ATTACKING); MovDelay[x][y] = 50; @@ -4341,7 +4427,7 @@ void StartMoving(int x, int y) DrawLevelField(newx, newy); } - PlaySoundLevel(x, y, SND_YAMYAM_DIGGING); + PlayLevelSound(x, y, SND_YAMYAM_DIGGING); } else if (element == EL_DARK_YAMYAM && IN_LEV_FIELD(newx, newy) && IS_FOOD_DARK_YAMYAM(Feld[newx][newy])) @@ -4362,7 +4448,7 @@ void StartMoving(int x, int y) DrawLevelField(newx, newy); } - PlaySoundLevel(x, y, SND_DARK_YAMYAM_DIGGING); + PlayLevelSound(x, y, SND_DARK_YAMYAM_DIGGING); } else if ((element == EL_PACMAN || element == EL_MOLE) && IN_LEV_FIELD(newx, newy) && IS_AMOEBOID(Feld[newx][newy])) @@ -4378,7 +4464,7 @@ void StartMoving(int x, int y) if (element == EL_MOLE) { Feld[newx][newy] = EL_AMOEBA_SHRINKING; - PlaySoundLevel(x, y, SND_MOLE_DIGGING); + PlayLevelSound(x, y, SND_MOLE_DIGGING); ResetGfxAnimation(x, y); GfxAction[x][y] = ACTION_DIGGING; @@ -4391,7 +4477,7 @@ void StartMoving(int x, int y) { Feld[newx][newy] = EL_EMPTY; DrawLevelField(newx, newy); - PlaySoundLevel(x, y, SND_PACMAN_DIGGING); + PlayLevelSound(x, y, SND_PACMAN_DIGGING); } } else if (element == EL_MOLE && IN_LEV_FIELD(newx, newy) && @@ -4430,7 +4516,7 @@ void StartMoving(int x, int y) TestIfBadThingTouchesHero(x, y); #if 0 - PlaySoundLevelAction(x, y, ACTION_WAITING); + PlayLevelSoundAction(x, y, ACTION_WAITING); #endif return; @@ -4438,7 +4524,7 @@ void StartMoving(int x, int y) InitMovingField(x, y, MovDir[x][y]); - PlaySoundLevelAction(x, y, ACTION_MOVING); + PlayLevelSoundAction(x, y, ACTION_MOVING); } if (MovDir[x][y]) @@ -4554,8 +4640,9 @@ void ContinueMoving(int x, int y) /* copy animation control values to new field */ GfxFrame[newx][newy] = GfxFrame[x][y]; - GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */ GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */ + GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */ + GfxDir[newx][newy] = GfxDir[x][y]; /* keep element direction */ Pushed[x][y] = Pushed[newx][newy] = FALSE; @@ -4580,7 +4667,7 @@ void ContinueMoving(int x, int y) if (!CAN_MOVE(element) || (CAN_FALL(element) && direction == MV_DOWN)) - MovDir[newx][newy] = 0; + GfxDir[x][y] = MovDir[newx][newy] = 0; #endif #endif @@ -4608,7 +4695,9 @@ void ContinueMoving(int x, int y) { TestIfBadThingTouchesHero(newx, newy); TestIfBadThingTouchesFriend(newx, newy); - TestIfBadThingTouchesOtherBadThing(newx, newy); + + if (!IS_CUSTOM_ELEMENT(element)) + TestIfBadThingTouchesOtherBadThing(newx, newy); } else if (element == EL_PENGUIN) TestIfFriendTouchesBadThing(newx, newy); @@ -4740,7 +4829,7 @@ void AmoebeUmwandeln(int ax, int ay) } } } - PlaySoundLevel(ax, ay, (IS_GEM(level.amoeba_content) ? + PlayLevelSound(ax, ay, (IS_GEM(level.amoeba_content) ? SND_AMOEBA_TURNING_TO_GEM : SND_AMOEBA_TURNING_TO_ROCK)); Bang(ax, ay); @@ -4765,7 +4854,7 @@ void AmoebeUmwandeln(int ax, int ay) if (Feld[x][y] == EL_AMOEBA_TO_DIAMOND) { - PlaySoundLevel(x, y, (IS_GEM(level.amoeba_content) ? + PlayLevelSound(x, y, (IS_GEM(level.amoeba_content) ? SND_AMOEBA_TURNING_TO_GEM : SND_AMOEBA_TURNING_TO_ROCK)); Bang(x, y); @@ -4808,7 +4897,7 @@ void AmoebeUmwandelnBD(int ax, int ay, int new_element) } if (done) - PlaySoundLevel(ax, ay, (new_element == EL_BD_ROCK ? + PlayLevelSound(ax, ay, (new_element == EL_BD_ROCK ? SND_BD_AMOEBA_TURNING_TO_ROCK : SND_BD_AMOEBA_TURNING_TO_GEM)); } @@ -4825,12 +4914,12 @@ void AmoebeWaechst(int x, int y) if (DelayReached(&sound_delay, sound_delay_value)) { #if 1 - PlaySoundLevelElementAction(x, y, Store[x][y], ACTION_GROWING); + PlayLevelSoundElementAction(x, y, Store[x][y], ACTION_GROWING); #else if (Store[x][y] == EL_BD_AMOEBA) - PlaySoundLevel(x, y, SND_BD_AMOEBA_GROWING); + PlayLevelSound(x, y, SND_BD_AMOEBA_GROWING); else - PlaySoundLevel(x, y, SND_AMOEBA_GROWING); + PlayLevelSound(x, y, SND_AMOEBA_GROWING); #endif sound_delay_value = 30; } @@ -5030,9 +5119,9 @@ void AmoebeAbleger(int ax, int ay) { Feld[newax][neway] = EL_AMOEBA_DROP; /* drop left/right of amoeba */ #if 1 - PlaySoundLevelAction(newax, neway, ACTION_GROWING); + PlayLevelSoundAction(newax, neway, ACTION_GROWING); #else - PlaySoundLevel(newax, neway, SND_AMOEBA_GROWING); + PlayLevelSound(newax, neway, SND_AMOEBA_GROWING); #endif } else @@ -5121,7 +5210,7 @@ void Life(int ax, int ay) } if (changed) - PlaySoundLevel(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING : + PlayLevelSound(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING : SND_GAME_OF_LIFE_GROWING); } @@ -5132,7 +5221,7 @@ static void InitRobotWheel(int x, int y) static void RunRobotWheel(int x, int y) { - PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE); + PlayLevelSound(x, y, SND_ROBOT_WHEEL_ACTIVE); } static void StopRobotWheel(int x, int y) @@ -5148,7 +5237,7 @@ static void InitTimegateWheel(int x, int y) static void RunTimegateWheel(int x, int y) { - PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE); + PlayLevelSound(x, y, SND_TIMEGATE_SWITCH_ACTIVE); } void CheckExit(int x, int y) @@ -5171,7 +5260,7 @@ void CheckExit(int x, int y) Feld[x][y] = EL_EXIT_OPENING; - PlaySoundLevelNearest(x, y, SND_CLASS_EXIT_OPENING); + PlayLevelSoundNearest(x, y, SND_CLASS_EXIT_OPENING); } void CheckExitSP(int x, int y) @@ -5192,7 +5281,7 @@ void CheckExitSP(int x, int y) Feld[x][y] = EL_SP_EXIT_OPENING; - PlaySoundLevelNearest(x, y, SND_CLASS_SP_EXIT_OPENING); + PlayLevelSoundNearest(x, y, SND_CLASS_SP_EXIT_OPENING); } static void CloseAllOpenTimegates() @@ -5209,9 +5298,9 @@ static void CloseAllOpenTimegates() { Feld[x][y] = EL_TIMEGATE_CLOSING; #if 1 - PlaySoundLevelAction(x, y, ACTION_CLOSING); + PlayLevelSoundAction(x, y, ACTION_CLOSING); #else - PlaySoundLevel(x, y, SND_TIMEGATE_CLOSING); + PlayLevelSound(x, y, SND_TIMEGATE_CLOSING); #endif } } @@ -5273,7 +5362,7 @@ void MauerWaechst(int x, int y) if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) { - int graphic = el_dir2img(Feld[x][y], MovDir[x][y]); + int graphic = el_dir2img(Feld[x][y], GfxDir[x][y]); int frame = getGraphicAnimationFrame(graphic, 17 - MovDelay[x][y]); DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame); @@ -5304,7 +5393,7 @@ void MauerWaechst(int x, int y) Feld[x][y] = Store[x][y]; Store[x][y] = 0; - MovDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING; DrawLevelField(x, y); } } @@ -5349,7 +5438,7 @@ void MauerAbleger(int ax, int ay) { Feld[ax][ay-1] = EL_EXPANDABLE_WALL_GROWING; Store[ax][ay-1] = element; - MovDir[ax][ay-1] = MV_UP; + GfxDir[ax][ay-1] = MovDir[ax][ay-1] = MV_UP; if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay-1))) DrawGraphic(SCREENX(ax), SCREENY(ay - 1), IMG_EXPANDABLE_WALL_GROWING_UP, 0); @@ -5359,7 +5448,7 @@ void MauerAbleger(int ax, int ay) { Feld[ax][ay+1] = EL_EXPANDABLE_WALL_GROWING; Store[ax][ay+1] = element; - MovDir[ax][ay+1] = MV_DOWN; + GfxDir[ax][ay+1] = MovDir[ax][ay+1] = MV_DOWN; if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay+1))) DrawGraphic(SCREENX(ax), SCREENY(ay + 1), IMG_EXPANDABLE_WALL_GROWING_DOWN, 0); @@ -5375,7 +5464,7 @@ void MauerAbleger(int ax, int ay) { Feld[ax-1][ay] = EL_EXPANDABLE_WALL_GROWING; Store[ax-1][ay] = element; - MovDir[ax-1][ay] = MV_LEFT; + GfxDir[ax-1][ay] = MovDir[ax-1][ay] = MV_LEFT; if (IN_SCR_FIELD(SCREENX(ax-1), SCREENY(ay))) DrawGraphic(SCREENX(ax - 1), SCREENY(ay), IMG_EXPANDABLE_WALL_GROWING_LEFT, 0); @@ -5386,7 +5475,7 @@ void MauerAbleger(int ax, int ay) { Feld[ax+1][ay] = EL_EXPANDABLE_WALL_GROWING; Store[ax+1][ay] = element; - MovDir[ax+1][ay] = MV_RIGHT; + GfxDir[ax+1][ay] = MovDir[ax+1][ay] = MV_RIGHT; if (IN_SCR_FIELD(SCREENX(ax+1), SCREENY(ay))) DrawGraphic(SCREENX(ax + 1), SCREENY(ay), IMG_EXPANDABLE_WALL_GROWING_RIGHT, 0); @@ -5415,9 +5504,9 @@ void MauerAbleger(int ax, int ay) if (new_wall) #if 1 - PlaySoundLevelAction(ax, ay, ACTION_GROWING); + PlayLevelSoundAction(ax, ay, ACTION_GROWING); #else - PlaySoundLevel(ax, ay, SND_EXPANDABLE_WALL_GROWING); + PlayLevelSound(ax, ay, SND_EXPANDABLE_WALL_GROWING); #endif } @@ -5501,7 +5590,7 @@ static void WarnBuggyBase(int x, int y) if (IS_PLAYER(xx, yy)) { - PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVE); + PlayLevelSound(x, y, SND_SP_BUGGY_BASE_ACTIVE); break; } @@ -5515,7 +5604,7 @@ static void InitTrap(int x, int y) static void ActivateTrap(int x, int y) { - PlaySoundLevel(x, y, SND_TRAP_ACTIVATING); + PlayLevelSound(x, y, SND_TRAP_ACTIVATING); } static void ChangeActiveTrap(int x, int y) @@ -5672,14 +5761,14 @@ static boolean ChangeElementNow(int x, int y, int element, int page) } if (something_has_changed) - PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); } } else { ChangeElementNowExt(x, y, change->target_element); - PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); } return TRUE; @@ -5720,7 +5809,7 @@ static void ChangeElement(int x, int y, int page) if (ChangeDelay[x][y] != 0) /* continue element change */ { - int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]); + int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); if (IS_ANIMATED(graphic)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); @@ -5855,6 +5944,100 @@ static boolean CheckElementChange(int x, int y, int element, int trigger_event) return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1); } +#if 1 +static byte PlayerActions(struct PlayerInfo *player, byte player_action) +{ +#if 0 + static byte stored_player_action[MAX_PLAYERS]; + static int num_stored_actions = 0; +#endif + boolean moved = FALSE, snapped = FALSE, dropped = FALSE; + int left = player_action & JOY_LEFT; + int right = player_action & JOY_RIGHT; + int up = player_action & JOY_UP; + int down = player_action & JOY_DOWN; + int button1 = player_action & JOY_BUTTON_1; + int button2 = player_action & JOY_BUTTON_2; + int dx = (left ? -1 : right ? 1 : 0); + int dy = (up ? -1 : down ? 1 : 0); + +#if 0 + stored_player_action[player->index_nr] = 0; + num_stored_actions++; +#endif + +#if 0 + printf("::: player %d [%d]\n", player->index_nr, FrameCounter); +#endif + + if (!player->active || tape.pausing) + return 0; + + if (player_action) + { +#if 0 + printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter); +#endif + + if (button1) + snapped = SnapField(player, dx, dy); + else + { + if (button2) + dropped = DropElement(player); + + moved = MovePlayer(player, dx, dy); + } + + if (tape.single_step && tape.recording && !tape.pausing) + { + if (button1 || (dropped && !moved)) + { + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + SnapField(player, 0, 0); /* stop snapping */ + } + } + +#if 1 + return player_action; +#else + stored_player_action[player->index_nr] = player_action; +#endif + } + else + { +#if 0 + printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter); +#endif + + /* no actions for this player (no input at player's configured device) */ + + DigField(player, 0, 0, 0, 0, DF_NO_PUSH); + SnapField(player, 0, 0); + CheckGravityMovement(player); + + if (player->MovPos == 0) + InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir); + + if (player->MovPos == 0) /* needed for tape.playing */ + player->is_moving = FALSE; + + return 0; + } + +#if 0 + if (tape.recording && num_stored_actions >= MAX_PLAYERS) + { + printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter); + + TapeRecordAction(stored_player_action); + num_stored_actions = 0; + } +#endif +} + +#else + static void PlayerActions(struct PlayerInfo *player, byte player_action) { static byte stored_player_action[MAX_PLAYERS]; @@ -5872,11 +6055,15 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) stored_player_action[player->index_nr] = 0; num_stored_actions++; + printf("::: player %d [%d]\n", player->index_nr, FrameCounter); + if (!player->active || tape.pausing) return; if (player_action) { + printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter); + if (button1) snapped = SnapField(player, dx, dy); else @@ -5900,6 +6087,8 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) } else { + printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter); + /* no actions for this player (no input at player's configured device) */ DigField(player, 0, 0, 0, 0, DF_NO_PUSH); @@ -5915,10 +6104,13 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) if (tape.recording && num_stored_actions >= MAX_PLAYERS) { + printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter); + TapeRecordAction(stored_player_action); num_stored_actions = 0; } } +#endif void GameActions() { @@ -5928,6 +6120,9 @@ void GameActions() int i, x, y, element, graphic; byte *recorded_player_action; byte summarized_player_action = 0; +#if 1 + byte tape_action[MAX_PLAYERS]; +#endif if (game_status != GAME_MODE_PLAYING) return; @@ -5972,6 +6167,10 @@ void GameActions() if (tape.pausing) return; +#if 0 + printf("::: getting new tape action [%d]\n", FrameCounter); +#endif + recorded_player_action = (tape.playing ? TapePlayAction() : NULL); for (i=0; ieffective_action = summarized_player_action; - for (i=0; i 0) @@ -6384,9 +6599,9 @@ void GameActions() if (SHIELD_ON(player)) { if (player->shield_deadly_time_left) - PlaySoundLevel(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE); + PlayLevelSound(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE); else if (player->shield_normal_time_left) - PlaySoundLevel(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE); + PlayLevelSound(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE); } } @@ -7451,11 +7666,11 @@ void BuryHero(struct PlayerInfo *player) return; #if 1 - PlaySoundLevelElementAction(jx, jy, player->element_nr, ACTION_DYING); + PlayLevelSoundElementAction(jx, jy, player->element_nr, ACTION_DYING); #else - PlaySoundLevel(jx, jy, SND_CLASS_PLAYER_DYING); + PlayLevelSound(jx, jy, SND_CLASS_PLAYER_DYING); #endif - PlaySoundLevel(jx, jy, SND_GAME_LOSING); + PlayLevelSound(jx, jy, SND_GAME_LOSING); player->GameOver = TRUE; RemoveHero(player); @@ -7650,7 +7865,7 @@ int DigField(struct PlayerInfo *player, player->programmed_action = move_direction; DOUBLE_PLAYER_SPEED(player); - PlaySoundLevel(x, y, SND_CLASS_SP_PORT_PASSING); + PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING); break; case EL_TUBE_ANY: @@ -7692,7 +7907,7 @@ int DigField(struct PlayerInfo *player, if (!(tube_enter_directions[i][1] & move_direction)) return MF_NO_ACTION; /* tube has no opening in this direction */ - PlaySoundLevel(x, y, SND_CLASS_TUBE_WALKING); + PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING); } break; @@ -7725,9 +7940,9 @@ int DigField(struct PlayerInfo *player, /* play sound from background or player, whatever is available */ if (element_info[element].sound[sound_action] != SND_UNDEFINED) - PlaySoundLevelElementAction(x, y, element, sound_action); + PlayLevelSoundElementAction(x, y, element, sound_action); else - PlaySoundLevelElementAction(x, y, player->element_nr, sound_action); + PlayLevelSoundElementAction(x, y, player->element_nr, sound_action); break; } @@ -7756,7 +7971,7 @@ int DigField(struct PlayerInfo *player, player->programmed_action = move_direction; DOUBLE_PLAYER_SPEED(player); - PlaySoundLevelAction(x, y, ACTION_PASSING); + PlayLevelSoundAction(x, y, ACTION_PASSING); break; } @@ -7775,7 +7990,7 @@ int DigField(struct PlayerInfo *player, player->is_digging = TRUE; } - PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING); + PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED); @@ -7873,7 +8088,7 @@ int DigField(struct PlayerInfo *player, } RaiseScoreElement(element); - PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING); + PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED); @@ -7997,23 +8212,23 @@ int DigField(struct PlayerInfo *player, Feld[x][y] = EL_SOKOBAN_OBJECT; if (Back[x][y] == Back[nextx][nexty]) - PlaySoundLevelAction(x, y, ACTION_PUSHING); + PlayLevelSoundAction(x, y, ACTION_PUSHING); else if (Back[x][y] != 0) - PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL, + PlayLevelSoundElementAction(x, y, EL_SOKOBAN_FIELD_FULL, ACTION_EMPTYING); else - PlaySoundLevelElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY, + PlayLevelSoundElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY, ACTION_FILLING); if (local_player->sokobanfields_still_needed == 0 && game.emulation == EMU_SOKOBAN) { player->LevelSolved = player->GameOver = TRUE; - PlaySoundLevel(x, y, SND_GAME_SOKOBAN_SOLVING); + PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING); } } else - PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING); + PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING); InitMovingField(x, y, move_direction); GfxAction[x][y] = ACTION_PUSHING; @@ -8047,7 +8262,7 @@ int DigField(struct PlayerInfo *player, player->switch_x = x; player->switch_y = y; - PlaySoundLevelElementAction(x, y, element, ACTION_ACTIVATING); + PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVATING); if (element == EL_ROBOT_WHEEL) { @@ -8084,7 +8299,7 @@ int DigField(struct PlayerInfo *player, ToggleLightSwitch(x, y); #if 0 - PlaySoundLevel(x, y, element == EL_LIGHT_SWITCH ? + PlayLevelSound(x, y, element == EL_LIGHT_SWITCH ? SND_LIGHT_SWITCH_ACTIVATING : SND_LIGHT_SWITCH_DEACTIVATING); #endif @@ -8265,7 +8480,7 @@ boolean DropElement(struct PlayerInfo *player) if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy))) DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0); - PlaySoundLevelAction(jx, jy, ACTION_DROPPING); + PlayLevelSoundAction(jx, jy, ACTION_DROPPING); CheckTriggeredElementChange(jx, jy, new_element, CE_OTHER_GETS_DROPPED); CheckElementChange(jx, jy, new_element, CE_DROPPED_BY_PLAYER); @@ -8282,7 +8497,7 @@ boolean DropElement(struct PlayerInfo *player) if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy))) DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0); - PlaySoundLevelAction(jx, jy, ACTION_DROPPING); + PlayLevelSoundAction(jx, jy, ACTION_DROPPING); } return TRUE; @@ -8295,7 +8510,7 @@ boolean DropElement(struct PlayerInfo *player) static int *loop_sound_frame = NULL; static int *loop_sound_volume = NULL; -void InitPlaySoundLevel() +void InitPlayLevelSound() { int num_sounds = getSoundListSize(); @@ -8309,7 +8524,7 @@ void InitPlaySoundLevel() loop_sound_volume = checked_calloc(num_sounds * sizeof(int)); } -static void PlaySoundLevel(int x, int y, int nr) +static void PlayLevelSound(int x, int y, int nr) { int sx = SCREENX(x), sy = SCREENY(y); int volume, stereo_position; @@ -8354,37 +8569,37 @@ static void PlaySoundLevel(int x, int y, int nr) PlaySoundExt(nr, volume, stereo_position, type); } -static void PlaySoundLevelNearest(int x, int y, int sound_action) +static void PlayLevelSoundNearest(int x, int y, int sound_action) { - PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) : + PlayLevelSound(x < LEVELX(BX1) ? LEVELX(BX1) : x > LEVELX(BX2) ? LEVELX(BX2) : x, y < LEVELY(BY1) ? LEVELY(BY1) : y > LEVELY(BY2) ? LEVELY(BY2) : y, sound_action); } -static void PlaySoundLevelAction(int x, int y, int action) +static void PlayLevelSoundAction(int x, int y, int action) { - PlaySoundLevelElementAction(x, y, Feld[x][y], action); + PlayLevelSoundElementAction(x, y, Feld[x][y], action); } -static void PlaySoundLevelElementAction(int x, int y, int element, int action) +static void PlayLevelSoundElementAction(int x, int y, int element, int action) { int sound_effect = element_info[element].sound[action]; if (sound_effect != SND_UNDEFINED) - PlaySoundLevel(x, y, sound_effect); + PlayLevelSound(x, y, sound_effect); } -static void PlaySoundLevelActionIfLoop(int x, int y, int action) +static void PlayLevelSoundActionIfLoop(int x, int y, int action) { int sound_effect = element_info[Feld[x][y]].sound[action]; if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect)) - PlaySoundLevel(x, y, sound_effect); + PlayLevelSound(x, y, sound_effect); } -static void StopSoundLevelActionIfLoop(int x, int y, int action) +static void StopLevelSoundActionIfLoop(int x, int y, int action) { int sound_effect = element_info[Feld[x][y]].sound[action]; @@ -8392,6 +8607,18 @@ static void StopSoundLevelActionIfLoop(int x, int y, int action) StopSoundExt(sound_effect, SND_CTRL_STOP_SOUND); } +static void PlayLevelMusic() +{ +#if 1 + if (levelset.music[level_nr] != MUS_UNDEFINED) + PlayMusic(levelset.music[level_nr]); /* from config file */ + else + PlayMusic(-(level_nr + 1)); /* from music dir */ +#else + PlayMusic(level_nr); +#endif +} + void RaiseScore(int value) { local_player->score += value; @@ -8692,7 +8919,8 @@ static void HandleGameButtons(struct GadgetInfo *gi) setup.sound = setup.sound_music = TRUE; SetAudioMode(setup.sound); - PlayMusic(level_nr); + + PlayLevelMusic(); } break;