Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes

wiimote Class Reference

#include <wiimote.h>

Inheritance diagram for wiimote:
Inheritance graph
[legend]
Collaboration diagram for wiimote:
Collaboration graph
[legend]

List of all members.

Classes

struct  hid
struct  recording

Public Types

enum  input_report {
  IN_BUTTONS = 0x30, IN_BUTTONS_ACCEL = 0x31, IN_BUTTONS_ACCEL_IR = 0x33, IN_BUTTONS_ACCEL_EXT = 0x35,
  IN_BUTTONS_ACCEL_IR_EXT = 0x37, IN_BUTTONS_BALANCE_BOARD = 0x32
}
typedef wiimote_state_event state_event
typedef std::list< state_eventstate_history

Public Member Functions

 wiimote ()
virtual ~wiimote ()
bool operator== (const wiimote &remote)
bool operator!= (const wiimote &remote)
bool IsConnected () const
bool ConnectionLost () const
bool IsBalanceBoard () const
bool NunchukConnected () const
bool ClassicConnected () const
bool MotionPlusConnected () const
bool MotionPlusEnabled () const
bool MotionPlusHasExtension () const
bool IsPlayingAudio () const
bool IsPlayingSample () const
bool IsUsingHIDwrites () const
bool IsRecordingState () const
virtual void ChangedNotifier (state_change_flags changed, const wiimote_state &new_state)
bool Connect (unsigned wiimote_index=FIRST_AVAILABLE, bool force_hidwrites=false)
void Disconnect ()
void SetReportType (input_report type, bool continuous=false)
bool EnableMotionPlus ()
bool DisableMotionPlus ()
void CalibrateAtRest ()
state_change_flags RefreshState ()
void Reset ()
void SetLEDs (BYTE led_bits)
void SetRumble (bool on)
void RumbleForAsync (unsigned milliseconds)
bool MuteSpeaker (bool on)
bool EnableSpeaker (bool on)
bool PlaySquareWave (speaker_freq freq, BYTE volume=0x40)
bool PlaySample (const wiimote_sample &sample, BYTE volume=0x40, speaker_freq freq_override=FREQ_NONE)
void RecordState (state_history &events_out, unsigned max_time_ms=UNTIL_STOP, state_change_flags change_trigger=CHANGED_ALL)
void StopRecording ()

Static Public Member Functions

static unsigned TotalConnected ()
static const TCHAR * GetButtonNameFromBit (unsigned index)
static const TCHAR * GetClassicButtonNameFromBit (unsigned index)
static const unsigned GetFreqLookup (unsigned index)
static bool Load16bitMonoSampleWAV (const TCHAR *filepath, wiimote_sample &out)
static bool Load16BitMonoSampleRAW (const TCHAR *filepath, bool _signed, speaker_freq freq, wiimote_sample &out)
static bool Convert16bitMonoSamples (const short *samples, bool _signed, DWORD length, speaker_freq freq, wiimote_sample &out)

Public Attributes

QWORD UniqueID
state_changed_callback ChangedCallback
state_change_flags CallbackTriggerFlags

Static Public Attributes

static const TCHAR * ReportTypeName []
static const TCHAR * ButtonNameFromBit [16]
static const TCHAR * ClassicButtonNameFromBit [16]
static const unsigned FreqLookup [10]
static const unsigned FIRST_AVAILABLE = 0xffffffff
static const unsigned UNTIL_STOP = 0xffffffff

Detailed Description

Definition at line 92 of file wiimote.h.


Member Typedef Documentation

Definition at line 283 of file wiimote.h.

typedef std::list<state_event> wiimote::state_history

Definition at line 285 of file wiimote.h.


Member Enumeration Documentation

Enumerator:
IN_BUTTONS 
IN_BUTTONS_ACCEL 
IN_BUTTONS_ACCEL_IR 
IN_BUTTONS_ACCEL_EXT 
IN_BUTTONS_ACCEL_IR_EXT 
IN_BUTTONS_BALANCE_BOARD 

Definition at line 108 of file wiimote.h.

                        {
                        // 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
                        };

Constructor & Destructor Documentation

wiimote::wiimote (  )

Definition at line 129 of file wiimote.cpp.

References _ASSERT, wiimote_state::Clear(), INVALID_HANDLE_VALUE, TRACE, and WARN.

        :
        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 (  ) [virtual]

Definition at line 199 of file wiimote.cpp.

