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

  1. // This file: Reads joystick devices thru pointer drivers
  2. // in joyptrs.c.  Adds and supports drivers.
  3. // Uses joystick data to "move" a POSE structure for user
  4.  
  5. // ALL code in this file by Dave Stampe, 12/24/93
  6.  
  7. /*
  8.  This code is part of the VR-386 project, created by Dave Stampe.
  9.  VR-386 is a desendent of REND386, created by Dave Stampe and
  10.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  11.  Stampre for VR-386.
  12.  
  13.  Copyright (c) 1994 by Dave Stampe:
  14.  May be freely used to write software for release into the public domain
  15.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  16.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  17.  this software or source code into their products!  Usually there is no
  18.  charge for under 50-100 items for low-cost or shareware products, and terms
  19.  are reasonable.  Any royalties are used for development, so equipment is
  20.  often acceptable payment.
  21.  
  22.  ATTRIBUTION:  If you use any part of this source code or the libraries
  23.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  24.  and any other authors in your documentation, source code, and at startup
  25.  of your program.  Let's keep the freeware ball rolling!
  26.  
  27.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  28.  REND386, improving programmer access by rewriting the code and supplying
  29.  a standard API.  If you write improvements, add new functions rather
  30.  than rewriting current functions.  This will make it possible to
  31.  include you improved code in the next API release.  YOU can help advance
  32.  VR-386.  Comments on the API are welcome.
  33.  
  34.  CONTACT: dstampe@psych.toronto.edu
  35. */
  36.  
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <dos.h>
  41. #include <bios.h>
  42. #include <conio.h>
  43.  
  44. #include "pointer.h"
  45. #include "vr_api.h"
  46. #include "pcdevice.h"  /* for low-level joystick and keyboard */
  47. #include "intmath.h"
  48. #include "vrconst.h"
  49.  
  50.  
  51. static unsigned lastarrowkey = 0;
  52. extern int use_keyjoy;
  53.  
  54.  
  55. BOOL process_motion_keys(unsigned c)
  56. {
  57.   BOOL handled = 1;
  58.   int i;
  59.  
  60.   key_set_move(0,0,0,0);        // reset key nav. joystick device
  61.  
  62.   switch (c)
  63.     {
  64.     case LEFT:
  65.     case SHLEFT:
  66.     case ASHLEFT:
  67.         if(use_keyjoy) break;
  68.         key_set_move(-1,0,0,0);
  69.         lastarrowkey = c;
  70.         break;
  71.     case RIGHT:
  72.     case SHRIGHT:
  73.     case ASHRIGHT:
  74.         if(use_keyjoy) break;
  75.         key_set_move(1,0,0,0);
  76.         lastarrowkey = c;
  77.         break;
  78.     case UP:
  79.         if(use_keyjoy) break;
  80.         key_set_move(0,-1,0,0);
  81.         lastarrowkey = c;
  82.         break;
  83.     case DOWN:
  84.         if(use_keyjoy) break;
  85.         key_set_move(0,1,0,0);
  86.         lastarrowkey = c;
  87.         break;
  88.     case SHDOWN:
  89.     case ASHDOWN:
  90.         if(use_keyjoy) break;
  91.         key_set_move(0,-1,1,0);
  92.         lastarrowkey = c;
  93.         break;
  94.     case SHUP:
  95.     case ASHUP:
  96.         if(use_keyjoy) break;
  97.         key_set_move(0,1,1,0);
  98.         lastarrowkey = c;
  99.         break;
  100.     case LSHLEFT:
  101.     case ALSHLEFT:
  102.         if(use_keyjoy) break;
  103.         key_set_move(1,0,0,1);
  104.         lastarrowkey = c;
  105.         break;
  106.     case LSHRIGHT:
  107.     case ALSHRIGHT:
  108.         if(use_keyjoy) break;
  109.         key_set_move(-1,0,0,1);
  110.         lastarrowkey = c;
  111.         break;
  112.     case LSHUP:
  113.     case ALSHUP:
  114.         if(use_keyjoy) break;
  115.     case PGUP:
  116.         key_set_move(0,-1,0,1);
  117.         lastarrowkey = c;
  118.         break;
  119.     case LSHDOWN:
  120.     case ALSHDOWN:
  121.         if(use_keyjoy) break;
  122.     case PGDN:
  123.         key_set_move(0,1,0,1);
  124.         lastarrowkey = c;
  125.         break;
  126.     case CTRLPGUP:
  127.         key_set_move(1,0,1,1);
  128.         lastarrowkey = c;
  129.         break;
  130.     case CTRLPGDN:
  131.         key_set_move(-1,0,1,1);
  132.         lastarrowkey = c;
  133.         break;
  134.     case 'R':                   // repeat (benchmark)
  135.         if (lastarrowkey)
  136.           for (i = 0; i < 100; i++)
  137.             {
  138.               process_motion_keys(lastarrowkey);
  139.               joystick_process();
  140.               update_body_links();
  141.               screen_refresh(current_camera);
  142.               if(kbhit()) break;
  143.             }
  144.         position_changed++;
  145.         break;
  146.  
  147.     default: handled = 0;
  148.     }
  149.   return handled;
  150. }
  151.  
  152. static int qset = 0;
  153.  
  154. // up to 9 joystick devices supported
  155.  
  156. static PDRIVER *joydevs[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  157.  
  158. static void joy_quit()
  159. {
  160.   PDRIVER **p = joydevs;
  161.   while(*p)
  162.     {
  163.       pointer_quit(*p);
  164.       p++;
  165.     }
  166. }
  167.  
  168.  
  169. BOOL add_joy_device(char *name)
  170. {
  171.   PDRIVER **ps, **pa = joydevs;
  172.   PDRIVER *p = pointer_init(P_IS2DP,name);
  173.   POINTER x;
  174.  
  175.   if(!p) return 1;    // can't create
  176.   init_pointer(&x); /* so that defaults are OK */
  177.   pointer_tscale(p, 50, 50, 50); /* scale motion */
  178.   pointer_read(p, &x);
  179.   pointer_read(p, &x); /* save current position */
  180.  
  181.   do { ps = pa; }  while((*pa++)!=NULL);
  182.   *ps = p;
  183.   if(!qset++) atexit(joy_quit);
  184.  
  185.   return 0;
  186. }
  187.  
  188.  
  189. /*************** JOYSTICK NAVIGATION ***************/
  190.  
  191.  
  192. /// This reads all pointer (joystick), changes body pose to match
  193.  
  194. static int b_spinmap[4] = { 1, 1, 1, 3 };
  195.  
  196.  
  197. BOOL do_joy_navigate(POSE * body_pose, BOOL spinmode, COORD sstep, ANGLE astep, BOOL screendir)
  198. {
  199.   PDRIVER **pa = joydevs;
  200.   PDRIVER *p;
  201.   POINTER px;
  202.   int c;
  203.   int x,y,b;
  204.   long dist;
  205.   long ang;
  206.   int sscale;
  207.   long mx=0, my=0, mz=0;
  208.   MATRIX n;
  209.   int changed = 0;
  210.  
  211.   while((p=*pa++)!=NULL)    // for each device...
  212.    {
  213.      c = pointer_read(p,&px);
  214.      x = px.x;
  215.      y = px.y;
  216.      if(x==0 && y==0) continue;
  217.      b = px.buttons & 3;
  218.      dist = sstep;
  219.      ang = astep;
  220.      sscale = last_render_time();
  221.      if(spinmode) b=b_spinmap[b];
  222.  
  223.      switch (b)    // set up move by buttons
  224.        {
  225.      case 0:/* no buttons down */
  226.         body_pose->ry += (x * ang)/2000*sscale;
  227.         mz = -(y * dist * sscale)/400L;
  228.         changed++;
  229.         break;
  230.  
  231.      case 1:/* first button down */
  232.         body_pose->rx -= (y * ang)/1200*sscale;
  233.         body_pose->ry += (x * ang)/1000*sscale;
  234.         changed++;
  235.         break;
  236.  
  237.      case 2:/* second button down */
  238.         mx = -(x * dist * sscale)/400L;
  239.         my = -(y * dist * sscale)/400L;
  240.         changed++;
  241.         break;
  242.  
  243.      case 3:/* both buttons down */
  244.         body_pose->rz += (x * ang)/3000*sscale;
  245.         if (stereo_type == MONOSCOPIC)           // none yet for stereo
  246.           {
  247.             SCALE z = get_camera_zoom(current_camera);
  248.             z += (y*65536L) /8000*sscale;
  249.             if(z<65536L*0.5) z = 65536L*0.5;
  250.             if(z>65536L*16.0) z = 65536L*16.0;
  251.             set_camera_zoom(current_camera,z);
  252.           }
  253.         changed++;
  254.         break;
  255.  
  256.      default:
  257.         break;
  258.        }
  259.     if(b!=1)            // map to screen orientation
  260.       {
  261.     if(screendir)
  262.       std_matrix(n,body_pose->rx,body_pose->ry,body_pose->rz, 0, 0, 0);
  263.     else
  264.       std_matrix(n, 0, body_pose->ry, 0, 0, 0, 0);
  265.     matrix_point(n, &mx, &my, &mz);
  266.     body_pose->x += mx;
  267.     body_pose->y += my;
  268.     body_pose->z += mz;
  269.     changed++;
  270.       }
  271.   }
  272.  
  273.   return changed;
  274. }
  275.  
  276.  
  277.     // passes command to all joystick drivers
  278.     // currently used to control mouse
  279.     // and to toggle acceleration mode
  280. void joy_set_mode(int mode)
  281. {
  282.   PDRIVER **pa = joydevs;
  283.   PDRIVER *p;
  284.  
  285.   while((p=*pa++)!=NULL)    // for each device...
  286.    {
  287.      device_command(p, mode);
  288.    }
  289. }
  290.  
  291.  
  292.