Gecko codes: Added parenthesis where they were needed.(thanks to glennrics and soren) Fixed a copy paste error with write & fill 8bit codes. Also forgot to remove a return false;.(some more codes should work (fixed issue 2968)) New Wiimote Plugin: Added emulated swinging.(seems to work) Changed the emulated calibration data to some nice values. ControllerInterface: moved and constified some stuff.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5980 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2010-07-26 05:30:50 +00:00
parent 0eaa7352fd
commit 5be58c6772
17 changed files with 224 additions and 224 deletions

View File

@ -168,7 +168,7 @@ bool RamWriteAndFill()
u32 new_addr = code.GetAddress(); u32 new_addr = code.GetAddress();
const u32& data = code.data; const u32& data = code.data;
u16 count = (data >> 16) + 1; // note: +1 u32 count = (data >> 16) + 1; // note: +1
switch (code.subtype) switch (code.subtype)
{ {
@ -176,7 +176,7 @@ bool RamWriteAndFill()
case DATATYPE_8BIT : case DATATYPE_8BIT :
while (count--) while (count--)
{ {
Memory::Write_U16((u16)data, new_addr); Memory::Write_U8((u8)data, new_addr);
++new_addr; ++new_addr;
} }
break; break;
@ -232,7 +232,7 @@ bool RamWriteAndFill()
const u8 data_type = current_code->address >> 28; const u8 data_type = current_code->address >> 28;
const u32 data_inc = current_code->data; // amount to increment the data const u32 data_inc = current_code->data; // amount to increment the data
const u16 addr_inc = (u16)current_code->address; // amount to increment the address const u16 addr_inc = (u16)current_code->address; // amount to increment the address
count = (current_code->address >> 16) & 0xFFF + 1; // count is different from the other subtypes, note: +1 count = ((current_code->address >> 16) & 0xFFF) + 1; // count is different from the other subtypes, note: +1
while (count--) while (count--)
{ {
// switch inside the loop, :/ o well // switch inside the loop, :/ o well
@ -435,7 +435,6 @@ bool FlowControl()
// needs -1 cause iterator gets ++ after code runs // needs -1 cause iterator gets ++ after code runs
current_code = codes_start + block[block_num].address - 1; current_code = codes_start + block[block_num].address - 1;
} }
return false; //
break; break;
// CST2 : Return // CST2 : Return

View File

@ -65,37 +65,35 @@ void GCPad_Init( void* const hwnd )
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{ {
memset( _pPADStatus, 0, sizeof(*_pPADStatus) ); memset(_pPADStatus, 0, sizeof(*_pPADStatus));
_pPADStatus->err = PAD_ERR_NONE; _pPADStatus->err = PAD_ERR_NONE;
// wtf is this? // wtf is this?
_pPADStatus->button |= PAD_USE_ORIGIN; _pPADStatus->button = PAD_USE_ORIGIN;
// try lock // try lock
if ( false == g_plugin.controls_crit.TryEnter() ) if (false == g_plugin.controls_crit.TryEnter())
{ {
// if gui has lock (messing with controls), skip this input cycle // if gui has lock (messing with controls), skip this input cycle
// center axes and return // center axes and return
memset( &_pPADStatus->stickX, 0x80, 4 ); memset(&_pPADStatus->stickX, 0x80, 4);
return; return;
} }
// if we are on the next input cycle, update output and input // if we are on the next input cycle, update output and input
// if we can get a lock // if we can get a lock
static int _last_numPAD = 4; static int _last_numPAD = 4;
if ( _numPAD <= _last_numPAD && g_plugin.interface_crit.TryEnter() ) if (_numPAD <= _last_numPAD)
{ {
g_plugin.controller_interface.UpdateOutput(); g_plugin.controller_interface.UpdateOutput();
g_plugin.controller_interface.UpdateInput(); g_plugin.controller_interface.UpdateInput();
g_plugin.interface_crit.Leave();
} }
_last_numPAD = _numPAD; _last_numPAD = _numPAD;
// get input // get input
((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus ); ((GCPad*)g_plugin.controllers[_numPAD])->GetInput(_pPADStatus);
// leave // leave
g_plugin.controls_crit.Leave(); g_plugin.controls_crit.Leave();
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________

View File

@ -261,13 +261,15 @@ ControllerEmu::Triggers::Triggers( const char* const _name ) : ControlGroup( _na
ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE ) ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE )
{ {
memset(m_swing, 0, sizeof(m_swing));
controls.push_back( new Input( "Up" ) ); controls.push_back( new Input( "Up" ) );
controls.push_back( new Input( "Down" ) ); controls.push_back( new Input( "Down" ) );
controls.push_back( new Input( "Left" ) ); controls.push_back( new Input( "Left" ) );
controls.push_back( new Input( "Right" ) ); controls.push_back( new Input( "Right" ) );
controls.push_back( new Input( "Forward" ) ); controls.push_back( new Input( "Forward" ) );
controls.push_back( new Input( "Backward" ) ); controls.push_back( new Input( "Backward" ) );
controls.push_back( new Input( "Modifier" ) ); //controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) ); settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) );
} }
@ -277,8 +279,6 @@ ControllerEmu::Tilt::Tilt( const char* const _name )
{ {
memset(m_tilt, 0, sizeof(m_tilt)); memset(m_tilt, 0, sizeof(m_tilt));
//for ( unsigned int i = 0; i < 4; ++i )
//controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Forward" ) ); controls.push_back( new Input( "Forward" ) );
controls.push_back( new Input( "Backward" ) ); controls.push_back( new Input( "Backward" ) );
controls.push_back( new Input( "Left" ) ); controls.push_back( new Input( "Left" ) );

View File

@ -253,19 +253,35 @@ public:
Force( const char* const _name ); Force( const char* const _name );
template <typename C, typename R> template <typename C, typename R>
void GetState( C* axis, const u8 base, const R range ) void GetState(C* axis, const u8 base, const R range)
{ {
const float deadzone = settings[0]->value; const float deadzone = settings[0]->value;
for ( unsigned int i=0; i<6; i+=2 ) for (unsigned int i=0; i<6; i+=2)
{ {
float tmpf = 0;
const float state = controls[i+1]->control_ref->State() - controls[i]->control_ref->State(); const float state = controls[i+1]->control_ref->State() - controls[i]->control_ref->State();
if (fabsf(state) > deadzone) if (fabsf(state) > deadzone)
*axis++ = (C)((state - (deadzone * sign(state))) / (1 - deadzone) * range + base); tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone));
//*axis++ = state * range + base;
else else
*axis++ = (C)(base); tmpf = 0;
float &ax = m_swing[i >> 1];
if (fabs(tmpf) > fabsf(ax))
{
if (tmpf > ax)
ax = std::min(ax + 0.15f, tmpf);
else if (tmpf < ax)
ax = std::max(ax - 0.15f, tmpf);
}
else
ax = tmpf;
*axis++ = (C)(ax * range + base);
} }
} }
private:
float m_swing[3];
}; };
class Tilt : public ControlGroup class Tilt : public ControlGroup

View File

@ -121,8 +121,13 @@ void ControllerInterface::SetHwnd( void* const hwnd )
// //
// update input for all devices, return true if all devices returned successful // update input for all devices, return true if all devices returned successful
// //
bool ControllerInterface::UpdateInput() bool ControllerInterface::UpdateInput(const bool force)
{ {
if (force)
update_lock.Enter();
else if (false == update_lock.TryEnter())
return false;
size_t ok_count = 0; size_t ok_count = 0;
std::vector<Device*>::const_iterator std::vector<Device*>::const_iterator
@ -137,6 +142,7 @@ bool ControllerInterface::UpdateInput()
//(*d)->ClearInputState(); //(*d)->ClearInputState();
} }
update_lock.Leave();
return (m_devices.size() == ok_count); return (m_devices.size() == ok_count);
} }
@ -145,8 +151,13 @@ bool ControllerInterface::UpdateInput()
// //
// update output for all devices, return true if all devices returned successful // update output for all devices, return true if all devices returned successful
// //
bool ControllerInterface::UpdateOutput() bool ControllerInterface::UpdateOutput(const bool force)
{ {
if (force)
update_lock.Enter();
else if (false == update_lock.TryEnter())
return false;
size_t ok_count = 0; size_t ok_count = 0;
std::vector<Device*>::const_iterator std::vector<Device*>::const_iterator
@ -155,6 +166,7 @@ bool ControllerInterface::UpdateOutput()
for (;d != e; ++d) for (;d != e; ++d)
(*d)->UpdateOutput(); (*d)->UpdateOutput();
update_lock.Leave();
return (m_devices.size() == ok_count); return (m_devices.size() == ok_count);
} }

