- Added support for NTLDR style freeloader GUI. To enable, edit freeldr.ini and add:
ShowTime=No
MinimalUI=Yes
MenuBox=No
CenterMenu=No
TimeText=Seconds until highlighted choice will be started automatically:  
Also make sure the following are set:
MenuTextColor=Gray
MenuColor=Black
TextColor=Gray
SelectedTextColor=Black
SelectedColor=Gray.
- Also made the boot-up screen black, not blue, since that's the actual color it's been after NT4. If booting without NOGUIBOOT, this results in a much nicer transition to the boot screen (especially if using the NTLDR theme)
- Some other minor changes done to simplify transitions while booting. Hoping for filip to finish his Bootvid patch to remove the last annoying gui->text->gui switch near the end :).
Modified: trunk/reactos/boot/freeldr/freeldr/include/ui/tui.h
Modified: trunk/reactos/boot/freeldr/freeldr/include/ui.h
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
Modified: trunk/reactos/boot/freeldr/freeldr/ui/tui.c
Modified: trunk/reactos/boot/freeldr/freeldr/ui/tuimenu.c
Modified: trunk/reactos/boot/freeldr/freeldr/ui/ui.c
Modified: trunk/reactos/hal/halx86/generic/display.c
Modified: trunk/reactos/hal/halx86/generic/halinit.c
Modified: trunk/reactos/ntoskrnl/ex/init.c
Modified: trunk/reactos/ntoskrnl/io/driver.c

Modified: trunk/reactos/boot/freeldr/freeldr/include/ui/tui.h
--- trunk/reactos/boot/freeldr/freeldr/include/ui/tui.h	2005-12-27 03:06:35 UTC (rev 20365)
+++ trunk/reactos/boot/freeldr/freeldr/include/ui/tui.h	2005-12-27 03:12:00 UTC (rev 20366)
@@ -73,12 +73,12 @@
 
 } TUI_MENU_INFO, *PTUI_MENU_INFO;
 
-VOID	TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo);
-VOID	TuiDrawMenu(PTUI_MENU_INFO MenuInfo);
-VOID	TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo);
-VOID	TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber);
-ULONG		TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter);
-BOOL	TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter);
+VOID	WINAPI TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo);
+VOID	WINAPI TuiDrawMenu(PTUI_MENU_INFO MenuInfo);
+VOID	WINAPI TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo);
+VOID	WINAPI TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber);
+ULONG	WINAPI TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter);
+BOOL	WINAPI TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter);
 
 
 /*

Modified: trunk/reactos/boot/freeldr/freeldr/include/ui.h
--- trunk/reactos/boot/freeldr/freeldr/include/ui.h	2005-12-27 03:06:35 UTC (rev 20365)
+++ trunk/reactos/boot/freeldr/freeldr/include/ui.h	2005-12-27 03:12:00 UTC (rev 20366)
@@ -46,6 +46,10 @@
 extern	BOOL	UserInterfaceUp;								// Tells us if the user interface is displayed
 
 extern	BOOL	UiUseSpecialEffects;							// Tells us if we should use fade effects
+extern BOOL UiCenterMenu;
+extern BOOL UiMenuBox;
+extern BOOL UiMinimal;
+extern CHAR UiTimeText[];
 
 extern	const CHAR	UiMonthNames[12][15];
 

Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
--- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c	2005-12-27 03:06:35 UTC (rev 20365)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c	2005-12-27 03:12:00 UTC (rev 20366)
@@ -587,6 +587,10 @@
 		return;
 	}
 
+	UiDrawBackdrop();
+	UiDrawStatusText("Detecting Hardware...");
+    UiDrawProgressBarCenter(1, 100, szLoadingMsg);
+
 	/*
 	 * Setup multiboot information structure
 	 */
@@ -677,19 +681,15 @@
 		strcat(reactos_kernel_cmdline, value);
 	}
 
