home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / JIREND / GDC.C < prev    next >
C/C++ Source or Header  |  1993-04-11  |  9KB  |  338 lines

  1. // gdc.c
  2. // Support for Global Devices 3D Controller
  3. // uses serial.c routines
  4. // written by Jerry Isdale and Joe Gradecki
  5. // March 1993
  6. //---------------------------------------------------
  7. // Define TEST to compile as a test program
  8. // Define REND386 to use with REND386
  9. //---------------------------------------------------
  10.   
  11. #include <stdio.h>
  12. #include <dos.h>
  13. #include <bios.h>
  14. #include "serial.h"
  15. #include "gdc.h"
  16.   
  17. //---------------------------------------------------
  18. int use_gdc = 0; // global devices controller ball
  19.                  // set to com port number if to be used
  20. //---------------------------------------------------
  21. unsigned G3D_Mode = GDC_MODE_BYTE1;
  22. int G3D_Port = 2;
  23.   
  24. // for early GDC versions
  25. //#define SINGLE_MODE
  26.   
  27. #define GDC_REQUEST_CONFIG 0x8f
  28. //---------------------------------------------------
  29.   
  30. unsigned char gdc_init( int port )
  31. {
  32.    unsigned in;
  33.   
  34.    G3D_Port = port;
  35.    com_install ( port, 100, 100 ); // dont need large buffers
  36.    com_set_speed ( port, 9600 );
  37.    com_set_parity ( port, COM_NONE, 1 );
  38.   
  39.    // NOTE: Request only works on newer boxes (not V0.4)
  40.    #ifndef SINGLE_MODE
  41.    com_tx ( port, GDC_REQUEST_CONFIG );
  42.    while ( (in= com_rx(port)) == '\0' );
  43.    G3D_Mode = in;
  44.    #endif
  45.   
  46.    return G3D_Mode;
  47.   
  48. }
  49.   
  50. unsigned char gdc_set_mode ( unsigned char mode )
  51. {
  52. #ifdef SINGLE_MODE
  53.    return TRUE;
  54. #else
  55.    unsigned in;
  56.   
  57.    if (G3D_Mode == mode)
  58.       return TRUE;
  59.   
  60.    com_tx(G3D_Port, mode+0x50);
  61.   
  62.    while ( (in=com_rx(G3D_Port)) == '\0' )
  63.       ;
  64.   
  65.    G3D_Mode = in;
  66.    if (in == mode)
  67.       return 1;
  68.    else
  69.       return 0;
  70. #endif
  71. }
  72.   
  73. void gdc_read (unsigned *linear, unsigned *rotation, unsigned *button)
  74. {
  75.    unsigned bytea, byteb, bytec;
  76.   
  77.    switch (G3D_Mode)
  78.    {
  79.       case GDC_MODE_POLLED:
  80.          com_tx(G3D_Port, 0x81);
  81.   
  82.          while ( (bytea=com_rx(G3D_Port)) == '\0' );
  83.          while ( (byteb=com_rx(G3D_Port)) == '\0' );
  84.          while ( (bytec=com_rx(G3D_Port)) == '\0' );
  85.   
  86.          if (linear){
  87.             if ( (bytea & 0xC0) == 0x40) *linear = ~bytea & 0x3f;
  88.             if ( (byteb & 0xC0) == 0x40) *linear = ~byteb & 0x3f;
  89.             if ( (bytec & 0xC0) == 0x40) *linear = ~bytec & 0x3f;
  90.          }
  91.          if (rotation)
  92.          {
  93.             if ( (bytea & 0xC0) == 0xC0) *rotation = ~bytea & 0x3f;
  94.             if ( (byteb & 0xC0) == 0xC0) *rotation = ~byteb & 0x3f;
  95.             if ( (bytec & 0xC0) == 0xC0) *rotation = ~bytec & 0x3f;
  96.          }
  97.          if (button)
  98.          {
  99.             if ( (bytea & 0xC0) == 0x80) *button = ~bytea & 0x3f;
  100.             if ( (byteb & 0xC0) == 0x80) *button = ~byteb & 0x3f;
  101.             if ( (bytec & 0xC0) == 0x80) *button = ~bytec & 0x3f;
  102.          }
  103.          return;
  104.   
  105.       case GDC_MODE_BYTE3:
  106.          bytea=com_rx(G3D_Port);
  107.          if ( bytea != '\0' )
  108.          {
  109.             while ( (byteb=com_rx(G3D_Port)) == '\0' );
  110.             while ( (bytec=com_rx(G3D_Port)) == '\0' );
  111.   
  112.             if (linear){
  113.                if ( (bytea & 0xC0) == 0x40) *linear = ~bytea & 0x3f;
  114.                if ( (byteb & 0xC0) == 0x40) *linear = ~byteb & 0x3f;
  115.                if ( (bytec & 0xC0) == 0x40) *linear = ~bytec & 0x3f;
  116.             }
  117.             if (rotation)
  118.             {
  119.                if ( (bytea & 0xC0) == 0xC0) *rotation = ~bytea & 0x3f;
  120.                if ( (byteb & 0xC0) == 0xC0) *rotation = ~byteb & 0x3f;
  121.                if ( (bytec & 0xC0) == 0xC0) *rotation = ~bytec & 0x3f;
  122.             }
  123.             if (button)
  124.             {
  125.                if ( (bytea & 0xC0) == 0x80) *button = ~bytea & 0x3f;
  126.                if ( (byteb & 0xC0) == 0x80) *button = ~byteb & 0x3f;
  127.                if ( (bytec & 0xC0) == 0x80) *button = ~bytec & 0x3f;
  128.             }
  129.          }
  130.          return;
  131.   
  132.       case GDC_MODE_BYTE1:
  133.          bytea = com_rx(G3D_Port);
  134.   
  135.          if ( bytea != '\0' )
  136.          {
  137.             if ( (bytea & 0xC0) == 0x40) // Linear
  138.                if (linear) *linear = ~bytea & 0x3f;
  139.   
  140.             if ( (bytea & 0xC0) == 0xC0)
  141.                if (rotation) *rotation = ~bytea & 0x3f;
  142.   
  143.             if ( (bytea & 0xC0) == 0x80)
  144.                if (button) *button = ~bytea & 0x3f;
  145.          }
  146.          return;
  147.    }
  148. }
  149.   
  150. void gdc_tactile ( unsigned char intensity, int length )
  151. {
  152.    if ( intensity <= 0 )
  153.       com_tx(G3D_Port, 0xA0);
  154.    else if ( intensity >= 15 )
  155.       com_tx(G3D_Port, 0xAF);
  156.    else
  157.       com_tx(G3D_Port, 0xA0|intensity);
  158.   
  159.    delay ( length );
  160.   
  161.    com_tx(G3D_Port, 0xA0);
  162. }
  163.   
  164. void gdc_tactile_pulse ( unsigned char time )
  165. {
  166.    if ( time <= 0 )
  167.       com_tx(G3D_Port, 0xB0);
  168.    else if ( time >= 15 )
  169.       com_tx(G3D_Port, 0xBF);
  170.    else
  171.       com_tx(G3D_Port, 0xB0|time);
  172. }
  173.   
  174.   
  175. void gdc_remove(void)
  176. {
  177.    com_deinstall(G3D_Port);
  178. }
  179.   
  180. //----------------------------------------------------------
  181. #ifdef TEST
  182. void main()
  183. {
  184.    unsigned char status_of_3d;
  185.    int linear = 0;
  186.    int rotation = 0;
  187.   
  188.    status_of_3d = gdc_init ( 2 ); // com1=1, com2=2, com3=3, com4=4
  189.   
  190.    if (!gdc_set_mode ( GDC_MODE_BYTE1 ))
  191.    {
  192.       printf("Error Cant set mode!\n");
  193.       exit(0);
  194.    }
  195.   
  196.    clrscr();
  197.    while ( !kbhit() )
  198.    {
  199.       gdc_read( &linear, &rotation, NULL );
  200.   
  201.       gotoxy(2,14);
  202.       printf("Linear: x%0.2x    Rotation: x%0.2x\n",linear, rotation);
  203.   
  204.       printf ( " down = %d,  up = %d,   left = %d,   right = %d,  ahead = %d, back = %d\n",
  205.       (linear & GDC_MOVE_DN)?1:0,
  206.       (linear & GDC_MOVE_UP)?1:0,
  207.       (linear & GDC_MOVE_LF)?1:0,
  208.       (linear & GDC_MOVE_RT)?1:0,
  209.       (linear & GDC_MOVE_FW)?1:0,
  210.       (linear & GDC_MOVE_BK)?1:0
  211.       );
  212.   
  213.       printf ( " rollc = %d, roll = %d, pitchd = %d, pitchu = %d, yawl = %d,  yawr = %d\n",
  214.       (rotation & GDC_ROLL_CC)?1:0,
  215.       (rotation & GDC_ROLL_CW)?1:0,
  216.       (rotation & GDC_PITCH_D)?1:0,
  217.       (rotation & GDC_PITCH_U)?1:0,
  218.       (rotation & GDC_YAW_LEF)?1:0,
  219.       (rotation & GDC_YAW_RIT)?1:0
  220.       );
  221.   
  222.       delay(50);
  223.    }
  224.   
  225.    gdc_tactile_pulse (8);
  226.   
  227.    gdc_remove();
  228. }
  229. #endif //TEST
  230.   
  231. //----------------------------------------------------------
  232. #ifdef REND386
  233. #include "rend386.h"
  234. #include "intmath.h"
  235. #include "eprint.h"
  236. #include "math.h"
  237.   
  238. extern long spacestep;
  239. extern int stepsize;
  240. extern VIEW *current_view;
  241. extern int redraw, review;
  242. extern long anglestep;
  243. extern long longitude;
  244.   
  245. #define to_rad(a) ((a) * 3.14159262 / 180.0)
  246. #define sine(x)   sin(to_rad(x/65536L))
  247. #define cosine(x) cos(to_rad(x/65536L))
  248.   
  249. static unsigned linear_state = 0;
  250. static unsigned rotate_state = 0;
  251.   
  252. void gdc_UpdatePos(void)
  253. {
  254.    gdc_read(&linear_state, &rotate_state, NULL);
  255.   
  256.   
  257.    // actions as in do_key if !use_old_keys
  258.    if (linear_state & GDC_MOVE_DN)
  259.    {
  260.       current_view->ey -= (stepsize * spacestep);
  261.    }
  262.   
  263.    if (linear_state & GDC_MOVE_UP)
  264.    {
  265.       current_view->ey += (stepsize * spacestep);
  266.    }
  267.   
  268.    if (linear_state & GDC_MOVE_LF)
  269.    {
  270.       current_view->ex -= 2*((stepsize * spacestep) * cosine(current_view->pan));
  271.       current_view->ez += 2*((stepsize * spacestep) * sine(current_view->pan));
  272.    }
  273.   
  274.    if (linear_state & GDC_MOVE_RT)
  275.    {
  276.       current_view->ex += 2*((stepsize * spacestep) * cosine(current_view->pan));
  277.       current_view->ez -= 2*((stepsize * spacestep) * sine(current_view->pan));
  278.    }
  279.   
  280.    if (linear_state & GDC_MOVE_BK)
  281.    {
  282.       current_view->ex -= 2*((stepsize * spacestep) * sine(current_view->pan));
  283.       current_view->ez -= 2*((stepsize * spacestep) * cosine(current_view->pan));
  284.    }
  285.   
  286.    if (linear_state & GDC_MOVE_FW)
  287.    {
  288.       current_view->ex += 2*((stepsize * spacestep) * sine(current_view->pan));
  289.       current_view->ez += 2*((stepsize * spacestep) * cosine(current_view->pan));
  290.    }
  291.   
  292.    // Rotations use 1/4 size of keyboard
  293.    if (rotate_state & GDC_ROLL_CC)
  294.    {
  295.       current_view->roll -= (stepsize * anglestep)/4;
  296.    }
  297.   
  298.    if (rotate_state & GDC_ROLL_CW)
  299.    {
  300.       current_view->roll += (stepsize * anglestep)/4;
  301.    }
  302.   
  303.    if (rotate_state & GDC_PITCH_D)
  304.    {
  305.       current_view->tilt += (stepsize * anglestep)/4;
  306.    }
  307.   
  308.    if (rotate_state & GDC_PITCH_U)
  309.    {
  310.       current_view->tilt -= (stepsize * anglestep)/4;
  311.    }
  312.   
  313.    if (rotate_state & GDC_YAW_LEF)
  314.    {
  315.       current_view->pan -= (stepsize * anglestep)/4;
  316.    }
  317.   
  318.    if (rotate_state & GDC_YAW_RIT)
  319.    {
  320.       current_view->pan += (stepsize * anglestep)/4;
  321.       longitude -= (stepsize * anglestep)/4;
  322.    }
  323.   
  324.    if (rotate_state | linear_state)
  325.    {
  326.       review = redraw = 1;
  327. #ifdef DEBUG
  328.       eprintf("Updated from GDC:\n");
  329.       eprintf("   View: xyz(%ld %ld %ld)\n",
  330.       current_view->ex, current_view->ey, current_view->ez);
  331.       eprintf("   View: ptr(%ld %ld %ld)\n",
  332.       current_view->pan, current_view->tilt, current_view->roll);
  333. #endif
  334.    }
  335. }
  336. #endif // REND386
  337.   
  338.