changed "http" to "https" in URLs
[rocksndiamonds.git] / src / tools.c
index 83620631c3ea9a8873936122d7b7a1b087f7c6bd..1762651003cd65ab3995e546b484237d09f5f997 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // tools.c
 // ============================================================================
@@ -193,22 +193,6 @@ static char *print_if_not_empty(int element)
   return s;
 }
 
-int correctLevelPosX_EM(int lx)
-{
-  lx -= 1;
-  lx -= (BorderElement != EL_EMPTY ? 1 : 0);
-
-  return lx;
-}
-
-int correctLevelPosY_EM(int ly)
-{
-  ly -= 1;
-  ly -= (BorderElement != EL_EMPTY ? 1 : 0);
-
-  return ly;
-}
-
 int getFieldbufferOffsetX_RND(int dir, int pos)
 {
   int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
@@ -307,8 +291,6 @@ static int getLevelFromScreenX_EM(int sx)
   int px = sx - SX;
   int lx = LEVELX((px + dx) / TILESIZE_VAR);
 
-  lx = correctLevelPosX_EM(lx);
-
   return lx;
 }
 
@@ -324,8 +306,6 @@ static int getLevelFromScreenY_EM(int sy)
   int py = sy - SY;
   int ly = LEVELY((py + dy) / TILESIZE_VAR);
 
-  ly = correctLevelPosY_EM(ly);
-
   return ly;
 }
 
@@ -971,19 +951,13 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type)
     height = WIN_YSIZE;
   }
 
-  if (!setup.fade_screens ||
-      fade_delay == 0 ||
-      fading.fade_mode == FADE_MODE_NONE)
-  {
-    if (fade_mode == FADE_MODE_FADE_OUT)
-      return;
-
-    BlitBitmap(backbuffer, window, x, y, width, height, x, y);
-
-    redraw_mask &= ~fade_mask;
+  // when switching screens without fading, set fade delay to zero
+  if (!setup.fade_screens || fading.fade_mode == FADE_MODE_NONE)
+    fade_delay = 0;
 
+  // do not display black frame when fading out without fade delay
+  if (fade_mode == FADE_MODE_FADE_OUT && fade_delay == 0)
     return;
-  }
 
   FadeRectangle(x, y, width, height, fade_mode, fade_delay, post_delay,
                draw_border_function);
@@ -999,8 +973,7 @@ static void SetScreenStates_BeforeFadingIn(void)
   global.anim_status = global.anim_status_next;
 
   // store backbuffer with all animations that will be started after fading in
-  if (fade_type_skip != FADE_MODE_SKIP_FADE_IN)
-    PrepareFadeBitmap(DRAW_TO_FADE_TARGET);
+  PrepareFadeBitmap(DRAW_TO_FADE_TARGET);
 
   // set screen mode for animations back to fading
   global.anim_status = GAME_MODE_PSEUDO_FADING;
@@ -1023,8 +996,7 @@ static void SetScreenStates_BeforeFadingOut(void)
   global.anim_status = GAME_MODE_PSEUDO_FADING;
 
   // store backbuffer with all animations that will be stopped for fading out
-  if (fade_type_skip != FADE_MODE_SKIP_FADE_OUT)
-    PrepareFadeBitmap(DRAW_TO_FADE_SOURCE);
+  PrepareFadeBitmap(DRAW_TO_FADE_SOURCE);
 }
 
 static void SetScreenStates_AfterFadingOut(void)
@@ -1462,8 +1434,8 @@ void SetBorderElement(void)
 
   BorderElement = EL_EMPTY;
 
-  // the MM game engine does not use a visible border element
-  if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+  // only the R'n'D game engine may use an additional steelwall border
+  if (level.game_engine_type != GAME_ENGINE_TYPE_RND)
     return;
 
   for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++)
@@ -5736,7 +5708,7 @@ static struct Mapping_EM_to_RND_object
   int action;
   int direction;
 }
