home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
GUILIB.ZIP
/
MENU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-27
|
63KB
|
1,982 lines
/*---------------------------------------------------------------------------*
* PLAIN DESIGN CORPORATION COPYRIGHT (c) 1992 *
*----------------------------------------------------------------------------*
* PULL DOWN MENU SYSTEM for character based user interfaces *
*---------------------------------------------------------------------------*/
#include "stdio.h"
#include "string.h"
#include "conio.h"
#include "stdlib.h"
#include "bios.h"
#include "ctype.h"
#include "conio.h"
#include "dos.h"
#include "menu.h"
/*-------------------------------*/
/* FOR MICROSOFT C COMPILER */
/*-------------------------------*/
#ifdef MSC
#define getvect(i) _dos_getvect(i)
#define bioskey(i) _bios_keybrd(i)
#endif
/*-------------------------------*/
int menu_descriptor=TEXT_FILE;
FILE *fp; /* file pointer for the menu file */
char menu_file[40]="MENUFILE"; /* menu descriptor file name */
int menu_color=0x70; /* menu color */
int menu_hotkey_color=0x74; /* color of the hotkey */
int menu_sel_color=0x47; /* selected menu item color */
int menu_shadow=0x08; /* shadow for expanded boxes */
int menu_x=0; /* menu bar x locations */
int menu_y=0; /* menu bar y locations */
int menu_x_size=80; /* size of the x axis of the bar */
char menu_title[MAX_TITLE][20]; /* menu title array */
char title_hotkey[MAX_TITLE]; /* title hotkey array */
char title_hotkey_loc[MAX_TITLE]; /* title hotkey location */
long title_loc [MAX_TITLE]; /* each title location in menufile */
int title_ident[MAX_TITLE]; /* title identifier number array */
int title_acc[MAX_TITLE]; /* title accelerator array */
int title_x[MAX_TITLE]; /* title x location array */
int title_num; /* number of titles in menufile */
int title_ptr; /* title pointer variable */
int menu_acc_num; /* number of menu accelerators */
int menu_acc[MAX_ACC]; /* store the accelerator key code */
int menu_ident[MAX_ACC]; /* return value for accelerated key code */
int cur_ident; /* used to pass the current ident */
int key_return; /* key board status variable */
/*--------------------------------------------------------------------------*/
union REGS iReg,oReg;
int mousefound=NO; /* mouse existance variable */
int mousex; /* mouse cursor x location */
int mousey; /* mouse cursor y location */
/*--------------------------------------------------------------------------*/
int txt_curs_x; /* text cursor x location */
int txt_curs_y; /* text cursor y location */
int curs_start_line=8;
int curs_end_line=8;
int ms; /* mouse key status */
int mouse_display; /* mouse cursor ON/OFF indicator */
char **menu;
int menu_lines;
int menu_line_ptr;
/*--------------------------------------------------------------------------*/
/*-------------------------------------*/
/* window declerations */
/*-------------------------------------*/
int box_num;
unsigned char *save_box [MAX_WINDOWS];
unsigned char *gsave_box[MAX_WINDOWS];
int xwin [MAX_WINDOWS];
int ywin [MAX_WINDOWS];
int xwinsize [MAX_WINDOWS];
int ywinsize [MAX_WINDOWS];
int wincolor [MAX_WINDOWS];
int winshadow [MAX_WINDOWS];
int winborder [MAX_WINDOWS];
/*-------------------------------------*/
int initvar=1; /* will indicate if initdisplay has been called */
unsigned char back_block; /* block used by frect to fill a rectangle */
/*--------------------------------------------------------------------------*/
/* int bar_menu(action); *
* *
* action : INIT initialize the menu function by opening the menu *
* file and display menu titles on the screen. *
* KEY_RETURN returns keyboard input as it would be returned *
* by getkey function; return EOF if no key pressed *
* . If ALT key is pressed and released (ALONE), it *
* will turn the menu on; when appropriate menu is *
* selected, it will return the menu identifier #. *
* . If mouse left key is pressed on a menu title, *
* bar_menu will turn the menu on and return the *
* menu_identifier when an entry is selected. *
* . If an accelerator is detected, bar_menu will *
* return the identifier associated with the *
* accelerator without turning the menu on. *
/*--------------------------------------------------------------------------*/
int bar_menu(action)
int action;
{
int ch=0;
int mouse_menu=NO;
int acc_expand=OFF;
int i;
/*----------------------------------------------------*/
/* initilize the menu bar variables and read the menu */
/* file and display the unactivated menu */
/*----------------------------------------------------*/
if(action==INIT)
{ init_menu();
return(EOF);
}
/*--------------------------------------------------------------------*/
if(action==DISPLAY)
{ display_menu();
return(EOF);
}
/*--------------------------------------------------------------------*/
/* ACTIONS FOR KEY_RETURN parameter */
/*--------------------------------------------------------------------*/
/*-------------------------------------------*/
/* check if mouse is clicked on the menu bar */
/*-------------------------------------------*/
if(mouse_left_pressed()==YES)
{ get_mouse_location();
if(mousey==menu_y)
{ for(i=0;i<title_num;i++)
{ if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1)
{ mouse_menu=YES;
title_ptr=i;
break;
}
}
}
}
/*-------------------------------------------*/
/* check if the alt key is pressed */
/*-------------------------------------------*/
if(mouse_menu==NO)
{ if(alt_pressed()==NO)
{ ch=getkey();
if(ch!=EOF) /* check if an accelerator key has been pressed */
{ for (i=0;i<menu_acc_num;i++)
{ if(menu_acc[i]==ch)
{ return(menu_ident[i]);
}
}
for (i=0;i<title_num;i++)
{ if(title_acc[i]==ch)
{ title_ptr=i;
acc_expand=ON;
break;
}
}
}
if(acc_expand==OFF)
{ return(ch);
}
}
/*----------------------*/
/* alt key is pressed */
/*----------------------*/
else
{ while(alt_pressed()==YES)
{ ch=getkey();
if(ch!=EOF)
{ key_return=ON;
for (i=0;i<menu_acc_num;i++)
{ if(menu_acc[i]==ch)
{ return(menu_ident[i]);
}
}
for (i=0;i<title_num;i++)
{ if(title_acc[i]==ch)
{ title_ptr=i;
acc_expand=ON;
break;
}
}
if(acc_expand==OFF)
{ return(ch);
}
}
if(acc_expand==ON)
{ break;
}
}
if(key_return==ON && acc_expand==OFF)
{ key_return=OFF;
return(EOF);
}
if(acc_expand==OFF)
{ title_ptr=0;
}
else
{ title_ptr=i;
}
}
}
/*--------------------------*/
/* turn on the menu now */
/*--------------------------*/
if(menu_descriptor==TEXT_FILE)
{ fp=fopen(menu_file,"r");
if(fp==NULL)
{ cls();
printf("\n cannot open file %s ",menu_file);
exit(-1);
}
}
while(1)
{ ch=expand(acc_expand);
if(acc_expand==ON)
{ acc_expand=OFF;
}
switch(ch)
{ case RIGHTKEY :
title_ptr++;
if(title_ptr==title_num)title_ptr=0;
continue;
case LEFTKEY :
title_ptr--;
if(title_ptr<0)title_ptr=title_num-1;
continue;
case ESC :
if(menu_descriptor==TEXT_FILE)
{ fclose(fp);
}
return(EOF);
case ENTER :
if(menu_descriptor==TEXT_FILE)
{ fclose(fp);
}
return(cur_ident);
}
}
}
/*--------------------------------------------------------------------------*/
/* initialize the menu system */
/*--------------------------------------------------------------------------*/
void init_menu(void)
{
char buffer[100];
char dumy[40];
int i;
if(menu_descriptor==TEXT_FILE)
{ fp=fopen(menu_file,"rb");
if(fp==NULL)
{ cls();
printf("\n cannot open %s file \n press a key to exit to dos ",menu_file);
getch();
exit(-1);
}
}
frect(menu_x,menu_y,menu_x+menu_x_size-1,menu_y,menu_color,0);
title_num=0;
menu_acc_num=0;
while(next_line(buffer,sizeof(buffer))!=-1)
{
if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
{ continue;
}
if(buffer[1]!='%')
{ if(menu_acc_num==MAX_ACC-1)
{ continue;
}
if(strnicmp(buffer,"LINE",4)==0 ||
strnicmp(buffer,"SUBMENU",7)==0 ||
strnicmp(buffer,"END",3)==0 )
{ continue;
}
menu_acc[menu_acc_num]=0;
seperate(buffer,dumy,&menu_ident[menu_acc_num],
&menu_acc[menu_acc_num] ,ON );
if( menu_acc[menu_acc_num]!=0)menu_acc_num++;
continue;
}
title_hotkey[title_num]=seperate(buffer,menu_title[title_num],
&title_ident[title_num],&title_acc[title_num],ON );
if(title_hotkey[title_num]!=0)
{ for(i=0;i<strlen(menu_title[title_num]);i++)
{ if(menu_title[title_num][i]==title_hotkey[title_num])
{ title_hotkey_loc[title_num]=i;
break;
}
}
}
title_loc[title_num]=get_pos();
title_x[title_num]=title_ptr;
pls(title_x[title_num],menu_y,menu_title[title_num]+1,menu_color);
place_title_hot(title_num);
title_ptr+=strlen(menu_title[title_num])+1;
title_num++;
if(title_num==MAX_TITLE)
{ cls();
printf("\n too many menu titles ");
getch();
exit(-1);
}
}
if(menu_descriptor==TEXT_FILE)
{ fclose(fp);
}
}
/*--------------------------------------------------------------------------*/
/* Display the menu bar */
/*--------------------------------------------------------------------------*/
void display_menu(void)
{
int i;
frect(menu_x,menu_y,menu_x+menu_x_size-1,menu_y,menu_color,0);
for(i=0;i<title_num;i++)
{ pls(title_x[i],menu_y,menu_title[i]+1,menu_color);
place_title_hot(i);
}
}
/*--------------------------------------------------------------------------*/
/* seperate entry from identifier and accelerator, ad return the hotkey */
/*--------------------------------------------------------------------------*/
unsigned char seperate(buffer,entry,ident,acc,hotkey_sep)
char *buffer;
char *entry;
int *ident;
int *acc;
int hotkey_sep;
{
int i;
int j=0;
int s=0;
unsigned char hotkey=0;
for(i=0;i<strlen(buffer);i++)
{ if(buffer[i]=='"')
{ s++;
continue;
}
if(s==1)
{ if(buffer[i]=='^' )
{ if(hotkey_sep==ON)
{ i++;
hotkey=buffer[i];
}
else
{ hotkey=buffer[i+1];
}
}
entry[j]=buffer[i];
j++;
}
if(s==2)
{ entry[j]=0;
break;
}
}
if (s!=2)
{ cls();
printf("\n the following line in the menu descriptor file is illegal");
printf("\n var s=%d and ^%s^",s,buffer);
getch();
exit(-1);
}
sscanf(buffer+i+1,"%d %d",ident,acc);
return(hotkey);
}
/*--------------------------------------------------------------------------*/
/* expand title # acc_expand */
/*--------------------------------------------------------------------------*/
int expand(acc_expand)
int acc_expand;
{
unsigned char entry[MAX_ENTRIES][50];
unsigned char hotkey[MAX_ENTRIES];
int hotkey_loc[MAX_ENTRIES];
unsigned char sep[42];
int ident[MAX_ENTRIES];
int acc [MAX_ENTRIES];
long submenu_loc[MAX_ENTRIES];
int entry_num=0;
int entry_ptr=0;
char buffer[100];
int box_x;
int box_y;
int box_width=0;
int ch;
int i;
int mouse_left;
int break_loop=OFF;
int highlight;
/*---------------------------------*/
/* change color of the title first */
/*---------------------------------*/
pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_sel_color);
set_pos(&title_loc[title_ptr]);
while(next_line(buffer,sizeof(buffer))!=-1)
{
if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
{ continue;
}
if(buffer[1]=='%')break;
submenu_loc[entry_num]=0L;
if(strnicmp(buffer,"LINE",4)==0)
{ strcpy(entry[entry_num],"LINE");
entry_num++;
if(entry_num==MAX_ENTRIES)
{ cls();
printf("\n too many entries for the title=%s",menu_title[title_ptr]);
getch();
exit(-1);
}
continue;
}
else if(strnicmp(buffer,"SUBMENU",7)==0)
{ submenu_loc[entry_num-1]=get_pos();
i=1;
while(next_line(buffer,sizeof(buffer))!=-1)
{
if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
{ continue;
}
if(strnicmp(buffer,"SUBMENU",7)==0)
{ i++;
}
if(strnicmp(buffer,"END",3)==0)
{ i--;
}
if(i==0)break;
}
if(i!=0)
{ cls();
printf("\n ERROR SUBMENU without an END ");
getch();
exit(-1);
}
continue;
}
hotkey[entry_num]=seperate(buffer,entry[entry_num],&ident[entry_num],
&acc[entry_num],ON ) ;
for(i=0;i<strlen(entry[entry_num]);i++)
{ if(entry[entry_num][i]==hotkey[entry_num])
{ hotkey_loc[entry_num]=i;
break;
}
else
{ hotkey_loc[entry_num]=0;
}
}
if(hotkey[entry_num]>='a' && hotkey[entry_num]<='z')
{ hotkey[entry_num]-=32;
}
if(strlen(entry[entry_num])>box_width)
{ box_width=strlen(entry[entry_num]);
}
entry_num++;
}
/*-----------------------------------*/
/* show a box to expand the title on */
/*-----------------------------------*/
if(entry_num>0)
{ box_x=title_x[title_ptr];
box_y=menu_y+1;
}
else
{ if(acc_expand==ON)
{ pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_sel_color);
cur_ident=title_ident[title_ptr];
return(ENTER);
}
box_x=-1;
box_y=-1;
}
strcpy(sep,"├");
for(i=0;i<box_width;i++)
{ strcat(sep,"─");
}
strcat(sep,"┤");
if(entry_num>0)
{
/*-------------------------------------*/
/* adjust box_x */
/*-------------------------------------*/
if(box_x+box_width+3>79)
{ box_x=79-box_width-3;
if(box_x+box_width+3>79)
{ box_x=76-box_width;
}
}
messagebox(box_x,box_y,box_width+2,entry_num+2,menu_color,menu_shadow,1,YES);
for(i=0;i<entry_num;i++)
{ if(stricmp(entry[i],"LINE")==0)
{ pls(box_x,box_y+1+i,sep,menu_color);
}
else
{ pls(box_x+1,box_y+1+i,entry[i],menu_color);
if(hotkey[i]!=0)
{ writechar(box_x+1+hotkey_loc[i],box_y+1+i,entry[i][hotkey_loc[i]],
menu_hotkey_color);
}
if(submenu_loc[i]!=0L)
{ writechar(box_x+box_width,box_y+1+i,16,menu_color);
}
}
}
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
highlight=ON;
}
while(1)
{ ch=getkey();
if(ch!=EOF)
{ for(i=0;i<title_num;i++)
{ if(title_acc[i]==ch && title_ptr!=i)
{ pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
place_title_hot(title_ptr);
title_ptr=i;
break_loop=ON;
break;
}
}
for (i=0;i<menu_acc_num;i++)
{ if(menu_acc[i]==ch)
{ cur_ident=menu_ident[i];
ch=ENTER;
break_loop=ON;
break;
}
}
}
/*-------------------------------------*/
/* check if a hot key has been pressed */
/*-------------------------------------*/
if(ch>='a' && ch<='z')
{ ch-=32;
}
for(i=0;i<entry_num;i++)
{ if(ch==hotkey[i])
{ cur_ident=ident[i];
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
entry_ptr=i;
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
ch=ENTER;
break;
}
}
mouse_left=mouse_state();
if(mouse_left==PRESSED)
{ get_mouse_location();
if(mousex>=box_x+1 && mousex<=box_x+box_width &&
mousey>box_y && mousey<=box_y+entry_num )
{ if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0 && highlight==ON)
{ chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
highlight=OFF;
continue;
}
if(entry_ptr != mousey-box_y-1 || highlight==OFF)
{ if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
{ highlight=OFF;
continue;
}
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
entry_ptr=mousey-box_y-1;
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
highlight=ON;
continue;
}
}
else if(mousey==menu_y) /* check for title change */
{ for(i=0;i<title_num;i++)
{ if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1
&& title_ptr != i )
{ pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
place_title_hot(title_ptr);
title_ptr=i;
break_loop=ON;
break;
}
}
}
else if(highlight==ON)
{ chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
highlight=OFF;
}
}
else if(mouse_left==PRESSEDRELEASED)
{ if(mousex>=box_x+1 && mousex<=box_x+box_width &&
mousey>box_y && mousey<=box_y+entry_num)
{ if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
{ ch=ESC;
break;
}
else
{ cur_ident=ident[entry_ptr];
ch=ENTER;
}
}
else if(entry_num==0 && mousey==menu_y && mousex>=title_x[title_ptr]
&& mousex<=title_x[title_ptr]+strlen(menu_title[title_ptr])-1 )
{ ch=ENTER;
cur_ident=title_ident[title_ptr];
}
else if(entry_num>0 && mousey==menu_y && mousex>=title_x[title_ptr]
&& mousex<=title_x[title_ptr]+strlen(menu_title[title_ptr])-1 )
{ ms=RELEASED;
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
continue;
}
else
{ ch=ESC;
}
ms=RELEASED;
}
if(ch==ENTER && entry_num>0 && submenu_loc[entry_ptr]!=0 )
{ ch=submenu(submenu_loc[entry_ptr],box_x+box_width/2+1,box_y+entry_ptr+2);
if(ch==-2)
{ get_mouse_location();
if(mousex>=box_x && mousex<=box_x+box_width+2 &&
mousey>=box_y+1 && mousey<=box_y+entry_num )
{ if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
{ ch=ESC;
break;
}
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
entry_ptr=mousey-box_y-1;
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
continue;
}
else if(mousey==menu_y) /* check for title change */
{ for(i=0;i<title_num;i++)
{ if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1
&& title_ptr != i )
{ pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
place_title_hot(title_ptr);
title_ptr=i;
break_loop=ON;
break;
}
}
if(break_loop==OFF)
{ ch=ESC;
}
}
else
{ ch=ESC;
}
}
if(ch!=-1)
{ break;
}
}
if(ch==RIGHTKEY || ch==LEFTKEY || ch==ESC || ch==ENTER)
{ if(entry_num>0)
{ cur_ident=ident[entry_ptr];
}
else
{ cur_ident=title_ident[title_ptr];
}
break;
}
switch(ch)
{ case DOWNKEY :
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
entry_ptr++;
if(entry_ptr==entry_num)entry_ptr=0;
if(stricmp(entry[entry_ptr],"LINE")==0)
{ entry_ptr++;
if(entry_ptr==entry_num)entry_ptr=0;
}
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
break;
case UPKEY :
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
if(hotkey[entry_ptr]!=0)
{ writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
}
entry_ptr--;
if(entry_ptr<0)entry_ptr=entry_num-1;
if(stricmp(entry[entry_ptr],"LINE")==0)
{ entry_ptr--;
if(entry_ptr<0)entry_ptr=entry_num-1;
}
chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
break;
}
if(break_loop==ON)break;
}
/*-----------------------------------------*/
/* change the color of the menu title back */
/* remove the background box for entries */
/*-----------------------------------------*/
pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
place_title_hot(title_ptr);
if(entry_num>0)
{ messagebox(box_x,box_y,box_width+2,entry_num+2,menu_color,menu_shadow,0,YES);
}
return(ch);
}
/*--------------------------------------------------------------------------*/
/* Place the hotkey letter on the title using the hotkey color */
/*--------------------------------------------------------------------------*/
void place_title_hot(tn)
int tn;
{
if(title_hotkey[tn]!=0)
{ writechar(title_x[tn]+title_hotkey_loc[tn]-1,
menu_y,title_hotkey[tn],menu_hotkey_color);
}
}
/*--------------------------------------------------------------------------*/
/* display submenu associated with an entry */
/*--------------------------------------------------------------------------*/
int submenu(location,xstart,ystart)
long location;
int xstart;
int ystart;
{
char menu[20][40];
int m_ident[20];
long submenu_loc[20];
int menu_num=0;
char buffer[100];
int box_width=0;
int ch=0;
int i;
int sl;
int def=0;
memset(menu,0,(size_t)600);
set_pos(&location);
while(next_line(buffer,sizeof(buffer))!=-1)
{
if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
{ continue;
}
if(strnicmp(buffer,"END",3)==0)
{ break;
}
submenu_loc[menu_num]=0L;
if(strnicmp(buffer,"SUBMENU",7)==0)
{ submenu_loc[menu_num-1]=get_pos();
i=1;
while(next_line(buffer,sizeof(buffer))!=-1)
{
if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
{ continue;
}
if(strnicmp(buffer,"SUBMENU",7)==0)
{ i++;
}
if(strnicmp(buffer,"END",3)==0)
{ i--;
}
if(i==0)break;
}
if(i!=0)
{ cls();
printf("\n ERROR SUBMENU without an END ");
getch();
exit(-1);
}
continue;
}
if(strnicmp(buffer,"LINE",4)==0)
{ strcpy(menu[menu_num],"LINE");
menu_num++;
continue;
}
ch=seperate(buffer,menu[menu_num],&m_ident[menu_num],&i,OFF );
if(strlen(menu[menu_num])>box_width && ch==0)
{ box_width=strlen(menu[menu_num]);
}
else if(strlen(menu[menu_num])-1>box_width && ch!=0)
{ box_width=strlen(menu[menu_num])-1;
}
menu_num++;
}
for(i=0;i<menu_num;i++)
{ while(strlen(menu[i])<box_width)
{ strcat(menu[i]," ");
}
if(submenu_loc[i]!=0)
{ if(strchr(menu[i],'^')==NULL)
{ menu[i][box_width-1]=16;
}
else
{ menu[i][box_width]=16;
}
}
}
/*--------------------------------------------------*/
/* adjust xstart and ystart to stay on the screen */
/*--------------------------------------------------*/
if (xstart+box_width+3>txt_scr_xsize-1)
{ xstart-=box_width+3;
}
if (ystart+menu_num+1>txt_scr_ysize-1)
{ ystart=txt_scr_ysize-3-menu_num;
}
/*--------------------------------------------------*/
messagebox(xstart,ystart,box_width+2,menu_num+2,menu_color,
menu_shadow,1,YES);
while(1)
{
ch=menus(menu,menu_num,xstart+1,ystart+1,menu_color,menu_sel_color,def);
if(ch>=0 && ch<menu_num)
{ def=ch;
}
if(submenu_loc[ch]!=0L && ch!=-1 && ch!=-2)
{ ch=submenu(submenu_loc[ch],xstart+box_width/2+1,ystart+ch+2);
if(ch==ENTER)
{ ch=ESC;
break;
}
if(ch==-1 )continue;
if(ch==-2)
{ sl=0;
for(i=0;i<menu_num;i++)
{ if(strlen(menu[i])>sl)
{ sl=strlen(menu[i]);
}
}
get_mouse_location();
if(mousex>=xstart+1 && mousex<=xstart+sl+1 &&
mousey>=ystart+1 && mousey<=ystart+menu_num)
{ def=mousey-ystart-1;
continue;
}
}
}
break;
}
messagebox(xstart,ystart,box_width+2,menu_num+2,menu_color,
menu_shadow,0,YES);
if(ch==-1 || ch==-2)
{ return(ch);
}
if(ch!=ESC)
{ cur_ident=m_ident[ch];
}
return(ENTER);
}
/*--------------------------------------------------------------------------*/
/* return number of spaces in the begining of a line */
/*--------------------------------------------------------------------------*/
int remove_spaces(buffer)
char *buffer;
{ int i=0;
while (buffer[i]==' ')
{ i++;
}
return(i);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* menus function will create a vertical scrolling menu, when a menu is */
/* selected, it will return the menu number which was highlighted */
/* parameters : menu -> two dimentional array of the menu text */
/* menu[menu_number][field_length] */
/* menu_num -> number of menus to be displayed */
/* x -> left coordinate of the left side of the menu */
/* y -> top coordinate of the menu */
/* menu_col -> menu display color */
/* sel_col -> highlighted menu color */
/* def_menu -> highlighted menu at default, if 0 first entry */
/* is highlighted. */
/*--------------------------------------------------------------------------*/
int menus(menu,menu_num,x,y,menu_col,sel_col,def_menu)
char menu[20][40] ; /* menu array */
int menu_num; /* number of menus */
int x; /* x coordinate of the menu */
int y; /* y coordinate of top left */
int menu_col; /* color of the menu display */
int sel_col; /* selected menu color */
int def_menu; /* default menu number */
/* if -1 just display items */
{
int i;
int ch;
int mp; /* menu pointer */
int sl=0;
unsigned char sep[60];
int highlight;
char *c;
unsigned char menu_hotkey[20];
int hotkey_loc[20];
char buffer[50];
mp=def_menu;
ms=RELEASED;
for(i=0;i<menu_num;i++)
{ c=strchr(menu[i],'^');
if(c!=NULL)
{ menu_hotkey[i]=c[1];
if(menu_hotkey[i]>='a' && menu_hotkey[i]<='z')
{ menu_hotkey[i]-=32;
}
hotkey_loc[i]=c-menu[i];
}
else
{ menu_hotkey[i]=0;
hotkey_loc[i]=-1;
}
if( (strlen(menu[i])>sl && menu_hotkey[i]==0) ||
(strlen(menu[i])-1 >sl && menu_hotkey[i]!=0 ) )
{ if(menu_hotkey[i]==0)
{ sl=strlen(menu[i]);
}
else
{ sl=strlen(menu[i])-1;
}
}
}
strcpy(sep,(unsigned char *)"├");
for(i=0;i<sl;i++)
{ strcat(sep,(unsigned char *)"─");
}
strcat(sep,(unsigned char *)"┤");
for(i=0;i<menu_num;i++) /* draw the menu with highlight */
{ if(strlen(menu[i])<sl)
{ while(strlen(menu[i])<sl)
{ strcat(menu[i]," ");
}
}
if(strnicmp(menu[i],"LINE",4)==0)
{ pls(x-1,y+i,(unsigned char *)sep,menu_color);
continue;
}
strcpy(buffer,menu[i]);
if(menu_hotkey[i]!=0)
{ c=strchr(buffer,'^');
strcpy(c,c+1);
}
if(i==def_menu)
{ pls(x,y+i,(unsigned char *)buffer,sel_col);
}
else
{ pls(x,y+i,(unsigned char *)buffer,menu_col);
if(menu_hotkey[i]!=0)
{ writechar(x+hotkey_loc[i],y+i,menu[i][hotkey_loc[i]+1],menu_hotkey_color);
}
}
}
if(def_menu==-1)return(-1);
highlight=ON;
while(1)
{ ch=getkey();
if(ch>='a' && ch<='z')
{ ch-=32;
}
if(ch!=EOF)
{ for(i=0;i<menu_num;i++)
{ if(ch==menu_hotkey[i])
{ ch=ENTER;
chcolor(x,y+mp,sl,1,menu_col);
if(menu_hotkey[mp]!=0)
{ writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
menu_hotkey_color);
}
mp=i;
chcolor(x,y+mp,sl,1,sel_col);
break;
}
}
}
if(ch==EOF && mousefound==YES) /* check mouse */
{ if(mouse_state()==PRESSED)
{ get_mouse_location();
if(mousex>=x && mousex<x+strlen(menu[0]) &&
mousey>=y && mousey<y+menu_num )
{ if(strnicmp(menu[mousey-y],"LINE",4)==0)
{ if(highlight==ON)
{ chcolor(x,y+mp,sl,1,menu_col);
if(menu_hotkey[mp]!=0)
{ writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
menu_hotkey_color);
}
highlight=OFF;
}
}
else if(highlight==OFF)
{ mp=mousey-y;
chcolor(x,mousey,sl,1,sel_col);
highlight=ON;
}
else
{ if(mp+y>mousey)ch=UPKEY;
else if(mp+y<mousey)ch=DOWNKEY;
else ch=EOF;
}
}
else
{ if(highlight==ON)
{ chcolor(x,y+mp,sl,1,menu_col);
if(menu_hotkey[mp]!=0)
{ writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
menu_hotkey_color);
}
highlight=OFF;
}
}
}
else if(mouse_state()==PRESSEDRELEASED)
{ get_mouse_location();
if(mousex>=x && mousex<x+strlen(menu[0]) &&
mousey>=y && mousey<y+menu_num )
{ ch=ENTER;
}
else ch=-2;
ms=RELEASED;
}
}
if(ch==UPKEY || ch==DOWNKEY)
{ if(mousefound==YES)hide_mouse_cursor();
chcolor(x,y+mp,sl,1,menu_col);
if(menu_hotkey[mp]!=0)
{ writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
menu_hotkey_color);
}
if(ch==UPKEY)
{ mp--;
if(strnicmp(menu[mp],"LINE",4)==0)mp--;
if(mp<0)mp=menu_num-1;
}
if(ch==DOWNKEY)
{ mp++;
if(strnicmp(menu[mp],"LINE",4)==0)mp++;
if(mp==menu_num)mp=0;
}
chcolor(x,y+mp,sl,1,sel_col);
if(mousefound==YES)show_mouse_cursor();
}
if(ch==ENTER)return(mp);
if(ch==ESC)return(-1);
if(ch==-2) return(-2);
}
}
/*--------------------------------------------------------------------------*/
/* place a string on the screen at appropriate coordinates */
/* parameters : xx1,yy1 -> coordinates */
/* c -> character pointer */
/* cm -> display color */
/*--------------------------------------------------------------------------*/
void pls (int xx1,int yy1,unsigned char c[],int cm)
{ int i;
int m;
if(initvar==0)
{ cls();
printf("\a \n Display borad not initialized");
getch();
exit(-1);
}
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
for (i = 0;i <strlen((char *)c) ;i++ )
{ writechar(xx1+i,yy1,c[i],cm);
}
if(m==YES)
{ show_mouse_cursor();
}
}
/*--------------------------------------------------------------------------*/
/* display a text mode rectangle Parameters: xx1,yy1,xx2,yy2 -> coordinates */
/* cm -> color */
/*--------------------------------------------------------------------------*/
void rect(int xx1,int yy1,int xx2,int yy2,int cm)
{
int x,y ;
int m;
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
if (xx1<=xx2 && yy1<=yy2)
{ for (x = xx1; x < xx2; x++)
{ writechar(x,yy1,196,cm);
writechar(x,yy2,196,cm);
}
for (y = yy1+1; y < yy2; y++)
{ writechar(xx1,y,179,cm);
writechar(xx2,y,179,cm);
}
writechar(xx1,yy1,218,cm);
writechar(xx2,yy1,191,cm);
writechar(xx1,yy2,192,cm);
writechar(xx2,yy2,217,cm);
}
if(m==YES)
{ show_mouse_cursor();
}
}
/*--------------------------------------------------------------------------*/
/* display a text mode filled rectangle. */
/* Parameters: xx1,yy1,xx2,yy2 -> coordinates */
/* cm -> color */
/*--------------------------------------------------------------------------*/
void frect(int xx1,int yy1,int xx2,int yy2,int cm,int shadow)
{
int x,y;
int m;
if(initvar==0)
{ cls();
printf("\a \n Display borad not initialized");
getch();
exit(-1);
}
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
for (y=yy1;y<yy2+1;y++)
{ for (x=xx1;x<xx2+1;x++)
{ writechar(x,y,back_block,cm);
}
}
if(shadow!=0)
{ chcolor(xx1+2,yy2+1,xx2-xx1+1,1,shadow);
chcolor(xx2+1,yy1+1,2,yy2-yy1,shadow);
}
if(m==YES)
{ show_mouse_cursor();
}
}
/*--------------------------------------------------------------------------*/
/* return a key from the keyboard, if non return EOF */
/*--------------------------------------------------------------------------*/
int getkey(void)
{
int key, lo, hi;
if(!kbhit())return(EOF);
key = bioskey(0);
lo = key & 0X00FF;
hi = (key & 0XFF00) >> 8;
if(lo==0)return(hi+256);
return(lo);
/* return((lo == 0) ? hi + 256 : lo); */
}
/*--------------------------------------------------------------------------*/
/* display a filled rectangle, while preserving the background. The */
/* background is saved in an allocated memory. If malloc failes, this */
/* routine will exit to dos.
/* and remove the box. */
/* Parameters : x,y -> coordinates of top left. */
/* xsize -> size in x direction. */
/* ysize -> size in y direction. */
/* backcolor -> color of the box. */
/* forcolor -> border line color. */
/* sw -> display or remove switch */
/* sw=1 : draw the box */
/* sw=0 : remove the last */
/* draw box */
/* border -> draw border on the box */
/*--------------------------------------------------------------------------*/
int messagebox(x,y,xsize,ysize,color,shadow,sw,border)
int x;
int y;
int xsize;
int ysize;
int color;
int shadow;
int sw;
int border;
{
int i,j;
unsigned char *temp;
unsigned char far *scr_temp;
int save_xsize;
int save_ysize;
int m;
if(sw==-1)
{ box_num=0;
return(-1);
}
if(initvar==0)
{ cls();
printf("\a \n Display borad not initialized");
getch();
exit(-1);
}
if(shadow==0)
{ save_ysize=ysize;
save_xsize=xsize;
}
else
{ save_ysize=ysize+1;
save_xsize=xsize+2;
}
switch(sw)
{
case ON :
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
if(box_num==MAX_ENTRIES)
{ cls();
printf("\n box_num has reached the maximum allowed submenu levels");
printf("\n to increase the levels change MAX_WINDOWS in def.h ");
getch();
exit(-1);
}
if( (save_box[box_num]=malloc(save_ysize*save_xsize*2))==NULL)
{ cls();
printf("\n not enough memory for message box # %d",box_num);
getch();
exit(-1);
}
temp=save_box[box_num];
for(i=y;i<y+save_ysize;i++)
{
for(j=x;j<x+save_xsize;j++)
{
*temp++=readchar(j,i);
*temp++=readcolor(j,i);
}
}
/*------------------------------*/
/* text background is saved now */
/*------------------------------*/
/*------------------------------*/
/* save graphics background now */
/*------------------------------*/
if(font_width>1)
{ /*
if( (gsave_box[box_num]=malloc(save_ysize*save_xsize*font_width*font_height))==NULL)
{ cls();
printf("\n not enough memory for graphics message box # %d",box_num);
printf("\n tryed to allocate %u bytes",save_ysize*save_xsize*font_width*font_height);
getch();
exit(-1);
}
temp=gsave_box[box_num];
*/
}
frect(x,y,x+xsize-1,y+ysize-1, color,shadow);
if(border==YES)
{ rect(x,y,x+xsize-1,y+ysize-1,color);
}
xwin[box_num]=x;
ywin[box_num]=y;
xwinsize[box_num]=xsize;
ywinsize[box_num]=ysize;
wincolor[box_num]=color;
winshadow[box_num]=shadow;
winborder[box_num]=border;
box_num++;
break;
case OFF :
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
box_num--;
temp=save_box[box_num];
for(i=y;i<y+save_ysize;i++)
{
for(j=x;j<x+save_xsize;j++)
{
writechar(j,i,*temp,*(temp+1) );
temp+=2;
}
}
free(save_box[box_num]);
break;
} /* end of the switch statement */
if(m==YES)
{ show_mouse_cursor();
}
return(box_num-1);
}
/*--------------------------------------------------------------------------*/
/* change color of a rectangle without changing the characters. */
/*--------------------------------------------------------------------------*/
void chcolor(x,y,xsize,ysize,color)
int x;
int y;
int xsize;
int ysize;
int color;
{ int i;
int j;
int m;
unsigned char far *scr_temp;
m=mouse_display;
if(mouse_display==YES)
{ hide_mouse_cursor();
}
for(j=y;j<y+ysize;j++)
{
for(i=x;i<x+xsize;i++)
{ writechar(i,j,readchar(i,j),color);
}
}
if(m==YES)
{ show_mouse_cursor();
}
}
/*--------------------------------------------------------------------------*/
/* Initialize the mouse driver */
/*--------------------------------------------------------------------------*/
void init_mouse(void)
{
int int_handler;
long vector;
unsigned char first_byte;
int_handler=(int)getvect(0x33);
first_byte=*(unsigned char far *)int_handler;
vector = (long) int_handler;
if((vector==0) || (first_byte==0xcf))
{ mousefound=NO;
ms=RELEASED;
return; /* mouse driver not found */
}
/* reset the mouse */
iReg.x.ax=0;
int86(0x33,&iReg,&oReg);
mousefound=YES;
if(mouse_left_pressed()==YES)
{ ms=PRESSED;
}
else
{ ms=RELEASED;
}
} /* end of set mouse */
/*--------------------------------------------------------------------------*/
/* Display the mouse cursor */
/*--------------------------------------------------------------------------*/
void show_mouse_cursor(void)
{
if(mousefound==NO)return;
iReg.x.ax=1;
int86(0x33,&iReg,&oReg);
mouse_display=YES;
}
/*--------------------------------------------------------------------------*/
/* Hide the mouse cursor */
/*--------------------------------------------------------------------------*/
void hide_mouse_cursor(void)
{
if(mousefound==NO)return;
iReg.x.ax=2;
int86(0x33,&iReg,&oReg);
mouse_display=NO;
}
/*--------------------------------------------------------------------------*/
/* find the mouse location and assign it to mousex, and mousey. */
/*--------------------------------------------------------------------------*/
void get_mouse_location(void)
{
if(mousefound==NO)return;
iReg.x.ax=3;
int86(0x33,&iReg,&oReg);
mousex=oReg.x.cx/8;
mousey=oReg.x.dx/8;
}
/*--------------------------------------------------------------------------*/
/* return the state of the left mouse key (YES) pressed (NO) released */
/*--------------------------------------------------------------------------*/
int mouse_left_pressed(void)
{
if(mousefound==NO)return(NO);
iReg.x.ax=3;
int86(0x33,&iReg,&oReg);
if(oReg.x.bx==1) return(YES);
return(NO);
}
/*--------------------------------------------------------------------------*/
/* return the mouse state, and keep track of if mouse left key has been */
/* pressed and released. */
/*--------------------------------------------------------------------------*/
int mouse_state(void)
{
int a;
a=mouse_left_pressed();
if(a==YES)
{ ms=PRESSED;
return(ms);
}
if(ms==PRESSED && a==NO)
{ ms=PRESSEDRELEASED;
return(ms);
}
return(ms);
}
/*--------------------------------------------------------------------------*/
/* control the text cursor */
/* action : */
/* ON : turn on the text cursor */
/* OFF : turn off the text cursor */
/* BLOCK : change the text cursor to a block */
/* SQUARE : change the text cursor to a square */
/* LINE : change the text cursor to a line */
/* POSITION : set the text cursor location to */
/* txt_curs_x,txt_curs_y. */
/*--------------------------------------------------------------------------*/
void txt_curs(action)
int action;
{
union REGS reg;
return;
switch(action)
{
case ON :
reg.h.ah=1;
reg.h.ch=curs_start_line;
reg.h.cl=curs_end_line;
break;
case OFF :
reg.h.ah=1;
reg.h.ch=1;
reg.h.cl=0;
break;
case BLOCK :
reg.h.ah=1;
curs_start_line=0;
curs_end_line=8;
reg.h.ch=curs_start_line;
reg.h.cl=curs_end_line;
break;
case SQUARE :
reg.h.ah=1;
curs_start_line=4;
curs_end_line=8;
reg.h.ch=curs_start_line;
reg.h.cl=curs_end_line;
break;
case LINE :
reg.h.ah=1;
curs_start_line=8;
curs_end_line=8;
reg.h.ch=curs_start_line;
reg.h.cl=curs_end_line;
break;
case POSITION :
reg.h.ah=2;
reg.h.dh=txt_curs_y;
reg.h.dl=txt_curs_x;
reg.h.bh=0;
break;
default :
return;
}
int86(0x10,®,®);
}
/*--------------------------------------------------------------------------*/
/* clear the screen to black */
/*--------------------------------------------------------------------------*/
void cls(void)
{
if(initvar==0)
{ system("CLS");
printf("\a \n Display borad not initialized");
getch();
exit(-1);
}
frect(0,0,txt_scr_xsize-1,txt_scr_ysize-1,0x07,0);
}
/*--------------------------------------------------------------------------*/
/* return the state of the ALT key */
/*--------------------------------------------------------------------------*/
int alt_pressed(void)
{
if( (bioskey(2) & 0x08)!=0 ) return(YES);
return(NO);
}
/*--------------------------------------------------------------------------*/
/* change the color of the menu. Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void bg_menu_color(int color)
{
menu_color&=0x0F;
menu_color|=color;
}
void fg_menu_color(int color)
{
menu_color&=0xF0;
menu_color|=color;
}
/*--------------------------------------------------------------------------*/
/* change the color of the menu hotkeys. */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void bg_menu_hotkey_color(int color)
{
menu_hotkey_color&=0x0F;
menu_hotkey_color|=color;
}
void fg_menu_hotkey_color(int color)
{
menu_hotkey_color&=0xF0;
menu_hotkey_color|=color;
}
/*--------------------------------------------------------------------------*/
/* change the color of the highlighted menu. */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void bg_menu_sel_color(int color)
{
menu_sel_color&=0x0F;
menu_sel_color|=color;
}
void fg_menu_sel_color(int color)
{
menu_sel_color&=0xF0;
menu_sel_color|=color;
}
/*--------------------------------------------------------------------------*/
/* change the color of the rectangle shadow. */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void bg_menu_shadow(int color)
{
menu_shadow&=0x0F;
menu_shadow|=color;
}
void fg_menu_shadow(int color)
{
menu_shadow&=0x0F;
menu_shadow|=color;
}
/*--------------------------------------------------------------------------*/
/* change the menu bar's x location. */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void ch_menu_x(int x)
{
menu_x=x;
}
/*--------------------------------------------------------------------------*/
/* change the menu bar's y location. */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void ch_menu_y(int y)
{
menu_y=y;
}
/*--------------------------------------------------------------------------*/
/* change the menu bar's x size. . */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void ch_menu_xsize(int xsize)
{
menu_x_size=xsize;
}
/*--------------------------------------------------------------------------*/
/* set the menu file descriptor name */
/* Call this function before bar_menu(INIT) */
/*--------------------------------------------------------------------------*/
void ch_menu_filename(char *f)
{
strcpy(menu_file,f);
}
/*--------------------------------------------------------------------------*/
/* return the next line from the menu descriptor */
/*--------------------------------------------------------------------------*/
int next_line(char *buffer,int buf_size)
{
switch(menu_descriptor)
{ case TEXT_FILE :
if(fgets(buffer,buf_size,fp)!=NULL)
{ strcpy(buffer,buffer+remove_spaces(buffer));
return(0);
}
return(-1);
case VARIABLE :
if(menu_line_ptr==menu_lines)
{ return(-1);
}
strcpy(buffer,*menu);
menu++;
menu_line_ptr++;
break;
}
return(0);
}
/*--------------------------------------------------------------------------*/
/* set the position in the menu descriptor */
/*--------------------------------------------------------------------------*/
void set_pos(long *l )
{
switch(menu_descriptor)
{ case TEXT_FILE :
fsetpos(fp,l);
break;
case VARIABLE :
menu+=(int)(*l-(long)menu_line_ptr);
menu_line_ptr=(int)*l;
break;
}
}
/*--------------------------------------------------------------------------*/
/* return the position in the menu descriptor */
/*--------------------------------------------------------------------------*/
long get_pos( void)
{
switch(menu_descriptor)
{ case TEXT_FILE :
return(ftell(fp));
case VARIABLE :
return((long)menu_line_ptr);
}
return(-1);
}
/*--------------------------------------------------------------------------*/
/* set the menu descriptor to TEXT_FILE, or VARIABLE */
/* when setting to VARIABLE, mv will be pointer to the menu descriptor, */
/* and l is the number of lines in the descriptor */
/* when setting to TEXT_FILE, set mv to NULL, and l to 0 */
/*--------------------------------------------------------------------------*/
void set_menu_descriptor(int md, char **mv,int l)
{
if(md==TEXT_FILE) /* default is set for text file */
{ menu_descriptor=TEXT_FILE;
return;
}
menu_descriptor=VARIABLE;
menu=mv;
menu_lines=l;
menu_line_ptr=0;
}
/*--------------------------------------------------------------------------*/
/* change the character used by frect to filled rectangle. This character */
/* by default is 32. */
/*--------------------------------------------------------------------------*/
void frect_char(unsigned char c)
{
back_block=c;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* display a field with the structure of field : all parameters must be */
/* passed, the field routine will return with return keys of ESC */
/* UPKEY */
/* DOWNKEY */
/* ENTER */
/* TAB */
/* SHIFTTAB */
/* struct field */
/* { int x; field's X coordinate */
/* int y; field's Y coordinate */
/* int length; field length */
/* char title[20]; title of the field */
/* char f[80]; field content */
/* int fcolor; field color */
/* int tcolor; title color */
/* int xstart; default x location for the cursor */
/* as character #, first char=0 */
/* }; */
/* */
/* */
/* When returned, the variable f[80] and xstart are updated with the */
/* new content of the field, and xstart is set to the location of the */
/* cursor with respect to the first character. */
/* */
/* When the function is called, the addres of the structure must be */
/* passed. */
/*--------------------------------------------------------------------------*/
int displayfield(field,action)
struct field *field;
int action;
{
int i;
int ch;
int xcurs;
txt_curs(ON);
hide_mouse_cursor();
for (i=0;i<field->length;i++)
writechar(field->x+i,field->y,' ',field->fcolor);
pls (field->x,field->y,(unsigned char *)field->f,field->fcolor);
pls (field->x,field->y-1,(unsigned char *)field->title,field->tcolor);
if(action==INIT)return EOF;
show_mouse_cursor();
xcurs=field->x+field->xstart;
txt_curs_x=xcurs;
txt_curs_y=field->y;
txt_curs(POSITION);
while(1)
{ ch=getkey();
if(mouse_state()==PRESSED)
{ get_mouse_location();
if(mousey==field->y && mousex>=field->x && mousex<=field->x+field->length)
{ xcurs=mousex;
txt_curs_x=xcurs;
txt_curs_y=field->y;
txt_curs(POSITION);
}
else
{ field->xstart=xcurs-field->x;
strncpy(field->f,"",sizeof((unsigned char *)field->f) ); /* set all to \0 */
txt_curs(OFF);
for(i=0;i<field->length;i++)
{ field->f[i]=readchar(i+field->x,field->y);
}
return(EOF);
}
}
if( (ch>=',' && ch<='~') || ch==' ') /* a valid character was pressed */
{
/*-------------------------------------------------*/
/* check the last character in the field; if it is */
/* a space, shift all characters in between, else */
/* write over what is there */
/*-------------------------------------------------*/
i=readchar(field->x+field->length-1,field->y);
if(i==' ') /* shift characters to the right */
{ txt_curs(OFF);
for(i=field->x+field->length-1;i!=xcurs; i--)
{ writechar(i,field->y,readchar(i-1,field->y),field->fcolor);
}
txt_curs(ON);
}
writechar(xcurs,field->y,ch,field->fcolor);
if(xcurs!=field->x+field->length-1)xcurs++;
txt_curs_x=xcurs;
txt_curs_y=field->y;
txt_curs(POSITION);
continue;
}
switch(ch)
{
case RIGHTKEY :
if(xcurs!=field->x+field->length-1)xcurs++;
else
{ field->xstart=xcurs-field->x;
strncpy(field->f,"",sizeof((unsigned char *)field->f) ); /* set all to \0 */
for(i=0;i<field->length;i++)
{ field->f[i]=readchar(field->x,field->y);
}
txt_curs(OFF);
return(ch);
}
break;
case LEFTKEY :
if(xcurs!=field->x)xcurs--;
else
{ field->xstart=xcurs-field->x;
strncpy(field->f,"",sizeof((unsigned char *)field->f) ); /* set all to \0 */
for(i=0;i<field->length;i++)
{ field->f[i]=readchar(i+field->x,field->y);
}
txt_curs(OFF);
return(ch);
}
break;
case ESC :
case UPKEY :
case DOWNKEY :
case ENTER :
case TAB :
case SHIFTTAB :
/*-------------------------------*/
/* assign the current variables */
/*-------------------------------*/
field->xstart=xcurs-field->x;
strncpy(field->f,"",sizeof((unsigned char *)field->f) ); /* set all to \0 */
for(i=0;i<field->length;i++)
{ field->f[i]=readchar(i+field->x,field->y);
}
txt_curs(OFF);
return(ch);
case DELKEY :
if(xcurs==field->x+field->length-1)
{ writechar(xcurs,field->y,' ',field->fcolor);
break;
}
xcurs++;
ch=BS;
case BS :
if(xcurs==field->x)continue;
txt_curs(OFF);
for(i=xcurs-1;i<field->x+field->length;i++)
{ writechar(i,field->y,readchar(i+1,field->y),field->fcolor);
}
writechar(field->x+field->length-1,field->y,' ',field->fcolor);
xcurs--;
txt_curs(ON);
}
txt_curs_x=xcurs;
txt_curs_y=field->y;
txt_curs(POSITION);
}
}
/*--------------------------------------------------------------------------*/
/* read a string in to the string variable from the screen */
/* string coordinate starts at x,y and the size of the string is size */
/*--------------------------------------------------------------------------*/
void readstring(x,y,size,string)
int x;
int y;
int size;
char *string;
{
int i;
char c;
for(i=x;i<x+size;i++)
{ c=readchar(i,y);
string[i-x]=c;
}
string[size]=0;
}
/*--------------------------------------------------------------------------*/
int set_video_mode(int v)
{
union REGS reg;
reg.x.ax=v;
int86(0x10,®,®);
return v;
}
/*--------------------------------------------------------------------------*/
int get_video_mode(void)
{
union REGS reg;
reg.h.ah=15;
int86(0x10,®,®);
return reg.h.al;
}
/*--------------------------------------------------------------------------*/