rnd-20100719-1-src
[rocksndiamonds.git] / src / tools.c
index 82fb4d0c34425e5a0b81a0d20384a0c876d349da..c89ef367bfee6a9f05ba0ac4ddddac863ffc445e 100644 (file)
@@ -304,6 +304,79 @@ void DrawMaskedBorder(int redraw_mask)
   }
 }
 
+void BlitScreenToBitmap(Bitmap *target_bitmap)
+{
+  DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
+  int fx = FX, fy = FY;
+
+#if NEW_TILESIZE
+  int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+  int dy = (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
+  int dx_var = dx * TILESIZE_VAR / TILESIZE;
+  int dy_var = dy * TILESIZE_VAR / TILESIZE;
+  int ffx, ffy;
+
+  // fx += dx * TILESIZE_VAR / TILESIZE;
+  // fy += dy * TILESIZE_VAR / TILESIZE;
+#else
+  fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+  fy += (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
+#endif
+
+  ffx = (scroll_x - SBX_Left)  * TILEX_VAR + dx_var;
+  ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
+
+  if (EVEN(SCR_FIELDX))
+  {
+    if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
+      fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
+    else
+      fx += (dx_var > 0 ? TILEX_VAR : 0);
+  }
+  else
+  {
+    fx += dx_var;
+  }
+
+  if (EVEN(SCR_FIELDY))
+  {
+    if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
+      fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
+    else
+      fy += (dy_var > 0 ? TILEY_VAR : 0);
+  }
+  else
+  {
+    fy += dy_var;
+  }
+
+#if 0
+  printf("::: (%d, %d) [(%d / %d, %d / %d)] => %d, %d\n",
+        scroll_x, scroll_y,
+        SBX_Left, SBX_Right,
+        SBY_Upper, SBY_Lower,
+        fx, fy);
+#endif
+
+  if (border.draw_masked[GAME_MODE_PLAYING])
+  {
+    if (buffer != backbuffer)
+    {
+      /* copy playfield buffer to backbuffer to add masked border */
+      BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY);
+      DrawMaskedBorder(REDRAW_FIELD);
+    }
+
+    BlitBitmap(backbuffer, target_bitmap,
+              REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+              REAL_SX, REAL_SY);
+  }
+  else
+  {
+    BlitBitmap(buffer, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY);
+  }
+}
+
 void BackToFront()
 {
   int x, y;
@@ -322,6 +395,13 @@ void BackToFront()
   if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
     redraw_mask |= REDRAW_FIELD;
 
+#if 0
+  /* !!! TEST ONLY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 */
+  /* (force full redraw) */
+  if (game_status == GAME_MODE_PLAYING)
+    redraw_mask |= REDRAW_FIELD;
+#endif
+
   if (redraw_mask & REDRAW_FIELD)
     redraw_mask &= ~REDRAW_TILES;
 
@@ -399,71 +479,88 @@ void BackToFront()
     }
     else
     {
+#if 1
+      BlitScreenToBitmap(window);
+#else
       int fx = FX, fy = FY;
 
-      if (setup.soft_scrolling)
-      {
 #if NEW_TILESIZE
-       int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
-       int dy = (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
-
-       fx += dx * TILESIZE_VAR / TILESIZE;
-       fy += dy * TILESIZE_VAR / TILESIZE;
+      int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+      int dy = (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
+      int dx_var = dx * TILESIZE_VAR / TILESIZE;
+      int dy_var = dy * TILESIZE_VAR / TILESIZE;
+      int ffx, ffy;
+
+      // fx += dx * TILESIZE_VAR / TILESIZE;
+      // fy += dy * TILESIZE_VAR / TILESIZE;
 #else
-       fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
-       fy += (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
+      fx += (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
+      fy += (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
 #endif
 
-#if 0
-       printf("::: %d, %d [%d, %d] [%d, %d]\n",
-              fx, fy, FX, FY, ScreenMovDir, ScreenGfxPos);
-#endif
+      /* !!! THIS WORKS !!! */
 
-#if 0
-#if NEW_TILESIZE
-       fx = fx * TILESIZE_VAR / TILESIZE;
-       fy = fy * TILESIZE_VAR / TILESIZE;
-#endif
-#endif
-      }
+      printf("::: %d, %d\n", scroll_x, scroll_y);
 
-      if (setup.soft_scrolling ||
-         ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
-         ABS(ScreenMovPos) == ScrollStepSize ||
-         redraw_tiles > REDRAWTILES_THRESHOLD)
+      ffx = (scroll_x - SBX_Left)  * TILEX_VAR + dx_var;
+      ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
+
+      if (EVEN(SCR_FIELDX))
       {
-       if (border.draw_masked[GAME_MODE_PLAYING])
-       {
-         if (buffer != backbuffer)
-         {
-           /* copy playfield buffer to backbuffer to add masked border */
-           BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY);
-           DrawMaskedBorder(REDRAW_FIELD);
-         }
+       if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
+         fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
+       else
+         fx += (dx > 0 ? TILEX_VAR : 0);
+      }
+      else
+      {
+       fx += dx;
+      }
 
-         BlitBitmap(backbuffer, window,
-                    REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
-                    REAL_SX, REAL_SY);
-       }
+      if (EVEN(SCR_FIELDY))
+      {
+       if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
+         fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
        else
+         fy += (dy > 0 ? TILEY_VAR : 0);
+      }
+      else
+      {
+       fy += dy;
+      }
+
+      if (border.draw_masked[GAME_MODE_PLAYING])
+      {
+       if (buffer != backbuffer)
        {
-         BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
+         /* copy playfield buffer to backbuffer to add masked border */
+         BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY);
+         DrawMaskedBorder(REDRAW_FIELD);
        }
 
+       BlitBitmap(backbuffer, window,
+                  REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+                  REAL_SX, REAL_SY);
+      }
+      else
+      {
+       BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
+      }
+#endif
+
 #if 0
 #ifdef DEBUG
-       printf("redrawing all (ScreenGfxPos == %d) because %s\n",
-              ScreenGfxPos,
-              (setup.soft_scrolling ?
-               "setup.soft_scrolling" :
-               ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
-               "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
-               ABS(ScreenGfxPos) == ScrollStepSize ?
-               "ABS(ScreenGfxPos) == ScrollStepSize" :
-               "redraw_tiles > REDRAWTILES_THRESHOLD"));
+      printf("redrawing all (ScreenGfxPos == %d) because %s\n",
+            ScreenGfxPos,
+            (setup.soft_scrolling ?
+             "setup.soft_scrolling" :
+             ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
+             "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
+             ABS(ScreenGfxPos) == ScrollStepSize ?
+             "ABS(ScreenGfxPos) == ScrollStepSize" :
+             "redraw_tiles > REDRAWTILES_THRESHOLD"));
 #endif
 #endif
-      }
     }
 
     redraw_mask &= ~REDRAW_MAIN;
@@ -498,6 +595,75 @@ void BackToFront()
 #endif
 
 #if NEW_TILESIZE
+
+#if 1
+    InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE);
+
+    {
+      int sx = SX; // - (EVEN(SCR_FIELDX) ? TILEX_VAR / 2 : 0);
+      int sy = SY; // + (EVEN(SCR_FIELDY) ? TILEY_VAR / 2 : 0);
+
+      int dx = 0, dy = 0;
+      int dx_var = dx * TILESIZE_VAR / TILESIZE;
+      int dy_var = dy * TILESIZE_VAR / TILESIZE;
+      int ffx, ffy;
+      int fx = FX, fy = FY;
+
+      int scr_fieldx = SCR_FIELDX + (EVEN(SCR_FIELDX) ? 2 : 0);
+      int scr_fieldy = SCR_FIELDY + (EVEN(SCR_FIELDY) ? 2 : 0);
+
+      ffx = (scroll_x - SBX_Left)  * TILEX_VAR + dx_var;
+      ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var;
+
+      if (EVEN(SCR_FIELDX))
+      {
+       if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR)
+       {
+         fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR;
+
+         if (fx % TILEX_VAR)
+           sx -= TILEX_VAR / 2;
+         else
+           sx -= TILEX_VAR;
+       }
+       else
+       {
+         fx += (dx_var > 0 ? TILEX_VAR : 0);
+       }
+      }
+
+      if (EVEN(SCR_FIELDY))
+      {
+       if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR)
+       {
+         fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR;
+
+         if (fy % TILEY_VAR)
+           sy -= TILEY_VAR / 2;
+         else
+           sy -= TILEY_VAR;
+       }
+       else
+       {
+         fy += (dy_var > 0 ? TILEY_VAR : 0);
+       }
+      }
+
+#if 0
+      printf("::: %d, %d, %d, %d\n", sx, sy, SCR_FIELDX, SCR_FIELDY);
+#endif
+
+      for (x = 0; x < scr_fieldx; x++)
+       for (y = 0 ; y < scr_fieldy; y++)
+         if (redraw[redraw_x1 + x][redraw_y1 + y])
+           BlitBitmap(buffer, window,
+                      FX + x * TILEX_VAR, FY + y * TILEY_VAR,
+                      TILEX_VAR, TILEY_VAR,
+                      sx + x * TILEX_VAR, sy + y * TILEY_VAR);
+    }
+
+    InitGfxClipRegion(FALSE, -1, -1, -1, -1);
+#else
     for (x = 0; x < SCR_FIELDX; x++)
       for (y = 0 ; y < SCR_FIELDY; y++)
        if (redraw[redraw_x1 + x][redraw_y1 + y])
