cleanup of setup value fonts on setup screens
[rocksndiamonds.git] / src / game_bd / main_bd.c
index 8f80b4f485e6d40bb4407ab930bc802df1cb1788..77af13a28c158a4e59ce6f43e1607d09af895325 100644 (file)
@@ -69,6 +69,11 @@ void setLevelInfoToDefaults_BD_Ext(int width, int height)
   {
     cave->w = width;
     cave->h = height;
+
+    cave->x1 = 0;
+    cave->y1 = 0;
+    cave->x2 = cave->w - 1;
+    cave->y2 = cave->h - 1;
   }
 
   gd_flatten_cave(cave, 0);
@@ -90,6 +95,30 @@ void setLevelInfoToDefaults_BD(void)
   setLevelInfoToDefaults_BD_Ext(0, 0);
 }
 
+static List *getNativeLevelReplay_BD_Ext(List *item, boolean only_successful_replays)
+{
+  // look for replay that was recorded for the current difficulty level
+  while (item != NULL &&
+        (item->data == NULL ||
+         (((GdReplay *)item->data)->success == FALSE && only_successful_replays) ||
+         ((GdReplay *)item->data)->level != native_bd_level.level_nr))
+    item = item->next;
+
+  return item;
+}
+
+static List *getNativeLevelReplay_BD(List *replays)
+{
+  // 1st try: look for successful replay
+  List *item = getNativeLevelReplay_BD_Ext(replays, TRUE);
+
+  if (item != NULL)
+    return item;
+
+  // 2nd try: look for any replay
+  return getNativeLevelReplay_BD_Ext(replays, FALSE);
+}
+
 boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_only)
 {
   static char *filename_loaded = NULL;
@@ -132,16 +161,9 @@ boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_onl
   // check if this cave has any replays
   if (native_bd_level.cave->replays != NULL)
   {
-    GList *item = native_bd_level.cave->replays;
+    List *item = getNativeLevelReplay_BD(native_bd_level.cave->replays);
 
-    // try to find replay that was recorded for this difficulty level
-    while (item != NULL &&
-          (item->data == NULL ||
-           ((GdReplay *)item->data)->success == FALSE ||
-           ((GdReplay *)item->data)->level != native_bd_level.level_nr))
-      item = item->next;
-
-    // matching replay found
+    // check if any matching replay was found
     if (item != NULL)
       native_bd_level.replay = (GdReplay *)item->data;
   }
@@ -149,6 +171,16 @@ boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_onl
   return TRUE;
 }
 
+boolean SaveNativeLevel_BD(char *filename)
+{
+  GdCave *cave = gd_cave_new_from_cave(native_bd_level.cave);
+
+  gd_caveset_clear();
+  gd_caveset = list_append(gd_caveset, cave);
+
+  return gd_caveset_save_to_file(filename);
+}
+
 
 // ============================================================================
 // game engine functions
@@ -233,12 +265,36 @@ static void UpdateGameDoorValues_BD(void)
   }
 }
 
+static void PrepareGameTileBitmap_BD(void)
+{
+  struct GraphicInfo_BD *g_template = &graphic_info_bd_color_template;
+  struct GraphicInfo_BD *g_default  = &graphic_info_bd_object[O_STONE][0];
+
+  gd_prepare_tile_bitmap(native_bd_level.cave, g_template->bitmap, 1);
+  gd_set_tile_bitmap_reference(g_default->bitmap);
+}
+
+void PreparePreviewTileBitmap_BD(Bitmap *bitmap, int scale_down_factor)
+{
+  gd_prepare_tile_bitmap(native_bd_level.cave, bitmap, scale_down_factor);
+}
+
+void SetPreviewTileBitmapReference_BD(Bitmap *bitmap)
+{
+  gd_set_tile_bitmap_reference(bitmap);
+}
+
+Bitmap *GetPreviewTileBitmap_BD(Bitmap *bitmap)
+{
+  return gd_get_tile_bitmap(bitmap);
+}
+
 unsigned int InitEngineRandom_BD(int seed)
 {
   if (seed == NEW_RANDOMIZE)
   {
     // get randomly selected seed to render the cave
-    seed = g_random_int_range(0, GD_CAVE_SEED_MAX);
+    seed = gd_random_int_range(0, GD_CAVE_SEED_MAX);
   }
 
   game_bd.random_seed = seed;
@@ -264,6 +320,13 @@ void InitGameEngine_BD(void)
 
   game_bd.game = gd_game_new(native_bd_level.cave_nr, native_bd_level.level_nr);
 
+  game_bd.game->itercycle = 0;
+  game_bd.game->itermax = 8;   // default; dynamically changed at runtime
+  game_bd.game->itermax_last = game_bd.game->itermax;
+
+  // prepare tile bitmap with level-specific colors, if available
+  PrepareGameTileBitmap_BD();
+
   // default: start with completely covered playfield
   int next_state = GAME_INT_START_UNCOVER + 1;
 
@@ -282,6 +345,8 @@ void InitGameEngine_BD(void)
   if (setup.bd_skip_uncovering)
     gd_scroll(game_bd.game, TRUE, TRUE);
 
+  ClearRectangle(gd_screen_bitmap, 0, 0, SXSIZE, SYSIZE);
+
   RedrawPlayfield_BD(TRUE);
 
   UpdateGameDoorValues_BD();
@@ -338,6 +403,19 @@ void GameActions_BD(byte action[MAX_PLAYERS])
 
   play_game_func(game_bd.game, action[0]);
 
+  // scroll without iterating engine if player out of sight (mainly due to wrap-around)
+  // (this is needed to prevent broken tapes in case of viewport or tile size changes)
+  while (game_bd.game->out_of_window)
+  {
+    RedrawPlayfield_BD(TRUE);
+
+    BlitScreenToBitmap_BD(backbuffer);
+
+    BackToFront();
+
+    play_game_func(game_bd.game, action[0]);
+  }
+
   RedrawPlayfield_BD(FALSE);
 
   UpdateGameDoorValues_BD();
@@ -348,6 +426,11 @@ void GameActions_BD(byte action[MAX_PLAYERS])
 // graphics functions
 // ============================================================================
 
+Bitmap *GetTitleScreen_BD(void)
+{
+  return gd_get_title_screen_bitmap();
+}
+
 void CoverScreen_BD(void)
 {
   game_bd.cover_screen = FALSE;
@@ -375,10 +458,11 @@ void CoverScreen_BD(void)
 
 void BlitScreenToBitmap_BD(Bitmap *target_bitmap)
 {
+  GdCave *cave = native_bd_level.cave;
   int xsize = SXSIZE;
   int ysize = SYSIZE;
-  int full_xsize = native_bd_level.cave->w * TILESIZE_VAR;
-  int full_ysize = native_bd_level.cave->h * TILESIZE_VAR;
+  int full_xsize = (cave->x2 - cave->x1 + 1) * TILESIZE_VAR;
+  int full_ysize = (cave->y2 - cave->y1 + 1) * TILESIZE_VAR;
   int sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
   int sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
   int sxsize = (full_xsize < xsize ? full_xsize : xsize);