-em_object_mapping_list[] =
+em_object_mapping_list[GAME_TILE_MAX + 1] =
 {
   {
     Zborder,                           FALSE,  FALSE,
@@ -6563,12 +6535,12 @@ em_object_mapping_list[] =
     EL_SPRING,                         -1, -1
   },
   {
-    Xspring_e,                         FALSE,  FALSE,
-    EL_SPRING,                         -1, -1
+    Xspring_e,                         TRUE,   FALSE,
+    EL_SPRING_RIGHT,                   -1, -1
   },
   {
-    Xspring_w,                         FALSE,  FALSE,
-    EL_SPRING,                         -1, -1
+    Xspring_w,                         TRUE,   FALSE,
+    EL_SPRING_LEFT,                    -1, -1
   },
   {
     Xspring_fall,                      FALSE,  FALSE,
@@ -6657,11 +6629,11 @@ em_object_mapping_list[] =
   },
   {
     Xpush_spring_e,                    FALSE,  FALSE,
-    EL_SPRING,                         -1, MV_BIT_RIGHT
+    EL_SPRING_RIGHT,                   -1, MV_BIT_RIGHT
   },
   {
     Xpush_spring_w,                    FALSE,  FALSE,
-    EL_SPRING,                         -1, MV_BIT_LEFT
+    EL_SPRING_LEFT,                    -1, MV_BIT_LEFT
   },
 
   {
@@ -6880,11 +6852,11 @@ em_object_mapping_list[] =
   },
 
   {
-    Xdrip,                             FALSE,  FALSE,
+    Xdrip,                             TRUE,   FALSE,
     EL_AMOEBA_DROP,                    ACTION_GROWING, -1
   },
   {
-    Xdrip_fall,                                TRUE,   FALSE,
+    Xdrip_fall,                                FALSE,  FALSE,
     EL_AMOEBA_DROP,                    -1, -1
   },
   {
@@ -7288,8 +7260,8 @@ em_object_mapping_list[] =
     EL_CHAR('!'),                      -1, -1
   },
   {
-    Xalpha_quote,                      TRUE,   FALSE,
-    EL_CHAR('"'),                      -1, -1
+    Xalpha_apost,                      TRUE,   FALSE,
+    EL_CHAR('\''),                     -1, -1
   },
   {
     Xalpha_comma,                      TRUE,   FALSE,
@@ -7492,7 +7464,7 @@ static struct Mapping_EM_to_RND_player
   int action;
   int direction;
 }
-em_player_mapping_list[] =
+em_player_mapping_list[MAX_PLAYERS * PLY_MAX + 1] =
 {
   {
     PLY_walk_n,                                0,
@@ -7709,7 +7681,7 @@ em_player_mapping_list[] =
   }
 };
 
-int map_element_RND_to_EM(int element_rnd)
+int map_element_RND_to_EM_cave(int element_rnd)
 {
   static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS];
   static boolean mapping_initialized = FALSE;
@@ -7730,17 +7702,49 @@ int map_element_RND_to_EM(int element_rnd)
     mapping_initialized = TRUE;
   }
 
-  if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS)
-    return mapping_RND_to_EM[element_rnd];
+  if (element_rnd < 0 || element_rnd >= NUM_FILE_ELEMENTS)
+  {
+    Error(ERR_WARN, "invalid RND level element %d", element_rnd);
+
+    return EL_UNKNOWN;
+  }
+
+  return map_em_element_X_to_C(mapping_RND_to_EM[element_rnd]);
+}
+
+int map_element_EM_to_RND_cave(int element_em_cave)
+{
+  static unsigned short mapping_EM_to_RND[GAME_TILE_MAX];
+  static boolean mapping_initialized = FALSE;
+
+  if (!mapping_initialized)
+  {
+    int i;
+
+    // return "EL_UNKNOWN" for all undefined elements in mapping array
+    for (i = 0; i < GAME_TILE_MAX; i++)
+      mapping_EM_to_RND[i] = EL_UNKNOWN;
+
+    for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+      mapping_EM_to_RND[em_object_mapping_list[i].element_em] =
+       em_object_mapping_list[i].element_rnd;
+
+    mapping_initialized = TRUE;
+  }
+
+  if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX)
+  {
+    Error(ERR_WARN, "invalid EM cave element %d", element_em_cave);
 
-  Error(ERR_WARN, "invalid RND level element %d", element_rnd);
+    return EL_UNKNOWN;
+  }
 
