rnd-20070405-1-src
[rocksndiamonds.git] / src / tools.c
index f21f232956e07c2ed8ac11d4924b2a6e569f235d..e7cd92d525a5b0ab66ec0ecd93c81d583affc5c3 100644 (file)
@@ -521,11 +521,60 @@ void FadeToFront()
 
 void FadeExt(int fade_mask, int fade_mode)
 {
+  static int fade_mode_skip = FADE_MODE_NONE;
   void (*draw_border_function)(void) = NULL;
-  Bitmap *bitmap = (fade_mode == FADE_MODE_CROSSFADE ? bitmap_db_cross : NULL);
+#if 0
+  Bitmap *bitmap = (fade_mode != FADE_MODE_FADE_IN ? bitmap_db_cross : NULL);
+#else
+  Bitmap *bitmap = (fade_mode & FADE_TYPE_TRANSFORM ? bitmap_db_cross : NULL);
+#endif
   int x, y, width, height;
   int fade_delay, post_delay;
 
+  redraw_mask |= fade_mask;
+
+  if (fade_mode & FADE_TYPE_SKIP)
+  {
+#if 0
+    printf("::: will skip %d ... [%d]\n", fade_mode, fade_mode_skip);
+#endif
+
+    fade_mode_skip = fade_mode;
+
+    return;
+  }
+
+  if (fade_mode_skip & FADE_TYPE_SKIP)
+  {
+#if 0
+    printf("::: skipping %d ... [%d]\n", fade_mode, fade_mode_skip);
+#endif
+
+    /* skip all fade operations until specified fade operation */
+    if (fade_mode & fade_mode_skip)
+      fade_mode_skip = FADE_MODE_NONE;
+
+    return;
+  }
+
+#if 1
+  if (global.autoplay_leveldir)
+  {
+    // fading.fade_mode = FADE_MODE_NONE;
+
+    return;
+  }
+#endif
+
+#if 1
+  if (fading.fade_mode == FADE_MODE_NONE)
+  {
+    BackToFront();
+
+    return;
+  }
+#endif
+
   if (fade_mask & REDRAW_FIELD)
   {
     x = REAL_SX;
@@ -549,9 +598,11 @@ void FadeExt(int fade_mask, int fade_mode)
     post_delay = (fade_mode == FADE_MODE_FADE_OUT ? fading.post_delay : 0);
   }
 
-  redraw_mask |= fade_mask;
-
+#if 1
   if (!setup.fade_screens || fade_delay == 0)
+#else
+  if (!setup.fade_screens || fade_delay == 0 || fading.anim_mode == ANIM_NONE)
+#endif
   {
     if (fade_mode == FADE_MODE_FADE_OUT)
       ClearRectangle(backbuffer, x, y, width, height);
@@ -569,12 +620,44 @@ void FadeExt(int fade_mask, int fade_mode)
 
 void FadeIn(int fade_mask)
 {
+#if 1
+  // printf("::: now fading in...\n");
+
+  if (fading.fade_mode & FADE_TYPE_TRANSFORM)
+    FadeExt(fade_mask, fading.fade_mode);
+  else
+    FadeExt(fade_mask, FADE_MODE_FADE_IN);
+#else
+#if 1
+  if (fading.fade_mode == FADE_MODE_CROSSFADE)
+    FadeExt(fade_mask, FADE_MODE_CROSSFADE);
+  else
+    FadeExt(fade_mask, FADE_MODE_FADE_IN);
+#else
   FadeExt(fade_mask, FADE_MODE_FADE_IN);
+#endif
+#endif
 }
 
 void FadeOut(int fade_mask)
 {
+#if 1
+  // printf("::: fading.fade_mode == %d\n", fading.fade_mode);
+
+  if (fading.fade_mode & FADE_TYPE_TRANSFORM)
+    FadeCrossSaveBackbuffer();
+  else
+    FadeExt(fade_mask, FADE_MODE_FADE_OUT);
+#else
+#if 1
+  if (fading.fade_mode == FADE_MODE_CROSSFADE)
+    FadeCrossSaveBackbuffer();
+  else
+    FadeExt(fade_mask, FADE_MODE_FADE_OUT);
+#else
   FadeExt(fade_mask, FADE_MODE_FADE_OUT);
+#endif
+#endif
 }
 
 void FadeCross(int fade_mask)
@@ -587,6 +670,69 @@ void FadeCrossSaveBackbuffer()
   BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 }
 
+static void FadeSetLeaveNext(struct TitleFadingInfo fading_leave, boolean set)
+{
+  static struct TitleFadingInfo fading_leave_stored;
+
+  if (set)
+    fading_leave_stored = fading_leave;
+  else
+    fading = fading_leave_stored;
+}
+
+void FadeSetEnterMenu()
+{
+  fading = menu.enter_menu;
+
+  FadeSetLeaveNext(fading, TRUE);      /* (keep same fade mode) */
+}
+
+void FadeSetLeaveMenu()
+{
+  fading = menu.leave_menu;
+
+  FadeSetLeaveNext(fading, TRUE);      /* (keep same fade mode) */
+}
+
+void FadeSetEnterScreen()
+{
+  fading = menu.enter_screen[game_status];
+
+  FadeSetLeaveNext(menu.leave_screen[game_status], TRUE);      /* store */
+}
+
+void FadeSetLeaveScreen()
+{
+  FadeSetLeaveNext(menu.leave_screen[game_status], FALSE);     /* recall */
+}
+
+void FadeSetFromType(int type)
+{
+  if (type & TYPE_ENTER_SCREEN)
+    FadeSetEnterScreen();
+  else if (type & TYPE_ENTER)
+    FadeSetEnterMenu();
+  else if (type & TYPE_LEAVE)
+    FadeSetLeaveMenu();
+}
+
+void FadeSetDisabled()
+{
+  static struct TitleFadingInfo fading_none = { FADE_MODE_NONE, -1, -1, -1 };
+
+  fading = fading_none;
+}
+
+void FadeSkipNextFadeIn()
+{
+  FadeExt(0, FADE_MODE_SKIP_FADE_IN);
+}
+
+void FadeSkipNextFadeOut()
+{
+  FadeExt(0, FADE_MODE_SKIP_FADE_OUT);
+}
+
 void SetWindowBackgroundImageIfDefined(int graphic)
 {
   if (graphic_info[graphic].bitmap)
@@ -774,6 +920,82 @@ inline int getGraphicAnimationFrame(int graphic, int sync_frame)
                           sync_frame);
 }
 