-
-	UiDrawBackdrop();
-	UiDrawStatusText("Detecting Hardware...");
-
 	/*
 	 * Detect hardware
 	 */
 	MachHwDetect();
+    UiDrawProgressBarCenter(5, 100, szLoadingMsg);
 
 	if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
 
 	UiDrawStatusText("Loading...");
-	UiDrawProgressBarCenter(0, 100, szLoadingMsg);
 
 	/*
 	 * Try to open system drive

Modified: trunk/reactos/boot/freeldr/freeldr/ui/tui.c
--- trunk/reactos/boot/freeldr/freeldr/ui/tui.c	2005-12-27 03:06:35 UTC (rev 20365)
+++ trunk/reactos/boot/freeldr/freeldr/ui/tui.c	2005-12-27 03:12:00 UTC (rev 20366)
@@ -20,6 +20,8 @@
 #include <freeldr.h>
 
 PVOID	TextVideoBuffer = NULL;
+extern BOOL UiDrawTime;
+extern BOOL UiMinimal;
 
 /*
  * printf() - prints formatted text to stdout
@@ -111,6 +113,25 @@
 
 VOID TuiDrawBackdrop(VOID)
 {
+    if (UiMinimal)
+    {
+        //
+        // Fill in a black background
+        //
+        TuiFillArea(0,
+                    0,
+                    UiScreenWidth - 1,
+                    UiScreenHeight - 1,
+                    0,
+                    0);
+
+        //
+        // Update the screen buffer
+        //
+        VideoCopyOffScreenBufferToVRAM();
+        return;
+    }
+
 	//
 	// Fill in the background (excluding title box & status bar)
 	//
@@ -429,6 +450,11 @@
 {
 	ULONG		i;
 
+    //
+    // Minimal UI doesn't have a status bar
+    //
+    if (UiMinimal) return;
+
 	TuiDrawText(0, UiScreenHeight-1, " ", ATTR(UiStatusBarFgColor, UiStatusBarBgColor));
 	TuiDrawText(1, UiScreenHeight-1, StatusText, ATTR(UiStatusBarFgColor, UiStatusBarBgColor));
 
@@ -449,6 +475,9 @@
 	CHAR	TempString[20];
 	BOOL	PMHour = FALSE;
 
+    /* Don't draw the time if this has been disabled */
+    if (!UiDrawTime) return;
+
 	MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second);
 	if (Year < 1 || 9999 < Year || Month < 1 || 12 < Month || Day < 1 ||
             31 < Day || 23 < Hour || 59 < Minute || 59 < Second)
@@ -663,10 +692,28 @@
 	ULONG		Width = 50; // Allow for 50 "bars"
 	ULONG		Height = 2;
 
-	Left = (UiScreenWidth - Width - 4) / 2;
-	Right = Left + Width + 3;
-	Top = (UiScreenHeight - Height - 2) / 2;
-	Top += 2;
+	//
+	// Is this the minimal UI?
+	//
+	if (UiMinimal)
+	{
+		//
+		// Use alternate settings
+		//
+		Width = 80;
+		Left = 0;
+		Right = Left + Width;
+		Top = UiScreenHeight - Height - 4;
+		Bottom = Top + Height + 1;
+	}
+	else
+	{
+		Left = (UiScreenWidth - Width - 4) / 2;
+		Right = Left + Width + 3;
+		Top = (UiScreenHeight - Height - 2) / 2;
+		Top += 2;
+	}
+
 	Bottom = Top + Height + 1;
 
 	TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText);
@@ -685,12 +732,26 @@
 		Position = Range;
 	}
 
-	// Draw the box
-	TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor));
+    //
+    // Minimal UI has no box, and only generic loading text
+    //
+    if (!UiMinimal)
+    {
+	    // Draw the box
+	    TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor));
 