References Disconnect(), and INVALID_HANDLE_VALUE.

        {
        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;
                }
        }

Member Function Documentation

void wiimote::CalibrateAtRest (  )

Definition at line 467 of file wiimote.cpp.

References _ASSERT, wiimote_state::balance_board::AtRestKg, wiimote_state::BalanceBoard, IsBalanceBoard(), IsConnected(), wiimote_state::balance_board::Kg, RefreshState(), and TRACE.

        {
        _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();
                }
        }
virtual void wiimote::ChangedNotifier ( state_change_flags  changed,
const wiimote_state new_state 
) [inline, virtual]

Definition at line 164 of file wiimote.h.

Referenced by Connect().

                                                                                                                                 {};
bool wiimote::ClassicConnected (  ) const [inline]

Definition at line 130 of file wiimote.h.

References wiimote_state::bExtension, wiimote_state::CLASSIC, and wiimote_state::ExtensionType.

                                                                   { return (Internal.bExtension &&
                                                        (Internal.ExtensionType==wiimote_state::CLASSIC)); }
bool wiimote::Connect ( unsigned  wiimote_index = FIRST_AVAILABLE,
bool  force_hidwrites = false 
)

Definition at line 224 of file wiimote.cpp.

References _ASSERT, wiimote_state::CalibrationInfo, CallbackTriggerFlags, ChangedCallback, ChangedNotifier(), wiimote_state::Clear(), CONNECTED, DEEP_TRACE, DETECT_MPLUS_COUNT, DETECT_MPLUS_EVERY_MS, Disconnect(), FIRST_AVAILABLE, INVALID_HANDLE_VALUE, IsConnected(), NO_CHANGE, RefreshState(), REQUEST_STATUS_EVERY_MS, Reset(), TRACE, UniqueID, and WARN.

        {
        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,
                                                                                                        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;
        }
bool wiimote::ConnectionLost (  ) const [inline]

Definition at line 125 of file wiimote.h.

{ return bConnectionLost; }
bool wiimote::Convert16bitMonoSamples ( const short *  samples,
bool  _signed,
DWORD  length,
speaker_freq  freq,
wiimote_sample out 
) [static]

Definition at line 2594 of file wiimote.cpp.

References _ASSERT, wiimote_sample::freq, wiimote_sample::length, and wiimote_sample::samples.

