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

  1. // written by Dave Stampe, March '93
  2.  
  3. // uses the new joystick driver to implement a head tracker
  4. // many PC game port cards don't support two game ports: beware!
  5.  
  6. // not tested for latest version yet
  7.  
  8. /*
  9.  This code is part of the REND386 project, created by Dave Stampe and
  10.  Bernie Roehl.
  11.  
  12.  Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
  13.  
  14.  May be freely used to write software for release into the public domain;
  15.  all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
  16.  for permission to incorporate any part of this software into their
  17.  products!  Usually there is no charge for under 50-100 items for
  18.  low-cost or shareware, and terms are reasonable.  Any royalties are used
  19.  for development, so equipment is often acceptable payment.
  20.  
  21.  ATTRIBUTION:  If you use any part of this source code or the libraries
  22.  in your projects, you must give attribution to REND386, Dave Stampe,
  23.  and Bernie Roehl in your documentation, source code, and at startup
  24.  of your program.  Let's keep the freeware ball rolling!  No more
  25.  code ripoffs please.
  26.  
  27.  CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
  28.  See the COPYRITE.H file for more information.
  29. */
  30.  
  31. /*
  32.  POTENTIOMETER 2D head tracker:
  33.  pot 3 is pan
  34.  pot 4 is tilt
  35.  button 3 is hold
  36.  button 4 is recenter
  37.  config file use:
  38.     pot <pscale> <poff> <tscale> <toff> <nr> <nrinc>
  39.  by Dave Stampe, May 1993
  40.  (c) 1993 Dave Stampe
  41. */
  42.  
  43. #include <stdlib.h>
  44. #include <dos.h>
  45. #include <bios.h>
  46. #include <stdio.h>
  47. #include <conio.h>
  48. #include <signal.h>
  49. #include <mem.h>
  50.  
  51. #include "vr_api.h"
  52. #include "rend386.h"
  53. #include "pcdevice.h"
  54. #include "userint.h"
  55. #include "pointer.h"
  56.  
  57.  
  58. /*****************/
  59.  
  60.  
  61.  
  62. /*
  63. static p_dump(int i)
  64. {
  65.  char c[100];
  66.  
  67.  sprintf(c,"%d: %d %.0f,%.0f,%.0f %.0f,%.0f,%.0f", i, status_6d,
  68.  ((float) x_6d) / 40.0, ((float) y_6d) / 40.0, ((float) z_6d) / 40.0,
  69.  ((float) rx_6d) / 40.0, ((float) ry_6d) / 40.0, ((float) rz_6d) / 40.0);
  70.  
  71.  popmsg(c);
  72. }
  73. */
  74.  
  75.  
  76. /************* POTENTIOMETER POINTER DRIVER *************/
  77.  
  78. static pconfig pot_pconfig = {
  79.     1640L, 1640L, 1640L,            /* position res: mm/tick in <16.16>  */
  80.     1048575L, 1048575L, 1048575L,   /* xyz ranges: just dummies */
  81.     -1048575L, -1048575L, -1048575L,
  82.     1640L, 1640L, 1640L,        /* rotation res: <ticks per */
  83.     7200L, 7200L, 7200L,
  84.     -7200L, -7200L, -7200L,         /* rotation range      */
  85.     320, 200, /* mouse emulation limits (writable) */
  86.     P_HASRX | P_HASRY,            /* databits  */
  87.     P_POINTER, 0, 0,                 /* modes, nullkey, flexnum           */
  88.     5, 5, 100,                     /* delay, idelay, reads/sec          */
  89.     P_IS6D | P_IS6H | P_IS3D,       /* uses  */
  90.     "Joystick Pot Head Tracker"
  91. };
  92.  
  93.  
  94. static int pan_off = 0;
  95. static int tilt_off = 0;
  96. static int boxnr = 0;
  97. static long boxnrs = 0;
  98.  
  99. static long rx, ry;
  100.  
  101. static pot_init()
  102. {
  103.  extern int use_pothead;
  104.  extern int joystick_check();
  105.  extern float hdo_x, hdo_y, hdo_z, hdo_rx, hdo_ry, hdo_rz;
  106.  
  107.  if((joystick_check() & 1)==0)
  108.   {
  109.    popmsg("No Pot Headtracker!");
  110.    getch();
  111.    exit(0);
  112.   }
  113.  
  114.  pot_pconfig.xrres = hdo_x*65536.0;    /* set scaling of rotation */
  115.  pot_pconfig.yrres = hdo_z*65536.0;
  116.  
  117.  pan_off = hdo_y;
  118.  tilt_off = hdo_rx;
  119.  
  120.  boxnr = hdo_ry;
  121.  boxnr = hdo_rz*256;
  122.  
  123.  rx = ry = 0;
  124.  
  125.  use_pothead++;
  126.  
  127.  hdo_x = hdo_y = hdo_z = hdo_rx = hdo_ry = hdo_rz = 0.0;  /* use only locally */
  128. }
  129.  
  130. static read_pots()
  131. {
  132.  extern int have_joystick;
  133.  extern int joystick_j1;
  134.  extern int joystick_j2;
  135.  extern int joystick_j3;
  136.  extern int joystick_j4;
  137.  extern int joystick_buttons;
  138.  int x, y;
  139.  int boxx, boxy;
  140.  
  141.  if(!have_joystick)    /* make sure it's read */
  142.   {
  143.    joystick_data joy;
  144.  
  145.    joy.port = 0;
  146.    joy.scale = 0;
  147.    joystick_read(&joy);
  148.   }
  149.  
  150.  x = joystick_j4;
  151.  y = joystick_j3;
  152.  
  153.  if(joystick_buttons & 8)  /* recenter */
  154.   {
  155.    pan_off = y;
  156.    tilt_off = x;
  157.    rx = 0;
  158.    ry = 0;
  159.    return 0;
  160.   }
  161.  if(joystick_buttons & 4) /* hold */
  162.   {
  163.    tilt_off = x - rx;
  164.    pan_off = y - ry;
  165.    return 0;
  166.   }
  167.  
  168.  boxx = boxnr;
  169.  boxy = boxnr;
  170.  if(boxnrs)                 /* adj. threshold for noise level */
  171.   {
  172.    boxx += (x*boxnrs)>>8;
  173.    boxy += (y*boxnrs)>>8;
  174.   }
  175.  
  176.  x -= tilt_off;
  177.  y -= pan_off;
  178.  
  179.  if (x-rx > boxx) rx = x-boxx;         /* X nr */
  180.  else if (rx-x > boxx) rx = x+boxx;
  181.  if (y-ry > boxy) ry = y-boxy;         /* Y nr */
  182.  else if (ry-y > boxy) ry = y+boxy;
  183. }
  184.  
  185.  
  186. pconfig far *pot_driver(int op, POINTER *p, int mode)
  187. {
  188.     int type = FP_OFF(p);         /* way to get integer arg. */
  189.     int ft, fi, fm, fp;
  190.  
  191.     switch(op)
  192.     {
  193.     case DRIVER_CMD:
  194.     case DRIVER_RESET:
  195.         break;
  196.  
  197.     case DRIVER_INIT:
  198.         pot_init();
  199.         break;
  200.  
  201.     case DRIVER_READ:        /* head pointer (6DP) read */
  202.         if (mode == P_POINTER)
  203.          {
  204.           read_pots();
  205.           p->x = 0;
  206.           p->z = 0;
  207.           p->y = 0;
  208.           p->rx = rx*65536L;
  209.           p->ry = ry*65536L;
  210.           p->buttons = 0;
  211.           p->keys = 0;
  212.           p->gesture = -1 ;
  213.          }
  214.         break;
  215.  
  216.     case DRIVER_CHECK:
  217.         break;
  218.     case DRIVER_QUIT:
  219.         break;
  220.     }
  221.     return &pot_pconfig;
  222. }
  223.  
  224.