-  return EL_UNKNOWN;
+  return mapping_EM_to_RND[map_em_element_C_to_X(element_em_cave)];
 }
 
-int map_element_EM_to_RND(int element_em)
+int map_element_EM_to_RND_game(int element_em_game)
 {
-  static unsigned short mapping_EM_to_RND[TILE_MAX];
+  static unsigned short mapping_EM_to_RND[GAME_TILE_MAX];
   static boolean mapping_initialized = FALSE;
 
   if (!mapping_initialized)
@@ -7748,7 +7752,7 @@ int map_element_EM_to_RND(int element_em)
     int i;
 
     // return "EL_UNKNOWN" for all undefined elements in mapping array
-    for (i = 0; i < TILE_MAX; i++)
+    for (i = 0; i < GAME_TILE_MAX; i++)
       mapping_EM_to_RND[i] = EL_UNKNOWN;
 
     for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
@@ -7758,12 +7762,14 @@ int map_element_EM_to_RND(int element_em)
     mapping_initialized = TRUE;
   }
 
-  if (element_em >= 0 && element_em < TILE_MAX)
-    return mapping_EM_to_RND[element_em];
+  if (element_em_game < 0 || element_em_game >= GAME_TILE_MAX)
+  {
+    Error(ERR_WARN, "invalid EM game element %d", element_em_game);
 
-  Error(ERR_WARN, "invalid EM level element %d", element_em);
+    return EL_UNKNOWN;
+  }
 
-  return EL_UNKNOWN;
+  return mapping_EM_to_RND[element_em_game];
 }
 
 void map_android_clone_elements_RND_to_EM(struct LevelInfo *level)
@@ -7772,17 +7778,18 @@ void map_android_clone_elements_RND_to_EM(struct LevelInfo *level)
   struct CAVE *cav = level_em->cav;
   int i, j;
 
-  for (i = 0; i < TILE_MAX; i++)
-    cav->android_array[i] = Xblank;
+  for (i = 0; i < GAME_TILE_MAX; i++)
+    cav->android_array[i] = Cblank;
 
   for (i = 0; i < level->num_android_clone_elements; i++)
   {
     int element_rnd = level->android_clone_element[i];
-    int element_em = map_element_RND_to_EM(element_rnd);
+    int element_em_cave = map_element_RND_to_EM_cave(element_rnd);
 
     for (j = 0; em_object_mapping_list[j].element_em != -1; j++)
       if (em_object_mapping_list[j].element_rnd == element_rnd)
-       cav->android_array[em_object_mapping_list[j].element_em] = element_em;
+       cav->android_array[em_object_mapping_list[j].element_em] =
+         element_em_cave;
   }
 }
 
@@ -7794,16 +7801,16 @@ void map_android_clone_elements_EM_to_RND(struct LevelInfo *level)
 
   level->num_android_clone_elements = 0;
 
-  for (i = 0; i < TILE_MAX; i++)
+  for (i = 0; i < GAME_TILE_MAX; i++)
   {
-    int element_em = cav->android_array[i];
+    int element_em_cave = cav->android_array[i];
     int element_rnd;
     boolean element_found = FALSE;
 
-    if (element_em == Xblank)
+    if (element_em_cave == Cblank)
       continue;
 
-    element_rnd = map_element_EM_to_RND(element_em);
+    element_rnd = map_element_EM_to_RND_cave(element_em_cave);
 
     for (j = 0; j < level->num_android_clone_elements; j++)
       if (level->android_clone_element[j] == element_rnd)
@@ -8232,11 +8239,21 @@ int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
   return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr);
 }
 