View File

@ -6,7 +6,9 @@
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <algorithm> #include <algorithm>
#include "Common.h" #include "Common.h"
#include "Thread.h"
// enable disable sources // enable disable sources
#ifdef _WIN32 #ifdef _WIN32
@ -214,12 +216,14 @@ public:
bool IsInit() const { return m_is_init; } bool IsInit() const { return m_is_init; }
void UpdateReference(ControlReference* control, const DeviceQualifier& default_device) const; void UpdateReference(ControlReference* control, const DeviceQualifier& default_device) const;
bool UpdateInput(); bool UpdateInput(const bool force = false);
bool UpdateOutput(); bool UpdateOutput(const bool force = false);
const std::vector<Device*>& Devices() const { return m_devices; } const std::vector<Device*>& Devices() const { return m_devices; }
Device* FindDevice(const DeviceQualifier& devq) const; Device* FindDevice(const DeviceQualifier& devq) const;
Common::CriticalSection update_lock;
private: private:
bool m_is_init; bool m_is_init;
std::vector<Device*> m_devices; std::vector<Device*> m_devices;

View File

@ -19,7 +19,7 @@ namespace ciface
namespace DInput namespace DInput
{ {
static struct static const struct
{ {
const BYTE code; const BYTE code;
const char* const name; const char* const name;
@ -28,7 +28,7 @@ static struct
#include "NamedKeys.h" #include "NamedKeys.h"
}; };
static struct static const struct
{ {
const BYTE code; const BYTE code;
const char* const name; const char* const name;

View File

@ -9,7 +9,7 @@ namespace ciface
namespace XInput namespace XInput
{ {
static struct static const struct
{ {
const char* const name; const char* const name;
const WORD bitmask; const WORD bitmask;

View File

@ -44,7 +44,7 @@ public:
std::vector< ControllerEmu* > controllers; std::vector< ControllerEmu* > controllers;
Common::CriticalSection controls_crit, interface_crit; // lock controls first Common::CriticalSection controls_crit; // critical section for changing any control references
ControllerInterface controller_interface; ControllerInterface controller_interface;
const char * const ini_name; const char * const ini_name;

View File

@ -429,7 +429,7 @@ void GamepadPage::ClearControl( wxCommandEvent& event )
{ {
ControlButton* const btn = (ControlButton*)event.GetEventObject(); ControlButton* const btn = (ControlButton*)event.GetEventObject();
btn->control_reference->expression.clear(); btn->control_reference->expression.clear();
//btn->control_reference->device_qualifier = controller->default_device; btn->control_reference->range = 1.0f;
m_plugin.controls_crit.Enter(); // enter m_plugin.controls_crit.Enter(); // enter
controller->UpdateReferences( m_plugin.controller_interface ); controller->UpdateReferences( m_plugin.controller_interface );

View File

@ -32,13 +32,10 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
if ( (*g)->static_bitmap ) if ( (*g)->static_bitmap )
{ {
// don't want game thread updating input when we are using it here
if ( false == m_plugin.interface_crit.TryEnter() )
return;
//if ( false == is_game_running )
// just always update
m_plugin.controller_interface.UpdateInput(); m_plugin.controller_interface.UpdateInput();
// don't want game thread updating input when we are using it here
if (false == m_plugin.controller_interface.update_lock.TryEnter())
return;
wxMemoryDC dc; wxMemoryDC dc;
wxBitmap bitmap((*g)->static_bitmap->GetBitmap()); wxBitmap bitmap((*g)->static_bitmap->GetBitmap());
@ -324,7 +321,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
(*g)->static_bitmap->SetBitmap(bitmap); (*g)->static_bitmap->SetBitmap(bitmap);
m_plugin.interface_crit.Leave(); m_plugin.controller_interface.update_lock.Leave();
} }
} }

View File

@ -27,68 +27,70 @@ static const u8 nunchuk_button_bitmasks[] =
Nunchuk::BUTTON_Z, Nunchuk::BUTTON_Z,
}; };
Nunchuk::Nunchuk(UDPWrapper * wrp) : Attachment( "Nunchuk" ) , udpWrap(wrp) Nunchuk::Nunchuk(UDPWrapper *wrp) : Attachment("Nunchuk") , m_udpWrap(wrp)
{ {
// buttons // buttons
groups.push_back( m_buttons = new Buttons( "Buttons" ) ); groups.push_back(m_buttons = new Buttons("Buttons"));
m_buttons->controls.push_back( new ControlGroup::Input( "C" ) ); m_buttons->controls.push_back(new ControlGroup::Input("C"));
m_buttons->controls.push_back( new ControlGroup::Input( "Z" ) ); m_buttons->controls.push_back(new ControlGroup::Input("Z"));
// stick // stick
groups.push_back( m_stick = new AnalogStick( "Stick" ) ); groups.push_back(m_stick = new AnalogStick("Stick"));
// tilt
groups.push_back( m_tilt = new Tilt( "Tilt" ) );
// swing // swing
//groups.push_back( m_swing = new Force( "Swing" ) ); groups.push_back(m_swing = new Force("Swing"));
// tilt
groups.push_back(m_tilt = new Tilt("Tilt"));
// shake // shake
groups.push_back( m_shake = new Buttons( "Shake" ) ); groups.push_back(m_shake = new Buttons("Shake"));
m_shake->controls.push_back( new ControlGroup::Input( "X" ) ); m_shake->controls.push_back(new ControlGroup::Input("X"));
m_shake->controls.push_back( new ControlGroup::Input( "Y" ) ); m_shake->controls.push_back(new ControlGroup::Input("Y"));
m_shake->controls.push_back( new ControlGroup::Input( "Z" ) ); m_shake->controls.push_back(new ControlGroup::Input("Z"));
// set up register // set up register
// calibration // calibration
memcpy( &reg[0x20], nunchuck_calibration, sizeof(nunchuck_calibration) ); memcpy(&reg[0x20], nunchuck_calibration, sizeof(nunchuck_calibration));
// id // id
memcpy( &reg[0xfa], nunchuck_id, sizeof(nunchuck_id) ); memcpy(&reg[0xfa], nunchuck_id, sizeof(nunchuck_id));
// this should get set to 0 on disconnect, but it isn't, o well // this should get set to 0 on disconnect, but it isn't, o well
memset(m_shake_step, 0, sizeof(m_shake_step)); memset(m_shake_step, 0, sizeof(m_shake_step));
} }
void Nunchuk::GetState( u8* const data, const bool focus ) void Nunchuk::GetState(u8* const data, const bool focus)
{ {
wm_extension* const ncdata = (wm_extension*)data; wm_extension* const ncdata = (wm_extension*)data;
ncdata->bt = 0; ncdata->bt = 0;
// stick / not using calibration data for stick, o well // stick / not using calibration data for stick, o well
m_stick->GetState( &ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0 ); m_stick->GetState(&ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0);
// tilt // tilt
EmulateTilt((wm_accel*)&ncdata->ax, m_tilt, (accel_cal*)&reg[0x20], focus); EmulateTilt((wm_accel*)&ncdata->ax, m_tilt, (accel_cal*)&reg[0x20], focus);
if (focus) if (focus)
{ {
// swing
EmulateSwing((wm_accel*)&ncdata->ax, m_swing, (accel_cal*)&reg[0x20]);
// shake // shake
EmulateShake(&ncdata->ax, m_shake, m_shake_step); EmulateShake(&ncdata->ax, m_shake, m_shake_step);
// buttons // buttons
m_buttons->GetState( &ncdata->bt, nunchuk_button_bitmasks ); m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks);
} }
// flip the button bits :/ // flip the button bits :/
ncdata->bt ^= 0x03; ncdata->bt ^= 0x03;
//UDPNunchuk stuff //UDPNunchuk stuff
if (udpWrap->inst) if (m_udpWrap->inst)
{ {
if (udpWrap->updNun) if (m_udpWrap->updNun)
{ {
u8 mask; u8 mask;
float x, y; float x, y;
udpWrap->inst->getNunchuck(x, y, mask); m_udpWrap->inst->getNunchuck(x, y, mask);
// buttons // buttons
if (mask & UDPWM_NC) if (mask & UDPWM_NC)
ncdata->bt &= ~WiimoteEmu::Nunchuk::BUTTON_C; ncdata->bt &= ~WiimoteEmu::Nunchuk::BUTTON_C;
@ -101,12 +103,12 @@ void Nunchuk::GetState( u8* const data, const bool focus )
ncdata->jy = u8(0x80 + y*127); ncdata->jy = u8(0x80 + y*127);
} }
} }
if (udpWrap->updNunAccel) if (m_udpWrap->updNunAccel)
{ {
const accel_cal * const calib = (accel_cal*)&reg[0x20]; const accel_cal * const calib = (accel_cal*)&reg[0x20];
wm_accel * const accel = (wm_accel*)&ncdata->ax; wm_accel * const accel = (wm_accel*)&ncdata->ax;
float x,y,z; float x,y,z;
udpWrap->inst->getNunchuckAccel(x,y,z); m_udpWrap->inst->getNunchuckAccel(x,y,z);
accel->x=u8(x*(calib->one_g.x-calib->zero_g.x)+calib->zero_g.x); accel->x=u8(x*(calib->one_g.x-calib->zero_g.x)+calib->zero_g.x);
accel->y=u8(y*(calib->one_g.y-calib->zero_g.y)+calib->zero_g.y); accel->y=u8(y*(calib->one_g.y-calib->zero_g.y)+calib->zero_g.y);
accel->z=u8(z*(calib->one_g.z-calib->zero_g.z)+calib->zero_g.z); accel->z=u8(z*(calib->one_g.z-calib->zero_g.z)+calib->zero_g.z);

View File

@ -31,7 +31,7 @@ private:
unsigned int m_shake_step[3]; unsigned int m_shake_step[3];
UDPWrapper * udpWrap; UDPWrapper* const m_udpWrap;
}; };
} }

View File

@ -4,6 +4,9 @@
#define UDPTLAYER_H #define UDPTLAYER_H
#include "UDPWiimote.h" #include "UDPWiimote.h"
#include "WiimoteEmu.h"
using WiimoteEmu::Wiimote;
namespace UDPTLayer namespace UDPTLayer
{ {
@ -12,17 +15,17 @@ namespace UDPTLayer
if (!(m->inst)) return; if (!(m->inst)) return;
if (!(m->updButt)) return; if (!(m->updButt)) return;
u32 mask=m->inst->getButtons(); u32 mask=m->inst->getButtons();
*butt|=(mask&UDPWM_BA)?WIIMOTE_A:0; *butt|=(mask&UDPWM_BA)?Wiimote::BUTTON_A:0;
*butt|=(mask&UDPWM_BB)?WIIMOTE_B:0; *butt|=(mask&UDPWM_BB)?Wiimote::BUTTON_B:0;
*butt|=(mask&UDPWM_B1)?WIIMOTE_ONE:0; *butt|=(mask&UDPWM_B1)?Wiimote::BUTTON_ONE:0;
*butt|=(mask&UDPWM_B2)?WIIMOTE_TWO:0; *butt|=(mask&UDPWM_B2)?Wiimote::BUTTON_TWO:0;
*butt|=(mask&UDPWM_BP)?WIIMOTE_PLUS:0; *butt|=(mask&UDPWM_BP)?Wiimote::BUTTON_PLUS:0;
*butt|=(mask&UDPWM_BM)?WIIMOTE_MINUS:0; *butt|=(mask&UDPWM_BM)?Wiimote::BUTTON_MINUS:0;
*butt|=(mask&UDPWM_BH)?WIIMOTE_HOME:0; *butt|=(mask&UDPWM_BH)?Wiimote::BUTTON_HOME:0;
*butt|=(mask&UDPWM_BU)?WIIMOTE_PAD_UP:0; *butt|=(mask&UDPWM_BU)?Wiimote::PAD_UP:0;
*butt|=(mask&UDPWM_BD)?WIIMOTE_PAD_DOWN:0; *butt|=(mask&UDPWM_BD)?Wiimote::PAD_DOWN:0;
*butt|=(mask&UDPWM_BL)?WIIMOTE_PAD_LEFT:0; *butt|=(mask&UDPWM_BL)?Wiimote::PAD_LEFT:0;
*butt|=(mask&UDPWM_BR)?WIIMOTE_PAD_RIGHT:0; *butt|=(mask&UDPWM_BR)?Wiimote::PAD_RIGHT:0;
} }
void GetAcceleration(UDPWrapper * m , wm_accel * data, accel_cal * calib) void GetAcceleration(UDPWrapper * m , wm_accel * data, accel_cal * calib)

View File

@ -10,22 +10,7 @@
#include <Timer.h> #include <Timer.h>
#include <Common.h> #include <Common.h>
// buttons #include "UDPTLayer.h"
#define WIIMOTE_PAD_LEFT 0x01
#define WIIMOTE_PAD_RIGHT 0x02
#define WIIMOTE_PAD_DOWN 0x04
#define WIIMOTE_PAD_UP 0x08
#define WIIMOTE_PLUS 0x10
#define WIIMOTE_TWO 0x0100
#define WIIMOTE_ONE 0x0200
#define WIIMOTE_B 0x0400
#define WIIMOTE_A 0x0800
#define WIIMOTE_MINUS 0x1000
#define WIIMOTE_HOME 0x8000
#include "UDPTLayer.h" //this must be included after the buttons
namespace WiimoteEmu namespace WiimoteEmu
{ {
@ -38,9 +23,9 @@ static const u8 eeprom_data_0[] = {
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, /*0x74, 0xD3,*/ 0x00, 0x00, // messing up the checksum on purpose 0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, /*0x74, 0xD3,*/ 0x00, 0x00, // messing up the checksum on purpose
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, /*0x74, 0xD3,*/ 0x00, 0x00, 0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, /*0x74, 0xD3,*/ 0x00, 0x00,
// Accelerometer // Accelerometer
// 0g x,y,z, 1g x,y,z, 2 byte checksum // 0g x,y,z, 1g x,y,z, idk, last byte is a checksum
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E, 0x80, 0x80, 0x80, 0x00, 0x9A, 0x9A, 0x9A, 0x00, 0x40, 0xE3,
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E 0x80, 0x80, 0x80, 0x00, 0x9A, 0x9A, 0x9A, 0x00, 0x40, 0xE3,
}; };
static const u8 motion_plus_id[] = { 0x00, 0x00, 0xA6, 0x20, 0x00, 0x05 }; static const u8 motion_plus_id[] = { 0x00, 0x00, 0xA6, 0x20, 0x00, 0x05 };
@ -51,6 +36,8 @@ static const u8 eeprom_data_16D0[] = {
0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13 0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13
}; };
#define SWING_INTENSITY 0x40
static struct ReportFeatures static struct ReportFeatures
{ {
u8 core, accel, ir, ext, size; u8 core, accel, ir, ext, size;
@ -98,10 +85,10 @@ void EmulateShake( u8* const accel
shake_step[i] = 0; shake_step[i] = 0;
} }
void EmulateTilt( wm_accel* const accel void EmulateTilt(wm_accel* const accel
, ControllerEmu::Tilt* const tilt_group , ControllerEmu::Tilt* const tilt_group
, const accel_cal* const cal , const accel_cal* const cal
, bool focus, bool sideways, bool upright) , const bool focus, const bool sideways, const bool upright)
{ {
float roll, pitch; float roll, pitch;
tilt_group->GetState( &roll, &pitch, 0, focus ? (PI / 2) : 0 ); // 90 degrees tilt_group->GetState( &roll, &pitch, 0, focus ? (PI / 2) : 0 ); // 90 degrees
@ -116,46 +103,12 @@ void EmulateTilt( wm_accel* const accel
unsigned int ud = 0, lr = 0, fb = 0; unsigned int ud = 0, lr = 0, fb = 0;
// some notes that no one will understand but me :p // some notes that no one will understand but me :p
// left, forward, up // left, forward, up
// lr/ left == negative for all orientations // lr/ left == negative for all orientations
// ud/ up == negative for upright longways // ud/ up == negative for upright longways
// fb/ forward == positive for (sideways flat) // fb/ forward == positive for (sideways flat)
//if (sideways) // determine which axis is which direction
//{
// if (upright)
// {
// ud = 0;
// lr = 1;
// fb = 2;
// }
// else
// {
// ud = 2;
// lr = 1;
// fb = 0;
// one_g[fb] *= -1;
// }
//}
//else
//{
// if (upright)
// {
// ud = 1;
// lr = 0;
// fb = 2;
// one_g[ud] *= -1;
// }
// else
// {
// ud = 2;
// lr = 0;
// fb = 1;
// }
//}
// this is the above statements compacted
ud = upright ? (sideways ? 0 : 1) : 2; ud = upright ? (sideways ? 0 : 1) : 2;
lr = sideways; lr = sideways;
fb = upright ? 2 : (sideways ? 0 : 1); fb = upright ? 2 : (sideways ? 0 : 1);
@ -171,34 +124,62 @@ void EmulateTilt( wm_accel* const accel
(&accel->x)[fb] = u8(sin(pitch) * one_g[fb] + zero_g[fb]); (&accel->x)[fb] = u8(sin(pitch) * one_g[fb] + zero_g[fb]);
} }
//void EmulateSwing() void EmulateSwing(wm_accel* const accel
//{ , ControllerEmu::Force* const swing_group
// , const accel_cal* const cal
//} , const bool sideways, const bool upright)
{
float swing[3];
swing_group->GetState(swing, 0, 2 * PI);
s8 g_dir[3] = {-1, -1, -1};
u8 axis_map[3];
// determine which axis is which direction
axis_map[0] = upright ? (sideways ? 0 : 1) : 2; // up/down
axis_map[1] = sideways; // left|right
axis_map[2] = upright ? 2 : (sideways ? 0 : 1); // forward/backward
// some orientations have up as positive, some as negative
// same with forward
if (sideways && !upright)
g_dir[axis_map[2]] *= -1;
if (!sideways && upright)
g_dir[axis_map[0]] *= -1;
for (unsigned int i=0; i<3; ++i)
{
if (swing[i])
{
// sin() should create a nice curve for the swing data
(&accel->x)[axis_map[i]] += sin(swing[i]) * SWING_INTENSITY * g_dir[i];
}
}
}
const u16 button_bitmasks[] = const u16 button_bitmasks[] =
{ {
WIIMOTE_A, WIIMOTE_B, WIIMOTE_ONE, WIIMOTE_TWO, WIIMOTE_MINUS, WIIMOTE_PLUS, WIIMOTE_HOME Wiimote::BUTTON_A,
Wiimote::BUTTON_B,
Wiimote::BUTTON_ONE,
Wiimote::BUTTON_TWO,
Wiimote::BUTTON_MINUS,
Wiimote::BUTTON_PLUS,
Wiimote::BUTTON_HOME
}; };
const u16 dpad_bitmasks[] = const u16 dpad_bitmasks[] =
{ {
WIIMOTE_PAD_UP, WIIMOTE_PAD_DOWN, WIIMOTE_PAD_LEFT, WIIMOTE_PAD_RIGHT Wiimote::PAD_UP, Wiimote::PAD_DOWN, Wiimote::PAD_LEFT, Wiimote::PAD_RIGHT
}; };
const u16 dpad_sideways_bitmasks[] = const u16 dpad_sideways_bitmasks[] =
{ {
WIIMOTE_PAD_RIGHT, WIIMOTE_PAD_LEFT, WIIMOTE_PAD_UP, WIIMOTE_PAD_DOWN Wiimote::PAD_RIGHT, Wiimote::PAD_LEFT, Wiimote::PAD_UP, Wiimote::PAD_DOWN
}; };
const char* const named_buttons[] = const char* const named_buttons[] =
{ {
"A", "A", "B", "1", "2", "-", "+", "Home",
"B",
"1",
"2",
"-",
"+",
"Home",
}; };
void Wiimote::Reset() void Wiimote::Reset()
@ -216,11 +197,11 @@ void Wiimote::Reset()
m_extension->active_extension = -1; m_extension->active_extension = -1;
// eeprom // eeprom
memset( m_eeprom, 0, sizeof(m_eeprom) ); memset(m_eeprom, 0, sizeof(m_eeprom));
// calibration data // calibration data
memcpy( m_eeprom, eeprom_data_0, sizeof(eeprom_data_0) ); memcpy(m_eeprom, eeprom_data_0, sizeof(eeprom_data_0));
// dunno what this is for, copied from old plugin // dunno what this is for, copied from old plugin
memcpy( m_eeprom + 0x16D0, eeprom_data_16D0, sizeof(eeprom_data_16D0) ); memcpy(m_eeprom + 0x16D0, eeprom_data_16D0, sizeof(eeprom_data_16D0));
// set up the register // set up the register
m_register.clear(); m_register.clear();
@ -235,10 +216,10 @@ void Wiimote::Reset()
m_reg_ir = (IrReg*)&m_register[0xB00000][0]; m_reg_ir = (IrReg*)&m_register[0xB00000][0];
// testing // testing
//memcpy( m_reg_motion_plus + 0xfa, motion_plus_id, sizeof(motion_plus_id) ); //memcpy(m_reg_motion_plus + 0xfa, motion_plus_id, sizeof(motion_plus_id));
// status // status
memset( &m_status, 0, sizeof(m_status) ); memset(&m_status, 0, sizeof(m_status));
// Battery levels in voltage // Battery levels in voltage
// 0x00 - 0x32: level 1 // 0x00 - 0x32: level 1
// 0x33 - 0x43: level 2 // 0x33 - 0x43: level 2
@ -247,7 +228,6 @@ void Wiimote::Reset()
m_status.battery = 0x5f; m_status.battery = 0x5f;
memset(m_shake_step, 0, sizeof(m_shake_step)); memset(m_shake_step, 0, sizeof(m_shake_step));
memset(m_swing_step, 0, sizeof(m_swing_step));
// clear read request queue // clear read request queue
while (m_read_requests.size()) while (m_read_requests.size())
@ -264,50 +244,50 @@ Wiimote::Wiimote( const unsigned int index )
// ---- set up all the controls ---- // ---- set up all the controls ----
// buttons // buttons
groups.push_back( m_buttons = new Buttons( "Buttons" ) ); groups.push_back(m_buttons = new Buttons("Buttons"));
for ( unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i ) for (unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i)
m_buttons->controls.push_back( new ControlGroup::Input( named_buttons[i] ) ); m_buttons->controls.push_back(new ControlGroup::Input( named_buttons[i]));
// ir // ir
groups.push_back( m_ir = new Cursor( "IR", &g_WiimoteInitialize ) ); groups.push_back(m_ir = new Cursor("IR", &g_WiimoteInitialize));
// tilt
groups.push_back( m_tilt = new Tilt( "Tilt" ) );
// swing // swing
//groups.push_back( m_swing = new Force( "Swing" ) ); groups.push_back(m_swing = new Force("Swing"));
//udp // tilt
groups.push_back( m_udp = new UDPWrapper( m_index , "UDP Wiimote" ) ); groups.push_back(m_tilt = new Tilt("Tilt"));
// udp
groups.push_back(m_udp = new UDPWrapper(m_index, "UDP Wiimote"));
// shake // shake
groups.push_back( m_shake = new Buttons( "Shake" ) ); groups.push_back(m_shake = new Buttons("Shake"));
m_shake->controls.push_back( new ControlGroup::Input( "X" ) ); m_shake->controls.push_back(new ControlGroup::Input("X"));
m_shake->controls.push_back( new ControlGroup::Input( "Y" ) ); m_shake->controls.push_back(new ControlGroup::Input("Y"));
m_shake->controls.push_back( new ControlGroup::Input( "Z" ) ); m_shake->controls.push_back(new ControlGroup::Input("Z"));
// extension // extension
groups.push_back( m_extension = new Extension( "Extension" ) ); groups.push_back(m_extension = new Extension("Extension"));
m_extension->attachments.push_back( new WiimoteEmu::None() ); m_extension->attachments.push_back(new WiimoteEmu::None());
m_extension->attachments.push_back( new WiimoteEmu::Nunchuk(m_udp) ); m_extension->attachments.push_back(new WiimoteEmu::Nunchuk(m_udp));
m_extension->attachments.push_back( new WiimoteEmu::Classic() ); m_extension->attachments.push_back(new WiimoteEmu::Classic());
m_extension->attachments.push_back( new WiimoteEmu::Guitar() ); m_extension->attachments.push_back(new WiimoteEmu::Guitar());
m_extension->attachments.push_back( new WiimoteEmu::Drums() ); m_extension->attachments.push_back(new WiimoteEmu::Drums());
// rumble // rumble
groups.push_back( m_rumble = new ControlGroup( "Rumble" ) ); groups.push_back(m_rumble = new ControlGroup("Rumble"));
m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) ); m_rumble->controls.push_back(new ControlGroup::Output("Motor"));
// dpad // dpad
groups.push_back( m_dpad = new Buttons( "D-Pad" ) ); groups.push_back(m_dpad = new Buttons("D-Pad"));
for ( unsigned int i=0; i < 4; ++i ) for (unsigned int i=0; i < 4; ++i)
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) ); m_dpad->controls.push_back(new ControlGroup::Input(named_directions[i]));
// options // options
groups.push_back( m_options = new ControlGroup( "Options" ) ); groups.push_back( m_options = new ControlGroup("Options"));
m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) ); m_options->settings.push_back(new ControlGroup::Setting("Background Input", false));
m_options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) ); m_options->settings.push_back(new ControlGroup::Setting("Sideways Wiimote", false));
m_options->settings.push_back( new ControlGroup::Setting( "Upright Wiimote", false ) ); m_options->settings.push_back(new ControlGroup::Setting("Upright Wiimote", false));
#ifdef USE_WIIMOTE_EMU_SPEAKER #ifdef USE_WIIMOTE_EMU_SPEAKER
// set up speaker stuff // set up speaker stuff
@ -466,33 +446,12 @@ void Wiimote::Update()
EmulateTilt((wm_accel*)&data[rpt.accel], m_tilt, (accel_cal*)&m_eeprom[0x16], is_focus, is_sideways, is_upright); EmulateTilt((wm_accel*)&data[rpt.accel], m_tilt, (accel_cal*)&m_eeprom[0x16], is_focus, is_sideways, is_upright);
// ----SWING---- // ----SWING----
//const s8 swing_data[] = { 0x20, 0x40, 0x20, 0x00 };
//u8 swing[3];
//m_swing->GetState( swing, 0x80, 0x40 );
//// up/down
//if (swing[0] != 0x80)
//{
// //data[rpt.accel + 0] = swing[0];
// data[rpt.accel + 2] += swing_data[m_swing_step[0]/4];
// if (m_swing_step[0] < 12)
// ++m_swing_step[0];
//}
//else
// m_swing_step[0] = 0;
//// left/right
//if (swing[1] != 0x80)
// data[rpt.accel + !is_sideways] = swing[1];
//// forward/backward
//if (swing[2] != 0x80)
// data[rpt.accel + is_sideways] = swing[2];
// ----SHAKE---- // ----SHAKE----
if (is_focus) if (is_focus)
{ {
EmulateSwing((wm_accel*)&data[rpt.accel], m_swing, (accel_cal*)&m_eeprom[0x16], is_sideways, is_upright);
EmulateShake(data + rpt.accel, m_shake, m_shake_step); EmulateShake(data + rpt.accel, m_shake, m_shake_step);
// UDP Wiimote
UDPTLayer::GetAcceleration(m_udp, (wm_accel*)&data[rpt.accel], (accel_cal*)&m_eeprom[0x16]); UDPTLayer::GetAcceleration(m_udp, (wm_accel*)&data[rpt.accel], (accel_cal*)&m_eeprom[0x16]);
} }
} }
@ -600,14 +559,6 @@ void Wiimote::Update()
{ {
m_extension->GetState(data + rpt.ext, is_focus); m_extension->GetState(data + rpt.ext, is_focus);
// ---- UDP Wiimote nunchuk stuff
// 1 == is hacky, for if nunchuk is attached
//if (is_focus && 1 == m_extension->active_extension)
//{
// UDPTLayer::GetNunchuk(m_udp,(wm_extension*)(data + rpt.ext));
//}
// ---- end UDP Wiimote
// i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this. // i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this.
// i think it should be unencrpyted in the register, encrypted when read. // i think it should be unencrpyted in the register, encrypted when read.
memcpy(m_reg_ext->controller_data, data + rpt.ext, sizeof(wm_extension)); memcpy(m_reg_ext->controller_data, data + rpt.ext, sizeof(wm_extension));
@ -862,5 +813,3 @@ void Wiimote::Register::Write( size_t address, void* src, size_t length )
} }
} }

