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

Win32Joystick.C

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

Generated on Mon Nov 17 02:47:29 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /