home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / ZIP / MISC3D / AVRIL11.ZIP / DRVCYMAN.C < prev    next >
C/C++ Source or Header  |  1994-09-05  |  5KB  |  156 lines

  1. /* Logitech Cyberman support for AVRIL */
  2.  
  3. /* Written by Bernie Roehl, July 1994 */
  4.  
  5. /* Copyright 1994 by Bernie Roehl */
  6.  
  7. /* You may use this code for your own non-commercial projects without
  8.    paying any fees or royalties.  "Non-commercial", in this context,
  9.    means that the software you write is given away for free to anyone
  10.    who wants it.
  11.    
  12.    Commercial use, including shareware, requires a licensing
  13.    fee and a specific written agreement with the author.
  14.  
  15.    All programs created using this software (both commercial and
  16.    non-commercial) must acknowledge the use of the AVRIL library,
  17.    both in the documentation and in a banner screen at the start or
  18.    end of the program.
  19.  
  20.    For more information, contact Bernie Roehl (broehl@uwaterloo.ca).
  21.  
  22. */
  23.  
  24. #include <dos.h>
  25. #include <alloc.h>
  26. #include <mem.h>
  27.  
  28. #include "avril.h"
  29.  
  30. static vrl_DeviceChannel cybchannel_defaults[] =
  31.     {
  32.         /* center, deadzone, range, scale, accum */
  33.         { 0, 5,  128, float2scalar(1000), 1 },  /* trans X */
  34.         { 0, 0,    1, float2scalar(1000), 1 },  /* trans Y */
  35.         { 0, 5, -128, float2scalar(1000), 1 },  /* trans Z */
  36.         { 0, 0,   -1, float2angle(20), 1 },  /* rot X */
  37.         { 0, 0,   -1, float2angle(20), 1 },  /* rot Y */
  38.         { 0, 0,    1, float2angle(20), 1 }   /* rot Z */
  39.     };
  40.  
  41. static void reset_cyberman(vrl_SerialPort *port)
  42.     {
  43.     vrl_SerialSetDTR(port, 1);  /* DTR high */
  44.     vrl_SerialSetRTS(port, 0);  /* RTS low */
  45.     vrl_TimerDelay(200);        /* spec says 100, but let's be generous */
  46.     vrl_SerialSetRTS(port, 1);  /* RTS high */
  47.     vrl_TimerDelay(400);        /* 110 for first char, 100 for second */
  48.     }
  49.  
  50. static int values[] = { 0, 1, -1, 0 };
  51.  
  52. int vrl_CybermanOutput(vrl_Device *dev, int parm1, vrl_Scalar parm2)
  53.     {
  54.     unsigned char val = ((vrl_32bit) scalar2float(parm2)) & 0xFF;
  55.     if (parm1) return -1;
  56.     vrl_SerialPutc('!', dev->port);
  57.     vrl_SerialPutc('T', dev->port);
  58.     vrl_SerialPutc(val, dev->port);
  59.     vrl_SerialPutc(255 - val, dev->port);
  60.     vrl_SerialPutc((val == 0) ? 0 : 7, dev->port);  /* 280 ms */
  61.     return 0;
  62.     }
  63.  
  64. int vrl_CybermanDevice(vrl_DeviceCommand cmd, vrl_Device *device)
  65.     {
  66.     switch (cmd)
  67.         {
  68.         case VRL_DEVICE_INIT:
  69.             if (device->port == NULL) return -4;
  70.             device->nchannels = 6;
  71.             device->channels = calloc(device->nchannels, sizeof(vrl_DeviceChannel));
  72.             if (device->channels == NULL) return -1;
  73.             device->localdata = vrl_DeviceCreatePacketBuffer(5);
  74.             if (device->localdata == NULL)
  75.                 {
  76.                 free(device->channels);
  77.                 device->channels = NULL;
  78.                 return -1;
  79.                 }
  80.             device->nbuttons = 3;
  81.             device->noutput_channels = 1;
  82.             device->outfunc = vrl_CybermanOutput;
  83.             device->desc = "Logitech Cyberman, direct serial";
  84.             device->version = 1;
  85.         case VRL_DEVICE_RESET:
  86.             vrl_SerialSetParameters(device->port, 1200, VRL_PARITY_NONE, 7, 1);
  87.             reset_cyberman(device->port);
  88.             /* look for the 'M3' identification sequence */
  89.             if (!vrl_SerialCheck(device->port)) return -2;
  90.             if (vrl_SerialGetc(device->port) != 'M') return -3;
  91.             if (!vrl_SerialCheck(device->port)) return -2;
  92.             if (vrl_SerialGetc(device->port) != '3') return -3;
  93.             /* enter Swift mode */
  94.             vrl_SerialPutc('*', device->port);  vrl_SerialPutc('S', device->port);
  95.             vrl_TimerDelay(500);
  96.             vrl_SerialSetParameters(device->port, 4800, VRL_PARITY_NONE, 8, 1);
  97.             vrl_TimerDelay(200);
  98.             vrl_SerialFlush(device->port);
  99.             /* request a Static Device Status report */
  100.             vrl_SerialPutc('!', device->port);  vrl_SerialPutc('S', device->port);
  101.             vrl_TimerDelay(500);  /* wait for the report to come in */
  102.             while (vrl_SerialCheck(device->port))
  103.                 if ((vrl_SerialGetc(device->port) & 0xE0) == 0xA0)
  104.                     break;
  105.             if (!vrl_SerialCheck(device->port))
  106.                 {
  107.                 reset_cyberman(device->port);
  108.                 return -2;  /* no report */
  109.                 }
  110.             vrl_SerialFlush(device->port);
  111.             memcpy(device->channels, cybchannel_defaults, sizeof(cybchannel_defaults));
  112.             return 0;
  113.         case VRL_DEVICE_POLL:
  114.             while (vrl_DeviceGetPacket(device->port, device->localdata))
  115.                 {
  116.                 unsigned char *p = vrl_DevicePacketGetBuffer(device->localdata);
  117.                 int x, y, i;
  118.                 unsigned int b;
  119.                 if ((p[0] & 0xE0) != 0x80) continue;  /* ignore non-data packets */
  120.                 b = p[0] & 0x1F;
  121.                 device->bchanged = b ^ device->buttons;
  122.                 device->buttons = b;
  123.                 x = (p[1] << 1) | ((p[2] >> 6) & 0x01);
  124.                 y = (p[2] << 2) | ((p[3] >> 5) & 0x03);
  125.                 if (x & 0x80) x |= 0xFF00;  /* sign extend */
  126.                 else x &= 0xFF;
  127.                 if (y & 0x80) y |= 0xFF00;  /* sign extend */
  128.                 else y &= 0xFF;
  129.                 device->channels[X].rawvalue = x;
  130.                 device->channels[Y].rawvalue = values[(p[3] >> 3) & 0x03];
  131.                 device->channels[Z].rawvalue = y;
  132.                 device->channels[XROT].rawvalue = values[(p[3] >> 1) & 0x03];
  133.                 device->channels[YROT].rawvalue = values[(p[4] >> 4) & 0x03];
  134.                 device->channels[ZROT].rawvalue = values[((p[3] << 1) | ((p[4] >> 6) & 0x01)) & 0x03];
  135.                 for (i = 0; i < 6; ++i)
  136.                     device->channels[i].changed = 1;
  137.                 }
  138.             return 0;
  139.         case VRL_DEVICE_QUIT:
  140.             reset_cyberman(device->port);
  141.             if (device->localdata)
  142.                 {
  143.                 vrl_DeviceDestroyPacketBuffer(device->localdata);
  144.                 device->localdata = NULL;
  145.                 }
  146.             if (device->channels)
  147.                 {
  148.                 free(device->channels);
  149.                 device->channels = NULL;
  150.                 }
  151.             return 0;
  152.         default: break;
  153.         }
  154.     return 1;  /* function not implemented */
  155.     }
  156.