@@ -505,6 +671,8 @@ void BackToFront()
                     FX + x * TILEX_VAR, FY + y * TILEY_VAR,
                     TILEX_VAR, TILEY_VAR,
                     SX + x * TILEX_VAR, SY + y * TILEY_VAR);
+#endif
+
 #else
     for (x = 0; x < SCR_FIELDX; x++)
       for (y = 0 ; y < SCR_FIELDY; y++)
@@ -7076,6 +7244,7 @@ inline static int get_effective_element_EM(int tile, int frame_em)
        return (frame_em > 5 ? EL_EMPTY : element);
 
 #if 0
+       /* !!! FIX !!! */
       case Ydiamond_stone:
        //  if (!game.use_native_emc_graphics_engine)
        return EL_ROCK;
@@ -8831,17 +9000,27 @@ void ChangeViewportPropertiesIfNeeded()
   int border_size = vp_playfield->border_size;
   int new_sx = vp_playfield->x + border_size;
   int new_sy = vp_playfield->y + border_size;
-  int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? TILESIZE_VAR :
-                 gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE);
   int new_sxsize = vp_playfield->width  - 2 * border_size;
   int new_sysize = vp_playfield->height - 2 * border_size;
+  int new_real_sx = vp_playfield->x;
+  int new_real_sy = vp_playfield->y;
+  int new_full_sxsize = vp_playfield->width;
+  int new_full_sysize = vp_playfield->height;
 #if NEW_TILESIZE