-	// Draw the "Loading..." text
-	//TuiDrawText(70/2, Top+1, "Loading...", ATTR(UiTextColor, UiMenuBgColor));
-	TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor));
+    	//
+        //  Draw the "Loading..." text
+        //
+	    TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor));
+    }
+    else
+    {
+    	//
+        //  Draw the "Loading..." text
+        //
+        TuiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, "ReactOS is loading files...", ATTR(7, 0));
+    }
 
 	// Draw the percent complete
 	for (i=0; i<(Position*ProgressBarWidth)/Range; i++)
@@ -698,14 +759,16 @@
 		TuiDrawText(Left+2+i, Top+2, "\xDB", ATTR(UiTextColor, UiMenuBgColor));
 	}
 
-	// Draw the rest
-	for (; i<ProgressBarWidth; i++)
-	{
-		TuiDrawText(Left+2+i, Top+2, "\xB2", ATTR(UiTextColor, UiMenuBgColor));
-	}
+	// Draw the shadow for non-minimal UI
+    if (!UiMinimal)
+    {
+	    for (; i<ProgressBarWidth; i++)
+	    {
+		    TuiDrawText(Left+2+i, Top+2, "\xB2", ATTR(UiTextColor, UiMenuBgColor));
+	    }
+    }
 
 	TuiUpdateDateTime();
-
 	VideoCopyOffScreenBufferToVRAM();
 }
 

Modified: trunk/reactos/boot/freeldr/freeldr/ui/tuimenu.c
--- trunk/reactos/boot/freeldr/freeldr/ui/tuimenu.c	2005-12-27 03:06:35 UTC (rev 20365)
+++ trunk/reactos/boot/freeldr/freeldr/ui/tuimenu.c	2005-12-27 03:12:00 UTC (rev 20366)
@@ -1,427 +1,549 @@
 /*
- *  FreeLoader
- *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         FreeLoader
+ * FILE:            freeldr/ui/tuimenu.c
+ * PURPOSE:         UI Menu Functions
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Brian Palmer (brianp@sginet.com)
  */
 
+/* INCLUDES ******************************************************************/
+
 #include <freeldr.h>
 
-BOOL TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter)
+/* FUNCTIONS *****************************************************************/
+
+BOOL
+WINAPI
+TuiDisplayMenu(PCSTR MenuItemList[],
+               ULONG MenuItemCount,
+               ULONG DefaultMenuItem,
+               LONG MenuTimeOut,
+               ULONG* SelectedMenuItem,
+               BOOL CanEscape,
+               UiMenuKeyPressFilterCallback KeyPressFilter)
 {
-	TUI_MENU_INFO	MenuInformation;
-	ULONG		LastClockSecond;
-	ULONG		CurrentClockSecond;
-	ULONG		KeyPress;
+    TUI_MENU_INFO MenuInformation;
+    ULONG LastClockSecond;
+    ULONG CurrentClockSecond;
+    ULONG KeyPress;
 
-	//
-	// The first thing we need to check is the timeout
-	// If it's zero then don't bother with anything,
-	// just return the default item
-	//
-	if (MenuTimeOut == 0)
-	{
-		if (SelectedMenuItem != NULL)
-		{
-			*SelectedMenuItem = DefaultMenuItem;
-		}
+    //
+    // Check if there's no timeout
+    if (!MenuTimeOut)
+    {
+        //
+        // Return the default selected item
+        //
+        if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem;
+        return TRUE;
+    }
 
-		return TRUE;
-	}
+    //
+    // Setup the MENU_INFO structure
+    //
+    MenuInformation.MenuItemList = MenuItemList;
+    MenuInformation.MenuItemCount = MenuItemCount;
+    MenuInformation.MenuTimeRemaining = MenuTimeOut;
+    MenuInformation.SelectedMenuItem = DefaultMenuItem;
 
-	//
-	// Setup the MENU_INFO structure
-	//
-	MenuInformation.MenuItemList = MenuItemList;
-	MenuInformation.MenuItemCount = MenuItemCount;
-	MenuInformation.MenuTimeRemaining = MenuTimeOut;
-	MenuInformation.SelectedMenuItem = DefaultMenuItem;
+    //
+    // Calculate the size of the menu box
+    //
+    TuiCalcMenuBoxSize(&MenuInformation);
 
-	//
-	// Calculate the size of the menu box
-	//
-	TuiCalcMenuBoxSize(&MenuInformation);
+    //
+    // Draw the menu
+    //
+    TuiDrawMenu(&MenuInformation);
 
-	//
-	// Draw the menu
-	//
-	TuiDrawMenu(&MenuInformation);
+    //
+    // Get the current second of time
+    //
+    MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &LastClockSecond);
 
