+ node_first = getTreeInfoFirstGroupEntry(leveldir_current);
+ node = getTreeInfoFromPos(node_first, leveldir_pos);
+
+ strncpy(buffer, node->name , max_buffer_len);
+ buffer[max_buffer_len] = '\0';
+
+ DrawText(SX + 32, SY + ypos * 32, buffer, FS_MEDIUM, node->color);
+
+ if (node->parent_link)
+ initCursor(i, GFX_ARROW_BLUE_LEFT);
+ else if (node->level_group)
+ initCursor(i, GFX_ARROW_BLUE_RIGHT);
+ else
+ initCursor(i, GFX_KUGEL_BLAU);
+ }
+
+ if (first_entry > 0)
+ DrawGraphic(0, 1, GFX_ARROW_BLUE_UP);
+
+ if (first_entry + num_page_entries < num_leveldirs)
+ DrawGraphic(0, MAX_MENU_ENTRIES_ON_SCREEN + 1, GFX_ARROW_BLUE_DOWN);
+}
+
+static void drawChooseLevelInfo(int leveldir_pos)
+{
+ LevelDirTree *node, *node_first;
+ int x, last_redraw_mask = redraw_mask;
+
+ node_first = getTreeInfoFirstGroupEntry(leveldir_current);
+ node = getTreeInfoFromPos(node_first, leveldir_pos);
+
+ ClearRectangle(drawto, SX + 32, SY + 32, SXSIZE - 64, 32);
+
+ if (node->parent_link)
+ DrawTextFCentered(40, FC_RED, "leave group \"%s\"", node->class_desc);
+ else if (node->level_group)
+ DrawTextFCentered(40, FC_RED, "enter group \"%s\"", node->class_desc);
+ else
+ DrawTextFCentered(40, FC_RED, "%3d levels (%s)",
+ node->levels, node->class_desc);
+
+ /* let BackToFront() redraw only what is needed */
+ redraw_mask = last_redraw_mask | REDRAW_TILES;
+ for (x=0; x<SCR_FIELDX; x++)
+ MarkTileDirty(x, 1);
+}
+
+void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
+{
+ static unsigned long choose_delay = 0;
+ int x = 0;
+ int y = leveldir_current->cl_cursor;
+ int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
+ int num_leveldirs = numTreeInfoInGroup(leveldir_current);
+ int num_page_entries;
+
+ if (num_leveldirs <= MAX_MENU_ENTRIES_ON_SCREEN)
+ num_page_entries = num_leveldirs;
+ else
+ num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+
+ if (button == MB_MENU_INITIALIZE)
+ {
+ int leveldir_pos = posTreeInfo(leveldir_current);
+
+ if (leveldir_current->cl_first == -1)
+ {
+ leveldir_current->cl_first = MAX(0, leveldir_pos - num_page_entries + 1);
+ leveldir_current->cl_cursor =
+ leveldir_pos - leveldir_current->cl_first;
+ }
+
+ if (dx == 999) /* first entry is set by scrollbar position */
+ leveldir_current->cl_first = dy;
+ else
+ AdjustChooseLevelScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ leveldir_current->cl_first);
+
+ drawChooseLevelList(leveldir_current->cl_first, num_page_entries);
+ drawChooseLevelInfo(leveldir_current->cl_first +
+ leveldir_current->cl_cursor);
+ drawCursor(leveldir_current->cl_cursor, FC_RED);
+ return;
+ }
+ else if (button == MB_MENU_LEAVE)
+ {
+ if (leveldir_current->node_parent)
+ {
+ leveldir_current = leveldir_current->node_parent;
+ DrawChooseLevel();
+ }
+ else
+ {
+ game_status = MAINMENU;
+ DrawMainMenu();
+ }
+ return;
+ }
+
+ if (mx || my) /* mouse input */
+ {
+ x = (mx - SX) / 32;
+ y = (my - SY) / 32 - MENU_SCREEN_START_YPOS;
+ }
+ else if (dx || dy) /* keyboard input */
+ {
+ if (dy)
+ y = leveldir_current->cl_cursor + dy;
+
+ if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
+ {
+ dy = SIGN(dy);
+ step = num_page_entries - 1;
+ y = (dy < 0 ? -1 : num_page_entries);
+ }
+ }
+
+ if (x == 0 && y == -1)
+ {
+ if (leveldir_current->cl_first > 0 &&
+ (dy || DelayReached(&choose_delay, GADGET_FRAME_DELAY)))
+ {
+ leveldir_current->cl_first -= step;
+ if (leveldir_current->cl_first < 0)
+ leveldir_current->cl_first = 0;
+
+ drawChooseLevelList(leveldir_current->cl_first, num_page_entries);
+ drawChooseLevelInfo(leveldir_current->cl_first +
+ leveldir_current->cl_cursor);
+ drawCursor(leveldir_current->cl_cursor, FC_RED);
+ AdjustChooseLevelScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ leveldir_current->cl_first);
+ return;
+ }
+ }
+ else if (x == 0 && y > num_page_entries - 1)
+ {
+ if (leveldir_current->cl_first + num_page_entries < num_leveldirs &&
+ (dy || DelayReached(&choose_delay, GADGET_FRAME_DELAY)))
+ {
+ leveldir_current->cl_first += step;
+ if (leveldir_current->cl_first + num_page_entries > num_leveldirs)
+ leveldir_current->cl_first = MAX(0, num_leveldirs - num_page_entries);
+
+ drawChooseLevelList(leveldir_current->cl_first, num_page_entries);
+ drawChooseLevelInfo(leveldir_current->cl_first +
+ leveldir_current->cl_cursor);
+ drawCursor(leveldir_current->cl_cursor, FC_RED);
+ AdjustChooseLevelScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ leveldir_current->cl_first);
+ return;
+ }
+ }
+
+ if (dx == 1)
+ {
+ LevelDirTree *node_first, *node_cursor;
+ int leveldir_pos = leveldir_current->cl_first + y;
+
+ node_first = getTreeInfoFirstGroupEntry(leveldir_current);
+ node_cursor = getTreeInfoFromPos(node_first, leveldir_pos);
+
+ if (node_cursor->node_group)
+ {
+ node_cursor->cl_first = leveldir_current->cl_first;
+ node_cursor->cl_cursor = leveldir_current->cl_cursor;
+ leveldir_current = node_cursor->node_group;
+ DrawChooseLevel();
+ return;
+ }
+ }
+ else if (dx == -1 && leveldir_current->node_parent)
+ {
+ leveldir_current = leveldir_current->node_parent;
+ DrawChooseLevel();
+ return;
+ }
+
+ if (x == 0 && y >= 0 && y < num_page_entries)
+ {
+ if (button)
+ {
+ if (y != leveldir_current->cl_cursor)
+ {
+ drawCursor(y, FC_RED);
+ drawCursor(leveldir_current->cl_cursor, FC_BLUE);
+ drawChooseLevelInfo(leveldir_current->cl_first + y);
+ leveldir_current->cl_cursor = y;
+ }
+ }
+ else
+ {
+ LevelDirTree *node_first, *node_cursor;
+ int leveldir_pos = leveldir_current->cl_first + y;
+
+ node_first = getTreeInfoFirstGroupEntry(leveldir_current);
+ node_cursor = getTreeInfoFromPos(node_first, leveldir_pos);
+
+ if (node_cursor->node_group)
+ {
+ node_cursor->cl_first = leveldir_current->cl_first;
+ node_cursor->cl_cursor = leveldir_current->cl_cursor;
+ leveldir_current = node_cursor->node_group;
+
+ DrawChooseLevel();
+ }
+ else if (node_cursor->parent_link)
+ {
+ leveldir_current = node_cursor->node_parent;
+
+ DrawChooseLevel();
+ }
+ else
+ {
+ node_cursor->cl_first = leveldir_current->cl_first;
+ node_cursor->cl_cursor = leveldir_current->cl_cursor;
+ leveldir_current = node_cursor;
+
+ LoadLevelSetup_SeriesInfo();
+
+ SaveLevelSetup_LastSeries();
+ SaveLevelSetup_SeriesInfo();
+ TapeErase();
+
+ game_status = MAINMENU;
+ DrawMainMenu();
+ }
+ }
+ }
+
+ BackToFront();
+
+ if (game_status == CHOOSELEVEL)
+ DoAnimation();
+}
+
+#endif
+
+
+void DrawHallOfFame(int highlight_position)
+{
+ UnmapAllGadgets();
+ FadeSounds();
+ CloseDoor(DOOR_CLOSE_2);
+
+ if (highlight_position < 0)
+ LoadScore(level_nr);
+
+ FadeToFront();
+ InitAnimation();
+ HandleHallOfFame(highlight_position,0, 0,0, MB_MENU_INITIALIZE);
+ PlaySound(SND_HALLOFFAME);
+}
+
+static void drawHallOfFameList(int first_entry, int highlight_position)
+{
+ int i;
+
+ ClearWindow();
+ DrawText(SX + 80, SY + 8, "Hall Of Fame", FS_BIG, FC_YELLOW);
+ DrawTextFCentered(46, FC_RED, "HighScores of Level %d", level_nr);
+
+ for(i=0; i<MAX_MENU_ENTRIES_ON_SCREEN; i++)
+ {
+ int entry = first_entry + i;
+ int color = (entry == highlight_position ? FC_RED : FC_GREEN);
+
+#if 0
+ DrawText(SX, SY + 64 + i * 32, ".................", FS_BIG, color);
+ DrawText(SX, SY + 64 + i * 32, highscore[i].Name, FS_BIG, color);
+ DrawText(SX + 12 * 32, SY + 64 + i * 32,
+ int2str(highscore[i].Score, 5), FS_BIG, color);
+#else
+ DrawText(SX, SY + 64 + i * 32, "..................................",
+ FS_MEDIUM, FC_YELLOW);
+ DrawText(SX, SY + 64 + i * 32, int2str(entry + 1, 3),
+ FS_MEDIUM, FC_YELLOW);
+ DrawText(SX + 64, SY + 64 + i * 32, highscore[entry].Name, FS_BIG, color);
+ DrawText(SX + 14 * 32 + 16, SY + 64 + i * 32,
+ int2str(highscore[entry].Score, 5), FS_MEDIUM, color);
+#endif
+ }
+}
+
+void HandleHallOfFame(int mx, int my, int dx, int dy, int button)
+{
+ static int first_entry = 0;
+ static int highlight_position = 0;
+ int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
+ int button_released = !button;
+
+ if (button == MB_MENU_INITIALIZE)
+ {
+ first_entry = 0;
+ highlight_position = mx;
+ drawHallOfFameList(first_entry, highlight_position);
+ return;
+ }
+
+ if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
+ step = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+
+ if (dy < 0)
+ {
+ if (first_entry > 0)
+ {
+ first_entry -= step;
+ if (first_entry < 0)
+ first_entry = 0;