Merge branch 'master' into global-anims
[rocksndiamonds.git] / src / libgame / toons.c
index bbbd88333e7fc106abb68146b8efd0d7306177f9..34fa8fbb675f157256375535116f9938538f239e 100644 (file)
@@ -1,26 +1,18 @@
-/***********************************************************
-* Artsoft Retro-Game Library                               *
-*----------------------------------------------------------*
-* (c) 1995-2006 Artsoft Entertainment                      *
-*               Holger Schemel                             *
-*               Detmolder Strasse 189                      *
-*               33604 Bielefeld                            *
-*               Germany                                    *
-*               e-mail: info@artsoft.org                   *
-*----------------------------------------------------------*
-* toons.c                                                  *
-***********************************************************/
+// ============================================================================
+// Artsoft Retro-Game Library
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+//                         Holger Schemel
+//                 info@artsoft.org
+//                 http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// toons.c
+// ============================================================================
 
 #include "toons.h"
 #include "misc.h"
 
 
-/* values for toon animation */
-#define ANIM_START     0
-#define ANIM_CONTINUE  1
-#define ANIM_STOP      2
-
-
 static struct ToonScreenInfo screen_info;
 
 
@@ -121,38 +113,60 @@ void InitToonScreen(Bitmap *save_buffer,
   screen_info.frame_delay_value = frame_delay_value;
 }
 