-	//
-	// Get the current second of time
-	//
-	MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &LastClockSecond);
+    //
+    // Process keys
+    //
+    while (TRUE)
+    {
+        //
+        // Process key presses
+        //
+        KeyPress = TuiProcessMenuKeyboardEvent(&MenuInformation,
+                                               KeyPressFilter);
 
-	//
-	// Process keys
-	//
-	while (1)
-	{
-		//
-		// Process key presses
-		//
-		KeyPress = TuiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter);
-		if (KeyPress == KEY_ENTER)
-		{
-			//
-			// If they pressed enter then exit this loop
-			//
-			break;
-		}
-		else if (CanEscape && KeyPress == KEY_ESC)
-		{
-			//
-			// They pressed escape, so just return FALSE
-			//
-			return FALSE;
-		}
+        //
+        // Check for ENTER or ESC
+        //
+        if (KeyPress == KEY_ENTER) break;
+        if (CanEscape && KeyPress == KEY_ESC) return FALSE;
 
-		//
-		// Update the date & time
-		//
-		TuiUpdateDateTime();
+        //
+        // Update the date & time
+        //
+        TuiUpdateDateTime();
+        VideoCopyOffScreenBufferToVRAM();
 
-		VideoCopyOffScreenBufferToVRAM();
+        //
+        // Check if there is a countdown
+        //
+        if (MenuInformation.MenuTimeRemaining)
+        {
+            //
+            // Get the updated time, seconds only
+            //
+            MachRTCGetCurrentDateTime(NULL,
+                                      NULL,
+                                      NULL,
+                                      NULL,
+                                      NULL,
+                                      &CurrentClockSecond);
 
-		if (MenuInformation.MenuTimeRemaining > 0)
-		{
-			MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &CurrentClockSecond);
-			if (CurrentClockSecond != LastClockSecond)
-			{
-				//
-				// Update the time information
-				//
-				LastClockSecond = CurrentClockSecond;
-				MenuInformation.MenuTimeRemaining--;
+            //
+            // Check if more then a second has now elapsed
+            //
+            if (CurrentClockSecond != LastClockSecond)
+            {
+                //
+                // Update the time information
+                //
+                LastClockSecond = CurrentClockSecond;
+                MenuInformation.MenuTimeRemaining--;
 
-				//
-				// Update the menu
-				//
-				TuiDrawMenuBox(&MenuInformation);
+                //
+                // Update the menu
+                //
+                TuiDrawMenuBox(&MenuInformation);
+                VideoCopyOffScreenBufferToVRAM();
+            }
+        }
+        else
+        {
+            //
+            // A time out occurred, exit this loop and return default OS
+            //
+            break;
+        }
+    }
 
-				VideoCopyOffScreenBufferToVRAM();
-			}
-		}
-		else if (MenuInformation.MenuTimeRemaining == 0)
-		{
-			//
-			// A time out occurred, exit this loop and return default OS
-			//
-			break;
-		}
-	}
-
-	//
-	// Update the selected menu item information
-	//
-	if (SelectedMenuItem != NULL)
-	{
-		*SelectedMenuItem = MenuInformation.SelectedMenuItem;
-	}
-
-	return TRUE;
+    //
+    // Return the selected item
+    //
+    if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem;
+    return TRUE;
 }
 
