diff options
| author | Wei Shuai <cpuwolf@gmail.com> | 2018-01-26 13:51:39 +0800 | 
|---|---|---|
| committer | Wei Shuai <cpuwolf@gmail.com> | 2018-01-26 13:51:39 +0800 | 
| commit | ef1172e936c054946cb8a4b5bed7e995b3136ebb (patch) | |
| tree | 76177039890366c4ec685e6409f1ada04d73f82d /tracker-pt | |
| parent | f089dc3db463b88b71d8d8ca92ee4fd4b47903e1 (diff) | |
opentrack/wiiyourself: new home
Diffstat (limited to 'tracker-pt')
| -rw-r--r-- | tracker-pt/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tracker-pt/tracker-wii/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/History.txt | 281 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/License.txt | 42 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/ReadMe.txt | 202 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/lang/nl_NL.ts | 4 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/lang/ru_RU.ts | 4 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/lang/stub.ts | 4 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/wiimote.cpp | 2806 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/wiimote.h | 495 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/wiimote_common.h | 109 | ||||
| -rw-r--r-- | tracker-pt/wiiyourself/wiimote_state.h | 379 | 
13 files changed, 1 insertions, 4329 deletions
diff --git a/tracker-pt/CMakeLists.txt b/tracker-pt/CMakeLists.txt index 2e8446d5..e588e567 100644 --- a/tracker-pt/CMakeLists.txt +++ b/tracker-pt/CMakeLists.txt @@ -6,6 +6,5 @@ if(OpenCV_FOUND)      target_link_libraries(opentrack-tracker-pt-base opentrack-cv ${modules})  endif()  add_subdirectory(module) -add_subdirectory(wiiyourself)  add_subdirectory(tracker-wii) diff --git a/tracker-pt/tracker-wii/CMakeLists.txt b/tracker-pt/tracker-wii/CMakeLists.txt index a22121ef..cab5b6a1 100644 --- a/tracker-pt/tracker-wii/CMakeLists.txt +++ b/tracker-pt/tracker-wii/CMakeLists.txt @@ -1,6 +1,6 @@  find_package(OpenCV 3.0 QUIET)  if(OpenCV_FOUND)      otr_module(tracker-wii) -    target_link_libraries(opentrack-tracker-wii opentrack-tracker-pt-base opentrack-tracker-wii-pt-wiiyourself) +    target_link_libraries(opentrack-tracker-wii opentrack-tracker-pt-base opentrack-wiiyourself)  	target_include_directories(opentrack-tracker-wii PRIVATE "${CMAKE_SOURCE_DIR}/tracker-pt")  endif()
\ No newline at end of file diff --git a/tracker-pt/wiiyourself/CMakeLists.txt b/tracker-pt/wiiyourself/CMakeLists.txt deleted file mode 100644 index e16787c7..00000000 --- a/tracker-pt/wiiyourself/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -otr_module(tracker-wii-pt-wiiyourself STATIC) diff --git a/tracker-pt/wiiyourself/History.txt b/tracker-pt/wiiyourself/History.txt deleted file mode 100644 index 6601dc97..00000000 --- a/tracker-pt/wiiyourself/History.txt +++ /dev/null @@ -1,281 +0,0 @@ -____________________________________________________________ - -  - WiiYourself! - native C++ Wiimote library  v1.15 -    (c) gl.tter 2007-10 - http://gl.tter.org -____________________________________________________________ - -History: - -What's new since 1.01a? - Main Features (see ReadMe & full history for details) - -    + Balance Board support with automatic offset removal. - -    + Seemingly solid MotionPlus support. - -    + Library no longer includes project files - just add wiimote.cpp & -      header to your project (avoids all build-settings releated issues) -     -    + better MinGW support:  (thanks Elmo) -      adds functional _ASSERT/TRACE/WARN/DEEP_TRACE macros -          non-MSYS dependent build option via 'make_mingw.bat'. -          Demo builds & works under MinGW. -     -    + new Python wrapper (by Robert Xiao, see 'Python' folder for details) -     -    + library now compiles on Borland (thanks Griff - demo not tested). -     -    + many fixes, connections should be more reliable. -     -    + join my mailing list to give feedback, share ideas & stay informed: -        http://gl.tter.org/mailman/listinfo/wiiyourself_gl.tter.org - -1.15 Final: -    + fixed MotionPlus detection on stacks that require HID writes! -    + Balance Board corner weight values have been quartered (.Total remains -       unchanged).  The non-raw corner weight incorrectly reported 4x their -       real value. -    + Wiimote calibration info is more reliably received (it may not have -       arrived in many instances) -    + exposed a partially-unique device ID (wiimote::UniqueID).  This 64bit -       number is set during the Connect() call, and is derived from the -       device-specific calibration values.  It's therefore not guaranteed to -       be truly unique (several devices may conceivably hold the same calibration -       values).  However in practice it is likely to be unique between a -       few wiimotes, so it can be used to eg. assign a particular wiimote to the -       same player every time. -    + internal: made the HID report output queue fixed-size to remove any -                 glitches from frequent dynamic memory allocation (thanks -                 Steve).  The old STL-queue based code can still be reenabled -                 by defining USE_DYNAMIC_HIDQUEUE. - -1.15 RC2: -    + added Python wrapper by Robert Xiao - you can now use WiiYourself! with -       Python! (thanks Robert) -    + hopefully fixed MotionPlus connection problems! (send report to my -       mailing list) - -    + added virtual event-change notifier to the wiimote object (thanks Robert -       Xio) - works the same as external callbacks.  To use, derive your own -       class from the wiimote object and override ChangedNotifier() - -    + changed the way callbacks work: -     -      in previous versions, it was OK to access the wiimote object's state -        from callbacks.  This required an internal RefreshState() call just -        before the callback function is executed - but this could then change -        the internal state unexpectedly, so values could change in polling -        loops even between the app's own RefreshState() calls. -         -      to correct this, the callback functions now get a read-only copy -       of the newest state passed in, you should only access this copy as -       state in the wiimote object is likely out-of-date. -        -      In short, the wiimote object's exposed state is now _only_ refreshed -       by the application, not by callbacks. -        -      (this also solved Motion+ connection and disabling failures). -       -    + added new change event 'CONNECTED' -     -      the demo previously used callbacks to set most of its report types, but -       it also set them once shortly after connecting the wiimote, and this could -       cause it to set the wrong one, breaking extension data.  Instead it now -       uses the CONNECTED event in the callback.  It's best to only set these -       in one place. -        -1.15 RC: -    + fixed missing Balance Board calibration values for the 34kg category -       (thanks Benjamin Lassort). -     -    + fixed Wiimote disconnecting in certain scenarios (ReportType wasn't -       initialised, and this could sometimes be sent to the 'mote, causing -       it to disconnect - thanks Robert Xiao). -        -    + minor changes to support Robert Xiao's WiiYourself! Python Wrapper! -      (next release). - -1.14 BETA: -	  - added new state & callback event: bBatteryDrained / BATTERY_DRAINED -	     this is sent went the wiimote signals that the batteries are nearly -	     empty. -	  - added MotionPlus extension events (ie. for extensions plugged into it): -	  	  MOTIONPLUS_EXTENSION_CONNECTED -	  	  MOTIONPLUS_EXTENSION_DISCONNECTED -	  	 wiimote::MotionPlusHasExtension() -	  	 wiimote::DisableMotionPlus() -	  	 wiimote::EnableMotionPlus() -          -         (apps can now decide if they want to disable the MotionPlus to read the -         extension instead, see demo for an example) -          -         ** however **, MotionPlus disabling isn't reliable at the moment (it -         rarely works), and so extension connected to an already enabled plus -         rarely are activated.  Could use some help on this one. -	      -1.13 BETA: -      + ** BALANCE BOARDS no longer require setting a report type! ** -        there is only one type for it, and this is now set automatically. -         -      + 'At Rest' offset removal added (currently only for Balance Boards). -         this reads the current analogue sensor values after a Connect() call, -         and then subtracts them from future values, to remove any unwanted -         offsets (currently ~ +- 0-2.5kg with Balance Boards).  'raw' values -         are not affected. -          -         If the device was not at rest during Connect(), then the app can -          remove the current offsets manually via CalibrateAtRest(). -           -      + ** PRELIMINARY MOTION PLUS SUPPORT! ** -       -        Motion Plus does not report itself until queried, so it's currently -        queried every second.  If detected, it is activated and is reported -        like any other extension.  Note that extensions plugged into the -        MotionPlus itself can't currently be used at the same time (it's not -        known if this is even possible).  Right now you need to unplug the -        MotionPlus to use another extension (I will add some way to toggle -        the MotionPlus so that another extensions becomes available again) -        in the next release. -         -        According to this interview with the MotionPlus designers -         -        there are two gyro sensitivity modes, but this has not been reverse -        engineered yet.  Also I'm not 100% certain of the correctness of the -        values (although they seem right), or their actual scale (ie. how many -        degrees rotations per second do the float values actually represent)? -         -      + the Demo has been updated for both devices. -      + ReadMe has been updated with new relevant info. -         -1.12 BETA: -      + ** REMOVED ALL LIBRARY PROJECTS ** -         instead just add wiimote.cpp to your application and include the header -         as before (this removes all build/project related-problems, like matching -         the runtime/Unicode settings etc). -       -      + Balance Board is now working (thanks to Akihiko's donation of a board!) -      + added wiimote::IsBalanceBoard() (Balance Boards are detected as wiimotes -         with a permanent BALANCE_BOARD extension). -         NOTE: Balance Boards require the IN_BUTTONS_BALANCE_BOARD report type -               (see demo). -      + changed some of the wiimote_state extension enums to ID a wider variety. -      + no more invalid acceleration values from devices that don't support it. -      + fixed some project settings. -       -1.11 BETA: -      + new way to detect extensions (supposedly works on all of them, including -         wireless Nunchuks) - only tested on stock Nunchuk. -      + longer sleep after SetReportType (may help data not being reported). - -1.1 BETA: -      + beta Balance Board support! -      + better MinGW support:  (thanks Elmo) -          adds functional _ASSERT/TRACE/WARN/DEEP_TRACE macros -          non-MSYS dependent build option via 'make_mingw.bat'. -          Demo builds & works under MinGW. -      + directory reorganisation: -            - Each compiler has own project dir (VC2005/VC2005/MinGW), -              and equivialent lib/ sudir. -      + now ships with working VC2005 SP1 / VC2008 / MinGW libraries -         (and MinGW DLL). -      + library now compiles on Borland (thanks Griff) - demo may not. - -1.01a: (1.01 had incorrect version defines) -      + extensions now work when already connected before Connect(), -         & also when an EXT SetReportType() is used initially. -      + ** renamed wiimote_state::IR::dot::bVisible to 'bVisible'. ** -      + Disconnect() now waits for its threads to exit. -      +  made TRACE/WARN macros VC2005+ specific (as earlier VC versions don't -         support variable arg macros). -      + corrected wiimote.h Connect() comments (wiimote selection is 1-based, -         not 0-based) - -1.00: -    + ** major bug fix, write buffer was abused. ** might have caused various -         problems. -    + ** added delay to EnableIR(), fixed IR init problems for those that -         had them (thanks Cameron) **.  if you had to use your own delays -         to get things to work, try removing them now. -    + wiimote_state::classic_controller::buttons::TriggerL() / R were reversed -       (thanks Vico). -    + patch & Makefile for MSYS / MinGW (thanks Dario). -    + updated ReadMe. - -0.99b: -    + added support for the Guitar Hero controller (thanks Morgan). -       It's just a Classic Controller with a different ID and is read the same, -       but can be differentiated via wiimote_state::extension_type::CLASSIC_GUITAR. - -0.96b: -    + fix ClassicButtonNameFromBit[] -    + fix WIIYOURSELF_VERSION_MINOR2 - -0.95b: -    + Classic Controller button fixes (thanks Farshid). -    + sightly longer Sleep() in Reset() - hopefully fixes some reports of -       wiimote acceleration values not working. -     -0.94b: -    + deadzones weren't working. -     -0.93b: -    + ** compiled libs are now stored in /libs ** -    + ** up to 4 dots are now available in every IR mode ** -    + some 'state_change_flags' weren't quite generated correctly. -    - removed 'wiimote_state::polling' flags (redundant, flags are already -       returned via RefreshState()). -    + various internal improvements -     -0.92b: -    ** Polling changes ** -      - now need to call RefreshState() once before each polling pass (see -         header comments & demo). this was done to synchronise the threaded -         state updates, so that data integrity is guaranteed. -    ** Callback changes ** -      - combined 'wiimote_state_changed' and 'extension_state_changed' flags -         into 'state_change_flags -      - removed 'ExtensionChangedCallback' (only a single callback is used now) -      - added 'CallbackTriggerFlags' to minimize callback overhead -       (see header comments & demo) -    + added Reset() (see header comments) -    + button mask TRIGGER is now _B -     -    Demo: removed 'wiimote2' line (debug leftover) - -0.82b: -    ** code/demo failed pre-XP (HID writes require XP+).  code now detects -        HID write support dynamically. ** -    + tidied code & surpressed redundant warning (or just enable C++ exceptions). -    + Improved debug output (mainly DEEP_TRACE) -    + Connect() can now take (and defaults to) 'FIRST_AVAILABLE' as the wiimote -      index (see header comments). -    + 'wiimote_sample' is now auto-cleared on construction -    + Adjusted max 'theoretical' raw IR coord values (1023x767) to largest -       actually observed, to output full 0-1 float range. -    + **Inverted** IR X float coord to match traditional 'left = 0' convention -       (raw coords unaffected for now). -    + Added state recording ability to aid state/motion analysis.  See RecordState(); -    - removed RequestBatteryUpdate() (battery level is now periodically refreshed) -    - disabled ...CALIBRATION_CHANGED flags (not useful) -     -    Demo  : should now work pre-XP. -    ReadMe: added Wiimote/PC installation notes (MS stack is especially tricky). - -0.81b: -    + connection loss is now detected (via failed writes) -      + ConnectionWasLost() added -    + report modes renamed for clarity. -    + Connect(): added 'force_hidwrites' (for testing only). -    + Extension connections now seem to be reliable. -    + Battery is now periodically refreshed (also used for loss detection) -    + 'BatteryRaw' was set incorrectly -    + added 'wiimote::ClassicButtonNameFromBit[]' - -    + Demo   : Classic Controller data shown. -    + Demo   : IR dot sizes now reported when possible (only if extension  -               data isn't requested as they're not available then). -             -    + License: 'no harm' clause added. -    + ReadMe : added build notes etc. - -0.1b: -    First release.
\ No newline at end of file diff --git a/tracker-pt/wiiyourself/License.txt b/tracker-pt/wiiyourself/License.txt deleted file mode 100644 index fc41a9a0..00000000 --- a/tracker-pt/wiiyourself/License.txt +++ /dev/null @@ -1,42 +0,0 @@ -____________________________________________________________ - -  - WiiYourself! - native C++ Wiimote library  v1.15 -    (c) gl.tter 2007-10 - http://gl.tter.org -____________________________________________________________ - - LICENSE:  My Wiimote library is free for any use (including -            commercial), with the following conditions: - -1) You may not use it to harm anyone, directly or -    indirectly. * this includes, but is not limited to, any -    kind of direct or indirect MILITARY use or related -    research * -    -   (but bruising egos is fine ;). -    -2) Any distribution in binary form (ie. linked with your -   program) must include the following text in your -   distribiutions's documentation (ReadMe file, help file, -   About box and/or splash screen): - -   "contains WiiYourself! wiimote code by gl.tter -    http://gl.tter.org" - -3) Any distribution in source code form must keep all my -   copyright notices intact unmodified (you can add to -   them if you've made changes), and must include this -   license text (either include this file in your -   distribution, or paste its contents into your  -   distribution's own licence file). - -4) You may not use the code to produce a competing -    library, unless you rewrite all of it considerably -    (for example to convert it to another language, but -    you need to contact me for written permission first). -   -   Instead please contribute new features, fixes and ideas -    to my mailining list (see ReadMe.txt). -__ - -gl.tter  (http://gl.tter.org | glATr-i-lDOTnet) - diff --git a/tracker-pt/wiiyourself/ReadMe.txt b/tracker-pt/wiiyourself/ReadMe.txt deleted file mode 100644 index 85ca0034..00000000 --- a/tracker-pt/wiiyourself/ReadMe.txt +++ /dev/null @@ -1,202 +0,0 @@ -__________________________________________________________________ - -     - WiiYourself! - native C++ Wiimote library  v1.15 -       (c) gl.tter 2007-10 - http://gl.tter.org -__________________________________________________________________ - -This marks the likely-final release of my free & fully-featured - Wiimote native C++ library for Windows. - -Originally based on Brian Peek's 'Managed Wiimote Library' - (http://blogs.msdn.com/coding4fun/archive/2007/03/14/1879033.aspx) - I then rewrote and extended it considerably. - -There's no documentation - check Brian's article for a good -overview and general 'Wiimote with Windows' info - but the -source code has extensive comments, and the demo app should help -you make sense of it all.  Any questions, join my mailing list -(below). - -Check License.txt for the (few) conditions of use, and - History.txt for important changes from previous versions. -_____ - -Notes: - -  - the library consists only of wiimote.cpp & wiimote.h.  Simply add -     them to your project and include the header. - -  - VC 2005 & 2008 projects, and a MSYS makefile for MinGW for the -     demo program are included. -   -  -	for MSYS: -        at the MSYS prompt type:  make -f Makefile.MSYS -         (it will create a folder named MinGW whith the binaries -          and proper folder structure) -         -  - The Windows Driver Development Kit (WDK or DDK) is required to -     build (for the HID API).  It's a free download from MS page -     (no need to register).  Currently it's found here (or search -     for it on microsoft.com): -   -     'Windows Driver Kit (WDK) 7.1.0' -     http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx - -    Unfortunately it changes frequently so the instructions below -     may be wrong or incomplete.  Google or ask on my mailing -     list for help if needed: -      -        - add its 'inc' and 'inc/api' dirs to your include paths -         (make sure they are *above* other paths, ie. searched first) -         -        - add its 'lib/win7/i386' dir to your library paths. -      -    You can also use earlier versions known as the 'DDK'.  The parts -     of the HID API I use haven't changed in a long time.  These paths -     are usually used: -       -        - add 'inc/wxp' dir to your include paths (*above* others) -        - add 'lib/wxp/i386' to your library paths. -       -    Notes: -      - do _not_ add any 'STL' paths from the WDK/DDK as they can cause -         build problems. -      - the order of your include paths can be important.  If you placed -         them above the paths and are still getting compilation errors, -         try moving them around. -   -  - The library is Unicode-ready via <tchar.h> (see demo project). -   -  - if you're not using VC you need to link with these libraries: -        setupapi.lib -        winmm.lib -        hid.lib     (from the DDK) -__________________________   - -Wiimote installation notes: -   -  The Wiimote needs to be 'paired' (Bluetooth connected) with the -   PC before you can install/use it.  Pressing 1 & 2 simultaneously -   puts it into 'discoverable' mode for a few seconds (LEDs will -   flash - the number of LEDs reflects the battery level). -    -  It will be detected as 'Nintendo RVL-CNT-01'. -      -  Stack-specific instructions: - -  - Windows' built-in Bluetooth stack: - -    1) open up the Bluetooth control panel. -    2) press _and hold_ 1 & 2 on the wiimote (LEDs flash) until the -       installation is complete (otherwise the wiimote usually times -       out half-way through the procedure, and although it may seem -       to have installed it's never 'connected' and doesn't work). -    3) add a new device - it should find it. don't use a password. -    4) when the installation is fully complete, let go of 1&2. The -       Bluetooth panel should now show it 'connected'. -     -    if something goes wrong you need to uninstall it and try again. -     -    if you un-pair the wiimote later (see below), it seems you need -     to remove and install it all over again to get it to work (if you -     know a workaround, let me know). -        -  - Toshiba stack: - -    straight forward, press 1 & 2 on the Wiimote (you don't need to -    hold them if you're quick) and click 'New Connection'. -     -    once found, you can pair it anytime again by right-clicking its -     device icon (and pressing 1 & 2 as before) - you can also set up -     a desktop shortcut that enters discovery mode immediately. - -  - Widcomm stack: - -    1) Open 'My Bluetooth Places'. -    2) Press and hold 1 & 2 (until the process is complete). -    3) Click 'View Devices in Range'. -    4) Wiimote is detected as Nintendo RVL-CNT-01. -    5) Select it, then click 'Bluetooth Setup Wizard'. -    5) Click 'Skip' (no password). -    6) Now it should be connected (you can let go of 1 & 2). - -    Troubleshooting: -        - the device seems to be connected but the Demo can't find it -          (CreateFile() fails with error 5 'Access Denied'), -     or - it disconnects almost immediately after connection -     or - asks for a password a few seconds after connection - -     Try uninstalling all HID devices from Device Manager, and then -      redetecting them with 'Scan for hardware changes' (I had all -      these problems and that fixed it for me). - -  - Other stacks -   -    similar to the above (contribute instructions?) -     -   -  - Disconnect/un-pair to save power (any stack): - -    hold the Wiimote Power button for a few seconds - it automatically -    unpairs itself, re-enters pairing mode for a few seconds -    (flashing LEDs), then times out and (effecively) switches off. - -__________________________   - -Balance Boards notes: - -  Balance Boards are installed using the same procedure as wiimotes, by -   holding the 'Sync' button in the battery compartment.  The Bluetooth -   stack detectes them as 'Nintendo RVL-WBC-01'. - -  They report to the library as wiimotes, with a permanent BALANCE_BOARD -   extension.  They only have one button (A), and no IR/Acceleration/Rumble -   or Speaker support.  There is only one supported 'report type' so the -   library sets this automatically (see the demo for details). -    -   You can detect them with the wiimote::IsBalanceBoard() call. -    -   The boards tested so far all report up to ~ +-2.5KB weight offsets even -    where there is no weight placed on them (ie. 'at rest').  It is unknown -    if this is normal sensor inaccuracy/drift, or if the calibration values -    read from the board are interpreted incorrectly.  For now the library -    automatically subtracts the first incoming sensor values after a Connect() -    call from all future non-raw values (the raw values are never modified). -     -    The offsets used are exposed in wiimote_state::balance_board::AtRestKG. -    -    - if the board wasn't at rest during the Connect() call these offsets -       will be wrong - the app can measure them manually (when the board -       is at rest) by calling  wiimote::CalibrateAtRest(). - -__________________________   - -MotionPlus notes: - -  Once activated it's reported like any other extension, but needs to be -   manually enabled (see demo for an example): -      - Test first if it's connected via MotionPlusConnected() -      - Then call EnableMotionPlus() -      - It will then replace any other extension connected to it, unil you -         disable the Motion+ again with DisableMotionPlus(). -    -  The speed values are believed to be correct.  The calibration values are not -   yet understood, so the data is currently uncalibrated.   -    -  Some technical details are mentioned in this interview with the MotionPlus -   hardware/software engineers: -   http://uk.wii.com/wii/en_GB/software/iwata_asks_motionplus_volume_1_2162.html#top -    - -  * Special thanks to the guys at WiiBrew.org, and all contributing hackers * -    for figuring out & documenting the wiimote protocols: -    http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus -    - -Sign up to the mailing list to stay in the loop, exchange ideas or help each - other out: http://gl.tter.org/mailman/listinfo/wiiyourself_gl.tter.org -__ - -gl.tter  (glATr-i-lDOTnet) - - diff --git a/tracker-pt/wiiyourself/lang/nl_NL.ts b/tracker-pt/wiiyourself/lang/nl_NL.ts deleted file mode 100644 index 9e739505..00000000 --- a/tracker-pt/wiiyourself/lang/nl_NL.ts +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS> -<TS version="2.1" language="nl_NL"> -</TS> diff --git a/tracker-pt/wiiyourself/lang/ru_RU.ts b/tracker-pt/wiiyourself/lang/ru_RU.ts deleted file mode 100644 index f62cf2e1..00000000 --- a/tracker-pt/wiiyourself/lang/ru_RU.ts +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS> -<TS version="2.1" language="ru_RU"> -</TS> diff --git a/tracker-pt/wiiyourself/lang/stub.ts b/tracker-pt/wiiyourself/lang/stub.ts deleted file mode 100644 index 6401616d..00000000 --- a/tracker-pt/wiiyourself/lang/stub.ts +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS> -<TS version="2.1"> -</TS> diff --git a/tracker-pt/wiiyourself/wiimote.cpp b/tracker-pt/wiiyourself/wiimote.cpp deleted file mode 100644 index 46130cca..00000000 --- a/tracker-pt/wiiyourself/wiimote.cpp +++ /dev/null @@ -1,2806 +0,0 @@ -// _______________________________________________________________________________ -// -//	 - WiiYourself! - native C++ Wiimote library  v1.15 -//	  (c) gl.tter 2007-10 - http://gl.tter.org -// -//	  see License.txt for conditions of use.  see History.txt for change log. -// _______________________________________________________________________________ -// -//  wiimote.cpp  (tab = 4 spaces) - -// VC-specifics: -#ifdef _MSC_VER  - // disable warning "C++ exception handler used, but unwind semantics are not enabled." - //				     in <xstring> (I don't use it - or just enable C++ exceptions) -# pragma warning(disable: 4530) -//  auto-link with the necessary libs -# pragma comment(lib, "setupapi.lib")	 -# pragma comment(lib, "hid.lib")		// for HID API (from DDK) -# pragma comment(lib, "winmm.lib")		// for timeGetTime() -#endif // _MSC_VER - -#include "wiimote.h" -#include <setupapi.h> -extern "C" { -# ifdef __MINGW32__ -#  include <ddk/hidsdi.h>// from WinDDK -# else -#  include <hidsdi.h> -# endif -} -#include <sys/types.h>	// for _stat -#include <sys/stat.h>	// " -#include <process.h>	// for _beginthreadex() -#ifdef __BORLANDC__ -# include <cmath.h>		// for orientation -#else -# include <math.h>		// " -#endif -#include <mmreg.h>		// for WAVEFORMATEXTENSIBLE -#include <mmsystem.h>	// for timeGetTime() - -// apparently not defined in some compilers: -#ifndef min -# define min(a,b)	(((a) < (b)) ? (a) : (b)) -#endif -// ------------------------------------------------------------------------------------ -// helpers -// ------------------------------------------------------------------------------------ -template<class T> inline T sign  (const T& val)  { return (val<0)? T(-1) : T(1); } -template<class T> inline T square(const T& val)  { return val*val; } -#define ARRAY_ENTRIES(array)	(sizeof(array)/sizeof(array[0])) - -// ------------------------------------------------------------------------------------ -//  Tracing & Debugging -// ------------------------------------------------------------------------------------ -#define PREFIX	_T("WiiYourself! : ") - -// comment these to auto-strip their code from the library: -//  (they currently use OutputDebugString() via _TRACE() - change to suit) -#if (_MSC_VER >= 1400) // VC 2005+ (earlier versions don't support variable args) -# define TRACE(fmt, ...) _TRACE(PREFIX          fmt          _T("\n"), __VA_ARGS__) -# define WARN(fmt, ...)  _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n"), __VA_ARGS__) -#elif defined(__MINGW32__) -# define TRACE(fmt, ...) _TRACE(PREFIX          fmt          _T("\n") , ##__VA_ARGS__) -# define WARN(fmt, ...)  _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n") , ##__VA_ARGS__) -#endif -// uncomment any of these for deeper debugging: -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n"), __VA_ARGS__)    // VC 2005+ -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n") , ##__VA_ARGS__) // mingw -//#define BEEP_DEBUG_READS -//#define BEEP_DEBUG_WRITES -//#define BEEP_ON_ORIENTATION_ESTIMATE -//#define BEEP_ON_PERIODIC_STATUSREFRESH - -// internals: auto-strip code from the macros if they weren't defined -#ifndef TRACE -# define TRACE -#endif -#ifndef DEEP_TRACE -# define DEEP_TRACE -#endif -#ifndef WARN -# define WARN -#endif -// ------------------------------------------------------------------------------------ -static void _cdecl _TRACE (const TCHAR* fmt, ...) -	{ -	static TCHAR buffer[256]; -	if (!fmt) return; - -	va_list	 argptr; -	va_start (argptr, fmt); -#if (_MSC_VER >= 1400) // VC 2005+ -	_vsntprintf_s(buffer, ARRAY_ENTRIES(buffer), _TRUNCATE, fmt, argptr); -#else -	_vsntprintf  (buffer, ARRAY_ENTRIES(buffer),			 fmt, argptr); -#endif -	va_end (argptr); - -	OutputDebugString(buffer); -	} - -// ------------------------------------------------------------------------------------ -//  wiimote -// ------------------------------------------------------------------------------------ -// class statics -HMODULE		   wiimote::HidDLL				  = NULL; -unsigned	   wiimote::_TotalCreated		  = 0; -unsigned	   wiimote::_TotalConnected		  = 0; -hidwrite_ptr   wiimote::_HidD_SetOutputReport = NULL; - -// (keep in sync with 'speaker_freq'): -const unsigned wiimote::FreqLookup [TOTAL_FREQUENCIES] =  -								{    0, 4200, 3920, 3640, 3360, -								  3130,	2940, 2760, 2610, 2470 }; - -const TCHAR*   wiimote::ButtonNameFromBit		 [TOTAL_BUTTON_BITS] = -								{ _T("Left") , _T("Right"), _T("Down"), _T("Up"), -								  _T("Plus") , _T("??")   , _T("??")  , _T("??") , -								  _T("Two")  , _T("One")  , _T("B")   , _T("A") , -								  _T("Minus"), _T("??")   , _T("??")  , _T("Home") }; - -const TCHAR*   wiimote::ClassicButtonNameFromBit [TOTAL_BUTTON_BITS] = -								{ _T("??")   , _T("TrigR")  , _T("Plus") , _T("Home"), -								  _T("Minus"), _T("TrigL") , _T("Down") , _T("Right") , -								  _T("Up")   , _T("Left")   , _T("ZR")   , _T("X") , -								  _T("A")    , _T("Y")      , _T("B")    , _T("ZL") }; -// ------------------------------------------------------------------------------------ -wiimote::wiimote () -	: -	DataRead			 (CreateEvent(NULL, FALSE, FALSE, NULL)), -	Handle				 (INVALID_HANDLE_VALUE), -	ReportType			 (IN_BUTTONS), -	bStatusReceived		 (false), // for output method detection -	bConnectInProgress	 (true ), -	bInitInProgress		 (false), -	bEnablingMotionPlus	 (false), -	bConnectionLost		 (false), // set if write fails after connection -	bMotionPlusDetected	 (false), -	bMotionPlusEnabled	 (false), -	bMotionPlusExtension (false), -	bCalibrateAtRest	 (false), -	bUseHIDwrite		 (false), // if OS supports it -	ChangedCallback		 (NULL), -	CallbackTriggerFlags (CHANGED_ALL), -	InternalChanged		 (NO_CHANGE), -	CurrentSample		 (NULL), -	HIDwriteThread		 (NULL), -	ReadParseThread		 (NULL), -	SampleThread		 (NULL), -	AsyncRumbleThread	 (NULL), -	AsyncRumbleTimeout	 (0), -	UniqueID			 (0)	// not _guaranteed_ unique, see comments in header -#ifdef ID2_FROM_DEVICEPATH		// (see comments in header) -	// UniqueID2			 (0)	 -#endif -	{ -	_ASSERT(DataRead != INVALID_HANDLE_VALUE); -				 -	// if this is the first wiimote object, detect & enable HID write support -	if(++_TotalCreated == 1) -		{ -		HidDLL = LoadLibrary(_T("hid.dll")); -		_ASSERT(HidDLL); -		if(!HidDLL) -			WARN(_T("Couldn't load hid.dll - shouldn't happen!")); -		else{ -			_HidD_SetOutputReport = (hidwrite_ptr) -									GetProcAddress(HidDLL, "HidD_SetOutputReport"); -			if(_HidD_SetOutputReport) -				TRACE(_T("OS supports HID writes.")); -			else -				TRACE(_T("OS doesn't support HID writes.")); -			} -		} - -	// clear our public and private state data completely (including deadzones) -	Clear		  (true); -	Internal.Clear(true); - -	// and the state recording vars -	memset(&Recording, 0, sizeof(Recording)); - -	// for overlapped IO (Read/WriteFile) -	memset(&Overlapped, 0, sizeof(Overlapped)); -	Overlapped.hEvent	  = DataRead; -	Overlapped.Offset	  = -	Overlapped.OffsetHigh = 0; - -	// for async HID output method -	InitializeCriticalSection(&HIDwriteQueueLock); -	// for polling -	InitializeCriticalSection(&StateLock); - -	// request millisecond timer accuracy -	timeBeginPeriod(1);		 -	} -// ------------------------------------------------------------------------------------ -wiimote::~wiimote () -	{ -	Disconnect(); - -	// events & critical sections are kept open for the lifetime of the object, -	//  so tidy them up here: -	if(DataRead != INVALID_HANDLE_VALUE) -		CloseHandle(DataRead); - -	DeleteCriticalSection(&HIDwriteQueueLock); -	DeleteCriticalSection(&StateLock); - -	// tidy up timer accuracy request -	timeEndPeriod(1);		 - -	// release HID DLL (for dynamic HID write method) -	if((--_TotalCreated == 0) && HidDLL) -		{ -		FreeLibrary(HidDLL); -		HidDLL				  = NULL; -		_HidD_SetOutputReport = NULL; -		} -	} - -// ------------------------------------------------------------------------------------ -bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) -	{ -	if(wiimote_index == FIRST_AVAILABLE) -		TRACE(_T("Connecting first available Wiimote:")); -	else -		TRACE(_T("Connecting Wiimote %u:"), wiimote_index); - -	// auto-disconnect if user is being naughty -	if(IsConnected()) -		Disconnect(); - -	// get the GUID of the HID class -	GUID guid; -	HidD_GetHidGuid(&guid); - -	// get a handle to all devices that are part of the HID class -	// Brian: Fun fact:  DIGCF_PRESENT worked on my machine just fine.  I reinstalled -	//   Vista, and now it no longer finds the Wiimote with that parameter enabled... -	HDEVINFO dev_info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE);// | DIGCF_PRESENT); -	if(!dev_info) { -		WARN(_T("couldn't get device info")); -		return false; -		} - -	// enumerate the devices -	SP_DEVICE_INTERFACE_DATA didata; -	didata.cbSize = sizeof(didata); -	 -	unsigned index			= 0; -	unsigned wiimotes_found = 0; -	while(SetupDiEnumDeviceInterfaces(dev_info, NULL, &guid, index, &didata)) -		{ -		// get the buffer size for this device detail instance -		DWORD req_size = 0; -		SetupDiGetDeviceInterfaceDetail(dev_info, &didata, NULL, 0, &req_size, NULL); - -		// (bizarre way of doing it) create a buffer large enough to hold the -		//  fixed-size detail struct components, and the variable string size -		SP_DEVICE_INTERFACE_DETAIL_DATA *didetail = -								(SP_DEVICE_INTERFACE_DETAIL_DATA*) new BYTE[req_size]; -		_ASSERT(didetail); -		didetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - -		// now actually get the detail struct -		if(!SetupDiGetDeviceInterfaceDetail(dev_info, &didata, didetail, -											req_size, &req_size, NULL)) { -			WARN(_T("couldn't get devinterface info for %u"), index); -			break; -			} - -		// open a shared handle to the device to query it (this will succeed even -		//  if the wiimote is already Connect()'ed) -		DEEP_TRACE(_T(".. querying device %s"), didetail->DevicePath); -		Handle = CreateFile(didetail->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, -												  NULL, OPEN_EXISTING, 0, NULL); -		if(Handle == INVALID_HANDLE_VALUE) { -			DEEP_TRACE(_T(".... failed with err %x (probably harmless)."),  -					   GetLastError()); -			goto skip; -			} -	 -		// get the device attributes -		HIDD_ATTRIBUTES attrib; -		attrib.Size = sizeof(attrib); -		if(HidD_GetAttributes(Handle, &attrib)) -			{ -			// is this a wiimote? -			if((attrib.VendorID != VID) || (attrib.ProductID != PID)) -				goto skip; - -			// yes, but is it the one we're interested in? -			++wiimotes_found; -			if((wiimote_index != FIRST_AVAILABLE) && -			   (wiimote_index != wiimotes_found)) -				goto skip; - -			// the wiimote is installed, but it may not be currently paired: -			if(wiimote_index == FIRST_AVAILABLE) -				TRACE(_T(".. opening Wiimote %u:"), wiimotes_found); -			else -				TRACE(_T(".. opening:")); - - -			// re-open the handle, but this time we don't allow write sharing -			//  (that way subsequent calls can still _discover_ wiimotes above, but -			//   will correctly fail here if they're already connected) -			CloseHandle(Handle); -			 -			// note this also means that if another application has already opened -			//  the device, the library can no longer connect it (this may happen -			//  with software that enumerates all joysticks in the system, because -			//  even though the wiimote is not a standard joystick (and can't -			//  be read as such), it unfortunately announces itself to the OS -			//  as one.  The SDL library was known to do grab wiimotes like this. -			//  If you cannot stop the application from doing it, you may change the -			//  call below to open the device in full shared mode - but then the -			//  library can no longer detect if you've already connected a device -			//  and will allow you to connect it twice!  So be careful ... -			Handle = CreateFile(didetail->DevicePath, GENERIC_READ|GENERIC_WRITE, -													FILE_SHARE_READ| FILE_SHARE_WRITE, -													NULL, OPEN_EXISTING, -													FILE_FLAG_OVERLAPPED, NULL); -			if(Handle == INVALID_HANDLE_VALUE) { -				TRACE(_T(".... failed with err %x"), GetLastError()); -				goto skip; -				} - -			// clear the wiimote state & buffers -			Clear		  (false);		// preserves existing deadzones -			Internal.Clear(false);		// " -			InternalChanged = NO_CHANGE; -			memset(ReadBuff , 0, sizeof(ReadBuff)); -			bConnectionLost	   = false; -			bConnectInProgress = true; // don't parse extensions or request regular -									   //  updates until complete -			// enable async reading -			BeginAsyncRead(); - -			// autodetect which write method the Bluetooth stack supports, -			//  by requesting the wiimote status report: -			if(force_hidwrites && !_HidD_SetOutputReport) { -				TRACE(_T(".. can't force HID writes (not supported)")); -				force_hidwrites = false; -				} - -			if(force_hidwrites) -				TRACE(_T(".. (HID writes forced)")); -			else{ -				//  - try WriteFile() first as it's the most efficient (it uses -				//     harware interrupts where possible and is async-capable): -				bUseHIDwrite = false; -				RequestStatusReport(); -				//  and wait for the report to arrive: -				DWORD last_time = timeGetTime(); -				while(!bStatusReceived && ((timeGetTime()-last_time) < 500)) -					Sleep(10); -				TRACE(_T(".. WriteFile() %s."), bStatusReceived? _T("succeeded") : -																 _T("failed")); -				} - -			// try HID write method (if supported) -			if(!bStatusReceived && _HidD_SetOutputReport) -				{ -				bUseHIDwrite = true; -				RequestStatusReport(); -				// wait for the report to arrive: -				DWORD last_time = timeGetTime(); -				while(!bStatusReceived && ((timeGetTime()-last_time) < 500)) -					Sleep(10); -				// did we get it? -				TRACE(_T(".. HID write %s."), bStatusReceived? _T("succeeded") : -															   _T("failed")); -				} - -			// still failed? -			if(!bStatusReceived) { -				WARN(_T("output failed - wiimote is not connected (or confused).")); -				Disconnect(); -				goto skip; -				} - -//Sleep(500); -			// reset it -			Reset(); - -			// read the wiimote calibration info -			ReadCalibration(); - -			// allow the result(s) to come in (so that the caller can immediately test -			//  MotionPlusConnected() -			Sleep(300); // note, don't need it on my system, better to be safe though - -			// connected succesfully: -			_TotalConnected++; - -			// use the first incomding analogue sensor values as the 'at rest' -			//  offsets (only supports the Balance Board currently) -			bCalibrateAtRest = true; - -			// refresh the public state from the internal one (so that everything -			//  is available straight away -			RefreshState(); - -			// attempt to construct a unique hardware ID from the calibration -			//  data bytes (this is obviously not guaranteed to be unique across -			//  all devices, but may work fairly well in practice... ?) -			memcpy(&UniqueID, &CalibrationInfo, sizeof(CalibrationInfo)); - -			_ASSERT(UniqueID != 0); // if this fires, the calibration data didn't -									//  arrive - this shouldn't happen - -#ifdef ID2_FROM_DEVICEPATH		// (see comments in header) -			// create a 2nd alternative id by simply adding all the characters -			//  in the device path to create a single number -			UniqueID2 = 0; -			for(unsigned index=0; index<_tcslen(didetail->DevicePath); index++) -				UniqueID2 += didetail->DevicePath[index]; -#endif -			// and show when we want to trigger the next periodic status request -			//  (for battery level and connection loss detection) -			NextStatusTime		= timeGetTime() + REQUEST_STATUS_EVERY_MS; -			NextMPlusDetectTime = timeGetTime() + DETECT_MPLUS_EVERY_MS; -			MPlusDetectCount	= DETECT_MPLUS_COUNT; - -			// tidy up -			delete[] (BYTE*)didetail; -			break; -			} -skip: -		// tidy up -		delete[] (BYTE*)didetail; - -		if(Handle != INVALID_HANDLE_VALUE) { -			CloseHandle(Handle); -			Handle = INVALID_HANDLE_VALUE; -			} -		// if this was the specified wiimote index, abort -		if((wiimote_index != FIRST_AVAILABLE) && -		   (wiimote_index == (wiimotes_found-1))) -		   break; - -		index++; -		} - -	// clean up our list -	SetupDiDestroyDeviceInfoList(dev_info); - -	bConnectInProgress = false; -	if(IsConnected()) { -		TRACE(_T(".. connected!")); -		// notify the callbacks (if requested to do so) -		if(CallbackTriggerFlags & CONNECTED) -			{ -			ChangedNotifier(CONNECTED, Internal); -			if(ChangedCallback) -				ChangedCallback(*this, CONNECTED, Internal); -			} -		return true; -		} -	TRACE(_T(".. connection failed.")); -	return false; -	} -// ------------------------------------------------------------------------------------ -void wiimote::CalibrateAtRest () -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return; - -	// the app calls this to remove 'at rest' offsets from the analogue sensor -	//  values (currently only works for the Balance Board): -	if(IsBalanceBoard()) { -		TRACE(_T(".. removing 'at rest' BBoard offsets.")); -		Internal.BalanceBoard.AtRestKg = Internal.BalanceBoard.Kg; -		RefreshState(); -		} -	} -// ------------------------------------------------------------------------------------ -void wiimote::Disconnect () -	{ -	if(Handle == INVALID_HANDLE_VALUE) -		return; - -	TRACE(_T("Disconnect().")); -	 -	if(IsConnected()) -		{ -		_ASSERT(_TotalConnected > 0); // sanity -		_TotalConnected--; -		 -		if(!bConnectionLost) -			Reset(); -		} - -	CloseHandle(Handle); -	Handle = INVALID_HANDLE_VALUE; -	UniqueID  = 0; -#ifdef ID2_FROM_DEVICEPATH		// (see comments in header) -	UniqueID2 = 0; -#endif - -	// close the read thread -	if(ReadParseThread) { -		// unblock it so it can realise we're closing and exit straight away -		SetEvent(DataRead); -		WaitForSingleObject(ReadParseThread, 3000); -		CloseHandle(ReadParseThread); -		ReadParseThread	= NULL; -		} -	// close the rumble thread -	if(AsyncRumbleThread) { -		WaitForSingleObject(AsyncRumbleThread, 3000); -		CloseHandle(AsyncRumbleThread); -		AsyncRumbleThread  = NULL; -		AsyncRumbleTimeout = 0; -		} -	// and the sample streaming thread -	if(SampleThread) { -		WaitForSingleObject(SampleThread, 3000); -		CloseHandle(SampleThread); -		SampleThread = NULL; -		} - -#ifndef USE_DYNAMIC_HIDQUEUE -	HID.Deallocate(); -#endif - -	bStatusReceived = false; - -	// and clear the state -	Clear		  (false); // (preserves deadzones) -	Internal.Clear(false); // " -	InternalChanged = NO_CHANGE; -	} -// ------------------------------------------------------------------------------------ -void wiimote::Reset () -	{ -	TRACE(_T("Resetting wiimote.")); -	 -	if(bMotionPlusEnabled) -		DisableMotionPlus(); - -	// stop updates (by setting report type to non-continuous, buttons-only) -	if(IsBalanceBoard()) -		SetReportType(IN_BUTTONS_BALANCE_BOARD, false); -	else -		SetReportType(IN_BUTTONS, false); - -	SetRumble	 (false); -	SetLEDs		 (0x00); -//	MuteSpeaker  (true); -	EnableSpeaker(false); - -	Sleep(150); // avoids loosing the extension calibration data on Connect() -	} -// ------------------------------------------------------------------------------------ -unsigned __stdcall wiimote::ReadParseThreadfunc (void* param) -	{ -	// this thread waits for the async ReadFile() to deliver data & parses it. -	//  it also requests periodic status updates, deals with connection loss -	//  and ends state recordings with a specific duration: -	_ASSERT(param); -	wiimote    &remote	   = *(wiimote*)param; -	OVERLAPPED &overlapped = remote.Overlapped; -	unsigned exit_code	   = 0; // (success) - -	while(1) -		{ -		// wait until the overlapped read completes, or the timeout is reached: -		DWORD wait = WaitForSingleObject(overlapped.hEvent, 500); - -		// before we deal with the result, let's do some housekeeping: - -		//  if we were recently Disconect()ed, exit now -		if(remote.Handle == INVALID_HANDLE_VALUE) { -			DEEP_TRACE(_T("read thread: wiimote was disconnected")); -			break; -			} -		//  ditto if the connection was lost (eg. through a failed write) -		if(remote.bConnectionLost) -			{ -connection_lost: -			TRACE(_T("read thread: connection to wiimote was lost")); -			remote.Disconnect(); -			remote.InternalChanged = (state_change_flags) -								(remote.InternalChanged | CONNECTION_LOST); -			// report via the callback (if any) -			if(remote.CallbackTriggerFlags & CONNECTION_LOST) -				{ -				remote.ChangedNotifier(CONNECTION_LOST, remote.Internal); -				if(remote.ChangedCallback) -					remote.ChangedCallback(remote, CONNECTION_LOST, remote.Internal); -				} -			break; -			} - -		DWORD time = timeGetTime(); -		//  periodic events (but not if we're streaming audio, -		//					 we don't want to cause a glitch) -		if(remote.IsConnected() && !remote.bInitInProgress && -		   !remote.IsPlayingAudio()) -			{ -			// status request due?  -			if(time > remote.NextStatusTime) -				{ -#ifdef BEEP_ON_PERIODIC_STATUSREFRESH -				Beep(2000,50); -#endif -				remote.RequestStatusReport(); -				// and schedule the next one -				remote.NextStatusTime = time + REQUEST_STATUS_EVERY_MS; -				} -			// motion plus detection due? -			if(!remote.IsBalanceBoard()		&& -//			   !remote.bConnectInProgress   && -			   !remote.bMotionPlusExtension && -			   (remote.Internal.ExtensionType != MOTION_PLUS) && -			   (remote.Internal.ExtensionType != PARTIALLY_INSERTED) && -			   (time > remote.NextMPlusDetectTime)) -				{ -				remote.DetectMotionPlusExtensionAsync(); -				// we try several times in quick succession before the next -				//  delay: -				if(--remote.MPlusDetectCount == 0) { -					remote.NextMPlusDetectTime = time + DETECT_MPLUS_EVERY_MS; -					remote.MPlusDetectCount    = DETECT_MPLUS_COUNT; -#ifdef _DEBUG -					TRACE(_T("--")); -#endif -					} -				} -			} - -		//  if we're state recording and have reached the specified duration, stop -		if(remote.Recording.bEnabled && (remote.Recording.EndTimeMS != UNTIL_STOP) && -		   (time >= remote.Recording.EndTimeMS)) -		   remote.Recording.bEnabled = false; - -		// now handle the wait result: -		//  did the wait time out? -		if(wait == WAIT_TIMEOUT) { -			DEEP_TRACE(_T("read thread: timed out")); -			continue; // wait again -			} -		//  did an error occurr? -		if(wait != WAIT_OBJECT_0) { -			DEEP_TRACE(_T("read thread: error waiting!")); -			remote.bConnectionLost = true; -			// deal with it straight away to avoid a longer delay -			goto connection_lost; -			} -	 -		// data was received: -#ifdef BEEP_DEBUG_READS -		Beep(500,1); -#endif -		DWORD read = 0; -		//  get the data read result -		GetOverlappedResult(remote.Handle, &overlapped, &read, TRUE); -		//  if we read data, parse it -		if(read) { -			DEEP_TRACE(_T("read thread: parsing data")); -			remote.OnReadData(read); -			} -		else -			DEEP_TRACE(_T("read thread: didn't get any data??")); -		} - -	TRACE(_T("(ending read thread)")); -#ifdef BEEP_DEBUG_READS -	if(exit_code != 0) -		Beep(200,1000); -#endif -	return exit_code; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::BeginAsyncRead () -	{ -	// (this is also called before we're fully connected) -	if(Handle == INVALID_HANDLE_VALUE) -		return false; - -	DEEP_TRACE(_T(".. starting async read")); -#ifdef BEEP_DEBUG_READS -	Beep(1000,1); -#endif - -	DWORD read; -	if (!ReadFile(Handle, ReadBuff, REPORT_LENGTH, &read, &Overlapped)) { -		DWORD err = GetLastError(); -		if(err != ERROR_IO_PENDING) { -			DEEP_TRACE(_T(".... ** ReadFile() failed! **")); -			return false; -			} -		} - -	// launch the completion wait/callback thread -	if(!ReadParseThread) { -		ReadParseThread = (HANDLE)_beginthreadex(NULL, 0, ReadParseThreadfunc, -												 this, 0, NULL); -		DEEP_TRACE(_T(".... creating read thread")); -		_ASSERT(ReadParseThread); -		if(!ReadParseThread) -			return false; -		SetThreadPriority(ReadParseThread, WORKER_THREAD_PRIORITY); -		} - -	// if ReadFile completed while we called, signal the thread to proceed -	if(read) { -		DEEP_TRACE(_T(".... got data right away")); -		SetEvent(DataRead); -		} -	return true; -	} -// ------------------------------------------------------------------------------------ -void wiimote::OnReadData (DWORD bytes_read) -	{ -	_ASSERT(bytes_read == REPORT_LENGTH); - -	// copy our input buffer -	BYTE buff [REPORT_LENGTH]; -	memcpy(buff, ReadBuff, bytes_read); - -	// start reading again -	BeginAsyncRead(); - -	// parse it -	ParseInput(buff); -	} -// ------------------------------------------------------------------------------------ -void wiimote::SetReportType (input_report type, bool continuous) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return; - -	// the balance board only uses one type of report -	_ASSERT(!IsBalanceBoard() || type == IN_BUTTONS_BALANCE_BOARD); -	if(IsBalanceBoard() && (type != IN_BUTTONS_BALANCE_BOARD)) -		return; - -#ifdef TRACE -	#define TYPE2NAME(_type)	(type==_type)? _T(#_type) -	const TCHAR* name = TYPE2NAME(IN_BUTTONS)				: -						TYPE2NAME(IN_BUTTONS_ACCEL_IR)		: -						TYPE2NAME(IN_BUTTONS_ACCEL_EXT)		: -						TYPE2NAME(IN_BUTTONS_ACCEL_IR_EXT)	: -						TYPE2NAME(IN_BUTTONS_BALANCE_BOARD) : -						_T("(unknown??)"); -	TRACE(_T("ReportType: %s (%s)"), name, (continuous? _T("continuous") : -														_T("non-continuous"))); -#endif -	ReportType = type; - -	switch(type) -		{ -		case IN_BUTTONS_ACCEL_IR: -			EnableIR(wiimote_state::ir::EXTENDED); -			break; -		case IN_BUTTONS_ACCEL_IR_EXT: -			EnableIR(wiimote_state::ir::BASIC); -			break; -		default: -			DisableIR(); -			break; -		} - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_TYPE; -	buff[1] = (continuous ? 0x04 : 0x00) | GetRumbleBit(); -	buff[2] = (BYTE)type; -	WriteReport(buff); -//	Sleep(15); -	} -// ------------------------------------------------------------------------------------ -void wiimote::SetLEDs (BYTE led_bits) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected() || bInitInProgress) -		return; - -	_ASSERT(led_bits <= 0x0f); -	led_bits &= 0xf; -	 -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_LEDs; -	buff[1] = (led_bits<<4) | GetRumbleBit(); -	WriteReport(buff); - -	Internal.LED.Bits = led_bits; -	} -// ------------------------------------------------------------------------------------ -void wiimote::SetRumble (bool on) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return; - -	if(Internal.bRumble == on) -		return; - -	Internal.bRumble = on; - -	// if we're streaming audio, we don't need to send a report (sending it makes -	// the audio glitch, and the rumble bit is sent with every report anyway) -	if(IsPlayingAudio()) -		return; - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_STATUS; -	buff[1] = on? 0x01 : 0x00; -	WriteReport(buff); -	} -// ------------------------------------------------------------------------------------ -unsigned __stdcall wiimote::AsyncRumbleThreadfunc (void* param) -	{ -	// auto-disables rumble after x milliseconds: -	_ASSERT(param); -	wiimote &remote = *(wiimote*)param; -	 -	while(remote.IsConnected()) -		{ -		if(remote.AsyncRumbleTimeout) -			{ -			DWORD current_time = timeGetTime(); -			if(current_time >= remote.AsyncRumbleTimeout) -				{ -				if(remote.Internal.bRumble) -					remote.SetRumble(false); -				remote.AsyncRumbleTimeout = 0; -				} -			Sleep(1); -			} -		else -			Sleep(4); -		} -	return 0; -	} -// ------------------------------------------------------------------------------------ -void wiimote::RumbleForAsync (unsigned milliseconds) -	{ -	// rumble for a fixed amount of time -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return; - -	SetRumble(true); - -	// show how long thread should wait to disable rumble again -	// (it it's currently rumbling it will just extend the time) -	AsyncRumbleTimeout = timeGetTime() + milliseconds; - -	// create the thread? -	if(AsyncRumbleThread) -		return; - -	AsyncRumbleThread = (HANDLE)_beginthreadex(NULL, 0, AsyncRumbleThreadfunc, this, -											   0, NULL); -	_ASSERT(AsyncRumbleThread); -	if(!AsyncRumbleThread) { -		WARN(_T("couldn't create rumble thread!")); -		return; -		} -	SetThreadPriority(AsyncRumbleThread, WORKER_THREAD_PRIORITY); -	} -// ------------------------------------------------------------------------------------ -void wiimote::RequestStatusReport () -	{ -	// (this can be called before we're fully connected) -	_ASSERT(Handle != INVALID_HANDLE_VALUE); -	if(Handle == INVALID_HANDLE_VALUE) -		return; - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_STATUS; -	buff[1] = GetRumbleBit(); -	WriteReport(buff); -	} -// ------------------------------------------------------------------------------------ -bool wiimote::ReadAddress (int address, short size) -	{ -	// asynchronous -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_READMEMORY; -	buff[1] = (BYTE)(((address & 0xff000000) >> 24) | GetRumbleBit()); -	buff[2] = (BYTE)( (address & 0x00ff0000) >> 16); -	buff[3] = (BYTE)( (address & 0x0000ff00) >>  8); -	buff[4] = (BYTE)( (address & 0x000000ff)); -	buff[5] = (BYTE)( (size	   & 0xff00	   ) >>  8); -	buff[6] = (BYTE)( (size	   & 0xff)); -	return WriteReport(buff); -	} -// ------------------------------------------------------------------------------------ -void wiimote::WriteData (int address, BYTE size, const BYTE* buff) -	{ -	// asynchronous -	BYTE write [REPORT_LENGTH] = {0}; -	write[0] = OUT_WRITEMEMORY; -	write[1] = (BYTE)(((address & 0xff000000) >> 24) | GetRumbleBit()); -	write[2] = (BYTE)( (address & 0x00ff0000) >> 16); -	write[3] = (BYTE)( (address & 0x0000ff00) >>  8); -	write[4] = (BYTE)( (address & 0x000000ff)); -	write[5] = size; -	memcpy(write+6, buff, size); -	WriteReport(write); -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseInput (BYTE* buff) -	{ -	int changed = 0; - -	// lock our internal state (so RefreshState() is blocked until we're done -	EnterCriticalSection(&StateLock); - -	switch(buff[0]) -		{ -		case IN_BUTTONS: -			DEEP_TRACE(_T(".. parsing buttons.")); -			changed |= ParseButtons(buff); -			break; - -		case IN_BUTTONS_ACCEL: -			DEEP_TRACE(_T(".. parsing buttons/accel.")); -			changed |= ParseButtons(buff); -			if(!IsBalanceBoard()) -				changed |= ParseAccel(buff); -			break; - -		case IN_BUTTONS_ACCEL_EXT: -			DEEP_TRACE(_T(".. parsing extenion/accel.")); -			changed |= ParseButtons(buff); -			changed |= ParseExtension(buff, 6); -			if(!IsBalanceBoard()) -				changed |= ParseAccel(buff); -			break; - -		case IN_BUTTONS_ACCEL_IR: -			DEEP_TRACE(_T(".. parsing ir/accel.")); -			changed |= ParseButtons(buff); -			if(!IsBalanceBoard()) { -				changed |= ParseAccel(buff); -				changed |= ParseIR(buff); -				} -			break; - -		case IN_BUTTONS_ACCEL_IR_EXT: -			DEEP_TRACE(_T(".. parsing ir/extenion/accel.")); -			changed |= ParseButtons(buff); -			changed |= ParseExtension(buff, 16); -			if(!IsBalanceBoard()) { -				changed |= ParseAccel(buff); -				changed |= ParseIR	   (buff); -				} -			break; - -		case IN_BUTTONS_BALANCE_BOARD: -			DEEP_TRACE(_T(".. parsing buttson/balance.")); -			changed |= ParseButtons(buff); -			changed |= ParseExtension(buff, 3); -			break; - -		case IN_READADDRESS: -			DEEP_TRACE(_T(".. parsing read address.")); -			changed |= ParseButtons	   (buff); -			changed |= ParseReadAddress(buff); -			break; - -		case IN_STATUS: -			DEEP_TRACE(_T(".. parsing status.")); -			changed |= ParseStatus(buff); -			// show that we received the status report (used for output method -			//  detection during Connect()) -			bStatusReceived = true; -			break; -		 -		default: -			DEEP_TRACE(_T(".. ** unknown input ** (happens).")); -			///_ASSERT(0); -			//Debug.WriteLine("Unknown report type: " + type.ToString()); -			LeaveCriticalSection(&StateLock); -			return false; -		} - -	// if we're recording and some state we care about has changed, insert it into -	//  the state history -	if(Recording.bEnabled && (changed & Recording.TriggerFlags)) -		{ -		DEEP_TRACE(_T(".. adding state to history")); -		state_event event; -		event.time_ms = timeGetTime(); -		event.state	  = *(wiimote_state*)this; -		Recording.StateHistory->push_back(event); -		} - -	// for polling: show which state has changed since the last RefreshState() -	InternalChanged = (state_change_flags)(InternalChanged | changed); - -	LeaveCriticalSection(&StateLock); - -	// callbacks: call it (if set & state the app is interested in has changed) -	if(changed & CallbackTriggerFlags) -		{ -		DEEP_TRACE(_T(".. calling state change callback")); -		ChangedNotifier((state_change_flags)changed, Internal); -		if(ChangedCallback) -			ChangedCallback(*this, (state_change_flags)changed, Internal); -		} -	 -	DEEP_TRACE(_T(".. parse complete.")); -	return true; -	} -// ------------------------------------------------------------------------------------ -state_change_flags wiimote::RefreshState () -	{ -	// nothing changed since the last call? -	if(InternalChanged == NO_CHANGE) -		return NO_CHANGE; - -	// copy the internal state to our public data members: -	//  synchronise the interal state with the read/parse thread (we don't want -	//   values changing during the copy) -	EnterCriticalSection(&StateLock); -	 -	// remember which state changed since the last call -	state_change_flags changed = InternalChanged; -	 -	// preserve the application-set deadzones (if any) -	joystick::deadzone nunchuk_deadzone	     = Nunchuk.Joystick.DeadZone; -	joystick::deadzone classic_joyl_deadzone = ClassicController.JoystickL.DeadZone; -	joystick::deadzone classic_joyr_deadzone = ClassicController.JoystickR.DeadZone; -		 -	 // copy the internal state to the public one -	*(wiimote_state*)this = Internal; -	InternalChanged		  = NO_CHANGE; -	  -	 // restore the application-set deadzones -	Nunchuk.Joystick.DeadZone			 = nunchuk_deadzone; -	ClassicController.JoystickL.DeadZone = classic_joyl_deadzone; -	ClassicController.JoystickR.DeadZone = classic_joyr_deadzone; - -	LeaveCriticalSection(&StateLock); -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -void wiimote::DetectMotionPlusExtensionAsync () -	{ -#ifdef _DEBUG -	TRACE(_T("(looking for motion plus)")); -#endif -	// show that we're expecting the result shortly -	MotionPlusDetectCount++; -	// MotionPLus reports at a different address than other extensions (until -	//  activated, when it maps itself into the usual extension registers), so -	//  try to detect it first: -	ReadAddress(REGISTER_MOTIONPLUS_DETECT, 6); -	} -// ------------------------------------------------------------------------------------ -bool wiimote::EnableMotionPlus () -	{ -	_ASSERT(bMotionPlusDetected); -	if(!bMotionPlusDetected) -		return false; -	if(bMotionPlusEnabled) -		return true; - -	TRACE(_T("Enabling Motion Plus:")); -	 -	bMotionPlusExtension = false; -	bInitInProgress		 = true; -	bEnablingMotionPlus	 = true; - -	// Initialize it: -	WriteData(REGISTER_MOTIONPLUS_INIT  , 0x55); -//	Sleep(50); -	// Enable it (this maps it to the standard extension port): -	WriteData(REGISTER_MOTIONPLUS_ENABLE, 0x04); -//	Sleep(50); -Sleep(500); -	return true; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::DisableMotionPlus () -	{ - 	if(!bMotionPlusDetected || !bMotionPlusEnabled) -		return false; - -	TRACE(_T("Disabling Motion Plus:")); - -	// disable it (this makes standard extensions visible again) -	WriteData(REGISTER_EXTENSION_INIT1, 0x55); -	return true; -	} -// ------------------------------------------------------------------------------------ -void wiimote::InitializeExtension () -	{ -	TRACE(_T("Initialising Extension.")); -	// wibrew.org: The new way to initialize the extension is by writing 0x55 to -	//	0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. It works on all extensions, and -	//  makes the extension type bytes unencrypted. This means that you no longer have -	//  to decrypt the extension bytes using the transform listed above.  -	bInitInProgress = true; -_ASSERT(Internal.bExtension); -	// only initialize if it's not a MotionPlus -	if(!bEnablingMotionPlus) { -		WriteData  (REGISTER_EXTENSION_INIT1, 0x55); -		WriteData  (REGISTER_EXTENSION_INIT2, 0x00); -		} -	else -		bEnablingMotionPlus = false; -	 -	ReadAddress(REGISTER_EXTENSION_TYPE , 6); -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseStatus (BYTE* buff) -	{ -	// parse the buttons -	int changed = ParseButtons(buff); -			 -	// get the battery level -	BYTE battery_raw = buff[6]; -	if(Internal.BatteryRaw != battery_raw) -		changed |= BATTERY_CHANGED; -	Internal.BatteryRaw	 = battery_raw; -	// it is estimated that ~200 is the maximum battery level -	Internal.BatteryPercent = battery_raw / 2; - -	// there is also a flag that shows if the battery is nearly empty -	bool drained = buff[3] & 0x01; -	if(drained != bBatteryDrained) -		{ -		bBatteryDrained = drained; -		if(drained) -			changed |= BATTERY_DRAINED; -		} - -	// leds -	BYTE leds = buff[3] >> 4; -	if(leds != Internal.LED.Bits) -		changed |= LEDS_CHANGED; -	Internal.LED.Bits = leds; - -	// don't handle extensions until a connection is complete -//	if(bConnectInProgress) -//		return changed; - -	bool extension = ((buff[3] & 0x02) != 0); -//	TRACE(_T("(extension = %s)"), (extension? _T("TRUE") : _T("false"))); - -	if(extension != Internal.bExtension) -		{ -		if(!Internal.bExtension) -			{ -			TRACE(_T("Extension connected:")); -			Internal.bExtension = true; -			InitializeExtension(); -			} -		else{ -			TRACE(_T("Extension disconnected.")); -			Internal.bExtension	   = false; -			Internal.ExtensionType = wiimote_state::NONE; -			bMotionPlusEnabled	   = false; -			bMotionPlusExtension   = false; -			bMotionPlusDetected	   = false; -			bInitInProgress		   = false; -			bEnablingMotionPlus	   = false; -			changed				  |= EXTENSION_DISCONNECTED; -			// renable reports -//			SetReportType(ReportType); -			} -		} -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseButtons (BYTE* buff) -	{ -	int changed = 0; -	 -//	WORD bits = *(WORD*)(buff+1); -	WORD bits = *(WORD*)(buff+1) & Button.ALL; - -	if(bits != Internal.Button.Bits) -		changed |= BUTTONS_CHANGED; -	Internal.Button.Bits = bits; -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::EstimateOrientationFrom (wiimote_state::acceleration &accel) -	{ -	// Orientation estimate from acceleration data (shared between wiimote and nunchuk) -	//  return true if the orientation was updated - -	//  assume the controller is stationary if the acceleration vector is near -	//  1g for several updates (this may not always be correct) -	float length_sq = square(accel.X) + square(accel.Y) + square(accel.Z); - -	// TODO: as I'm comparing _squared_ length, I really need different -	//		  min/max epsilons... -	#define DOT(x1,y1,z1, x2,y2,z2)	((x1*x2) + (y1*y2) + (z1*z2)) - -	static const float epsilon = 0.2f; -	if((length_sq >= (1.f-epsilon)) && (length_sq <= (1.f+epsilon))) -		{ -		if(++WiimoteNearGUpdates < 2) -			return false; -		 -		// wiimote seems to be stationary:  normalize the current acceleration -		//  (ie. the assumed gravity vector) -		float inv_len = 1.f / sqrt(length_sq); -		float x = accel.X * inv_len; -		float y = accel.Y * inv_len; -		float z = accel.Z * inv_len; - -		// copy the values -		accel.Orientation.X = x; -		accel.Orientation.Y = y; -		accel.Orientation.Z = z; - -		// and extract pitch & roll from them: -		// (may not be optimal) -		float pitch = -asin(y)    * 57.2957795f; -//		float roll  =  asin(x)    * 57.2957795f; -        float roll  =  atan2(x,z) * 57.2957795f; -		if(z < 0) { -			pitch = (y < 0)?  180 - pitch : -180 - pitch; -			roll  = (x < 0)? -180 - roll  :  180 - roll; -			} - -		accel.Orientation.Pitch = pitch; -		accel.Orientation.Roll  = roll; - -		// show that we just updated orientation -		accel.Orientation.UpdateAge = 0; -#ifdef BEEP_ON_ORIENTATION_ESTIMATE -		Beep(2000, 1); -#endif -		return true; // updated -		} - -	// not updated this time: -	WiimoteNearGUpdates	= 0; -	// age the last orientation update -	accel.Orientation.UpdateAge++; -	return false; -	} -// ------------------------------------------------------------------------------------ -void wiimote::ApplyJoystickDeadZones (wiimote_state::joystick &joy) -	{ -	// apply the deadzones to each axis (if set) -	if((joy.DeadZone.X > 0.f) && (joy.DeadZone.X <= 1.f)) -		{ -		if(fabs(joy.X) <= joy.DeadZone.X) -			joy.X = 0; -		else{ -			joy.X -= joy.DeadZone.X * sign(joy.X); -			joy.X /= 1.f - joy.DeadZone.X; -			} -		} -	if((joy.DeadZone.Y > 0.f) && (joy.DeadZone.Y <= 1.f)) -		{ -		if(fabs(joy.Y) <= joy.DeadZone.Y) -			joy.Y = 0; -		else{ -			joy.Y -= joy.DeadZone.Y * sign(joy.Y); -			joy.Y /= 1.f - joy.DeadZone.Y; -			} -		} -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseAccel (BYTE* buff) -	{ -	int changed = 0; -	 -	BYTE raw_x = buff[3]; -	BYTE raw_y = buff[4]; -	BYTE raw_z = buff[5]; - -	if((raw_x != Internal.Acceleration.RawX) || -	   (raw_y != Internal.Acceleration.RawY) || -	   (raw_z != Internal.Acceleration.RawZ)) -	   changed |= ACCEL_CHANGED; -	 -	Internal.Acceleration.RawX = raw_x; -	Internal.Acceleration.RawY = raw_y; -	Internal.Acceleration.RawZ = raw_z; - -	// avoid / 0.0 when calibration data hasn't arrived yet -	if(Internal.CalibrationInfo.X0) -		{ -		Internal.Acceleration.X = -					((float)Internal.Acceleration.RawX  - Internal.CalibrationInfo.X0) /  -					((float)Internal.CalibrationInfo.XG - Internal.CalibrationInfo.X0); -		Internal.Acceleration.Y = -					((float)Internal.Acceleration.RawY  - Internal.CalibrationInfo.Y0) / -					((float)Internal.CalibrationInfo.YG - Internal.CalibrationInfo.Y0); -		Internal.Acceleration.Z = -					((float)Internal.Acceleration.RawZ  - Internal.CalibrationInfo.Z0) / -					((float)Internal.CalibrationInfo.ZG - Internal.CalibrationInfo.Z0); -		} -	else{ -		Internal.Acceleration.X = -		Internal.Acceleration.Y = -		Internal.Acceleration.Z = 0.f; -		} - -	// see if we can estimate the orientation from the current values -	if(EstimateOrientationFrom(Internal.Acceleration)) -		changed |= ORIENTATION_CHANGED; -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseIR (BYTE* buff) -	{ -	if(Internal.IR.Mode == wiimote_state::ir::OFF) -		return NO_CHANGE; - -	// avoid garbage values when the MotionPlus is enabled, but the app is -	//  still using the extended IR report type -	if(bMotionPlusEnabled && (Internal.IR.Mode == wiimote_state::ir::EXTENDED)) -		return NO_CHANGE; - -	// take a copy of the existing IR state (so we can detect changes) -	wiimote_state::ir prev_ir = Internal.IR; - -	// only updates the other values if the dots are visible (so that the last -	//  valid values stay unmodified) -	switch(Internal.IR.Mode) -		{ -		case wiimote_state::ir::BASIC: -			// 2 dots are encoded in 5 bytes, so read 2 at a time -			for(unsigned step=0; step<2; step++) -				{ -				ir::dot &dot0 = Internal.IR.Dot[step*2  ]; -				ir::dot &dot1 = Internal.IR.Dot[step*2+1]; -				const unsigned offs = 6 + (step*5); // 5 bytes for 2 dots - -				dot0.bVisible = !(buff[offs  ] == 0xff && buff[offs+1] == 0xff); -				dot1.bVisible = !(buff[offs+3] == 0xff && buff[offs+4] == 0xff); -			 -				if(dot0.bVisible) { -					dot0.RawX = buff[offs  ] | ((buff[offs+2] >> 4) & 0x03) << 8;; -					dot0.RawY = buff[offs+1] | ((buff[offs+2] >> 6) & 0x03) << 8;; -					dot0.X    = 1.f - (dot0.RawX / (float)wiimote_state::ir::MAX_RAW_X); -					dot0.Y    =	      (dot0.RawY / (float)wiimote_state::ir::MAX_RAW_Y); -					} -				if(dot1.bVisible) { -					dot1.RawX = buff[offs+3] | ((buff[offs+2] >> 0) & 0x03) << 8; -					dot1.RawY = buff[offs+4] | ((buff[offs+2] >> 2) & 0x03) << 8; -					dot1.X    = 1.f - (dot1.RawX / (float)wiimote_state::ir::MAX_RAW_X); -					dot1.Y    =	      (dot1.RawY / (float)wiimote_state::ir::MAX_RAW_Y); -					} -				} -			break; -		 -		case wiimote_state::ir::EXTENDED: -			// each dot is encoded into 3 bytes -			for(unsigned index=0; index<4; index++) -				{ -				ir::dot &dot = Internal.IR.Dot[index]; -				const unsigned offs = 6 + (index * 3); -			 -				dot.bVisible = !(buff[offs  ]==0xff && buff[offs+1]==0xff && -							   buff[offs+2]==0xff); -				if(dot.bVisible) { -					dot.RawX = buff[offs  ] | ((buff[offs+2] >> 4) & 0x03) << 8; -					dot.RawY = buff[offs+1] | ((buff[offs+2] >> 6) & 0x03) << 8; -					dot.X    = 1.f - (dot.RawX / (float)wiimote_state::ir::MAX_RAW_X); -					dot.Y    =	     (dot.RawY / (float)wiimote_state::ir::MAX_RAW_Y); -					dot.Size = buff[offs+2] & 0x0f; -					} -				} -			break; - -		case wiimote_state::ir::FULL: -			_ASSERT(0); // not supported yet; -			break; -		} - -	return memcmp(&prev_ir, &Internal.IR, sizeof(Internal.IR))? IR_CHANGED : 0; -	} -// ------------------------------------------------------------------------------------ -inline float wiimote::GetBalanceValue (short sensor, short min, short mid, short max) -	{ -	if(max == mid || mid == min) -		return 0; - -	float val = (sensor < mid)? -					68.0f * ((float)(sensor - min) / (mid - min)) : -					68.0f * ((float)(sensor - mid) / (max - mid)) + 68.0f; -	 -	// divide by four (so that each sensor is correct) -	return val * 0.25f; -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseExtension (BYTE *buff, unsigned offset) -	{ -	int changed = 0; -	 -	switch(Internal.ExtensionType) -		{ -		case wiimote_state::NUNCHUK: -			{ -			// buttons -			bool c = (buff[offset+5] & 0x02) == 0; -			bool z = (buff[offset+5] & 0x01) == 0; -			 -			if((c != Internal.Nunchuk.C) || (z != Internal.Nunchuk.Z)) -				changed |= NUNCHUK_BUTTONS_CHANGED; -			 -			Internal.Nunchuk.C = c; -			Internal.Nunchuk.Z = z; - -			// acceleration -			{ -			wiimote_state::acceleration &accel = Internal.Nunchuk.Acceleration; -			 -			BYTE raw_x = buff[offset+2]; -			BYTE raw_y = buff[offset+3]; -			BYTE raw_z = buff[offset+4]; -			if((raw_x != accel.RawX) || (raw_y != accel.RawY) || (raw_z != accel.RawZ)) -				changed |= NUNCHUK_ACCEL_CHANGED; - -			accel.RawX = raw_x; -			accel.RawY = raw_y; -			accel.RawZ = raw_z; - -			wiimote_state::nunchuk::calibration_info &calib = -													Internal.Nunchuk.CalibrationInfo; -			accel.X = ((float)raw_x - calib.X0) / ((float)calib.XG - calib.X0); -			accel.Y = ((float)raw_y - calib.Y0) / ((float)calib.YG - calib.Y0); -			accel.Z = ((float)raw_z - calib.Z0) / ((float)calib.ZG - calib.Z0); - -			// try to extract orientation from the accel: -			if(EstimateOrientationFrom(accel)) -				changed |= NUNCHUK_ORIENTATION_CHANGED; -			} -			{ -			// joystick: -			wiimote_state::joystick &joy = Internal.Nunchuk.Joystick; - -			float raw_x = buff[offset+0]; -			float raw_y = buff[offset+1]; -			 -			if((raw_x != joy.RawX) || (raw_y != joy.RawY)) -				changed |= NUNCHUK_JOYSTICK_CHANGED; - -			joy.RawX = raw_x; -			joy.RawY = raw_y; - -			// apply the calibration data -			wiimote_state::nunchuk::calibration_info &calib = -													Internal.Nunchuk.CalibrationInfo; -			if(Internal.Nunchuk.CalibrationInfo.MaxX != 0x00) -				joy.X = ((float)raw_x - calib.MidX) / ((float)calib.MaxX - calib.MinX); -			if(calib.MaxY != 0x00) -				joy.Y = ((float)raw_y - calib.MidY) / ((float)calib.MaxY - calib.MinY); - -			// i prefer the outputs to range -1 - +1 (note this also affects the -			//  deadzone calculations) -			joy.X *= 2;	joy.Y *= 2; - -			// apply the public deadzones to the internal state (if set) -			joy.DeadZone = Nunchuk.Joystick.DeadZone; -			ApplyJoystickDeadZones(joy); -			} -			} -			break; -		 -		case wiimote_state::CLASSIC: -		case wiimote_state::GH3_GHWT_GUITAR: -		case wiimote_state::GHWT_DRUMS: -			{ -			// buttons: -			WORD bits = *(WORD*)(buff+offset+4); -			bits = ~bits; // need to invert bits since 0 is down, and 1 is up - -			if(bits != Internal.ClassicController.Button.Bits) -				changed |= CLASSIC_BUTTONS_CHANGED; - -			Internal.ClassicController.Button.Bits = bits; - -			// joysticks: -			wiimote_state::joystick &joyL = Internal.ClassicController.JoystickL; -			wiimote_state::joystick &joyR = Internal.ClassicController.JoystickR; - -			float l_raw_x = (float) (buff[offset+0] & 0x3f); -			float l_raw_y = (float) (buff[offset+1] & 0x3f); -			float r_raw_x = (float)((buff[offset+2]		    >> 7) | -								   ((buff[offset+1] & 0xc0) >> 5) | -								   ((buff[offset+0] & 0xc0) >> 3)); -			float r_raw_y = (float) (buff[offset+2] & 0x1f); - -			if((joyL.RawX != l_raw_x) || (joyL.RawY != l_raw_y)) -				changed |= CLASSIC_JOYSTICK_L_CHANGED; -			if((joyR.RawX != r_raw_x) || (joyR.RawY != r_raw_y)) -				changed |= CLASSIC_JOYSTICK_R_CHANGED; - -			joyL.RawX = l_raw_x; joyL.RawY = l_raw_y; -			joyR.RawX = r_raw_x; joyR.RawY = r_raw_y; - -			// apply calibration -			wiimote_state::classic_controller::calibration_info &calib = -											Internal.ClassicController.CalibrationInfo; -			if(calib.MaxXL != 0x00) -				joyL.X = (joyL.RawX - calib.MidXL) / ((float)calib.MaxXL - calib.MinXL); -			if(calib.MaxYL != 0x00) -				joyL.Y = (joyL.RawY - calib.MidYL) / ((float)calib.MaxYL - calib.MinYL); -			if(calib.MaxXR != 0x00) -				joyR.X = (joyR.RawX - calib.MidXR) / ((float)calib.MaxXR - calib.MinXR); -			if(calib.MaxYR != 0x00) -				joyR.Y = (joyR.RawY - calib.MidYR) / ((float)calib.MaxYR - calib.MinYR); - -			// i prefer the joystick outputs to range -1 - +1 (note this also affects -			//  the deadzone calculations) -			joyL.X *= 2; joyL.Y *= 2; joyR.X *= 2; joyR.Y *= 2; - -			// apply the public deadzones to the internal state (if set) -			joyL.DeadZone = ClassicController.JoystickL.DeadZone; -			joyR.DeadZone = ClassicController.JoystickR.DeadZone; -			ApplyJoystickDeadZones(joyL); -			ApplyJoystickDeadZones(joyR); - -			// triggers -			BYTE raw_trigger_l = ((buff[offset+2] & 0x60) >> 2) | -								  (buff[offset+3]		  >> 5); -			BYTE raw_trigger_r =   buff[offset+3] & 0x1f; -			 -			if((raw_trigger_l != Internal.ClassicController.RawTriggerL) || -			   (raw_trigger_r != Internal.ClassicController.RawTriggerR)) -			   changed |= CLASSIC_TRIGGERS_CHANGED; -			 -			Internal.ClassicController.RawTriggerL  = raw_trigger_l; -			Internal.ClassicController.RawTriggerR  = raw_trigger_r; - -			if(calib.MaxTriggerL != 0x00) -				Internal.ClassicController.TriggerL = -									 (float)Internal.ClassicController.RawTriggerL /  -									((float)calib.MaxTriggerL -	calib.MinTriggerL); -			if(calib.MaxTriggerR != 0x00) -				Internal.ClassicController.TriggerR = -									 (float)Internal.ClassicController.RawTriggerR /  -									((float)calib.MaxTriggerR - calib.MinTriggerR); -			} -			break; - -		case BALANCE_BOARD: -			{ -			wiimote_state::balance_board::sensors_raw prev_raw = -														Internal.BalanceBoard.Raw; -			Internal.BalanceBoard.Raw.TopR	  = -						(short)((short)buff[offset+0] << 8 | buff[offset+1]); -			Internal.BalanceBoard.Raw.BottomR = -						(short)((short)buff[offset+2] << 8 | buff[offset+3]); -			Internal.BalanceBoard.Raw.TopL	  = -						(short)((short)buff[offset+4] << 8 | buff[offset+5]); -			Internal.BalanceBoard.Raw.BottomL = -						(short)((short)buff[offset+6] << 8 | buff[offset+7]); - -			if((Internal.BalanceBoard.Raw.TopL    != prev_raw.TopL)    || -			   (Internal.BalanceBoard.Raw.TopR    != prev_raw.TopR)    || -			   (Internal.BalanceBoard.Raw.BottomL != prev_raw.BottomL) || -			   (Internal.BalanceBoard.Raw.BottomR != prev_raw.BottomR)) -				changed |= BALANCE_WEIGHT_CHANGED; - -			Internal.BalanceBoard.Kg.TopL	 = -				GetBalanceValue(Internal.BalanceBoard.Raw.TopL, -								Internal.BalanceBoard.CalibrationInfo.Kg0 .TopL, -								Internal.BalanceBoard.CalibrationInfo.Kg17.TopL, -								Internal.BalanceBoard.CalibrationInfo.Kg34.TopL); -			Internal.BalanceBoard.Kg.TopR	 = -				GetBalanceValue(Internal.BalanceBoard.Raw.TopR, -								Internal.BalanceBoard.CalibrationInfo.Kg0 .TopR, -								Internal.BalanceBoard.CalibrationInfo.Kg17.TopR, -								Internal.BalanceBoard.CalibrationInfo.Kg34.TopR); -			Internal.BalanceBoard.Kg.BottomL = -				GetBalanceValue(Internal.BalanceBoard.Raw.BottomL, -								Internal.BalanceBoard.CalibrationInfo.Kg0 .BottomL, -								Internal.BalanceBoard.CalibrationInfo.Kg17.BottomL, -								Internal.BalanceBoard.CalibrationInfo.Kg34.BottomL); -			Internal.BalanceBoard.Kg.BottomR = -				GetBalanceValue(Internal.BalanceBoard.Raw.BottomR, -								Internal.BalanceBoard.CalibrationInfo.Kg0 .BottomR, -								Internal.BalanceBoard.CalibrationInfo.Kg17.BottomR, -								Internal.BalanceBoard.CalibrationInfo.Kg34.BottomR); -			 -			// uses these as the 'at rest' offsets? (immediately after Connect(), -			//  or if the app called CalibrateAtRest()) -			if(bCalibrateAtRest) { -				bCalibrateAtRest = false; -				TRACE(_T(".. Auto-removing 'at rest' BBoard offsets.")); -				Internal.BalanceBoard.AtRestKg = Internal.BalanceBoard.Kg; -				} - -			// remove the 'at rest' offsets -			Internal.BalanceBoard.Kg.TopL	 -= BalanceBoard.AtRestKg.TopL; -			Internal.BalanceBoard.Kg.TopR	 -= BalanceBoard.AtRestKg.TopR; -			Internal.BalanceBoard.Kg.BottomL -= BalanceBoard.AtRestKg.BottomL; -			Internal.BalanceBoard.Kg.BottomR -= BalanceBoard.AtRestKg.BottomR; - -			// compute the average -			Internal.BalanceBoard.Kg.Total	  = Internal.BalanceBoard.Kg.TopL    + -												Internal.BalanceBoard.Kg.TopR    + -												Internal.BalanceBoard.Kg.BottomL + -												Internal.BalanceBoard.Kg.BottomR; -			// and convert to Lbs -			const float KG2LB = 2.20462262f; -			Internal.BalanceBoard.Lb		  = Internal.BalanceBoard.Kg; -			Internal.BalanceBoard.Lb.TopL	 *= KG2LB; -			Internal.BalanceBoard.Lb.TopR	 *= KG2LB; -			Internal.BalanceBoard.Lb.BottomL *= KG2LB; -			Internal.BalanceBoard.Lb.BottomR *= KG2LB; -			Internal.BalanceBoard.Lb.Total	 *= KG2LB; -			} -			break; - -		case MOTION_PLUS: -			{ -			bMotionPlusDetected = true; -			bMotionPlusEnabled  = true; - -			short yaw   = ((unsigned short)buff[offset+3] & 0xFC)<<6 | -						   (unsigned short)buff[offset+0]; -			short pitch = ((unsigned short)buff[offset+5] & 0xFC)<<6 | -                           (unsigned short)buff[offset+2]; -			short roll  = ((unsigned short)buff[offset+4] & 0xFC)<<6 | -				           (unsigned short)buff[offset+1]; - -			// we get one set of bogus values when the MotionPlus is disconnected, -			//  so ignore them -			if((yaw != 0x3fff) || (pitch != 0x3fff) || (roll != 0x3fff)) -				{ -				wiimote_state::motion_plus::sensors_raw &raw = Internal.MotionPlus.Raw; -	 -				if((raw.Yaw != yaw) || (raw.Pitch != pitch) || (raw.Roll  != roll)) -					changed |= MOTIONPLUS_SPEED_CHANGED; - -				raw.Yaw   = yaw; -				raw.Pitch = pitch; -				raw.Roll  = roll; -	 -				// convert to float values -				bool    yaw_slow = (buff[offset+3] & 0x2) == 0x2; -				bool  pitch_slow = (buff[offset+3] & 0x1) == 0x1; -				bool   roll_slow = (buff[offset+4] & 0x2) == 0x2; -				float y_scale    =   yaw_slow? 0.05f : 0.25f; -				float p_scale    = pitch_slow? 0.05f : 0.25f; -				float r_scale    =  roll_slow? 0.05f : 0.25f; -			 -				Internal.MotionPlus.Speed.Yaw   = -(raw.Yaw   - 0x1F7F) * y_scale; -		        Internal.MotionPlus.Speed.Pitch = -(raw.Pitch - 0x1F7F) * p_scale; -			    Internal.MotionPlus.Speed.Roll  = -(raw.Roll  - 0x1F7F) * r_scale; -	 -				// show if there's an extension plugged into the MotionPlus: -				bool extension = buff[offset+4] & 1; -				if(extension != bMotionPlusExtension) -					{ -					if(extension) { -						TRACE(_T(".. MotionPlus extension found.")); -						changed |= MOTIONPLUS_EXTENSION_CONNECTED; -						} -					else{ -						TRACE(_T(".. MotionPlus' extension disconnected.")); -						changed |= MOTIONPLUS_EXTENSION_DISCONNECTED; -						} -					} -				bMotionPlusExtension = extension; -				} -			// while we're getting data, the plus is obviously detected/enabled -//			bMotionPlusDetected = bMotionPlusEnabled = true; -			} -			break; -		} -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -int wiimote::ParseReadAddress (BYTE* buff) -	{ -	// decode the address that was queried: -	int address = buff[4]<<8 | buff[5]; -	int size    = buff[3] >> 4; -	int changed	= 0; - -	if((buff[3] & 0x08) != 0) { -		WARN(_T("error: read address not valid.")); -		_ASSERT(0); -		return NO_CHANGE; -		} -	// address read failed (write-only)? -	else if((buff[3] & 0x07) != 0) -		{ -		// this also happens when attempting to detect a non-existant MotionPlus -		if(MotionPlusDetectCount) -			{ -			--MotionPlusDetectCount; -			if(Internal.ExtensionType == MOTION_PLUS) -				{ -				if(bMotionPlusDetected) -					TRACE(_T(".. MotionPlus removed.")); -				bMotionPlusDetected  = false; -				bMotionPlusEnabled   = false; -				// the MotionPlus can sometimes get confused - initializing -				//  extenions fixes it: -//				if(address == 0xfa) -//					InitializeExtension(); -				} -			} -		else -			WARN(_T("error: attempt to read from write-only register 0x%X."), buff[3]); - -		return NO_CHANGE; -		} - -	// *NOTE*: this is a major (but convenient) hack!  The returned data only -	//          contains the lower two bytes of the address that was queried. -	//			as these don't collide between any of the addresses/registers -	//			we currently read, it's OK to match just those two bytes - -	// skip the header -	buff += 6; - -	switch(address) -		{ -		case (REGISTER_CALIBRATION & 0xffff): -			{ -			_ASSERT(size == 6); -			TRACE(_T(".. got wiimote calibration.")); -			Internal.CalibrationInfo.X0 = buff[0]; -			Internal.CalibrationInfo.Y0 = buff[1]; -			Internal.CalibrationInfo.Z0 = buff[2]; -			Internal.CalibrationInfo.XG = buff[4]; -			Internal.CalibrationInfo.YG = buff[5]; -			Internal.CalibrationInfo.ZG = buff[6]; -			//changed |= CALIBRATION_CHANGED;	 -			} -			break; -			 -		// note: this covers both the normal extension and motion plus extension -		//        addresses (0x4a400fa / 0x4a600fa) -		case (REGISTER_EXTENSION_TYPE & 0xffff): -			{ -			_ASSERT(size == 5); -			QWORD type = *(QWORD*)buff; - -//			TRACE(_T("(found extension 0x%I64x)"), type); - -			static const QWORD NUNCHUK		       = 0x000020A40000ULL; -			static const QWORD CLASSIC		       = 0x010120A40000ULL; -			static const QWORD GH3_GHWT_GUITAR     = 0x030120A40000ULL; -			static const QWORD GHWT_DRUMS	       = 0x030120A40001ULL; -			static const QWORD BALANCE_BOARD	   = 0x020420A40000ULL; -			static const QWORD MOTION_PLUS		   = 0x050420A40000ULL; -			static const QWORD MOTION_PLUS_DETECT  = 0x050020a60000ULL; -			static const QWORD MOTION_PLUS_DETECT2 = 0x050420a60000ULL; -			static const QWORD PARTIALLY_INSERTED  = 0xffffffffffffULL; - -			// MotionPlus: _before_ it's been activated -			if((type == MOTION_PLUS_DETECT) || (type == MOTION_PLUS_DETECT2)) -				{ -				if(!bMotionPlusDetected) { -					TRACE(_T("Motion Plus detected!")); -					changed |= MOTIONPLUS_DETECTED; -					} -				bMotionPlusDetected = true; -				--MotionPlusDetectCount; -				break; -				} - -			#define IF_TYPE(id)	if(type == id) { \ -									/* sometimes it comes in more than once */ \ -									if(Internal.ExtensionType == wiimote_state::id)\ -										break; \ -									Internal.ExtensionType = wiimote_state::id; - -			// MotionPlus: once it's activated & mapped to the standard ext. port -			IF_TYPE(MOTION_PLUS) -				TRACE(_T(".. Motion Plus!")); -				// and start a query for the calibration data -				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				bMotionPlusDetected = true; -				} -			else IF_TYPE(NUNCHUK) -				TRACE(_T(".. Nunchuk!")); -				bMotionPlusEnabled = false; -				// and start a query for the calibration data -				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(CLASSIC) -				TRACE(_T(".. Classic Controller!")); -				bMotionPlusEnabled = false; -				// and start a query for the calibration data -				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(GH3_GHWT_GUITAR) -				// sometimes it comes in more than once? -				TRACE(_T(".. GH3/GHWT Guitar Controller!")); -				bMotionPlusEnabled = false; -				// and start a query for the calibration data -				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(GHWT_DRUMS) -				TRACE(_T(".. GHWT Drums!")); -				bMotionPlusEnabled = false; -				// and start a query for the calibration data -				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(BALANCE_BOARD) -				TRACE(_T(".. Balance Board!")); -				bMotionPlusEnabled = false; -				// and start a query for the calibration data -				ReadAddress(REGISTER_BALANCE_CALIBRATION, 24); -				} -			else if(type == PARTIALLY_INSERTED) { -				// sometimes it comes in more than once? -				if(Internal.ExtensionType == wiimote_state::PARTIALLY_INSERTED) -					Sleep(50); -				TRACE(_T(".. partially inserted!")); -				bMotionPlusEnabled = false; -				Internal.ExtensionType = wiimote_state::PARTIALLY_INSERTED; -				changed |= EXTENSION_PARTIALLY_INSERTED; -				// try initializing the extension again by requesting another -				//  status report (this usually fixes it) -				Internal.bExtension = false; -				RequestStatusReport(); -				} -			else{ -				TRACE(_T("unknown extension controller found (0x%I64x)"), type); -				} -			} -			break; -		 -		case (REGISTER_EXTENSION_CALIBRATION & 0xffff): -		case (REGISTER_BALANCE_CALIBRATION   & 0xffff): -			{ -//			_ASSERT(((Internal.ExtensionType == BALANCE_BOARD) && (size == 31)) || -//					((Internal.ExtensionType != BALANCE_BOARD) && (size == 15))); - -			switch(Internal.ExtensionType) -				{ -				case wiimote_state::NUNCHUK: -					{ -					wiimote_state::nunchuk::calibration_info -						&calib = Internal.Nunchuk.CalibrationInfo; - -					calib.X0   = buff[ 0]; -					calib.Y0   = buff[ 1]; -					calib.Z0   = buff[ 2]; -					calib.XG   = buff[ 4]; -					calib.YG   = buff[ 5]; -					calib.ZG   = buff[ 6]; -					calib.MaxX = buff[ 8]; -					calib.MinX = buff[ 9]; -					calib.MidX = buff[10]; -					calib.MaxY = buff[11]; -					calib.MinY = buff[12]; -					calib.MidY = buff[13]; - -					changed |= NUNCHUK_CONNECTED;//|NUNCHUK_CALIBRATION_CHANGED; -					// reenable reports -//					SetReportType(ReportType); -					} -					break; -				 -				case wiimote_state::CLASSIC: -				case wiimote_state::GH3_GHWT_GUITAR: -				case wiimote_state::GHWT_DRUMS: -					{ -					wiimote_state::classic_controller::calibration_info -						&calib = Internal.ClassicController.CalibrationInfo; -					 -					calib.MaxXL = buff[ 0] >> 2; -					calib.MinXL = buff[ 1] >> 2; -					calib.MidXL = buff[ 2] >> 2; -					calib.MaxYL = buff[ 3] >> 2; -					calib.MinYL = buff[ 4] >> 2; -					calib.MidYL = buff[ 5] >> 2; -					calib.MaxXR = buff[ 6] >> 3; -					calib.MinXR = buff[ 7] >> 3; -					calib.MidXR = buff[ 8] >> 3; -					calib.MaxYR = buff[ 9] >> 3; -					calib.MinYR = buff[10] >> 3; -					calib.MidYR = buff[11] >> 3; -					// this doesn't seem right... -					//	calib.MinTriggerL = buff[12] >> 3; -					//	calib.MaxTriggerL = buff[14] >> 3; -					//	calib.MinTriggerR = buff[13] >> 3; -					//	calib.MaxTriggerR = buff[15] >> 3; -					calib.MinTriggerL = 0; -					calib.MaxTriggerL = 31; -					calib.MinTriggerR = 0; -					calib.MaxTriggerR = 31; - -					changed |= CLASSIC_CONNECTED;//|CLASSIC_CALIBRATION_CHANGED; -					// reenable reports -//					SetReportType(ReportType); -					} -					break; - -				case BALANCE_BOARD: -					{ -					// first part, 0 & 17kg calibration values -					wiimote_state::balance_board::calibration_info -						&calib = Internal.BalanceBoard.CalibrationInfo; - -					calib.Kg0 .TopR	   = (short)((short)buff[0] << 8 | buff[1]); -					calib.Kg0 .BottomR = (short)((short)buff[2] << 8 | buff[3]); -					calib.Kg0 .TopL	   = (short)((short)buff[4] << 8 | buff[5]); -					calib.Kg0 .BottomL = (short)((short)buff[6] << 8 | buff[7]); - -					calib.Kg17.TopR	   = (short)((short)buff[8] << 8 | buff[9]); -					calib.Kg17.BottomR = (short)((short)buff[10] << 8 | buff[11]); -					calib.Kg17.TopL	   = (short)((short)buff[12] << 8 | buff[13]); -					calib.Kg17.BottomL = (short)((short)buff[14] << 8 | buff[15]); - -					// 2nd part is scanned above -					} -					break; - -				case MOTION_PLUS: -					{ -					// TODO: not known how the calibration values work -					changed |= MOTIONPLUS_ENABLED; -					bMotionPlusEnabled = true; -					bInitInProgress	   = false; -					// reenable reports -//					SetReportType(ReportType); -					} -					break; -				} -			case 0x34: -				{ -				if(Internal.ExtensionType == BALANCE_BOARD) -					{ -					wiimote_state::balance_board::calibration_info -						&calib = Internal.BalanceBoard.CalibrationInfo; - -					// 2nd part of the balance board calibration, -					//  34kg calibration values -					calib.Kg34.TopR    = (short)((short)buff[0] << 8 | buff[1]); -					calib.Kg34.BottomR = (short)((short)buff[2] << 8 | buff[3]); -					calib.Kg34.TopL    = (short)((short)buff[4] << 8 | buff[5]); -					calib.Kg34.BottomL = (short)((short)buff[6] << 8 | buff[7]); -						 -					changed |= BALANCE_CONNECTED; -					// reenable reports -					SetReportType(IN_BUTTONS_BALANCE_BOARD); -					} -				// else unknown what these are for -				} -			bInitInProgress = false; -			} -			break; - -		default: -//			_ASSERT(0); // shouldn't happen -			break; -		} -	 -	return changed; -	} -// ------------------------------------------------------------------------------------ -void wiimote::ReadCalibration () -	{ -	TRACE(_T("Requestion wiimote calibration:")); -	// this appears to change the report type to 0x31 -	ReadAddress(REGISTER_CALIBRATION, 7); -	} -// ------------------------------------------------------------------------------------ -void wiimote::EnableIR (wiimote_state::ir::mode mode) -	{ -	Internal.IR.Mode = mode; - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_IR; -	buff[1] = 0x04 | GetRumbleBit(); -	WriteReport(buff); - -	memset(buff, 0, REPORT_LENGTH); -	buff[0] = OUT_IR2; -	buff[1] = 0x04 | GetRumbleBit(); -	WriteReport(buff); - -	static const BYTE ir_sens1[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, -									0xc0}; -	static const BYTE ir_sens2[] = {0x40, 0x00}; - -	WriteData(REGISTER_IR, 0x08); -	Sleep(25); 	// wait a little to make IR more reliable (for some) -	WriteData(REGISTER_IR_SENSITIVITY_1, sizeof(ir_sens1), ir_sens1); -	WriteData(REGISTER_IR_SENSITIVITY_2, sizeof(ir_sens2), ir_sens2); -	WriteData(REGISTER_IR_MODE, (BYTE)mode); -	} -// ------------------------------------------------------------------------------------ -void wiimote::DisableIR () -	{ -	Internal.IR.Mode = wiimote_state::ir::OFF; - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_IR; -	buff[1] = GetRumbleBit(); -	WriteReport(buff); - -	memset(buff, 0, REPORT_LENGTH); -	buff[0] = OUT_IR2; -	buff[1] = GetRumbleBit(); -	WriteReport(buff); -	} -// ------------------------------------------------------------------------------------ -unsigned __stdcall wiimote::HIDwriteThreadfunc (void* param) -	{ -	_ASSERT(param); -	TRACE(_T("(starting HID write thread)")); -	wiimote &remote = *(wiimote*)param; - -	while(remote.Handle != INVALID_HANDLE_VALUE) -		{ -		// try to write the oldest entry in the queue -#ifdef USE_DYNAMIC_HIDQUEUE -		if(!remote.HIDwriteQueue.empty()) -#else -		if(!remote.HID.IsEmpty()) -#endif -			{ -#ifdef BEEP_DEBUG_WRITES -			Beep(1500,1); -#endif -			EnterCriticalSection(&remote.HIDwriteQueueLock); -#ifdef USE_DYNAMIC_HIDQUEUE -			 BYTE *buff = remote.HIDwriteQueue.front(); -			 _ASSERT(buff); -#else -			 BYTE *buff = remote.HID.Queue[remote.HID.ReadIndex].Report; -#endif -			LeaveCriticalSection(&remote.HIDwriteQueueLock); - -			if(!_HidD_SetOutputReport(remote.Handle, buff, REPORT_LENGTH)) -				{ -				DWORD err = GetLastError(); -if(err==ERROR_BUSY) -TRACE(_T("**** HID WRITE: BUSY ****")); -else if(err == ERROR_NOT_READY) -TRACE(_T("**** HID WRITE: NOT READY ****")); - -				if((err != ERROR_BUSY)	&&	 // "the requested resource is in use" -				   (err != ERROR_NOT_READY)) // "the device is not ready" -					{ -					if(err == ERROR_NOT_SUPPORTED) { -						WARN(_T("BT Stack doesn't suport HID writes!")); -						goto remove_entry; -						} -					else{ -						DEEP_TRACE(_T("HID write failed (err %u)! - "), err); -						// if this worked previously, the connection was probably lost -						if(remote.IsConnected()) -							remote.bConnectionLost = true; -						} -					//_T("aborting write thread"), err); -					//return 911; -					} -				} -			else{ -remove_entry: -				EnterCriticalSection(&remote.HIDwriteQueueLock); -#ifdef USE_DYNAMIC_HIDQUEUE -				 remote.HIDwriteQueue.pop(); -				 delete[] buff; -#else -				 remote.HID.ReadIndex++; -				 remote.HID.ReadIndex &= (hid::MAX_QUEUE_ENTRIES-1); -#endif -				LeaveCriticalSection(&remote.HIDwriteQueueLock); -				} -			} -		Sleep(1); -		} - -	TRACE(_T("ending HID write thread")); -	return 0; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::WriteReport (BYTE *buff) -	{ -#ifdef BEEP_DEBUG_WRITES -	Beep(2000,1); -#endif - -#ifdef _DEBUG -	#define DEEP_TRACE_TYPE(type)	case OUT_##type: DEEP_TRACE(_T("WriteReport: ")\ -																_T(#type)); break -	switch(buff[0]) -		{ -		DEEP_TRACE_TYPE(NONE); -		DEEP_TRACE_TYPE(LEDs); -		DEEP_TRACE_TYPE(TYPE); -		DEEP_TRACE_TYPE(IR); -		DEEP_TRACE_TYPE(SPEAKER_ENABLE); -		DEEP_TRACE_TYPE(STATUS); -		DEEP_TRACE_TYPE(WRITEMEMORY); -		DEEP_TRACE_TYPE(READMEMORY); -		DEEP_TRACE_TYPE(SPEAKER_DATA); -		DEEP_TRACE_TYPE(SPEAKER_MUTE); -		DEEP_TRACE_TYPE(IR2); -		default: -			TRACE(_T("WriteReport: type [%02x][%02x]"), buff[1], buff[2]); -		} -#endif - -	if(bUseHIDwrite) -		{ -		// HidD_SetOutputReport: +: works on MS Bluetooth stacks (WriteFile doesn't). -		//						 -: is synchronous, so make it async -		if(!HIDwriteThread) -			{ -			HIDwriteThread = (HANDLE)_beginthreadex(NULL, 0, HIDwriteThreadfunc, -													this, 0, NULL); -			_ASSERT(HIDwriteThread); -			if(!HIDwriteThread) { -				WARN(_T("couldn't create HID write thread!")); -				return false; -				} -			SetThreadPriority(HIDwriteThread, WORKER_THREAD_PRIORITY); -			} - -		// insert the write request into the thread's queue -#ifdef USE_DYNAMIC_HIDQUEUE -		EnterCriticalSection(&HIDwriteQueueLock); -		 BYTE *buff_copy = new BYTE[REPORT_LENGTH]; -#else -		// allocate the HID write queue once -		if(!HID.Queue && !HID.Allocate()) -			return false; - -		EnterCriticalSection(&HIDwriteQueueLock); -		 BYTE *buff_copy = HID.Queue[HID.WriteIndex].Report; -#endif -		 memcpy(buff_copy, buff, REPORT_LENGTH); - -#ifdef USE_DYNAMIC_HIDQUEUE -		 HIDwriteQueue.push(buff_copy); -#else -		 HID.WriteIndex++; -		 HID.WriteIndex &= (HID.MAX_QUEUE_ENTRIES-1); - -		 // check if the fixed report queue has overflown: -		 //  if this ASSERT triggers, the HID write queue (that stores reports -		 //   for asynchronous output by HIDwriteThreadfunc) has overflown. -		 //  this can happen if the connection with the wiimote has been lost -		 //   and in that case is harmless. -		 // -		 //  if it happens during normal operation though you need to increase -		 //   hid::MAX_QUEUE_ENTRIES to the next power-of-2 (see comments) -		 //   _and_ email me the working setting so I can update the next release -		 _ASSERT(HID.WriteIndex != HID.ReadIndex); -#endif -		LeaveCriticalSection(&HIDwriteQueueLock); -		return true; -		} - -	// WriteFile: -	DWORD written; -	if(!WriteFile(Handle, buff, REPORT_LENGTH, &written, &Overlapped)) -		{ -		DWORD error = GetLastError(); -		if(error != ERROR_IO_PENDING) { -			TRACE(_T("WriteFile failed, err: %u!"), error); -			// if it worked previously, assume we lost the connection -			if(IsConnected()) -				bConnectionLost = true; -#ifndef USE_DYNAMIC_HIDQUEUE -			HID.Deallocate(); -#endif -			return false; -			} -		} -	return true; -	} -// ------------------------------------------------------------------------------------ -// experimental speaker support: -// ------------------------------------------------------------------------------------ -bool wiimote::MuteSpeaker (bool on) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return false; - -	if(Internal.Speaker.bMuted == on) -		return true; - -	if(on) TRACE(_T("muting speaker."  )); -	else   TRACE(_T("unmuting speaker.")); - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_SPEAKER_MUTE; -	buff[1] = (on? 0x04 : 0x00) | GetRumbleBit(); -	if(!WriteReport(buff)) -		return false; -	Sleep(1); -	Internal.Speaker.bMuted = on; -	return true; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::EnableSpeaker (bool on) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return false; - -	if(Internal.Speaker.bEnabled == on) -		return true; - -	if(on) TRACE(_T("enabling speaker.")); else TRACE(_T("disabling speaker.")); - -	BYTE buff [REPORT_LENGTH] = {0}; -	buff[0] = OUT_SPEAKER_ENABLE; -	buff[1] = (on? 0x04 : 0x00) | GetRumbleBit(); -	if(!WriteReport(buff)) -		return false; - -	if(!on) { -		Internal.Speaker.Freq   = FREQ_NONE; -		Internal.Speaker.Volume = 0; -		MuteSpeaker(true); -		} - -	Internal.Speaker.bEnabled = on; -	return true; -	} -// ------------------------------------------------------------------------------------ -#ifdef TR4 // TEMP, ignore - extern int hzinc; -#endif -// ------------------------------------------------------------------------------------ -unsigned __stdcall wiimote::SampleStreamThreadfunc (void* param) -	{ -	TRACE(_T("(starting sample thread)")); -	// sends a simple square wave sample stream -	wiimote &remote = *(wiimote*)param; -	 -	static BYTE squarewave_report[REPORT_LENGTH] = -		{ OUT_SPEAKER_DATA, 20<<3, 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3, -								   0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3, }; -	static BYTE sample_report [REPORT_LENGTH] =  -		{ OUT_SPEAKER_DATA, 0 }; - -	bool		   last_playing    = false; -	DWORD		   frame		   = 0; -	DWORD		   frame_start     = 0; -	unsigned	   total_samples   = 0; -	unsigned	   sample_index	   = 0; -	wiimote_sample *current_sample = NULL; -	 -	// TODO: duration!! -	while(remote.IsConnected()) -		{ -		bool playing = remote.IsPlayingAudio(); -		 -		if(!playing) -			Sleep(1); -		else{ -			const unsigned freq_hz  = FreqLookup[remote.Internal.Speaker.Freq]; -#ifdef TR4 -			const float    frame_ms = 1000 / ((freq_hz+hzinc) / 40.f); // 20bytes = 40 samples per write -#else -			const float    frame_ms = 1000 / (freq_hz		  / 40.f); // 20bytes = 40 samples per write -#endif - -			// has the sample just changed? -			bool sample_changed = (current_sample != remote.CurrentSample); -			current_sample		= (wiimote_sample*)remote.CurrentSample; - -// (attempts to minimise glitches, doesn't seem to help though) -//#define FIRSTFRAME_IS_SILENT	// send all-zero for first frame - -#ifdef FIRSTFRAME_IS_SILENT -			bool silent_frame = false; -#endif -			if(!last_playing || sample_changed) { -				frame		  = 0; -				frame_start   = timeGetTime(); -				total_samples = current_sample? current_sample->length : 0; -				sample_index  = 0; -#ifdef FIRSTFRAME_IS_SILENT -				silent_frame  = true; -#endif -				} - -			// are we streaming a sample? -			if(current_sample) -				{ -				if(sample_index < current_sample->length) -					{ -					// (remember that samples are 4bit, ie. 2 per byte) -					unsigned samples_left   = (current_sample->length - sample_index); -					unsigned report_samples = min(samples_left, (unsigned)40); -					// round the entries up to the nearest multiple of 2 -					unsigned report_entries = (report_samples+1) >> 1; -					 -					sample_report[1] = (BYTE)((report_entries<<3) | -											  remote.GetRumbleBit()); -#ifdef FIRSTFRAME_IS_SILENT -					if(silent_frame) { -						// send all-zeroes -						for(unsigned index=0; index<report_entries; index++) -							sample_report[2+index] = 0; -						remote.WriteReport(sample_report); -						} -					else -#endif -					{ -						for(unsigned index=0; index<report_entries; index++) -							sample_report[2+index] = -									current_sample->samples[(sample_index>>1)+index]; -						remote.WriteReport(sample_report); -						sample_index += report_samples; -						} -					} -				else{ -					// we reached the sample end -					remote.CurrentSample		   = NULL; -					current_sample				   = NULL; -					remote.Internal.Speaker.Freq   = FREQ_NONE; -					remote.Internal.Speaker.Volume = 0; -					} -				} -			// no, a squarewave -			else{ -				squarewave_report[1] = (20<<3) | remote.GetRumbleBit(); -				remote.WriteReport(squarewave_report); -#if 0 -				// verify that we're sending at the correct rate (we are) -				DWORD elapsed		   = (timeGetTime()-frame_start); -				unsigned total_samples = frame * 40; -				float elapsed_secs	   = elapsed / 1000.f; -				float sent_persec	   = total_samples / elapsed_secs; -#endif -				} - -			frame++; - -			// send the first two buffers immediately? (attempts to lessen startup -			//  startup glitches by assuming we're filling a small sample -			//  (or general input) buffer on the wiimote) - doesn't seem to help -//			if(frame > 2) { -				while((timeGetTime()-frame_start) < (unsigned)(frame*frame_ms)) -					Sleep(1); -//				} -			} - -		last_playing = playing; -		} -	 -	TRACE(_T("(ending sample thread)")); -	return 0; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::Load16bitMonoSampleWAV (const TCHAR* filepath, wiimote_sample &out) -	{ -	// converts unsigned 16bit mono .wav audio data to the 4bit ADPCM variant -	//  used by the Wiimote (at least the closest match so far), and returns -	//  the data in a BYTE array (caller must delete[] it when no longer needed): -	memset(&out, 0, sizeof(out)); - -	TRACE(_T("Loading '%s'"), filepath); - -	FILE *file; -#if (_MSC_VER >= 1400) // VC 2005+ -	_tfopen_s(&file, filepath, _T("rb")); -#else -	file = _tfopen(filepath, _T("rb")); -#endif -	_ASSERT(file); -	if(!file) { -		WARN(_T("Couldn't open '%s"), filepath); -		return false; -		} - -	// parse the .wav file -	struct riff_chunkheader { -		char  ckID [4]; -		DWORD ckSize; -		char  formType [4]; -		}; -	struct chunk_header { -		char  ckID [4]; -		DWORD ckSize; -		}; -	union { -		WAVEFORMATEX		 x; -		WAVEFORMATEXTENSIBLE xe; -		} wf = {0}; - -	riff_chunkheader riff_chunkheader; -	chunk_header	 chunk_header; -	speaker_freq	 freq = FREQ_NONE; - -	#define READ(data)			if(fread(&data, sizeof(data), 1, file) != 1) { \ -									TRACE(_T(".wav file corrupt"));			   \ -									fclose(file);							   \ -									return false;							   \ -									} -	#define READ_SIZE(ptr,size)	if(fread(ptr, size, 1, file) != 1) {		   \ -									TRACE(_T(".wav file corrupt"));			   \ -									fclose(file);							   \ -									return false;							   \ -									} -	// read the riff chunk header -	READ(riff_chunkheader); - -	// valid RIFF file? -	_ASSERT(!strncmp(riff_chunkheader.ckID, "RIFF", 4)); -	if(strncmp(riff_chunkheader.ckID, "RIFF", 4)) -		goto unsupported; // nope -	// valid WAV variant? -	_ASSERT(!strncmp(riff_chunkheader.formType, "WAVE", 4)); -	if(strncmp(riff_chunkheader.formType, "WAVE", 4)) -		goto unsupported; // nope - -	// find the format & data chunks -	while(1) -		{ -		READ(chunk_header); -		 -		if(!strncmp(chunk_header.ckID, "fmt ", 4)) -			{ -			// not a valid .wav file? -			if(chunk_header.ckSize < 16 || -			   chunk_header.ckSize > sizeof(WAVEFORMATEXTENSIBLE)) -				goto unsupported; - -			READ_SIZE((BYTE*)&wf.x, chunk_header.ckSize); - -			// now we know it's true wav file -			bool extensible = (wf.x.wFormatTag == WAVE_FORMAT_EXTENSIBLE); -			int format	    = extensible? wf.xe.SubFormat.Data1 : -										  wf.x .wFormatTag; -			// must be uncompressed PCM (the format comparisons also work on -			//  the 'extensible' header, even though they're named differently) -			if(format != WAVE_FORMAT_PCM) { -				TRACE(_T(".. not uncompressed PCM")); -				goto unsupported; -				} - -			// must be mono, 16bit -			if((wf.x.nChannels != 1) || (wf.x.wBitsPerSample != 16)) { -				TRACE(_T(".. %d bit, %d channel%s"), wf.x.wBitsPerSample, -													 wf.x.nChannels, -													(wf.x.nChannels>1? _T("s"):_T(""))); -				goto unsupported; -				} - -			// must be _near_ a supported speaker frequency range (but allow some -			//  tolerance, especially as the speaker freq values aren't final yet): -			unsigned	   sample_freq = wf.x.nSamplesPerSec; -			const unsigned epsilon	   = 100; // for now -			 -			for(unsigned index=1; index<ARRAY_ENTRIES(FreqLookup); index++) -				{ -				if((sample_freq+epsilon) >= FreqLookup[index] && -				   (sample_freq-epsilon) <= FreqLookup[index]) { -					freq = (speaker_freq)index; -					TRACE(_T(".. using speaker freq %u"), FreqLookup[index]); -					break; -					} -				} -			if(freq == FREQ_NONE) { -				WARN(_T("Couldn't (loosely) match .wav samplerate %u Hz to speaker"), -					 sample_freq); -				goto unsupported; -				} -			} -		else if(!strncmp(chunk_header.ckID, "data", 4)) -			{ -			// make sure we got a valid fmt chunk first -			if(!wf.x.nBlockAlign) -				goto corrupt_file; - -			// grab the data -			unsigned total_samples = chunk_header.ckSize / wf.x.nBlockAlign; -			if(total_samples == 0) -				goto corrupt_file; -			 -			short *samples = new short[total_samples]; -			size_t read = fread(samples, 2, total_samples, file); -			fclose(file); -			if(read != total_samples) -				{ -				if(read == 0) { -					delete[] samples; -					goto corrupt_file; -					} -				// got a different number, but use them anyway -				WARN(_T("found %s .wav audio data than expected (%u/%u samples)"), -					((read < total_samples)? _T("less") : _T("more")), -					read, total_samples); - -				total_samples = read; -				} - -			// and convert them -			bool res = Convert16bitMonoSamples(samples, true, total_samples, freq, -											   out); -			delete[] samples; -			return res; -			} -		else{ -			// unknown chunk, skip its data -			DWORD chunk_bytes = (chunk_header.ckSize + 1) & ~1L; -			if(fseek(file, chunk_bytes, SEEK_CUR)) -				goto corrupt_file; -			} -		} - -corrupt_file: -	WARN(_T(".wav file is corrupt")); -	fclose(file); -	return false; - -unsupported: -	WARN(_T(".wav file format not supported (must be mono 16bit PCM)")); -	fclose(file); -	return false; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::Load16BitMonoSampleRAW (const TCHAR*   filepath, -									  bool		     _signed, -									  speaker_freq   freq, -									  wiimote_sample &out) -	{ -	// converts (.wav style) unsigned 16bit mono raw data to the 4bit ADPCM variant -	//  used by the Wiimote, and returns the data in a BYTE array (caller must -	//  delete[] it when no longer needed): -	memset(&out, 0, sizeof(out)); - -	// get the length of the file -	struct _stat file_info; -	if(_tstat(filepath, &file_info)) { -		WARN(_T("couldn't get filesize for '%s'"), filepath); -		return false; -		} -	 -	DWORD len = file_info.st_size; -	_ASSERT(len); -	if(!len) { -		WARN(_T("zero-size sample file '%s'"), filepath); -		return false; -		} - -	unsigned total_samples = (len+1) / 2; // round up just in case file is corrupt -	// allocate a buffer to hold the samples to convert -	short *samples = new short[total_samples];  -	_ASSERT(samples); -	if(!samples) { -		TRACE(_T("Couldn't open '%s"), filepath); -		return false; -		} - -	// load them -	FILE *file; -	bool res; -#if (_MSC_VER >= 1400) // VC 2005+ -	_tfopen_s(&file, filepath, _T("rb")); -#else -	file = _tfopen(filepath, _T("rb")); -#endif -	_ASSERT(file); -	if(!file) { -		TRACE(_T("Couldn't open '%s"), filepath); -        goto error; -        } - -	res = (fread(samples, 1, len, file) == len); -	fclose(file); -	if(!res) { -		WARN(_T("Couldn't load file '%s'"), filepath); -		goto error; -		} - -	// and convert them -	res = Convert16bitMonoSamples(samples, _signed, total_samples, freq, out); -	delete[] samples; -	return res; - -error: -	delete[] samples; -	return false; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::Convert16bitMonoSamples (const short*   samples, -									   bool		      _signed, -									   DWORD		  length, -									   speaker_freq   freq, -									   wiimote_sample &out) -	{ -	// converts 16bit mono sample data to the native 4bit format used by the Wiimote, -	//  and returns the data in a BYTE array (caller must delete[] when no -	//  longer needed): -	memset(&out, 0, sizeof(0)); - -	_ASSERT(samples && length); -	if(!samples || !length) -		return false; - -	// allocate the output buffer -	out.samples = new BYTE[length]; -	_ASSERT(out.samples); -	if(!out.samples) -		return false; - -	// clear it -	memset(out.samples, 0, length); -	out.length = length; -	out.freq   = freq; - -	// ADPCM code, adapted from -	//  http://www.wiindows.org/index.php/Talk:Wiimote#Input.2FOutput_Reports -	static const int index_table[16] = {  -1,  -1,  -1,  -1,   2,   4,   6,   8, -										  -1,  -1,  -1,  -1,   2,   4,   6,   8 }; -	static const int diff_table [16] = {   1,   3,   5,   7,   9,  11,  13,  15, -										  -1,  -3,  -5,  -7,  -9, -11, -13,  15 }; -	static const int step_scale [16] = { 230, 230, 230, 230, 307, 409, 512, 614, -										 230, 230, 230, 230, 307, 409, 512, 614 }; -	// Encode to ADPCM, on initialization set adpcm_prev_value to 0 and adpcm_step -	//  to 127 (these variables must be preserved across reports) -	int adpcm_prev_value = 0; -	int adpcm_step		 = 127; - -	for(size_t i=0; i<length; i++) -		{ -		// convert to 16bit signed -		int value = samples[i];// (8bit) << 8);// | samples[i]; // dither it? -		if(!_signed) -			value -= 32768; -		// encode: -		int  diff = value - adpcm_prev_value; -		BYTE encoded_val = 0; -		if(diff < 0) { -			encoded_val |= 8; -			diff = -diff; -			} -		diff = (diff << 2) / adpcm_step; -		if (diff > 7) -			diff = 7; -		encoded_val |= diff; -		adpcm_prev_value += ((adpcm_step * diff_table[encoded_val]) / 8); -		if(adpcm_prev_value  >  0x7fff) -			adpcm_prev_value =  0x7fff; -		if(adpcm_prev_value  < -0x8000) -			adpcm_prev_value = -0x8000; -		adpcm_step = (adpcm_step * step_scale[encoded_val]) >> 8; -		if(adpcm_step < 127) -			adpcm_step = 127; -		if(adpcm_step > 24567) -			adpcm_step = 24567; -		if(i & 1) -			out.samples[i>>1] |= encoded_val; -		else -			out.samples[i>>1] |= encoded_val << 4; -		} - -	return true; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::PlaySample (const wiimote_sample &sample, BYTE volume,  -						  speaker_freq freq_override) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return false; - -	speaker_freq freq = freq_override? freq_override : sample.freq; - -	TRACE(_T("playing sample.")); -	EnableSpeaker(true); -	MuteSpeaker  (true); - -#if 0 -	// combine everything into one write - faster, seems to work? -	BYTE bytes[9] = { 0x00, 0x00, 0x00, 10+freq, vol, 0x00, 0x00, 0x01, 0x01 }; -	WriteData(0x04a20001, sizeof(bytes), bytes); -#else -	// Write 0x01 to register 0x04a20009  -	WriteData(0x04a20009, 0x01); -	// Write 0x08 to register 0x04a20001  -	WriteData(0x04a20001, 0x08); -	// Write 7-byte configuration to registers 0x04a20001-0x04a20008  -	BYTE bytes[7] = { 0x00, 0x00, 0x00, 10+(BYTE)freq, volume, 0x00, 0x00 }; -	WriteData(0x04a20001, sizeof(bytes), bytes); -	// + Write 0x01 to register 0x04a20008  -	WriteData(0x04a20008, 0x01); -#endif - -	Internal.Speaker.Freq   = freq; -	Internal.Speaker.Volume = volume; -	CurrentSample			= &sample; - -	MuteSpeaker(false); - -	return StartSampleThread(); -	} -// ------------------------------------------------------------------------------------ -bool wiimote::StartSampleThread () -	{ -	if(SampleThread) -		return true; - -	SampleThread = (HANDLE)_beginthreadex(NULL, 0, SampleStreamThreadfunc, -										  this, 0, NULL); -	_ASSERT(SampleThread); -	if(!SampleThread) { -		WARN(_T("couldn't create sample thread!")); -		MuteSpeaker  (true); -		EnableSpeaker(false);	 -		return false; -		} -	SetThreadPriority(SampleThread, WORKER_THREAD_PRIORITY); -	return true; -	} -// ------------------------------------------------------------------------------------ -bool wiimote::PlaySquareWave (speaker_freq freq, BYTE volume) -	{ -	_ASSERT(IsConnected()); -	if(!IsConnected()) -		return false; - -	// if we're already playing a sample, stop it first -	if(IsPlayingSample()) -		CurrentSample = NULL; -	// if we're already playing a square wave at this freq and volume, return -	else if(IsPlayingAudio() && (Internal.Speaker.Freq   == freq) && -								(Internal.Speaker.Volume == volume)) -		return true; - -	TRACE(_T("playing square wave.")); -	// stop playing samples -	CurrentSample = 0; - -	EnableSpeaker(true); -	MuteSpeaker  (true); - -#if 0 -	// combined everything into one write - much faster, seems to work? -	BYTE bytes[9] = { 0x00, 0x00, 0x00, freq, volume, 0x00, 0x00, 0x01, 0x1 }; -	WriteData(0x04a20001, sizeof(bytes), bytes); -#else -	// write 0x01 to register 0xa20009  -	WriteData(0x04a20009, 0x01); -	// write 0x08 to register 0xa20001  -	WriteData(0x04a20001, 0x08); -	// write default sound mode (4bit ADPCM, we assume) 7-byte configuration -	//  to registers 0xa20001-0xa20008  -	BYTE bytes[7] = { 0x00, 0x00, 0x00, 10+(BYTE)freq, volume, 0x00, 0x00 }; -	WriteData(0x04a20001, sizeof(bytes), bytes); -	// write 0x01 to register 0xa20008  -	WriteData(0x04a20008, 0x01); -#endif - -	Internal.Speaker.Freq   = freq; -	Internal.Speaker.Volume = volume; - -	MuteSpeaker(false); -	return StartSampleThread(); -	} -// ------------------------------------------------------------------------------------ -void wiimote::RecordState (state_history	  &events_out, -						   unsigned			  max_time_ms, -						   state_change_flags change_trigger) -	{ -	// user being naughty? -	if(Recording.bEnabled) -		StopRecording(); - -	// clear the list -	if(!events_out.empty()) -		events_out.clear(); - -	// start recording  -	Recording.StateHistory = &events_out; -	Recording.StartTimeMS  = timeGetTime(); -	Recording.EndTimeMS    = Recording.StartTimeMS + max_time_ms; -	Recording.TriggerFlags = change_trigger; -	// as this call happens outside the read/parse thread, set the boolean -	//  which will enable reocrding last, so that all params are in place. -	// TODO: * stricly speaking this only works on VC2005+ or better, as it -	//		   automatically places a memory barrier on volatile variables - earlier/ -	//         other compilers may reorder the assignments!). * -	Recording.bEnabled	   = true; -	} -// ------------------------------------------------------------------------------------ -void wiimote::StopRecording () -	{ -	if(!Recording.bEnabled) -		return; - -	Recording.bEnabled = false; -	// make sure the read/parse thread has time to notice the change (else it might -	//  still write one more state to the list) -	Sleep(10); // too much? -	} -// ------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------ diff --git a/tracker-pt/wiiyourself/wiimote.h b/tracker-pt/wiiyourself/wiimote.h deleted file mode 100644 index 1db2c098..00000000 --- a/tracker-pt/wiiyourself/wiimote.h +++ /dev/null @@ -1,495 +0,0 @@ -// _______________________________________________________________________________ -// -//	 - WiiYourself! - native C++ Wiimote library  v1.15 -//	  (c) gl.tter 2007-10 - http://gl.tter.org -// -//	  see License.txt for conditions of use.  see History.txt for change log. -// _______________________________________________________________________________ -// -//  wiimote.h  (tab = 4 spaces) - -#ifdef _MSC_VER // VC -# pragma once -#endif - -#ifndef _WIIMOTE_H -# define _WIIMOTE_H - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <tchar.h>		// auto Unicode/Ansi support -#include <queue>		// for HID write method -#include <list>			// for state recording -  -#ifndef QWORD - typedef unsigned __int64 QWORD; -#endif - -#ifdef _MSC_VER			   // VC-specific: _DEBUG build only _ASSERT() sanity checks -# include <crtdbg.h> -#elif defined(__MINGW32__) // define NDEBUG to disable assert -# include <assert.h> -# define _ASSERT assert -#else -# define _ASSERT(x) ((void)0) // (add your compiler's implementation if you like) -#endif - -#ifdef SWIGWRAPPER		// Python Wrapper -#include "Python/wiimote_state.i" -#else -#include "wiimote_state.h" -#endif - -// configs: -//#define USE_DYNAMIC_HIDQUEUE // deprecated - -//  we request periodic status report updates to refresh the battery level -//   and to detect connection loss (through failed writes) -#define REQUEST_STATUS_EVERY_MS		1000 -#define DETECT_MPLUS_EVERY_MS		1000 -#define DETECT_MPLUS_COUNT			1	 // # of tries in quick succession - -//  all threads (read/parse, audio streaming, async rumble...) use this priority -#define WORKER_THREAD_PRIORITY		THREAD_PRIORITY_HIGHEST - - // internals -#define	WIIYOURSELF_VERSION_MAJOR	1 -#define	WIIYOURSELF_VERSION_MINOR1	1 -#define	WIIYOURSELF_VERSION_MINOR2	5 -//#define WIIYOURSELF_VERSION_BETA	// not defined for non-beta releases -#define WIIYOURSELF_VERSION_STR		_T("1.15") - -// array sizes -#define	TOTAL_BUTTON_BITS	16	// Number of bits for (Classic)ButtonNameFromBit[] -#define	TOTAL_FREQUENCIES	10	// Number of frequencies (see speaker_freq[]) - - // clarity -typedef HANDLE EVENT; - - -// state data changes can be signalled to the app via a callback.  Set the wiimote -//  object's 'ChangedCallback' any time to enable them, or alternatively inherit -//   from the wiimote object and override the ChangedNotifier() virtual method. - -//  of flags indicating which state has changed since the last callback. -typedef void (*state_changed_callback)	(class wiimote	     &owner, -										 state_change_flags  changed, -										 const wiimote_state &new_state); - -// internals -typedef BOOLEAN (__stdcall *hidwrite_ptr)(HANDLE HidDeviceObject, -										  PVOID  ReportBuffer, -										  ULONG  ReportBufferLength); - -// (global due to Python wrapper) -struct wiimote_state_event { -	DWORD		  time_ms;	// system timestamp in milliseconds -	wiimote_state state; -	}; - -// wiimote class - connects and manages a wiimote and its optional extensions -//                 (Nunchuk/Classic Controller), and exposes their state -class wiimote : public wiimote_state -	{ -	public: -		wiimote (); -		virtual ~wiimote (); - -	public: -		// these can be used to identify Connect()ed wiimote objects (if both -		//  are unconnected they will pass the compare as their handles are invalid) -		inline bool operator == (const wiimote& remote) -			{ return Handle == remote.Handle; } -		inline bool operator != (const wiimote& remote) -			{ return Handle != remote.Handle; } - -		// wiimote data input mode (use with SetReportType()) -		//  (only enable what you need to save battery power) -		enum input_report -			{ -			// combinations if buttons/acceleration/IR/Extension data -			IN_BUTTONS				 = 0x30, -			IN_BUTTONS_ACCEL		 = 0x31, -			IN_BUTTONS_ACCEL_IR		 = 0x33, // reports IR EXTENDED data (dot sizes) -			IN_BUTTONS_ACCEL_EXT	 = 0x35, -			IN_BUTTONS_ACCEL_IR_EXT	 = 0x37, // reports IR BASIC data (no dot sizes) -			IN_BUTTONS_BALANCE_BOARD = 0x32, // must use this for the balance board -			}; -		// string versions  -		static const TCHAR* ReportTypeName []; - - -	public: // convenience accessors: -		inline bool	IsConnected			  () const { return bStatusReceived; } -		// if IsConnected() unexpectedly returns false, connection was probably lost -		inline bool	ConnectionLost		  () const { return bConnectionLost; } -		inline bool IsBalanceBoard		  () const { return (Internal.bExtension && -							(Internal.ExtensionType==wiimote_state::BALANCE_BOARD)); } -		inline bool	NunchukConnected	  () const { return (Internal.bExtension && -							(Internal.ExtensionType==wiimote_state::NUNCHUK)); } -		inline bool	ClassicConnected	  () const { return (Internal.bExtension && -							(Internal.ExtensionType==wiimote_state::CLASSIC)); } -		inline bool MotionPlusConnected   () const { return bMotionPlusDetected; } -		inline bool MotionPlusEnabled	  () const { return bMotionPlusEnabled; } -		inline bool MotionPlusHasExtension() const { return bMotionPlusExtension; } -		inline bool	IsPlayingAudio		  () const { return (Internal.Speaker.Freq && -															 Internal.Speaker.Volume); } -		inline bool	IsPlayingSample		  () const { return IsPlayingAudio() && -															(CurrentSample != NULL); } -		inline bool	IsUsingHIDwrites	  () const { return bUseHIDwrite; } -		inline bool	IsRecordingState	  () const { return Recording.bEnabled; } - -		static inline unsigned TotalConnected() { return _TotalConnected; } - - -	public: // data -		QWORD UniqueID;		   // constructed from device-specific calibration info. -							   //  Note this is not guaranteed to be truly unique -							   //  as several devices may contain the same calibration -							   //  vluaes - but unique amongst a small number of  -							   //  devices. -#ifdef ID2_FROM_DEVICEPATH -		QWORD UniqueID2;	   // (low-reliabilty, left for reference) -							   //  constructed from the 'device path' string (as -							   //  reported by the OS/stack).  This is hopefully -							   //  unique as long as the devices remain installed -							   //  (or at least paired). -#endif -		// optional callbacks - set these to your own fuctions (if required) -		state_changed_callback  ChangedCallback; -		//  you can avoid unnecessary callback overhead by specifying a mask -		//   of which state changes should trigger them (default is any) -		state_change_flags		CallbackTriggerFlags; -		// alternatively, inherit from this class and override this virtual function: -		virtual void			ChangedNotifier (state_change_flags  changed, -												 const wiimote_state &new_state) {}; - -		// get the button name from its bit index (some bits are unused) -		static const TCHAR*		   ButtonNameFromBit [TOTAL_BUTTON_BITS]; -		static const TCHAR*		GetButtonNameFromBit (unsigned index) -			{ -			_ASSERT(index < TOTAL_BUTTON_BITS); -			if(index >= TOTAL_BUTTON_BITS) -				return _T("[invalid index]"); -			return ButtonNameFromBit[index]; -			} - -		// same for the Classic Controller -		static const TCHAR*		   ClassicButtonNameFromBit [TOTAL_BUTTON_BITS]; -		static const TCHAR*		GetClassicButtonNameFromBit (unsigned index) -			{ -			_ASSERT(index < TOTAL_BUTTON_BITS); -			if(index >= TOTAL_BUTTON_BITS) -				return _T("[invalid index]"); -			return ClassicButtonNameFromBit[index]; -			} - -		// get the frequency from speaker_freq enum -		static const unsigned	   FreqLookup [TOTAL_FREQUENCIES]; -		static const unsigned	GetFreqLookup (unsigned index) -			{ -			_ASSERT(index < TOTAL_FREQUENCIES); -			if(index >= TOTAL_FREQUENCIES) -				return 0; -			return FreqLookup[index]; -			} - -	public: // methods -		// call Connect() first - returns true if wiimote was found & enabled -		//  - 'wiimote_index' specifies which *installed* (not necessarily -		//     *connected*) wiimote should be tried (1 = first, 2 = 2nd etc). -		//    if you just want the first *available* wiimote that isn't already -		//     in use, pass in FIRST_AVAILABLE (default). -		//  - 'force_hidwrites' forces HID output method (it's auto-selected -		//     when needed and less efficient, so only force for testing). -		static const unsigned FIRST_AVAILABLE = 0xffffffff; -		bool Connect				 (unsigned wiimote_index = FIRST_AVAILABLE, -									  bool force_hidwrites   = false); -		// disconnect from the controller and stop reading data from it -		void Disconnect				 (); -		// set wiimote reporting mode (call after Connnect()) -		//  continous = true forces the wiimote to send constant updates, even when -		//			     nothing has changed. -		//			  = false only sends data when something has changed (note that -		//			     acceleration data will cause frequent updates anyway as it -		//			     jitters even when the wiimote is stationary) -		void SetReportType			 (input_report type, bool continuous = false); -		 -		// toggle the MotionPlus extension.  Call MotionPlusDetected() first to -		//  see if it's attached.  Unlike normal extensions, the MotionPlus does -		//  not report itself as one until enabled.  Once done, it then replaces -		//  any standard extension attached to it, so be sure to disable it -		//  if you want to read those (it's not currently known of both can -		//  be read simultaneously). -		bool EnableMotionPlus  (); -		bool DisableMotionPlus (); -	 -		// this is used to remove unwanted 'at rest' offsets, currently only from -		//  the Balance Board.  make sure there is no weight on the board before -		//  calling this. it reads the current sensor values and then removes them -		//  offsets from all subsequent KG and LB state values (the 'raw' values -		//  are never modified). -		void CalibrateAtRest		 (); -		// NOTE: the library automatically calls this when the first weight values -		//        come in after Connect()ion, but if the device wasn't at rest at -		//        the time the app can call it again later. - -		// to read the state via polling (reading the public state data direct from -		//  the wiimote object) you must call RefreshState() at the top of every pass. -		//  returns a combination of flags to indicate which state (if any) has -		//  changed since the last call. -		state_change_flags RefreshState (); - -		// reset the wiimote (changes report type to non-continuous buttons-only, -		//					  clears LEDs & rumble, mutes & disables speaker) -		void Reset					 (); -		// set/clear the wiimote LEDs -		void SetLEDs				 (BYTE led_bits); // bits 0-3 are valid -		// set/clear rumble -		void SetRumble				 (bool on); -		// alternative - rumble for a fixed amount of time (asynchronous) -		void RumbleForAsync			 (unsigned milliseconds); - -		// *experimental* speaker support: -		bool MuteSpeaker			 (bool on); -		bool EnableSpeaker			 (bool on); -		bool PlaySquareWave			 (speaker_freq freq, BYTE volume = 0x40); -		//  note: PlaySample currently streams from the passed-in wiimote_sample - -		//		   don't delete it until playback has stopped. -		bool PlaySample				 (const		   wiimote_sample &sample, -									  BYTE		   volume		 = 0x40, -									  speaker_freq freq_override = FREQ_NONE); - -		//  16bit mono sample loading/conversion to native format: -		//   .wav sample -		static bool Load16bitMonoSampleWAV	 (const TCHAR*   filepath, -											  wiimote_sample &out); -		//   raw 16bit mono audio data (can be signed or unsigned) -		static bool Load16BitMonoSampleRAW	 (const TCHAR*   filepath, -											  bool		     _signed, -											  speaker_freq   freq, -											  wiimote_sample &out); -		//   converts a 16bit mono sample array to a wiimote_sample -		static bool Convert16bitMonoSamples  (const short*   samples, -											  bool		     _signed, -											  DWORD		     length, -											  speaker_freq   freq, -											  wiimote_sample &out); -		 -		// state recording - records state snapshots to a 'state_history' supplied -		//					  by the caller.  states are timestamped and only added -		//					  to the list when the specified state changes. -#ifndef SWIG // !Python Wrapper -		typedef wiimote_state_event state_event; -#endif -		typedef std::list<state_event> state_history; -		static const unsigned UNTIL_STOP = 0xffffffff; -		// - pass in a 'state_history' list, and don't destroy/change it until -		//	  recording is stopped.  note the list will be cleared first. -		// - you can request a specific duration (and use IsRecordingState() to detect -		//    the end), or UNTIL_STOP.  StopRecording() can be called either way. -		// - you can use 'change trigger' to specify specific state changes that will -		//    trigger an insert into the history (others are then ignored). -		void RecordState  (state_history	  &events_out, -						   unsigned			  max_time_ms	 = UNTIL_STOP, -						   state_change_flags change_trigger = CHANGED_ALL); -		void StopRecording (); - - -	private: // methods -		// start reading asynchronously from the controller -		bool BeginAsyncRead			(); -		// request status update (battery level, extension status etc) -		void RequestStatusReport	(); -		// read address or register from Wiimote asynchronously (the result is -		//  parsed internally whenever it arrives) -		bool ReadAddress			(int address, short size); -		// write a single BYTE to a wiimote address or register -		inline void WriteData		(int address, BYTE data) { WriteData(address, 1, &data); } -		// write a BYTE array to a wiimote address or register -		void WriteData				(int address, BYTE size, const BYTE* buff); -		// callback when data is ready to be processed -		void OnReadData				(DWORD bytes_read); -		// parse individual reports by type -		int	 ParseInput				(BYTE* buff); -		// detects if MotionPlus is attached (it doesn't report as a normal -		//  extesnion until it is enabled) -		void DetectMotionPlusExtensionAsync (); -		// initializes an extension when plugged in. -		void InitializeExtension	(); -		// parses a status report -		int	 ParseStatus		    (BYTE* buff); -		// parses the buttons -		int	 ParseButtons			(BYTE* buff); -		// parses accelerometer data -		int	 ParseAccel				(BYTE* buff); -		bool EstimateOrientationFrom(wiimote_state::acceleration &accel); -		void ApplyJoystickDeadZones (wiimote_state::joystick &joy); -		// parses IR data from report -		int  ParseIR				(BYTE* buff); -		// parses data from an extension. -		int  ParseExtension			(BYTE* buff, unsigned offset); -		// parses data returned from a read report -		int  ParseReadAddress		(BYTE* buff); -		// reads calibration information stored on Wiimote -		void ReadCalibration		(); -		float GetBalanceValue(short sensor, short min, short mid, short max); -		// turns on the IR sensor (the mode must match the reporting mode caps) -		void EnableIR				(wiimote_state::ir::mode mode); -		// disables the IR sensor -		void DisableIR				(); -		// writes a report to the Wiimote (NULL = use 'WriteBuff') -		bool WriteReport			(BYTE* buff); -		bool StartSampleThread		(); -		// returns the rumble BYTE that needs to be sent with reports. -		inline BYTE  GetRumbleBit	()	const { return Internal.bRumble? 0x01 : 0x00; } - -		// static thread funcs: -		static unsigned __stdcall ReadParseThreadfunc   (void* param); -		static unsigned __stdcall AsyncRumbleThreadfunc (void* param); -		static unsigned __stdcall SampleStreamThreadfunc(void* param); -		static unsigned __stdcall HIDwriteThreadfunc	(void* param); - -	private: // data -		// wiimote output comands -		enum output_report -			{ -			OUT_NONE			= 0x00, -			OUT_LEDs			= 0x11, -			OUT_TYPE			= 0x12, -			OUT_IR				= 0x13, -			OUT_SPEAKER_ENABLE	= 0x14, -			OUT_STATUS			= 0x15, -			OUT_WRITEMEMORY		= 0x16, -			OUT_READMEMORY		= 0x17, -			OUT_SPEAKER_DATA	= 0x18, -			OUT_SPEAKER_MUTE	= 0x19, -			OUT_IR2				= 0x1a, -			}; -		// input reports used only internally: -		static const int IN_STATUS						= 0x20; -		static const int IN_READADDRESS					= 0x21; -		// wiimote device IDs: -		static const int VID							= 0x057e; // 'Nintendo' -		static const int PID							= 0x0306; // 'Wiimote' -		// we could find this out the hard way using HID, but it's 22 -		static const int REPORT_LENGTH					= 22; -		// wiimote registers -		static const int REGISTER_CALIBRATION			= 0x0016; -		static const int REGISTER_IR					= 0x4b00030; -		static const int REGISTER_IR_SENSITIVITY_1		= 0x4b00000; -		static const int REGISTER_IR_SENSITIVITY_2		= 0x4b0001a; -		static const int REGISTER_IR_MODE				= 0x4b00033; -		static const int REGISTER_EXTENSION_INIT1		= 0x4a400f0; -		static const int REGISTER_EXTENSION_INIT2		= 0x4a400fb; -		static const int REGISTER_EXTENSION_TYPE		= 0x4a400fa; -		static const int REGISTER_EXTENSION_CALIBRATION	= 0x4a40020; -		static const int REGISTER_BALANCE_CALIBRATION	= 0x4a40024; -		static const int REGISTER_MOTIONPLUS_DETECT		= 0x4a600fa; -		static const int REGISTER_MOTIONPLUS_INIT		= 0x4a600f0; -		static const int REGISTER_MOTIONPLUS_ENABLE		= 0x4a600fe; - -		HANDLE			 Handle;		  // read/write device handle -		OVERLAPPED		 Overlapped;	  // for async Read/WriteFile() IO -		HANDLE			 ReadParseThread; // waits for overlapped reads & parses result -		EVENT			 DataRead;		  // signals overlapped read complete -		bool			 bUseHIDwrite;	  // alternative write method (less efficient -										  //  but required for some BT stacks (eg. MS') -		// HidD_SetOutputReport is only supported from XP onwards, so detect & -		//  load it dynamically: -		static HMODULE	 HidDLL;	 -		static hidwrite_ptr _HidD_SetOutputReport; -		 -		volatile bool	 bStatusReceived;	  // for output method detection -		volatile bool	 bConnectInProgress;  // don't handle extensions until complete -		volatile bool	 bInitInProgress;	  // stop regular requests until complete -		volatile bool	 bEnablingMotionPlus; // for special init codepath -		volatile bool	 bConnectionLost;	  // auto-Disconnect()s if set -volatile int	 MotionPlusDetectCount;		  // waiting for the result -		volatile bool	 bMotionPlusDetected; -		volatile bool	 bMotionPlusEnabled; -		volatile bool	 bMotionPlusExtension;// detected one plugged into MotionPlus -		volatile bool	 bCalibrateAtRest;	  // as soon as the first sensor values 											  //  come in after a Connect() call. -		static unsigned	 _TotalCreated; -		static unsigned	 _TotalConnected; -		input_report	 ReportType;	      // type of data the wiimote delivers	 -		// read buffer -		BYTE			 ReadBuff  [REPORT_LENGTH]; -		// for polling: state is updated on a thread internally, and made only -		//  made public via RefreshState() -		CRITICAL_SECTION StateLock;	 -		wiimote_state	 Internal; -		state_change_flags InternalChanged;   // state changes since last RefreshState() -		// periodic status report requests (for battery level and connection loss -		//  detection) -		DWORD			  NextStatusTime; -		DWORD			  NextMPlusDetectTime;// gap between motion plus detections -		DWORD			  MPlusDetectCount;	  // # of detection tries in quick succesion -		// async Hidd_WriteReport() thread -		HANDLE			  HIDwriteThread; -#ifdef USE_DYNAMIC_HIDQUEUE -		std::queue<BYTE*> HIDwriteQueue; -#else -		// fixed-size queue (to eliminate glitches caused by frequent dynamic memory -		//	allocations) -		struct hid -			{ -			hid () : Queue(NULL), ReadIndex(0), WriteIndex(0) {} - -			// Increase the static queue size if you get ASSERTs signalling an -			//  overflow (too many reports queued up before being sent by the write -			//  thread).  These asserts are harmless though if caused as a result of -			//  loosing the wiimote connection (eg. battery runs out, or wiimote is -			//  unpaired by holding the power button). -			// Note: MAX_QUEUE_ENTRIES _must_ be a power-of-2, as it -			//  uses index wraparound optimisations. -			static const unsigned MAX_QUEUE_ENTRIES = 1<<7; -		 -			inline bool IsEmpty() const { return (ReadIndex == WriteIndex); } - -			bool Allocate	()	{ // allocate memory (only when needed) -								_ASSERT(!Queue); if(Queue) return true; -								ReadIndex = WriteIndex = 0; -								Queue = new queue_entry[MAX_QUEUE_ENTRIES]; -								_ASSERT(Queue); return (Queue != NULL); -								} -			void Deallocate ()	{ -								if(!Queue) return; -								delete[] Queue; Queue = NULL; -								ReadIndex = WriteIndex = 0; -								} -								 -			struct queue_entry -				{ -				queue_entry() { memset(Report, 0, sizeof(Report)); } -				 -				BYTE Report [REPORT_LENGTH]; -				} *Queue; -			 -			unsigned ReadIndex, WriteIndex; -			} HID; -#endif -		CRITICAL_SECTION  HIDwriteQueueLock;  // queue must be locked before being  modified - -		// async rumble -		HANDLE			 AsyncRumbleThread;	  // automatically disables rumble if requested -		volatile DWORD	 AsyncRumbleTimeout; -		// orientation estimation -		unsigned		 WiimoteNearGUpdates; -		unsigned		 NunchukNearGUpdates; -		// audio -		HANDLE			 SampleThread; -		const wiimote_sample* volatile CurrentSample;	// otherwise playing square wave -		// state recording -		struct recording -			{ -			volatile bool	bEnabled; -			state_history	*StateHistory; -			volatile DWORD	StartTimeMS; -			volatile DWORD	EndTimeMS;		// can be UNTIL_STOP -			unsigned		TriggerFlags;	// wiimote changes trigger a state event -			unsigned		ExtTriggerFlags;// extension changes " -			} Recording; -	}; - -#endif // _WIIMOTE_H
\ No newline at end of file diff --git a/tracker-pt/wiiyourself/wiimote_common.h b/tracker-pt/wiiyourself/wiimote_common.h deleted file mode 100644 index c0fd01e1..00000000 --- a/tracker-pt/wiiyourself/wiimote_common.h +++ /dev/null @@ -1,109 +0,0 @@ -// _______________________________________________________________________________ -// -//	 - WiiYourself! - native C++ Wiimote library  v1.15 RC -//	  (c) gl.tter 2007-9 - http://gl.tter.org -// -//	  see License.txt for conditions of use.  see History.txt for change log. -// _______________________________________________________________________________ -// -//  wiimote_common.h  (tab = 4 spaces) - -// speaker support: -enum speaker_freq -	{ -	// (keep in sync with FreqLookup in wiimote.cpp) -	FREQ_NONE	= 0, -	// my PC can't keep up with these using bUseHIDwrite, so I haven't -	//  been able to tune them yet -	FREQ_4200HZ = 1, -	FREQ_3920HZ = 2, -	FREQ_3640HZ = 3, -	FREQ_3360HZ = 4, -	// these were tuned until the square-wave was glitch-free on my remote - -	//  may not be exactly right -	FREQ_3130HZ = 5,	// +190 -	FREQ_2940HZ = 6,	// +180 -	FREQ_2760HZ = 7,	// +150 -	FREQ_2610HZ = 8,	// +140 -	FREQ_2470HZ = 9, -	}; - -// wiimote_sample - holds the audio sample in the native wiimote format -struct wiimote_sample -	{ -	wiimote_sample() : samples(NULL), length(0), freq(FREQ_NONE) {} -	BYTE*		 samples; -	DWORD		 length; -	speaker_freq freq; -	}; - -// flags & masks that indicate which part(s) of the wiimote state have changed -enum state_change_flags -	{ -	// state didn't change at all -	NO_CHANGE					   = 0, - -	// Wiimote specific: -	CONNECTED					   = 1<<0, // wiimote just connected -	CONNECTION_LOST				   = 1<<1, -	BATTERY_CHANGED				   = 1<<2, -	BATTERY_DRAINED				   = 1<<3, // close to empty -	LEDS_CHANGED				   = 1<<4, // (probably redudant as wiimmote never -	BUTTONS_CHANGED				   = 1<<5, //  changes them unless requested) -	ACCEL_CHANGED				   = 1<<6, -	ORIENTATION_CHANGED			   = 1<<7, -	IR_CHANGED					   = 1<<8, -	//  all wiimote flags -	WIIMOTE_CHANGED				   = CONNECTION_LOST|BATTERY_CHANGED|BATTERY_DRAINED| -								     LEDS_CHANGED|BUTTONS_CHANGED|ACCEL_CHANGED| -								     ORIENTATION_CHANGED|IR_CHANGED, -	// - Extensions -: -	//  Nunchuk: -	NUNCHUK_CONNECTED			   = 1<<9, -	NUNCHUK_BUTTONS_CHANGED		   = 1<<10, -	NUNCHUK_ACCEL_CHANGED		   = 1<<11, -	NUNCHUK_ORIENTATION_CHANGED	   = 1<<12, -	NUNCHUK_JOYSTICK_CHANGED	   = 1<<13, -	//   all flags -	NUNCHUK_CHANGED				   = NUNCHUK_CONNECTED|NUNCHUK_BUTTONS_CHANGED| -								     NUNCHUK_ACCEL_CHANGED|NUNCHUK_ORIENTATION_CHANGED| -								     NUNCHUK_JOYSTICK_CHANGED, -	//  Classic Controller (inc. Guitars etc): -	CLASSIC_CONNECTED			   = 1<<14, -	CLASSIC_BUTTONS_CHANGED		   = 1<<15, -	CLASSIC_JOYSTICK_L_CHANGED	   = 1<<16, -	CLASSIC_JOYSTICK_R_CHANGED	   = 1<<17, -	CLASSIC_TRIGGERS_CHANGED	   = 1<<18, -	//   all flags -	CLASSIC_CHANGED				   = CLASSIC_CONNECTED|CLASSIC_BUTTONS_CHANGED| -								     CLASSIC_JOYSTICK_L_CHANGED| -								     CLASSIC_JOYSTICK_R_CHANGED| -									 CLASSIC_TRIGGERS_CHANGED, -	//  Balance Board: -	BALANCE_CONNECTED			   = 1<<19, -	BALANCE_WEIGHT_CHANGED		   = 1<<20, -	//   all flags -	BALANCE_CHANGED				   = BALANCE_CONNECTED|BALANCE_WEIGHT_CHANGED, - -	//  Motion Plus -	MOTIONPLUS_DETECTED			   = 1<<21, // attached but not enabled -	MOTIONPLUS_ENABLED			   = 1<<22, -	MOTIONPLUS_SPEED_CHANGED	   = 1<<23, -	MOTIONPLUS_EXTENSION_CONNECTED = 1<<24,		// an extension is found in the -												//  MotionPlus port -	MOTIONPLUS_EXTENSION_DISCONNECTED = 1<<25, // it was disconnected -	//   all flags -	MOTIONPLUS_CHANGED			   = MOTIONPLUS_DETECTED|MOTIONPLUS_ENABLED| -									 MOTIONPLUS_SPEED_CHANGED| -									 MOTIONPLUS_EXTENSION_CONNECTED| -									 MOTIONPLUS_EXTENSION_DISCONNECTED, -	//  General: -	EXTENSION_DISCONNECTED		 = 1<<26, -	EXTENSION_PARTIALLY_INSERTED = 1<<27, -	EXTENSION_CONNECTED			 = NUNCHUK_CONNECTED|CLASSIC_CONNECTED| -								   BALANCE_CONNECTED|MOTIONPLUS_ENABLED, -	EXTENSION_CHANGED			 = EXTENSION_DISCONNECTED|NUNCHUK_CHANGED| -								   CLASSIC_CHANGED|BALANCE_CHANGED|MOTIONPLUS_CHANGED, -	//  ALL flags: -	CHANGED_ALL					 = WIIMOTE_CHANGED|EXTENSION_CHANGED, -	}; diff --git a/tracker-pt/wiiyourself/wiimote_state.h b/tracker-pt/wiiyourself/wiimote_state.h deleted file mode 100644 index 1bf167a2..00000000 --- a/tracker-pt/wiiyourself/wiimote_state.h +++ /dev/null @@ -1,379 +0,0 @@ -// _______________________________________________________________________________ -// -//	 - WiiYourself! - native C++ Wiimote library  v1.15 -//	  (c) gl.tter 2007-10 - http://gl.tter.org -// -//	  see License.txt for conditions of use.  see History.txt for change log. -// _______________________________________________________________________________ -// -//  wiimote_state.h  (tab = 4 spaces) - -// the 'wiimote_state' struct contains all the Wiimote and Extension state data -//  (buttons etc) - the wiimote class inherits from this and the app can poll -//  the data there at any time. -#ifdef _MSC_VER // VC -# pragma once -#endif - -#ifndef _WIIMOTE_STATE_H -# define _WIIMOTE_STATE_H - -#include "wiimote_common.h" - - -// wiimote_state (contains the Wiimote and Extension data and settings) -struct wiimote_state -	{ -	friend class wiimote; // for Clear() - -	// calibration information (stored on the Wiimote) -	struct calibration_info -		{ -		BYTE X0, Y0, Z0; -		BYTE XG, YG, ZG; -		} CalibrationInfo; - -	// button state: -	struct buttons -		{ -		// convenience accessors -		inline bool A		() const	{ return (Bits & _A)    != 0; } -		inline bool B		() const	{ return (Bits & _B)	!= 0; } -		inline bool Plus	() const	{ return (Bits & PLUS)  != 0; } -		inline bool Home	() const	{ return (Bits & HOME)  != 0; } -		inline bool Minus	() const	{ return (Bits & MINUS) != 0; } -		inline bool One		() const	{ return (Bits & ONE)   != 0; } -		inline bool Two		() const	{ return (Bits & TWO)   != 0; } -		inline bool Up		() const	{ return (Bits & UP)	!= 0; } -		inline bool Down	() const	{ return (Bits & DOWN)  != 0; } -		inline bool Left	() const	{ return (Bits & LEFT)  != 0; } -		inline bool Right	() const	{ return (Bits & RIGHT) != 0; } - -		// all 11 buttons stored as bits (set = pressed) -		WORD Bits; - -		// button bit masks (little-endian order) -		enum mask -			{ -			LEFT	= 0x0001, -			RIGHT	= 0x0002, -			DOWN	= 0x0004, -			UP		= 0x0008, -			PLUS	= 0x0010, -			TWO		= 0x0100, -			ONE		= 0x0200, -			_B		= 0x0400,	// ie. trigger -			_A		= 0x0800, -			MINUS	= 0x1000, -			HOME	= 0x8000, -			// -			ALL		= LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME, -			}; -		} Button; - -	// accelerometers state: -	struct acceleration -		{ -		BYTE  RawX, RawY, RawZ; -		float X, Y, Z; - -		// note: experimental! the orientation values can only be safely estimated -		//        if the controller isn't accelerating (otherwise there is no -		//		  simple way to seperate orientation from acceleration - except -		//		  perhaps using the IR reference and/or some clever assumptions). -		//		  so for now the code only updates orientation if the controller -		//		  appear to be stationary (by checking if the acceleration vector -		//		  length is near 1G for several updates in a row). -		//		  also note that there is no way to detect Yaw from the accelerometer -		//		  alone when it's pointing at the screen (and I'm not curently -		//		  processing IR): -		struct orientation -			{ -			float X, Y, Z; -			unsigned UpdateAge;	// how many acceleration updates ago the last -								//  orientation estimate was made (if this -								//  value is high, the values are out-of-date -								//  and probably shouldn't be used). -			// Euler angle support (useful for some things). -			// * note that decomposing to Euler angles is complex, not always reliable, -			//    and also depends on your assumptions about the order each component -			//    is applied in.  you may need to handle this yourself for more -			//    complex scenarios * -			float	 Pitch;	// in degrees (-180 - +180) -			float	 Roll;	// " -			// float Yaw;	 -			} Orientation; -		} Acceleration; - -	// IR camera state: -	struct ir -		{ -		// in theory the IR imager is 1024x768 and so should report raw coords -		//  0-1023 x 0-767.  in practice I have never seen them exceed the values -		//  below, so I'm using them instead to give the full 0-1 float range -		//  (it's possible that the edge pixels are used for processing, or masked -		//  out due to being unreliable).  let me know if your wiimote reports -		//  a different range. -		static const unsigned MAX_RAW_X = 1016; -		static const unsigned MAX_RAW_Y =  760; - -		// data mode reported by the IR sensor -		enum mode -			{ -			OFF			= 0x00, -			BASIC		= 0x01,	// 10 bytes -			EXTENDED	= 0x03,	// 12 bytes -			FULL		= 0x05,	// 16 bytes * 2 (format unknown) -			}; -		 -		mode	Mode;		// read-only (depends on ReportType set) -		 -		struct dot -			{ -			bool     bVisible;	// other values are not valid if == false -			unsigned RawX; -			unsigned RawY; -			float    X;			// 0-1 (left-right) -			float    Y;			// "   (top -bottom) -			int		 Size;		// (not available in BASIC mode) -			} Dot[4]; -		} IR; - -	struct leds -		{ -		// all LEDs stored in bits 0-3  (1 = lit) -		 BYTE Bits; - -		// convenience accessors: -		inline bool Lit (unsigned index) -			{ _ASSERT(index < 4); -			  return (index >= 4)? false : ((Bits & (1<<index)) != 0); } -		} LED; - -	 BYTE BatteryRaw;		// 0 - ~200 (it seems 200 *may* be the maximum charge) -	 BYTE BatteryPercent;	// (using the above assumption, where 200 raw = 100%) -	 bool bBatteryDrained;	// battery is nearly flat -	 bool bRumble; -	 bool bExtension;		// an extension (eg. Nunchuk) is connected. - -	// speaker state: -	struct speaker -		{ -		 bool		  bEnabled; -		 bool		  bMuted; -		 speaker_freq Freq; -		 BYTE		  Volume; -		} Speaker; - -	// the extension plugged into the Wiimote (if any) -	enum extension_type -		{ -		NONE = 0, -		NUNCHUK, -		CLASSIC, -		GH3_GHWT_GUITAR, // GH3 or GHWT Guitar (treated as Classic) -		GHWT_DRUMS,		 // not yet used -		BALANCE_BOARD, -		MOTION_PLUS, -		PARTIALLY_INSERTED, -		}; -	 extension_type	ExtensionType; - -	// joystick struct (shared between Nunchuk & Classic Controller) -	struct joystick -		{ -		friend class wiimote; -		 -		// raw unprocessed coordinates: -		float RawX, RawY; - -		// processed coordinates in approximately -1 - +1 range (includes calibration -		//  data and deadzones) - note that due to calibration inaccuracies, the -		//  extremes may be slightly over/under (+-)1.0. -		float X, Y; - -		// a 'deadzone' is a user-defined range near the joystick center which -		//  is treated as zero (joysticks often drift a little even at the center -		//  position).  you can set a deadzone for each axis at any time, range is -		//  0.0 (off) to 1.0 (entire range - not useful :). try 0.03. -		struct deadzone -			{ -			 float X, Y; -			} DeadZone; -		}; - -	// Nunchuk state (if connected) -	struct nunchuk -		{ -		struct calibration_info -			{ -			 BYTE X0, Y0, Z0; -			 BYTE XG, YG, ZG; -			 BYTE MinX, MidX, MaxX; -			 BYTE MinY, MidY, MaxY; -			} CalibrationInfo; - -		acceleration  Acceleration; -		joystick	  Joystick; -		 bool C; -		 bool Z; -		} Nunchuk; - -	// Classic Controller state (if connected) -	struct classic_controller -		{ -		// calibration information (stored on the controller) -		struct calibration_info -			{ -			 BYTE MinXL, MidXL, MaxXL; -			 BYTE MinYL, MidYL, MaxYL; -			 BYTE MinXR, MidXR, MaxXR; -			 BYTE MinYR, MidYR, MaxYR; -			 BYTE MinTriggerL, MaxTriggerL; -			 BYTE MinTriggerR, MaxTriggerR; -			} CalibrationInfo; - -		// button state -		struct buttons -			{ -			// convenience accessors -			inline  bool A			() const { return (Bits & _A)	  != 0; } -			inline  bool B			() const { return (Bits & _B)	  != 0; } -			inline  bool Plus		() const { return (Bits & PLUS)   != 0; } -			inline  bool Minus		() const { return (Bits & MINUS)  != 0; } -			inline  bool Home		() const { return (Bits & HOME)   != 0; } -			inline  bool Up			() const { return (Bits & UP)     != 0; } -			inline  bool Down		() const { return (Bits & DOWN)   != 0; } -			inline  bool Left		() const { return (Bits & LEFT)   != 0; } -			inline  bool Right		() const { return (Bits & RIGHT)  != 0; } -			inline  bool X			() const { return (Bits & _X)	  != 0; } -			inline  bool Y			() const { return (Bits & _Y)	  != 0; } -			inline  bool ZL			() const { return (Bits & _ZL)	  != 0; } -			inline  bool ZR			() const { return (Bits & _ZR)	  != 0; } -			inline  bool TriggerL	() const { return (Bits & TRIG_L) != 0; } -			inline  bool TriggerR	() const { return (Bits & TRIG_R) != 0; } -			 -			// all 15 buttons stored as bits (set = pressed) -			 WORD Bits; - -			// button bitmasks (little-endian order) -			enum mask -				{ -				TRIG_R  = 0x0002, -				PLUS    = 0x0004, -				HOME    = 0x0008, -				MINUS   = 0x0010, -				TRIG_L  = 0x0020, -				DOWN    = 0x0040, -				RIGHT   = 0x0080, -				UP      = 0x0100, -				LEFT    = 0x0200, -				_ZR     = 0x0400, -				_X      = 0x0800, -				_A      = 0x1000, -				_Y      = 0x2000, -				_B      = 0x4000, -				_ZL     = 0x8000, -				// -				ALL		= TRIG_R|PLUS|HOME|MINUS|TRIG_L|DOWN|RIGHT|UP|LEFT| -						  _ZR|_X|_A|_Y|_B|_ZL, -				}; -			} Button; - -		// joysticks -		joystick JoystickL; -		joystick JoystickR; - -		// triggers -		BYTE  RawTriggerL, RawTriggerR; -		float TriggerL, TriggerR; -		} ClassicController; - -	struct balance_board -		{ -		// values for each of the board's 4 sensors: -		//  (these values are always exposed unmodifed) -		struct sensors_raw -			{ -			short	 TopR; -			short	 TopL; -			short BottomR; -			short BottomL; -			}; -		struct sensors_f -			{ -			float	 TopL; -			float	 TopR; -			float BottomL; -			float BottomR; -			 -			float Total; // sum of the 4 corner weights -			}; - -		// calibration info -		struct calibration_info -			{ -			sensors_raw Kg0;	// calibration at  0 Kg -			sensors_raw Kg17;	// "			  17 Kg -			sensors_raw Kg34;	// "			  34 Kg -			} CalibrationInfo; - -		// state: -		sensors_raw	Raw;	  // raw values (per sensor) -		sensors_f	AtRestKg; // set by Connect() and CalibrateAtRest() -		//  (the values below have their 'at-rest' offsets automatically removed) -		sensors_f	Kg;		  // kilograms  (per sensor) -		sensors_f	Lb;		  // pounds	  (per sensor) -		} BalanceBoard; - -	struct motion_plus -		{ -		//  (these values are always exposed unmodifed) -		struct sensors_raw -			{ -			short Yaw; -			short Pitch; -			short Roll; -			}; -		struct sensors_f -			{ -			float Yaw; -			float Pitch; -			float Roll; -			}; - -		// state: -		sensors_raw	Raw; -		sensors_f	Speed; -		} MotionPlus; - -	// ---- internal use only ---- -	protected:  -		 unsigned WiimoteNearGUpdates; -		 unsigned NunchukNearGUpdates; - -		void Clear (bool including_deadzones) -			{ -			joystick::deadzone nunchuk_deadzone, -							   classic_joyl_deadzone, -							   classic_joyr_deadzone; -		 -			// preserve the deadzone settings? -			if(!including_deadzones) { -				nunchuk_deadzone	  = Nunchuk.Joystick.DeadZone; -				classic_joyl_deadzone = ClassicController.JoystickL.DeadZone; -				classic_joyr_deadzone = ClassicController.JoystickR.DeadZone; -				} - -			memset(this, 0, sizeof(wiimote_state)); - -			// restore the deadzones? -			if(!including_deadzones) { -				Nunchuk.Joystick.DeadZone			 = nunchuk_deadzone; -				ClassicController.JoystickL.DeadZone = classic_joyl_deadzone; -				ClassicController.JoystickR.DeadZone = classic_joyr_deadzone; -				} -			} -	}; - -#endif // _WIIMOTE_STATE_H
\ No newline at end of file  | 