+void getSizedGraphicSource(int graphic, int frame, int tilesize_raw,
+                          Bitmap **bitmap, int *x, int *y)
+{
+  struct
+  {
+    int width_mult, width_div;
+    int height_mult, height_div;
+  }
+  offset_calc[6] =
+  {
+    { 15, 16,  2, 3    },      /* 1 x 1 */
+    { 7, 8,    2, 3    },      /* 2 x 2 */
+    { 3, 4,    2, 3    },      /* 4 x 4 */
+    { 1, 2,    2, 3    },      /* 8 x 8 */
+    { 0, 1,    2, 3    },      /* 16 x 16 */
+    { 0, 1,    0, 1    },      /* 32 x 32 */
+  };
+  struct GraphicInfo *g = &graphic_info[graphic];
+  Bitmap *src_bitmap = g->bitmap;
+  int tilesize = MIN(MAX(1, tilesize_raw), TILESIZE);
+  int offset_calc_pos = log_2(tilesize);
+  int width_mult  = offset_calc[offset_calc_pos].width_mult;
+  int width_div   = offset_calc[offset_calc_pos].width_div;
+  int height_mult = offset_calc[offset_calc_pos].height_mult;
+  int height_div  = offset_calc[offset_calc_pos].height_div;
+  int startx = src_bitmap->width * width_mult / width_div;
+  int starty = src_bitmap->height * height_mult / height_div;
+  int src_x = g->src_x * tilesize / TILESIZE;
+  int src_y = g->src_y * tilesize / TILESIZE;
+  int width = g->width * tilesize / TILESIZE;
+  int height = g->height * tilesize / TILESIZE;
+  int offset_x = g->offset_x * tilesize / TILESIZE;
+  int offset_y = g->offset_y * tilesize / TILESIZE;
+
+  if (g->offset_y == 0)                /* frames are ordered horizontally */
+  {
+    int max_width = g->anim_frames_per_line * width;
+    int pos = (src_y / height) * max_width + src_x + frame * offset_x;
+
+    src_x = pos % max_width;
+    src_y = src_y % height + pos / max_width * height;
+  }
+  else if (g->offset_x == 0)   /* frames are ordered vertically */
+  {
+    int max_height = g->anim_frames_per_line * height;
+    int pos = (src_x / width) * max_height + src_y + frame * offset_y;
+
+    src_x = src_x % width + pos / max_height * width;
+    src_y = pos % max_height;
+  }
+  else                         /* frames are ordered diagonally */
+  {
+    src_x = src_x + frame * offset_x;
+    src_y = src_y + frame * offset_y;
+  }
+
+  *bitmap = src_bitmap;
+  *x = startx + src_x;
+  *y = starty + src_y;
+}
+
+void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+{
+#if 1
+  getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y);
+#else
+  struct GraphicInfo *g = &graphic_info[graphic];
+  int mini_startx = 0;
+  int mini_starty = g->bitmap->height * 2 / 3;
+
+  *bitmap = g->bitmap;
+  *x = mini_startx + g->src_x / 2;
+  *y = mini_starty + g->src_y / 2;
+#endif
+}
+
 inline void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
                                int *x, int *y, boolean get_backside)
 {
@@ -865,21 +1087,27 @@ void DrawGraphicThruMaskExt(DrawBuffer *d, int dst_x, int dst_y, int graphic,
   BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dst_x, dst_y);
 }
 