-VOID TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo)
+VOID
+WINAPI
+TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo)
 {
-	ULONG		Idx;
-	ULONG		Width;
-	ULONG		Height;
-	ULONG		Length;
+    ULONG i;
+    ULONG Width = 0;
+    ULONG Height;
+    ULONG Length;
 
-	//
-	// Height is the menu item count plus 2 (top border & bottom border)
-	//
-	Height = MenuInfo->MenuItemCount + 2;
-	Height -= 1; // Height is zero-based
+    //
+    // Height is the menu item count plus 2 (top border & bottom border)
+    //
+    Height = MenuInfo->MenuItemCount + 2;
+    Height -= 1; // Height is zero-based
 
-	//
-	// Find the length of the longest string in the menu
-	//
-	Width = 0;
-	for(Idx=0; Idx<MenuInfo->MenuItemCount; Idx++)
-	{
-		Length = strlen(MenuInfo->MenuItemList[Idx]);
+    //
+    // Loop every item
+    //
+    for(i = 0; i < MenuInfo->MenuItemCount; i++)
+    {
+        //
+        // Get the string length and make it become the new width if necessary
+        //
+        Length = strlen(MenuInfo->MenuItemList[i]);
+        if (Length > Width) Width = Length;
+    }
 
-		if (Length > Width)
-		{
-			Width = Length;
-		}
-	}
+    //
+    // Allow room for left & right borders, plus 8 spaces on each side
+    //
+    Width += 18;
 
-	//
-	// Allow room for left & right borders, plus 8 spaces on each side
-	//
-	Width += 18;
+    //
+    // Check if we're drawing a centered menu
+    //
+    if (UiCenterMenu)
+    {
+        //
+        // Calculate the menu box area for a centered menu
+        //
+        MenuInfo->Left = (UiScreenWidth - Width) / 2;
+        MenuInfo->Top = (((UiScreenHeight - TUI_TITLE_BOX_CHAR_HEIGHT) -
+                          Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT;
+    }
+    else
+    {
+        //
+        // Put the menu in the default left-corner position
+        //
+        MenuInfo->Left = -1;
+        MenuInfo->Top = 4;
+    }
 
-	//
-	// Calculate the menu box area
-	//
-	MenuInfo->Left = (UiScreenWidth - Width) / 2;
-	MenuInfo->Right = (MenuInfo->Left) + Width;
-	MenuInfo->Top = (((UiScreenHeight - TUI_TITLE_BOX_CHAR_HEIGHT) - Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT;
-	MenuInfo->Bottom = (MenuInfo->Top) + Height;
+    //
+    // The other margins are the same
+    //
+    MenuInfo->Right = (MenuInfo->Left) + Width;
+    MenuInfo->Bottom = (MenuInfo->Top) + Height;
 }
 
-VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo)
+VOID
+WINAPI
+TuiDrawMenu(PTUI_MENU_INFO MenuInfo)
 {
-	ULONG		Idx;
+    ULONG i;
 
-	//
-	// Draw the backdrop
-	//
-	UiDrawBackdrop();
+    //
+    // Draw the backdrop
+    //
+    UiDrawBackdrop();
 
-	//
-	// Update the status bar
-	//
-	UiDrawStatusText("Use \x18\x19 to select, then press ENTER.");
+    //
+    // Check if this is the minimal (console) UI
+    //
+    if (UiMinimal)
+    {
+        //
+        // No GUI status bar text, just minimal text. first to tell the user to
+        // choose.
+        //
+        TuiDrawText(0,
+                    MenuInfo->Top - 2,
+                    "Please select the operating system to start:",
+                    ATTR(UiMenuFgColor, UiMenuBgColor));
 
-	//
-	// Draw the menu box
-	//
-	TuiDrawMenuBox(MenuInfo);
+        //
+        // Now tell him how to choose
+        //
+        TuiDrawText(0,
+                    MenuInfo->Bottom + 1,
+                    "Use the up and down arrow keys to move the highlight to "
+                    "your choice.",
+                    ATTR(UiMenuFgColor, UiMenuBgColor));
+        TuiDrawText(0,
+                    MenuInfo->Bottom + 2,
+                    "Press ENTER to choose.",
+                    ATTR(UiMenuFgColor, UiMenuBgColor));
 
-	//
-	// Draw each line of the menu
-	//
-	for (Idx=0; Idx<MenuInfo->MenuItemCount; Idx++)
-	{
-		TuiDrawMenuItem(MenuInfo, Idx);
-	}
+        //
+        // And offer F8 options
+        //
+        TuiDrawText(0,
+                    UiScreenHeight - 4,
+                    "For troubleshooting and advanced startup options for "
+                    "ReactOS, press F8.",
+                    ATTR(UiMenuFgColor, UiMenuBgColor));
+    }
+    else
+    {
+        //
+        // Update the status bar
+        //
+        UiDrawStatusText("Use \x18\x19 to select, then press ENTER.");
+    }
 
-	VideoCopyOffScreenBufferToVRAM();
-}
+    //
+    // Draw the menu box
+    //
+    TuiDrawMenuBox(MenuInfo);
 
-VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo)
-{
-	CHAR	MenuLineText[80];
-	CHAR	TempString[80];
-	ULONG		Idx;
-
-	//
-	// Draw the menu box
-	//
-	UiDrawBox(MenuInfo->Left,
-		MenuInfo->Top,
-		MenuInfo->Right,
-		MenuInfo->Bottom,
-		D_VERT,
-		D_HORZ,
-		FALSE,		// Filled
-		TRUE,		// Shadow
-		ATTR(UiMenuFgColor, UiMenuBgColor));
-
-	//
-	// If there is a timeout draw the time remaining
-	//
-	if (MenuInfo->MenuTimeRemaining >= 0)
-	{
-		strcpy(MenuLineText, "[ Time Remaining: ");
-		_itoa(MenuInfo->MenuTimeRemaining, TempString, 10);
-		strcat(MenuLineText, TempString);
-		strcat(MenuLineText, " ]");
-
-		UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
-			MenuInfo->Bottom,
-			MenuLineText,
-			ATTR(UiMenuFgColor, UiMenuBgColor));
-	}
-
-	//
-	// Now draw the separators
-	//
-	for (Idx=0; Idx<MenuInfo->MenuItemCount; Idx++)
-	{
-		if (_stricmp(MenuInfo->MenuItemList[Idx], "SEPARATOR") == 0)
-		{
-			UiDrawText(MenuInfo->Left, MenuInfo->Top + Idx + 1, "\xC7", ATTR(UiMenuFgColor, UiMenuBgColor));
-			UiDrawText(MenuInfo->Right, MenuInfo->Top + Idx + 1, "\xB6", ATTR(UiMenuFgColor, UiMenuBgColor));
-		}
-	}
+    //
+    // Draw each line of the menu
+    //
+    for (i = 0; i < MenuInfo->MenuItemCount; i++) TuiDrawMenuItem(MenuInfo, i);
+    VideoCopyOffScreenBufferToVRAM();
 }
 
-VOID TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber)
+VOID
+WINAPI
+TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo)
 {
-	ULONG		Idx;
-	CHAR	MenuLineText[80];
-	ULONG		SpaceTotal;
-	ULONG		SpaceLeft;
-	ULONG		SpaceRight;
-	UCHAR	Attribute;
+    CHAR MenuLineText[80];
+    CHAR TempString[80];
+    ULONG i;
 
-	//
-	// We will want the string centered so calculate
-	// how many spaces will be to the left and right
-	//
-	SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) - strlen(MenuInfo->MenuItemList[MenuItemNumber]);
-	SpaceLeft = (SpaceTotal / 2) + 1;
-	SpaceRight = (SpaceTotal - SpaceLeft) + 1;
+    //
+    // Draw the menu box if requested
+    //
+    if (UiMenuBox)
+    {
+        UiDrawBox(MenuInfo->Left,
+                  MenuInfo->Top,
+                  MenuInfo->Right,
+                  MenuInfo->Bottom,
+                  D_VERT,
+                  D_HORZ,
+                  FALSE,        // Filled
+                  TRUE,        // Shadow
+                  ATTR(UiMenuFgColor, UiMenuBgColor));
+    }
 
