home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
FGDEMO40.ZIP
/
SOURCE.COM
/
MENU.C
< prev
next >
Wrap
Text File
|
1995-02-12
|
15KB
|
533 lines
/**********************************************************************\
* *
* menu.c -- menu management functions *
* *
\**********************************************************************/
#include "defs.h"
MENU main_menu[] =
{
{ submenu1, "File", 6, 91, 1, 4},
{ submenu2, "Video", 92, 190, 2, 0},
{ submenu3, "Fundamentals", 191, 345, 3, 1},
{ submenu4, "Display", 346, 457, 4, 2},
{ submenu5, "Miscellaneous", 458, 633, 0, 3}
};
MENU menu1[] =
{
{ about_fg, "About Fastgraph ", 7, 174, 1,10},
{ about_demo, "About This Demo ", 7, 174, 2, 0},
{ about_tech, "Technical Support ", 7, 174, 3, 1},
{ about_docs, "Documentation ", 7, 174, 4, 2},
{ about_site, "Site Licenses ", 7, 174, 5, 3},
{ about_source, "Source Code ", 7, 174, 6, 4},
{ about_fgl, "Fastgraph/Light ", 7, 174, 7, 5},
{ about_order, "Order by Phone/FAX", 7, 174, 8, 6},
{ print_form, "Print Order Form ", 7, 174, 9, 7},
{ shell, "Shell to DOS ", 7, 174,10, 8},
{ exit_program, "Exit ", 7, 174, 0, 9}
};
MENU menu2[] =
{
{ about_modes, "Video Modes ", 93, 230, 1, 6},
{ auto_detect, "Autodetect ", 93, 230, 2, 0},
{ physical_pages, "Physical Pages ", 93, 230, 3, 1},
{ virtual_pages, "Virtual Pages ", 93, 230, 4, 2},
{ logical_pages, "Logical Pages ", 93, 230, 5, 3},
{virtual_buffers, "Virtual Buffers", 93, 230, 6, 4},
{ coordinates, "Coordinates ", 93, 230, 0, 5}
};
MENU menu3[] =
{
{ do_points, "Points ", 192, 324, 1, 8},
{ do_lines, "Lines ", 192, 324, 2, 0},
{ do_rects, "Rectangles ", 192, 324, 3, 1},
{ do_boxes, "Boxes ", 192, 324, 4, 2},
{ do_circles, "Circles ", 192, 324, 5, 3},
{do_ellipses, "Ellipses ", 192, 324, 6, 4},
{do_polygons, "Polygons ", 192, 324, 7, 5},
{ do_text, "Text ", 192, 324, 8, 6},
{ do_paint, "Region Fill", 192, 324, 0, 7}
};
MENU menu4[] =
{
{ do_bitmaps, "Bitmaps ", 347, 464, 1, 4},
{ do_scaling, "Scaling ", 347, 464, 2, 0},
{ do_transfer, "Transfer ", 347, 464, 3, 1},
{ do_scroll, "Scroll ", 347, 464, 4, 2},
{ do_split, "Split Screen", 347, 464, 0, 3}
};
MENU menu5[] =
{
{ do_keyboard, "Keyboard ", 459, 588, 1, 6},
{ do_joystick, "Joystick ", 459, 588, 2, 0},
{ do_mouse, "Mouse ", 459, 588, 3, 1},
{ do_bird, "Bird ", 459, 588, 4, 2},
{ do_borland, "Borland ", 459, 588, 5, 3},
{ do_dub, "Dub Media", 459, 588, 6, 4},
{do_histogram, "Histogram", 459, 588, 0, 5}
};
/**********************************************************************\
* *
* highlight option -- highlight an option on the main menu *
* *
\**********************************************************************/
void highlight_option(int n)
{
int y;
y = menu_top + PTSIZE + 1;
/* set the color to black, draw a rectangle */
fg_setcolor(0);
fg_rect(main_menu[n].x1,main_menu[n].x2,menu_top,menu_bottom-1);
/* set the color to white, write the text */
fg_setcolor(15);
center_pstring(main_menu[n].menu_item,main_menu[n].x1,main_menu[n].x2,y);
}
/**********************************************************************\
* *
* horizontal_menu -- main menu function. All the vertical submenu *
* functions are called from this function, and this function contains *
* the main program loop. Parameters are passed to horizontal menu *
* as follows: *
* *
* MENU menutab[] -- this is the command table, an array of structures *
* defining the menu commands, the location and the *
* function to be called when this item is selected. *
* *
* int n -- number of items on the horizontal menu *
* *
* int current -- the current highlighted option *
* *
\**********************************************************************/
horizontal_menu(struct menu *menutab,int n,int current)
{
register int i, k;
int c;
int found, choice;
int ymin, ymax;
char l;
int foregrnd, backgrnd;
int hilite_fgnd, hilite_bkgnd;
/* colors for highlighted and unhighted text and background */
foregrnd = 0; backgrnd = 15; hilite_fgnd = 15; hilite_bkgnd = 0;
/* check if current item is out of range */
if (current >= abs(n))
return(ERR);
ymin = menu_top;
ymax = ymin + PTSIZE + 1;
fg_mousevis(OFF);
/* set up the list of options -- display the menu on the screen */
if (n < 0)
{
for (i = 0; i < abs(n); i++)
{
fg_setcolor(backgrnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(foregrnd);
center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
}
}
/* if we're just displaying the menu options, return */
if (current < 0) return (OK);
/* highlight current option */
i = (current);
fg_setcolor(hilite_bkgnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(hilite_fgnd);
center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
fg_mousevis(ON);
/* A negative number is a flag to display the options and return
without taking any action. */
if (n < 0) return(OK);
/* choose an option */
choice = current;
fg_setnum(OFF);
flushkey();
for(;;)
{
/* activate the corresponding vertical menu */
c = (*menutab[i].menu_func)();
/* cycle through choices */
if (c == LEFT_ARROW || c == BS)
choice = menutab[i].prev;
else if (c == RIGHT_ARROW || c == SPACEBAR)
choice = menutab[i].next;
else if (c >= 0 && c <= n)
choice = c;
else if (c == ESC)
{
exit_program();
}
else if (isalpha(c))
{
c = tolower(c);
found = FALSE;
for (k = i+1; k < n; k++)
{
l = first_nonblank(menutab[k].menu_item);
if (c == tolower((int)l))
{
found = TRUE;
break;
}
}
if (!found)
{
for (k = 0; k <= i; k++)
{
l = first_nonblank(menutab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
}
if (found)
choice = k;
}
if (i != choice)
{
/* unmark previous option */
fg_mousevis(OFF);
fg_setcolor(backgrnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(foregrnd);
center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
/* mark new option */
i = choice;
fg_setcolor(hilite_bkgnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(hilite_fgnd);
center_pstring(menutab[i].menu_item,menutab[i].x1,menutab[i].x2,ymax);
fg_mousevis(ON);
}
}
}
/**********************************************************************\
* *
* submenus -- functions called from the horizontal menu *
* *
\**********************************************************************/
int submenu1()
{
return(vertical_menu(menu1,0,11));
}
int submenu2()
{
return(vertical_menu(menu2,1,7));
}
int submenu3()
{
return(vertical_menu(menu3,2,9));
}
int submenu4()
{
return(vertical_menu(menu4,3,5));
}
int submenu5()
{
return(vertical_menu(menu5,4,7));
}
/**********************************************************************\
* *
* vertical_menu -- submenu from horizontal menu. This function *
* works almost the same as the horizontal menu function. *
* *
\**********************************************************************/
vertical_menu(struct menu *menutab,int index,int n)
{
register int i, j, k;
int found, choice;
int height;
int left, right;
int string_x;
int x1, x2, y1, y2;
int ymin, ymax;
int count;
char c, l;
unsigned char key, aux;
int foregrnd, backgrnd;
int hilite_fgnd, hilite_bkgnd;
foregrnd = 0; backgrnd = 15; hilite_fgnd = 15; hilite_bkgnd = 0;
/* height in pixels of an individual menu item */
height = PTSIZE + 2;
/* the first menu item determines the x coordinate for the other items */
string_x = get_center(menutab[0].menu_item,menutab[0].x1,menutab[0].x2);
/* define the menu extremes */
x1 = menutab[0].x1 - 1;
x2 = menutab[0].x2 + 3;
y1 = menu_bottom;
y2 = menu_bottom + n*height + 1;
/* define the associated horizontal mouse limits */
if (mouse)
{
left = mouse_limits[index];
right = mouse_limits[index+1] - 2;
}
/* display the vertical menu if necessary */
if (redraw)
{
/* do this stuff on the hidden page to make it look faster */
fg_setpage(hidden);
/* draw the menu outline and the shadow around it */
fg_mousevis(OFF);
fg_setcolor(backgrnd);
fg_box(x1,x2-2,y1,y2-1);
fg_setcolor(8);
fg_rect(x1+2,x2,y2,y2);
fg_rect(x2-1,x2,y1+2,y2);
fg_setcolor(foregrnd);
fg_box(x1,x2-2,y1,y2-1);
/* set up list of options */
ymax = menu_bottom - 1;
for (i = 0; i < n; i++)
{
ymin = ymax + 1;
ymax = ymin + height - 1;
fg_setcolor(backgrnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(foregrnd);
put_pstring(menutab[i].menu_item,string_x,ymax);
}
/* highlight first or previously selected option */
i = selection;
ymin = menu_bottom + i*height;
ymax = ymin + height - 1;
fg_setcolor(hilite_bkgnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(hilite_fgnd);
put_pstring(menutab[i].menu_item,string_x,ymax);
/* restore the menu to the visual page */
fg_setpage(visual);
fg_restore(x1,x2,y1,y2);
redraw = FALSE;
fg_setpage(hidden);
/* clear the hidden page under the menu */
fg_setcolor(15);
fg_rect(x1,x2,y1,y2);
fg_setcolor(11);
fg_drect(x1,x2,y1,y2,matrix2);
fg_setpage(visual);
fg_mousevis(ON);
}
/* choose an option */
i = selection;
choice = i;
fg_setnum(OFF);
flushkey();
for(;;)
{
/* read a keystroke */
fg_mousevis(ON);
fg_waitfor(1);
fg_intkey(&key,&aux);
/* if using a mouse, check its position */
if (mouse && key+aux == 0)
{
fg_mousebut(1,&count,&xmouse,&ymouse);
if (count > 0)
{
if (BETWEEN(xmouse,x1,x2) && BETWEEN(ymouse,y1,y2-2))
{
choice = (ymouse - y1) / height;
/* check if this is the second click of a double click */
if (i == choice)
key = CR;
}
else if (!BETWEEN(xmouse,left,right) && BETWEEN(ymouse,menu_top,y1-1))
{
fg_mousevis(OFF);
fg_restore(0,xlimit,menu_bottom,ylimit);
redraw = TRUE;
selection = 0;
for (j = 0; j <= ITEMS; j++)
{
if (BETWEEN(xmouse,mouse_limits[j],mouse_limits[j+1]))
return(j);
}
}
}
}
/* cycle through choices */
if (aux == UP_ARROW || key == BS)
choice = menutab[i].prev;
else if (aux == DOWN_ARROW || key == SPACEBAR)
choice = menutab[i].next;
else if (aux == HOME || aux == PAGE_UP)
choice = 0;
else if (aux == END || aux == PAGE_DOWN)
choice = n - 1;
else if (aux == LEFT_ARROW || aux == RIGHT_ARROW)
{
fg_mousevis(OFF);
fg_restore(0,xlimit,menu_bottom,ylimit);
redraw = TRUE;
selection = 0;
return((int)aux);
}
/* pick one choice */
else if (key == CR)
{
(*menutab[i].menu_func)();
wait_for_mouse_buttons();
selection = i;
return(index);
}
else if (key == ESC)
{
selection = 0;
return(ESC);
}
else if (isalpha((int)key))
{
c = (char)tolower((int)key);
found = FALSE;
for (k = i+1; k < n; k++)
{
l = first_nonblank(menutab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
if (!found)
{
for (k = 0; k <= i; k++)
{
l = first_nonblank(menutab[k].menu_item);
if (c == (char)tolower((int)l))
{
found = TRUE;
break;
}
}
}
if (found)
choice = k;
else
{
redraw = TRUE;
return(-1);
}
}
else if (key+aux > 0) /* any other key */
{
redraw = TRUE;
return(-1);
}
if (i != choice)
{
/* unmark previous option */
ymin = menu_bottom + i*height;
ymax = ymin + height - 1;
fg_mousevis(OFF);
fg_setcolor(backgrnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(foregrnd);
put_pstring(menutab[i].menu_item,string_x,ymax);
/* mark option */
i = choice;
ymin = menu_bottom + i*height;
ymax = ymin + height - 1;
fg_setcolor(hilite_bkgnd);
fg_rect(menutab[i].x1,menutab[i].x2,ymin,ymax);
fg_setcolor(hilite_fgnd);
put_pstring(menutab[i].menu_item,string_x,ymax);
}
}
}