rnd-20051205-1-src
[rocksndiamonds.git] / src / screens.c
index 268cd9c83a1897fd45cd96c1272b3303c30965f3..43d02fb4bd630d60383070fd7d15266760edc38c 100644 (file)
@@ -97,12 +97,13 @@ static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
 static int setup_mode = SETUP_MODE_MAIN;
 static int info_mode = INFO_MODE_MAIN;
 
-#define mSX (SX + (game_status >= GAME_MODE_MAIN &&    \
-                  game_status <= GAME_MODE_SETUP ?     \
-                  menu.draw_xoffset[game_status] : menu.draw_xoffset_default))
-#define mSY (SY + (game_status >= GAME_MODE_MAIN &&    \
-                  game_status <= GAME_MODE_SETUP ?     \
-                  menu.draw_yoffset[game_status] : menu.draw_yoffset_default))
+#define DRAW_OFFSET_MODE(x)    (x >= GAME_MODE_MAIN &&                 \
+                                x <= GAME_MODE_SETUP ? x :             \
+                                x == GAME_MODE_PSEUDO_TYPENAME ?       \
+                                GAME_MODE_MAIN : GAME_MODE_DEFAULT)
+
+#define mSX (SX + menu.draw_xoffset[DRAW_OFFSET_MODE(game_status)])
+#define mSY (SY + menu.draw_yoffset[DRAW_OFFSET_MODE(game_status)])
 
 #define NUM_MENU_ENTRIES_ON_SCREEN (menu.list_size[game_status] > 2 ?  \
                                    menu.list_size[game_status] :       \
@@ -114,28 +115,29 @@ static Bitmap *scrollbar_bitmap[NUM_SCROLLBAR_BITMAPS];
 #endif
 
 
-static void drawCursorExt(int xpos, int ypos, int color, int graphic)
+static void drawCursorExt(int xpos, int ypos, int color, int g)
 {
   static int cursor_array[SCR_FIELDY];
 
   if (xpos == 0)
   {
-    if (graphic != 0)
-      cursor_array[ypos] = graphic;
+    if (g != 0)
+      cursor_array[ypos] = g;
     else
-      graphic = cursor_array[ypos];
+      g = cursor_array[ypos];
   }
 
   if (color == FC_RED)
-    graphic = (graphic == IMG_MENU_BUTTON_LEFT  ? IMG_MENU_BUTTON_LEFT_ACTIVE :
-              graphic == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE:
-              IMG_MENU_BUTTON_ACTIVE);
+    g = (g == IMG_MENU_BUTTON_LEFT  ? IMG_MENU_BUTTON_LEFT_ACTIVE  :
+        g == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE :
+        g == IMG_MENU_BUTTON_LEAVE_MENU ? IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE :
+        g == IMG_MENU_BUTTON_ENTER_MENU ? IMG_MENU_BUTTON_ENTER_MENU_ACTIVE :
+        IMG_MENU_BUTTON_ACTIVE);
 
   ypos += MENU_SCREEN_START_YPOS;
 
   DrawBackground(mSX + xpos * TILEX, mSY + ypos * TILEY, TILEX, TILEY);
-  DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY,
-                        graphic, 0);
+  DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY, g, 0);
 }
 
 static void initCursor(int ypos, int graphic)
@@ -308,7 +310,7 @@ void DrawMainMenu()
   DrawText(mSX + level_width + 5 * 32, mSY + 3*32, int2str(level_nr,3),
           FONT_VALUE_1);
 
-  DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
+  DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, TRUE);
 
   DrawTextF(mSX + 32 + level_width - 2, mSY + 3*32 + 1, FONT_TEXT_3, "%d-%d",
            leveldir_current->first_level, leveldir_current->last_level);
@@ -322,11 +324,11 @@ void DrawMainMenu()
   }
 
   for (i = 0; i < 8; i++)
-    initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_RIGHT :
+    initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_ENTER_MENU :
                   IMG_MENU_BUTTON));
 
-  drawCursorXY(level_width/32 + 4, 1, IMG_MENU_BUTTON_LEFT);
-  drawCursorXY(level_width/32 + 8, 1, IMG_MENU_BUTTON_RIGHT);
+  drawCursorXY(level_width / 32 + 4, 1, IMG_MENU_BUTTON_LEFT);
+  drawCursorXY(level_width / 32 + 8, 1, IMG_MENU_BUTTON_RIGHT);
 
   DrawTextSCentered(326, FONT_TITLE_2, "A Game by Artsoft Entertainment");
 