-void DrawMiniGraphic(int x, int y, int graphic)
+void DrawSizedGraphic(int x, int y, int graphic, int frame, int tilesize)
 {
-  DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
-  MarkTileDirty(x / 2, y / 2);
+  DrawSizedGraphicExt(drawto, SX + x * tilesize, SY + y * tilesize, graphic,
+                     frame, tilesize);
+  MarkTileDirty(x / tilesize, y / tilesize);
 }
 
-void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame,
+                        int tilesize)
 {
-  struct GraphicInfo *g = &graphic_info[graphic];
-  int mini_startx = 0;
-  int mini_starty = g->bitmap->height * 2 / 3;
+  Bitmap *src_bitmap;
+  int src_x, src_y;
 
-  *bitmap = g->bitmap;
-  *x = mini_startx + g->src_x / 2;
-  *y = mini_starty + g->src_y / 2;
+  getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y);
+  BlitBitmap(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y);
+}
+
+void DrawMiniGraphic(int x, int y, int graphic)
+{
+  DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
+  MarkTileDirty(x / 2, y / 2);
 }
 
 void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
@@ -1688,44 +1916,13 @@ void ShowEnvelope(int envelope_nr)
   BackToFront();
 }
 
-void getPreviewGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y,
-                            int tilesize)
-{
-  struct
-  {
-    int width_mult, width_div;
-    int height_mult, height_div;
-  } offset_calc[4] =
-  {
-    { 0, 1,    0, 1    },
-    { 0, 1,    2, 3    },
-    { 1, 2,    2, 3    },
-    { 3, 4,    2, 3    },
-  };
-  int offset_calc_pos = (tilesize < MICRO_TILESIZE || tilesize > TILESIZE ? 3 :
-                        5 - log_2(tilesize));
-  Bitmap *src_bitmap = graphic_info[graphic].bitmap;
-  int width_mult = offset_calc[offset_calc_pos].width_mult;
-  int width_div = offset_calc[offset_calc_pos].width_div;
-  int height_mult = offset_calc[offset_calc_pos].height_mult;
-  int height_div = offset_calc[offset_calc_pos].height_div;
-  int mini_startx = src_bitmap->width * width_mult / width_div;
-  int mini_starty = src_bitmap->height * height_mult / height_div;
-  int src_x = mini_startx + graphic_info[graphic].src_x * tilesize / TILESIZE;
-  int src_y = mini_starty + graphic_info[graphic].src_y * tilesize / TILESIZE;
-
-  *bitmap = src_bitmap;
-  *x = src_x;
-  *y = src_y;
-}
-
 void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
 {
   Bitmap *src_bitmap;
   int src_x, src_y;
   int graphic = el2preimg(element);
 
-  getPreviewGraphicSource(graphic, &src_bitmap, &src_x, &src_y, tilesize);
+  getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
   BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize, dst_x,dst_y);
 }
 
