+static int getGraphicAnimationPhase(int frames, int delay, int mode)
+{
+ int phase;
+
+ if (mode & ANIM_PINGPONG)
+ {
+ int max_anim_frames = 2 * frames - 2;
+
+ phase = (FrameCounter % (delay * max_anim_frames)) / delay;
+ phase = (phase < frames ? phase : max_anim_frames - phase);
+ }
+ else
+ phase = (FrameCounter % (delay * frames)) / delay;
+
+ if (mode & ANIM_REVERSE)
+ phase = -phase;
+
+ return phase;
+}
+
+inline int getGraphicAnimationFrame(int graphic, int sync_frame)
+{
+ /* animation synchronized with global frame counter, not move position */
+ if (new_graphic_info[graphic].anim_global_sync || sync_frame < 0)
+ sync_frame = FrameCounter;
+
+ return getAnimationFrame(new_graphic_info[graphic].anim_frames,
+ new_graphic_info[graphic].anim_delay,
+ new_graphic_info[graphic].anim_mode,
+ new_graphic_info[graphic].anim_start_frame,
+ sync_frame);
+}
+
+inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+ int graphic, int sync_frame, int mask_mode)
+{
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ if (mask_mode == USE_MASKING)
+ DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
+ else
+ DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
+}
+
+inline boolean DrawGraphicAnimation(int x, int y, int graphic)
+{
+ int lx = LEVELX(x), ly = LEVELY(y);
+
+ if (!IN_SCR_FIELD(x, y) ||
+ (GfxFrame[lx][ly] % new_graphic_info[graphic].anim_delay) != 0)
+ return FALSE;
+
+ DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
+ graphic, GfxFrame[lx][ly], NO_MASKING);
+ MarkTileDirty(x, y);
+
+ return TRUE;
+}
+
+boolean DrawLevelGraphicAnimation(int x, int y, int graphic)
+{
+ return DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
+}
+
+boolean DrawLevelElementAnimation(int x, int y, int element)
+{
+ return DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
+}
+