rnd-20061019-1-src
[rocksndiamonds.git] / src / tools.c
index 23a255108812d00a7028e4d171f69cc6f408bdd7..41ed06d693d078aa0c8d52cdce9efa773474f012 100644 (file)
@@ -138,7 +138,6 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
       level.game_engine_type == GAME_ENGINE_TYPE_EM)
   {
     /* currently there is no partial redraw -- always redraw whole playfield */
-
     RedrawPlayfield_EM(TRUE);
 
     /* blit playfield from scroll buffer to normal back buffer for fading in */
@@ -184,9 +183,78 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
     }
   }
 
+  if (force_redraw)
+  {
+    x = gfx.sx;
+    y = gfx.sy;
+    width = gfx.sxsize;
+    height = gfx.sysize;
+  }
+
   BlitBitmap(drawto, window, x, y, width, height, x, y);
 }
 
+void DrawMaskedBorder_Rect(int x, int y, int width, int height)
+{
+  Bitmap *bitmap = graphic_info[IMG_GLOBAL_BORDER].bitmap;
+
+  SetClipOrigin(bitmap, bitmap->stored_clip_gc, 0, 0);
+  BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y);
+}
+
+void DrawMaskedBorder_FIELD()
+{
+  if (game_status >= GAME_MODE_TITLE &&
+      game_status <= GAME_MODE_PLAYING &&
+      border.draw_masked[game_status])
+    DrawMaskedBorder_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+}
+
+void DrawMaskedBorder_DOOR_1()
+{
+  if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] &&
+      (game_status != GAME_MODE_EDITOR ||
+       border.draw_masked[GFX_SPECIAL_ARG_EDITOR]))
+    DrawMaskedBorder_Rect(DX, DY, DXSIZE, DYSIZE);
+}
+
+void DrawMaskedBorder_DOOR_2()
+{
+  if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] &&
+      game_status != GAME_MODE_EDITOR)
+    DrawMaskedBorder_Rect(VX, VY, VXSIZE, VYSIZE);
+}
+
+void DrawMaskedBorder_DOOR_3()
+{
+  /* currently not available */
+}
+
+void DrawMaskedBorder_ALL()
+{
+  DrawMaskedBorder_FIELD();
+  DrawMaskedBorder_DOOR_1();
+  DrawMaskedBorder_DOOR_2();
+  DrawMaskedBorder_DOOR_3();
+}
+
+void DrawMaskedBorder(int redraw_mask)
+{
+  if (redraw_mask & REDRAW_ALL)
+    DrawMaskedBorder_ALL();
+  else
+  {
+    if (redraw_mask & REDRAW_FIELD)
+      DrawMaskedBorder_FIELD();
+    if (redraw_mask & REDRAW_DOOR_1)
+      DrawMaskedBorder_DOOR_1();
+    if (redraw_mask & REDRAW_DOOR_2)
+      DrawMaskedBorder_DOOR_2();
+    if (redraw_mask & REDRAW_DOOR_3)
+      DrawMaskedBorder_DOOR_3();
+  }
+}
+
 void BackToFront()
 {
   int x,y;
@@ -204,6 +272,11 @@ void BackToFront()
   if (redraw_mask == REDRAW_NONE)
     return;
 
+  if (redraw_mask & REDRAW_TILES &&
+      game_status == GAME_MODE_PLAYING &&
+      border.draw_masked[game_status])
+    redraw_mask |= REDRAW_FIELD;
+
   if (global.fps_slowdown && game_status == GAME_MODE_PLAYING)
   {
     static boolean last_frame_skipped = FALSE;
@@ -241,8 +314,15 @@ void BackToFront()
 
   SyncDisplay();
 
+#if 1
+  DrawMaskedBorder(redraw_mask);
+#endif
+
   if (redraw_mask & REDRAW_ALL)
   {
+#if 0
+    DrawMaskedBorder(REDRAW_ALL);
+#endif
     BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
     redraw_mask = REDRAW_NONE;
@@ -253,6 +333,9 @@ void BackToFront()
     if (game_status != GAME_MODE_PLAYING ||
        redraw_mask & REDRAW_FROM_BACKBUFFER)
     {
+#if 0
+      DrawMaskedBorder(REDRAW_FIELD);
+#endif
       BlitBitmap(backbuffer, window,
                 REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
     }
@@ -271,7 +354,21 @@ void BackToFront()
          ABS(ScreenMovPos) == ScrollStepSize ||
          redraw_tiles > REDRAWTILES_THRESHOLD)
       {
+#if 1
+       if (border.draw_masked[GFX_SPECIAL_ARG_MAIN])
+       {
+         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);
+#else
        BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
+#endif
 
 #if 0
 #ifdef DEBUG
@@ -295,13 +392,28 @@ void BackToFront()
   if (redraw_mask & REDRAW_DOORS)
   {
     if (redraw_mask & REDRAW_DOOR_1)
+    {
+#if 0
+      DrawMaskedBorder(REDRAW_DOOR_1);
+#endif
       BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
+    }
 
     if (redraw_mask & REDRAW_DOOR_2)
+    {
+#if 0
+      DrawMaskedBorder(REDRAW_DOOR_2);
+#endif
       BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
+    }
 
     if (redraw_mask & REDRAW_DOOR_3)
+    {
+#if 0
+      DrawMaskedBorder(REDRAW_DOOR_3);
+#endif
       BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
+    }
 
     redraw_mask &= ~REDRAW_DOORS;
   }
@@ -419,6 +531,7 @@ void FadeToFront()
 
 void FadeExt(int fade_mask, int fade_mode)
 {
+  void (*draw_border_function)(void) = NULL;
   Bitmap *bitmap = (fade_mode == FADE_MODE_CROSSFADE ? bitmap_db_cross : NULL);
   int fade_delay = menu.fade_delay;
   int post_delay = (fade_mode == FADE_MODE_FADE_OUT ? menu.post_delay : 0);
@@ -430,6 +543,8 @@ void FadeExt(int fade_mask, int fade_mode)
     y = REAL_SY;
     width  = FULL_SXSIZE;
     height = FULL_SYSIZE;
+
+    draw_border_function = DrawMaskedBorder_FIELD;
   }
   else         /* REDRAW_ALL */
   {
@@ -451,7 +566,8 @@ void FadeExt(int fade_mask, int fade_mode)
     return;
   }
 
-  FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay);
+  FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay,
+               draw_border_function);
 
   redraw_mask &= ~fade_mask;
 }
@@ -1554,8 +1670,6 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
 static void DrawPreviewLevelExt(int from_x, int from_y)
 {
   boolean show_level_border = (BorderElement != EL_EMPTY);
-  int dst_x = preview.x;
-  int dst_y = preview.y;
   int level_xsize = lev_fieldx + (show_level_border ? 2 : 0);
   int level_ysize = lev_fieldy + (show_level_border ? 2 : 0);
   int tile_size = preview.tile_size;
@@ -1563,6 +1677,8 @@ static void DrawPreviewLevelExt(int from_x, int from_y)
   int preview_height = preview.ysize * tile_size;
   int real_preview_xsize = MIN(level_xsize, preview.xsize);
   int real_preview_ysize = MIN(level_ysize, preview.ysize);
+  int dst_x = SX + ALIGNED_XPOS(preview.x, preview_width, preview.align);
+  int dst_y = SY + preview.y;
   int x, y;
 
   DrawBackground(dst_x, dst_y, preview_width, preview_height);
@@ -1596,8 +1712,24 @@ static void DrawPreviewLevelExt(int from_x, int from_y)
 #define MICROLABEL_IMPORTED_BY_HEAD    6
 #define MICROLABEL_IMPORTED_BY         7
 
+static int getMaxTextLength(struct MenuPosInfo *pos, int font_nr)
+{
+  int max_text_width = SXSIZE;
+  int font_width = getFontWidth(font_nr);
+
+  if (pos->align == ALIGN_CENTER)
+    max_text_width = (pos->x < SXSIZE / 2 ? pos->x * 2 : (SXSIZE - pos->x) * 2);
+  else if (pos->align == ALIGN_RIGHT)
+    max_text_width = pos->x;
+  else
+    max_text_width = SXSIZE - pos->x;
+
+  return max_text_width / font_width;
+}
+
 static void DrawPreviewLevelLabelExt(int mode)
 {
+  struct MenuPosInfo *pos = &menu.main.text.level_info_2;
   char label_text[MAX_OUTPUT_LINESIZE + 1];
   int max_len_label_text;
   int font_nr = FONT_TEXT_2;
@@ -1608,7 +1740,11 @@ static void DrawPreviewLevelLabelExt(int mode)
       mode == MICROLABEL_IMPORTED_BY_HEAD)
     font_nr = FONT_TEXT_3;
 
+#if 1
+  max_len_label_text = getMaxTextLength(pos, font_nr);
+#else
   max_len_label_text = SXSIZE / getFontWidth(font_nr);
+#endif
 
   for (i = 0; i < max_len_label_text; i++)
     label_text[i] = ' ';
@@ -1616,10 +1752,14 @@ static void DrawPreviewLevelLabelExt(int mode)
 
   if (strlen(label_text) > 0)
   {
+#if 1
+    DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+#else
     int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
     int lypos = MICROLABEL2_YPOS;
 
     DrawText(lxpos, lypos, label_text, font_nr);
+#endif
   }
 
   strncpy(label_text,
@@ -1635,10 +1775,14 @@ static void DrawPreviewLevelLabelExt(int mode)
 
   if (strlen(label_text) > 0)
   {
+#if 1
+    DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+#else
     int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
     int lypos = MICROLABEL2_YPOS;
 
     DrawText(lxpos, lypos, label_text, font_nr);
+#endif
   }
 
   redraw_mask |= REDRAW_MICROLEVEL;
@@ -1661,7 +1805,20 @@ void DrawPreviewLevel(boolean restart)
 
   if (restart)
   {
-    from_x = from_y = 0;
+    from_x = 0;
+    from_y = 0;
+
+    if (preview.anim_mode == ANIM_CENTERED)
+    {
+      if (level_xsize > preview.xsize)
+       from_x = (level_xsize - preview.xsize) / 2;
+      if (level_ysize > preview.ysize)
+       from_y = (level_ysize - preview.ysize) / 2;
+    }
+
+    from_x += preview.xoffset;
+    from_y += preview.yoffset;
+
     scroll_direction = MV_RIGHT;
     label_state = 1;
     label_counter = 0;
@@ -1675,18 +1832,30 @@ void DrawPreviewLevel(boolean restart)
 
     if (leveldir_current->name)
     {
+      struct MenuPosInfo *pos = &menu.main.text.level_info_1;
       char label_text[MAX_OUTPUT_LINESIZE + 1];
       int font_nr = FONT_TEXT_1;
+#if 1
+      int max_len_label_text = getMaxTextLength(pos, font_nr);
+#else
       int max_len_label_text = SXSIZE / getFontWidth(font_nr);
+#endif
+#if 0
+      int text_width;
       int lxpos, lypos;
+#endif
 
       strncpy(label_text, leveldir_current->name, max_len_label_text);
       label_text[max_len_label_text] = '\0';
 
+#if 1
+      DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+#else
       lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
       lypos = SY + MICROLABEL1_YPOS;
 
       DrawText(lxpos, lypos, label_text, font_nr);
+#endif
     }
 
     game_status = last_game_status;    /* restore current game status */
@@ -1695,7 +1864,8 @@ void DrawPreviewLevel(boolean restart)
   }
 
   /* scroll preview level, if needed */
-  if ((level_xsize > preview.xsize || level_ysize > preview.ysize) &&
+  if (preview.anim_mode != ANIM_NONE &&
+      (level_xsize > preview.xsize || level_ysize > preview.ysize) &&
       DelayReached(&scroll_delay, scroll_delay_value))
   {
     switch (scroll_direction)
@@ -2535,8 +2705,13 @@ boolean Request(char *text, unsigned int req_state)
 
     DoAnimation();
 
+#if 1
+    if (!PendingEvent())       /* delay only if no pending events */
+      Delay(10);
+#else
     /* don't eat all CPU time */
     Delay(10);
+#endif
   }
 
   if (game_status != GAME_MODE_MAIN)
@@ -3086,6 +3261,7 @@ void CreateToolButtons()
                      GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
                      GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
                      GDI_DECORATION_SHIFTING, 1, 1,
+                     GDI_DIRECT_DRAW, FALSE,
                      GDI_EVENT_MASK, event_mask,
                      GDI_CALLBACK_ACTION, HandleToolButtons,
                      GDI_END);
@@ -5995,23 +6171,45 @@ void PlayMenuMusic()
 
 void ToggleFullscreenIfNeeded()
 {
+  boolean change_fullscreen = (setup.fullscreen !=
+                              video.fullscreen_enabled);
+  boolean change_fullscreen_mode = (video.fullscreen_enabled &&
+                                   !strEqual(setup.fullscreen_mode,
+                                             video.fullscreen_mode_current));
+
+  if (!video.fullscreen_available)
+    return;
+
+#if 1
+  if (change_fullscreen || change_fullscreen_mode)
+#else
   if (setup.fullscreen != video.fullscreen_enabled ||
       setup.fullscreen_mode != video.fullscreen_mode_current)
+#endif
   {
     Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
 
     /* save backbuffer content which gets lost when toggling fullscreen mode */
     BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
+#if 1
+    if (change_fullscreen_mode)
+#else
     if (setup.fullscreen && video.fullscreen_enabled)
+#endif
     {
-      /* keep fullscreen mode, but change screen mode */
+      /* keep fullscreen, but change fullscreen mode (screen resolution) */
+#if 1
+      /* (this is now set in sdl.c) */
+#else
       video.fullscreen_mode_current = setup.fullscreen_mode;
-      video.fullscreen_enabled = FALSE;
+#endif
+      video.fullscreen_enabled = FALSE;                /* force new fullscreen mode */
     }
 
     /* toggle fullscreen */
     ChangeVideoModeIfNeeded(setup.fullscreen);
+
     setup.fullscreen = video.fullscreen_enabled;
 
     /* restore backbuffer content from temporary backbuffer backup bitmap */
@@ -6019,6 +6217,11 @@ void ToggleFullscreenIfNeeded()
 
     FreeBitmap(tmp_backbuffer);
 
+#if 1
+    /* update visible window/screen */
+    BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+#else
     redraw_mask = REDRAW_ALL;
+#endif
   }
 }