@@ -346,6 +348,7 @@ void DrawMainMenu()
   OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
 }
 
+#if 0
 static void gotoTopLevelDir()
 {
   /* move upwards to top level directory */
@@ -374,9 +377,11 @@ static void gotoTopLevelDir()
     leveldir_current = leveldir_current->node_parent;
   }
 }
+#endif
 
 void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 {
+  static unsigned long level_delay = 0;
   static int choice = 5;
   int x = 0;
   int y = choice;
@@ -402,9 +407,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 
   if (y == 1 && ((x == 10 && level_nr > leveldir_current->first_level) ||
                 (x == 14 && level_nr < leveldir_current->last_level)) &&
-      button)
+      button && DelayReached(&level_delay, GADGET_FRAME_DELAY))
   {
-    static unsigned long level_delay = 0;
     int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
     int old_level_nr = level_nr;
     int new_level_nr;
@@ -416,10 +420,19 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       new_level_nr = leveldir_current->last_level;
 
     if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
+    {
+      /* skipping levels is only allowed when trying to skip single level */
+      if (setup.skip_levels && step == 1 &&
+         Request("Level still unsolved ! Skip despite handicap ?", REQ_ASK))
+      {
+       leveldir_current->handicap_level++;
+       SaveLevelSetup_SeriesInfo();
+      }
+
       new_level_nr = leveldir_current->handicap_level;
+    }
 
-    if (new_level_nr != old_level_nr &&
-       DelayReached(&level_delay, GADGET_FRAME_DELAY))
+    if (new_level_nr != old_level_nr)
     {
       level_nr = new_level_nr;
 
@@ -427,7 +440,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
               FONT_VALUE_1);
 
       LoadLevel(level_nr);
-      DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
+      DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, TRUE);
 
       TapeErase();
       LoadTape(level_nr);
@@ -466,7 +479,9 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
          SaveLevelSetup_LastSeries();
          SaveLevelSetup_SeriesInfo();
 
+#if 0
          gotoTopLevelDir();
+#endif
 
          DrawChooseLevel();
        }
@@ -492,30 +507,20 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       }
       else if (y == 5)
       {
-       if (setup.autorecord)
-         TapeStartRecording();
-
-#if defined(NETWORK_AVALIABLE)
-       if (options.network)
-         SendToServer_StartPlaying();
-       else
-#endif
-       {
-         game_status = GAME_MODE_PLAYING;
-         StopAnimation();
-         InitGame();
-       }
+       StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE);
       }
       else if (y == 6)
       {
        game_status = GAME_MODE_SETUP;
        setup_mode = SETUP_MODE_MAIN;
+
        DrawSetupScreen();
       }
       else if (y == 7)
       {
        SaveLevelSetup_LastSeries();
        SaveLevelSetup_SeriesInfo();
+
         if (Request("Do you really want to quit ?", REQ_ASK | REQ_STAY_CLOSED))
          game_status = GAME_MODE_QUIT;
       }
@@ -524,7 +529,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 
   if (game_status == GAME_MODE_MAIN)
   {
-    DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, FALSE);
+    DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, FALSE);
     DoAnimation();
   }
 }
@@ -608,9 +613,9 @@ static void DrawInfoScreen_Main()
     DrawText(mSX + 32, mSY + ypos * 32, info_info[i].text, font_nr);
 
     if (info_info[i].type & TYPE_ENTER_MENU)
-      initCursor(i, IMG_MENU_BUTTON_RIGHT);
+      initCursor(i, IMG_MENU_BUTTON_ENTER_MENU);
     else if (info_info[i].type & TYPE_LEAVE_MENU)
-      initCursor(i, IMG_MENU_BUTTON_LEFT);
+      initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU);
     else if (info_info[i].type & ~TYPE_SKIP_ENTRY)
       initCursor(i, IMG_MENU_BUTTON);
 
@@ -727,7 +732,6 @@ void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init)
     for (i = 0; i < MAX_INFO_ELEMENTS_ON_SCREEN; i++)
       infoscreen_step[i] = infoscreen_frame[i] = 0;
 
-    SetMainBackgroundImage(IMG_BACKGROUND_INFO);
     ClearWindow();
     DrawHeadline();
 