-	//
-	// Insert the spaces on the left
-	//
-	for (Idx=0; Idx<SpaceLeft; Idx++)
-	{
-		MenuLineText[Idx] = ' ';
-	}
-	MenuLineText[Idx] = '\0';
+    //
+    // If there is a timeout draw the time remaining
+    //
+    if (MenuInfo->MenuTimeRemaining >= 0)
+    {
+        //
+        // Copy the integral time text string, and remove the last 2 chars
+        //
+        strcpy(TempString, UiTimeText);
+        i = strlen(TempString);
+        TempString[i - 2] = 0;
 
-	//
-	// Now append the text string
-	//
-	strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
+        //
+        // Display the first part of the string and the remaining time
+        //
+        strcpy(MenuLineText, TempString);
+        _itoa(MenuInfo->MenuTimeRemaining, TempString, 10);
+        strcat(MenuLineText, TempString);
 
-	//
-	// Now append the spaces on the right
-	//
-	for (Idx=0; Idx<SpaceRight; Idx++)
-	{
-		strcat(MenuLineText, " ");
-	}
+        //
+        // Add the last 2 chars
+        //
+        strcat(MenuLineText, &UiTimeText[i - 2]);
 
-	//
-	// If it is a separator then adjust the text accordingly
-	//
-	if (_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR") == 0)
-	{
-		memset(MenuLineText, 0, 80);
-		memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1));
-		Attribute = ATTR(UiMenuFgColor, UiMenuBgColor);
-	}
-	else
-	{
-		Attribute = ATTR(UiTextColor, UiMenuBgColor);
-	}
+        //
+        // Check if this is a centered menu
+        //
+        if (UiCenterMenu)
+        {
+            //
+            // Display it in the center of the menu
+            //
+            UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
+                       MenuInfo->Bottom,
+                       MenuLineText,
+                       ATTR(UiMenuFgColor, UiMenuBgColor));
+        }
+        else
+        {
+            //
+            // Display under the menu directly
+            //
+            UiDrawText(0,
+                       MenuInfo->Bottom + 3,
+                       MenuLineText,
+                       ATTR(UiMenuFgColor, UiMenuBgColor));
+        }
+    }
 
