+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)
+ {
+ /* blit all (up to four) parts of the scroll buffer to the backbuffer */
+ BlitScreenToBitmap_EM(backbuffer);
+
+ /* blit the completely updated backbuffer to the window (in one blit) */
+ BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY);
+ }
+ 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
+
+#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++)
+ {
+ 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, SY + y * TILEY);
+ }
+ }
+#endif
+ }
+
+ FlushDisplay();
+
+ for (x = 0; x < MAX_BUF_XSIZE; x++)
+ for (y = 0; y < MAX_BUF_YSIZE; y++)
+ redraw[x][y] = FALSE;
+ redraw_tiles = 0;
+
+ screen_x_last = screen_x;
+ screen_y_last = screen_y;
+ scrolling_last = scrolling;
+}
+
+void blitscreen(void)
+{
+ BackToFront_EM();
+}
+
+static struct GraphicInfo_EM *getObjectGraphic(int x, int y)
+{
+ int tile = Draw[y][x];
+ struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
+
+ if (!game.use_native_emc_graphics_engine)
+ getGraphicSourceObjectExt_EM(g, tile, 7 - frame, x - 2, y - 2);
+
+ return g;
+}
+
+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(g, player_nr, anim, 7 - frame);
+
+ return g;
+}
+
+static void DrawLevelField_EM(int x, int y, int sx, int sy,
+ boolean draw_masked)
+{
+ struct GraphicInfo_EM *g = getObjectGraphic(x, y);
+ 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;
+ int left = screen_x / TILEX;
+ int top = screen_y / TILEY;
+
+ /* do not draw fields that are outside the visible screen area */
+ if (x < left || x >= left + MAX_BUF_XSIZE ||
+ y < top || y >= top + MAX_BUF_YSIZE)
+ return;
+
+ if (draw_masked)
+ {
+ if (width > 0 && height > 0)
+ {
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ }
+ else
+ {
+ if ((width != TILEX || height != TILEY) && !g->preserve_background)
+ ClearRectangle(screenBitmap, sx * TILEX, sy * TILEY, TILEX, TILEY);
+
+ if (width > 0 && height > 0)
+ BlitBitmap(g->bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+}
+
+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 left = screen_x / TILEX;
+ int top = screen_y / TILEY;
+ int i;
+
+ /* do not draw fields that are outside the visible screen area */
+ if (x < left || x >= left + MAX_BUF_XSIZE ||
+ y < top || y >= top + MAX_BUF_YSIZE)
+ return;
+
+ if (crm == 0) /* no crumbled edges for this tile */
+ return;
+
+#if 1
+ g = getObjectGraphic(x, y);
+#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))
+ {
+ int width, height, cx, cy;
+
+ if (i == 1 || i == 2)
+ {
+ width = g->crumbled_border_size;
+ height = TILEY;
+ cx = (i == 2 ? TILEX - g->crumbled_border_size : 0);
+ cy = 0;
+ }
+ else
+ {
+ width = TILEX;
+ height = g->crumbled_border_size;
+ cx = 0;
+ cy = (i == 3 ? TILEY - g->crumbled_border_size : 0);
+ }
+
+ if (width > 0 && height > 0)
+ {
+ int src_x = g->crumbled_src_x + cx;
+ int src_y = g->crumbled_src_y + cy;
+ int dst_x = sx * TILEX + cx;
+ int dst_y = sy * TILEY + cy;
+
+ if (draw_masked)
+ {
+ SetClipOrigin(g->crumbled_bitmap, g->crumbled_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->crumbled_bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ else
+ BlitBitmap(g->crumbled_bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ }
+ }
+}
+
+static void DrawLevelPlayer_EM(int x1, int y1, int player_nr, int anim,
+ boolean draw_masked)
+{
+ struct GraphicInfo_EM *g = getPlayerGraphic(player_nr, anim);
+ int src_x = g->src_x, src_y = g->src_y;
+ int dst_x, dst_y;
+
+ /* do not draw fields that are outside the visible screen area */
+ if (x1 < screen_x - TILEX || x1 >= screen_x + MAX_BUF_XSIZE * TILEX ||
+ y1 < screen_y - TILEY || y1 >= screen_y + MAX_BUF_YSIZE * TILEY)
+ return;
+
+ x1 %= MAX_BUF_XSIZE * TILEX;
+ y1 %= MAX_BUF_YSIZE * TILEY;
+
+ if (draw_masked)
+ {
+ /* draw the player to current location */
+ dst_x = x1;
+ dst_y = y1;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ src_x, src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around column */
+ dst_x = x1 - MAX_BUF_XSIZE * TILEX;
+ dst_y = y1;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around row */
+ dst_x = x1;
+ dst_y = y1 - MAX_BUF_YSIZE * TILEY;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+ }
+ else
+ {
+ /* draw the player to current location */
+ dst_x = x1;
+ dst_y = y1;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around column */
+ dst_x = x1 - MAX_BUF_XSIZE * TILEX;
+ dst_y = y1;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around row */
+ dst_x = x1;
+ dst_y = y1 - MAX_BUF_YSIZE * TILEY;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+ }
+}