Category : Files from Magazines
Archive   : VOL7N10.ZIP
Filename : MENU.C

 
Output of file : MENU.C contained in archive : VOL7N10.ZIP
/* menu.c */

#include
#include
#include
#include"PcMag.h"

/* screen colors:
* NORMAL_VID value for ordinary characters,
* HIGHLITE for reverse
*/

#define NORMAL_VID 0x1700 /* white text, blue field */
#define HIGHLITE_VID 0x7000 /* black text, white field */

/* Ascii key definitions */

#define ENTER 13
#define SPACE 32
#define ESC 27

/* Scan key redefinitions */

#define RIGHT_ARROW 77+'z'
#define LEFT_ARROW 75+'z'

/* limitations: */

#define MAXMENUITEMS 25 /* number of menu items */
#define NAME_ROW 2 /* row number of item name */
#define NAME_COL 1 /* column number for name */
#define DESCRIPTION_ROW 3 /* description row number */
#define DESCRIPTION_COL 2 /* description column */

/* macros to make the code more readable, don't touch these */

#define SCREEN_SIZE 2000 /* screen size @ 2000 words */
#define ring_bell() putch(7) /* bell-ringing macro */
#define VIDEO_INT 0x10 /* Bios video interrupt */
#define SET_CURSOR_SIZE 0x01 /* Int 10 function 1 */
#define GET_CURSOR_POS 0x02 /* Int 10 function 2 */
#define READ_CURSOR 0x03 /* Int 10 function 3 */
#define GET_VID_MODE 0x0f /* Int 10 function F */
#define MONO_MODE 7 /* monochrome video mode # */
#define MONO_SCREEN 0xb0000000 /* address of mono screen */
#define COLOR_SCREEN 0xb8000000 /* address of color screen */
#define CURSOR_SAVE 0 /* macro for cursor save */
#define CURSOR_RESTORE 1 /* macro for cursor store */

/* global objects: */

int far *screen; /* pointer to screen buffer */
int old_screen[SCREEN_SIZE]; /* store old screen here */

/* list of function declarations for cue_function */

int addf(), subf(), mulf(), divf(), exitf();

/* array of structures with names, descriptions and function pointers */

struct _cue
{
char *cue_name; /* name to be displayed */
char *cue_description; /* description */
int (*cue_function)(); /* function to be called */
}
cue[MAXMENUITEMS] =
{
/* --1234567890--------1234567890123456789012-----for alignment */

" Add ", "Explain addition ", addf,
" Subtract ", "Discuss subtraction ", subf,
" Multiply ", "Portray multiplication", mulf,
" Divide ", "Characterize division ", divf,
" Exit ", "Exit to system ", exitf,

/* you can add more items here in the same fashion -
* up to MAXMENUITEMS total
*/
NULL,NULL,NULL
};


/* functions */

/* cls()
* clears the screen by writing blanks to screen buffer
*/
cls()
{
int pos=0;

while(pos < SCREEN_SIZE) /* for each word in screen */
*(screen + pos++) = NORMAL_VID; /* set it to NORMAL_VID */
}

/* print()
* prints a null-terminated string at row,col with attributes
* returns next available column
*/
print(str, row, col, att)
char *str;
int row, col, att;
{
while(*str)
*(screen+row*80+col++) = att + *str++;
return (col);
}

/* four test functions */
addf()
{
cls();
print("In Add, press a key for menu",2,1,HIGHLITE_VID);
getch();
}

subf()
{
cls();
print("In Subtract, press a key for menu",2,1,HIGHLITE_VID);
getch();
}

mulf()
{
cls();
print("In Multiply, press a key for menu",2,1,HIGHLITE_VID);
getch();
}

divf()
{
cls();
print("In Divide, press a key for menu",2,1,HIGHLITE_VID);
getch();
}

exitf()
{
int i;

for( i = 0; i < SCREEN_SIZE; i++) /* restore original screen */
*(screen+i) = old_screen[i];

cursor(CURSOR_RESTORE); /* reset cursor size/posit.*/
}


/* Run()
* runs the appropriate test function at cue[itemnumber].cue_function.
* This could be modified to use spawn() to run other programs.
*/
Run(itemnumber)
int itemnumber;
{
return (cue[itemnumber].cue_function)();
}