-	//
-	// If this is the selected menu item then draw it as selected
-	// otherwise just draw it using the normal colors
-	//
-	if (MenuItemNumber == MenuInfo->SelectedMenuItem)
-	{
-		UiDrawText(MenuInfo->Left + 1,
-			MenuInfo->Top + 1 + MenuItemNumber,
-			MenuLineText,
-			ATTR(UiSelectedTextColor, UiSelectedTextBgColor));
-	}
-	else
-	{
-		UiDrawText(MenuInfo->Left + 1,
-			MenuInfo->Top + 1 + MenuItemNumber,
-			MenuLineText,
-			Attribute);
-	}
+    //
+    // Loop each item
+    //
+    for (i = 0; i < MenuInfo->MenuItemCount; i++)
+    {
+        //
+        // Check if it's a separator
+        //
+        if (!(_stricmp(MenuInfo->MenuItemList[i], "SEPARATOR")))
+        {
+            //
+            // Draw the separator line
+            //
+            UiDrawText(MenuInfo->Left,
+                       MenuInfo->Top + i + 1,
+                       "\xC7",
+                       ATTR(UiMenuFgColor, UiMenuBgColor));
+            UiDrawText(MenuInfo->Right,
+                       MenuInfo->Top + i + 1,
+                       "\xB6",
+                       ATTR(UiMenuFgColor, UiMenuBgColor));
+        }
+    }
 }
 