+boolean swapTiles_EM(boolean is_pre_emc_cave)
+{
+  return is_pre_emc_cave && leveldir_current->use_emc_tiles;
+}
+
 boolean getTeamMode_EM(void)
 {
   return game.team_mode || network_playing;
 }
 
+boolean isActivePlayer_EM(int player_nr)
+{
+  return stored_player[player_nr].active;
+}
+
 unsigned int InitRND(int seed)
 {
   if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
@@ -8249,7 +8266,7 @@ unsigned int InitRND(int seed)
     return InitEngineRandom_RND(seed);
 }
 
-static struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
+static struct Mapping_EM_to_RND_object object_mapping[GAME_TILE_MAX];
 static struct Mapping_EM_to_RND_player player_mapping[MAX_PLAYERS][PLY_MAX];
 
 static int get_effective_element_EM(int tile, int frame_em)
@@ -8595,7 +8612,7 @@ void InitGraphicInfo_EM(void)
   int i, j, p;
 
   // always start with reliable default values
-  for (i = 0; i < TILE_MAX; i++)
+  for (i = 0; i < GAME_TILE_MAX; i++)
   {
     object_mapping[i].element_rnd = EL_UNKNOWN;
     object_mapping[i].is_backside = FALSE;
@@ -8644,7 +8661,7 @@ void InitGraphicInfo_EM(void)
        MV_DIR_FROM_BIT(em_player_mapping_list[i].direction);
   }
 
-  for (i = 0; i < TILE_MAX; i++)
+  for (i = 0; i < GAME_TILE_MAX; i++)
   {
     int element = object_mapping[i].element_rnd;
     int action = object_mapping[i].action;
@@ -8701,7 +8718,7 @@ void InitGraphicInfo_EM(void)
       boolean has_action_graphics = (graphic != base_graphic);
       boolean has_crumbled_graphics = (base_crumbled != base_graphic);
       struct GraphicInfo *g = &graphic_info[graphic];
-      struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
+      struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][j];
       Bitmap *src_bitmap;
       int src_x, src_y;
       // ensure to get symmetric 3-frame, 2-delay animations as used in EM
@@ -8909,7 +8926,7 @@ void InitGraphicInfo_EM(void)
     }
   }
 
-  for (i = 0; i < TILE_MAX; i++)
+  for (i = 0; i < GAME_TILE_MAX; i++)
   {
     for (j = 0; j < 8; j++)
     {
@@ -8932,8 +8949,8 @@ void InitGraphicInfo_EM(void)
                 Xspring);
 
        // no separate animation for "smashed by rock" -- use rock instead
-       struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
-       struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][7 - j];
+       struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][j];
+       struct GraphicInfo_EM *g_xx = &graphic_info_em_object[e][j];
 
        g_em->bitmap            = g_xx->bitmap;
        g_em->src_x             = g_xx->src_x;
@@ -8969,7 +8986,7 @@ void InitGraphicInfo_EM(void)
                       el_act_dir2img(effective_element, effective_action,
                                      direction));
        struct GraphicInfo *g = &graphic_info[graphic];
-       struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][7 - j];
+       struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][j];
        Bitmap *src_bitmap;
        int src_x, src_y;
        int sync_frame = j;
@@ -9000,7 +9017,7 @@ static void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame,
                                       boolean any_player_snapping,
                                       boolean any_player_dropping)
 {
-  if (frame == 0 && !any_player_dropping)
+  if (frame == 7 && !any_player_dropping)
   {
     if (!local_player->was_waiting)
     {
@@ -9058,7 +9075,7 @@ void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
                            boolean any_player_dropping)
 {
   if (tape.single_step && tape.recording && !tape.pausing)
-    if (frame == 0 && !any_player_dropping)
+    if (frame == 7 && !any_player_dropping)
       TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
 
   CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,