rnd-20070401-1-src
[rocksndiamonds.git] / src / tools.c
index 88c813441050f05ac9595b2a56261e3d586b1866..9530644e204d1787fbe18e240867c44b5923b7e9 100644 (file)
@@ -242,8 +242,7 @@ void DrawMaskedBorder_ALL()
 void DrawMaskedBorder(int redraw_mask)
 {
   /* do not draw masked screen borders when displaying title screens */
-  if (effectiveGameStatus() == GAME_MODE_TITLE ||
-      effectiveGameStatus() == GAME_MODE_MESSAGE)
+  if (effectiveGameStatus() == GAME_MODE_TITLE)
     return;
 
   if (redraw_mask & REDRAW_ALL)
@@ -522,11 +521,52 @@ 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;
+#endif
+
+#if 1
+  if (fading.fade_mode == FADE_MODE_NONE)
+    return;
+#endif
+
   if (fade_mask & REDRAW_FIELD)
   {
     x = REAL_SX;
@@ -534,8 +574,8 @@ void FadeExt(int fade_mask, int fade_mode)
     width  = FULL_SXSIZE;
     height = FULL_SYSIZE;
 
-    fade_delay = menu.fade_delay;
-    post_delay = (fade_mode == FADE_MODE_FADE_OUT ? menu.post_delay : 0);
+    fade_delay = fading.fade_delay;
+    post_delay = (fade_mode == FADE_MODE_FADE_OUT ? fading.post_delay : 0);
 
     draw_border_function = DrawMaskedBorder_FIELD;
   }
@@ -546,13 +586,15 @@ void FadeExt(int fade_mask, int fade_mode)
     width  = WIN_XSIZE;
     height = WIN_YSIZE;
 
-    fade_delay = title.fade_delay_final;
-    post_delay = (fade_mode == FADE_MODE_FADE_OUT ? title.post_delay_final : 0);
+    fade_delay = fading.fade_delay;
+    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);
@@ -570,12 +612,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)
@@ -588,6 +662,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)
@@ -1696,15 +1833,29 @@ void getPreviewGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y,
   {
     int width_mult, width_div;
     int height_mult, height_div;
-  } offset_calc[4] =
+#if 1
+  }
+  offset_calc[6] =
+#else
+  offset_calc[4] =
+#endif
   {
     { 0, 1,    0, 1    },
     { 0, 1,    2, 3    },
     { 1, 2,    2, 3    },
     { 3, 4,    2, 3    },
+#if 1
+    { 7, 8,    2, 3    },
+    { 15, 16,  2, 3    },
+#endif
   };
+#if 1
+  int offset_calc_pos = (tilesize < MICRO_TILESIZE / 4 ||
+                        tilesize > TILESIZE ? 5 : 5 - log_2(tilesize));
+#else
   int offset_calc_pos = (tilesize < MICRO_TILESIZE || tilesize > TILESIZE ? 3 :
                         5 - log_2(tilesize));
+#endif
   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;
@@ -1766,7 +1917,7 @@ static void DrawPreviewLevelExt(int from_x, int from_y)
   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 dst_y = SY + ALIGNED_YPOS(preview.y, preview_height, preview.valign);
   int x, y;
 
   DrawBackground(dst_x, dst_y, preview_width, preview_height);
@@ -1820,6 +1971,15 @@ static void DrawPreviewLevelLabelExt(int mode)
   struct TextPosInfo *pos = &menu.main.text.level_info_2;
   char label_text[MAX_OUTPUT_LINESIZE + 1];
   int max_len_label_text;
+#if 1
+  int font_nr = pos->font;
+  int i;
+
+  if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+      mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+      mode == MICROLABEL_IMPORTED_BY_HEAD)
+    font_nr = pos->font_alt;
+#else
   int font_nr = FONT_TEXT_2;
   int i;
 
@@ -1827,6 +1987,7 @@ static void DrawPreviewLevelLabelExt(int mode)
       mode == MICROLABEL_IMPORTED_FROM_HEAD ||
       mode == MICROLABEL_IMPORTED_BY_HEAD)
     font_nr = FONT_TEXT_3;
+#endif
 
 #if 1
   max_len_label_text = getMaxTextLength(pos, font_nr);
@@ -1893,8 +2054,10 @@ void DrawPreviewLevel(boolean restart)
   int level_ysize = lev_fieldy + (show_level_border ? 2 : 0);
   int last_game_status = game_status;          /* save current game status */
 
+#if 0
   /* force PREVIEW font on preview level */
   game_status = GAME_MODE_PSEUDO_PREVIEW;
