home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / userint.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  7KB  |  313 lines

  1. /* User interface routines for REND386 */
  2. /* Original module written by Bernie Roehl, January 1992 */
  3. // Menu, key process routines by Dave Stampe, July '92
  4.  
  5. // Completely rewritten for VR-386 by Dave Stampe, 9/1/94
  6.  
  7.  
  8. /*
  9.  This code is part of the VR-386 project, created by Dave Stampe.
  10.  VR-386 is a desendent of REND386, created by Dave Stampe and
  11.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  12.  Stampre for VR-386.
  13.  
  14.  Copyright (c) 1994 by Dave Stampe:
  15.  May be freely used to write software for release into the public domain
  16.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  17.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  18.  this software or source code into their products!  Usually there is no
  19.  charge for under 50-100 items for low-cost or shareware products, and terms
  20.  are reasonable.  Any royalties are used for development, so equipment is
  21.  often acceptable payment.
  22.  
  23.  ATTRIBUTION:  If you use any part of this source code or the libraries
  24.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  25.  and any other authors in your documentation, source code, and at startup
  26.  of your program.  Let's keep the freeware ball rolling!
  27.  
  28.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  29.  REND386, improving programmer access by rewriting the code and supplying
  30.  a standard API.  If you write improvements, add new functions rather
  31.  than rewriting current functions.  This will make it possible to
  32.  include you improved code in the next API release.  YOU can help advance
  33.  VR-386.  Comments on the API are welcome.
  34.  
  35.  CONTACT: dstampe@psych.toronto.edu
  36. */
  37.  
  38.  
  39. #include <stdio.h>
  40. #include <ctype.h>
  41. #include <dos.h>
  42. #include <conio.h>     /* kbhit() */
  43. #include <bios.h>      /* bioskey() */
  44. #include <string.h>    /* strlen() */
  45.  
  46. #include "pointint.h"
  47. #include "vr_api.h"
  48. #include "pcdevice.h"
  49.  
  50. /* Colors */
  51. #define INTERIOR   4
  52. #define TEXT      14
  53.  
  54. #define TEXTHEIGHT 9
  55. #define TEXTWIDTH 8
  56.  
  57. extern PDRIVER *menu_device;
  58.  
  59. #define CTRLF10   0x6700
  60.  
  61. unsigned getkey(void)
  62. {
  63.   unsigned c, d;
  64.   union REGS regs;
  65.   int shifted;
  66.  
  67.   c = bioskey(0);
  68.   regs.h.ah = 2;
  69.   int86(0x16, ®s, ®s);
  70.   shifted = (regs.h.al & 3);
  71.   d = c & 0xFF;
  72.   if (d == 0)
  73.     {
  74.       c |= shifted; /* normal case */
  75.       if (c == CTRLF10)
  76.     {
  77.       screendump();
  78.       return 0;
  79.     }
  80.       return c; /* special case (shifted keypad) */
  81.     }
  82.   if (!shifted) return d;
  83.   if (d == '8' || d == '4' || d == '6' || d == '2') return (c << 8) + shifted;
  84.   else return d;
  85. }
  86.  
  87.  
  88. void save_screen()
  89. {
  90.   BOOL i = cursor_hide();
  91.   if(!screen_has_been_saved)
  92.      copy_page(current_video_page, screen_save_video_page);
  93.   if(i) cursor_show();
  94.   screen_has_been_saved = TRUE;
  95. }
  96.  
  97. void restore_screen()
  98. {
  99.   BOOL i = cursor_hide();
  100.   copy_page(screen_save_video_page, current_video_page);
  101.   if(i) cursor_show();
  102. //  screen_has_been_saved = 0;
  103. }
  104.  
  105.  
  106. void neatbox(int w, int h, int *x, int *y)
  107. {
  108.  
  109.   *x = (screeninfo->xcent - (w >> 1)) & 0x0FF8;
  110.   *y = screeninfo->ycent - (h >> 1);
  111.   stop_stereo();
  112.   if(*y<5) *y = 5;
  113.   if(*x<5) *x = 5;
  114.   user_box(*x-2, *y-2, *x+w+8, *y+h+8, 0);
  115.   user_box(*x-5, *y-5, *x+w+5, *y+h+5, INTERIOR);
  116. }
  117.  
  118. static int last_jb, last_mb;    /* used to detect click for exit */
  119.  
  120.  
  121. void poptext(char *text[])
  122. {
  123.  int i, h = 0, w = 0, x, y, n=0;
  124.  BOOL was_visible;
  125.  WORD less_height = 0;
  126.  
  127.  was_visible = cursor_hide();
  128.  save_screen();
  129.  
  130.  for (i = 0; text[i]; ++i)
  131.   {
  132.    h += TEXTHEIGHT;
  133.    if (strlen(text[i])*TEXTWIDTH > w)
  134.    w = strlen(text[i])*TEXTWIDTH;
  135.   }
  136.  if (w > screeninfo->xmax-screeninfo->xmin) w = screeninfo->xmax-screeninfo->xmin;
  137.  if (h > screeninfo->ymax-screeninfo->ymin)
  138.    {
  139.      h = screeninfo->ymax-screeninfo->ymin;
  140.      less_height = 1;
  141.    }
  142.  neatbox(w , h , &x, &y);
  143.  for (i = 0; text[i]; ++i)
  144.   {
  145.    user_text(x, y, TEXT, text[i]);
  146.    y += TEXTHEIGHT - less_height;
  147.   }
  148.  if(was_visible) cursor_show();
  149. }
  150.  
  151.  
  152. static set_goodbye()      // records state for response test
  153. {
  154.  int x,y;
  155.  
  156.  last_jb = joystick_buttons;
  157.  last_mb = 0;
  158.  move_2D(menu_device,&x,&y,&last_mb);
  159.  while(kbhit())getch();            // flush keys
  160. }
  161.  
  162.     // test for exit event
  163.     // returns 0 if none
  164.     // buttons (1,2,3) for mouse,
  165.     // 4 for joystick
  166.     // else key value
  167.  
  168. static int goodbye()
  169. {
  170.  int x, y, b;
  171.  
  172.  b = joystick_buttons;
  173.  if((b^last_jb)&b) return 1;
  174.  last_jb = b;
  175.  
  176.  b = 0;
  177.  move_2D(menu_device,&x,&y,&b);  /* test for mouse click */
  178.  if((b^last_mb)&b) return 1;
  179.  last_mb = b;
  180.  
  181.  if(kbhit())            /* check for key click */
  182.   {
  183.    return getkey();
  184.   }
  185.  
  186.  return 0;
  187. }
  188.  
  189.  
  190.     // test for response event
  191.     // returns 0 if none
  192.     // buttons (1,2,3) for mouse,
  193.     // 4 for joystick
  194.     // else key value
  195. WORD get_response(BOOL wait)
  196. {
  197.  int i;
  198.  if(wait) set_goodbye();
  199.  while((!(i=goodbye()) && wait));
  200. // if(!wait) set_goodbye();
  201.  return i;
  202. }
  203.  
  204.     // prints out menu on screen
  205.     // accepts key press,
  206.     // returns capitalized letter in menu if click of mouse
  207.     // click elsewhere or joy click exits
  208.  
  209. WORD menu(char *text[])
  210. {
  211.   int i, h = 0, w = 0, x, y;
  212.   BOOL was_visible;
  213.   int top, left;
  214.   unsigned buttons;
  215.   int num = 0;
  216.   char *c;
  217.  
  218.   was_visible = cursor_hide();
  219.   save_screen();
  220.   for (i = 0; text[i]; ++i)
  221.     {
  222.       h += TEXTHEIGHT;
  223.       if (strlen(text[i])*TEXTWIDTH > w)
  224.         w = strlen(text[i])*TEXTWIDTH;
  225.     }
  226.   if (w > 300) w = 300;
  227.     neatbox(w, h, &x, &y);
  228.   top = y;
  229.   left = x;
  230.   for (i = 0; text[i]; ++i)
  231.     {
  232.       user_text(x, y, TEXT, text[i]);
  233.       y += TEXTHEIGHT;
  234.       num++;
  235.     }
  236.   cursor_show();
  237.   i = get_response(1);
  238.   if(i>0 && i<4)           // mouse click: analyze which entry
  239.     {
  240.       mouse_read(menu_device, &x, &y, &buttons);
  241.       if (y < top || x < left || x > left+w || y > h+top) return 0;
  242.       i = (y-top) / TEXTHEIGHT;
  243.       if((i < 0) || (i >= num))
  244.     {
  245.       i = 0;
  246.       goto end_of_menu;
  247.     }
  248.       for (c = text[i]; (!(isupper(*c))) && (*c); c++);
  249.       i = *c;
  250.     }
  251.   else if(i>' ') i = toupper(i);    // key press
  252. end_of_menu:
  253.   restore_screen();
  254.   if(was_visible==FALSE) cursor_hide();
  255.   return(i);
  256. }
  257.  
  258.  
  259. void popmsg(char *msg)
  260. {
  261.   int x, y;
  262.   BOOL was_visible = cursor_hide();
  263.  
  264.   save_screen();
  265.   neatbox(strlen(msg)*TEXTWIDTH+16, TEXTHEIGHT+16, &x, &y);
  266.   user_text(x+8, y+8, TEXT, msg);
  267.   if(was_visible) cursor_show();
  268. }
  269.  
  270.  
  271. WORD askfor(char *prompt, char *buff, WORD n)
  272. {
  273.   unsigned c;
  274.   int x, y, i;
  275.   BOOL was_visible = cursor_hide();
  276.  
  277.   save_screen();
  278.  
  279.   if(n+strlen(prompt)>36) n = 36-strlen(prompt);            // center
  280.   neatbox(strlen(prompt)*TEXTWIDTH + n * TEXTWIDTH + 10,    // box
  281.       TEXTHEIGHT + 5, &x, &y);
  282.   user_text(x, y, TEXT, prompt);           // print prompt
  283.   x += strlen(prompt) * TEXTWIDTH;
  284.   buff[i = 0] = '\0';
  285.   while (1)
  286.     {
  287.       c = get_response(1);       // get key, click
  288.       if(c==0x1B || c<=4)       // click or esc: abort
  289.     {
  290.       buff[0] = 0;
  291.       break;
  292.     }
  293.       if (c == '\r') break;    // proocess key
  294.       if (c == '\b' && i > 0)
  295.     {
  296.       user_box(x, y, x+TEXTWIDTH*strlen(buff), y+TEXTHEIGHT, INTERIOR);
  297.       buff[--i] = '\0';
  298.       user_text(x, y, TEXT,buff);
  299.     }
  300.       if (isprint(c) && i < n)
  301.     {
  302.       buff[i++] = c;
  303.       buff[i] = '\0';
  304.       user_text(x, y, TEXT, buff);
  305.     }
  306.     }
  307.   restore_screen();
  308.   if(was_visible) cursor_show();
  309.   return c;
  310. }
  311.  
  312.  
  313.