Full screen config.sys menus (use MENUCOLOR=)

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@696 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2003-09-18 20:55:41 +00:00
parent c20f68e73d
commit f489b1a1b1
2 changed files with 352 additions and 79 deletions

View File

@ -118,6 +118,53 @@ MENUDEFAULT=0,0
DEVICE=ATAPICDD.SYS /D:MSCD000
Full Screen Menus (thanks to Rune Espeseth)
Use MENUCOLOR=foreground[,background] to obtain a full screen menu
where you can use the arrow keys. Example (note that box drawing
characters are used that look strange in other character sets):
REM *** This is the FreeDos Config.sys ***
REM *** executed before autoexec.bat ***
REM *** Set white foreground, red background ***
menucolor=7,4
files=20
buffers=20
REM *** The Menu ***
MENU
MENU ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
MENU º My Menu - FreeDOS rules! º
MENU ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
MENU º º
MENU º 1. Test with border º
MENU º º
MENU º 2. Another test... º
MENU º º
MENU º 3. Third choice º
MENU º º
MENU º 4. Fourth choice. º
MENU º º
MENU ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
MENU
MENUDEFAULT=1,10 ( configuration 1, wait 10 seconds)
1? REM 1st choice
1? ECHO You selected menu #1
2? REM 2nd choice
2? ECHO You selected menu #2
3? REM 3rd choice
3? ECHO You selected menu #3
4? REM 4th choice
4? ECHO You selected menu #4
@ -125,9 +172,4 @@ DEVICE=ATAPICDD.SYS /D:MSCD000
2002-11-28 - Tom Ehlert
2003-07-15 - Bernd Blaauw
2003-09-18 - Bart Oldeman

View File

