home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Homebrewer's Handbook
/
vr.iso
/
vr386
/
userint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-19
|
7KB
|
313 lines
/* User interface routines for REND386 */
/* Original module written by Bernie Roehl, January 1992 */
// Menu, key process routines by Dave Stampe, July '92
// Completely rewritten for VR-386 by Dave Stampe, 9/1/94
/*
This code is part of the VR-386 project, created by Dave Stampe.
VR-386 is a desendent of REND386, created by Dave Stampe and
Bernie Roehl. Almost all the code has been rewritten by Dave
Stampre for VR-386.
Copyright (c) 1994 by Dave Stampe:
May be freely used to write software for release into the public domain
or for educational use; all commercial endeavours MUST contact Dave Stampe
(dstampe@psych.toronto.edu) for permission to incorporate any part of
this software or source code into their products! Usually there is no
charge for under 50-100 items for low-cost or shareware products, and terms
are reasonable. Any royalties are used for development, so equipment is
often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to VR-386 and Dave Stampe,
and any other authors in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling!
DEVELOPMENT: VR-386 is a effort to develop the process started by
REND386, improving programmer access by rewriting the code and supplying
a standard API. If you write improvements, add new functions rather
than rewriting current functions. This will make it possible to
include you improved code in the next API release. YOU can help advance
VR-386. Comments on the API are welcome.
CONTACT: dstampe@psych.toronto.edu
*/
#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include <conio.h> /* kbhit() */
#include <bios.h> /* bioskey() */
#include <string.h> /* strlen() */
#include "pointint.h"
#include "vr_api.h"
#include "pcdevice.h"
/* Colors */
#define INTERIOR 4
#define TEXT 14
#define TEXTHEIGHT 9
#define TEXTWIDTH 8
extern PDRIVER *menu_device;
#define CTRLF10 0x6700
unsigned getkey(void)
{
unsigned c, d;
union REGS regs;
int shifted;
c = bioskey(0);
regs.h.ah = 2;
int86(0x16, ®s, ®s);
shifted = (regs.h.al & 3);
d = c & 0xFF;
if (d == 0)
{
c |= shifted; /* normal case */
if (c == CTRLF10)
{
screendump();
return 0;
}
return c; /* special case (shifted keypad) */
}
if (!shifted) return d;
if (d == '8' || d == '4' || d == '6' || d == '2') return (c << 8) + shifted;
else return d;
}
void save_screen()
{
BOOL i = cursor_hide();
if(!screen_has_been_saved)
copy_page(current_video_page, screen_save_video_page);
if(i) cursor_show();
screen_has_been_saved = TRUE;
}
void restore_screen()
{
BOOL i = cursor_hide();
copy_page(screen_save_video_page, current_video_page);
if(i) cursor_show();
// screen_has_been_saved = 0;
}
void neatbox(int w, int h, int *x, int *y)
{
*x = (screeninfo->xcent - (w >> 1)) & 0x0FF8;
*y = screeninfo->ycent - (h >> 1);
stop_stereo();
if(*y<5) *y = 5;
if(*x<5) *x = 5;
user_box(*x-2, *y-2, *x+w+8, *y+h+8, 0);
user_box(*x-5, *y-5, *x+w+5, *y+h+5, INTERIOR);
}
static int last_jb, last_mb; /* used to detect click for exit */
void poptext(char *text[])
{
int i, h = 0, w = 0, x, y, n=0;
BOOL was_visible;
WORD less_height = 0;
was_visible = cursor_hide();
save_screen();
for (i = 0; text[i]; ++i)
{
h += TEXTHEIGHT;
if (strlen(text[i])*TEXTWIDTH > w)
w = strlen(text[i])*TEXTWIDTH;
}
if (w > screeninfo->xmax-screeninfo->xmin) w = screeninfo->xmax-screeninfo->xmin;
if (h > screeninfo->ymax-screeninfo->ymin)
{
h = screeninfo->ymax-screeninfo->ymin;
less_height = 1;
}
neatbox(w , h , &x, &y);
for (i = 0; text[i]; ++i)
{
user_text(x, y, TEXT, text[i]);
y += TEXTHEIGHT - less_height;
}
if(was_visible) cursor_show();
}
static set_goodbye() // records state for response test
{
int x,y;
last_jb = joystick_buttons;
last_mb = 0;
move_2D(menu_device,&x,&y,&last_mb);
while(kbhit())getch(); // flush keys
}
// test for exit event
// returns 0 if none
// buttons (1,2,3) for mouse,
// 4 for joystick
// else key value
static int goodbye()
{
int x, y, b;
b = joystick_buttons;
if((b^last_jb)&b) return 1;
last_jb = b;
b = 0;
move_2D(menu_device,&x,&y,&b); /* test for mouse click */
if((b^last_mb)&b) return 1;
last_mb = b;
if(kbhit()) /* check for key click */
{
return getkey();
}
return 0;
}
// test for response event
// returns 0 if none
// buttons (1,2,3) for mouse,
// 4 for joystick
// else key value
WORD get_response(BOOL wait)
{
int i;
if(wait) set_goodbye();
while((!(i=goodbye()) && wait));
// if(!wait) set_goodbye();
return i;
}
// prints out menu on screen
// accepts key press,
// returns capitalized letter in menu if click of mouse
// click elsewhere or joy click exits
WORD menu(char *text[])
{
int i, h = 0, w = 0, x, y;
BOOL was_visible;
int top, left;
unsigned buttons;
int num = 0;
char *c;
was_visible = cursor_hide();
save_screen();
for (i = 0; text[i]; ++i)
{
h += TEXTHEIGHT;
if (strlen(text[i])*TEXTWIDTH > w)
w = strlen(text[i])*TEXTWIDTH;
}
if (w > 300) w = 300;
neatbox(w, h, &x, &y);
top = y;
left = x;
for (i = 0; text[i]; ++i)
{
user_text(x, y, TEXT, text[i]);
y += TEXTHEIGHT;
num++;
}
cursor_show();
i = get_response(1);
if(i>0 && i<4) // mouse click: analyze which entry
{
mouse_read(menu_device, &x, &y, &buttons);
if (y < top || x < left || x > left+w || y > h+top) return 0;
i = (y-top) / TEXTHEIGHT;
if((i < 0) || (i >= num))
{
i = 0;
goto end_of_menu;
}
for (c = text[i]; (!(isupper(*c))) && (*c); c++);
i = *c;
}
else if(i>' ') i = toupper(i); // key press
end_of_menu:
restore_screen();
if(was_visible==FALSE) cursor_hide();
return(i);
}
void popmsg(char *msg)
{
int x, y;
BOOL was_visible = cursor_hide();
save_screen();
neatbox(strlen(msg)*TEXTWIDTH+16, TEXTHEIGHT+16, &x, &y);
user_text(x+8, y+8, TEXT, msg);
if(was_visible) cursor_show();
}
WORD askfor(char *prompt, char *buff, WORD n)
{
unsigned c;
int x, y, i;
BOOL was_visible = cursor_hide();
save_screen();
if(n+strlen(prompt)>36) n = 36-strlen(prompt); // center
neatbox(strlen(prompt)*TEXTWIDTH + n * TEXTWIDTH + 10, // box
TEXTHEIGHT + 5, &x, &y);
user_text(x, y, TEXT, prompt); // print prompt
x += strlen(prompt) * TEXTWIDTH;
buff[i = 0] = '\0';
while (1)
{
c = get_response(1); // get key, click
if(c==0x1B || c<=4) // click or esc: abort
{
buff[0] = 0;
break;
}
if (c == '\r') break; // proocess key
if (c == '\b' && i > 0)
{
user_box(x, y, x+TEXTWIDTH*strlen(buff), y+TEXTHEIGHT, INTERIOR);
buff[--i] = '\0';
user_text(x, y, TEXT,buff);
}
if (isprint(c) && i < n)
{
buff[i++] = c;
buff[i] = '\0';
user_text(x, y, TEXT, buff);
}
}
restore_screen();
if(was_visible) cursor_show();
return c;
}