+#endif
 
   if (restart)
   {
@@ -1927,7 +2090,11 @@ void DrawPreviewLevel(boolean restart)
     {
       struct TextPosInfo *pos = &menu.main.text.level_info_1;
       char label_text[MAX_OUTPUT_LINESIZE + 1];
+#if 1
+      int font_nr = pos->font;
+#else
       int font_nr = FONT_TEXT_1;
+#endif
 #if 1
       int max_len_label_text = getMaxTextLength(pos, font_nr);
 #else
@@ -2610,7 +2777,7 @@ boolean Request(char *text, unsigned int req_state)
   /* clear door drawing field */
   DrawBackground(DX, DY, DXSIZE, DYSIZE);
 
-  /* force DOOR font on preview level */
+  /* force DOOR font inside door area */
   game_status = GAME_MODE_PSEUDO_DOOR;
 
   /* write text for request */
@@ -2973,7 +3140,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;
   }
 
@@ -5578,6 +5745,115 @@ int font2baseimg(int font_nr)
   return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
 }
 
+int getBeltNrFromBeltElement(int element)
+{
+  return (element < EL_CONVEYOR_BELT_2_LEFT ? 0 :
+         element < EL_CONVEYOR_BELT_3_LEFT ? 1 :
+         element < EL_CONVEYOR_BELT_4_LEFT ? 2 : 3);
+}
+
+int getBeltNrFromBeltActiveElement(int element)
+{
+  return (element < EL_CONVEYOR_BELT_2_LEFT_ACTIVE ? 0 :
+         element < EL_CONVEYOR_BELT_3_LEFT_ACTIVE ? 1 :
+         element < EL_CONVEYOR_BELT_4_LEFT_ACTIVE ? 2 : 3);
+}
+
+int getBeltNrFromBeltSwitchElement(int element)
+{
+  return (element < EL_CONVEYOR_BELT_2_SWITCH_LEFT ? 0 :
+         element < EL_CONVEYOR_BELT_3_SWITCH_LEFT ? 1 :
+         element < EL_CONVEYOR_BELT_4_SWITCH_LEFT ? 2 : 3);
+}
+
+int getBeltDirNrFromBeltElement(int element)
+{
+  static int belt_base_element[4] =
+  {
+    EL_CONVEYOR_BELT_1_LEFT,
+    EL_CONVEYOR_BELT_2_LEFT,
+    EL_CONVEYOR_BELT_3_LEFT,
+    EL_CONVEYOR_BELT_4_LEFT
+  };
+
+  int belt_nr = getBeltNrFromBeltElement(element);
+  int belt_dir_nr = element - belt_base_element[belt_nr];
+
+  return (belt_dir_nr % 3);
+}
+
+int getBeltDirNrFromBeltSwitchElement(int element)
+{
+  static int belt_base_element[4] =
+  {
+    EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+    EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+    EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+    EL_CONVEYOR_BELT_4_SWITCH_LEFT
+  };
+
+  int belt_nr = getBeltNrFromBeltSwitchElement(element);
+  int belt_dir_nr = element - belt_base_element[belt_nr];
+
+  return (belt_dir_nr % 3);
+}
+
+int getBeltDirFromBeltElement(int element)
+{
+  static int belt_move_dir[3] =
+  {
+    MV_LEFT,
+    MV_NONE,
+    MV_RIGHT
+  };
+
+  int belt_dir_nr = getBeltDirNrFromBeltElement(element);
+
+  return belt_move_dir[belt_dir_nr];
+}
+
+int getBeltDirFromBeltSwitchElement(int element)
+{
+  static int belt_move_dir[3] =
+  {
+    MV_LEFT,
+    MV_NONE,
+    MV_RIGHT
+  };
+
+  int belt_dir_nr = getBeltDirNrFromBeltSwitchElement(element);
+
+  return belt_move_dir[belt_dir_nr];
+}
+
+int getBeltElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
+{
+  static int belt_base_element[4] =
+  {
+    EL_CONVEYOR_BELT_1_LEFT,
+    EL_CONVEYOR_BELT_2_LEFT,
+    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)
+{
+  static int belt_base_element[4] =
+  {
+    EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+    EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+    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 getNumActivePlayers_EM()
 {
   int num_players = 0;
@@ -5616,10 +5892,94 @@ unsigned int InitRND(long seed)
     return InitEngineRandom_RND(seed);
 }
 
+#if 1
+static struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
+static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][SPR_MAX];
+#endif
+
+void ResetGfxAnimation_EM(int x, int y, int tile)
+{
+  GfxFrame[x][y] = 0;
+}
+
+void getGraphicSourceObjectExt_EM(int tile, int frame_em,
+                                 Bitmap **src_bitmap, int *src_x, int *src_y,
+                                 int x, int y)
+{
+  int element         = object_mapping[tile].element_rnd;
+  int action          = object_mapping[tile].action;
+  int direction       = object_mapping[tile].direction;
+  boolean is_backside = object_mapping[tile].is_backside;
+  boolean action_removing = (action == ACTION_DIGGING ||
+                            action == ACTION_SNAPPING ||
+                            action == ACTION_COLLECTING);
+  int effective_element = (frame_em > 0 ? element :
+                          is_backside ? EL_EMPTY :
+                          action_removing ? EL_EMPTY :
+                          element);
+  int graphic = (direction == MV_NONE ?
+                el_act2img(effective_element, action) :
+                el_act_dir2img(effective_element, action, direction));
+  struct GraphicInfo *g = &graphic_info[graphic];
+  int sync_frame;
+
+  if (graphic_info[graphic].anim_global_sync)
+    sync_frame = FrameCounter;
+  else
+    sync_frame = 7 - frame_em;
+
+  SetRandomAnimationValue(x, y);
+
+  int frame = getAnimationFrame(g->anim_frames,
+                               g->anim_delay,
+                               g->anim_mode,
+                               g->anim_start_frame,
+                               sync_frame);
+
+  getGraphicSourceExt(graphic, frame, src_bitmap, src_x, src_y, FALSE);
+}
+
+void getGraphicSourcePlayerExt_EM(int player_nr, int anim, int frame_em,
+                                 Bitmap **src_bitmap, int *src_x, int *src_y)
+{
+  int element   = player_mapping[player_nr][anim].element_rnd;
+  int action    = player_mapping[player_nr][anim].action;
+  int direction = player_mapping[player_nr][anim].direction;
+  int graphic = (direction == MV_NONE ?
+                el_act2img(element, action) :
+                el_act_dir2img(element, action, direction));
+  struct GraphicInfo *g = &graphic_info[graphic];
+  int sync_frame;
+
+  InitPlayerGfxAnimation(&stored_player[player_nr], action, direction);
+
+  stored_player[player_nr].StepFrame = 7 - frame_em;
+
+  sync_frame = stored_player[player_nr].Frame;
+
+#if 0
+  printf("::: %d: %d, %d [%d]\n",
+        player_nr,
+        stored_player[player_nr].Frame,
+        stored_player[player_nr].StepFrame,
+        FrameCounter);
+#endif
+
+  int frame = getAnimationFrame(g->anim_frames,
+                               g->anim_delay,
+                               g->anim_mode,
+                               g->anim_start_frame,
+                               sync_frame);
+
+  getGraphicSourceExt(graphic, frame, src_bitmap, src_x, src_y, FALSE);
+}
+
 void InitGraphicInfo_EM(void)
 {
+#if 0
   struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
   struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][SPR_MAX];
+#endif
   int i, j, p;
 
 #if DEBUG_EM_GFX
@@ -6166,7 +6526,7 @@ void InitGraphicInfo_EM(void)
                                      g->anim_start_frame,
                                      sync_frame);
 
-       getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE);
+       getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE);
 
        g_em->bitmap = src_bitmap;
        g_em->src_x = src_x;