+  int new_tilesize_var = TILESIZE / (setup.small_game_graphics ? 2 : 1);
+  int tilesize = (gfx_game_mode == GAME_MODE_PLAYING ? new_tilesize_var :
+                 gfx_game_mode == GAME_MODE_EDITOR ? MINI_TILESIZE : TILESIZE);
   int new_scr_fieldx = new_sxsize / tilesize;
   int new_scr_fieldy = new_sysize / tilesize;
+  int new_scr_fieldx_buffers = new_sxsize / new_tilesize_var;
+  int new_scr_fieldy_buffers = new_sysize / new_tilesize_var;
 #else
   int new_scr_fieldx = (vp_playfield->width  - 2 * border_size) / TILESIZE;
   int new_scr_fieldy = (vp_playfield->height - 2 * border_size) / TILESIZE;
 #endif
+  boolean init_gfx_buffers = FALSE;
+  boolean init_video_buffer = FALSE;
+  boolean init_gadgets_and_toons = FALSE;
 
 #if 0
   /* !!! TEST ONLY !!! */
@@ -8855,6 +9034,10 @@ void ChangeViewportPropertiesIfNeeded()
     WIN_XSIZE = viewport.window.width;
     WIN_YSIZE = viewport.window.height;
 
+#if 1
+    init_video_buffer = TRUE;
+    init_gfx_buffers = TRUE;
+#else
     InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
     InitGfxBuffers();
 
@@ -8864,45 +9047,123 @@ void ChangeViewportPropertiesIfNeeded()
 
     // RedrawBackground();
 #endif