Referenced by Load16BitMonoSampleRAW(), and Load16bitMonoSampleWAV().

        {
        // 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::DisableMotionPlus (  )

Definition at line 1086 of file wiimote.cpp.

References TRACE.

Referenced by Reset().

        {
        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::Disconnect (  )

Definition at line 482 of file wiimote.cpp.

References _ASSERT, wiimote_state::Clear(), INVALID_HANDLE_VALUE, IsConnected(), NO_CHANGE, Reset(), TRACE, and UniqueID.

Referenced by Connect(), and ~wiimote().

        {
        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;
        }
bool wiimote::EnableMotionPlus (  )

Definition at line 1062 of file wiimote.cpp.

References _ASSERT, and TRACE.

        {
        _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::EnableSpeaker ( bool  on )

Definition at line 2208 of file wiimote.cpp.

References _ASSERT, wiimote_state::speaker::bEnabled, wiimote_state::speaker::Freq, FREQ_NONE, IsConnected(), MuteSpeaker(), wiimote_state::Speaker, TRACE, and wiimote_state::speaker::Volume.

Referenced by PlaySample(), PlaySquareWave(), and Reset().

        {
        _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;
        }
static const TCHAR* wiimote::GetButtonNameFromBit ( unsigned  index ) [inline, static]

Definition at line 169 of file wiimote.h.

References _ASSERT, ButtonNameFromBit, and TOTAL_BUTTON_BITS.

                        {
                        _ASSERT(index < TOTAL_BUTTON_BITS);
                        if(index >= TOTAL_BUTTON_BITS)
                                return _T("[invalid index]");
                        return ButtonNameFromBit[index];
                        }
static const TCHAR* wiimote::GetClassicButtonNameFromBit ( unsigned  index ) [inline, static]

Definition at line 179 of file wiimote.h.

References _ASSERT, ClassicButtonNameFromBit, and TOTAL_BUTTON_BITS.

                        {
                        _ASSERT(index < TOTAL_BUTTON_BITS);
                        if(index >= TOTAL_BUTTON_BITS)
                                return _T("[invalid index]");
                        return ClassicButtonNameFromBit[index];
                        }
static const unsigned wiimote::GetFreqLookup ( unsigned  index ) [inline, static]

Definition at line 189 of file wiimote.h.

References _ASSERT, FreqLookup, and TOTAL_FREQUENCIES.

                        {
                        _ASSERT(index < TOTAL_FREQUENCIES);
                        if(index >= TOTAL_FREQUENCIES)
                                return 0;
                        return FreqLookup[index];
                        }
bool wiimote::IsBalanceBoard (  ) const [inline]
bool wiimote::IsConnected (  ) const [inline]
bool wiimote::IsPlayingAudio (  ) const [inline]

Definition at line 135 of file wiimote.h.

References wiimote_state::speaker::Freq, wiimote_state::Speaker, and wiimote_state::speaker::Volume.

Referenced by IsPlayingSample(), PlaySquareWave(), and SetRumble().

                                                                   { return (Internal.Speaker.Freq &&
                                                                                                                         Internal.Speaker.Volume); }
bool wiimote::IsPlayingSample (  ) const [inline]

Definition at line 137 of file wiimote.h.

References IsPlayingAudio().

Referenced by PlaySquareWave().

                                                                   { return IsPlayingAudio() &&
                                                                                                                        (CurrentSample != NULL); }
bool wiimote::IsRecordingState (  ) const [inline]

Definition at line 140 of file wiimote.h.

{ return Recording.bEnabled; }
bool wiimote::IsUsingHIDwrites (  ) const [inline]

Definition at line 139 of file wiimote.h.

{ return bUseHIDwrite; }
bool wiimote::Load16BitMonoSampleRAW ( const TCHAR *  filepath,
bool  _signed,
speaker_freq  freq,
wiimote_sample out 
) [static]

Definition at line 2530 of file wiimote.cpp.

References _ASSERT, Convert16bitMonoSamples(), TRACE, and WARN.

        {
        // 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::Load16bitMonoSampleWAV ( const TCHAR *  filepath,
wiimote_sample out 
) [static]

Definition at line 2362 of file wiimote.cpp.

References _ASSERT, ARRAY_ENTRIES, Convert16bitMonoSamples(), FREQ_NONE, FreqLookup, READ, READ_SIZE, TRACE, and WARN.

        {
        // 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::MotionPlusConnected (  ) const [inline]

Definition at line 132 of file wiimote.h.

{ return bMotionPlusDetected; }
bool wiimote::MotionPlusEnabled (  ) const [inline]

Definition at line 133 of file wiimote.h.

{ return bMotionPlusEnabled; }
bool wiimote::MotionPlusHasExtension (  ) const [inline]

Definition at line 134 of file wiimote.h.

{ return bMotionPlusExtension; }
bool wiimote::MuteSpeaker ( bool  on )

Definition at line 2186 of file wiimote.cpp.

References _ASSERT, wiimote_state::speaker::bMuted, IsConnected(), wiimote_state::Speaker, and TRACE.

Referenced by EnableSpeaker(), PlaySample(), and PlaySquareWave().

        {
        _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::NunchukConnected (  ) const [inline]

Definition at line 128 of file wiimote.h.

References wiimote_state::bExtension, wiimote_state::ExtensionType, and wiimote_state::NUNCHUK.

                                                                   { return (Internal.bExtension &&
                                                        (Internal.ExtensionType==wiimote_state::NUNCHUK)); }
bool wiimote::operator!= ( const wiimote remote ) [inline]

Definition at line 103 of file wiimote.h.

                        { return Handle != remote.Handle; }
bool wiimote::operator== ( const wiimote remote ) [inline]

Definition at line 101 of file wiimote.h.

                        { return Handle == remote.Handle; }
bool wiimote::PlaySample ( const wiimote_sample sample,
BYTE  volume = 0x40,
speaker_freq  freq_override = FREQ_NONE 
)

Definition at line 2669 of file wiimote.cpp.

References _ASSERT, EnableSpeaker(), wiimote_state::speaker::Freq, wiimote_sample::freq, HANDLE(), IsConnected(), MuteSpeaker(), wiimote_state::Speaker, TRACE, wiimote_state::speaker::Volume, WARN, and WORKER_THREAD_PRIORITY.

        {
        _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::PlaySquareWave ( speaker_freq  freq,
BYTE  volume = 0x40 
)

Definition at line 2725 of file wiimote.cpp.

References _ASSERT, EnableSpeaker(), wiimote_state::speaker::Freq, IsConnected(), IsPlayingAudio(), IsPlayingSample(), MuteSpeaker(), wiimote_state::Speaker, TRACE, and wiimote_state::speaker::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 = UNTIL_STOP,
state_change_flags  change_trigger = CHANGED_ALL 
)

Definition at line 2770 of file wiimote.cpp.

References StopRecording().

        {
        // 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;
        }
state_change_flags wiimote::RefreshState (  )

Definition at line 1016 of file wiimote.cpp.

References wiimote_state::ClassicController, wiimote_state::joystick::DeadZone, wiimote_state::nunchuk::Joystick, wiimote_state::classic_controller::JoystickL, wiimote_state::classic_controller::JoystickR, NO_CHANGE, and wiimote_state::Nunchuk.

Referenced by CalibrateAtRest(), and Connect().

        {
        // 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::Reset (  )

Definition at line 539 of file wiimote.cpp.

References DisableMotionPlus(), EnableSpeaker(), IN_BUTTONS, IN_BUTTONS_BALANCE_BOARD, IsBalanceBoard(), SetLEDs(), SetReportType(), SetRumble(), and TRACE.

Referenced by Connect(), and Disconnect().

        {
        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()
        }
void wiimote::RumbleForAsync ( unsigned  milliseconds )

Definition at line 843 of file wiimote.cpp.

References _ASSERT, HANDLE(), IsConnected(), SetRumble(), WARN, and WORKER_THREAD_PRIORITY.

        {
        // 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::SetLEDs ( BYTE  led_bits )

Definition at line 779 of file wiimote.cpp.

References _ASSERT, wiimote_state::leds::Bits, IsConnected(), and wiimote_state::LED.

Referenced by Reset().

        {
        _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::SetReportType ( input_report  type,
bool  continuous = false 
)

Definition at line 734 of file wiimote.cpp.

References _ASSERT, wiimote_state::ir::BASIC, wiimote_state::ir::EXTENDED, IN_BUTTONS, IN_BUTTONS_ACCEL_EXT, IN_BUTTONS_ACCEL_IR, IN_BUTTONS_ACCEL_IR_EXT, IN_BUTTONS_BALANCE_BOARD, IsBalanceBoard(), IsConnected(), TRACE, and TYPE2NAME.

Referenced by Reset().

        {
        _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::SetRumble ( bool  on )

Definition at line 796 of file wiimote.cpp.

References _ASSERT, wiimote_state::bRumble, IsConnected(), and IsPlayingAudio().

Referenced by Reset(), and RumbleForAsync().

        {
        _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);
        }
void wiimote::StopRecording (  )

Definition at line 2795 of file wiimote.cpp.

Referenced by RecordState().

        {
        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?
        }
static unsigned wiimote::TotalConnected (  ) [inline, static]

Definition at line 142 of file wiimote.h.

{ return _TotalConnected; }

Member Data Documentation

const TCHAR * wiimote::ButtonNameFromBit [static]
Initial value:
                                                                { _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") }

Definition at line 165 of file wiimote.h.

Referenced by GetButtonNameFromBit().

Definition at line 162 of file wiimote.h.

Referenced by Connect(), and mitk::WiiMoteThread::WiiMoteThread().

Definition at line 159 of file wiimote.h.

Referenced by Connect(), and mitk::WiiMoteThread::WiiMoteThread().

const TCHAR * wiimote::ClassicButtonNameFromBit [static]
Initial value:
                                                                { _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") }

Definition at line 178 of file wiimote.h.

Referenced by GetClassicButtonNameFromBit().

const unsigned wiimote::FIRST_AVAILABLE = 0xffffffff [static]
const unsigned wiimote::FreqLookup [static]
Initial value:
 
                                                                {    0, 4200, 3920, 3640, 3360,
                                                                  3130, 2940, 2760, 2610, 2470 }

Definition at line 188 of file wiimote.h.

Referenced by GetFreqLookup(), and Load16bitMonoSampleWAV().

const TCHAR* wiimote::ReportTypeName[] [static]

Definition at line 119 of file wiimote.h.

Definition at line 146 of file wiimote.h.

Referenced by Connect(), and Disconnect().

const unsigned wiimote::UNTIL_STOP = 0xffffffff [static]

Definition at line 286 of file wiimote.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines