Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Win32Joystick.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: Win32Joystick.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.25 $       $Date: 2011/01/28 17:06:54 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   The Win32Joystick UI object, which maintains the current state of the 
00019  *   joystick.
00020  ***************************************************************************/
00021 
00022 #include "Win32Joystick.h"
00023 #include "DisplayDevice.h"
00024 #include "TextEvent.h"
00025 #include "CommandQueue.h"
00026 #include "Inform.h"
00027 #include "PickList.h"
00028 #include "VMDApp.h"
00029 #include "stdlib.h" // for getenv()
00030 
00031 // constructor
00032 Win32Joystick::Win32Joystick(VMDApp *vmdapp)
00033         : UIObject(vmdapp) {
00034   MMRESULT mres;
00035   int i, numsticks;
00036   sticks = NULL;
00037 
00038   // max joysticks the driver supports, returns 0 if no driver, or failure
00039   maxjoys = joyGetNumDevs(); 
00040 
00041   if (maxjoys > 0) {
00042     sticks = (vmdwinjoystick *) malloc(maxjoys * sizeof(vmdwinjoystick));
00043 
00044     if (sticks != NULL) {
00045       numsticks = 0; 
00046       for (i=0; i<maxjoys; i++) {
00047         memset(&(sticks[i]), 0, sizeof(vmdwinjoystick));
00048         mres = joyGetDevCaps(i, &sticks[i].caps, sizeof(JOYCAPS));
00049     
00050         if (mres == JOYERR_NOERROR) {
00051           msgInfo << "Joystick " << i << ", " << ((int) sticks[i].caps.wNumAxes) << " axes, " << ((int) sticks[i].caps.wNumButtons) << " buttons, ";
00052 
00053           if (sticks[i].caps.szPname == NULL) 
00054              msgInfo << "type unknown." << sendmsg;
00055           else 
00056              msgInfo << sticks[i].caps.szPname << sendmsg;
00057 
00058           sticks[i].xrange = sticks[i].caps.wXmax - sticks[i].caps.wXmin; 
00059           sticks[i].yrange = sticks[i].caps.wYmax - sticks[i].caps.wYmin; 
00060           sticks[i].zrange = sticks[i].caps.wZmax - sticks[i].caps.wZmin; 
00061 
00062           sticks[i].moveMode = OFF; // set joystick off by default, in case
00063                                     // its wacko, this prevents a bad joystick
00064                                     // from interfering with VMD unless the
00065                                     // user intentionally enables it.
00066           sticks[i].exists = TRUE;
00067           numsticks++;
00068         } else {
00069           sticks[i].exists = FALSE;
00070         }
00071       }
00072     }
00073   }
00074 
00075   if (numsticks < 1 || maxjoys < 1) {
00076     msgInfo << "No joysticks found.  Joystick interface disabled." << sendmsg; 
00077   }
00078 
00079   // set the default translation and rotation increments
00080   transInc = 1.0f / 4000.0f;
00081     rotInc = 1.0f / 500.0f;
00082   scaleInc = 1.0f / 4000.0f;
00083   reset();
00084 }
00085 
00086 
00087 // destructor
00088 Win32Joystick::~Win32Joystick(void) {
00089   if (sticks != NULL)
00090     free(sticks);
00091 }
00092 
00094    
00095 // reset the joystick to original settings
00096 void Win32Joystick::reset(void) {
00097   scaling = 1.0;
00098 }
00099 
00100 // update the display due to a command being executed.  Return whether
00101 // any action was taken on this command.
00102 // Arguments are the command type, command object, and the 
00103 // success of the command (T or F).
00104 int Win32Joystick::act_on_command(int type, Command *cmd) {
00105   return FALSE; // we don't take any commands presently
00106 }
00107 
00108 
00109 // do null region processing on raw joystick values
00110 static int nullregion(int null, int val) {
00111   if (abs(val) > null) {
00112     return ((val > 0) ? (val - null) : (val + null));
00113   }
00114   return 0;
00115 }
00116 
00117 
00118 // check for an event, and queue it if found.  Return TRUE if an event
00119 // was generated.
00120 int Win32Joystick::check_event(void) {
00121   int retval = FALSE;
00122   int rx, ry, rz, tx, ty, tz;
00123   int i;
00124   MMRESULT mres;
00125   float scf;
00126   // for use in UserKeyEvent() calls
00127   DisplayDevice::EventCodes keydev=DisplayDevice::WIN_KBD;
00128   
00129   if (maxjoys < 1 || sticks == NULL)
00130     return FALSE; // joysticks disabled 
00131 
00132   rx = ry = rz = tx = ty = tz = 0;
00133 
00134   for (i=0; i<maxjoys; i++) {
00135     if (sticks[i].exists == FALSE) 
00136       continue; // skip processing joysticks that aren't there
00137 
00138     memset(&(sticks[i].info), 0, sizeof(JOYINFOEX));
00139     sticks[i].info.dwSize = sizeof(JOYINFOEX);
00140     sticks[i].info.dwFlags = JOY_RETURNALL;
00141 
00142     // query current joystick status
00143     mres = joyGetPosEx(i, &sticks[i].info);
00144 
00145     if (mres == JOYERR_NOERROR) {
00146       sticks[i].vx = (int) (10000.0f * ((((float) sticks[i].info.dwXpos - sticks[i].caps.wXmin) / ((float) sticks[i].xrange)) - 0.5f));
00147       sticks[i].vy = (int) (10000.0f * ((((float) sticks[i].info.dwYpos - sticks[i].caps.wYmin) / ((float) sticks[i].yrange)) - 0.5f));
00148       sticks[i].vz = (int) (10000.0f * ((((float) sticks[i].info.dwZpos - sticks[i].caps.wZmin) / ((float) sticks[i].zrange)) - 0.5f));
00149  
00150       sticks[i].vx = nullregion(800, sticks[i].vx);
00151       sticks[i].vy = nullregion(800, sticks[i].vy);
00152       sticks[i].vz = nullregion(800, sticks[i].vz);
00153       sticks[i].avail = TRUE; // joystick moved
00154       retval = TRUE; // at least one stick had data
00155     } else {
00156       sticks[i].avail = FALSE; // error of some kind, or not there
00157     }
00158   }
00159 
00160   // process what stick is actually doing
00161   for (i=0; i<maxjoys; i++) {
00162     if (sticks[i].avail != TRUE) 
00163       continue;  // skip processing that stick 
00164   
00165     sticks[i].buttonchanged = sticks[i].info.dwButtons ^ sticks[i].buttons;
00166    
00167     // if the user presses button 1, reset the view
00168     if ((sticks[i].buttonchanged & JOY_BUTTON1) && (sticks[i].info.dwButtons & JOY_BUTTON1)) {
00169       scaling = 1.0;
00170       app->scene_resetview();
00171       msgInfo << "Joystick " << i << " reset view orientation" << sendmsg;
00172     }
00173 
00174     // Toggle between the different modes
00175     if ((sticks[i].buttonchanged & JOY_BUTTON2) && (sticks[i].info.dwButtons & JOY_BUTTON2)) {
00176       switch (sticks[i].moveMode) {
00177         case ROTATION:
00178           sticks[i].moveMode = TRANSLATION;
00179           msgInfo << "Joystick " << i << " set to translation mode" << sendmsg;
00180           break;
00181 
00182         case TRANSLATION:
00183           sticks[i].moveMode = SCALING;
00184           msgInfo << "Joystick " << i << " set to scaling mode" << sendmsg;
00185           break;
00186 
00187         case SCALING:
00188           sticks[i].moveMode = OFF;
00189           msgInfo << "Joystick " << i << " axes disabled" << sendmsg;
00190           break;
00191 
00192         case OFF:
00193         default:
00194           sticks[i].moveMode = ROTATION;
00195           msgInfo << "Joystick " << i << " set to rotation mode" << sendmsg;
00196           break;
00197       }
00198     }
00199 
00200     if ((sticks[i].buttonchanged & JOY_BUTTON3) && (sticks[i].info.dwButtons & JOY_BUTTON3)) {
00201       runcommand(new UserKeyEvent(keydev, '3', (int) DisplayDevice::AUX));
00202     }
00203     if ((sticks[i].buttonchanged & JOY_BUTTON4) && (sticks[i].info.dwButtons & JOY_BUTTON4)) {
00204       runcommand(new UserKeyEvent(keydev, '4', (int) DisplayDevice::AUX));
00205     }
00206     if ((sticks[i].buttonchanged & JOY_BUTTON5) && (sticks[i].info.dwButtons & JOY_BUTTON5)) {
00207       runcommand(new UserKeyEvent(keydev, '5', (int) DisplayDevice::AUX));
00208     }
00209     if ((sticks[i].buttonchanged & JOY_BUTTON6) && (sticks[i].info.dwButtons & JOY_BUTTON6)) {
00210       runcommand(new UserKeyEvent(keydev, '6', (int) DisplayDevice::AUX));
00211     }
00212     if ((sticks[i].buttonchanged & JOY_BUTTON7) && (sticks[i].info.dwButtons & JOY_BUTTON7)) {
00213       runcommand(new UserKeyEvent(keydev, '7', (int) DisplayDevice::AUX));
00214     }
00215     if ((sticks[i].buttonchanged & JOY_BUTTON8) && (sticks[i].info.dwButtons & JOY_BUTTON8)) {
00216       runcommand(new UserKeyEvent(keydev, '8', (int) DisplayDevice::AUX));
00217     }
00218     if ((sticks[i].buttonchanged & JOY_BUTTON9) && (sticks[i].info.dwButtons & JOY_BUTTON9)) {
00219       runcommand(new UserKeyEvent(keydev, '9', (int) DisplayDevice::AUX));
00220     }
00221  
00222     switch(sticks[i].moveMode) {
00223       case ROTATION:
00224         rx = sticks[i].vy;
00225         ry = sticks[i].vx;
00226 
00227         if (sticks[i].caps.wCaps & JOYCAPS_HASZ)
00228           rz = sticks[i].vz;
00229         else 
00230           rz = 0;
00231 
00232         app->scene_rotate_by(((float) rx) * rotInc, 'x');
00233         app->scene_rotate_by(((float) ry) * rotInc, 'y');
00234         app->scene_rotate_by(((float) rz) * rotInc, 'z');
00235         break;
00236   
00237       case TRANSLATION:
00238         tx = sticks[i].vx;
00239         ty = sticks[i].vy;
00240 
00241         if (sticks[i].caps.wCaps & JOYCAPS_HASZ)
00242           tz = sticks[i].vz;
00243         else 
00244           tz = 0;
00245 
00246         app->scene_translate_by(tx * transInc, ty * transInc, -tz * transInc);
00247         break;
00248 
00249       case SCALING: 
00250         tx = sticks[i].vx;
00251         scf = scaling + scaleInc * (float) tx;
00252         if (scf < 0.0)
00253           scf = 0.0;
00254         app->scene_scale_by(scf);
00255         break;
00256 
00257       case OFF:
00258       default:
00259         // do nothing
00260         // The OFF mode is a safety feature so that VMD's stability 
00261         // isn't compromised by bad joysticks.  This provides the user
00262         // with a way to selectively enable joysticks, even though VMD
00263         // will find and attach them all, only the ones that the user has
00264         // enabled will actually affect the VMD view.
00265         break;
00266     }
00267 
00268     sticks[i].buttons = sticks[i].info.dwButtons;
00269   }
00270 
00271   return retval;
00272 }
00273 
00274 
00275 

Generated on Sat May 26 01:48:40 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002