rnd-20090531-1-src
[rocksndiamonds.git] / src / libgame / system.c
index e94949d4245ef027c86383970b9a78e7a38ad2d5..c3d9575489c60fb74c5bb67c6fd8a926b2341268 100644 (file)
@@ -189,9 +189,16 @@ void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
   gfx.vysize = vysize;
 }
 
+void InitGfxWindowInfo(int win_xsize, int win_ysize)
+{
+  gfx.win_xsize = win_xsize;
+  gfx.win_ysize = win_ysize;
+}
+
 void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
 {
   /* currently only used by MSDOS code to alloc VRAM buffer, if available */
+  /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
   gfx.scrollbuffer_width = scrollbuffer_width;
   gfx.scrollbuffer_height = scrollbuffer_height;
 }
@@ -201,6 +208,15 @@ void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void))
   gfx.draw_busy_anim_function = draw_busy_anim_function;
 }
 
+void InitGfxCustomArtworkInfo()
+{
+  gfx.override_level_graphics = FALSE;
+  gfx.override_level_sounds = FALSE;
+  gfx.override_level_music = FALSE;
+
+  gfx.draw_init_text = TRUE;
+}
+
 void SetDrawDeactivationMask(int draw_deactivation_mask)
 {
   gfx.draw_deactivation_mask = draw_deactivation_mask;
@@ -267,17 +283,24 @@ void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
 
 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
 {
+  /* remove every mask before setting mask for window */
+  /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
+  SetBackgroundBitmap(NULL, 0xffff);           /* !!! FIX THIS !!! */
   SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
 }
 
 void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
 {
+  /* remove window area mask before setting mask for main area */
+  /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
   SetBackgroundBitmap(NULL, REDRAW_ALL);       /* !!! FIX THIS !!! */
   SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
 }
 
 void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
 {
+  /* remove window area mask before setting mask for door area */
+  /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
   SetBackgroundBitmap(NULL, REDRAW_ALL);       /* !!! FIX THIS !!! */
   SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
 }
@@ -368,16 +391,18 @@ Bitmap *CreateBitmapStruct(void)
 Bitmap *CreateBitmap(int width, int height, int depth)
 {
   Bitmap *new_bitmap = CreateBitmapStruct();
-  int real_depth = GetRealDepth(depth);
+  int real_width  = MAX(1, width);     /* prevent zero bitmap width */
+  int real_height = MAX(1, height);    /* prevent zero bitmap height */
+  int real_depth  = GetRealDepth(depth);
 
 #if defined(TARGET_SDL)
-  SDLCreateBitmapContent(new_bitmap, width, height, real_depth);
+  SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
 #else
-  X11CreateBitmapContent(new_bitmap, width, height, real_depth);
+  X11CreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
 #endif
 
-  new_bitmap->width width;
-  new_bitmap->height = height;
+  new_bitmap->width  = real_width;
+  new_bitmap->height = real_height;
 
   return new_bitmap;
 }
@@ -473,8 +498,55 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
   if (DrawingDeactivated(dst_x, dst_y, width, height))
     return;
 
-  sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
-             dst_x, dst_y, BLIT_OPAQUE);
+#if 0
+  /* !!! 2009-03-24: It seems that this problem still exists with 1.2.12 !!! */
+#if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
+  if (src_bitmap == dst_bitmap)
+  {
+    /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
+
+    /* needed when blitting directly to same bitmap -- should not be needed with
+       recent SDL libraries, but apparently does not work in 1.2.11 directly */
+
+    static Bitmap *tmp_bitmap = NULL;
+    static int tmp_bitmap_xsize = 0;
+    static int tmp_bitmap_ysize = 0;
+
+    /* start with largest static bitmaps for initial bitmap size ... */
+    if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
+    {
+      tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
+      tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
+    }
+
+    /* ... and allow for later re-adjustments due to custom artwork bitmaps */
+    if (src_bitmap->width > tmp_bitmap_xsize ||
+       src_bitmap->height > tmp_bitmap_ysize)
+    {
+      tmp_bitmap_xsize = MAX(tmp_bitmap_xsize, src_bitmap->width);
+      tmp_bitmap_ysize = MAX(tmp_bitmap_ysize, src_bitmap->height);
+
+      FreeBitmap(tmp_bitmap);
+
+      tmp_bitmap = NULL;
+    }
+
+    if (tmp_bitmap == NULL)
+      tmp_bitmap = CreateBitmap(tmp_bitmap_xsize, tmp_bitmap_ysize,
+                               DEFAULT_DEPTH);
+
+    sysCopyArea(src_bitmap, tmp_bitmap,
+               src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
+    sysCopyArea(tmp_bitmap, dst_bitmap,
+               dst_x, dst_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
+
+    return;
+  }
+#endif
+#endif
+
+  sysCopyArea(src_bitmap, dst_bitmap,
+             src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
 }
 
 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,