/* cursor() * cursor operations: saves the current cursor size and position in
* the statics, or restores the cursor size and position previously
* saved.
*/
cursor(op)
{
union REGS r;
static int oldcurrow,oldcurcol,oldcurstart,oldcurend;

if(op) /* restore cursor */
{
r.h.ah = SET_CURSOR_POS; /* cursor position function */
r.h.dh = oldcurrow; /* set the row */
r.h.dl = oldcurcol; /* set the column */
r.h.bh = 0; /* for video page 0 */
int86(VIDEO_INT,&r,&r); /* call the bios */

r.h.ah = SET_CURSOR_SIZE; /* cursor size function */
r.h.ch = oldcurstart; /* set the start */
r.h.cl = oldcurend; /* set the end */
r.h.bh = 0; /* for video page 0 */
int86(VIDEO_INT,&r,&r); /* call the bios */
}
else /* save the cursor */
{
r.h.ah = READ_CURSOR; /* cursor read function */
r.h.bh = 0; /* page 0 */
int86(VIDEO_INT,&r,&r); /* call the bios */
oldcurrow = r.h.dh; /* save the cursor row */
oldcurcol = r.h.dl = 0; /* save the cursor column */
oldcurstart = r.h.ch; /* save the cursor start */
oldcurend = r.h.cl; /* save the cursor end */
r.h.ah = SET_CURSOR_SIZE; /* cursor size function */
r.h.ch = 0x20; /* set bit 5 to hide cursor */
int86(VIDEO_INT,&r,&r); /* call the bios */
}
}

/* initialize()
* initializes the initials array, sets number of choices found, and
* saves the screen buffer in the old_screen array
*/
initialize(choices,initials)
int *choices;
char *initials;
{
int i;
get_screen_mode(); /* set screen pointer */

/* initialize the initials */
for( i = 0; cue[i].cue_name && i < MAXMENUITEMS; i++)
initials[i] = tolower(cue[i].cue_name[1]);
initials[i] = NULL;
*choices = i;
/* save old screen */
for( i = 0; i < SCREEN_SIZE; i++)
old_screen[i] = *(screen+i);
}

/* get_screen_mode()
* returns the current screen mode in AL, and sets the screen pointer
* to the appropriate video buffer address.
*/
get_screen_mode()
{
union REGS r;

r.h.ah = GET_VID_MODE; /* get video mode function */
int86(VIDEO_INT,&r,&r); /* call the bios */
/* set screen pointer */
screen = (int far *)((r.h.al == MONO_MODE) ? MONO_SCREEN : COLOR_SCREEN);
}

/* menu()
* main menu creation function, callable from anywhere in a program.
* Performs the following tasks:
* 1. saves the current screen and cursor
* 2. clears the screen
* 3. loops until the exit function is called through the following:
* 1. prints the menu items (highlights current selection)

* 2. prints the description of the highlighted selection
* 3. gets a key from the user (adjusts for non-ascii keys)
* 4. takes the appropriate actions for , ,
* , , , or the first
* letter of the menu item.
* Assumes last item is exit item and returns when that is executed.
*/
menu()
{
static int mark = 0;
int col, i, key, choices;
char *match, initials[MAXMENUITEMS];

initialize(&choices,initials); /* initialize & save screen */

cursor(CURSOR_SAVE); /* save the cursor */
cls(); /* clear the screen */

while(TRUE) /* main loop */
{
col = NAME_COL;

/* print the names and highlight the current selection */

for( i = 0; i < choices; i++)
col = print(cue[i].cue_name, NAME_ROW, col,
(mark == i) ? HIGHLITE_VID : NORMAL_VID);
/* print description */

print(cue[mark].cue_description, DESCRIPTION_ROW, DESCRIPTION_COL, NORMAL_VID);

if(!(key = tolower(getch()))) /* get key, and lowercase */
key = (getch() + 'z'); /* Not Ascii? get scan code */

switch(key) /* which key was pressed? */
{
case ENTER: /* if ENTER */
Run(mark); /* run function at mark */
break;

case RIGHT_ARROW: /* if RIGHT_ARROW/SPACE bar */
case SPACE:
mark = ((mark+1) % choices); /* move to next choice */
break;

case LEFT_ARROW: /* if LEFT_ARROW */
/* move to previous choice */
mark = ((mark+choices-1) % choices);
break;

case ESC: /* if ESC */
return Run(choices-1); /* select last choice (exit)*/
break;

default: /* if initials match */
if(match = strchr(initials,key))
{
mark = (match-initials);
Run(match-initials);
}
else
ring_bell(); /* bad choice, ring the bell*/
break;
}
}
}

main() /* main program */
{
menu(); /* called as needed */
}

/* End of Menu.c */

  3 Responses to “Category : Files from Magazines
Archive   : VOL7N10.ZIP
Filename : MENU.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/