X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=ce26a3b853d51fc72f42b0108e6f65df741bc45c;hb=ab0c2cf87c09fdc785f5124640a9f3334bb3a4b4;hp=09ea5e2ec74455bfe11eaf8e99f6ef2198c3d255;hpb=c5ee7e4524f10322894b2547337e4c973a80a552;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 09ea5e2e..ce26a3b8 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,9 +119,6 @@ static void HandleGameButtons(struct GadgetInfo *); static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; -#define IS_ANIMATED(g) (graphic_info[g].anim_frames > 1) -#define IS_LOOP_SOUND(s) (sound_info[s].loop) - /* ------------------------------------------------------------------------- */ /* definition of elements that automatically change to other elements after */ @@ -722,7 +723,7 @@ void InitGame() GfxFrame[x][y] = 0; GfxAction[x][y] = ACTION_DEFAULT; - GfxRandom[x][y] = SimpleRND(1000000); + GfxRandom[x][y] = INIT_GFX_RANDOM(); } } @@ -1251,6 +1252,31 @@ int NewHiScore() return position; } +static void ResetRandomAnimationValue(int x, int y) +{ + int element = Feld[x][y]; + int graphic = el2img(element); + + /* reset random value not until one full delay cycle has reached */ + if (ANIM_MODE(graphic) == ANIM_RANDOM && + GfxFrame[x][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]; @@ -1258,10 +1284,9 @@ 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; @@ -1270,6 +1295,10 @@ void InitMovingField(int x, int y, int direction) GfxAction[x][y] = ACTION_FALLING; else 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) @@ -1410,21 +1439,15 @@ void DrawDynamite(int x, int y) void CheckDynamite(int x, int y) { -#if 0 - int element = Feld[x][y]; -#endif - if (MovDelay[x][y] != 0) /* dynamite is still waiting to explode */ { MovDelay[x][y]--; if (MovDelay[x][y] != 0) { -#if 0 - if (checkDrawLevelGraphicAnimation(x, y, el2img(element))) -#endif - DrawDynamite(x, y); + DrawDynamite(x, y); + /* !!! correct: "PlaySoundLevelActionIfLoop" etc. !!! */ PlaySoundLevelAction(x, y, ACTION_ACTIVE); return; @@ -2118,8 +2141,8 @@ void Impact(int x, int y) return; object_hit = (!IS_FREE(x, y+1) && (!IS_MOVING(x, y+1) || - MovDir[x][y+1]!=MV_DOWN || - MovPos[x][y+1]<=TILEY/2)); + MovDir[x][y+1] != MV_DOWN || + MovPos[x][y+1] <= TILEY / 2)); if (object_hit) smashed = MovingOrBlocked2Element(x, y+1); } @@ -2130,6 +2153,17 @@ void Impact(int x, int y) return; } +#if 1 + if (lastline || object_hit) + { +#if 0 + MovDir[x][y] = 0; +#endif + ResetGfxAnimation(x, y); + DrawLevelField(x, y); + } +#endif + if ((element == EL_BOMB || element == EL_SP_DISK_ORANGE || element == EL_DX_SUPABOMB) && @@ -2882,6 +2916,9 @@ void StartMoving(int x, int y) } else if (IS_FREE(x, y+1)) { + if (JustStopped[x][y]) /* prevent animation from being restarted */ + MovDir[x][y] = MV_DOWN; + InitMovingField(x, y, MV_DOWN); started_moving = TRUE; } @@ -3003,7 +3040,7 @@ void StartMoving(int x, int y) element == EL_DARK_YAMYAM) { #if 1 - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); #else if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) { @@ -3027,7 +3064,7 @@ void StartMoving(int x, int y) #endif } else if (element == EL_SP_ELECTRON) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_DRAGON) { int i; @@ -3285,11 +3322,11 @@ void StartMoving(int x, int y) element == EL_SP_SNIKSNAK || element == EL_MOLE) DrawLevelField(x, y); else if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_SATELLITE) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_SP_ELECTRON) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); if (DONT_TOUCH(element)) TestIfBadThingTouchesHero(x, y); @@ -3424,10 +3461,20 @@ void ContinueMoving(int x, int y) MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; MovDelay[newx][newy] = 0; +#if 0 + /* all done in "InitMovingField()" */ GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */ GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */ - GfxAction[x][y] = ACTION_DEFAULT; +#endif + /* copy animation control values to new field */ + GfxFrame[newx][newy] = GfxFrame[x][y]; + GfxAction[newx][newy] = GfxAction[x][y]; + GfxRandom[newx][newy] = GfxRandom[x][y]; + + ResetGfxAnimation(x, y); /* reset animation values for old field */ + +#if 1 #if 0 if (!CAN_MOVE(element)) MovDir[newx][newy] = 0; @@ -3440,6 +3487,7 @@ void ContinueMoving(int x, int y) if (!CAN_MOVE(element) || (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN)) MovDir[newx][newy] = 0; +#endif #endif DrawLevelField(x, y); @@ -3974,13 +4022,6 @@ static void RunTimegateWheel(int x, int y) PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE); } -void SiebAktivieren(int x, int y, int type) -{ - int graphic = (type == 1 ? IMG_MAGIC_WALL_FULL : IMG_BD_MAGIC_WALL_FULL); - - ContinueLevelGraphicAnimation(x, y, graphic); -} - void CheckExit(int x, int y) { if (local_player->gems_still_needed > 0 || @@ -4325,10 +4366,9 @@ 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 new animation frame was drawn, correct crumbled sand border */ + if (IS_NEW_FRAME(GfxFrame[x][y], graphic)) + DrawCrumbledSand(SCREENX(x), SCREENY(y)); } static void ChangeElement(int x, int y) @@ -4338,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); @@ -4349,7 +4390,7 @@ static void ChangeElement(int x, int y) if (MovDelay[x][y] != 0) /* continue element change */ { if (IS_ANIMATED(el2img(element))) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); if (changing_element[element].change_function) changing_element[element].change_function(x, y); @@ -4357,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); @@ -4511,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; @@ -4649,6 +4691,15 @@ 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)) @@ -4656,7 +4707,7 @@ void GameActions() #if 1 if (IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif continue; @@ -4666,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)) - ContinueLevelGraphicAnimation(x, y, graphic); -#else if (IS_ANIMATED(graphic) && - !IS_MOVING(x, y)) - ContinueLevelGraphicAnimation(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); @@ -4693,7 +4736,7 @@ void GameActions() element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY) && IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif else if (IS_MOVING(x, y)) @@ -4777,7 +4820,7 @@ void GameActions() else if (element == EL_EXPLOSION) ; /* drawing of correct explosion animation is handled separately */ else if (IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif if (IS_BELT_ACTIVE(element)) @@ -4788,26 +4831,17 @@ void GameActions() 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; } } } @@ -4875,14 +4909,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) @@ -6417,7 +6451,8 @@ boolean PlaceBomb(struct PlayerInfo *player) Store[jx][jy] = element; MovDelay[jx][jy] = 96; - GfxFrame[jx][jy] = 0; + + ResetGfxAnimation(jx, jy); if (player->dynamite) {