@@ -835,11 +839,7 @@ static char *getHelpText(int element, int action, int direction)
 
 void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos)
 {
-#if 0
-  int font_nr = FONT_TEXT_2;
-#else
   int font_nr = FONT_LEVEL_NUMBER;
-#endif
   int font_width = getFontWidth(font_nr);
   int sx = mSX + MINI_TILEX + TILEX + MINI_TILEX;
   int sy = mSY + 65 + 2 * 32 + 1;
@@ -873,6 +873,8 @@ void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos)
 
 void DrawInfoScreen_Elements()
 {
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_ELEMENTS);
+
   LoadHelpAnimInfo();
   LoadHelpTextInfo();
 
@@ -948,6 +950,8 @@ void HandleInfoScreen_Elements(int button)
 
 void DrawInfoScreen_Music()
 {
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_MUSIC);
+
   ClearWindow();
   DrawHeadline();
 
@@ -1080,6 +1084,8 @@ void DrawInfoScreen_Credits()
   int ystart = 150, ystep = 30;
   int ybottom = SYSIZE - 20;
 
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_CREDITS);
+
   FadeSoundsAndMusic();
 
   ClearWindow();
@@ -1128,6 +1134,8 @@ void DrawInfoScreen_Program()
   int ystart = 150, ystep = 30;
   int ybottom = SYSIZE - 20;
 
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_PROGRAM);
+
   ClearWindow();
   DrawHeadline();
 
@@ -1191,11 +1199,7 @@ void DrawInfoScreen_LevelSet()
   int ystart = 150;
   int ybottom = SYSIZE - 20;
   char *filename = getLevelSetInfoFilename();
-#if 0
-  int font_nr = FONT_TEXT_2;
-#else
   int font_nr = FONT_LEVEL_NUMBER;
-#endif
   int font_width = getFontWidth(font_nr);
   int font_height = getFontHeight(font_nr);
   int pad_x = 32;
@@ -1205,6 +1209,8 @@ void DrawInfoScreen_LevelSet()
   int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
   int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
 
+  SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET);
+
   ClearWindow();
   DrawHeadline();
 
@@ -1430,9 +1436,9 @@ static void drawChooseTreeList(int first_entry, int num_page_entries,
     DrawText(mSX + 32, mSY + ypos * 32, buffer, FONT_TEXT_1 + node->color);
 
     if (node->parent_link)
-      initCursor(i, IMG_MENU_BUTTON_LEFT);
+      initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU);
     else if (node->level_group)
-      initCursor(i, IMG_MENU_BUTTON_RIGHT);
+      initCursor(i, IMG_MENU_BUTTON_ENTER_MENU);
     else
       initCursor(i, IMG_MENU_BUTTON);
   }
@@ -1481,6 +1487,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
   int num_entries = numTreeInfoInGroup(ti);
   int num_page_entries;
   int last_game_status = game_status;  /* save current game status */
+  boolean position_set_by_scrollbar = (dx == 999);
 
   /* force LEVELS draw offset on choose level and artwork setup screen */
   game_status = GAME_MODE_LEVELS;
@@ -1512,7 +1519,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
       ti->cl_cursor = entry_pos - ti->cl_first;
     }
 
-    if (dx == 999)     /* first entry is set by scrollbar position */
+    if (position_set_by_scrollbar)
       ti->cl_first = dy;
     else
       AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
@@ -1634,7 +1641,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
     return;
   }
 