-ULONG TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter)
+VOID
+WINAPI
+TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo,
+                ULONG MenuItemNumber)
 {
-	ULONG		KeyEvent = 0;
+    ULONG i;
+    CHAR MenuLineText[80];
+    ULONG SpaceTotal;
+    ULONG SpaceLeft;
+    ULONG SpaceRight = 0;
+    UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor);
 
-	//
-	// Check for a keypress
-	//
-	if (MachConsKbHit())
-	{
-		//
-		// Cancel the timeout
-		//
-		if (MenuInfo->MenuTimeRemaining != -1)
-		{
-			MenuInfo->MenuTimeRemaining = -1;
-			TuiDrawMenuBox(MenuInfo);
-		}
+    //
+    // Check if using centered menu
+    //
+    if (UiCenterMenu)
+    {
+        //
+        // We will want the string centered so calculate
+        // how many spaces will be to the left and right
+        //
+        SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) -
+                     strlen(MenuInfo->MenuItemList[MenuItemNumber]);
+        SpaceLeft = (SpaceTotal / 2) + 1;
+        SpaceRight = (SpaceTotal - SpaceLeft) + 1;
 
-		//
-		// Get the key
-		//
-		KeyEvent = MachConsGetCh();
+        //
+        // Insert the spaces on the left
+        //
+        for (i = 0; i < SpaceLeft; i++) MenuLineText[i] = ' ';
+        MenuLineText[i] = '\0';
+    }
+    else
+    {
+        //
+        // Simply left-align it
+        //
+        MenuLineText[0] = '\0';
+        strcat(MenuLineText, "    ");
+    }
 
-		//
-		// Is it extended?
-		//
-		if (KeyEvent == 0)
-			KeyEvent = MachConsGetCh(); // Yes - so get the extended key
+    //
+    // Now append the text string
+    //
+    strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
 
-		//
-		// Call the supplied key filter callback function to see
-		// if it is going to handle this keypress.
-		//
-		if (KeyPressFilter != NULL)
-		{
-			if (KeyPressFilter(KeyEvent))
-			{
-				// It processed the key character
-				TuiDrawMenu(MenuInfo);
+    //
+    // Check if using centered menu, and add spaces on the right if so
+    //
+    if (UiCenterMenu) for (i=0; i < SpaceRight; i++) strcat(MenuLineText, " ");
 
-				return 0;
-			}
-		}
+    //
+    // If it is a separator
+    //
+    if (!(_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR")))
+    {
+        //
+        // Make it a separator line and use menu colors
+        //
+        memset(MenuLineText, 0, 80);
+        memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1));
+        Attribute = ATTR(UiMenuFgColor, UiMenuBgColor);
+    }
+    else if (MenuItemNumber == MenuInfo->SelectedMenuItem)
+    {
+        //
+        // If this is the selected item, use the selected colors
+        //
+        Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor);
+    }
 
-		//
-		// Process the key
-		//
-		switch (KeyEvent)
-		{
-		case KEY_UP:
+    //
+    // Draw the item
+    //
+    UiDrawText(MenuInfo->Left + 1,
+               MenuInfo->Top + 1 + MenuItemNumber,
+               MenuLineText,
+               Attribute);
+}
 
-			if (MenuInfo->SelectedMenuItem > 0)
-			{
-				MenuInfo->SelectedMenuItem--;
+ULONG
+WINAPI
+TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo,
[truncated at 1000 lines; 314 more skipped]