|
SpacePoint Fusion plugin 1.0
|
00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OpenSpace3D 00004 For the latest info, see http://www.openspace3d.com 00005 00006 Copyright (c) 2010 I-maginer 00007 00008 This program is free software; you can redistribute it and/or modify it under 00009 the terms of the GNU Lesser General Public License as published by the Free Software 00010 Foundation; either version 2 of the License, or (at your option) any later 00011 version. 00012 00013 This program is distributed in the hope that it will be useful, but WITHOUT 00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License along with 00018 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00019 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00020 http://www.gnu.org/copyleft/lesser.txt 00021 00022 You may alternatively use this source under the terms of a specific version of 00023 the OpenSpace3D Unrestricted License provided you have obtained such a license from 00024 I-maginer. 00025 ----------------------------------------------------------------------------- 00026 */ 00027 00028 /* 00029 SpacePoint Fusion library based on USB HID library from WDK 00030 First version : april 2011 00031 Author : Aymeric Suteau 00032 */ 00033 00041 // Include Header File 00042 #include "Plugin.h" 00043 00045 cbmachine ww; 00046 HWND HScol = NULL; 00047 00049 int OBJFUSIONSCOL; 00050 00052 //===== CB Connected === 00053 int SCOL_FUSION_CONNECTED_CB = 0; 00054 int FUSION_CONNECTED_CB; 00055 00056 //===== CB Disconnected === 00057 int SCOL_FUSION_DISCONNECTED_CB = 1; 00058 int FUSION_DISCONNECTED_CB; 00059 00060 //===== CB New orientation data === 00061 int SCOL_FUSION_ORIENTATION_DATA_CB = 2; 00062 int FUSION_ORIENTATION_DATA_CB; 00063 00064 //===== CB New raw data === 00065 int SCOL_FUSION_RAW_DATA_CB = 3; 00066 int FUSION_RAW_DATA_CB; 00067 00068 //===== CB Button pressed/released === 00069 int SCOL_FUSION_BUTTON_CB = 4; 00070 int FUSION_BUTTON_CB; 00071 00072 00083 00084 int destroyFusionObj(mmachine m, int handsys, int fusionTab) 00085 { 00086 // Read the first element of a TAB element (table of objects) 00087 Fusion* FusionObj = (Fusion*) MMfetch(m, MTOP(fusionTab), 0); 00088 00089 // Safely dispose of "FusionObj" pointer 00090 SAFE_DELETE(FusionObj); 00091 00092 // Write the first element of a TAB element 00093 MMstore(m, MTOP(fusionTab), 0, 0); 00094 00095 // Display debug message 00096 MMechostr(MSKDEBUG, "FusionObj destroyed.\n"); 00097 return 0; 00098 } 00099 00100 00110 int _OpenFusionDevice(mmachine m) 00111 { 00112 #ifdef _SCOL_DEBUG_ 00113 MMechostr(MSKDEBUG,"_OpenFusionDevice\n"); 00114 #endif 00115 00116 // Declare local variables 00117 int k = 0; 00118 int dataType; 00119 00120 // Test channel 00121 if (MMget(m, 1) == NIL) // NOTE: Channel is the first parameter, so on the top of the stack 00122 { 00123 MMechostr(MSKDEBUG,"_OpenFusionDevice : channel NIL\n"); 00124 m->pp += 1; 00125 return 0; 00126 } 00127 00128 // Retrieve data type (raw or orientation) 00129 if ((dataType = MTOI(MMpull(m))) == NIL) 00130 dataType = ORIENTATION_DATA; // Default data mode : orientation 00131 00132 // Create Fusion instance 00133 Fusion * fusion = new Fusion(); 00134 MMechostr(MSKDEBUG, "_OpenFusionDevice ...new SpacePoint Fusion instance created !\n"); 00135 00136 // Open Fusion device on USB port 00137 if (!fusion->OpenDevice(dataType)) 00138 { 00139 MMechostr(MSKDEBUG, "_OpenFusionDevice ...initialization failed\n"); 00140 SAFE_DELETE(fusion); 00141 MMpull(m); // Pull the channel 00142 MMpush(m, NIL); // Push NIL on the stack 00143 return 0; 00144 } 00145 00146 // Allocate a block in the stack for a table of Fusion objects 00147 int fusionTab = MMmalloc(m, 1, TYPETAB); 00148 if (fusionTab == NIL) 00149 { 00150 MMechostr(MSKDEBUG, "_OpenFusionDevice ...MMmalloc failed\n"); 00151 SAFE_DELETE(fusion); 00152 MMpull(m); // Pull the channel 00153 return MMpush(m, NIL); // Push NIL on the stack 00154 } 00155 MMechostr(MSKDEBUG, "_OpenFusionDevice ...MMmalloc successful\n"); 00156 00157 // Push the TAB Fusion object into the stack 00158 MMstore(m, fusionTab, 0, (int)fusion); 00159 MMpush(m, PTOM(fusionTab)); 00160 00161 // Create a new SpacePoint Fusion object 00162 k = OBJcreate(m, OBJFUSIONSCOL, (int)fusion, NULL, NULL); 00163 MMechostr(MSKDEBUG, "_OpenFusionDevice ...object creation successful\n"); 00164 00165 #ifdef _SCOL_DEBUG_ 00166 MMechostr(MSKDEBUG,"ok\n"); 00167 #endif 00168 00169 // Return Fusion object 00170 return k; 00171 } 00172 00173 00182 int _CloseFusionDevice(mmachine m) 00183 { 00184 #ifdef _SCOL_DEBUG_ 00185 MMechostr(MSKDEBUG,"_CloseFusionDevice\n"); 00186 #endif 00187 00188 // Get the table of Fusion objects into the stack (without pulling it) 00189 int fusionTab = MTOP(MMget(m, 0)); 00190 MMechostr(MSKDEBUG, "_CloseFusionDevice\n"); 00191 if (fusionTab == NIL) 00192 { 00193 MMechostr(MSKDEBUG, "_CloseFusionDevice ...ObjFusion NIL\n"); 00194 MMset(m, 0, NIL); 00195 return 0; 00196 } 00197 00198 // Destroy Fusion object according to its type and magma object 00199 OBJdelTM(m, OBJFUSIONSCOL, PTOM(fusionTab)); 00200 00201 // Reinitialize the stack 00202 MMset(m, 0, ITOM(0)); 00203 00204 #ifdef _SCOL_DEBUG_ 00205 MMechostr(MSKDEBUG,"ok\n"); 00206 #endif 00207 00208 return 0; 00209 } 00210 00211 00223 int _CBFusionConnected(mmachine m) 00224 { 00225 return OBJaddreflex(m, OBJFUSIONSCOL, SCOL_FUSION_CONNECTED_CB); 00226 } 00227 00228 int getFusionConnectedCb(mmachine m, HWND h, unsigned msg, UINT id, LONG param, int *ret) 00229 { 00230 int k = 0; 00231 Fusion * FusionObj = (Fusion*) id; 00232 00233 // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype) 00234 if (OBJbeginreflex(m, OBJFUSIONSCOL, (int)FusionObj, SCOL_FUSION_CONNECTED_CB)) 00235 return 0; 00236 00237 return (OBJcallreflex(m, 0)); 00238 } 00239 00240 00252 int _CBFusionDisconnected(mmachine m) 00253 { 00254 return OBJaddreflex(m, OBJFUSIONSCOL, SCOL_FUSION_DISCONNECTED_CB); 00255 } 00256 00257 int getFusionDisconnectedCb(mmachine m, HWND h, unsigned msg, UINT id, LONG param, int *ret) 00258 { 00259 int k = 0; 00260 Fusion * FusionObj = (Fusion*) id; 00261 00262 // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype) 00263 if (OBJbeginreflex(m, OBJFUSIONSCOL, (int)FusionObj, SCOL_FUSION_DISCONNECTED_CB)) 00264 return 0; 00265 00266 return (OBJcallreflex(m, 0)); 00267 } 00268 00269 00281 int _CBFusionOrientationData(mmachine m) 00282 { 00283 // Add a reflex 00284 MMechostr(MSKDEBUG, "_CBFusionOrientationData ...adding reflex\n"); 00285 return OBJaddreflex(m, OBJFUSIONSCOL, SCOL_FUSION_ORIENTATION_DATA_CB); 00286 } 00287 00288 00289 int getFusionOrientationDataCb(mmachine m, HWND h, unsigned msg, UINT id, LONG param, int *ret) 00290 { 00291 int k = 0; 00292 float accX = 0, accY = 0, accZ = 0; // Initialize acceleration values 00293 00294 // Cast id parameter to GloveObj type 00295 Fusion * FusionObj = (Fusion*) id; 00296 00297 // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type) 00298 if (OBJbeginreflex(m, OBJFUSIONSCOL, (int)FusionObj, SCOL_FUSION_ORIENTATION_DATA_CB)) 00299 { 00300 //MMechostr(MSKDEBUG, "getFusionOrientationDataCb ...ObjFusion not found\n"); 00301 return 0; 00302 } 00303 00304 // Retrieve acceleration values 00305 accX = FusionObj->fAcceleration[0]; 00306 accY = FusionObj->fAcceleration[1]; 00307 accZ = FusionObj->fAcceleration[2]; 00308 00309 // 1. Create tuple for acceleration values 00310 int tupleAcc = MMmalloc(m, 3, TYPETAB); 00311 if (tupleAcc == NIL) { 00312 MMpush(m, NIL); // Reinitialize the stack 00313 return MERRMEM; // Return an error code (-1) 00314 } 00315 // Write TAB object field by field 00316 MMstore(m, tupleAcc, 0, FTOM(accX)); 00317 MMstore(m, tupleAcc, 1, FTOM(accY)); 00318 MMstore(m, tupleAcc, 2, FTOM(accZ)); 00319 00320 // Push tuple on the stack 00321 MMpush(m, PTOM(tupleAcc)); 00322 00323 // 2. Create tuple for quaternion values 00324 int tupleQuat = MMmalloc(m, 4, TYPETAB); 00325 if (tupleQuat == NIL) 00326 { 00327 MMpush(m, NIL); 00328 return MERRMEM; 00329 } 00330 MMstore(m, tupleQuat, 0, FTOM(FusionObj->fQuaternion.x)); 00331 MMstore(m, tupleQuat, 1, FTOM(FusionObj->fQuaternion.y)); 00332 MMstore(m, tupleQuat, 2, FTOM(FusionObj->fQuaternion.z)); 00333 MMstore(m, tupleQuat, 3, FTOM(FusionObj->fQuaternion.w)); 00334 MMpush(m, PTOM(tupleQuat)); 00335 00336 // Call reflex previously defined (second parameter = number of user parameters) 00337 k = OBJcallreflex(m, 2); 00338 return k; 00339 } 00340 00341 00353 int _CBFusionRawData(mmachine m) 00354 { 00355 // Add a reflex 00356 MMechostr(MSKDEBUG, "_CBFusionRawData ...adding reflex\n"); 00357 return OBJaddreflex(m, OBJFUSIONSCOL, SCOL_FUSION_RAW_DATA_CB); 00358 } 00359 00360 00361 int getFusionRawDataCb(mmachine m, HWND h, unsigned msg, UINT id, LONG param, int *ret) 00362 { 00363 int k = 0; 00364 int magX = 0, magY = 0, magZ = 0; 00365 int accX = 0, accY = 0, accZ = 0; 00366 int gyrR = 0, gyrP = 0, gyrY = 0; 00367 int res1 = 0, res2 = 0; 00368 int buttonL = 0, buttonR = 0; 00369 00370 // Cast id parameter to GloveObj type 00371 Fusion * FusionObj = (Fusion*) id; 00372 00373 // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type) 00374 if (OBJbeginreflex(m, OBJFUSIONSCOL, (int)FusionObj, SCOL_FUSION_RAW_DATA_CB)) 00375 { 00376 //MMechostr(MSKDEBUG, "getFusionRawDataCb ...ObjFusion not found\n"); 00377 return 0; 00378 } 00379 00380 // Retrieve magnetometer values 00381 magX = FusionObj->iRawAxes[0]; 00382 magY = FusionObj->iRawAxes[1]; 00383 magZ = FusionObj->iRawAxes[2]; 00384 00385 // Retrieve accelerometer values 00386 accX = FusionObj->iRawAxes[3]; 00387 accY = FusionObj->iRawAxes[4]; 00388 accZ = FusionObj->iRawAxes[5]; 00389 00390 // Retrieve gyroscope values 00391 gyrR = FusionObj->iRawAxes[6]; 00392 gyrP = FusionObj->iRawAxes[7]; 00393 gyrY = FusionObj->iRawAxes[8]; 00394 00395 // Retrieve results 1 and 2 values 00396 res1 = FusionObj->iRawAxes[9]; 00397 res2 = FusionObj->iRawAxes[10]; 00398 00399 // 1. Create tuple for magnetometer values 00400 int tupleMag = MMmalloc(m, 3, TYPETAB); 00401 if (tupleMag == NIL) 00402 { 00403 MMpush(m, NIL); // Reinitialize the stack 00404 return MERRMEM; // Return an error code (-1) 00405 } 00406 // Write TAB object field by field 00407 MMstore(m, tupleMag, 0, ITOM(magX)); 00408 MMstore(m, tupleMag, 1, ITOM(magY)); 00409 MMstore(m, tupleMag, 2, ITOM(magZ)); 00410 00411 // Push tuple on the stack 00412 MMpush(m, PTOM(tupleMag)); 00413 00414 // 2. Create tuple for accelerometer values 00415 int tupleAcc = MMmalloc(m, 3, TYPETAB); 00416 if (tupleAcc == NIL) 00417 { 00418 MMpush(m, NIL); // Reinitialize the stack 00419 return MERRMEM; // Return an error code (-1) 00420 } 00421 MMstore(m, tupleAcc, 0, ITOM(accX)); 00422 MMstore(m, tupleAcc, 1, ITOM(accY)); 00423 MMstore(m, tupleAcc, 2, ITOM(accZ)); 00424 MMpush(m, PTOM(tupleAcc)); 00425 00426 // 3. Create tuple for gyroscope values 00427 int tupleGyr = MMmalloc(m, 3, TYPETAB); 00428 if (tupleGyr == NIL) 00429 { 00430 MMpush(m, NIL); // Reinitialize the stack 00431 return MERRMEM; // Return an error code (-1) 00432 } 00433 MMstore(m, tupleGyr, 0, ITOM(gyrR)); 00434 MMstore(m, tupleGyr, 1, ITOM(gyrP)); 00435 MMstore(m, tupleGyr, 2, ITOM(gyrY)); 00436 MMpush(m, PTOM(tupleGyr)); 00437 00438 // 4. Create tuple for results 1 and 2 values 00439 int tupleRes = MMmalloc(m, 2, TYPETAB); 00440 if (tupleRes == NIL) 00441 { 00442 MMpush(m, NIL); // Reinitialize the stack 00443 return MERRMEM; // Return an error code (-1) 00444 } 00445 MMstore(m, tupleRes, 0, ITOM(res1)); 00446 MMstore(m, tupleRes, 1, ITOM(res2)); 00447 MMpush(m, PTOM(tupleRes)); 00448 00449 // Call reflex previously defined (second parameter = number of user parameters) 00450 k = OBJcallreflex(m, 4); 00451 return k; 00452 } 00453 00454 00466 int _CBFusionButton(mmachine m) 00467 { 00468 // Add a reflex 00469 MMechostr(MSKDEBUG, "_CBFusionButton ...adding reflex\n"); 00470 return OBJaddreflex(m, OBJFUSIONSCOL, SCOL_FUSION_BUTTON_CB); 00471 } 00472 00473 00474 int getFusionButtonCb(mmachine m, HWND h, unsigned msg, UINT id, LONG param, int *ret) 00475 { 00476 int k = 0; 00477 int fusionButtons = 0; 00478 00479 // Cast id parameter to GloveObj type 00480 Fusion * FusionObj = (Fusion*) id; 00481 00482 // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type) 00483 if (OBJbeginreflex(m, OBJFUSIONSCOL, (int)FusionObj, SCOL_FUSION_BUTTON_CB)) 00484 { 00485 MMechostr(MSKDEBUG, "getFusionButtonCb ...ObjFusion not found\n"); 00486 return 0; 00487 } 00488 00489 // Retrieve button values 00490 if (FusionObj->iButton[0]) 00491 fusionButtons |= 1; 00492 if (FusionObj->iButton[1]) 00493 fusionButtons |= 2; 00494 00495 // Store Fusion buttons values into the stack 00496 MMpush(m, ITOM(fusionButtons)); 00497 00498 // Call reflex previously defined 00499 k = OBJcallreflex(m, 1); 00500 return k; 00501 } 00502 00503 00511 00512 00514 #define NbTplPKG 8 00515 00516 00520 char *TplName[NbTplPKG] = 00521 { 00522 "ObjFusion", 00523 "_OpenFusionDevice", 00524 "_CloseFusionDevice", 00525 "_CBFusionConnected", 00526 "_CBFusionDisconnected", 00527 "_CBFusionOrientationData", 00528 "_CBFusionRawData", 00529 "_CBFusionButton" 00530 }; 00531 00532 00536 int (*TplFunc[NbTplPKG])(mmachine m)= 00537 { 00538 NULL, // ObjFusion 00539 _OpenFusionDevice, // _OpenFusionDevice 00540 _CloseFusionDevice, // _CloseFusionDevice 00541 _CBFusionConnected, // _CBFusionConnected 00542 _CBFusionDisconnected, // _CBFusionDisconnected 00543 _CBFusionOrientationData, // _CBFusionOrientationData 00544 _CBFusionRawData, // _CBFusionRawData 00545 _CBFusionButton // _CBFusionButton 00546 }; 00547 00548 00552 int TplNArg[NbTplPKG]= 00553 { 00554 TYPTYPE, // ObjFusion 00555 2, // _OpenFusionDevice 00556 1, // _CloseFusionDevice 00557 3, // _CBFusionConnected 00558 3, // _CBFusionDisconnected 00559 3, // _CBFusionOrientationData 00560 3, // _CBFusionRawData 00561 3 // _CBFusionButton 00562 }; 00563 00564 00568 char* TplType[NbTplPKG]= 00569 { 00570 NULL, // ObjFusion 00571 "fun [Chn I] ObjFusion", // _OpenFusionDevice 00572 "fun [ObjFusion] I", // _CloseFusionDevice 00573 "fun [ObjFusion fun [ObjFusion u0] u1 u0] ObjFusion", // _CBFusionConnected 00574 "fun [ObjFusion fun [ObjFusion u0] u1 u0] ObjFusion", // _CBFusionDisconnected 00575 "fun [ObjFusion fun [ObjFusion u0 [F F F] [F F F F]] u1 u0] ObjFusion", // _CBFusionOrientationData 00576 "fun [ObjFusion fun [ObjFusion u0 [I I I] [I I I] [I I I] [I I]] u1 u0] ObjFusion", // _CBFusionRawData 00577 "fun [ObjFusion fun [ObjFusion u0 I] u1 u0] ObjFusion" // _CBFusionButton 00578 }; 00579 00580 00588 // Everything inside _cond and _endcond is ignored by doxygen 00590 00595 int LoadFusion(mmachine m) 00596 { 00597 // Return variable for PKhardpak function 00598 int k; 00599 00600 // Declare a new type of object ("OBJFUSIONSCOL") 00601 OBJFUSIONSCOL = OBJregister(5, 1, destroyFusionObj, "OBJFUSIONSCOL"); 00602 00603 // Get new user events and associate these events with a callback 00604 FUSION_CONNECTED_CB = OBJgetUserEvent(); 00605 OBJdefEvent(FUSION_CONNECTED_CB, (int (__cdecl *)(struct Mmachine *, int, unsigned int, int, int, int *))getFusionConnectedCb); 00606 00607 FUSION_DISCONNECTED_CB = OBJgetUserEvent(); 00608 OBJdefEvent(FUSION_DISCONNECTED_CB, (int (__cdecl *)(struct Mmachine *, int, unsigned int, int, int, int *))getFusionDisconnectedCb); 00609 00610 FUSION_ORIENTATION_DATA_CB = OBJgetUserEvent(); 00611 OBJdefEvent(FUSION_ORIENTATION_DATA_CB, (int (__cdecl *)(struct Mmachine *, int, unsigned int, int, int, int *))getFusionOrientationDataCb); 00612 00613 FUSION_RAW_DATA_CB = OBJgetUserEvent(); 00614 OBJdefEvent(FUSION_RAW_DATA_CB, (int (__cdecl *)(struct Mmachine *, int, unsigned int, int, int, int *))getFusionRawDataCb); 00615 00616 FUSION_BUTTON_CB = OBJgetUserEvent(); 00617 OBJdefEvent(FUSION_BUTTON_CB, (int (__cdecl *)(struct Mmachine *, int, unsigned int, int, int, int *))getFusionButtonCb); 00618 00619 // Load package 00620 k = PKhardpak(m, "FusionEngine", NbTplPKG, TplName, TplFunc, TplNArg, TplType); 00621 return k; 00622 } 00624 00625 00630 extern "C" __declspec (dllexport) int SCOLloadFUSION(mmachine m, cbmachine w) 00631 { 00632 SCOLinitplugin(w); 00633 00634 // Get Scol window handle (for message callback) 00635 HScol = (HWND)SCgetExtra("hscol"); 00636 00637 // Display debug message 00638 MMechostr(MSKDEBUG, "SCOLloadFUSION loading SpacePoint Fusion DLL ...\n"); 00639 00640 LoadFusion(m); 00641 return 0; 00642 } 00643 00644 00649 extern "C" __declspec (dllexport) int SCOLfreeFUSION() 00650 { 00651 // Display debug messages 00652 MMechostr(MSKDEBUG, "Release SpacePoint Fusion DLL\n"); 00653 MMechostr(MSKDEBUG, "SpacePoint Fusion DLL CLOSED...\n\n" ); 00654 return 0; 00655 }
1.7.3