@ -43,6 +43,94 @@ static BYTE *RcsId =
#endif
#define para2far(seg) ((mcb FAR *)MK_FP((seg), 0))
/**
Menu selection bar struct:
x pos, ypos, string
*/
#define MENULINEMAX 80
#define MENULINESMAX 10
struct MenuSelector
{
int x;
int y;
BYTE bSelected;
BYTE Text[MENULINEMAX];
};
/** Structure below holds the menu-strings */
STATIC struct MenuSelector MenuStruct[MENULINESMAX] =
{
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}},
{0,0,0,{""}}
};
int nMenuLine=0;
BOOL MenuColor = -1;
STATIC void WriteMenuLine(int MenuSelected)
{
iregs r;
unsigned char attr = (unsigned char)MenuColor;
char *pText = MenuStruct[MenuSelected].Text;
size_t len = 0;
if (pText[0] == 0)
return;
do len++; while (pText[len]);
if(MenuStruct[MenuSelected].bSelected==1)
attr = ((attr << 4) | (attr >> 4));
/* clear line */
r.a.x = 0x0600;
r.b.b.h = attr;
r.c.b.l = r.d.b.l = MenuStruct[MenuSelected].x;
r.c.b.h = r.d.b.h = MenuStruct[MenuSelected].y;
r.d.b.l += len - 1;
init_call_intr(0x10, &r);
/* set cursor position: */
r.a.b.h = 0x02;
r.b.b.h = 0;
r.d.b.l = MenuStruct[MenuSelected].x;
r.d.b.h = MenuStruct[MenuSelected].y;
init_call_intr(0x10, &r);
printf("%s", pText);
}
/* Deselect the previously selected line */
STATIC void DeselectLastLine(void)
{
int i;
for (i = 0 ; i < MENULINESMAX; i++)
{
if (MenuStruct[i].bSelected == 1)
{
/* deselect it: */
MenuStruct[i].bSelected = 0;
WriteMenuLine(i);
break;
}
}
}
STATIC void SelectLine(int MenuSelected)
{
DeselectLastLine(); /* clear previous selection */
MenuStruct[MenuSelected].bSelected = 1; /* set selection flag for this one */
WriteMenuLine(MenuSelected);
}
UWORD umb_start = 0, UMB_top = 0;
UWORD ram_top = 0; /* How much ram in Kbytes */
@ -97,6 +185,8 @@ BYTE MenuSelected = 0;
UCOUNT MenuLine = 0;
UCOUNT Menus = 0;
STATIC VOID CfgMenuColor(BYTE * pLine);
STATIC VOID Config_Buffers(BYTE * pLine);
STATIC VOID sysScreenMode(BYTE * pLine);
STATIC VOID sysVersion(BYTE * pLine);
@ -179,12 +269,14 @@ STATIC struct table commands[] = {
/* first = switches! this one is special since it is asked for but
also checked before F5/F8 */
{"SWITCHES", 0, CfgSwitches},
/* rem is never executed by locking out pass */
{"REM", 0, CfgIgnore},
{";", 0, CfgIgnore},
{"MENUDEFAULT", 0, CfgMenuDefault},
{"MENUCOLOR",0,CfgMenuColor},
{"MENUDEFAULT", 0, CfgMenuDefault},
{"MENU", 0, CfgMenu}, /* lines to print in pass 0 */
{"ECHO", 2, CfgMenu}, /* lines to print in pass 2 - install(high) */
{"EECHO", 2, CfgMenuEsc}, /* modified ECHO (ea) */
@ -219,6 +311,23 @@ STATIC struct table commands[] = {
{"", -1, CfgFailure}
};
/* RE function for menu. */
int findend(BYTE * s)
{
int nLen = 0;
/* 'marks' end if at least three spaces, 0, or newline is found. */
while (*s && (*s != 0x0d || *s != 0x0a) )
{
BYTE *p= skipwh(s);
/* ah, more than two whitespaces ? We're done here (hrmph!) */
if((unsigned int)p - (unsigned int)s>=3)
break;
nLen++;
++s;
}
return nLen;
}
BYTE *pLineStart = 0;
BYTE HMAState = 0;
@ -606,22 +715,30 @@ VOID DoConfig(int pass)
if (nPass == 0) /* pass 0 always executed (rem Menu prompt switches) */
{
(*(pEntry->func)) (pLine);
pEntry->func(pLine);
continue;
}
else
{
{
if (SkipLine(pLineStart)) /* F5/F8 processing */
continue;
}
if ((pEntry->func != CfgMenu) && (pEntry->func != CfgMenuEsc))
{
/* compatibility "device foo.sys" */
if (' ' != *pLine && '\t' != *pLine && '=' != *pLine)
{
CfgFailure(pLine);
continue;
}
pLine = skipwh(pLine);
}
if ('=' == *pLine || pEntry->func == CfgMenu || pEntry->func == CfgMenuEsc)
pLine = skipwh(pLine+1);
if ('=' != *pLine && pEntry->func != CfgMenu && pEntry->func != CfgMenuEsc)
CfgFailure(pLine);
else /* YES. DO IT */
(*(pEntry->func)) (skipwh(pLine + 1));
/* YES. DO IT */
pEntry->func(pLine);
}
close(nFileDesc);
@ -708,7 +825,7 @@ STATIC BOOL SkipLine(char *pLine)
{
SkipAllConfig = TRUE;
}
if (key == 0x4200) /* F8 */
else if (key == 0x4200) /* F8 */
{
singleStep = TRUE;
}
@ -725,7 +842,7 @@ STATIC BOOL SkipLine(char *pLine)
/* 1?device=CDROM.SYS */
/* 12?device=OAKROM.SYS */
/* 123?device=EMM386.EXE NOEMS */
if ( MenuLine != 0 &&
if ( MenuLine != 0 &&
(MenuLine & (1 << MenuSelected)) == 0)
return TRUE;
@ -807,35 +924,34 @@ STATIC void Config_Buffers(BYTE * pLine)
(nBuffers < 0 ? nBuffers : max(Config.cfgBuffers, nBuffers));
}
/**
Set screen mode - rewritten to use init_call_intr() by RE / ICD
*/
STATIC VOID sysScreenMode(BYTE * pLine)
{
iregs r;
COUNT nMode;
COUNT nFunc = 0x11;
/* Get the argument */
if (GetNumArg(pLine, &nMode) == (BYTE *) 0)
return;
if ((nMode != 0x11) && (nMode != 0x12) && (nMode != 0x14))
return;
if(nMode<0x10)
nFunc = 0; /* set lower screenmode */
else if ((nMode != 0x11) && (nMode != 0x12) && (nMode != 0x14))
return; /* do nothing; invalid screenmode */
/* Modes
0x11 (17) 28 lines
0x12 (18) 43/50 lines
0x14 (20) 25 lines
*/
#if defined(__TURBOC__)
_AX = (0x11 << 8) + nMode;
_BL = 0;
__int__(0x10);
#elif defined(I86)
asm
{
mov al, byte ptr nMode;
mov ah, 0x11;
mov bl, 0;
int 0x10;
}
#endif
/* move cursor to pos 0,0: */
r.a.b.h = nFunc; /* set videomode */
r.a.b.l = nMode;
r.b.b.l = 0;
init_call_intr(0x10, &r);
}
STATIC VOID sysVersion(BYTE * pLine)
@ -982,13 +1098,8 @@ STATIC VOID CfgSwitchar(BYTE * pLine)
STATIC VOID CfgSwitches(BYTE * pLine)
{
pLine = skipwh(pLine);
if (commands[0].pass == 0) {
/* compatibility "device foo.sys" */
if ('=' != *pLine && ' ' != *pLine && '\t' != *pLine)
{
CfgFailure(pLine);
return;
}
if (*pLine == '=')
{
pLine = skipwh(pLine + 1);
}
while (*pLine)
@ -1008,15 +1119,15 @@ STATIC VOID CfgSwitches(BYTE * pLine)
break;
case 'E': /* /E[[:]nnnn] Set the desired EBDA amount to move in bytes */
{ /* Note that if there is no EBDA, this will have no effect */
char *p;
int n = 0;
if (*++pLine == ':')
pLine++; /* skip optional separator */
if ((p = GetNumArg(pLine, &n)) == 0) {
if (!isnum(*pLine))
{
Config.ebda2move = 0;
break;
}
pLine = p - 1; /* p points past number */
pLine = GetNumArg(pLine, &n) - 1;
/* allowed values: [48..1024] bytes, multiples of 16
* e.g. AwardBIOS: 48, AMIBIOS: 1024
* (Phoenix, MRBIOS, Unicore = ????)
@ -1738,10 +1849,44 @@ STATIC VOID CfgIgnore(BYTE * pLine)
*/
STATIC void ClearScreen(unsigned char attr);
STATIC VOID CfgMenu(BYTE * pLine)
{
int nLen;
BYTE *pNumber = pLine;
printf("%s\n",pLine);
}
if (MenuColor == -1)
return;
pLine = skipwh(pLine);
/* skip drawing characters in cp437, which is what we'll have
just after booting! */
while ((unsigned char)*pLine >= 0xb0 && (unsigned char)*pLine < 0xe0)
pLine++;
pLine = skipwh(pLine); /* skip more whitespaces... */
/* now I'm expecting a number here if this is a menu-choice line. */
if (pLine[0]>='1' && pLine[0]<='9')
{
int nIndex = pLine[0]-'0';
MenuStruct[nIndex].x = (pLine-pNumber); /* xpos is at start of number */
MenuStruct[nIndex].y = nMenuLine;
/* copy menu text: */
nLen = findend(pLine); /* length is until cr/lf, null or three spaces */
/* max 40 chars including nullterminator
(change struct at top of file if you want more...) */
if (nLen > MENULINEMAX-1)
nLen = MENULINEMAX-1;
fmemcpy(MenuStruct[nIndex].Text, pLine, nLen);
MenuStruct[nIndex].Text[nLen] = 0; /* nullTerminate */
}
nMenuLine++;
}
STATIC VOID CfgMenuEsc(BYTE * pLine)
{
@ -1749,40 +1894,63 @@ STATIC VOID CfgMenuEsc(BYTE * pLine)
for (check = pLine; check[0]; check++)
if (check[0] == '$') check[0] = 27; /* translate $ to ESC */
printf("%s\n",pLine);
}
}
STATIC VOID DoMenu(void)
{
{
iregs r;
int key = -1;
if (Menus == 0)
return;
InitKernelConfig.SkipConfigSeconds = -1;
return;
Menus |= 1 << 0; /* '0' Menu always allowed */
InitKernelConfig.SkipConfigSeconds = -1;
printf("\n\n");
if (MenuColor == -1)
Menus |= 1 << 0; /* '0' Menu always allowed */
nMenuLine+=2; /* use this to position "select menu" text (ypos): */
for (;;)
{
int key,i;
int i;
RestartInput:
if (MenuColor != -1)
{
SelectLine(MenuSelected); /* select current line. */
/* set new cursor position: */
r.a.b.h = 0x02;
r.b.b.h = 0;
r.d.b.l = 3;
r.d.b.h = nMenuLine;
init_call_intr(0x10, &r); /* set cursor pos */
}
printf("Select from Menu [");
RestartInput:
printf("\rSinglestepping (F8) is :%s - ", singleStep ? "ON " : "OFF");
printf("please select a Menu[");
for (i = 0; i <= 9; i++)
if (Menus & (1 << i))
printf("%c", '0' + i);
printf("]");
printf(" (default=%d)", MenuSelected);
printf("], or press [ENTER]");
if (MenuColor != -1)
printf(" (Selection=%d)", MenuSelected);
if (MenuTimeout >= 0)
printf(" - %d \b", MenuTimeout);
else
else
printf(" \b\b\b\b\b");
if (MenuColor != -1)
printf("\r\n\n ");
else
printf(" -");
printf(" Singlestepping (F8) is: %s \r", singleStep ? "ON " : "OFF");
key = GetBiosKey(MenuTimeout >= 0 ? 1 : -1);
if (key == -1) /* timeout, take default */
@ -1792,9 +1960,9 @@ RestartInput:
MenuTimeout--;
goto RestartInput;
}
break;
}
else
break;
}
else
MenuTimeout = -1;
if (key == 0x3f00) /* F5 */
@ -1806,27 +1974,36 @@ RestartInput:
{
singleStep = !singleStep;
}
key &= 0xff;
if (key == '\r') /* CR - use default */
else if(key == 0x4800 && MenuColor != -1) /* arrow up */
{
break;
}
if (key == 0x1b) /* ESC - use default */
{
break;
}
printf("%c", key);
if (key >= '0' && key <= '9')
if (Menus & (1 << (key - '0')))
if(MenuSelected>=0 && (Menus & (1 << (MenuSelected-1))) )
{
MenuSelected = key - '0'; break;
MenuSelected--;
}
}
else if(key == 0x5000 && MenuColor != -1) /* arrow down */
{
if(MenuSelected<10 && (Menus & (1 << (MenuSelected+1))) )
{
MenuSelected++;
}
}
key &= 0xff;
if (key == '\r' || key == 0x1b) /* CR/ESC - use default */
break;
if (key >= '0' && key <= '9' && (Menus & (1 << (key - '0'))))
{
MenuSelected = key - '0';
break;
}
}
printf("\n");
if (MenuColor != -1)
ClearScreen(0x7);
}
STATIC VOID CfgMenuDefault(BYTE * pLine)
@ -1853,6 +2030,60 @@ STATIC VOID CfgMenuDefault(BYTE * pLine)
}
}
STATIC void ClearScreen(unsigned char attr)
{
/* scroll down (newlines): */
iregs r;
unsigned char columns, rows;
/* clear */
r.a.x = 0x0600;
r.b.b.h = attr;
r.c.x = 0;
columns = peekb(0x40, 0x4a) - 1;
rows = peekb(0x40, 0x84);
if (rows == 0) rows = 24;
r.d.x = rows * 0x100 + columns;
init_call_intr(0x10, &r);
/* move cursor to pos 0,0: */
r.a.b.h = 0x02; /* set cursorpos */
r.b.b.h = 0; /* displaypage: */
r.d.x = 0; /* pos 0,0 */
init_call_intr(0x10, &r);
MenuColor = attr;
}
/**
MENUCOLOR[=] fg[, bg]
*/
STATIC void CfgMenuColor(BYTE * pLine)
{
int num = 0;
unsigned char fg, bg = 0;
pLine = skipwh(pLine);
if ('=' == *pLine)
pLine = skipwh(pLine + 1);
pLine = GetNumArg(pLine, &num);
if (pLine == 0)
return;
fg = (unsigned char)num;
pLine = skipwh(pLine);
if (*pLine == ',')
{
pLine = GetNumArg(skipwh(pLine+1), &num);
if (pLine == 0)
return;
bg = (unsigned char)num;
}
ClearScreen((bg << 4) | fg);
}
/*********************************************************************************
National specific things.
this handles only Date/Time/Currency, and NOT codepage things.