rnd-20140819-2-src
[rocksndiamonds.git] / src / game_em / graphics.c
index f33d4db800e610b6f53ead1bb26fd9aee8d6f261..5e53a433708cac6e390b9000cb28266d5aa2d298 100644 (file)
 
 #define USE_EXTENDED_GRAPHICS_ENGINE           1
 
-int frame;                     /* current screen frame */
-int screen_x;                  /* current scroll position */
-int screen_y;
+
+#if 0
+int TILEX = ORIG_TILEX * ZOOM_FACTOR;
+int TILEY = ORIG_TILEY * ZOOM_FACTOR;
+#endif
+
+int frame;                             /* current screen frame */
+int screen_x, screen_y;                        /* current scroll position */
 
 /* tiles currently on screen */
+#if 1
+static int screentiles[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2];
+static int crumbled_state[MAX_PLAYFIELD_HEIGHT + 2][MAX_PLAYFIELD_WIDTH + 2];
+
+static boolean redraw[MAX_PLAYFIELD_WIDTH + 2][MAX_PLAYFIELD_HEIGHT + 2];
+#else
 static int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
 static int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
 
 static boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+#endif
 
 #if 0
 #if 1
@@ -53,7 +65,69 @@ void BlitScreenToBitmap_EM(Bitmap *target_bitmap)
 {
   int x = screen_x % (MAX_BUF_XSIZE * TILEX);
   int y = screen_y % (MAX_BUF_YSIZE * TILEY);
+  int sx, sy, sxsize, sysize;
+  int xsize = SXSIZE;
+  int ysize = SYSIZE;
+  int full_xsize = lev.width  * TILEX;
+  int full_ysize = lev.height * TILEY;
+
+#if 0
+  printf("::: %d, %d\n", screenBitmap->width, screenBitmap->height);
+  printf("::: %d / %d, %d / %d\n",
+        MAX_BUF_XSIZE, MAX_BUF_YSIZE, SXSIZE, SYSIZE);
+#endif
+
+  sxsize = (full_xsize < xsize ? full_xsize : xsize);
+  sysize = (full_ysize < ysize ? full_ysize : ysize);
+  sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
+  sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
+
+#if 0
+  printf("::: %d, %d\n", screenBitmap->width, screenBitmap->height);
+  BlitBitmap(screenBitmap, target_bitmap, 0, 0, 544, 544, SX, SY);
+  return;
+#endif
 
+#if 1
+  if (x < 2 * TILEX && y < 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              sxsize, sysize, sx, sy);
+  }
+  else if (x < 2 * TILEX && y >= 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              sxsize, MAX_BUF_YSIZE * TILEY - y,
+              sx, sy);
+    BlitBitmap(screenBitmap, target_bitmap, x, 0,
+              sxsize, y - 2 * TILEY,
+              sx, sy + MAX_BUF_YSIZE * TILEY - y);
+  }
+  else if (x >= 2 * TILEX && y < 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              MAX_BUF_XSIZE * TILEX - x, sysize,
+              sx, sy);
+    BlitBitmap(screenBitmap, target_bitmap, 0, y,
+              x - 2 * TILEX, sysize,
+              sx + MAX_BUF_XSIZE * TILEX - x, sy);
+  }
+  else
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
+              sx, sy);
+    BlitBitmap(screenBitmap, target_bitmap, 0, y,
+              x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
+              sx + MAX_BUF_XSIZE * TILEX - x, sy);
+    BlitBitmap(screenBitmap, target_bitmap, x, 0,
+              MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
+              sx, sy + MAX_BUF_YSIZE * TILEY - y);
+    BlitBitmap(screenBitmap, target_bitmap, 0, 0,
+              x - 2 * TILEX, y - 2 * TILEY,
+              sx + MAX_BUF_XSIZE * TILEX - x, sy + MAX_BUF_YSIZE * TILEY - y);
+  }
+#else
   if (x < 2 * TILEX && y < 2 * TILEY)
   {
     BlitBitmap(screenBitmap, target_bitmap, x, y,
@@ -92,16 +166,26 @@ void BlitScreenToBitmap_EM(Bitmap *target_bitmap)
               x - 2 * TILEX, y - 2 * TILEY,
               SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
   }
+#endif
 }
 
 void BackToFront_EM(void)
 {
+  static int screen_x_last = -1, screen_y_last = -1;
   static boolean scrolling_last = FALSE;
   int left = screen_x / TILEX;
   int top  = screen_y / TILEY;
+#if 1
+  boolean scrolling = (screen_x != screen_x_last || screen_y != screen_y_last);
+#else
   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
+#endif
   int x, y;
 
+#if 0
+  printf("::: %d, %d\n", screen_x, screen_y);
+#endif
+
   SyncDisplay();
 
   if (redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last)
@@ -114,6 +198,66 @@ void BackToFront_EM(void)
   }
   else
   {
+#if 1
+#if 1
+    boolean half_shifted_x = (screen_x % TILEX != 0);
+    boolean half_shifted_y = (screen_y % TILEY != 0);
+#else
+    boolean half_shifted_x = (EVEN(SCR_FIELDX) && screen_x % TILEX != 0);
+    boolean half_shifted_y = (EVEN(SCR_FIELDY) && screen_y % TILEY != 0);
+#endif
+
+    int sx, sy;
+#if 0
+    int sxsize, sysize;
+#endif
+    int xsize = SXSIZE;
+    int ysize = SYSIZE;
+    int full_xsize = lev.width  * TILEX;
+    int full_ysize = lev.height * TILEY;
+
+#if 0
+    sxsize = (full_xsize < xsize ? full_xsize : xsize);
+    sysize = (full_ysize < ysize ? full_ysize : ysize);
+#endif
+    sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
+    sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
+
+#if 0
+#if 1
+    printf("::: %d, %d\n", EVEN(SCR_FIELDX), screen_x);
+#else
+    half_shifted_x = TRUE;
+    half_shifted_y = FALSE;
+#endif
+#endif
+
+    int x1 = 0, x2 = SCR_FIELDX - (half_shifted_x ? 0 : 1);
+    int y1 = 0, y2 = SCR_FIELDY - (half_shifted_y ? 0 : 1);
+    int scroll_xoffset = (half_shifted_x ? TILEX / 2 : 0);
+    int scroll_yoffset = (half_shifted_y ? TILEY / 2 : 0);
+
+    InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE);
+
+    for (x = x1; x <= x2; x++)
+    {
+      for (y = y1; y <= y2; y++)
+      {
+       int xx = (left + x) % MAX_BUF_XSIZE;
+       int yy = (top  + y) % MAX_BUF_YSIZE;
+
+       if (redraw[xx][yy])
+         BlitBitmap(screenBitmap, window,
+                    xx * TILEX, yy * TILEY, TILEX, TILEY,
+                    sx + x * TILEX - scroll_xoffset,
+                    sy + y * TILEY - scroll_yoffset);
+      }
+    }
+
+    InitGfxClipRegion(FALSE, -1, -1, -1, -1);
+
+#else
+
     for (x = 0; x < SCR_FIELDX; x++)
     {
       for (y = 0; y < SCR_FIELDY; y++)
@@ -127,6 +271,7 @@ void BackToFront_EM(void)
                     SX + x * TILEX, SY + y * TILEY);
       }
     }
