2009-07-28 21:32:10 +00:00
// Copyright (C) 2003 Dolphin Project.
2008-12-08 05:25:12 +00:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
2009-01-25 23:07:15 +00:00
# include <iostream> // System
2009-02-09 13:10:29 +00:00
# include <queue>
2008-12-08 05:25:12 +00:00
# include "wiiuse.h"
# include "Common.h"
# include "Thread.h"
2009-01-25 23:07:15 +00:00
# include "StringUtil.h"
2009-02-01 13:01:50 +00:00
# include "Timer.h"
2009-02-09 13:10:29 +00:00
# include "pluginspecs_wiimote.h"
2008-12-08 05:25:12 +00:00
# include "wiimote_hid.h"
2009-01-25 23:07:15 +00:00
# include "main.h"
2009-01-28 16:09:08 +00:00
# include "Config.h"
2008-12-08 05:25:12 +00:00
# include "EmuMain.h"
2009-01-31 01:18:57 +00:00
# include "EmuDefinitions.h"
2009-01-28 16:09:08 +00:00
# define EXCLUDE_H // Avoid certain declarations in wiimote_real.h
2009-01-25 23:07:15 +00:00
# include "wiimote_real.h"
2010-01-12 22:35:28 +00:00
# if defined(HAVE_WX) && HAVE_WX
2010-01-08 20:27:54 +00:00
# include "ConfigRecordingDlg.h"
2010-04-26 17:51:32 +00:00
# include "ConfigBasicDlg.h"
2010-01-12 22:35:28 +00:00
# endif
2010-01-08 20:27:54 +00:00
2010-01-05 17:38:37 +00:00
# ifdef WIN32
# include <bthdef.h>
# include <BluetoothAPIs.h>
2008-12-08 05:25:12 +00:00
2010-01-05 17:38:37 +00:00
# pragma comment(lib, "Bthprops.lib")
# endif
2008-12-08 05:25:12 +00:00
extern SWiimoteInitialize g_WiimoteInitialize ;
namespace WiiMoteReal
{
2010-02-21 18:53:11 +00:00
bool g_RealWiiMoteInitialized = false ;
bool g_RealWiiMoteAllocated = false ;
2008-12-08 05:25:12 +00:00
// Forwarding
2009-07-05 05:59:03 +00:00
2009-01-25 23:07:15 +00:00
class CWiiMote ;
2008-12-08 05:25:12 +00:00
// Variable declarations
2009-07-05 05:59:03 +00:00
2009-01-25 23:07:15 +00:00
wiimote_t * * g_WiiMotesFromWiiUse = NULL ;
Common : : Thread * g_pReadThread = NULL ;
int g_NumberOfWiiMotes ;
CWiiMote * g_WiiMotes [ MAX_WIIMOTES ] ;
bool g_Shutdown = false ;
2010-01-09 19:06:23 +00:00
Common : : Event g_StartThread ;
Common : : Event g_StopThreadTemporary ;
2009-01-25 23:07:15 +00:00
bool g_LocalThread = true ;
2009-02-03 00:59:26 +00:00
bool g_IRSensing = false ;
2009-01-28 16:09:08 +00:00
bool g_MotionSensing = false ;
2009-02-01 13:01:50 +00:00
u64 g_UpdateTime = 0 ;
int g_UpdateCounter = 0 ;
2009-02-01 14:58:44 +00:00
bool g_RunTemporary = false ;
2009-02-05 00:02:54 +00:00
int g_RunTemporaryCountdown = 0 ;
2009-02-03 00:59:26 +00:00
u8 g_EventBuffer [ 32 ] ;
2010-01-01 00:38:24 +00:00
bool g_WiimoteInUse [ MAX_WIIMOTES ] ;
2010-04-26 17:51:32 +00:00
Common : : Event NeedsConnect ;
Common : : Event Connected ;
# if defined(_WIN32) && defined(HAVE_WIIUSE)
//Autopairup
Common : : Thread * g_AutoPairUpInvisibleWindow = NULL ;
Common : : Thread * g_AutoPairUpMonitoring = NULL ;
Common : : Event g_StartAutopairThread ;
int stoprefresh = 0 ;
unsigned int PairUpTimer = 2000 ;
int PaiUpRefreshWiimote ( ) ;
THREAD_RETURN PairUp_ThreadFunc ( void * arg ) ;
THREAD_RETURN RunInvisibleMessageWindow_ThreadFunc ( void * arg ) ;
# endif
THREAD_RETURN ReadWiimote_ThreadFunc ( void * arg ) ;
THREAD_RETURN SafeCloseReadWiimote_ThreadFunc ( void * arg ) ;
2008-12-08 05:25:12 +00:00
// Probably this class should be in its own file
2009-01-25 23:07:15 +00:00
class CWiiMote
{
public :
CWiiMote ( u8 _WiimoteNumber , wiimote_t * _pWiimote )
: m_WiimoteNumber ( _WiimoteNumber )
, m_channelID ( 0 )
, m_pWiiMote ( _pWiimote )
, m_pCriticalSection ( NULL )
, m_LastReportValid ( false )
{
m_pCriticalSection = new Common : : CriticalSection ( ) ;
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
//wiiuse_set_leds(m_pWiiMote, WIIMOTE_LED_4);
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
# ifdef _WIN32
// F|RES: i dunno if we really need this
CancelIo ( m_pWiiMote - > dev_handle ) ;
# endif
}
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
virtual ~ CWiiMote ( )
{
delete m_pCriticalSection ;
} ;
2008-12-08 05:25:12 +00:00
2009-02-01 13:01:50 +00:00
// Queue raw HID data from the core to the wiimote
2009-01-25 23:07:15 +00:00
void SendData ( u16 _channelID , const u8 * _pData , u32 _Size )
{
m_channelID = _channelID ;
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
m_pCriticalSection - > Enter ( ) ;
{
SEvent WriteEvent ;
2009-11-19 22:58:36 +00:00
memcpy ( WriteEvent . m_PayLoad , _pData , _Size ) ;
WriteEvent . _Size = _Size ;
2009-01-25 23:07:15 +00:00
m_EventWriteQueue . push ( WriteEvent ) ;
2009-02-01 13:01:50 +00:00
// Debugging
//std::string Temp = ArrayToString(WriteEvent.m_PayLoad, 28, 0, 30);
2009-09-15 02:12:55 +00:00
//DEBUG_LOG(WIIMOTE, "Wiimote Write:\n%s", Temp.c_str());
2009-01-25 23:07:15 +00:00
}
m_pCriticalSection - > Leave ( ) ;
}
2008-12-08 05:25:12 +00:00
2009-02-01 13:01:50 +00:00
/* Read and write data to the Wiimote */
2009-01-25 23:07:15 +00:00
void ReadData ( )
{
2010-04-10 18:49:26 +00:00
m_pCriticalSection - > Enter ( ) ;
2009-01-25 23:07:15 +00:00
// Send data to the Wiimote
2010-04-10 18:49:26 +00:00
if ( ! m_EventWriteQueue . empty ( ) )
{
2009-09-15 02:12:55 +00:00
//DEBUG_LOG(WIIMOTE, "Writing data to the Wiimote");
2010-04-10 18:49:26 +00:00
SEvent & rEvent = m_EventWriteQueue . front ( ) ;
2009-11-19 22:47:57 +00:00
wiiuse_io_write ( m_pWiiMote , ( byte * ) rEvent . m_PayLoad , rEvent . _Size ) ;
2010-04-10 18:49:26 +00:00
# ifdef _WIN32
2010-04-10 14:39:54 +00:00
if ( m_pWiiMote - > event = = WIIUSE_UNEXPECTED_DISCONNECT )
{
NOTICE_LOG ( WIIMOTE , " wiiuse_io_write: unexpected disconnect. handle: %08x " , m_pWiiMote - > dev_handle ) ;
}
2010-04-10 18:49:26 +00:00
# endif
m_EventWriteQueue . pop ( ) ;
2009-01-25 23:07:15 +00:00
2010-04-10 18:49:26 +00:00
// InterruptDebugging(false, rEvent.m_PayLoad);
}
m_pCriticalSection - > Leave ( ) ;
2009-01-25 23:07:15 +00:00
2009-09-15 02:12:55 +00:00
2009-02-01 13:01:50 +00:00
// Read data from wiimote (but don't send it to the core, just filter and queue)
if ( wiiuse_io_read ( m_pWiiMote ) )
{
const byte * pBuffer = m_pWiiMote - > event_buf ;
// Check if we have a channel (connection) if so save the data...
if ( m_channelID > 0 )
2009-01-28 16:09:08 +00:00
{
2009-02-01 13:01:50 +00:00
m_pCriticalSection - > Enter ( ) ;
2010-04-10 18:49:26 +00:00
2009-02-01 13:01:50 +00:00
// Filter out data reports
2009-11-19 22:47:57 +00:00
if ( pBuffer [ 1 ] > = 0x30 )
2009-01-28 16:09:08 +00:00
{
2009-02-01 13:01:50 +00:00
// Copy Buffer to LastReport
2009-11-25 16:22:46 +00:00
memcpy ( m_LastReport . m_PayLoad , pBuffer + 1 , MAX_PAYLOAD - 1 ) ;
2009-02-01 13:01:50 +00:00
m_LastReportValid = true ;
2009-01-28 16:09:08 +00:00
}
2009-02-01 13:01:50 +00:00
else
{
// Copy Buffer to ImportantEvent
SEvent ImportantEvent ;
2009-11-25 16:22:46 +00:00
memcpy ( ImportantEvent . m_PayLoad , pBuffer + 1 , MAX_PAYLOAD - 1 ) ;
2009-01-28 16:09:08 +00:00
2009-02-01 13:01:50 +00:00
// Put it in the read queue right away
m_EventReadQueue . push ( ImportantEvent ) ;
}
m_pCriticalSection - > Leave ( ) ;
2009-01-28 16:09:08 +00:00
}
2009-02-01 13:01:50 +00:00
}
2010-04-10 18:49:26 +00:00
# ifdef _WIN32
2010-04-10 14:39:54 +00:00
else if ( m_pWiiMote - > event = = WIIUSE_UNEXPECTED_DISCONNECT )
{
NOTICE_LOG ( WIIMOTE , " wiiuse_io_read: unexpected disconnect. handle: %08x " , m_pWiiMote - > dev_handle ) ;
}
2010-04-10 18:49:26 +00:00
# endif
2009-01-25 23:07:15 +00:00
} ;
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
// Send queued data to the core
void Update ( )
{
// Thread function
m_pCriticalSection - > Enter ( ) ;
if ( m_EventReadQueue . empty ( ) )
{
2009-02-01 13:01:50 +00:00
// Send the data report
2010-01-01 00:38:24 +00:00
if ( m_LastReportValid )
SendEvent ( m_LastReport ) ;
2009-01-25 23:07:15 +00:00
}
else
{
2009-02-01 13:01:50 +00:00
// Send a 0x20, 0x21 or 0x22 report
2009-01-25 23:07:15 +00:00
SendEvent ( m_EventReadQueue . front ( ) ) ;
m_EventReadQueue . pop ( ) ;
}
m_pCriticalSection - > Leave ( ) ;
} ;
2008-12-08 05:25:12 +00:00
2009-02-01 13:01:50 +00:00
// Clear events
void ClearEvents ( )
{
while ( ! m_EventReadQueue . empty ( ) )
m_EventReadQueue . pop ( ) ;
while ( ! m_EventWriteQueue . empty ( ) )
m_EventWriteQueue . pop ( ) ;
}
2009-01-25 23:07:15 +00:00
private :
2008-12-08 05:25:12 +00:00
2009-01-25 23:07:15 +00:00
struct SEvent
{
SEvent ( )
2008-12-08 05:25:12 +00:00
{
2009-01-25 23:07:15 +00:00
memset ( m_PayLoad , 0 , MAX_PAYLOAD ) ;
2008-12-08 05:25:12 +00:00
}
2009-01-25 23:07:15 +00:00
byte m_PayLoad [ MAX_PAYLOAD ] ;
2009-11-19 22:47:57 +00:00
u32 _Size ;
2008-12-08 05:25:12 +00:00
} ;
2009-01-25 23:07:15 +00:00
typedef std : : queue < SEvent > CEventQueue ;
u8 m_WiimoteNumber ; // Just for debugging
u16 m_channelID ;
2009-02-01 13:01:50 +00:00
CEventQueue m_EventReadQueue ; // Read from Wiimote
CEventQueue m_EventWriteQueue ; // Write to Wiimote
2009-01-25 23:07:15 +00:00
SEvent m_LastReport ;
wiimote_t * m_pWiiMote ; // This is g_WiiMotesFromWiiUse[]
2009-09-08 21:16:05 +00:00
Common : : CriticalSection * m_pCriticalSection ;
2009-11-19 22:47:57 +00:00
bool m_LastReportValid ;
2009-01-25 23:07:15 +00:00
2009-02-01 13:01:50 +00:00
// Send queued data to the core
2009-01-25 23:07:15 +00:00
void SendEvent ( SEvent & _rEvent )
{
// We don't have an answer channel
2010-01-01 00:38:24 +00:00
if ( m_channelID = = 0 )
return ;
2009-01-25 23:07:15 +00:00
2009-02-01 13:01:50 +00:00
// Check event buffer
2009-01-25 23:07:15 +00:00
u8 Buffer [ 1024 ] ;
u32 Offset = 0 ;
hid_packet * pHidHeader = ( hid_packet * ) ( Buffer + Offset ) ;
pHidHeader - > type = HID_TYPE_DATA ;
pHidHeader - > param = HID_PARAM_INPUT ;
2009-02-01 13:01:50 +00:00
// Create the buffer
2009-11-26 05:01:24 +00:00
memcpy ( & Buffer [ Offset ] , pHidHeader , sizeof ( hid_packet ) ) ;
Offset + = sizeof ( hid_packet ) ;
2009-11-14 23:54:30 +00:00
memcpy ( & Buffer [ Offset ] , _rEvent . m_PayLoad , sizeof ( _rEvent . m_PayLoad ) ) ;
Offset + = sizeof ( _rEvent . m_PayLoad ) ;
2009-01-25 23:07:15 +00:00
2009-02-01 13:01:50 +00:00
// Send it
2010-01-01 00:38:24 +00:00
g_WiimoteInitialize . pWiimoteInput ( m_WiimoteNumber , m_channelID , Buffer , Offset ) ;
2009-01-31 01:18:57 +00:00
2009-02-01 13:01:50 +00:00
// Debugging
2009-02-27 23:44:15 +00:00
// ReadDebugging(false, Buffer, Offset);
2009-01-25 23:07:15 +00:00
}
} ;
2008-12-08 05:25:12 +00:00
// Function Definitions
2009-01-29 08:35:29 +00:00
2009-02-01 13:01:50 +00:00
void SendAcc ( u8 _ReportID )
{
byte DataAcc [ MAX_PAYLOAD ] ;
DataAcc [ 0 ] = 0x22 ; // Report 0x12
DataAcc [ 1 ] = 0x00 ; // Core buttons
DataAcc [ 2 ] = 0x00 ;
DataAcc [ 3 ] = _ReportID ; // Reporting mode
2010-01-01 00:38:24 +00:00
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
wiiuse_io_write ( WiiMoteReal : : g_WiiMotesFromWiiUse [ i ] , ( byte * ) DataAcc , MAX_PAYLOAD ) ;
2009-02-01 13:01:50 +00:00
std : : string Temp = ArrayToString ( DataAcc , 28 , 0 , 30 ) ;
2009-09-15 02:12:55 +00:00
DEBUG_LOG ( WIIMOTE , " SendAcc: %s " , Temp . c_str ( ) ) ;
2009-02-01 13:01:50 +00:00
//22 00 00 _reportID 00
}
// Clear any potential queued events
void ClearEvents ( )
{
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
2010-01-01 02:19:19 +00:00
if ( g_WiimoteInUse [ i ] )
g_WiiMotes [ i ] - > ClearEvents ( ) ;
2009-02-01 13:01:50 +00:00
}
2009-01-29 08:35:29 +00:00
// Flash lights, and if connecting, also rumble
void FlashLights ( bool Connect )
{
2009-05-16 04:53:48 +00:00
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
{
2010-01-01 00:38:24 +00:00
if ( Connect )
wiiuse_rumble ( WiiMoteReal : : g_WiiMotesFromWiiUse [ i ] , 1 ) ;
2009-05-16 04:53:48 +00:00
}
2010-01-05 17:38:37 +00:00
SLEEP ( 200 ) ;
2009-05-16 04:53:48 +00:00
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
{
2010-01-01 16:50:11 +00:00
if ( Connect ) {
2009-05-16 04:53:48 +00:00
wiiuse_rumble ( WiiMoteReal : : g_WiiMotesFromWiiUse [ i ] , 0 ) ;
2010-01-01 16:50:11 +00:00
wiiuse_set_leds ( WiiMoteReal : : g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4 ) ;
}
2010-01-01 00:38:24 +00:00
else
wiiuse_set_leds ( WiiMoteReal : : g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_NONE ) ;
2009-05-16 04:53:48 +00:00
}
2009-01-29 08:35:29 +00:00
}
2010-01-01 16:50:11 +00:00
int Initialize ( )
2009-01-25 23:07:15 +00:00
{
2009-02-01 13:01:50 +00:00
// Return if already initialized
2010-01-01 00:38:24 +00:00
if ( g_RealWiiMoteInitialized )
return g_NumberOfWiiMotes ;
2010-03-05 07:03:44 +00:00
NeedsConnect . Init ( ) ;
Connected . Init ( ) ;
2009-01-07 02:59:19 +00:00
2009-02-01 13:01:50 +00:00
// Clear the wiimote classes
2009-01-25 23:07:15 +00:00
memset ( g_WiiMotes , 0 , sizeof ( CWiiMote * ) * MAX_WIIMOTES ) ;
2010-01-01 00:38:24 +00:00
for ( int i = 0 ; i < MAX_WIIMOTES ; i + + )
g_WiimoteInUse [ i ] = false ;
g_RealWiiMotePresent = false ;
2010-01-01 16:50:11 +00:00
g_RealWiiMoteAllocated = false ;
2010-01-01 00:38:24 +00:00
2010-01-11 13:56:11 +00:00
// Call Wiiuse.dll
g_WiiMotesFromWiiUse = wiiuse_init ( MAX_WIIMOTES ) ;
g_NumberOfWiiMotes = wiiuse_find ( g_WiiMotesFromWiiUse , MAX_WIIMOTES , 5 ) ;
DEBUG_LOG ( WIIMOTE , " Found No of Wiimotes: %i " , g_NumberOfWiiMotes ) ;
if ( g_NumberOfWiiMotes > 0 )
2010-03-05 07:03:44 +00:00
{
2010-01-11 13:56:11 +00:00
g_RealWiiMotePresent = true ;
2010-03-05 07:03:44 +00:00
// Create a new thread for listening for Wiimote data
// and also connecting in Linux/OSX.
// Windows connects to Wiimote in the wiiuse_find function
g_pReadThread = new Common : : Thread ( ReadWiimote_ThreadFunc , NULL ) ;
2010-04-10 14:39:54 +00:00
// Don't run the Wiimote thread if no wiimotes were found
g_Shutdown = false ;
2010-03-05 07:03:44 +00:00
NeedsConnect . Set ( ) ;
Connected . Wait ( ) ;
}
2010-01-01 16:50:11 +00:00
else
return 0 ;
2008-12-08 05:25:12 +00:00
2009-05-16 04:53:48 +00:00
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
{
// Remove the wiiuse_poll() threshold
wiiuse_set_accel_threshold ( g_WiiMotesFromWiiUse [ i ] , 0 ) ;
2010-03-26 12:36:28 +00:00
// Set the ir sensor sensitivity.
if ( g_Config . iIRLevel ) {
wiiuse_set_ir_sensitivity ( g_WiiMotesFromWiiUse [ i ] , g_Config . iIRLevel ) ;
}
2009-05-16 04:53:48 +00:00
// Set the sensor bar position, this should only affect the internal wiiuse api functions
wiiuse_set_ir_position ( g_WiiMotesFromWiiUse [ i ] , WIIUSE_IR_ABOVE ) ;
2009-02-12 16:43:35 +00:00
2009-05-16 04:53:48 +00:00
// Set flags
//wiiuse_set_flags(g_WiiMotesFromWiiUse[i], NULL, WIIUSE_SMOOTHING);
}
2009-09-15 02:12:55 +00:00
// psyjoe reports this allows majority of lost packets to be transferred.
// Will test soon
//wiiuse_set_timeout(g_WiiMotesFromWiiUse, g_NumberOfWiiMotes, 220, 220);
2010-01-01 00:38:24 +00:00
// If we are connecting from the config window without a game running we set the LEDs
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
if ( g_EmulatorState ! = PLUGIN_EMUSTATE_PLAY & & g_RealWiiMotePresent )
2010-01-01 00:38:24 +00:00
FlashLights ( true ) ;
2010-03-05 07:03:44 +00:00
2008-12-08 05:25:12 +00:00
2009-07-05 05:59:03 +00:00
/* Allocate memory and copy the Wiimote eeprom accelerometer neutral values
to g_Eeprom . Unlike with and extension we have to do this here , because
this data is only read once when the Wiimote is connected . Also , we
can ' t change the neutral values the wiimote will report , I think , unless
we update its eeprom ? In any case it ' s probably better to let the
current calibration be where it is and adjust the global values after
that to avoid overwriting critical data on any Wiimote . */
2010-01-01 00:38:24 +00:00
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
{
byte * data = ( byte * ) malloc ( sizeof ( byte ) * sizeof ( WiiMoteEmu : : EepromData_0 ) ) ;
wiiuse_read_data ( g_WiiMotesFromWiiUse [ i ] , data , 0 , sizeof ( WiiMoteEmu : : EepromData_0 ) ) ;
}
2009-02-01 14:58:44 +00:00
2009-02-07 03:16:41 +00:00
// Initialized, even if we didn't find a Wiimote
g_RealWiiMoteInitialized = true ;
2009-02-03 07:43:52 +00:00
2009-02-20 22:04:52 +00:00
return g_NumberOfWiiMotes ;
2009-01-25 23:07:15 +00:00
}
2008-12-08 05:25:12 +00:00
2010-01-01 16:50:11 +00:00
// Allocate each Real WiiMote found to a WiiMote slot with Source set to "WiiMote Real"
void Allocate ( )
{
2010-02-21 18:53:11 +00:00
if ( g_RealWiiMoteAllocated )
return ;
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
if ( ! g_RealWiiMoteInitialized )
2010-01-01 16:50:11 +00:00
Initialize ( ) ;
// Clear the wiimote classes
memset ( g_WiiMotes , 0 , sizeof ( CWiiMote * ) * MAX_WIIMOTES ) ;
for ( int i = 0 ; i < MAX_WIIMOTES ; i + + )
g_WiimoteInUse [ i ] = false ;
g_Config . bNumberEmuWiimotes = g_Config . bNumberRealWiimotes = 0 ;
// Create Wiimote classes, one for each Real WiiMote found
int current_number = 0 ;
for ( int i = 0 ; i < g_NumberOfWiiMotes ; i + + )
{
// Let's find out the slot this Real WiiMote will be using... We need this because the user can set any of the 4 WiiMotes as Real, Emulated or Inactive...
for ( ; current_number < MAX_WIIMOTES ; current_number + + )
{
// Just to be sure we won't be overlapping any WiiMote...
if ( g_WiimoteInUse [ current_number ] = = true )
continue ;
if ( WiiMoteEmu : : WiiMapping [ current_number ] . Source = = 1 )
g_Config . bNumberEmuWiimotes + + ;
// Found a WiiMote (slot) that wants to be real :P
else if ( WiiMoteEmu : : WiiMapping [ current_number ] . Source = = 2 ) {
g_Config . bNumberRealWiimotes + + ;
break ;
}
}
// If we found a valid slot for this WiiMote...
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
if ( current_number < MAX_WIIMOTES )
2010-01-01 16:50:11 +00:00
{
g_WiiMotes [ current_number ] = new CWiiMote ( current_number , g_WiiMotesFromWiiUse [ i ] ) ;
g_WiimoteInUse [ current_number ] = true ;
switch ( current_number )
{
case 0 :
wiiuse_set_leds ( g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_1 ) ;
break ;
case 1 :
wiiuse_set_leds ( g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_2 ) ;
break ;
case 2 :
wiiuse_set_leds ( g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_3 ) ;
break ;
case 3 :
wiiuse_set_leds ( g_WiiMotesFromWiiUse [ i ] , WIIMOTE_LED_4 ) ;
break ;
default :
PanicAlert ( " Trying to create real wiimote %i WTF " , current_number ) ;
break ;
}
DEBUG_LOG ( WIIMOTE , " Real WiiMote allocated as WiiMote #%i " , current_number ) ;
}
}
// If there are more slots marked as "Real WiiMote" than the number of Real WiiMotes connected, disable them!
for ( current_number + + ; current_number < MAX_WIIMOTES ; current_number + + )
{
if ( WiiMoteEmu : : WiiMapping [ current_number ] . Source = = 1 )
g_Config . bNumberEmuWiimotes + + ;
else if ( WiiMoteEmu : : WiiMapping [ current_number ] . Source = = 2 )
WiiMoteEmu : : WiiMapping [ current_number ] . Source = 0 ;
}
DEBUG_LOG ( WIIMOTE , " Using %i Real Wiimote(s) and %i Emu Wiimote(s) " , g_Config . bNumberRealWiimotes , g_Config . bNumberEmuWiimotes ) ;
// If we are not using any emulated wiimotes we can run the thread temporary until the data has beeen copied
if ( g_Config . bNumberEmuWiimotes = = 0 )
g_RunTemporary = true ;
g_RealWiiMoteAllocated = true ;
}
2009-07-03 12:22:32 +00:00
void DoState ( PointerWrap & p )
{
//TODO: Implement
}
2009-01-25 23:07:15 +00:00
void Shutdown ( void )
{
2010-02-21 18:53:11 +00:00
if ( ! g_RealWiiMoteInitialized )
return ;
2009-02-03 04:03:56 +00:00
// Stop the loop in the thread
2010-01-08 20:27:54 +00:00
g_Shutdown = true ; // not safe .. might crash when still @ReadWiimote
2009-02-03 04:03:56 +00:00
2009-02-20 22:04:52 +00:00
// Stop the thread
if ( g_pReadThread ! = NULL )
{
2010-01-08 20:27:54 +00:00
delete g_pReadThread ;
2009-02-20 22:04:52 +00:00
g_pReadThread = NULL ;
}
2009-01-25 23:07:15 +00:00
2009-02-20 22:04:52 +00:00
// Delete the wiimotes
2010-01-01 16:50:11 +00:00
for ( int i = 0 ; i < MAX_WIIMOTES ; i + + )
2009-02-20 22:04:52 +00:00
{
delete g_WiiMotes [ i ] ;
g_WiiMotes [ i ] = NULL ;
}
2009-01-25 23:07:15 +00:00
2009-01-29 08:35:29 +00:00
// Flash flights
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
if ( g_EmulatorState ! = PLUGIN_EMUSTATE_PLAY & & g_RealWiiMotePresent )
2009-02-20 22:04:52 +00:00
FlashLights ( false ) ;
2009-01-26 07:01:43 +00:00
2009-01-29 08:35:29 +00:00
// Clean up wiiuse
wiiuse_cleanup ( g_WiiMotesFromWiiUse , g_NumberOfWiiMotes ) ;
2009-01-25 23:07:15 +00:00
// Uninitialized
g_RealWiiMoteInitialized = false ;
2009-01-26 07:01:43 +00:00
g_RealWiiMotePresent = false ;
2009-01-25 23:07:15 +00:00
}
2010-01-01 00:38:24 +00:00
void InterruptChannel ( int _WiimoteNumber , u16 _channelID , const void * _pData , u32 _Size )
2009-01-25 23:07:15 +00:00
{
2010-01-01 00:38:24 +00:00
//DEBUG_LOG(WIIMOTE, "Real InterruptChannel on WiiMote #%i", _WiimoteNumber);
g_WiiMotes [ _WiimoteNumber ] - > SendData ( _channelID , ( const u8 * ) _pData , _Size ) ;
2009-01-25 23:07:15 +00:00
}
2010-01-01 00:38:24 +00:00
void ControlChannel ( int _WiimoteNumber , u16 _channelID , const void * _pData , u32 _Size )
2009-01-25 23:07:15 +00:00
{
2010-01-01 00:38:24 +00:00
//DEBUG_LOG(WIIMOTE, "Real ControlChannel on WiiMote #%i", _WiimoteNumber);
g_WiiMotes [ _WiimoteNumber ] - > SendData ( _channelID , ( const u8 * ) _pData , _Size ) ;
2009-01-25 23:07:15 +00:00
}
// Read the Wiimote once
2010-01-01 00:38:24 +00:00
void Update ( int _WiimoteNumber )
2009-01-25 23:07:15 +00:00
{
2010-01-01 00:38:24 +00:00
//DEBUG_LOG(WIIMOTE, "Real Update on WiiMote #%i", _WiimoteNumber);
g_WiiMotes [ _WiimoteNumber ] - > Update ( ) ;
2009-01-25 23:07:15 +00:00
}
2008-12-08 05:25:12 +00:00
2009-07-05 05:59:03 +00:00
/* Continuously read the Wiimote status. However, the actual sending of data
occurs in Update ( ) . If we are not currently using the real Wiimote we allow
the separate ReadWiimote ( ) function to run . Wo don ' t use them at the same
time to avoid a potential collision . */
2009-07-10 20:22:25 +00:00
THREAD_RETURN ReadWiimote_ThreadFunc ( void * arg )
2009-01-25 23:07:15 +00:00
{
2010-01-09 19:06:23 +00:00
g_StopThreadTemporary . Init ( ) ;
g_StartThread . Init ( ) ;
2010-03-05 07:03:44 +00:00
NeedsConnect . Wait ( ) ;
# ifndef _WIN32
int Connect ;
// WiiUse initializes the Wiimotes in Windows right from the wiiuse_find function
// The Functionality should REALLY be changed
Connect = wiiuse_connect ( g_WiiMotesFromWiiUse , MAX_WIIMOTES ) ;
DEBUG_LOG ( WIIMOTE , " Connected: %i " , Connect ) ;
# endif
Connected . Set ( ) ;
2010-01-08 20:27:54 +00:00
2009-05-16 04:53:48 +00:00
while ( ! g_Shutdown )
{
2010-01-05 17:38:37 +00:00
// There is at least one Real Wiimote in use
2010-01-08 20:27:54 +00:00
2010-01-05 17:38:37 +00:00
if ( g_Config . bNumberRealWiimotes > 0 & & ! g_RunTemporary )
{
for ( int i = 0 ; i < MAX_WIIMOTES ; i + + )
if ( g_WiimoteInUse [ i ] )
g_WiiMotes [ i ] - > ReadData ( ) ;
}
2010-01-08 20:27:54 +00:00
else {
2010-01-09 19:06:23 +00:00
if ( ! g_StopThreadTemporary . Wait ( 0 ) )
2010-01-08 20:27:54 +00:00
{
2010-01-09 19:06:23 +00:00
// Event object was signaled, exiting thread to close ConfigRecordingDlg
2010-01-08 20:27:54 +00:00
new Common : : Thread ( SafeCloseReadWiimote_ThreadFunc , NULL ) ;
2010-01-09 19:06:23 +00:00
g_StartThread . Set ( ) ; //tell the new thread to get going
2010-01-08 20:27:54 +00:00
return 0 ;
}
2010-01-09 19:06:23 +00:00
else
ReadWiimote ( ) ;
2010-01-08 20:27:54 +00:00
}
2009-05-16 04:53:48 +00:00
}
return 0 ;
2009-01-25 23:07:15 +00:00
}
2010-02-21 18:53:11 +00:00
// Returns whether SafeClose_ThreadFunc will take over closing of Recording dialog.
// FIXME: this whole threading stuff is bad, and should be removed.
// OSX is having problems with the threading anyways, since WiiUse is used
// from multiple threads, and not just the one where it was created on.
bool SafeClose ( )
{
if ( ! g_RealWiiMoteInitialized )
return false ;
g_StopThreadTemporary . Set ( ) ;
return true ;
}
2010-01-09 19:06:23 +00:00
// Thread to avoid racing conditions by directly closing of ReadWiimote_ThreadFunc() resp. ReadWiimote()
// shutting down the Dlg while still beeing @ReadWiimote will result in a crash;
THREAD_RETURN SafeCloseReadWiimote_ThreadFunc ( void * arg )
2010-01-08 20:27:54 +00:00
{
2010-01-09 19:06:23 +00:00
g_Shutdown = true ;
g_StartThread . Wait ( ) ; //Ready to start cleaning
2010-01-08 20:27:54 +00:00
2010-01-09 19:06:23 +00:00
if ( g_RealWiiMoteInitialized )
Shutdown ( ) ;
2010-01-12 22:35:28 +00:00
# if defined(HAVE_WX) && HAVE_WX
2010-01-09 19:06:23 +00:00
m_RecordingConfigFrame - > Close ( true ) ;
2010-01-12 22:35:28 +00:00
# endif
2010-01-09 19:06:23 +00:00
if ( ! g_RealWiiMoteInitialized )
Initialize ( ) ;
return 0 ;
2010-01-08 20:27:54 +00:00
}
2010-01-05 17:38:37 +00:00
// WiiMote Pair-Up
# ifdef WIN32
2010-04-15 16:47:55 +00:00
int WiimotePairUp ( bool unpair )
2010-01-05 17:38:37 +00:00
{
HANDLE hRadios [ 256 ] ;
int nRadios ;
int nPaired = 0 ;
// Enumerate BT radios
HBLUETOOTH_RADIO_FIND hFindRadio ;
BLUETOOTH_FIND_RADIO_PARAMS radioParam ;
radioParam . dwSize = sizeof ( BLUETOOTH_FIND_RADIO_PARAMS ) ;
nRadios = 0 ;
hFindRadio = BluetoothFindFirstRadio ( & radioParam , & hRadios [ nRadios + + ] ) ;
if ( hFindRadio )
{
while ( BluetoothFindNextRadio ( & radioParam , & hRadios [ nRadios + + ] ) ) ;
BluetoothFindRadioClose ( hFindRadio ) ;
}
else
{
ERROR_LOG ( WIIMOTE , " Pair-Up: Error enumerating radios " , GetLastError ( ) ) ;
return - 1 ;
}
nRadios - - ;
2010-04-26 17:51:32 +00:00
//DEBUG_LOG(WIIMOTE, "Pair-Up: Found %d radios\n", nRadios);
2010-01-05 17:38:37 +00:00
// Pair with Wii device(s)
int radio = 0 ;
2010-04-02 14:04:24 +00:00
for ( radio = 0 ; radio < nRadios ; radio + + )
{
BLUETOOTH_RADIO_INFO radioInfo ;
HBLUETOOTH_DEVICE_FIND hFind ;
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
BLUETOOTH_DEVICE_INFO btdi ;
BLUETOOTH_DEVICE_SEARCH_PARAMS srch ;
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
radioInfo . dwSize = sizeof ( radioInfo ) ;
btdi . dwSize = sizeof ( btdi ) ;
srch . dwSize = sizeof ( BLUETOOTH_DEVICE_SEARCH_PARAMS ) ;
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
BluetoothGetRadioInfo ( hRadios [ radio ] , & radioInfo ) ;
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
srch . fReturnAuthenticated = TRUE ;
srch . fReturnRemembered = TRUE ;
srch . fReturnConnected = TRUE ; // does not filter properly somehow, so we 've to do an additional check on fConnected BT Devices
srch . fReturnUnknown = TRUE ;
srch . fIssueInquiry = TRUE ;
srch . cTimeoutMultiplier = 1 ;
srch . hRadio = hRadios [ radio ] ;
2010-01-05 17:38:37 +00:00
2010-04-26 17:51:32 +00:00
//DEBUG_LOG(WIIMOTE, "Pair-Up: Scanning for BT Device(s)");
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
hFind = BluetoothFindFirstDevice ( & srch , & btdi ) ;
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
if ( hFind = = NULL )
{
ERROR_LOG ( WIIMOTE , " Pair-Up: Error enumerating devices: %08x " , GetLastError ( ) ) ;
return - 1 ;
}
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
do
{
2010-04-26 17:51:32 +00:00
//btdi.szName is sometimes missings it's content - it's a bt feature..
2010-04-15 16:47:55 +00:00
if ( ( ! wcscmp ( btdi . szName , L " Nintendo RVL-WBC-01 " ) | | ! wcscmp ( btdi . szName , L " Nintendo RVL-CNT-01 " ) ) & & ! btdi . fConnected & & ! unpair )
2010-01-05 17:38:37 +00:00
{
2010-04-02 14:04:24 +00:00
//TODO: improve the readd of the BT driver, esp. when batteries of the wiimote are removed while beeing fConnected
if ( btdi . fRemembered )
{
// Make Windows forget old expired pairing
// we can pretty much ignore the return value here.
// it either worked (ERROR_SUCCESS), or the device did not exist (ERROR_NOT_FOUND)
// in both cases, there is nothing left.
BluetoothRemoveDevice ( & btdi . Address ) ;
}
2010-01-05 17:38:37 +00:00
2010-04-02 14:04:24 +00:00
// Activate service
DWORD hr = BluetoothSetServiceState ( hRadios [ radio ] , & btdi , & HumanInterfaceDeviceServiceClass_UUID , BLUETOOTH_SERVICE_ENABLE ) ;
if ( ! hr = = ERROR_SUCCESS )
2010-01-05 17:38:37 +00:00
{
2010-04-02 14:04:24 +00:00
nPaired + + ;
2010-01-05 17:38:37 +00:00
}
2010-04-02 14:04:24 +00:00
else
{
ERROR_LOG ( WIIMOTE , " Pair-Up: BluetoothSetServiceState() returned %08x " , hr ) ;
}
}
2010-04-15 16:47:55 +00:00
else if ( ( ! wcscmp ( btdi . szName , L " Nintendo RVL-WBC-01 " ) | | ! wcscmp ( btdi . szName , L " Nintendo RVL-CNT-01 " ) ) & & unpair )
{
BluetoothRemoveDevice ( & btdi . Address ) ;
2010-04-26 17:51:32 +00:00
NOTICE_LOG ( WIIMOTE , " Pair-Up: Automatically removed BT Device on shutdown: %08x " , GetLastError ( ) ) ;
nPaired + + ;
2010-04-15 16:47:55 +00:00
}
2010-04-02 14:04:24 +00:00
} while ( BluetoothFindNextDevice ( hFind , & btdi ) ) ;
BluetoothFindRadioClose ( hFind ) ;
}
SLEEP ( 10 ) ;
2010-01-05 17:38:37 +00:00
// Clean up
for ( radio = 0 ; radio < nRadios ; radio + + )
{
CloseHandle ( hRadios [ radio ] ) ;
}
return nPaired ;
}
2010-04-26 17:51:32 +00:00
# ifdef HAVE_WIIUSE
LRESULT CALLBACK CallBackDeviceChange ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg )
{
case WM_DEVICECHANGE :
// DBT_DEVNODES_CHANGED 0x007 (devnodes are atm not received); DBT_DEVICEARRIVAL 0x8000 DBT_DEVICEREMOVECOMPLETE 0x8004 // avoiding header file^^
if ( ( wParam = = 0x8000 | | wParam = = 0x8004 | | wParam = = 0x0007 ) )
{
if ( wiiuse_check_system_notification ( uMsg , wParam , lParam ) ) //extern wiiuse function: returns 1 if the event came from a wiimote
{
switch ( wParam )
{
case 0x8000 :
if ( stoprefresh ) // arrival will pop up twice //need to rewrite the stoprefresh thing, to support multiple pair ups in one go
{
stoprefresh = 0 ;
PaiUpRefreshWiimote ( ) ;
break ;
}
else stoprefresh = 1 ; //fake arrival wait for second go
break ;
case 0x8004 :
if ( ! stoprefresh ) // removal event will pop up only once (it will also pop up if we add a device: fake arrival, fake removal, real arrival.
{
PaiUpRefreshWiimote ( ) ;
}
break ;
}
}
}
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
default :
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
}
return 0 ;
}
THREAD_RETURN RunInvisibleMessageWindow_ThreadFunc ( void * arg )
{
MSG Msg ;
HWND hwnd ;
WNDCLASSEX WCEx ;
ZeroMemory ( & WCEx , sizeof ( WCEx ) ) ;
WCEx . cbSize = sizeof ( WCEx ) ;
WCEx . lpfnWndProc = CallBackDeviceChange ;
WCEx . hInstance = g_hInstance ;
WCEx . lpszClassName = L " MSGWND " ;
if ( RegisterClassEx ( & WCEx ) ! = 0 )
{
hwnd = CreateWindowEx ( 0 , WCEx . lpszClassName , NULL , 0 ,
0 , 0 , 0 , 0 , HWND_MESSAGE , NULL , g_hInstance , NULL ) ;
if ( ! hwnd ) {
UnregisterClass ( WCEx . lpszClassName , g_hInstance ) ;
return 1 ;
}
}
wiiuse_register_system_notification ( hwnd ) ; //function moved into wiiuse to avoid ddk/wdk dependicies
while ( GetMessage ( & Msg , 0 , 0 , 0 ) > 0 )
{
TranslateMessage ( & Msg ) ;
DispatchMessage ( & Msg ) ;
}
UnregisterClass ( WCEx . lpszClassName , g_hInstance ) ;
if ( g_Config . bUnpairRealWiimote )
WiiMoteReal : : WiimotePairUp ( true ) ;
return ( int ) Msg . wParam ;
}
int PaiUpRefreshWiimote ( )
{
if ( g_EmulatorState ! = PLUGIN_EMUSTATE_PLAY )
{
Shutdown ( ) ;
Initialize ( ) ;
//Allocate();
if ( m_BasicConfigFrame ! = NULL )
m_BasicConfigFrame - > UpdateGUI ( ) ;
}
else {
Sleep ( 100 ) ;
PostMessage ( GetParent ( g_WiimoteInitialize . hWnd ) , WM_USER , WM_USER_PAUSE , 0 ) ;
while ( g_EmulatorState = = PLUGIN_EMUSTATE_PLAY ) Sleep ( 50 ) ;
Shutdown ( ) ;
Initialize ( ) ;
Allocate ( ) ;
PostMessage ( GetParent ( g_WiimoteInitialize . hWnd ) , WM_USER , WM_USER_PAUSE , 0 ) ;
while ( g_EmulatorState ! = PLUGIN_EMUSTATE_PLAY ) Sleep ( 50 ) ;
}
return 0 ;
}
THREAD_RETURN PairUp_ThreadFunc ( void * arg )
{
Sleep ( 100 ) ; //small pause till the callback is registered on first start
DEBUG_LOG ( WIIMOTE , " PairUp_ThreadFunc started. " ) ;
g_StartAutopairThread . Init ( ) ;
int result ;
while ( 1 ) {
if ( g_Config . bPairRealWiimote ) {
PairUpTimer = 2000 ;
result = g_StartAutopairThread . Wait ( PairUpTimer ) ;
}
else {
result = g_StartAutopairThread . Wait ( ) ;
}
if ( result )
WiimotePairUp ( false ) ;
else {
if ( m_BasicConfigFrame ! = NULL )
m_BasicConfigFrame - > UpdateBasicConfigDialog ( false ) ;
WiimotePairUp ( false ) ;
if ( m_BasicConfigFrame ! = NULL )
m_BasicConfigFrame - > UpdateBasicConfigDialog ( true ) ;
}
}
DEBUG_LOG ( WIIMOTE , " PairUp_ThreadFunc terminated. " ) ;
return 0 ;
}
# endif
2010-01-05 17:38:37 +00:00
# endif
2008-12-08 05:25:12 +00:00
} ; // end of namespace