-void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc,
-             int src_x, int src_y, int width, int height,
+void DrawAnim(Bitmap *toon_bitmap, int src_x, int src_y, int width, int height,
              int dest_x, int dest_y, int pad_x, int pad_y)
 {
-  int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1;
+  int pad_dest_x = dest_x - pad_x;
+  int pad_dest_y = dest_y - pad_y;
+  int pad_width  = width  + 2 * pad_x;
+  int pad_height = height + 2 * pad_y;
+  int buffer_x = 0;
+  int buffer_y = 0;
+
+  /* correct values to avoid off-screen blitting (start position) */
+  if (pad_dest_x < screen_info.startx)
+  {
+    pad_width -= (screen_info.startx - pad_dest_x);
+    pad_dest_x = screen_info.startx;
+  }
+  if (pad_dest_y < screen_info.starty)
+  {
+    pad_height -= (screen_info.starty - pad_dest_y);
+    pad_dest_y = screen_info.starty;
+  }
+
+  /* correct values to avoid off-screen blitting (blit size) */
+  if (pad_width > screen_info.width)
+    pad_width = screen_info.width;
+  if (pad_height > screen_info.height)
+    pad_height = screen_info.height;
 
   /* special method to avoid flickering interference with BackToFront() */
-  BlitBitmap(backbuffer, screen_info.save_buffer, dest_x-pad_x, dest_y-pad_y,
-            width+2*pad_x, height+2*pad_y, buf_x, buf_y);
-  SetClipOrigin(toon_bitmap, toon_clip_gc, dest_x-src_x, dest_y-src_y);
-  BlitBitmapMasked(toon_bitmap, backbuffer,
-                  src_x, src_y, width, height, dest_x, dest_y);
-  BlitBitmap(backbuffer, window, dest_x-pad_x, dest_y-pad_y,
-            width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
+  BlitBitmap(backbuffer, screen_info.save_buffer, pad_dest_x, pad_dest_y,
+            pad_width, pad_height, buffer_x, buffer_y);
+  BlitBitmapMasked(toon_bitmap, backbuffer, src_x, src_y, width, height,
+                  dest_x, dest_y);
+  BlitBitmap(backbuffer, window, pad_dest_x, pad_dest_y, pad_width, pad_height,
+            pad_dest_x, pad_dest_y);
 
   screen_info.update_function();
 
-  BlitBitmap(screen_info.save_buffer, backbuffer, buf_x, buf_y,
-           width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
+  BlitBitmap(screen_info.save_buffer, backbuffer, buffer_x, buffer_y,
+            pad_width, pad_height, pad_dest_x, pad_dest_y);
 
-  FlushDisplay();
+  /* prevent immediate redraw of restored toon area in backbuffer */
+  redraw_mask = REDRAW_NONE;
 }
 
 boolean AnimateToon(int toon_nr, boolean restart)
 {
-  static unsigned long animation_frame_counter = 0;
+  static unsigned int animation_frame_counter = 0;
   static int pos_x = 0, pos_y = 0;
   static int delta_x = 0, delta_y = 0;
   static int frame = 0;
   static boolean horiz_move, vert_move;
-  static unsigned long anim_delay = 0;
-  static unsigned long anim_delay_value = 0;
+  static unsigned int anim_delay = 0;
+  static unsigned int anim_delay_value = 0;
   static int width,height;
   static int pad_x,pad_y;
   static int cut_x,cut_y;
@@ -160,7 +174,6 @@ boolean AnimateToon(int toon_nr, boolean restart)
   static int dest_x, dest_y;
   struct ToonInfo *anim = &screen_info.toons[toon_nr];
   Bitmap *anim_bitmap = screen_info.toons[toon_nr].bitmap;
-  GC anim_clip_gc = anim_bitmap->stored_clip_gc;
   int direction = get_toon_direction(anim->direction);
 
   if (restart)
@@ -220,7 +233,7 @@ boolean AnimateToon(int toon_nr, boolean restart)
       else
       {
        delta_y = -anim->step_offset;
-       pos_y = screen_info.width + delta_y;
+       pos_y = screen_info.height + delta_y;
       }
 
       delta_x = 0;
@@ -236,7 +249,7 @@ boolean AnimateToon(int toon_nr, boolean restart)
   if (!DelayReached(&anim_delay, anim_delay_value))
   {
     if (screen_info.redraw_needed_function() && !restart)
-      DrawAnim(anim_bitmap, anim_clip_gc,
+      DrawAnim(anim_bitmap,
               src_x + cut_x, src_y + cut_y,
               width, height,
               screen_info.startx + dest_x,
@@ -283,7 +296,7 @@ boolean AnimateToon(int toon_nr, boolean restart)
   else if (pos_y > screen_info.height - anim->height)
     height -= (pos_y - (screen_info.height - anim->height));
 
-  DrawAnim(anim_bitmap, anim_clip_gc,
+  DrawAnim(anim_bitmap,
           src_x + cut_x, src_y + cut_y,
           width, height,
           screen_info.startx + dest_x,
@@ -302,8 +315,8 @@ boolean AnimateToon(int toon_nr, boolean restart)
 
 void HandleAnimation(int mode)
 {
-  static unsigned long animstart_delay = -1;
-  static unsigned long animstart_delay_value = 0;
+  static unsigned int animstart_delay = -1;
+  static unsigned int animstart_delay_value = 0;
   static boolean anim_running = FALSE;
   static boolean anim_restart = TRUE;
   static boolean reset_delay = TRUE;
@@ -336,17 +349,9 @@ void HandleAnimation(int mode)
     case ANIM_STOP:
       if (anim_running)
       {
-#if 1
-       int draw_mode;
+       redraw_mask |= REDRAW_FIELD;
 
-       redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER);
-
-       /* Redraw background even when in direct drawing mode */
-       draw_mode = setup.direct_draw;
-       setup.direct_draw = FALSE;
        screen_info.update_function();
-       setup.direct_draw = draw_mode;
-#endif
 
        anim_running = FALSE;
       }
@@ -374,18 +379,3 @@ void HandleAnimation(int mode)
 
   anim_restart = reset_delay = AnimateToon(toon_nr, anim_restart);
 }
-
-void InitAnimation()
-{
-  HandleAnimation(ANIM_START);
-}
-
-void StopAnimation()
-{
-  HandleAnimation(ANIM_STOP);
-}
-
-void DoAnimation()
-{
-  HandleAnimation(ANIM_CONTINUE);
-}