@@ -6237,10 +6597,8 @@ void InitGraphicInfo_EM(void)
 #endif
 }
 
-void PlayMenuSound()
+void PlayMenuSoundExt(int sound)
 {
-  int sound = menu.sound[game_status];
-
   if (sound == SND_UNDEFINED)
     return;
 
@@ -6254,6 +6612,11 @@ void PlayMenuSound()
     PlaySound(sound);
 }
 
+void PlayMenuSound()
+{
+  PlayMenuSoundExt(menu.sound[game_status]);
+}
+
 void PlayMenuSoundStereo(int sound, int stereo_position)
 {
   if (sound == SND_UNDEFINED)
@@ -6269,10 +6632,8 @@ void PlayMenuSoundStereo(int sound, int stereo_position)
     PlaySoundStereo(sound, stereo_position);
 }
 
-void PlayMenuSoundIfLoop()
+void PlayMenuSoundIfLoopExt(int sound)
 {
-  int sound = menu.sound[game_status];
-
   if (sound == SND_UNDEFINED)
     return;
 
@@ -6284,10 +6645,13 @@ void PlayMenuSoundIfLoop()
     PlaySoundLoop(sound);
 }
 
-void PlayMenuMusic()
+void PlayMenuSoundIfLoop()
 {
-  int music = menu.music[game_status];
+  PlayMenuSoundIfLoopExt(menu.sound[game_status]);
+}
 
+void PlayMenuMusicExt(int music)
+{
   if (music == MUS_UNDEFINED)
     return;
 
@@ -6297,6 +6661,11 @@ void PlayMenuMusic()
   PlayMusic(music);
 }
 
+void PlayMenuMusic()
+{
+  PlayMenuMusicExt(menu.music[game_status]);
+}
+
 void PlaySoundActivating()
 {
 #if 0