-  if (IN_VIS_FIELD(x, y) &&
+  if (!anyScrollbarGadgetActive() &&
+      IN_VIS_FIELD(x, y) &&
       mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x &&
       y >= 0 && y < num_page_entries)
   {
@@ -1942,6 +1950,7 @@ static struct TokenInfo setup_info_game[] =
 {
   { TYPE_SWITCH,       &setup.team_mode,       "Team-Mode:"            },
   { TYPE_SWITCH,       &setup.handicap,        "Handicap:"             },
+  { TYPE_SWITCH,       &setup.skip_levels,     "Skip Levels:"          },
   { TYPE_SWITCH,       &setup.time_limit,      "Timelimit:"            },
   { TYPE_SWITCH,       &setup.autorecord,      "Auto-Record:"          },
   { TYPE_EMPTY,                NULL,                   ""                      },
@@ -2211,21 +2220,15 @@ static void DrawSetupScreen_Generic()
        (value_ptr == &setup.fullscreen   && !video.fullscreen_available))
       setup_info[i].type |= TYPE_GHOSTED;
 
-#if 0
-    if (setup_info[i].type & TYPE_STRING ||
-       (setup_info[i].type & TYPE_SWITCH && setup_mode == SETUP_MODE_EDITOR))
-      font_nr = FONT_MENU_2;
-#else
     if (setup_info[i].type & TYPE_STRING)
       font_nr = FONT_MENU_2;
-#endif
 
     DrawText(mSX + 32, mSY + ypos * 32, setup_info[i].text, font_nr);
 
     if (setup_info[i].type & TYPE_ENTER_MENU)
-      initCursor(i, IMG_MENU_BUTTON_RIGHT);
+      initCursor(i, IMG_MENU_BUTTON_ENTER_MENU);
     else if (setup_info[i].type & TYPE_LEAVE_MENU)
-      initCursor(i, IMG_MENU_BUTTON_LEFT);
+      initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU);
     else if (setup_info[i].type & ~TYPE_SKIP_ENTRY)
       initCursor(i, IMG_MENU_BUTTON);
 
@@ -2337,10 +2340,10 @@ void DrawSetupScreen_Input()
 
   DrawText(mSX+16, mSY+16, "Setup Input", FONT_TITLE_1);
 
-  initCursor(0, IMG_MENU_BUTTON);
-  initCursor(1, IMG_MENU_BUTTON);
-  initCursor(2, IMG_MENU_BUTTON_RIGHT);
-  initCursor(13, IMG_MENU_BUTTON_LEFT);
+  initCursor(0,  IMG_MENU_BUTTON);
+  initCursor(1,  IMG_MENU_BUTTON);
+  initCursor(2,  IMG_MENU_BUTTON_ENTER_MENU);
+  initCursor(13, IMG_MENU_BUTTON_LEAVE_MENU);
 
   drawCursorXY(10, 0, IMG_MENU_BUTTON_LEFT);
   drawCursorXY(12, 0, IMG_MENU_BUTTON_RIGHT);
@@ -2409,14 +2412,11 @@ static void drawPlayerSetupInputInfo(int player_nr)
   custom_key = setup.input[player_nr].key;
 
   DrawText(mSX+11*32, mSY+2*32, int2str(player_nr +1, 1), FONT_INPUT_1_ACTIVE);
-#if 1
+
   ClearRectangleOnBackground(drawto, mSX + 8 * TILEX, mSY + 2 * TILEY,
                             TILEX, TILEY);
   DrawGraphicThruMaskExt(drawto, mSX + 8 * TILEX, mSY + 2 * TILEY,
                         PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0);
-#else
-  DrawGraphicThruMask(8, 2, PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0);
-#endif
 
   if (setup.input[player_nr].use_joystick)
   {
@@ -2985,6 +2985,12 @@ void HandleGameActions()
 
     recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
 
+#if 1
+    /* !!! CHECK THIS (tape.pausing is always FALSE here!) !!! */
+    if (recorded_player_action == NULL && tape.pausing)
+      return;
+#endif
+
     for (i = 0; i < MAX_PLAYERS; i++)
     {
       summarized_player_action |= stored_player[i].action;
@@ -3020,6 +3026,29 @@ void HandleGameActions()
       TimeFrames = 0;
       TapeTime++;
 
+      if (!level.use_step_counter)
+      {
+       TimePlayed++;
+
+       if (TimeLeft > 0)
+       {
+         TimeLeft--;
+
+         if (TimeLeft <= 10 && setup.time_limit)
+           PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+
+         DrawGameValue_Time(TimeLeft);
+
+         if (!TimeLeft && setup.time_limit)
+           level.native_em_level->lev->killed_out_of_time = TRUE;
+       }
+       else if (level.time == 0 && level.native_em_level->lev->home > 0)
+         DrawGameValue_Time(TimePlayed);
+
+       level.native_em_level->lev->time =
+         (level.time == 0 ? TimePlayed : TimeLeft);
+      }
+
       if (tape.recording || tape.playing)
        DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
     }
@@ -3031,6 +3060,9 @@ void HandleGameActions()
   }
   else
   {
+    if (game.restart_level)
+      StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE);
+
     if (local_player->LevelSolved)
       GameWon();
 
@@ -3045,6 +3077,30 @@ void HandleGameActions()
   }
 }
 
+void StartGameActions(boolean init_network_game, boolean record_tape,
+                     long random_seed)
+{
+  if (record_tape)
+    TapeStartRecording(random_seed);
+
+#if defined(NETWORK_AVALIABLE)
+  if (init_network_game)
+  {
+    SendToServer_StartPlaying();
+
+    return;
+  }
+#endif
+
+  StopAnimation();
+
+  game_status = GAME_MODE_PLAYING;
+
+  InitRND(random_seed);
+
+  InitGame();
+}
+
 /* ---------- new screen button stuff -------------------------------------- */
 
 /* graphic position and size values for buttons and scrollbars */