+#endif
   }
 
   FlushDisplay();
@@ -136,6 +281,8 @@ void BackToFront_EM(void)
       redraw[x][y] = FALSE;
   redraw_tiles = 0;
 
+  screen_x_last = screen_x;
+  screen_y_last = screen_y;
   scrolling_last = scrolling;
 }
 
@@ -150,8 +297,8 @@ static struct GraphicInfo_EM *getObjectGraphic(int x, int y)
   struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
 
   if (!game.use_native_emc_graphics_engine)
-    getGraphicSourceObjectExt_EM(tile, frame, &g->bitmap, &g->src_x, &g->src_y,
-                                x - 2, y - 2);
+    getGraphicSourceObjectExt_EM(g, tile, 7 - frame, x - 2, y - 2);
+
   return g;
 }
 
@@ -160,8 +307,8 @@ static struct GraphicInfo_EM *getPlayerGraphic(int player_nr, int anim)
   struct GraphicInfo_EM *g = &graphic_info_em_player[player_nr][anim][frame];
 
   if (!game.use_native_emc_graphics_engine)
-    getGraphicSourcePlayerExt_EM(player_nr, anim, frame,
-                                &g->bitmap, &g->src_x, &g->src_y);
+    getGraphicSourcePlayerExt_EM(g, player_nr, anim, 7 - frame);
+
   return g;
 }
 