@@ -1844,8 +2041,8 @@ static void DrawPreviewLevelLabelExt(int mode)
 #endif
 
 #if 1
-  if (pos->chars != -1)
-    max_len_label_text = pos->chars;
+  if (pos->size != -1)
+    max_len_label_text = pos->size;
 #endif
 
   for (i = 0; i < max_len_label_text; i++)
@@ -1954,8 +2151,8 @@ void DrawPreviewLevel(boolean restart)
 #endif
 
 #if 1
-      if (pos->chars != -1)
-       max_len_label_text = pos->chars;
+      if (pos->size != -1)
+       max_len_label_text = pos->size;
 #endif
 
       strncpy(label_text, leveldir_current->name, max_len_label_text);
@@ -2786,6 +2983,11 @@ boolean Request(char *text, unsigned int req_state)
        case EVENT_KEYPRESS:
          switch (GetEventKey((KeyEvent *)&event, TRUE))
          {
+           case KSYM_space:
+             if (req_state & REQ_CONFIRM)
+               result = 1;
+             break;
+
            case KSYM_Return:
              result = 1;
              break;
@@ -2797,6 +2999,7 @@ boolean Request(char *text, unsigned int req_state)
            default:
              break;
          }
+
          if (req_state & REQ_PLAYER)
            result = 0;
          break;
@@ -2988,7 +3191,7 @@ unsigned int MoveDoor(unsigned int door_state)
 
   if (setup.quick_doors)
   {
-    stepsize = 20;             /* must be choosen to always draw last frame */
+    stepsize = 20;             /* must be chosen to always draw last frame */
     door_delay_value = 0;
   }
 
@@ -5588,6 +5791,13 @@ int el2preimg(int element)
   return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW];
 }
 
+int el2panelimg(int element)
+{
+  element = GFX_ELEMENT(element);
+
+  return element_info[element].special_graphic[GFX_SPECIAL_ARG_PANEL];
+}
+
 int font2baseimg(int font_nr)
 {
   return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
@@ -5674,7 +5884,7 @@ int getBeltDirFromBeltSwitchElement(int element)
   return belt_move_dir[belt_dir_nr];
 }
 
-int getBeltElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
+int getBeltElementFromBeltNrAndBeltDirNr(int belt_nr, int belt_dir_nr)
 {
   static int belt_base_element[4] =
   {
@@ -5683,12 +5893,18 @@ int getBeltElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
     EL_CONVEYOR_BELT_3_LEFT,
     EL_CONVEYOR_BELT_4_LEFT
   };
-  int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1);
 
   return belt_base_element[belt_nr] + belt_dir_nr;
 }
 
-int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
+int getBeltElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
+{
+  int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1);
+
+  return getBeltElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr);
+}
+
+int getBeltSwitchElementFromBeltNrAndBeltDirNr(int belt_nr, int belt_dir_nr)
 {
   static int belt_base_element[4] =
   {
@@ -5697,11 +5913,17 @@ int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
     EL_CONVEYOR_BELT_3_SWITCH_LEFT,
     EL_CONVEYOR_BELT_4_SWITCH_LEFT
   };
-  int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1);
 
   return belt_base_element[belt_nr] + belt_dir_nr;
 }
 
+int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
+{
+  int belt_dir_nr = (belt_dir == MV_LEFT ? 0 : belt_dir == MV_RIGHT ? 2 : 1);
+
+  return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr);
+}
+
 int getNumActivePlayers_EM()
 {
   int num_players = 0;