+#endif
+
+    // printf("::: video: init_video_buffer, init_gfx_buffers\n");
   }
 
   if (new_scr_fieldx != SCR_FIELDX ||
-      new_scr_fieldy != SCR_FIELDY ||
-      new_sx != SX ||
+      new_scr_fieldy != SCR_FIELDY)
+  {
+    /* this always toggles between MAIN and GAME when using small tile size */
+
+    SCR_FIELDX = new_scr_fieldx;
+    SCR_FIELDY = new_scr_fieldy;
+
+    // printf("::: new_scr_fieldx != SCR_FIELDX ...\n");
+  }
+
+#if 0
+  if (new_tilesize_var != TILESIZE_VAR &&
+      gfx_game_mode == GAME_MODE_PLAYING)
+  {
+    /* doing this outside GAME_MODE_PLAYING would give wrong playfield size */
+
+    TILESIZE_VAR = new_tilesize_var;
+
+    init_gfx_buffers = TRUE;
+
+    // printf("::: tilesize: init_gfx_buffers\n");
+  }
+#endif
+
+  if (new_sx != SX ||
       new_sy != SY ||
-      vp_playfield->x != REAL_SX ||
-      vp_playfield->y != REAL_SY ||
+      new_sxsize != SXSIZE ||
+      new_sysize != SYSIZE ||
+      new_real_sx != REAL_SX ||
+      new_real_sy != REAL_SY ||
+      new_full_sxsize != FULL_SXSIZE ||
+      new_full_sysize != FULL_SYSIZE ||
+      new_tilesize_var != TILESIZE_VAR ||
       vp_door_1->x != *door_1_x ||
       vp_door_1->y != *door_1_y ||
       vp_door_2->x != *door_2_x ||
       vp_door_2->y != *door_2_y)
   {
-    SCR_FIELDX = new_scr_fieldx;
-    SCR_FIELDY = new_scr_fieldy;
     SX = new_sx;
     SY = new_sy;
-    REAL_SX = vp_playfield->x;
-    REAL_SY = vp_playfield->y;
-
     SXSIZE = new_sxsize;
     SYSIZE = new_sysize;
-    FULL_SXSIZE = vp_playfield->width;
-    FULL_SYSIZE = vp_playfield->width;
+    REAL_SX = new_real_sx;
+    REAL_SY = new_real_sy;
+    FULL_SXSIZE = new_full_sxsize;
+    FULL_SYSIZE = new_full_sysize;
+    TILESIZE_VAR = new_tilesize_var;
+
+#if 0
+    printf("::: %d, %d, %d [%d]\n",
+          SCR_FIELDX, SCR_FIELDY, TILESIZE_VAR,
+          setup.small_game_graphics);
+#endif
 
     *door_1_x = vp_door_1->x;
     *door_1_y = vp_door_1->y;
     *door_2_x = vp_door_2->x;
     *door_2_y = vp_door_2->y;
 
+#if 1
+    init_gfx_buffers = TRUE;
+
+    // printf("::: viewports: init_gfx_buffers\n");
+#else
     InitGfxBuffers();
+#endif
 
     if (gfx_game_mode == GAME_MODE_MAIN)
     {
+#if 1
+      init_gadgets_and_toons = TRUE;
+
+      // printf("::: viewports: init_gadgets_and_toons\n");
+#else
       InitGadgets();
       InitToons();
+#endif
     }
   }
 
+  if (init_gfx_buffers)
+  {
+    // printf("::: init_gfx_buffers\n");
+
+    SCR_FIELDX = new_scr_fieldx_buffers;
+    SCR_FIELDY = new_scr_fieldy_buffers;
+
+    InitGfxBuffers();
+
+    SCR_FIELDX = new_scr_fieldx;
+    SCR_FIELDY = new_scr_fieldy;
+  }
+
+  if (init_video_buffer)
+  {
+    // printf("::: init_video_buffer\n");
+
+    InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
+
+    SetDrawDeactivationMask(REDRAW_NONE);
+    SetDrawBackgroundMask(REDRAW_FIELD);
+  }
+
+  if (init_gadgets_and_toons)
+  {
+    // printf("::: init_gadgets_and_toons\n");
+
+    InitGadgets();
+    InitToons();
+  }
+
 #if 0
   printf("::: %d, %d  /  %d, %d [%d]\n", VX, VY, EX, EY, game_status);
 #endif