View File

@ -32,18 +32,40 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiimoteEmu namespace WiimoteEmu
{ {
void EmulateShake( u8* const accel_data void EmulateShake(u8* const accel_data
, ControllerEmu::Buttons* const buttons_group , ControllerEmu::Buttons* const buttons_group
, unsigned int* const shake_step ); , unsigned int* const shake_step);
void EmulateTilt( wm_accel* const accel void EmulateTilt(wm_accel* const accel
, ControllerEmu::Tilt* const tilt_group , ControllerEmu::Tilt* const tilt_group
, const accel_cal* const cal , const accel_cal* const cal
, bool focus, bool sideways = false, bool upright = false); , const bool focus, const bool sideways = false, const bool upright = false);
void EmulateSwing(wm_accel* const accel
, ControllerEmu::Force* const tilt_group
, const accel_cal* const cal
, const bool sideways = false, const bool upright = false);
class Wiimote : public ControllerEmu class Wiimote : public ControllerEmu
{ {
public: public:
enum
{
PAD_LEFT = 0x01,
PAD_RIGHT = 0x02,
PAD_DOWN = 0x04,
PAD_UP = 0x08,
BUTTON_PLUS = 0x10,
BUTTON_TWO = 0x0100,
BUTTON_ONE = 0x0200,
BUTTON_B = 0x0400,
BUTTON_A = 0x0800,
BUTTON_MINUS = 0x1000,
BUTTON_HOME = 0x8000,
};
Wiimote( const unsigned int index ); Wiimote( const unsigned int index );
std::string GetName() const; std::string GetName() const;
@ -103,7 +125,6 @@ private:
u16 m_reporting_channel; u16 m_reporting_channel;
unsigned int m_shake_step[3]; unsigned int m_shake_step[3];
unsigned int m_swing_step[3];
wm_status_report m_status; wm_status_report m_status;

View File

@ -211,11 +211,10 @@ void Wiimote_Update(int _number)
g_plugin.controls_crit.Enter(); g_plugin.controls_crit.Enter();
static int _last_number = 4; static int _last_number = 4;
if ( _number <= _last_number && g_plugin.interface_crit.TryEnter() ) if (_number <= _last_number)
{ {
g_plugin.controller_interface.UpdateOutput(); g_plugin.controller_interface.UpdateOutput();
g_plugin.controller_interface.UpdateInput(); g_plugin.controller_interface.UpdateInput();
g_plugin.interface_crit.Leave();
} }
_last_number = _number; _last_number = _number;
@ -225,7 +224,7 @@ void Wiimote_Update(int _number)
WiimoteReal::Update(_number); WiimoteReal::Update(_number);
break; break;
case WIIMOTE_SRC_EMU : case WIIMOTE_SRC_EMU :
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->Update(); ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->Update();
break; break;
} }