@@ -169,12 +316,21 @@ static void DrawLevelField_EM(int x, int y, int sx, int sy,
                              boolean draw_masked)
 {
   struct GraphicInfo_EM *g = getObjectGraphic(x, y);
+#if NEW_TILESIZE
+  int src_x = g->src_x + g->src_offset_x * TILESIZE_VAR / TILESIZE;
+  int src_y = g->src_y + g->src_offset_y * TILESIZE_VAR / TILESIZE;
+  int dst_x = sx * TILEX + g->dst_offset_x * TILESIZE_VAR / TILESIZE;
+  int dst_y = sy * TILEY + g->dst_offset_y * TILESIZE_VAR / TILESIZE;
+  int width = g->width * TILESIZE_VAR / TILESIZE;
+  int height = g->height * TILESIZE_VAR / TILESIZE;
+#else
   int src_x = g->src_x + g->src_offset_x;
   int src_y = g->src_y + g->src_offset_y;
   int dst_x = sx * TILEX + g->dst_offset_x;
   int dst_y = sy * TILEY + g->dst_offset_y;
   int width = g->width;
   int height = g->height;
+#endif
   int left = screen_x / TILEX;
   int top  = screen_y / TILEY;
 
@@ -207,7 +363,12 @@ static void DrawLevelField_EM(int x, int y, int sx, int sy,
 static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy,
                                      int crm, boolean draw_masked)
 {
+#if 1
+  struct GraphicInfo_EM *g;
+#else
   struct GraphicInfo_EM *g = getObjectGraphic(x, y);
+#endif
+  int crumbled_border_size;
   int left = screen_x / TILEX;
   int top  = screen_y / TILEY;
   int i;
@@ -220,6 +381,23 @@ static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy,
   if (crm == 0)                /* no crumbled edges for this tile */
     return;
 
+#if 1
+  g = getObjectGraphic(x, y);
+#endif
+
+  crumbled_border_size = g->crumbled_border_size;
+
+#if NEW_TILESIZE
+  crumbled_border_size = crumbled_border_size * TILESIZE_VAR / TILESIZE;
+#endif
+
+#if 0
+  if (x == 3 && y == 3 && frame == 0)
+    printf("::: %d, %d\n",
+          graphic_info_em_object[207][0].crumbled_src_x,
+          graphic_info_em_object[207][0].crumbled_src_y);
+#endif
+
   for (i = 0; i < 4; i++)
   {
     if (crm & (1 << i))
@@ -228,17 +406,17 @@ static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy,
 
       if (i == 1 || i == 2)
       {
-       width = g->crumbled_border_size;
+       width = crumbled_border_size;
        height = TILEY;
-       cx = (i == 2 ? TILEX - g->crumbled_border_size : 0);
+       cx = (i == 2 ? TILEX - crumbled_border_size : 0);
        cy = 0;
       }
       else
       {
        width = TILEX;
-       height = g->crumbled_border_size;
+       height = crumbled_border_size;
        cx = 0;
-       cy = (i == 3 ? TILEY - g->crumbled_border_size : 0);
+       cy = (i == 3 ? TILEY - crumbled_border_size : 0);
       }
 
       if (width > 0 && height > 0)
@@ -347,7 +525,8 @@ static void animscreen(void)
   if (!game.use_native_emc_graphics_engine)
     for (y = 2; y < EM_MAX_CAVE_HEIGHT - 2; y++)
       for (x = 2; x < EM_MAX_CAVE_WIDTH - 2; x++)
-       SetGfxAnimation_EM(Draw[y][x], frame, x - 2, y - 2);
+       SetGfxAnimation_EM(&graphic_info_em_object[Draw[y][x]][frame],
+                          Draw[y][x], 7 - frame, x - 2, y - 2);
 
   for (y = top; y < top + MAX_BUF_YSIZE; y++)
   {
@@ -384,9 +563,11 @@ static void animscreen(void)
       redraw_screen_tile = (screentiles[sy][sx]    != obj ||
                            crumbled_state[sy][sx] != crm);
 
+#if 0
       /* !!! TEST ONLY -- CHANGE THIS !!! */
       if (!game.use_native_emc_graphics_engine)
        redraw_screen_tile = TRUE;
+#endif
 
       /* only redraw screen tiles if they (or their crumbled state) changed */
       if (redraw_screen_tile)
@@ -423,6 +604,10 @@ static void blitplayer(struct PLAYER *ply)
   x2 = x1 + TILEX - 1;
   y2 = y1 + TILEY - 1;
 
+#if 0
+  printf("::: %d, %d\n", x1, y1);
+#endif
+
   if ((int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) &&
       (int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1))
   {
@@ -434,9 +619,9 @@ static void blitplayer(struct PLAYER *ply)
     int new_x = old_x + SIGN(dx);
     int new_y = old_y + SIGN(dy);
     int old_sx = old_x % MAX_BUF_XSIZE;
-    int old_sy = old_y % MAX_BUF_XSIZE;
+    int old_sy = old_y % MAX_BUF_YSIZE;
     int new_sx = new_x % MAX_BUF_XSIZE;
-    int new_sy = new_y % MAX_BUF_XSIZE;
+    int new_sy = new_y % MAX_BUF_YSIZE;
 #if 0
     int old_crm = crumbled_state[old_sy][old_sx];
 #endif
@@ -834,9 +1019,9 @@ void RedrawPlayfield_EM(boolean force_redraw)
   if (draw_new_player_location && !quick_relocation)
   {
 #if 1
-    unsigned long game_frame_delay_value = getGameFrameDelay_EM(20);
+    unsigned int game_frame_delay_value = getGameFrameDelay_EM(20);
 #else
-    unsigned long game_frame_delay_value = getGameFrameDelay_EM(25);
+    unsigned int game_frame_delay_value = getGameFrameDelay_EM(25);
 #endif
     int wait_delay_value = game_frame_delay_value;
     int screen_xx = VALID_SCREEN_X(sx);