Commited my new wiimote plugin work so far. Some code was copied from the current wiimote plugin. I have cleaned up most of the functions, but there are still a bunch of unused structs and stuff that I need to clean up.
Moved ControllerInterface to InputCommon. Moved GCPadNew GUI/Config code to a new project, InputPluginCommon. It is used by both GCPadNew and WiimoteNew. I hope that I included everyone's fixes to GCPadNew and ControllerInterface. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5355 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
9592da1a9b
commit
d8906d2a0c
|
@ -408,6 +408,74 @@
|
|||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="ControllerInterface"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\ControllerInterface.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\ControllerInterface.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="DirectInput"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputJoystick.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputJoystick.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputKeyboardMouse.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputKeyboardMouse.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\NamedKeys.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SDL"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\SDL\SDL.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\SDL\SDL.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="XInput"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\XInput\XInput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\XInput\XInput.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\Src\Configuration.cpp"
|
||||
>
|
||||
|
|
|
@ -40,7 +40,7 @@ void ControllerInterface::Init()
|
|||
ciface::DirectInput::Init( m_devices/*, (HWND)m_hwnd*/ );
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
ciface::Xlib::Init( m_devices, m_hwnd );
|
||||
ciface::XLIB::Init( m_devices, m_hwnd );
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
ciface::OSX::Init( m_devices, m_hwnd );
|
||||
|
@ -238,7 +238,7 @@ ControlState ControllerInterface::InputReference::State( const ControlState igno
|
|||
if ( NULL == device )
|
||||
return 0;
|
||||
|
||||
ControlState state = 0;
|
||||
ControlState state;
|
||||
// this mode thing will be turned into a switch statement
|
||||
switch ( mode )
|
||||
{
|
||||
|
@ -360,7 +360,11 @@ void ControllerInterface::DeviceQualifier::FromDevice(const ControllerInterface:
|
|||
//
|
||||
bool ControllerInterface::DeviceQualifier::operator==(const ControllerInterface::Device* const dev) const
|
||||
{
|
||||
return (dev->GetName() == name) && (dev->GetId() == cid) && (dev->GetSource() == source);
|
||||
if ( dev->GetName() == name )
|
||||
if ( dev->GetId() == cid )
|
||||
if ( dev->GetSource() == source )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
|
@ -377,12 +377,10 @@ std::string Joystick::GetSource() const
|
|||
|
||||
// update IO
|
||||
|
||||
|
||||
bool Joystick::UpdateInput()
|
||||
{
|
||||
if ( m_must_poll )
|
||||
m_device->Poll();
|
||||
//return false;
|
||||
|
||||
HRESULT hr = m_device->GetDeviceState( sizeof(m_state_in), &m_state_in );
|
||||
|
|
@ -189,8 +189,8 @@ bool KeyboardMouse::UpdateOutput()
|
|||
m_current_state_out[i] ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( kbinputs.size() )
|
||||
|
||||
if (kbinputs.size())
|
||||
return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) );
|
||||
else
|
||||
return true;
|
|
@ -1,101 +1,101 @@
|
|||
#include "../ControllerInterface.h"
|
||||
|
||||
#ifdef CIFACE_USE_OSX
|
||||
|
||||
#include "OSX.h"
|
||||
#include "OSXPrivate.h"
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace OSX
|
||||
{
|
||||
|
||||
|
||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd )
|
||||
{
|
||||
// mouse will be added to this, Keyboard class will be turned into KeyboardMouse
|
||||
// single device for combined keyboard/mouse, this will allow combinations like shift+click more easily
|
||||
//devices.push_back( new Keyboard( hwnd ) );
|
||||
}
|
||||
|
||||
Keyboard::Keyboard( void *View )
|
||||
{
|
||||
|
||||
memset( &m_state, 0, sizeof(m_state) );
|
||||
OSX_Init(View);
|
||||
// This is REALLY dumb right here
|
||||
// Should REALLY cover the entire UTF-8 Range
|
||||
for (int a = 0; a < 256; ++a)
|
||||
inputs.push_back( new Key( (char)a ) );
|
||||
}
|
||||
|
||||
|
||||
Keyboard::~Keyboard()
|
||||
{
|
||||
// might not need this func
|
||||
}
|
||||
|
||||
|
||||
ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input )
|
||||
{
|
||||
return ((Input*)input)->GetState( &m_state );
|
||||
}
|
||||
|
||||
void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Keyboard::UpdateInput()
|
||||
{
|
||||
memset(m_state.keyboard, 0, 256);
|
||||
OSX_UpdateKeys(256, m_state.keyboard );
|
||||
|
||||
// mouse stuff in here too
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Keyboard::UpdateOutput()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string Keyboard::GetName() const
|
||||
{
|
||||
return "Keyboard";
|
||||
//return "Keyboard Mouse"; // change to this later
|
||||
}
|
||||
|
||||
std::string Keyboard::GetSource() const
|
||||
{
|
||||
return "OSX";
|
||||
}
|
||||
|
||||
int Keyboard::GetId() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ControlState Keyboard::Key::GetState( State* const state )
|
||||
{
|
||||
for(unsigned int a = 0; a < 256; ++a)
|
||||
if(state->keyboard[a] == m_index)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Keyboard::Key::GetName() const
|
||||
{
|
||||
char temp[16];
|
||||
sprintf(temp, "Key:%c", m_index);
|
||||
return std::string(temp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "../ControllerInterface.h"
|
||||
|
||||
#ifdef CIFACE_USE_OSX
|
||||
|
||||
#include "OSX.h"
|
||||
#include "OSXPrivate.h"
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace OSX
|
||||
{
|
||||
|
||||
|
||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd )
|
||||
{
|
||||
// mouse will be added to this, Keyboard class will be turned into KeyboardMouse
|
||||
// single device for combined keyboard/mouse, this will allow combinations like shift+click more easily
|
||||
//devices.push_back( new Keyboard( hwnd ) );
|
||||
}
|
||||
|
||||
Keyboard::Keyboard( void *View )
|
||||
{
|
||||
|
||||
memset( &m_state, 0, sizeof(m_state) );
|
||||
OSX_Init(View);
|
||||
// This is REALLY dumb right here
|
||||
// Should REALLY cover the entire UTF-8 Range
|
||||
for (int a = 0; a < 256; ++a)
|
||||
inputs.push_back( new Key( (char)a ) );
|
||||
}
|
||||
|
||||
|
||||
Keyboard::~Keyboard()
|
||||
{
|
||||
// might not need this func
|
||||
}
|
||||
|
||||
|
||||
ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input )
|
||||
{
|
||||
return ((Input*)input)->GetState( &m_state );
|
||||
}
|
||||
|
||||
void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Keyboard::UpdateInput()
|
||||
{
|
||||
memset(m_state.keyboard, 0, 256);
|
||||
OSX_UpdateKeys(256, m_state.keyboard );
|
||||
|
||||
// mouse stuff in here too
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Keyboard::UpdateOutput()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string Keyboard::GetName() const
|
||||
{
|
||||
return "Keyboard";
|
||||
//return "Keyboard Mouse"; // change to this later
|
||||
}
|
||||
|
||||
std::string Keyboard::GetSource() const
|
||||
{
|
||||
return "OSX";
|
||||
}
|
||||
|
||||
int Keyboard::GetId() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ControlState Keyboard::Key::GetState( State* const state )
|
||||
{
|
||||
for(unsigned int a = 0; a < 256; ++a)
|
||||
if(state->keyboard[a] == m_index)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Keyboard::Key::GetName() const
|
||||
{
|
||||
char temp[16];
|
||||
sprintf(temp, "Key:%c", m_index);
|
||||
return std::string(temp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,68 +1,68 @@
|
|||
#ifndef _CIFACE_OSX_H_
|
||||
#define _CIFACE_OSX_H_
|
||||
|
||||
#include "../ControllerInterface.h"
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace OSX
|
||||
{
|
||||
|
||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd );
|
||||
|
||||
class Keyboard : public ControllerInterface::Device
|
||||
{
|
||||
friend class ControllerInterface;
|
||||
friend class ControllerInterface::ControlReference;
|
||||
|
||||
protected:
|
||||
|
||||
struct State
|
||||
{
|
||||
char keyboard[256]; // really dumb
|
||||
// mouse crap will go here
|
||||
};
|
||||
|
||||
class Input : public ControllerInterface::Device::Input
|
||||
{
|
||||
friend class Keyboard;
|
||||
protected:
|
||||
Input( const unsigned char index ) : m_index(index) {}
|
||||
virtual ControlState GetState( State* const js ) = 0;
|
||||
|
||||
const unsigned char m_index;
|
||||
};
|
||||
|
||||
class Key : public Input
|
||||
{
|
||||
friend class Keyboard;
|
||||
public:
|
||||
std::string GetName() const;
|
||||
protected:
|
||||
Key( const unsigned char key ) : Input(key) {}
|
||||
ControlState GetState( State* const js );
|
||||
|
||||
};
|
||||
|
||||
bool UpdateInput();
|
||||
bool UpdateOutput();
|
||||
|
||||
ControlState GetInputState( const ControllerInterface::Device::Input* const input );
|
||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
||||
|
||||
public:
|
||||
Keyboard( void* view );
|
||||
~Keyboard();
|
||||
|
||||
std::string GetName() const;
|
||||
std::string GetSource() const;
|
||||
int GetId() const;
|
||||
|
||||
private:
|
||||
State m_state;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef _CIFACE_OSX_H_
|
||||
#define _CIFACE_OSX_H_
|
||||
|
||||
#include "../ControllerInterface.h"
|
||||
|
||||
namespace ciface
|
||||
{
|
||||
namespace OSX
|
||||
{
|
||||
|
||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd );
|
||||
|
||||
class Keyboard : public ControllerInterface::Device
|
||||
{
|
||||
friend class ControllerInterface;
|
||||
friend class ControllerInterface::ControlReference;
|
||||
|
||||
protected:
|
||||
|
||||
struct State
|
||||
{
|
||||
char keyboard[256]; // really dumb
|
||||
// mouse crap will go here
|
||||
};
|
||||
|
||||
class Input : public ControllerInterface::Device::Input
|
||||
{
|
||||
friend class Keyboard;
|
||||
protected:
|
||||
Input( const unsigned char index ) : m_index(index) {}
|
||||
virtual ControlState GetState( State* const js ) = 0;
|
||||
|
||||
const unsigned char m_index;
|
||||
};
|
||||
|
||||
class Key : public Input
|
||||
{
|
||||
friend class Keyboard;
|
||||
public:
|
||||
std::string GetName() const;
|
||||
protected:
|
||||
Key( const unsigned char key ) : Input(key) {}
|
||||
ControlState GetState( State* const js );
|
||||
|
||||
};
|
||||
|
||||
bool UpdateInput();
|
||||
bool UpdateOutput();
|
||||
|
||||
ControlState GetInputState( const ControllerInterface::Device::Input* const input );
|
||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
||||
|
||||
public:
|
||||
Keyboard( void* view );
|
||||
~Keyboard();
|
||||
|
||||
std::string GetName() const;
|
||||
std::string GetSource() const;
|
||||
int GetId() const;
|
||||
|
||||
private:
|
||||
State m_state;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -148,7 +148,15 @@ bool Device::UpdateInput()
|
|||
|
||||
bool Device::UpdateOutput()
|
||||
{
|
||||
return ( ERROR_SUCCESS == XInputSetState( m_index, &m_state_out ) );
|
||||
// this if statement is to make rumble work better when multiple ControllerInterfaces are using the device
|
||||
static XINPUT_VIBRATION current_state_out = {0,0};
|
||||
if ( memcmp( &m_state_out, ¤t_state_out, sizeof(m_state_out) ) )
|
||||
{
|
||||
current_state_out = m_state_out;
|
||||
return ( ERROR_SUCCESS == XInputSetState( m_index, &m_state_out ) );
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// GET name/source/id
|
|
@ -0,0 +1,450 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="InputPluginCommon"
|
||||
ProjectGUID="{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}"
|
||||
RootNamespace="VideoCommon"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_SECURE_SCL=0;_LIB;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
EnableEnhancedInstructionSet="2"
|
||||
FloatingPointModel="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="false"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\$(ProjectName).lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="DebugFast|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="DebugFast|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../Core/InputCommon/Src;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\Src\Config.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\Config.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiag.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiag.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiagBitmaps.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\IniFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\IniFile.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -1,11 +1,14 @@
|
|||
|
||||
#include "Config.h"
|
||||
|
||||
Plugin::Plugin()
|
||||
Plugin::Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name )
|
||||
: ini_name(_ini_name)
|
||||
, gui_name(_gui_name)
|
||||
, profile_name(_profile_name)
|
||||
{
|
||||
// GCPads
|
||||
for ( unsigned int i = 0; i<4; ++i )
|
||||
controllers.push_back( new GCPad( i ) );
|
||||
//for ( unsigned int i = 0; i<4; ++i )
|
||||
//controllers.push_back( new GCPad( i ) );
|
||||
// Wiimotes / disabled, cause it only the GUI half is done
|
||||
//for ( unsigned int i = 0; i<4; ++i )
|
||||
// controllers.push_back( new Wiimote( i ) );
|
||||
|
@ -25,7 +28,7 @@ void Plugin::LoadConfig()
|
|||
IniFile inifile;
|
||||
|
||||
std::ifstream file;
|
||||
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + CONFIG_FILE_NAME ).c_str() );
|
||||
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() );
|
||||
inifile.Load( file );
|
||||
file.close();
|
||||
|
||||
|
@ -48,7 +51,7 @@ void Plugin::SaveConfig()
|
|||
inifile.Clean();
|
||||
|
||||
std::ofstream file;
|
||||
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + CONFIG_FILE_NAME ).c_str() );
|
||||
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() );
|
||||
inifile.Save( file );
|
||||
file.close();
|
||||
}
|
|
@ -1,16 +1,12 @@
|
|||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#define CONFIG_FILE_NAME "GCPadNew.ini"
|
||||
|
||||
#include "ControllerInterface/ControllerInterface.h"
|
||||
#include <ControllerInterface/ControllerInterface.h>
|
||||
#include "Thread.h"
|
||||
#include "FileUtil.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
#include "ControllerEmu.h"
|
||||
#include "ControllerEmu/GCPad/GCPad.h"
|
||||
#include "ControllerEmu/Wiimote/Wiimote.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -21,7 +17,7 @@ class Plugin
|
|||
{
|
||||
public:
|
||||
|
||||
Plugin();
|
||||
Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name );
|
||||
~Plugin();
|
||||
|
||||
void LoadConfig();
|
||||
|
@ -31,6 +27,10 @@ public:
|
|||
|
||||
Common::CriticalSection controls_crit, interface_crit; // lock controls first
|
||||
ControllerInterface controller_interface;
|
||||
|
||||
const char * const ini_name;
|
||||
const char * const gui_name;
|
||||
const char * const profile_name;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +1,64 @@
|
|||
|
||||
#include "ConfigDiag.h"
|
||||
|
||||
#define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s );
|
||||
|
||||
void GamepadPage::ConfigExtension( wxCommandEvent& event )
|
||||
{
|
||||
ControllerEmu::Extension* const ex = ((ExtensionButton*)event.GetEventObject())->extension;
|
||||
|
||||
// show config diag, if "none" isn't selected
|
||||
if ( ex->switch_extension )
|
||||
{
|
||||
wxDialog* const dlg = new wxDialog( this, -1, wxString::FromAscii(ex->attachments[ex->switch_extension]->GetName().c_str()), wxDefaultPosition );
|
||||
wxPanel* const pnl = new wxPanel( dlg, -1, wxDefaultPosition );
|
||||
wxBoxSizer* const pnl_szr = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
const std::size_t orig_size = control_groups.size();
|
||||
|
||||
ControlGroupsSizer* const szr = new ControlGroupsSizer( ex->attachments[ex->switch_extension], pnl, this, &control_groups );
|
||||
pnl->SetSizerAndFit( szr );
|
||||
pnl_szr->Add( pnl, 0, wxLEFT, 5 );
|
||||
dlg->SetSizerAndFit( pnl_szr );
|
||||
|
||||
dlg->Center();
|
||||
|
||||
dlg->ShowModal();
|
||||
dlg->Destroy();
|
||||
|
||||
// remove the new groups that were just added, now that the window closed
|
||||
control_groups.resize( orig_size );
|
||||
}
|
||||
}
|
||||
|
||||
PadSettingExtension::PadSettingExtension( wxWindow* const parent, ControllerEmu::Extension* const ext )
|
||||
: wxChoice( parent, -1 )
|
||||
, extension(ext)
|
||||
{
|
||||
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
i = extension->attachments.begin(),
|
||||
e = extension->attachments.end();
|
||||
|
||||
for ( ; i!=e; ++i )
|
||||
Append( wxString::FromAscii( (*i)->GetName().c_str() ) );
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
void PadSettingExtension::UpdateGUI()
|
||||
{
|
||||
Select( extension->switch_extension );
|
||||
}
|
||||
|
||||
void PadSettingExtension::UpdateValue()
|
||||
{
|
||||
extension->switch_extension = GetSelection();
|
||||
}
|
||||
|
||||
PadSettingCheckBox::PadSettingCheckBox( wxWindow* const parent, ControlState& _value, const char* const label )
|
||||
: PadSetting(_value)
|
||||
, wxCheckBox( parent, -1, wxString::FromAscii( label ), wxDefaultPosition )
|
||||
: wxCheckBox( parent, -1, wxString::FromAscii( label ), wxDefaultPosition )
|
||||
, value(_value)
|
||||
{
|
||||
UpdateGUI();
|
||||
}
|
||||
|
@ -20,8 +75,8 @@ void PadSettingCheckBox::UpdateValue()
|
|||
}
|
||||
|
||||
PadSettingChoice::PadSettingChoice( wxWindow* const parent, ControlState& _value, int min, int max )
|
||||
: PadSetting(_value)
|
||||
, wxChoice( parent, -1, wxDefaultPosition, wxSize( 54, -1 ) )
|
||||
: wxChoice( parent, -1, wxDefaultPosition, wxSize( 54, -1 ) )
|
||||
, value(_value)
|
||||
{
|
||||
Append( wxT("0") );
|
||||
for ( ; min<=max; ++min )
|
||||
|
@ -53,10 +108,10 @@ ControlDialog::ControlDialog( wxWindow* const parent, ControllerInterface::Contr
|
|||
|
||||
device_cbox = new wxComboBox( this, -1, wxString::FromAscii( ref->device_qualifier.ToString().c_str() ), wxDefaultPosition, wxSize(256,-1), wxArrayString(), wxTE_PROCESS_ENTER );
|
||||
|
||||
#define _connect_macro2_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
//#define _connect_macro2_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
|
||||
_connect_macro2_( device_cbox, SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED );
|
||||
_connect_macro2_( device_cbox, SetDevice, wxEVT_COMMAND_TEXT_ENTER );
|
||||
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED, parent );
|
||||
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_TEXT_ENTER, parent );
|
||||
|
||||
std::vector< ControllerInterface::Device* >::const_iterator i = devs.begin(),
|
||||
e = devs.end();
|
||||
|
@ -93,7 +148,7 @@ ControlButton::ControlButton( wxWindow* const parent, ControllerInterface::Contr
|
|||
void ConfigDialog::UpdateProfileComboBox()
|
||||
{
|
||||
std::string pname( File::GetUserPath(D_CONFIG_IDX) );
|
||||
pname += PROFILES_PATH;
|
||||
pname += PROFILES_PATH; pname += m_plugin.profile_name;
|
||||
|
||||
CFileSearch::XStringVector exts;
|
||||
exts.push_back("*.ini");
|
||||
|
@ -185,24 +240,21 @@ void ControlChooser::UpdateGUI()
|
|||
|
||||
void GamepadPage::UpdateGUI()
|
||||
{
|
||||
device_cbox->SetLabel( wxString::FromAscii( controller->default_device.ToString().c_str() ) );
|
||||
device_cbox->SetValue( wxString::FromAscii( controller->default_device.ToString().c_str() ) );
|
||||
|
||||
std::vector< ControlGroupBox* >::const_iterator
|
||||
g = control_groups.begin(),
|
||||
std::vector< ControlGroupBox* >::const_iterator g = control_groups.begin(),
|
||||
ge = control_groups.end();
|
||||
for ( ; g!=ge; ++g )
|
||||
{
|
||||
// buttons
|
||||
std::vector<ControlButton*>::const_iterator
|
||||
i = (*g)->control_buttons.begin(),
|
||||
e = (*g)->control_buttons.end();
|
||||
std::vector<ControlButton*>::const_iterator i = (*g)->control_buttons.begin()
|
||||
, e = (*g)->control_buttons.end();
|
||||
for ( ; i!=e; ++i )
|
||||
(*i)->SetLabel( wxString::FromAscii( (*i)->control_reference->control_qualifier.name.c_str() ) );
|
||||
|
||||
// settings
|
||||
std::vector<PadSetting*>::const_iterator
|
||||
si = (*g)->options.begin(),
|
||||
se = (*g)->options.end();
|
||||
// cboxes
|
||||
std::vector<PadSetting*>::const_iterator si = (*g)->options.begin()
|
||||
, se = (*g)->options.end();
|
||||
for ( ; si!=se; ++si )
|
||||
(*si)->UpdateGUI();
|
||||
}
|
||||
|
@ -213,12 +265,12 @@ void GamepadPage::ClearAll( wxCommandEvent& event )
|
|||
m_plugin.controls_crit.Enter(); // enter
|
||||
|
||||
// just load an empty ini section to clear everything :P
|
||||
IniSection Section = IniSection();
|
||||
ControllerInterface Face = ControllerInterface();
|
||||
controller->LoadConfig( Section );
|
||||
IniSection section;
|
||||
controller->LoadConfig( section );
|
||||
|
||||
// no point in using the real ControllerInterface i guess
|
||||
controller->UpdateReferences( Face );
|
||||
ControllerInterface face;
|
||||
controller->UpdateReferences( face );
|
||||
|
||||
UpdateGUI();
|
||||
|
||||
|
@ -229,7 +281,8 @@ void GamepadPage::SetControl( wxCommandEvent& event )
|
|||
{
|
||||
m_plugin.controls_crit.Enter(); // enter
|
||||
|
||||
m_control_dialog->control_reference->control_qualifier.name = std::string( m_control_dialog->control_chooser->textctrl->GetValue().ToAscii() );
|
||||
m_control_dialog->control_reference->control_qualifier.name =
|
||||
std::string( m_control_dialog->control_chooser->textctrl->GetValue().ToAscii() );
|
||||
m_control_dialog->control_reference->UpdateControls();
|
||||
m_control_dialog->control_chooser->UpdateGUI();
|
||||
|
||||
|
@ -356,18 +409,15 @@ void ControlDialog::SelectControl( wxCommandEvent& event )
|
|||
|
||||
wxString final_label;
|
||||
|
||||
if (sels.GetCount() == 0)
|
||||
return;
|
||||
|
||||
if ( sels.GetCount() == 1 )
|
||||
if (sels.GetCount() == 1)
|
||||
final_label = names[ sels[0] ];
|
||||
//else if ( sels.GetCount() == lb->GetCount() )
|
||||
//else if ( sels.size() == lb->GetCount() )
|
||||
// final_label = "||";
|
||||
else
|
||||
{
|
||||
final_label = wxT('|');
|
||||
for ( unsigned int i=0; i<sels.GetCount(); ++i )
|
||||
final_label += names[ sels[i] ] + wxT('|');
|
||||
final_label = wxT('|');
|
||||
for ( unsigned int i=0; i<sels.GetCount(); ++i )
|
||||
final_label += names[ sels[i] ] + wxT('|');
|
||||
}
|
||||
|
||||
control_chooser->textctrl->SetValue( final_label );
|
||||
|
@ -375,14 +425,14 @@ void ControlDialog::SelectControl( wxCommandEvent& event )
|
|||
// kinda dumb
|
||||
wxCommandEvent nullevent;
|
||||
((GamepadPage*)m_parent)->SetControl( nullevent );
|
||||
|
||||
|
||||
}
|
||||
|
||||
ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::ControlReference* const ref, wxWindow* const eventsink )
|
||||
: wxStaticBoxSizer( wxVERTICAL, parent, ref->is_input ? wxT("Input") : wxT("Output") )
|
||||
, control_reference(ref)
|
||||
{
|
||||
#define _connect_macro_( b, f, c ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)eventsink );
|
||||
//#define _connect_macro_( b, f, c ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)eventsink );
|
||||
|
||||
textctrl = new wxTextCtrl( parent, -1 );
|
||||
wxButton* detect_button = new wxButton( parent, -1, ref->is_input ? wxT("Detect 1") : wxT("Test") );
|
||||
|
@ -399,7 +449,7 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con
|
|||
for ( unsigned int i = 2; i<5; ++i )
|
||||
{
|
||||
wxButton* d_btn = new wxButton( parent, -1, wxChar( '0'+i ), wxDefaultPosition, wxSize(20,-1) );
|
||||
_connect_macro_( d_btn, ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED);
|
||||
_connect_macro_( d_btn, GamepadPage::ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||
button_sizer->Add( d_btn );
|
||||
}
|
||||
button_sizer->Add( clear_button, 1, 0, 5 );
|
||||
|
@ -409,11 +459,11 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con
|
|||
|
||||
range_slider->SetValue( control_reference->range * SLIDER_TICK_COUNT );
|
||||
|
||||
_connect_macro_( detect_button, ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED);
|
||||
_connect_macro_( clear_button, ClearControl, wxEVT_COMMAND_BUTTON_CLICKED);
|
||||
_connect_macro_( set_button, SetControl, wxEVT_COMMAND_BUTTON_CLICKED);
|
||||
_connect_macro_( detect_button, GamepadPage::ConfigDetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
||||
_connect_macro_( clear_button, GamepadPage::ClearControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
||||
_connect_macro_( set_button, GamepadPage::SetControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink);
|
||||
|
||||
_connect_macro_( range_slider, AdjustControlOption, wxEVT_SCROLL_CHANGED);
|
||||
_connect_macro_( range_slider, GamepadPage::AdjustControlOption, wxEVT_SCROLL_CHANGED, eventsink);
|
||||
wxStaticText* range_label = new wxStaticText( parent, -1, wxT("Range"));
|
||||
m_bound_label = new wxStaticText( parent, -1, wxT("") );
|
||||
|
||||
|
@ -425,7 +475,7 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con
|
|||
|
||||
txtbox_szr->Add( textctrl, 1, wxEXPAND, 0 );
|
||||
|
||||
wxBoxSizer* mode_szr = NULL;
|
||||
wxBoxSizer* mode_szr;
|
||||
if ( control_reference->is_input )
|
||||
{
|
||||
mode_cbox = new wxChoice( parent, -1 );
|
||||
|
@ -434,7 +484,7 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con
|
|||
mode_cbox->Append( wxT("NOT") );
|
||||
mode_cbox->Select( ((ControllerInterface::InputReference*)control_reference)->mode );
|
||||
|
||||
_connect_macro_( mode_cbox, AdjustControlOption, wxEVT_COMMAND_CHOICE_SELECTED );
|
||||
_connect_macro_( mode_cbox, GamepadPage::AdjustControlOption, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
|
||||
mode_szr = new wxBoxSizer( wxHORIZONTAL );
|
||||
mode_szr->Add( new wxStaticText( parent, -1, wxT("Mode") ), 0, wxCENTER|wxLEFT|wxRIGHT, 5 );
|
||||
|
@ -462,7 +512,8 @@ void GamepadPage::LoadProfile( wxCommandEvent& event )
|
|||
|
||||
std::ifstream file;
|
||||
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
||||
fname += PROFILES_PATH; fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
||||
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
||||
fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
||||
|
||||
if ( false == File::Exists( fname.c_str() ) )
|
||||
return;
|
||||
|
@ -491,7 +542,7 @@ void GamepadPage::SaveProfile( wxCommandEvent& event )
|
|||
controller->SaveConfig( inifile["Profile"] );
|
||||
std::ofstream file;
|
||||
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
||||
fname += PROFILES_PATH;
|
||||
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
||||
|
||||
if ( false == File::Exists( fname.c_str() ) )
|
||||
File::CreateFullPath( fname.c_str() );
|
||||
|
@ -513,7 +564,8 @@ void GamepadPage::DeleteProfile( wxCommandEvent& event )
|
|||
|
||||
// don't need lock
|
||||
std::string fname( File::GetUserPath(D_CONFIG_IDX) );
|
||||
fname += PROFILES_PATH; fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
||||
fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/';
|
||||
fname += profile_cbox->GetValue().ToAscii(); fname += ".ini";
|
||||
if ( File::Exists( fname.c_str() ) )
|
||||
File::Delete( fname.c_str() );
|
||||
|
||||
|
@ -556,7 +608,7 @@ void GamepadPage::RefreshDevices( wxCommandEvent& event )
|
|||
m_plugin.controls_crit.Leave(); // leave
|
||||
}
|
||||
|
||||
ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent )
|
||||
ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink )
|
||||
: wxStaticBoxSizer( wxVERTICAL, parent, wxString::FromAscii( group->name ) )
|
||||
{
|
||||
|
||||
|
@ -568,19 +620,17 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
{
|
||||
|
||||
wxStaticText* label = new wxStaticText( parent, -1, wxString::FromAscii( group->controls[c]->name )/*.append(wxT(" :"))*/ );
|
||||
|
||||
ControlButton* control_button = new ControlButton( parent, group->controls[c]->control_ref, 80 );
|
||||
control_button->SetFont(m_SmallFont);
|
||||
controls.push_back( control_button );
|
||||
ControlButton* adv_button = new ControlButton( parent, group->controls[c]->control_ref, 18, "+" );
|
||||
adv_button->SetFont(m_SmallFont);
|
||||
|
||||
controls.push_back( control_button );
|
||||
control_buttons.push_back( control_button );
|
||||
|
||||
control_button->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::DetectControl ),
|
||||
(wxObject*)0, (wxEvtHandler*)parent );
|
||||
|
||||
adv_button->Connect( wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GamepadPage::ConfigControl ),
|
||||
(wxObject*)0, (wxEvtHandler*)parent );
|
||||
_connect_macro_( control_button, GamepadPage::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||
_connect_macro_( adv_button, GamepadPage::ConfigControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||
|
||||
wxBoxSizer* control_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
control_sizer->AddStretchSpacer( 1 );
|
||||
|
@ -595,6 +645,7 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
switch ( group->type )
|
||||
{
|
||||
case GROUP_TYPE_STICK :
|
||||
case GROUP_TYPE_TILT :
|
||||
{
|
||||
wxBitmap bitmap(64, 64);
|
||||
wxMemoryDC dc;
|
||||
|
@ -607,8 +658,8 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
PadSettingChoice* deadzone_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 50 );
|
||||
PadSettingChoice* diagonal_cbox = new PadSettingChoice( parent, group->settings[1]->value, 1, 100 );
|
||||
|
||||
deadzone_cbox->Connect( wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GamepadPage::AdjustSetting ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
diagonal_cbox->Connect( wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GamepadPage::AdjustSetting ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
_connect_macro_( deadzone_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
_connect_macro_( diagonal_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
|
||||
options.push_back( deadzone_cbox );
|
||||
options.push_back( diagonal_cbox );
|
||||
|
@ -636,8 +687,7 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
||||
|
||||
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 99 );
|
||||
// threshold_cbox->SetFont(m_SmallFont);
|
||||
threshold_cbox->Connect( wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GamepadPage::AdjustSetting ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
|
||||
options.push_back( threshold_cbox );
|
||||
|
||||
|
@ -659,7 +709,7 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
||||
|
||||
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0]->value, 1, 99 );
|
||||
threshold_cbox->Connect( wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GamepadPage::AdjustSetting ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
|
||||
options.push_back( threshold_cbox );
|
||||
|
||||
|
@ -671,28 +721,72 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
|||
Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_EXTENSION :
|
||||
{
|
||||
PadSettingExtension* const attachments = new PadSettingExtension( parent, (ControllerEmu::Extension*)group );
|
||||
wxButton* const configure = new ExtensionButton( parent, (ControllerEmu::Extension*)group );
|
||||
|
||||
options.push_back( attachments );
|
||||
|
||||
_connect_macro_( attachments, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
_connect_macro_( configure, GamepadPage::ConfigExtension, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||
|
||||
Add( attachments, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 5 );
|
||||
Add( configure, 0, wxALL|wxEXPAND, 5 );
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
//options
|
||||
|
||||
std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator
|
||||
i = group->settings.begin(),
|
||||
e = group->settings.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
PadSettingCheckBox* setting_cbox = new PadSettingCheckBox( parent, (*i)->value, (*i)->name );
|
||||
setting_cbox->Connect( wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GamepadPage::AdjustSetting ), (wxObject*)0, (wxEvtHandler*)parent );
|
||||
_connect_macro_( setting_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHECKBOX_CLICKED, eventsink );
|
||||
options.push_back( setting_cbox );
|
||||
|
||||
Add( setting_cbox, 0, wxALL|wxCENTER, 5 );
|
||||
Add( setting_cbox, 0, wxALL|wxLEFT, 5 );
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//AddStretchSpacer( 0 );
|
||||
}
|
||||
|
||||
ControlGroupsSizer::ControlGroupsSizer( ControllerEmu* const controller, wxWindow* const parent, wxWindow* const eventsink, std::vector<ControlGroupBox*>* groups )
|
||||
: wxBoxSizer( wxHORIZONTAL )
|
||||
{
|
||||
|
||||
wxBoxSizer* stacked_groups = NULL;
|
||||
for ( unsigned int i = 0; i < controller->groups.size(); ++i )
|
||||
{
|
||||
ControlGroupBox* control_group = new ControlGroupBox( controller->groups[i], parent, eventsink );
|
||||
|
||||
if ( control_group->control_buttons.size() > 1 )
|
||||
{
|
||||
if ( stacked_groups )
|
||||
Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
stacked_groups = new wxBoxSizer( wxVERTICAL );
|
||||
stacked_groups->Add( control_group, 0, wxEXPAND );
|
||||
}
|
||||
else
|
||||
stacked_groups->Add( control_group, 0, wxEXPAND );
|
||||
|
||||
if ( groups )
|
||||
groups->push_back( control_group );
|
||||
}
|
||||
|
||||
if ( stacked_groups )
|
||||
Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
}
|
||||
|
||||
GamepadPage::GamepadPage( wxWindow* parent, Plugin& plugin, const unsigned int pad_num, ConfigDialog* const config_dialog )
|
||||
: wxNotebookPage( parent, -1 , wxDefaultPosition, wxDefaultSize )
|
||||
,controller(plugin.controllers[pad_num])
|
||||
|
@ -700,29 +794,7 @@ GamepadPage::GamepadPage( wxWindow* parent, Plugin& plugin, const unsigned int p
|
|||
,m_config_dialog(config_dialog)
|
||||
{
|
||||
|
||||
wxBoxSizer* control_group_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* stacked_groups = NULL;
|
||||
for ( unsigned int i = 0; i < m_plugin.controllers[pad_num]->groups.size(); ++i )
|
||||
{
|
||||
ControlGroupBox* control_group = new ControlGroupBox( m_plugin.controllers[pad_num]->groups[i], this );
|
||||
|
||||
if ( control_group->control_buttons.size() > 2 )
|
||||
{
|
||||
if ( stacked_groups )
|
||||
control_group_sizer->Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
stacked_groups = new wxBoxSizer( wxVERTICAL );
|
||||
stacked_groups->Add( control_group, 0, wxEXPAND );
|
||||
}
|
||||
else
|
||||
stacked_groups->Add( control_group, 0, wxEXPAND );
|
||||
|
||||
control_groups.push_back( control_group );
|
||||
}
|
||||
|
||||
if ( stacked_groups )
|
||||
control_group_sizer->Add( stacked_groups, 0, /*wxEXPAND|*/wxBOTTOM|wxRIGHT, 5 );
|
||||
wxBoxSizer* control_group_sizer = new ControlGroupsSizer( m_plugin.controllers[pad_num], this, this, &control_groups );
|
||||
|
||||
wxStaticBoxSizer* profile_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Profile") );
|
||||
|
||||
|
@ -734,11 +806,11 @@ GamepadPage::GamepadPage( wxWindow* parent, Plugin& plugin, const unsigned int p
|
|||
|
||||
wxButton* refresh_button = new wxButton( this, -1, wxT("Refresh"), wxDefaultPosition, wxSize(60,-1) );
|
||||
|
||||
#define _connect_macro3_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)this );
|
||||
//#define _connect_macro3_( b, f, c ) (b)->Connect( wxID_ANY, c, wxCommandEventHandler( GamepadPage::f ), (wxObject*)0, (wxEvtHandler*)this );
|
||||
|
||||
_connect_macro3_( device_cbox, SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED );
|
||||
_connect_macro3_( device_cbox, SetDevice, wxEVT_COMMAND_TEXT_ENTER );
|
||||
_connect_macro3_( refresh_button, RefreshDevices, wxEVT_COMMAND_BUTTON_CLICKED );
|
||||
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED, this );
|
||||
_connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_TEXT_ENTER, this );
|
||||
_connect_macro_( refresh_button, GamepadPage::RefreshDevices, wxEVT_COMMAND_BUTTON_CLICKED, this );
|
||||
|
||||
device_sbox->Add( device_cbox, 1, wxLEFT|wxRIGHT, 5 );
|
||||
device_sbox->Add( refresh_button, 0, wxRIGHT|wxBOTTOM, 5 );
|
||||
|
@ -799,7 +871,7 @@ ConfigDialog::ConfigDialog( wxWindow* const parent, Plugin& plugin, const std::s
|
|||
{
|
||||
GamepadPage* gp = new GamepadPage( m_pad_notebook, plugin, i, this );
|
||||
m_padpages.push_back( gp );
|
||||
m_pad_notebook->AddPage( gp, wxString::FromAscii((plugin.controllers[i]->GetName().c_str())) );
|
||||
m_pad_notebook->AddPage( gp, wxString::FromAscii( m_plugin.gui_name ) + wxT(' ') + wxChar('1'+i) );
|
||||
}
|
||||
|
||||
UpdateDeviceComboBox();
|
|
@ -6,7 +6,7 @@
|
|||
#define PREVIEW_UPDATE_TIME 25
|
||||
|
||||
// might have to change this setup for wiimote
|
||||
#define PROFILES_PATH "Profiles/GCPad/"
|
||||
#define PROFILES_PATH "Profiles/"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/listbox.h>
|
||||
|
@ -21,38 +21,49 @@
|
|||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "ControllerInterface/ControllerInterface.h"
|
||||
#include <ControllerInterface/ControllerInterface.h>
|
||||
#include "Config.h"
|
||||
#include "FileSearch.h"
|
||||
|
||||
class PadSetting
|
||||
{
|
||||
protected:
|
||||
PadSetting( ControlState& _value ) : value(_value) {}
|
||||
PadSetting() {}
|
||||
|
||||
public:
|
||||
virtual void UpdateGUI() = 0;
|
||||
virtual void UpdateValue() = 0;
|
||||
|
||||
ControlState& value;
|
||||
};
|
||||
|
||||
class PadSettingChoice : public PadSetting, public wxChoice
|
||||
class PadSettingExtension : public wxChoice, public PadSetting
|
||||
{
|
||||
public:
|
||||
PadSettingExtension( wxWindow* const parent, ControllerEmu::Extension* const ext );
|
||||
void UpdateGUI();
|
||||
void UpdateValue();
|
||||
|
||||
ControllerEmu::Extension* const extension;
|
||||
};
|
||||
|
||||
class PadSettingChoice : public wxChoice, public PadSetting
|
||||
{
|
||||
public:
|
||||
PadSettingChoice( wxWindow* const parent, ControlState& _value, int min, int max );
|
||||
void UpdateGUI();
|
||||
void UpdateValue();
|
||||
|
||||
ControlState& value;
|
||||
};
|
||||
|
||||
class PadSettingCheckBox : public PadSetting, public wxCheckBox
|
||||
class PadSettingCheckBox : public wxCheckBox, public PadSetting
|
||||
{
|
||||
public:
|
||||
PadSettingCheckBox( wxWindow* const parent, ControlState& _value, const char* const label );
|
||||
void UpdateGUI();
|
||||
void UpdateValue();
|
||||
};
|
||||
|
||||
ControlState& value;
|
||||
};
|
||||
|
||||
class ControlChooser : public wxStaticBoxSizer
|
||||
{
|
||||
|
@ -93,6 +104,16 @@ public:
|
|||
ControlChooser* control_chooser;
|
||||
};
|
||||
|
||||
class ExtensionButton : public wxButton
|
||||
{
|
||||
public:
|
||||
ExtensionButton( wxWindow* const parent, ControllerEmu::Extension* const ext )
|
||||
: wxButton( parent, -1, wxT("Configure"), wxDefaultPosition )
|
||||
, extension(ext) {}
|
||||
|
||||
ControllerEmu::Extension* const extension;
|
||||
};
|
||||
|
||||
class ControlButton : public wxButton
|
||||
{
|
||||
public:
|
||||
|
@ -104,7 +125,7 @@ public:
|
|||
class ControlGroupBox : public wxStaticBoxSizer
|
||||
{
|
||||
public:
|
||||
ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent );
|
||||
ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink );
|
||||
|
||||
ControllerEmu::ControlGroup* control_group;
|
||||
wxStaticBitmap* static_bitmap;
|
||||
|
@ -113,6 +134,14 @@ public:
|
|||
std::vector<ControlButton*> control_buttons;
|
||||
};
|
||||
|
||||
class ControlGroupsSizer : public wxBoxSizer
|
||||
{
|
||||
public:
|
||||
ControlGroupsSizer( ControllerEmu* const controller, wxWindow* const parent, wxWindow* const eventsink, std::vector<ControlGroupBox*>* const groups = NULL );
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ConfigDialog;
|
||||
|
||||
class GamepadPage : public wxNotebookPage
|
||||
|
@ -135,6 +164,8 @@ public:
|
|||
void DetectControl( wxCommandEvent& event );
|
||||
void ClearControl( wxCommandEvent& event );
|
||||
|
||||
void ConfigExtension( wxCommandEvent& event );
|
||||
|
||||
void SetDevice( wxCommandEvent& event );
|
||||
void SetControl( wxCommandEvent& event );
|
||||
|
|
@ -24,16 +24,20 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
|||
|
||||
switch ( (*g)->control_group->type )
|
||||
{
|
||||
case GROUP_TYPE_TILT :
|
||||
case GROUP_TYPE_STICK :
|
||||
{
|
||||
float x, y;
|
||||
float x = 0, y = 0;
|
||||
float xx, yy;
|
||||
((ControllerEmu::AnalogStick*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
|
||||
if ( GROUP_TYPE_STICK == (*g)->control_group->type )
|
||||
((ControllerEmu::AnalogStick*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
|
||||
else
|
||||
((ControllerEmu::Tilt*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
|
||||
|
||||
xx = ((ControllerEmu::AnalogStick*)(*g)->control_group)->controls[3]->control_ref->State();
|
||||
xx -= ((ControllerEmu::AnalogStick*)(*g)->control_group)->controls[2]->control_ref->State();
|
||||
yy = ((ControllerEmu::AnalogStick*)(*g)->control_group)->controls[1]->control_ref->State();
|
||||
yy -= ((ControllerEmu::AnalogStick*)(*g)->control_group)->controls[0]->control_ref->State();
|
||||
xx = (*g)->control_group->controls[3]->control_ref->State();
|
||||
xx -= (*g)->control_group->controls[2]->control_ref->State();
|
||||
yy = (*g)->control_group->controls[1]->control_ref->State();
|
||||
yy -= (*g)->control_group->controls[0]->control_ref->State();
|
||||
xx *= 32 - 1; xx += 32;
|
||||
yy *= 32 - 1; yy += 32;
|
||||
|
||||
|
@ -48,11 +52,14 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
|||
// circle for visual aid for diagonal adjustment
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawCircle( 32, 32, 32);
|
||||
if ( GROUP_TYPE_STICK == (*g)->control_group->type )
|
||||
dc.DrawCircle( 32, 32, 32);
|
||||
else
|
||||
dc.DrawRectangle( 16, 16, 32, 32 );
|
||||
|
||||
// deadzone circle
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.DrawCircle( 32, 32, ((ControllerEmu::AnalogStick*)(*g)->control_group)->settings[0]->value * 32 );
|
||||
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[0]->value * 32 );
|
||||
|
||||
// raw dot
|
||||
dc.SetPen(*wxGREY_PEN);
|
|
@ -0,0 +1,258 @@
|
|||
#include "ControllerEmu.h"
|
||||
|
||||
const char modifier[] = "Modifier";
|
||||
|
||||
|
||||
ControllerEmu::~ControllerEmu()
|
||||
{
|
||||
std::vector<ControlGroup*>::const_iterator
|
||||
i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
delete *i;
|
||||
}
|
||||
|
||||
ControllerEmu::ControlGroup::~ControlGroup()
|
||||
{
|
||||
std::vector<Control*>::const_iterator
|
||||
ci = controls.begin(),
|
||||
ce = controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
delete *ci;
|
||||
|
||||
std::vector<Setting*>::const_iterator
|
||||
si = settings.begin(),
|
||||
se = settings.end();
|
||||
for ( ; si!=se; ++si )
|
||||
delete *si;
|
||||
}
|
||||
|
||||
void ControllerEmu::UpdateReferences( ControllerInterface& devi )
|
||||
{
|
||||
std::vector<ControlGroup*>::const_iterator
|
||||
i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
std::vector<ControlGroup::Control*>::const_iterator
|
||||
ci = (*i)->controls.begin(),
|
||||
ce = (*i)->controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
devi.UpdateReference( (*ci)->control_ref );
|
||||
|
||||
// extension
|
||||
if ( GROUP_TYPE_EXTENSION == (*i)->type )
|
||||
{
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
ai = ((Extension*)*i)->attachments.begin(),
|
||||
ae = ((Extension*)*i)->attachments.end();
|
||||
for ( ; ai!=ae; ++ai )
|
||||
(*ai)->UpdateReferences( devi );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::UpdateDefaultDevice()
|
||||
{
|
||||
std::vector<ControlGroup*>::const_iterator
|
||||
i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
std::vector<ControlGroup::Control*>::const_iterator
|
||||
ci = (*i)->controls.begin(),
|
||||
ce = (*i)->controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
(*ci)->control_ref->device_qualifier = default_device;
|
||||
|
||||
// extension
|
||||
if ( GROUP_TYPE_EXTENSION == (*i)->type )
|
||||
{
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
ai = ((Extension*)*i)->attachments.begin(),
|
||||
ae = ((Extension*)*i)->attachments.end();
|
||||
for ( ; ai!=ae; ++ai )
|
||||
{
|
||||
(*ai)->default_device = default_device;
|
||||
(*ai)->UpdateDefaultDevice();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::ControlGroup::LoadConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base )
|
||||
{
|
||||
std::string group( base + name ); group += "/";
|
||||
|
||||
// settings
|
||||
std::vector<ControlGroup::Setting*>::const_iterator
|
||||
si = settings.begin(),
|
||||
se = settings.end();
|
||||
for ( ; si!=se; ++si )
|
||||
(*si)->value = sec.Get(group+(*si)->name, (*si)->default_value*100) / 100;
|
||||
|
||||
// controls
|
||||
std::vector<ControlGroup::Control*>::const_iterator
|
||||
ci = controls.begin(),
|
||||
ce = controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
{
|
||||
// control and dev qualifier
|
||||
(*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name];
|
||||
(*ci)->control_ref->device_qualifier.FromString( sec.Get( group+(*ci)->name+"/Device", defdev ) );
|
||||
|
||||
// range
|
||||
(*ci)->control_ref->range = sec.Get( group+(*ci)->name+"/Range", 100.0f ) / 100;
|
||||
|
||||
// input mode
|
||||
if ( (*ci)->control_ref->is_input )
|
||||
((ControllerInterface::InputReference*)((*ci)->control_ref))->mode
|
||||
= sec.Get( group+(*ci)->name+"/Mode", 0 );
|
||||
}
|
||||
|
||||
// extensions
|
||||
if ( GROUP_TYPE_EXTENSION == type )
|
||||
{
|
||||
Extension* const ex = ((Extension*)this);
|
||||
|
||||
ex->switch_extension = 0;
|
||||
unsigned int n = 0;
|
||||
const std::string extname = sec[ base + name ];
|
||||
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
ai = ((Extension*)this)->attachments.begin(),
|
||||
ae = ((Extension*)this)->attachments.end();
|
||||
for ( ; ai!=ae; ++ai,++n )
|
||||
{
|
||||
(*ai)->default_device.FromString( defdev );
|
||||
(*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" );
|
||||
|
||||
if ( (*ai)->GetName() == extname )
|
||||
ex->switch_extension = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::LoadConfig( IniFile::Section& sec, const std::string& base )
|
||||
{
|
||||
std::string defdev = default_device.ToString();
|
||||
if ( base.empty() )
|
||||
{
|
||||
defdev = sec[ base + "Device" ];
|
||||
default_device.FromString( defdev );
|
||||
}
|
||||
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
(*i)->LoadConfig( sec, defdev, base );
|
||||
}
|
||||
|
||||
void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base )
|
||||
{
|
||||
std::string group( base + name ); group += "/";
|
||||
|
||||
// settings
|
||||
std::vector<ControlGroup::Setting*>::const_iterator
|
||||
si = settings.begin(),
|
||||
se = settings.end();
|
||||
for ( ; si!=se; ++si )
|
||||
sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 );
|
||||
|
||||
// controls
|
||||
std::vector<ControlGroup::Control*>::const_iterator
|
||||
ci = controls.begin(),
|
||||
ce = controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
{
|
||||
// control and dev qualifier
|
||||
sec[group + (*ci)->name] = (*ci)->control_ref->control_qualifier.name;
|
||||
sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), defdev );
|
||||
|
||||
// range
|
||||
sec.Set( group+(*ci)->name+"/Range", (*ci)->control_ref->range*100, 100 );
|
||||
|
||||
// input mode
|
||||
if ( (*ci)->control_ref->is_input )
|
||||
sec.Set( group+(*ci)->name+"/Mode",
|
||||
((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, (unsigned int)0 );
|
||||
}
|
||||
|
||||
// extensions
|
||||
if ( GROUP_TYPE_EXTENSION == type )
|
||||
{
|
||||
Extension* const ext = ((Extension*)this);
|
||||
sec.Set( base + name, ext->attachments[ext->switch_extension]->GetName(), std::string("None") );
|
||||
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
ai = ((Extension*)this)->attachments.begin(),
|
||||
ae = ((Extension*)this)->attachments.end();
|
||||
for ( ; ai!=ae; ++ai )
|
||||
(*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" );
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::SaveConfig( IniFile::Section& sec, const std::string& base )
|
||||
{
|
||||
const std::string defdev = default_device.ToString();
|
||||
if ( base.empty() )
|
||||
sec[ std::string(" ") + base + "Device" ] = defdev;
|
||||
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
(*i)->SaveConfig( sec, defdev, base );
|
||||
}
|
||||
|
||||
ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK )
|
||||
{
|
||||
for ( unsigned int i = 0; i < 4; ++i )
|
||||
controls.push_back( new Input( named_directions[i] ) );
|
||||
|
||||
controls.push_back( new Input( modifier ) );
|
||||
|
||||
settings.push_back( new Setting("Dead Zone", 0 ) );
|
||||
settings.push_back( new Setting("Square Stick", 0 ) );
|
||||
|
||||
}
|
||||
|
||||
ControllerEmu::Buttons::Buttons( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_BUTTONS )
|
||||
{
|
||||
settings.push_back( new Setting("Threshold", 0.5f ) );
|
||||
}
|
||||
|
||||
ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_MIXED_TRIGGERS )
|
||||
{
|
||||
settings.push_back( new Setting("Threshold", 0.9f ) );
|
||||
}
|
||||
|
||||
ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE )
|
||||
{
|
||||
controls.push_back( new Input( "X-" ) );
|
||||
controls.push_back( new Input( "X+" ) );
|
||||
controls.push_back( new Input( "Y-" ) );
|
||||
controls.push_back( new Input( "Y+" ) );
|
||||
controls.push_back( new Input( "Z-" ) );
|
||||
controls.push_back( new Input( "Z+" ) );
|
||||
}
|
||||
|
||||
void ControllerEmu::Force::GetState( u8* data, const u8 base, const u8 range )
|
||||
{
|
||||
for ( unsigned int i=0; i<3; ++i,++data )
|
||||
*data = u8( ( controls[i*2+1]->control_ref->State() - controls[i*2]->control_ref->State() ) * range + base );
|
||||
}
|
||||
|
||||
ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_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( "Backward" ) );
|
||||
controls.push_back( new Input( "Left" ) );
|
||||
controls.push_back( new Input( "Right" ) );
|
||||
|
||||
controls.push_back( new Input( modifier ) );
|
||||
|
||||
settings.push_back( new Setting("Dead Zone", 0 ) );
|
||||
settings.push_back( new Setting("Circle Stick", 0 ) );
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
//#include <CommonTypes.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ControllerInterface/ControllerInterface.h"
|
||||
#include <ControllerInterface/ControllerInterface.h>
|
||||
#include "IniFile.h"
|
||||
|
||||
#include <vector>
|
||||
|
@ -20,10 +20,13 @@
|
|||
|
||||
enum
|
||||
{
|
||||
GROUP_TYPE_OTHER
|
||||
,GROUP_TYPE_STICK
|
||||
,GROUP_TYPE_MIXED_TRIGGERS
|
||||
,GROUP_TYPE_BUTTONS
|
||||
GROUP_TYPE_OTHER,
|
||||
GROUP_TYPE_STICK,
|
||||
GROUP_TYPE_MIXED_TRIGGERS,
|
||||
GROUP_TYPE_BUTTONS,
|
||||
GROUP_TYPE_FORCE,
|
||||
GROUP_TYPE_EXTENSION,
|
||||
GROUP_TYPE_TILT,
|
||||
};
|
||||
|
||||
const char * const named_directions[] =
|
||||
|
@ -89,7 +92,8 @@ public:
|
|||
ControlGroup( const char* const _name, const unsigned int _type = GROUP_TYPE_OTHER ) : name(_name), type(_type) {}
|
||||
virtual ~ControlGroup();
|
||||
|
||||
//ControlGroup( const ControlGroup& ctrl );
|
||||
void LoadConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
||||
void SaveConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
||||
|
||||
//const unsigned int type;
|
||||
const char* const name;
|
||||
|
@ -119,8 +123,8 @@ public:
|
|||
// modifier code
|
||||
if ( m )
|
||||
{
|
||||
yy = (abs(yy)>deadzone) * sign(yy) * m;
|
||||
xx = (abs(xx)>deadzone) * sign(xx) * m;
|
||||
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
|
||||
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
|
||||
}
|
||||
|
||||
// deadzone / square stick code
|
||||
|
@ -146,7 +150,7 @@ public:
|
|||
dist /= ( 1 - deadzone );
|
||||
|
||||
// square stick code
|
||||
ControlState amt = ( dist ) / stick_full;
|
||||
ControlState amt = dist / stick_full;
|
||||
dist -= ((square_full - 1) * amt * square);
|
||||
|
||||
yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) );
|
||||
|
@ -203,18 +207,102 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class Force : public ControlGroup
|
||||
{
|
||||
public:
|
||||
Force( const char* const _name );
|
||||
|
||||
void GetState( u8* data, const u8 base, const u8 range );
|
||||
};
|
||||
|
||||
class Tilt : public ControlGroup
|
||||
{
|
||||
public:
|
||||
Tilt( const char* const _name );
|
||||
|
||||
template <typename C, typename R>
|
||||
void GetState( C* const x, C* const y, const unsigned int base, const R range )
|
||||
{
|
||||
// this is all a mess
|
||||
|
||||
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
|
||||
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
|
||||
|
||||
ControlState deadzone = settings[0]->value;
|
||||
ControlState circle = settings[1]->value;
|
||||
ControlState m = controls[4]->control_ref->State();
|
||||
|
||||
// modifier code
|
||||
if ( m )
|
||||
{
|
||||
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
|
||||
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
|
||||
}
|
||||
|
||||
// deadzone / circle stick code
|
||||
if ( deadzone || circle )
|
||||
{
|
||||
// this section might be all wrong, but its working good enough, i think
|
||||
|
||||
ControlState ang = atan2( yy, xx );
|
||||
ControlState ang_sin = sin(ang);
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
// the amt a full square stick would have at current angle
|
||||
ControlState square_full = std::min( 1/abs(ang_sin), 1/abs(ang_cos) );
|
||||
|
||||
// the amt a full stick would have that was ( user setting circular ) at current angle
|
||||
// i think this is more like a pointed circle rather than a rounded square like it should be
|
||||
ControlState stick_full = (square_full * (1 - circle)) + (circle);
|
||||
|
||||
ControlState dist = sqrt(xx*xx + yy*yy);
|
||||
|
||||
// dead zone code
|
||||
dist = std::max( 0.0f, dist - deadzone * stick_full );
|
||||
dist /= (1 - deadzone);
|
||||
|
||||
// circle stick code
|
||||
ControlState amt = dist / stick_full;
|
||||
dist += (square_full - 1) * amt * circle;
|
||||
|
||||
yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) );
|
||||
xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) );
|
||||
}
|
||||
|
||||
*y = C( yy * range + base );
|
||||
*x = C( xx * range + base );
|
||||
}
|
||||
};
|
||||
|
||||
class Extension : public ControlGroup
|
||||
{
|
||||
public:
|
||||
Extension( const char* const _name )
|
||||
: ControlGroup( _name, GROUP_TYPE_EXTENSION )
|
||||
, switch_extension(0)
|
||||
, active_extension(0) {}
|
||||
|
||||
void GetState( u8* const data );
|
||||
|
||||
std::vector<ControllerEmu*> attachments;
|
||||
|
||||
unsigned int switch_extension;
|
||||
unsigned int active_extension;
|
||||
};
|
||||
|
||||
virtual ~ControllerEmu();
|
||||
|
||||
virtual std::string GetName() const = 0;
|
||||
|
||||
void LoadConfig( IniFile::Section& sec );
|
||||
void SaveConfig( IniFile::Section& sec );
|
||||
void LoadConfig( IniFile::Section& sec, const std::string& base = "" );
|
||||
void SaveConfig( IniFile::Section& sec, const std::string& base = "" );
|
||||
void UpdateDefaultDevice();
|
||||
|
||||
void UpdateReferences( ControllerInterface& devi );
|
||||
|
||||
std::vector< ControlGroup* > groups;
|
||||
|
||||
|
||||
ControlGroup* options;
|
||||
|
||||
ControllerInterface::DeviceQualifier default_device;
|
||||
|
@ -222,6 +310,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -196,6 +196,29 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_GCPad", "Plugins\Plu
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_GCPadNew", "Plugins\Plugin_GCPadNew\Plugin_GCPadNew.vcproj", "{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
|
||||
{05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75}
|
||||
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
||||
{0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E}
|
||||
{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE} = {660BB3F7-ED8F-4027-A460-8E4EDA8189BE}
|
||||
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_WiimoteNew", "Plugins\Plugin_WiimoteNew\Plugin_WiimoteNew.vcproj", "{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
|
||||
{05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75}
|
||||
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
||||
{0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E}
|
||||
{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE} = {660BB3F7-ED8F-4027-A460-8E4EDA8189BE}
|
||||
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputPluginCommon", "Core\InputPluginCommon\InputPluginCommon.vcproj", "{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
|
||||
{05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75}
|
||||
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
||||
{0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E}
|
||||
|
@ -575,6 +598,30 @@ Global
|
|||
{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|Win32.Build.0 = Release|Win32
|
||||
{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|x64.ActiveCfg = Release|x64
|
||||
{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|x64.Build.0 = Release|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|x64.Build.0 = Debug|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.DebugFast|Win32.Build.0 = DebugFast|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.DebugFast|x64.Build.0 = DebugFast|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Release|Win32.Build.0 = Release|Win32
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Release|x64.ActiveCfg = Release|x64
|
||||
{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Release|x64.Build.0 = Release|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Debug|x64.Build.0 = Debug|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.DebugFast|Win32.Build.0 = DebugFast|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.DebugFast|x64.Build.0 = DebugFast|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Release|Win32.Build.0 = Release|Win32
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Release|x64.ActiveCfg = Release|x64
|
||||
{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Version="9.00"
|
||||
Name="Plugin_GCPadNew"
|
||||
ProjectGUID="{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}"
|
||||
RootNamespace="Plugin_GCPadNew"
|
||||
|
@ -44,7 +44,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
@ -126,7 +126,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
@ -206,7 +206,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
|
@ -293,7 +293,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
|
@ -373,7 +373,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;DEBUGFAST;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
|
@ -455,7 +455,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;DEBUGFAST;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
|
@ -514,150 +514,14 @@
|
|||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Config"
|
||||
<File
|
||||
RelativePath=".\Src\GCPadEmu.cpp"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\Config.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\Config.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="GUI"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiag.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiag.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ConfigDiagBitmaps.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="IniFile"
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\GCPadEmu.h"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\IniFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\IniFile.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ControllerInterface"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\ControllerInterface.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\ControllerInterface.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="XInput"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\XInput\XInput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\XInput\XInput.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SDL"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\SDL\SDL.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\SDL\SDL.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="DirectInput"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInput.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputJoystick.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputJoystick.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputKeyboardMouse.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\DirectInputKeyboardMouse.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerInterface\DirectInput\NamedKeys.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ControllerEmu"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="GCPad"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu\GCPad\GCPad.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu\GCPad\GCPad.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Wiimote"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu\Wiimote\Wiimote.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ControllerEmu\Wiimote\Wiimote.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\GCPadNew.cpp"
|
||||
>
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "ControllerEmu.h"
|
||||
|
||||
#include "ControllerEmu/GCPad/GCPad.h"
|
||||
|
||||
const char modifier[] = "Modifier";
|
||||
|
||||
// TODO: make this use iterators
|
||||
ControllerEmu::~ControllerEmu()
|
||||
{
|
||||
for ( unsigned int g = 0; g<groups.size(); ++g )
|
||||
delete groups[g];
|
||||
}
|
||||
// TODO: make this use iterators
|
||||
ControllerEmu::ControlGroup::~ControlGroup()
|
||||
{
|
||||
for ( unsigned int i = 0; i < controls.size(); ++i )
|
||||
delete controls[i];
|
||||
for ( unsigned int i = 0; i < settings.size(); ++i )
|
||||
delete settings[i];
|
||||
}
|
||||
|
||||
// TODO: make this use iterators
|
||||
void ControllerEmu::UpdateReferences( ControllerInterface& devi )
|
||||
{
|
||||
for ( unsigned int g = 0; g<groups.size(); ++g )
|
||||
for ( unsigned int i = 0; i < groups[g]->controls.size(); ++i )
|
||||
devi.UpdateReference( groups[g]->controls[i]->control_ref );
|
||||
}
|
||||
|
||||
void ControllerEmu::UpdateDefaultDevice()
|
||||
{
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
std::vector<ControlGroup::Control*>::const_iterator ci = (*i)->controls.begin(),
|
||||
ce = (*i)->controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
(*ci)->control_ref->device_qualifier = default_device;
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::LoadConfig( IniFile::Section& sec )
|
||||
{
|
||||
const std::string default_dev = sec[ "Device" ];
|
||||
default_device.FromString( default_dev );
|
||||
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
std::string group( (*i)->name ); group += "/";
|
||||
|
||||
// settings
|
||||
std::vector<ControlGroup::Setting*>::const_iterator si = (*i)->settings.begin(),
|
||||
se = (*i)->settings.end();
|
||||
for ( ; si!=se; ++si )
|
||||
(*si)->value = sec.Get(group+(*si)->name, (*si)->default_value*100) / 100;
|
||||
|
||||
// controls
|
||||
std::vector<ControlGroup::Control*>::const_iterator ci = (*i)->controls.begin(),
|
||||
ce = (*i)->controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
{
|
||||
// control and dev qualifier
|
||||
(*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name];
|
||||
(*ci)->control_ref->device_qualifier.FromString( sec.Get( group+(*ci)->name+"/Device", default_dev ) );
|
||||
|
||||
// range
|
||||
(*ci)->control_ref->range = sec.Get( group+(*ci)->name+"/Range", 100.0f ) / 100;
|
||||
|
||||
// input mode
|
||||
if ( (*ci)->control_ref->is_input )
|
||||
((ControllerInterface::InputReference*)((*ci)->control_ref))->mode
|
||||
= sec.Get( group+(*ci)->name+"/Mode", 0 );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerEmu::SaveConfig( IniFile::Section& sec )
|
||||
{
|
||||
const std::string default_dev = default_device.ToString();
|
||||
sec[ " Device" ] = default_dev;
|
||||
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
for ( ; i!=e; ++i )
|
||||
{
|
||||
std::string group( (*i)->name ); group += "/";
|
||||
|
||||
// settings
|
||||
std::vector<ControlGroup::Setting*>::const_iterator si = (*i)->settings.begin(),
|
||||
se = (*i)->settings.end();
|
||||
for ( ; si!=se; ++si )
|
||||
sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 );
|
||||
|
||||
// controls
|
||||
std::vector<ControlGroup::Control*>::const_iterator ci = (*i)->controls.begin(),
|
||||
ce = (*i)->controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
{
|
||||
// control and dev qualifier
|
||||
sec[group + (*ci)->name] = (*ci)->control_ref->control_qualifier.name;
|
||||
sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), default_dev );
|
||||
|
||||
// range
|
||||
sec.Set( group+(*ci)->name+"/Range", (*ci)->control_ref->range*100, 100 );
|
||||
|
||||
// input mode
|
||||
if ( (*ci)->control_ref->is_input )
|
||||
sec.Set( group+(*ci)->name+"/Mode",
|
||||
((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, (unsigned int)0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK )
|
||||
{
|
||||
for ( unsigned int i = 0; i < 4; ++i )
|
||||
controls.push_back( new Input( named_directions[i] ) );
|
||||
|
||||
controls.push_back( new Input( modifier ) );
|
||||
|
||||
settings.push_back( new Setting("Dead Zone", 0 ) );
|
||||
settings.push_back( new Setting("Square Stick", 0 ) );
|
||||
|
||||
}
|
||||
|
||||
ControllerEmu::Buttons::Buttons( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_BUTTONS )
|
||||
{
|
||||
settings.push_back( new Setting("Threshold", 0.5f ) );
|
||||
}
|
||||
|
||||
ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_MIXED_TRIGGERS )
|
||||
{
|
||||
settings.push_back( new Setting("Threshold", 0.9f ) );
|
||||
}
|
|
@ -1,257 +0,0 @@
|
|||
|
||||
#include "Wiimote.h"
|
||||
|
||||
// buttons
|
||||
|
||||
#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
|
||||
|
||||
// reports
|
||||
|
||||
#define REPORT_UNKNOWN 0x10
|
||||
#define REPORT_LEDS 0x11
|
||||
#define REPORT_DATA_MODE 0x12
|
||||
#define REPORT_IR_ENABLE 0x13
|
||||
#define REPORT_SPEAKER_ENABLE 0x14
|
||||
#define REPORT_STATUS_REQUEST 0x15
|
||||
#define REPORT_WRITE_MEMORY 0x16
|
||||
#define REPORT_READ_MEMORY 0x17
|
||||
#define REPORT_SPEAKER_DATA 0x18
|
||||
#define REPORT_SPEAKER_MUTE 0x19
|
||||
#define REPORT_IR_ENABLE_2 0x1a
|
||||
#define REPORT_STATUS 0x20
|
||||
#define REPORT_READ_MEMORY_DATA 0x21
|
||||
#define REPORT_ACKNOWLEDGE_OUTPUT 0x22
|
||||
//#define REPORT_DATA_REPORTS 0x30-0x3f
|
||||
|
||||
// reporting modes
|
||||
|
||||
#define REPORT_MODE_CORE 0x30
|
||||
#define REPORT_MODE_CORE_ACCEL 0x31
|
||||
#define REPORT_MODE_CORE_EXTEN8 0x32
|
||||
#define REPORT_MODE_CORE_ACCEL_IR12 0x33
|
||||
#define REPORT_MODE_CORE_EXTEN19 0x34
|
||||
#define REPORT_MODE_CORE_ACCEL_EXTEN16 0x35
|
||||
#define REPORT_MODE_CORE_IR10_EXTEN9 0x36
|
||||
#define REPORT_MODE_CORE_ACCEL_IR10_EXTEN6 0x37
|
||||
#define REPORT_MODE_EXTEN21 0x3d
|
||||
#define REPORT_MODE_IL_CORE_ACCEL_IR36_1 0x3e
|
||||
#define REPORT_MODE_IL_CORE_ACCEL_IR36_2 0x3f
|
||||
|
||||
// this is all temporary, but sticking with the padspecs ...for now
|
||||
const u16 button_bitmasks[] =
|
||||
{
|
||||
WIIMOTE_A, WIIMOTE_B, WIIMOTE_ONE, WIIMOTE_TWO, WIIMOTE_MINUS, WIIMOTE_PLUS, WIIMOTE_HOME
|
||||
};
|
||||
|
||||
const u16 dpad_bitmasks[] =
|
||||
{
|
||||
WIIMOTE_PAD_UP, WIIMOTE_PAD_DOWN, WIIMOTE_PAD_LEFT, WIIMOTE_PAD_RIGHT
|
||||
};
|
||||
|
||||
const char* const named_buttons[] =
|
||||
{
|
||||
"A",
|
||||
"B",
|
||||
"One",
|
||||
"Two",
|
||||
"Minus",
|
||||
"Plus",
|
||||
"Home",
|
||||
};
|
||||
|
||||
const char * const named_groups[] =
|
||||
{
|
||||
"Buttons", "D-Pad"
|
||||
};
|
||||
|
||||
Wiimote::Wiimote( const unsigned int index ) : m_index(index), m_report_mode(REPORT_MODE_CORE)
|
||||
{
|
||||
|
||||
// buttons
|
||||
groups.push_back( m_buttons = new Buttons( named_groups[0] ) );
|
||||
for ( unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i )
|
||||
m_buttons->controls.push_back( new ControlGroup::Input( named_buttons[i] ) );
|
||||
|
||||
// dpad
|
||||
groups.push_back( m_dpad = new Buttons( named_groups[1] ) );
|
||||
for ( unsigned int i=0; i < 4; ++i )
|
||||
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) );
|
||||
|
||||
// rumble
|
||||
groups.push_back( m_rumble = new ControlGroup( "Rumble" ) );
|
||||
m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) );
|
||||
|
||||
}
|
||||
|
||||
std::string Wiimote::GetName() const
|
||||
{
|
||||
return std::string("Wiimote") + char('1'+m_index);
|
||||
}
|
||||
|
||||
void Wiimote::Cycle()
|
||||
{
|
||||
|
||||
HIDReport rpt;
|
||||
rpt << (u8)m_report_mode;
|
||||
|
||||
switch ( m_report_mode )
|
||||
{
|
||||
//(a1) 30 BB BB
|
||||
case REPORT_MODE_CORE :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons;
|
||||
}
|
||||
break;
|
||||
//(a1) 31 BB BB AA AA AA
|
||||
case REPORT_MODE_CORE_ACCEL :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 32 BB BB EE EE EE EE EE EE EE EE
|
||||
case REPORT_MODE_CORE_EXTEN8 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 33 BB BB AA AA AA II II II II II II II II II II II II
|
||||
case REPORT_MODE_CORE_ACCEL_IR12 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u32)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
|
||||
case REPORT_MODE_CORE_EXTEN19 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
|
||||
case REPORT_MODE_CORE_ACCEL_EXTEN16 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 36 BB BB II II II II II II II II II II EE EE EE EE EE EE EE EE EE
|
||||
case REPORT_MODE_CORE_IR10_EXTEN9 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 37 BB BB AA AA AA II II II II II II II II II II EE EE EE EE EE EE
|
||||
case REPORT_MODE_CORE_ACCEL_IR10_EXTEN6 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 3d EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
|
||||
case REPORT_MODE_EXTEN21 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
//(a1) 3e/3f BB BB AA II II II II II II II II II II II II II II II II II II
|
||||
case REPORT_MODE_IL_CORE_ACCEL_IR36_1 :
|
||||
case REPORT_MODE_IL_CORE_ACCEL_IR36_2 :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
//rpt << buttons << (u64)0 << (u64)0 << (u64)0 << (u64)0 << (u32)0 << (u8)0;
|
||||
rpt << buttons << (u64)0 << (u64)0 << (u16)0 << (u8)0;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Wiimote& Wiimote::operator<<( HIDReport& rpt_in )
|
||||
{
|
||||
const u8 report_id = rpt_in.front(); rpt_in.pop();
|
||||
|
||||
HIDReport rpt_out;
|
||||
|
||||
switch ( report_id )
|
||||
{
|
||||
case REPORT_LEDS :
|
||||
break;
|
||||
case REPORT_DATA_MODE :
|
||||
{
|
||||
rpt_in.pop(); // continuous
|
||||
m_report_mode = rpt_in.front();
|
||||
}
|
||||
break;
|
||||
case REPORT_IR_ENABLE :
|
||||
break;
|
||||
case REPORT_SPEAKER_ENABLE :
|
||||
break;
|
||||
case REPORT_STATUS_REQUEST :
|
||||
{
|
||||
u16 buttons;
|
||||
m_buttons->GetState( &buttons, button_bitmasks );
|
||||
m_dpad->GetState( &buttons, dpad_bitmasks );
|
||||
rpt_out << (u8)REPORT_STATUS << buttons << (u16)0 << (u8)0 << (u8)0xFF;
|
||||
}
|
||||
break;
|
||||
case REPORT_WRITE_MEMORY :
|
||||
break;
|
||||
case REPORT_READ_MEMORY :
|
||||
break;
|
||||
case REPORT_SPEAKER_DATA :
|
||||
break;
|
||||
case REPORT_SPEAKER_MUTE :
|
||||
break;
|
||||
case REPORT_IR_ENABLE_2 :
|
||||
break;
|
||||
case REPORT_STATUS :
|
||||
break;
|
||||
case REPORT_READ_MEMORY_DATA :
|
||||
break;
|
||||
case REPORT_ACKNOWLEDGE_OUTPUT :
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef _CONEMU_WIIMOTE_H_
|
||||
#define _CONEMU_WIIMOTE_H_
|
||||
|
||||
#include "../../ControllerEmu.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
class HIDReport : public std::queue<u8>
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
HIDReport& operator<<( const T& t )
|
||||
{
|
||||
const u8* const e = ((u8*)&t) + sizeof(t);
|
||||
const u8* i = (u8*)&t;
|
||||
for ( ;i<e; ++i )
|
||||
push(*i);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class Wiimote : public ControllerEmu
|
||||
{
|
||||
public:
|
||||
|
||||
Wiimote( const unsigned int index );
|
||||
void Cycle();
|
||||
Wiimote& operator<<( HIDReport& );
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
private:
|
||||
|
||||
Buttons* m_buttons;
|
||||
Buttons* m_dpad;
|
||||
ControlGroup* m_rumble;
|
||||
// TODO: add forces
|
||||
// TODO: add ir
|
||||
|
||||
const unsigned int m_index;
|
||||
unsigned int m_report_mode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
#include "GCPad.h"
|
||||
#include "GCPadEmu.h"
|
||||
|
||||
// this is all temporary, but sticking with the padspecs ...for now
|
||||
const u16 button_bitmasks[] =
|
||||
{
|
||||
PAD_BUTTON_A,
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _CONEMU_GCPAD_H_
|
||||
#define _CONEMU_GCPAD_H_
|
||||
|
||||
#include "../../ControllerEmu.h"
|
||||
#include <ControllerEmu.h>
|
||||
|
||||
class GCPad : public ControllerEmu
|
||||
{
|
|
@ -2,9 +2,10 @@
|
|||
#include <math.h>
|
||||
#include "Common.h"
|
||||
#include "pluginspecs_pad.h"
|
||||
#include "pluginspecs_wiimote.h"
|
||||
|
||||
#include "ControllerInterface/ControllerInterface.h"
|
||||
#include "GCPadEmu.h"
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "ConfigDiag.h"
|
||||
#endif
|
||||
|
@ -16,16 +17,20 @@
|
|||
|
||||
#define PLUGIN_VERSION 0x0100
|
||||
|
||||
#define PLUGIN_NAME "Dolphin GCPad New"
|
||||
#ifdef DEBUGFAST
|
||||
#define PLUGIN_FULL_NAME "Dolphin GCPad New (DebugFast)"
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME" (DebugFast)"
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#define PLUGIN_FULL_NAME "Dolphin GCPad New (Debug)"
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME" (Debug)"
|
||||
#else
|
||||
#define PLUGIN_FULL_NAME "Dolphin GCPad New"
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// the plugin
|
||||
Plugin g_plugin( "GCPadNew", "Pad", "GCPad" );
|
||||
SPADInitialize *g_PADInitialize = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
class wxDLLApp : public wxApp
|
||||
|
@ -38,14 +43,6 @@ class wxDLLApp : public wxApp
|
|||
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
|
||||
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
||||
#endif
|
||||
// copied from GCPad
|
||||
SPADInitialize *g_PADInitialize = NULL;
|
||||
// Check if Dolphin is in focus
|
||||
// ----------------
|
||||
bool IsFocus()
|
||||
{
|
||||
return g_PADInitialize->pRendererHasFocus();
|
||||
}
|
||||
|
||||
// copied from GCPad
|
||||
HINSTANCE g_hInstance;
|
||||
|
@ -67,8 +64,6 @@ wxWindow* GetParentedWxWindow(HWND Parent)
|
|||
#endif
|
||||
// /
|
||||
|
||||
// the plugin
|
||||
Plugin g_plugin;
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
||||
{
|
||||
|
@ -90,18 +85,32 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
|||
}
|
||||
#endif
|
||||
|
||||
void DeInitPlugin()
|
||||
{
|
||||
// i realize i am checking IsInit() twice, just too lazy to change it
|
||||
if ( g_plugin.controller_interface.IsInit() )
|
||||
{
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
i = g_plugin.controllers.begin(),
|
||||
e = g_plugin.controllers.end();
|
||||
for ( ; i!=e; ++i )
|
||||
delete *i;
|
||||
g_plugin.controllers.clear();
|
||||
|
||||
int _last_numPAD = 4;
|
||||
|
||||
g_plugin.controller_interface.DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
// if plugin isn't initialized, init and load config
|
||||
void InitPlugin( void* const hwnd )
|
||||
{
|
||||
//g_plugin.controls_crit.Enter(); // enter
|
||||
//g_plugin.interface_crit.Enter();
|
||||
|
||||
// i realize i am checking IsInit() twice, just too lazy to change it
|
||||
if ( false == g_plugin.controller_interface.IsInit() )
|
||||
{
|
||||
// add 4 gcpads
|
||||
for ( unsigned int i = 0; i<4; ++i )
|
||||
g_plugin.controllers.push_back( new GCPad( i ) );
|
||||
|
||||
// load the saved controller config
|
||||
g_plugin.LoadConfig();
|
||||
|
||||
|
@ -116,9 +125,6 @@ void InitPlugin( void* const hwnd )
|
|||
(*i)->UpdateReferences( g_plugin.controller_interface );
|
||||
|
||||
}
|
||||
|
||||
//g_plugin.interface_crit.Leave();
|
||||
//g_plugin.controls_crit.Leave(); // leave
|
||||
}
|
||||
|
||||
// I N T E R F A C E
|
||||
|
@ -131,10 +137,6 @@ void InitPlugin( void* const hwnd )
|
|||
//
|
||||
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||
{
|
||||
// why not, i guess
|
||||
if ( NULL == _pPADStatus )
|
||||
return;
|
||||
|
||||
memset( _pPADStatus, 0, sizeof(*_pPADStatus) );
|
||||
_pPADStatus->err = PAD_ERR_NONE;
|
||||
// wtf is this?
|
||||
|
@ -151,6 +153,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|||
|
||||
// if we are on the next input cycle, update output and input
|
||||
// if we can get a lock
|
||||
static int _last_numPAD = 4;
|
||||
if ( _numPAD <= _last_numPAD && g_plugin.interface_crit.TryEnter() )
|
||||
{
|
||||
g_plugin.controller_interface.UpdateOutput();
|
||||
|
@ -160,7 +163,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|||
_last_numPAD = _numPAD;
|
||||
|
||||
// if we want background input or have focus
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || IsFocus() )
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
||||
{
|
||||
// get input
|
||||
((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus );
|
||||
|
@ -201,7 +204,7 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
|||
if ( g_plugin.controls_crit.TryEnter() )
|
||||
{
|
||||
// only on/off rumble, if we have focus or background input on
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || IsFocus() )
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
||||
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
|
||||
|
||||
// leave
|
||||
|
@ -241,7 +244,7 @@ void DllConfig(HWND _hParent)
|
|||
#if defined(HAVE_X11) && HAVE_X11
|
||||
Display *dpy = NULL;
|
||||
#endif
|
||||
if ( g_plugin.controller_interface.IsInit() ) // hack for showing dialog when game isnt running
|
||||
if ( g_plugin.controller_interface.IsInit() ) // check if game is running
|
||||
was_init = true;
|
||||
else
|
||||
{
|
||||
|
@ -278,12 +281,12 @@ void DllConfig(HWND _hParent)
|
|||
#endif
|
||||
// /
|
||||
|
||||
if ( !was_init ) // hack for showing dialog when game isnt running
|
||||
if ( !was_init ) // if game is running
|
||||
{
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
XCloseDisplay(dpy);
|
||||
#endif
|
||||
g_plugin.controller_interface.DeInit();
|
||||
DeInitPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,10 +334,8 @@ void Initialize(void *init)
|
|||
//
|
||||
void Shutdown(void)
|
||||
{
|
||||
//plugin.controls_crit.Enter(); // enter
|
||||
if ( g_plugin.controller_interface.IsInit() )
|
||||
g_plugin.controller_interface.DeInit();
|
||||
//plugin.controls_crit.Leave(); // leave
|
||||
DeInitPlugin();
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
|
|
|
@ -653,6 +653,18 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="UDP Wiimote"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\UDPWiimote.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\UDPWiimote.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\Src\main.cpp"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,591 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="Plugin_WiimoteNew"
|
||||
ProjectGUID="{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}"
|
||||
RootNamespace="Plugin_WiimoteNew"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;_SECURE_SCL=0"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib rpcrt4.lib wxbase28ud.lib wxmsw28ud_core.lib"
|
||||
OutputFile="..\..\..\Binary\Win32/Plugins\Plugin_WiimoteNewD.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="0"
|
||||
EnableCOMDATFolding="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;_SECURE_SCL=0"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib rpcrt4.lib wxbase28ud.lib wxmsw28ud_core.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_WiimoteNewD.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="0"
|
||||
EnableCOMDATFolding="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="0"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/NODEFAULTLIB:msvcrt.lib"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib wxbase28u.lib wxmsw28u_core.lib"
|
||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_WiimoteNew.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="0"
|
||||
EnableCOMDATFolding="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="0"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib wxbase28u.lib wxmsw28u_core.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_WiimoteNew.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="0"
|
||||
EnableCOMDATFolding="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="DebugFast|Win32"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="DEBUGFAST;WIN32;NDEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/NODEFAULTLIB:msvcrt.lib"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib wxbase28u.lib wxmsw28u_core.lib"
|
||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_WiimoteNewDF.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="DebugFast|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\Core\InputPluginCommon\Src;..\..\Core\InputCommon\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;Plugin_WiimoteNew_TEST_EXPORTS;DEBUGFAST;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib wxbase28u.lib wxmsw28u_core.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_WiimoteNewDF.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="WiimoteEmu"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\EmuSubroutines.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Encryption.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Encryption.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\WiimoteEmu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\WiimoteEmu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\WiimoteHid.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Attachment"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Attachment.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Attachment.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Classic.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Classic.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Nunchuk.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Nunchuk.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\Src\WiimoteNew.cpp"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "Attachment.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
// Extension device IDs to be written to the last bytes of the extension reg
|
||||
static const u8 gh3glp_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
||||
static const u8 ghwtdrums_id[] = { 0x01, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
||||
// The id for nothing inserted
|
||||
static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
|
||||
// The id for a partially inserted extension
|
||||
static const u8 partially_id[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
Attachment::Attachment( const char* const _name ) : name( _name )
|
||||
{
|
||||
reg.resize( WIIMOTE_REG_EXT_SIZE, 0);
|
||||
}
|
||||
|
||||
None::None() : Attachment( "None" )
|
||||
{
|
||||
// set up register
|
||||
memcpy( ®[0xfa], nothing_id, sizeof(nothing_id) );
|
||||
}
|
||||
|
||||
std::string Attachment::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ControllerEmu::Extension::GetState( u8* const data )
|
||||
{
|
||||
((WiimoteEmu::Attachment*)attachments[ active_extension ])->GetState( data );
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _ATTACHMENT_EMU_H_
|
||||
#define _ATTACHMENT_EMU_H_
|
||||
|
||||
#include "ControllerEmu.h"
|
||||
#include "../WiimoteEmu.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
class Attachment : public ControllerEmu
|
||||
{
|
||||
public:
|
||||
Attachment( const char* const _name );
|
||||
|
||||
virtual void GetState( u8* const data ) {}
|
||||
std::string GetName() const;
|
||||
|
||||
const char* const name;
|
||||
std::vector<u8> reg;
|
||||
};
|
||||
|
||||
class None : public Attachment
|
||||
{
|
||||
public:
|
||||
None();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
#include "Classic.h"
|
||||
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
static const u8 classic_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x01 };
|
||||
/* Classic Controller calibration */
|
||||
static const u8 classic_calibration[] =
|
||||
{
|
||||
0xff, 0x00, 0x80, 0xff, 0x00, 0x80,
|
||||
0xff, 0x00, 0x80, 0xff, 0x00, 0x80,
|
||||
0x00, 0x00, 0x51, 0xa6
|
||||
};
|
||||
|
||||
// classic buttons
|
||||
#define CLASSIC_PAD_RIGHT 0x80
|
||||
#define CLASSIC_PAD_DOWN 0x40
|
||||
#define CLASSIC_TRIGGER_L 0x20
|
||||
#define CLASSIC_MINUS 0x10
|
||||
#define CLASSIC_HOME 0x08
|
||||
#define CLASSIC_PLUS 0x04
|
||||
#define CLASSIC_TRIGGER_R 0x02
|
||||
#define CLASSIC_NOTHING 0x01
|
||||
#define CLASSIC_ZL 0x8000
|
||||
#define CLASSIC_B 0x4000
|
||||
#define CLASSIC_Y 0x2000
|
||||
#define CLASSIC_A 0x1000
|
||||
#define CLASSIC_X 0x0800
|
||||
#define CLASSIC_ZR 0x0400
|
||||
#define CLASSIC_PAD_LEFT 0x0200
|
||||
#define CLASSIC_PAD_UP 0x0100
|
||||
|
||||
|
||||
const u16 classic_button_bitmasks[] =
|
||||
{
|
||||
CLASSIC_A,
|
||||
CLASSIC_B,
|
||||
CLASSIC_X,
|
||||
CLASSIC_Y,
|
||||
|
||||
CLASSIC_ZL,
|
||||
CLASSIC_ZR,
|
||||
|
||||
CLASSIC_MINUS,
|
||||
CLASSIC_PLUS,
|
||||
|
||||
CLASSIC_HOME,
|
||||
};
|
||||
|
||||
const char* classic_button_names[] =
|
||||
{
|
||||
"A","B","X","Y","ZL","ZR","Minus","Plus","Home",
|
||||
};
|
||||
|
||||
const u16 classic_trigger_bitmasks[] =
|
||||
{
|
||||
CLASSIC_TRIGGER_L, CLASSIC_TRIGGER_R,
|
||||
};
|
||||
|
||||
const char* const classic_trigger_names[] =
|
||||
{
|
||||
"L", "R", "L-Analog", "R-Analog"
|
||||
};
|
||||
|
||||
const u16 classic_dpad_bitmasks[] =
|
||||
{
|
||||
CLASSIC_PAD_UP, CLASSIC_PAD_DOWN, CLASSIC_PAD_LEFT, CLASSIC_PAD_RIGHT
|
||||
};
|
||||
|
||||
Classic::Classic() : Attachment( "Classic Controller" )
|
||||
{
|
||||
// buttons
|
||||
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
||||
for ( unsigned int i = 0; i < sizeof(classic_button_names)/sizeof(*classic_button_names); ++i )
|
||||
m_buttons->controls.push_back( new ControlGroup::Input( classic_button_names[i] ) );
|
||||
|
||||
// sticks
|
||||
groups.push_back( m_left_stick = new AnalogStick( "Left Stick" ) );
|
||||
groups.push_back( m_right_stick = new AnalogStick( "Right Stick" ) );
|
||||
|
||||
// triggers
|
||||
groups.push_back( m_triggers = new MixedTriggers( "Triggers" ) );
|
||||
for ( unsigned int i=0; i < sizeof(classic_trigger_names)/sizeof(*classic_trigger_names); ++i )
|
||||
m_triggers->controls.push_back( new ControlGroup::Input( classic_trigger_names[i] ) );
|
||||
|
||||
// dpad
|
||||
groups.push_back( m_dpad = new Buttons( "D-Pad" ) );
|
||||
for ( unsigned int i=0; i < 4; ++i )
|
||||
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) );
|
||||
|
||||
// set up register
|
||||
// calibration
|
||||
memcpy( ®[0x20], classic_calibration, sizeof(classic_calibration) );
|
||||
// id
|
||||
memcpy( ®[0xfa], classic_id, sizeof(classic_id) );
|
||||
}
|
||||
|
||||
void Classic::GetState( u8* const data )
|
||||
{
|
||||
wm_classic_extension* const ccdata = (wm_classic_extension*)data;
|
||||
|
||||
// left stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_left_stick->GetState( &x, &y, 0x20, 0x1F /*0x15*/ );
|
||||
|
||||
ccdata->lx = x;
|
||||
ccdata->ly = y;
|
||||
}
|
||||
|
||||
// right stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_right_stick->GetState( &x, &y, 0x10, 0x0F /*0x0C*/ );
|
||||
|
||||
ccdata->rx1 = x;
|
||||
ccdata->rx2 = x >> 1;
|
||||
ccdata->rx3 = x >> 3;
|
||||
ccdata->ry = y;
|
||||
}
|
||||
|
||||
//triggers
|
||||
{
|
||||
u8 trigs[2];
|
||||
m_triggers->GetState( &ccdata->bt, classic_trigger_bitmasks, trigs, 0x1F );
|
||||
|
||||
ccdata->lt1 = trigs[0];
|
||||
ccdata->lt2 = trigs[0] >> 3;
|
||||
ccdata->rt = trigs[1];
|
||||
}
|
||||
|
||||
// buttons
|
||||
m_buttons->GetState( &ccdata->bt, classic_button_bitmasks );
|
||||
// dpad
|
||||
m_dpad->GetState( &ccdata->bt, classic_dpad_bitmasks );
|
||||
|
||||
// flip button bits
|
||||
ccdata->bt ^= 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include "Attachment.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
class Classic : public Attachment
|
||||
{
|
||||
public:
|
||||
Classic();
|
||||
void GetState( u8* const data );
|
||||
|
||||
private:
|
||||
Buttons* m_buttons;
|
||||
Buttons* m_shake;
|
||||
MixedTriggers* m_triggers;
|
||||
Buttons* m_dpad;
|
||||
AnalogStick* m_left_stick;
|
||||
AnalogStick* m_right_stick;
|
||||
};
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
#include "Nunchuk.h"
|
||||
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
static const u8 nunchuck_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x00, 0x00 };
|
||||
/* Default calibration for the nunchuck. It should be written to 0x20 - 0x3f of the
|
||||
extension register. 0x80 is the neutral x and y accelerators and 0xb3 is the
|
||||
neutral z accelerometer that is adjusted for gravity. */
|
||||
static const u8 nunchuck_calibration[] =
|
||||
{
|
||||
0x80, 0x80, 0x80, 0x00, // accelerometer x, y, z neutral
|
||||
0xb3, 0xb3, 0xb3, 0x00, // x, y, z g-force values
|
||||
|
||||
// 0x80 = analog stick x and y axis center
|
||||
0xff, 0x00, 0x80,
|
||||
0xff, 0x00, 0x80,
|
||||
0xee, 0x43 // checksum on the last two bytes
|
||||
};
|
||||
|
||||
// nunchuk buttons
|
||||
#define NUNCHUK_C 0x02
|
||||
#define NUNCHUK_Z 0x01
|
||||
|
||||
const u8 nunchuk_button_bitmasks[] =
|
||||
{
|
||||
NUNCHUK_C,
|
||||
NUNCHUK_Z,
|
||||
};
|
||||
|
||||
Nunchuk::Nunchuk() : Attachment( "Nunchuk" )
|
||||
{
|
||||
// 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( "Z" ) );
|
||||
|
||||
// stick
|
||||
groups.push_back( m_stick = new AnalogStick( "Stick" ) );
|
||||
|
||||
// force
|
||||
//groups.push_back( m_tilt = new Tilt( "Tilt" ) );
|
||||
groups.push_back( m_tilt = new Tilt( "Pitch and Roll" ) );
|
||||
//groups.push_back( m_swing = new Force( "Swing" ) );
|
||||
|
||||
// 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( "Y" ) );
|
||||
m_shake->controls.push_back( new ControlGroup::Input( "Z" ) );
|
||||
|
||||
// set up register
|
||||
// calibration
|
||||
memcpy( ®[0x20], nunchuck_calibration, sizeof(nunchuck_calibration) );
|
||||
// id
|
||||
memcpy( ®[0xfa], nunchuck_id, sizeof(nunchuck_id) );
|
||||
}
|
||||
|
||||
void Nunchuk::GetState( u8* const data )
|
||||
{
|
||||
wm_extension* const ncdata = (wm_extension*)data;
|
||||
|
||||
// stick / not using calibration data for stick, o well
|
||||
m_stick->GetState( &ncdata->jx, &ncdata->jy, 0x80, 127 );
|
||||
|
||||
// tilt
|
||||
float x, y;
|
||||
m_tilt->GetState( &x, &y, 0, (PI / 2) ); // 90 degrees
|
||||
|
||||
// this isn't doing anything with those low bits in the calib data, o well
|
||||
|
||||
const accel_cal* const cal = (accel_cal*)®[0x20];
|
||||
const u8* const zero_g = &cal->zero_g.x;
|
||||
u8 one_g[3];
|
||||
for ( unsigned int i=0; i<3; ++i )
|
||||
one_g[i] = (&cal->one_g.x)[i] - zero_g[i];
|
||||
|
||||
// this math should be good enough :P
|
||||
ncdata->az = u8(sin( (PI / 2) - std::max( abs(x), abs(y) ) ) * one_g[2] + zero_g[2]);
|
||||
ncdata->ax = u8(sin(x) * -one_g[0] + zero_g[0]);
|
||||
ncdata->ay = u8(sin(y) * one_g[1] + zero_g[1]);
|
||||
|
||||
// shake
|
||||
const unsigned int btns[] = { 0x01, 0x02, 0x04 };
|
||||
unsigned int shake = 0;
|
||||
m_shake->GetState( &shake, btns );
|
||||
static unsigned int shake_step = 0;
|
||||
if (shake)
|
||||
{
|
||||
shake_step = (shake_step + 1) % sizeof(shake_data);
|
||||
for ( unsigned int i=0; i<3; ++i )
|
||||
if ( shake & (1 << i) )
|
||||
(&ncdata->ax)[i] = shake_data[shake_step];
|
||||
}
|
||||
else
|
||||
shake_step = 0;
|
||||
|
||||
// buttons
|
||||
m_buttons->GetState( &ncdata->bt, nunchuk_button_bitmasks );
|
||||
|
||||
// flip the button bits :/
|
||||
ncdata->bt ^= 0x3;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "Attachment.h"
|
||||
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
class Nunchuk : public Attachment
|
||||
{
|
||||
public:
|
||||
Nunchuk();
|
||||
void GetState( u8* const data );
|
||||
|
||||
private:
|
||||
Tilt* m_tilt;
|
||||
Force* m_swing;
|
||||
|
||||
Buttons* m_shake;
|
||||
|
||||
Buttons* m_buttons;
|
||||
AnalogStick* m_stick;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,443 @@
|
|||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// 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/
|
||||
|
||||
|
||||
/* HID reports access guide. */
|
||||
|
||||
/* 0x10 - 0x1a Output EmuMain.cpp: HidOutputReport()
|
||||
0x10 - 0x14: General
|
||||
0x15: Status report request from the Wii
|
||||
0x16 and 0x17: Write and read memory or registers
|
||||
0x19 and 0x1a: General
|
||||
0x20 - 0x22 Input EmuMain.cpp: HidOutputReport() to the destination
|
||||
0x15 leads to a 0x20 Input report
|
||||
0x17 leads to a 0x21 Input report
|
||||
0x10 - 0x1a leads to a 0x22 Input report
|
||||
0x30 - 0x3f Input This file: Update() */
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Common.h" // Common
|
||||
#include "pluginspecs_wiimote.h"
|
||||
|
||||
#include "WiimoteEmu.h"
|
||||
#include "Attachment/Attachment.h"
|
||||
|
||||
/* Bit shift conversions */
|
||||
u32 convert24bit(const u8* src)
|
||||
{
|
||||
return (src[0] << 16) | (src[1] << 8) | src[2];
|
||||
}
|
||||
|
||||
u16 convert16bit(const u8* src)
|
||||
{
|
||||
return (src[0] << 8) | src[1];
|
||||
}
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
void Wiimote::ReportMode(u16 _channelID, wm_report_mode* dr)
|
||||
{
|
||||
//INFO_LOG(WIIMOTE, "Set data report mode");
|
||||
//DEBUG_LOG(WIIMOTE, " Rumble: %x", dr->rumble);
|
||||
//DEBUG_LOG(WIIMOTE, " Continuous: %x", dr->continuous);
|
||||
//DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time);
|
||||
//DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
|
||||
|
||||
// should I use the rumble var in here?
|
||||
//m_rumble->controls[0]->control_ref->State( dr->rumble );
|
||||
|
||||
m_reporting_auto = dr->all_the_time;
|
||||
m_reporting_mode = dr->mode;
|
||||
m_reporting_channel = _channelID;
|
||||
|
||||
if (0 == dr->all_the_time)
|
||||
PanicAlert("Wiimote: Reporting Always is set to OFF!");
|
||||
|
||||
// Validation check
|
||||
switch (dr->mode)
|
||||
{
|
||||
case WM_REPORT_CORE :
|
||||
case WM_REPORT_CORE_ACCEL :
|
||||
case WM_REPORT_CORE_ACCEL_IR12 :
|
||||
case WM_REPORT_CORE_ACCEL_EXT16 :
|
||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6 :
|
||||
break;
|
||||
default:
|
||||
PanicAlert("Wiimote: Unsupported reporting mode 0x%x", dr->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we process the Output Reports that the Wii sends. Our response will be
|
||||
an Input Report back to the Wii. Input and Output is from the Wii's
|
||||
perspective, Output means data to the Wiimote (from the Wii), Input means
|
||||
data from the Wiimote.
|
||||
|
||||
The call browser:
|
||||
|
||||
1. Wiimote_InterruptChannel > InterruptChannel > HidOutputReport
|
||||
2. Wiimote_ControlChannel > ControlChannel > HidOutputReport
|
||||
|
||||
The IR enable/disable and speaker enable/disable and mute/unmute values are
|
||||
bit2: 0 = Disable (0x02), 1 = Enable (0x06)
|
||||
*/
|
||||
void Wiimote::HidOutputReport(u16 _channelID, wm_report* sr)
|
||||
{
|
||||
INFO_LOG(WIIMOTE, "HidOutputReport (page: %i, cid: 0x%02x, wm: 0x%02x)", m_index, _channelID, sr->wm);
|
||||
|
||||
switch (sr->wm)
|
||||
{
|
||||
case WM_RUMBLE : // 0x10
|
||||
m_rumble->controls[0]->control_ref->State( sr->data[0] > 0 );
|
||||
return; // no ack
|
||||
break;
|
||||
|
||||
case WM_LEDS : // 0x11
|
||||
//INFO_LOG(WIIMOTE, "Set LEDs: 0x%02x", sr->data[0]);
|
||||
m_status.leds = sr->data[0] >> 4;
|
||||
break;
|
||||
|
||||
case WM_REPORT_MODE : // 0x12
|
||||
ReportMode(_channelID, (wm_report_mode*)sr->data);
|
||||
break;
|
||||
|
||||
case WM_IR_PIXEL_CLOCK : // 0x13
|
||||
//INFO_LOG(WIIMOTE, "WM IR Clock: 0x%02x", sr->data[0]);
|
||||
//m_ir_clock = (sr->data[0] & 0x04) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case WM_SPEAKER_ENABLE : // 0x14
|
||||
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
|
||||
m_status.speaker = (sr->data[0] & 0x04) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case WM_REQUEST_STATUS : // 0x15
|
||||
RequestStatus(_channelID, (wm_request_status*)sr->data);
|
||||
return; // sends its own ack
|
||||
break;
|
||||
|
||||
case WM_WRITE_DATA : // 0x16
|
||||
WriteData(_channelID, (wm_write_data*)sr->data);
|
||||
break;
|
||||
|
||||
case WM_READ_DATA : // 0x17
|
||||
ReadData(_channelID, (wm_read_data*)sr->data);
|
||||
return; // sends its own ack
|
||||
break;
|
||||
|
||||
case WM_WRITE_SPEAKER_DATA : // 0x18
|
||||
// TODO: Does this need an ack?
|
||||
return; // no ack
|
||||
break;
|
||||
|
||||
case WM_SPEAKER_MUTE : // 0x19
|
||||
//INFO_LOG(WIIMOTE, "WM Speaker Mute: 0x%02x", sr->data[0]);
|
||||
//m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case WM_IR_LOGIC: // 0x1a
|
||||
// comment from old plugin:
|
||||
// This enables or disables the IR lights, we update the global variable g_IR
|
||||
// so that WmRequestStatus() knows about it
|
||||
//INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
|
||||
m_status.ir = (sr->data[0] & 0x04) ? 1 : 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->wm);
|
||||
return; // no ack
|
||||
break;
|
||||
}
|
||||
|
||||
// send ack
|
||||
SendAck(_channelID, sr->wm);
|
||||
}
|
||||
|
||||
/* This will generate the 0x22 acknowledgement for most Input reports.
|
||||
It has the form of "a1 22 00 00 _reportID 00".
|
||||
The first two bytes are the core buttons data,
|
||||
00 00 means nothing is pressed.
|
||||
The last byte is the success code 00. */
|
||||
void Wiimote::SendAck(u16 _channelID, u8 _reportID)
|
||||
{
|
||||
u8 data[6];
|
||||
|
||||
data[0] = 0xA1;
|
||||
data[1] = WM_ACK_DATA;
|
||||
|
||||
wm_acknowledge* const ack = (wm_acknowledge*)(data + 2);
|
||||
|
||||
ack->buttons = m_status.buttons;
|
||||
ack->reportID = _reportID;
|
||||
ack->errorID = 0;
|
||||
|
||||
m_wiimote_init->pWiimoteInput( m_index, _channelID, data, sizeof(data));
|
||||
}
|
||||
|
||||
/* Here we produce a 0x20 status report to send to the Wii. We currently ignore
|
||||
the status request rs and all its eventual instructions it may include (for
|
||||
example turn off rumble or something else) and just send the status
|
||||
report. */
|
||||
void Wiimote::RequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
|
||||
{
|
||||
// handle switch extension
|
||||
if ( m_extension->active_extension != m_extension->switch_extension )
|
||||
{
|
||||
if ( m_extension->active_extension && m_extension->switch_extension )
|
||||
// detach extension first
|
||||
m_extension->active_extension = 0;
|
||||
else
|
||||
m_extension->active_extension = m_extension->switch_extension;
|
||||
|
||||
// set register, I hate this line
|
||||
m_register[ 0xa40000 ] = ((WiimoteEmu::Attachment*)m_extension->attachments[ m_extension->active_extension ])->reg;
|
||||
|
||||
// Wiibrew: Following a connection or disconnection event on the Extension Port,
|
||||
// data reporting is disabled and the Data Reporting Mode must be reset before new data can arrive.
|
||||
m_reporting_auto = false;
|
||||
}
|
||||
|
||||
// extension status
|
||||
m_status.extension = m_extension->active_extension ? 1 : 0;
|
||||
|
||||
// set up report
|
||||
u8 data[8];
|
||||
data[0] = 0xA1;
|
||||
data[1] = WM_STATUS_REPORT;
|
||||
|
||||
// status values
|
||||
*(wm_status_report*)(data + 2) = m_status;
|
||||
|
||||
// send report
|
||||
m_wiimote_init->pWiimoteInput(m_index, _channelID, data, sizeof(data));
|
||||
}
|
||||
|
||||
/* Write data to Wiimote and Extensions registers. */
|
||||
void Wiimote::WriteData(u16 _channelID, wm_write_data* wd)
|
||||
{
|
||||
u32 address = convert24bit(wd->address);
|
||||
// this is done in ReadDate, but not here in WriteData ?
|
||||
//u16 size = convert16bit(rd->size);
|
||||
|
||||
if (wd->size > 16)
|
||||
{
|
||||
PanicAlert("WriteData: size is > 16 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (wd->space)
|
||||
{
|
||||
case WM_SPACE_EEPROM :
|
||||
{
|
||||
static bool first = true;
|
||||
if (first)
|
||||
{
|
||||
PanicAlert("WriteData: first write to EEPROM");
|
||||
first = false;
|
||||
}
|
||||
// Write to EEPROM
|
||||
if (address + wd->size > WIIMOTE_EEPROM_SIZE)
|
||||
{
|
||||
ERROR_LOG(WIIMOTE, "WriteData: address + size out of bounds!");
|
||||
PanicAlert("WriteData: address + size out of bounds!");
|
||||
return;
|
||||
}
|
||||
memcpy(m_eeprom + address, wd->data, wd->size);
|
||||
}
|
||||
break;
|
||||
case WM_SPACE_REGS1 :
|
||||
case WM_SPACE_REGS2 :
|
||||
{
|
||||
// Write to Control Register
|
||||
|
||||
// ignore the 0x010000 bit
|
||||
address &= 0xFEFFFF;
|
||||
|
||||
// ignore second byte for extension area
|
||||
if (0xA4 == (address >> 16))
|
||||
address &= 0xFF00FF;
|
||||
|
||||
// write to the register
|
||||
m_register.Write(address, wd->data, wd->size);
|
||||
|
||||
switch (address >> 16)
|
||||
{
|
||||
// extension register
|
||||
case 0xa4 :
|
||||
{
|
||||
// Run the key generation on all writes in the key area, it doesn't matter
|
||||
// that we send it parts of a key, only the last full key will have an effect
|
||||
// I might have f'ed this up
|
||||
if ( address >= 0xa40040 && address <= 0xa4004c )
|
||||
{
|
||||
u8 data[WIIMOTE_REG_EXT_SIZE];
|
||||
m_register.Read( 0xa40000, data, WIIMOTE_REG_EXT_SIZE );
|
||||
wiimote_gen_key( &m_ext_key, data + 0x40 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PanicAlert("WriteData: unimplemented parameters!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read data from Wiimote and Extensions registers. */
|
||||
void Wiimote::ReadData(u16 _channelID, wm_read_data* rd)
|
||||
{
|
||||
u32 address = convert24bit(rd->address);
|
||||
u16 size = convert16bit(rd->size);
|
||||
|
||||
switch (rd->space)
|
||||
{
|
||||
case WM_SPACE_EEPROM :
|
||||
{
|
||||
//PanicAlert("ReadData: reading from EEPROM: address: 0x%x size: 0x%x", address, size);
|
||||
// Read from EEPROM
|
||||
if (address + size > WIIMOTE_EEPROM_FREE_SIZE)
|
||||
{
|
||||
// generate a read error
|
||||
size = 0;
|
||||
|
||||
if (address + size > WIIMOTE_EEPROM_SIZE)
|
||||
{
|
||||
PanicAlert("ReadData: address + size out of bounds");
|
||||
return;
|
||||
}
|
||||
}
|
||||
SendReadDataReply(_channelID, m_eeprom + address, address, size);
|
||||
}
|
||||
break;
|
||||
case WM_SPACE_REGS1 :
|
||||
case WM_SPACE_REGS2 :
|
||||
{
|
||||
// Read from Control Register
|
||||
|
||||
// ignore the 0x010000 bit
|
||||
address &= 0xFEFFFF;
|
||||
|
||||
// ignore second byte for extension area
|
||||
if (0xA4 == (address >> 16))
|
||||
address &= 0xFF00FF;
|
||||
|
||||
u8* const block = new u8[ size ];
|
||||
m_register.Read( address, block, size );
|
||||
|
||||
switch (address >> 16)
|
||||
{
|
||||
case 0xa4 :
|
||||
{
|
||||
// Encrypt data read from extension register
|
||||
// Check if encrypted reads is on
|
||||
if ( m_reg_ext[0xf0] == 0xaa )
|
||||
{
|
||||
// I probably totally f'ed this up
|
||||
wiimote_encrypt(&m_ext_key, block, address & 0xffff, (u8)size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xa6 :
|
||||
{
|
||||
// motion plus crap copied from old wiimote plugin
|
||||
//block[0xFC] = 0xA6;
|
||||
//block[0xFD] = 0x20;
|
||||
//block[0xFE] = 0x00;
|
||||
//block[0xFF] = 0x05;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Let this function process the message and send it to the Wii
|
||||
SendReadDataReply(_channelID, block, address, (int)size);
|
||||
|
||||
delete[] block;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x)!", size, rd->space);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we produce the actual 0x21 Input report that we send to the Wii. The
|
||||
message is divided into 16 bytes pieces and sent piece by piece. There will
|
||||
be five formatting bytes at the begging of all reports. A common format is
|
||||
00 00 f0 00 20, the 00 00 means that no buttons are pressed, the f means 16
|
||||
bytes in the message, the 0 means no error, the 00 20 means that the message
|
||||
is at the 00 20 offest in the registry that was read.
|
||||
|
||||
_Base: The data beginning at _Base[0]
|
||||
_Address: The starting address inside the registry, this is used to check for out of bounds reading
|
||||
_Size: The total size to send
|
||||
*/
|
||||
void Wiimote::SendReadDataReply(u16 _channelID, const void* _Base, unsigned int _Address, unsigned int _Size)
|
||||
{
|
||||
u8 data[23];
|
||||
data[0] = 0xA1;
|
||||
data[1] = WM_READ_DATA_REPLY;
|
||||
wm_read_data_reply* const reply = (wm_read_data_reply*)(data + 2);
|
||||
reply->buttons = m_status.buttons;
|
||||
reply->error = 0;
|
||||
|
||||
// Out of bounds. The real Wiimote generate an error for the first
|
||||
// request to 0x1770 if we dont't replicate that the game will never
|
||||
// read the calibration data at the beginning of Eeprom. I think this
|
||||
// error is supposed to occur when we try to read above the freely
|
||||
// usable space that ends at 0x16ff.
|
||||
if (0 == _Size)
|
||||
{
|
||||
reply->size = 0x0f;
|
||||
reply->error = 0x08;
|
||||
|
||||
memset(reply->data, 0, sizeof(reply->data));
|
||||
m_wiimote_init->pWiimoteInput(m_index, _channelID, data, sizeof(data));
|
||||
}
|
||||
|
||||
while (_Size)
|
||||
{
|
||||
// Limit the amt to 16 bytes
|
||||
// AyuanX: the MTU is 640B though... what a waste!
|
||||
const int amt = std::min( (unsigned int)16, _Size );
|
||||
|
||||
// 0x1 means two bytes, 0xf means 16 bytes
|
||||
reply->size = amt - 1;
|
||||
reply->address = Common::swap16(_Address);
|
||||
|
||||
// Clear the mem first
|
||||
memset(reply->data, 0, sizeof(reply->data));
|
||||
|
||||
// copy piece of mem
|
||||
memcpy(reply->data, _Base, amt);
|
||||
|
||||
// Send a piece
|
||||
m_wiimote_init->pWiimoteInput(m_index, _channelID, data, sizeof(data));
|
||||
|
||||
// advance pointers
|
||||
_Size -= amt;
|
||||
_Base = (u8*)_Base + amt;
|
||||
_Address += amt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,296 @@
|
|||
// Copyright (C) 2003 Dolphin Project.
|
||||
// Copyright (C) Hector Martin "marcan" (hector@marcansoft.com)
|
||||
|
||||
// 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/
|
||||
|
||||
|
||||
#include "Common.h"
|
||||
#include "pluginspecs_wiimote.h"
|
||||
#include "Encryption.h"
|
||||
|
||||
|
||||
u8 ans_tbl[7][6] = {
|
||||
{0xA8,0x77,0xA6,0xE0,0xF7,0x43},
|
||||
{0x5A,0x35,0x85,0xE2,0x72,0x97},
|
||||
{0x8F,0xB7,0x1A,0x62,0x87,0x38},
|
||||
{ 0xD,0x67,0xC7,0xBE,0x4F,0x3E},
|
||||
{0x20,0x76,0x37,0x8F,0x68,0xB7},
|
||||
{0xA9,0x26,0x3F,0x2B,0x10,0xE3},
|
||||
{0x30,0x7E,0x90, 0xE,0x85, 0xA},
|
||||
};
|
||||
|
||||
u8 tsbox[256] = {
|
||||
0x70,0x51, 3,0x86,0x40, 0xD,0x4F,0xEB,0x3E,0xCC,0xD1,0x87,0x35,0xBD,0xF5, 0xB,
|
||||
0x5E,0xD0,0xF8,0xF2,0xD5,0xE2,0x6C,0x31, 0xC,0xAD,0xFC,0x21,0xC3,0x78,0xC1, 6,
|
||||
0xC2,0x4C,0x55,0xE6,0x4A,0x34,0x48,0x11,0x1E,0xDA,0xE7,0x1A,0x84,0xA0,0x96,0xA7,
|
||||
0xE3,0x7F,0xAF,0x63,0x9C,0xFA,0x23,0x5B,0x79,0xC8,0x9E,0xBA,0xB2,0xC9,0x22,0x12,
|
||||
0x4B,0xB3,0xA1,0xB6,0x32,0x49,0xA2,0xE1,0x89,0x39,0x10,0x66,0xC5, 7,0x8F,0x54,
|
||||
0xEA,0x91,0xCA,0x3F,0xF9,0x19,0xF0,0xD7,0x46,0xBC,0x28,0x1B,0x61,0xE8,0x2F,0x6A,
|
||||
0xAE,0x9D,0xF6,0x4E, 9,0x14,0x77,0x4D,0xDB,0x1F,0x2E,0x7B,0x7C,0xF1,0x43,0xA3,
|
||||
0,0xB8,0x13,0x8C,0x85,0xB9,0x29,0x75,0x88,0xFD,0xD2,0x56,0x1C,0x50,0x97,0x41,
|
||||
0xE5,0x3B,0x60,0xB5,0xC0,0x64,0xEE,0x98,0xD6,0x2D,0x25,0xA4,0xAA,0xCD,0x7D,0xA8,
|
||||
0x83,0xC6,0xAB,0xBE,0x44,0x99,0x26,0x3C,0xCE,0x9F,0xBF,0xD3,0xCB,0x76,0x7A,0x7E,
|
||||
0x82, 1,0x8A,0x9A,0x80,0x1D, 0xE,0xB0,0x5C,0xD4,0x38,0x62,0xF4,0x30,0xE0,0x8E,
|
||||
0x53,0xB7, 2,0x57,0xAC,0xA6,0x52, 0xA,0x6D,0x92,0x65,0x17,0x24,0x33,0x45,0x72,
|
||||
0x74,0xB1,0xB4,0xF7,0x5D,0xED,0x2C,0xFF,0x47,0x37,0x5A,0x90,0xBB,0xDF,0x2A,0x16,
|
||||
0x59,0x95,0xD9,0xC4,0x27,0x67,0x73,0xC7,0x68,0xFE,0xA5,0xDD,0x6B,0x5F,0x93,0xD8,
|
||||
0xEC, 5,0x3A,0x8D,0x6E,0xFB,0x3D,0xA9,0x69,0x36,0xF3,0x94,0xDE,0xEF,0x15,0x6F,
|
||||
0x8B,0x9B, 8, 0xF,0xDC,0x81,0x18,0x20, 4,0xE4,0x71,0xCF,0xE9,0x2B,0x42,0x58,
|
||||
};
|
||||
|
||||
u8 sboxes[8][256] = {
|
||||
{
|
||||
1,0xA0,0xA9,0x62,0xD6,0x3F,0x85,0xA7,0xB6,0xD4,0xFA,0x15,0x66,0x17, 9,0xBD,
|
||||
0x5D,0x14,0x34,0x26,0x59,0x72,0x91,0x54, 6,0x4F,0xF8,0xB0,0x5B,0x74,0x93,0x99,
|
||||
0x8C,0xF2,0x45,0xCD,0xEA,0x4E,0xAD,0x10,0x4A,0xE5,0xCA,0xEE,0xDF,0xC6,0x6F,0x9F,
|
||||
0x88,0x8E, 2,0xCC, 8,0xA8,0x77,0x94,0x6D,0x21,0xB1,0x28,0xE4,0x39,0x79,0x96,
|
||||
0x60,0x71,0x81,0x16,0x2E,0xE6,0x78,0xB9,0xC4,0x46,0x9A,0x42,0xAE,0xB7,0x7C,0x43,
|
||||
0xB3,0x22,0x1A,0x86,0xC2,0x32,0x3D,0x2D,0x9C,0xD2,0x29,0xE9,0x63,0x9B,0xD1,0x31,
|
||||
0x38,0x5E,0x1E,0x36,0x41,0xBB, 3,0x18,0x2B,0x3E,0xBF,0x68,0x61,0xFC,0x52,0xC0,
|
||||
0xDE,0xE0, 0xA,0x58,0x13,0x5A, 0,0xBE,0x1C,0x90, 0xE,0x53,0x12,0xFD,0xE2,0x6E,
|
||||
0xBA,0xCE,0x24,0x27,0x44,0x7F,0x87,0xA3,0xA1,0xD5,0x50,0x40,0xE3,0xF9,0x83,0xF7,
|
||||
0xC7,0xA2,0x35,0xC8,0xDB,0x19,0xAB,0x2F,0x11,0x25,0xED,0x33,0x9E,0x55,0xE1,0x48,
|
||||
0xAF,0x73,0x84,0xDA,0x2A,0xAA,0x51,0xEB,0x9D,0x95,0xB2,0xCB,0xE7,0x70,0x80,0xFE,
|
||||
0x4C,0x65, 4,0xEF,0xC5,0xF1,0xC3,0x3A,0xB4,0xF5,0x5F,0x23,0x89,0xDD,0x30,0xA5,
|
||||
0x8B,0xD3,0xF6,0xDC,0x4D,0x64,0xD7,0xF0,0x8F,0xEC,0x56,0x37,0x5C,0xA4, 0xD, 7,
|
||||
0x76,0x8A,0x2C, 0xB,0xB5,0xD8,0xC1,0x1F,0xE8,0x3B,0xF4,0x4B,0x1B,0x47,0x6C,0x49,
|
||||
0x67,0x7B,0x92,0xCF,0x75,0x7E,0x20,0xD9,0x7D,0x3C,0x97,0x7A,0xD0, 5,0x6B, 0xF,
|
||||
0x1D,0xFB,0x82,0x98,0x57,0x8D,0xF3,0x6A,0xBC,0xAC,0xC9,0xA6,0xFF,0xB8,0x69, 0xC,
|
||||
},
|
||||
{
|
||||
0x4C,0x4D,0x72, 7,0x5A,0x49,0x33,0x8D,0xA2,0xAB,0x46,0x3D,0x63, 0xD,0xA0,0x97,
|
||||
0xFF,0xF0,0xF5,0xFA,0xC0,0xE9,0xDB,0x62,0xE4,0xE1,0x74,0x43,0xDC,0x86,0x18,0x29,
|
||||
0x37,0xF4, 6,0xE2,0xED,0x6F,0x90,0x48,0x1E,0x2D,0x1D,0xEA,0x73,0x94,0x54,0xDF,
|
||||
0x25,0xF6,0x47,0x27,0xD9,0x11,0x77,0xC9,0x84,0x1C,0x5B,0x5C,0x51,0x81,0xA6,0x22,
|
||||
0x3E,0x24,0x96,0xC8,0x8A,0xEC,0x82,0x7C, 9,0xB8,0x45,0x4A,0x57,0xBB,0x2F,0x50,
|
||||
0x75,0x8E,0x61,0x70,0x8C,0x6C,0xAF,0xD0,0xFD,0xB4,0x1B,0xAE,0xDE,0xFE,0x3B,0xB5,
|
||||
0x36,0xBD,0x55, 1, 0xE,0x9C,0x41,0x56,0x5F,0xB3,0x26, 3,0x83,0xBA,0x13,0x4B,
|
||||
0xCA,0xC5, 0xA,0xF8,0x60,0xA5,0xB9,0xC7,0xC3,0x98,0x32,0xFB,0x12,0xF9,0xA7,0x92,
|
||||
0xAA,0x68,0xF3,0x78,0x7E, 5,0x20,0x21, 2,0xE8,0xBF,0xF2,0xB0,0x59,0x8F,0xD2,
|
||||
0xCB,0x87,0x65,0x15,0xF1,0x1A,0xB2,0x30,0xAD,0xEE,0x58,0xA3,0x8B,0x66,0x1F,0x2C,
|
||||
0xD7,0x5D,0x19,0x85,0xA8,0xE6,0xD3,0x6B,0xA1, 0xC,0x91,0x93,0x6A,0x5E, 0xB,0x79,
|
||||
0xE3,0xDD, 0,0x4F,0x3C,0x89,0x6E,0x71,0x69,0xA9,0xAC,0x40,0xE5,0x99,0x28,0xC6,
|
||||
0x31,0x4E,0x7A,0xCD, 8,0x9E,0x7D,0xEF,0x17,0xFC,0x88,0xD8,0xA4,0x6D,0x44,0x95,
|
||||
0xD1,0xB7,0xD4,0x9B,0xBE,0x2A,0x34,0x64,0x2B,0xCF,0x2E,0xEB,0x38,0xCE,0x23,0xE0,
|
||||
0x3A,0x3F,0xF7,0x7B,0x9F,0x10,0x53,0xBC,0x52,0x67,0x16,0xE7,0x80,0x76, 4,0xC4,
|
||||
0xB6,0xC1,0xC2,0x7F,0x9A,0xDA,0xD5,0x39,0x42,0x14,0x9D,0xB1, 0xF,0x35,0xD6,0xCC,
|
||||
},
|
||||
{
|
||||
0xB9,0xDA,0x38, 0xC,0xA2,0x9C, 9,0x1F, 6,0xB1,0xB6,0xFD,0x1A,0x69,0x23,0x30,
|
||||
0xC4,0xDE, 1,0xD1,0xF4,0x58,0x29,0x37,0x1C,0x7D,0xD5,0xBF,0xFF,0xBD,0xC8,0xC9,
|
||||
0xCF,0x65,0xBE,0x7B,0x78,0x97,0x98,0x67, 8,0xB3,0x26,0x57,0xF7,0xFA,0x40,0xAD,
|
||||
0x8E,0x75,0xA6,0x7C,0xDB,0x91,0x8B,0x51,0x99,0xD4,0x17,0x7A,0x90,0x8D,0xCE,0x63,
|
||||
0xCB,0x4E,0xA0,0xAB,0x18,0x3A,0x5B,0x50,0x7F,0x21,0x74,0xC1,0xBB,0xB8,0xB7,0xBA,
|
||||
0xB,0x35,0x95,0x31,0x59,0x9A,0x4D, 4, 7,0x1E,0x5A,0x76,0x13,0xF3,0x71,0x83,
|
||||
0xD0,0x86, 3,0xA8,0x39,0x42,0xAA,0x28,0xE6,0xE4,0xD8,0x5D,0xD3,0xD0,0x6E,0x6F,
|
||||
0x96,0xFB,0x5E,0xBC,0x56,0xC2,0x5F,0x85,0x9B,0xE7,0xAF,0xD2,0x3B,0x84,0x6A,0xA7,
|
||||
0x53,0xC5,0x44,0x49,0xA5,0xF9,0x36,0x72,0x3D,0x2C,0xD9,0x1B,0xA1,0xF5,0x4F,0x93,
|
||||
0x9D,0x68,0x47,0x41,0x16,0xCA,0x2A,0x4C,0xA3,0x87,0xD6,0xE5,0x19,0x2E,0x77,0x15,
|
||||
0x6D,0x70,0xC0,0xDF,0xB2, 0,0x46,0xED,0xC6,0x6C,0x43,0x60,0x92,0x2D,0xA9,0x22,
|
||||
0x45,0x8F,0x34,0x55,0xAE,0xA4, 0xA,0x66,0x32,0xE0,0xDC, 2,0xAC,0xE8,0x20,0x8C,
|
||||
0x89,0x62,0x4A,0xFE,0xEE,0xC3,0xE3,0x3C,0xF1,0x79, 5,0xE9,0xF6,0x27,0x33,0xCC,
|
||||
0xF2,0x9E,0x11,0x81,0x7E,0x80,0x10,0x8A,0x82,0x9F,0x48, 0xD,0xD7,0xB4,0xFC,0x2F,
|
||||
0xB5,0xC7,0xDD,0x88,0x14,0x6B,0x2B,0x54,0xEA,0x1D,0x94,0x5C,0xB0,0xEF,0x12,0x24,
|
||||
0xCD,0xEB,0xE1,0xE2,0x64,0x73,0x3F, 0xE,0x52,0x61,0x25,0x3E,0xF8, 0xF,0x4B,0xEC,
|
||||
},
|
||||
{
|
||||
0xC0, 0,0x30,0xF6, 2,0x49,0x3D,0x10,0x6E,0x20,0xC9,0xA6,0x2F,0xFE,0x2C,0x2B,
|
||||
0x75,0x2E,0x45,0x26,0xAB,0x48,0xA9,0x80,0xFC, 4,0xCC,0xD3,0xB5,0xBA,0xA3,0x38,
|
||||
0x31,0x7D, 1,0xD9,0xA7,0x7B,0x96,0xB6,0x63,0x69,0x4E,0xF7,0xDE,0xE0,0x78,0xCA,
|
||||
0x50,0xAA,0x41,0x91,0x65,0x88,0xE4,0x21,0x85,0xDA,0x3A,0x27,0xBE,0x1C,0x3E,0x42,
|
||||
0x5E,0x17,0x52,0x7F,0x1F,0x89,0x24,0x6F,0x8F,0x5C,0x67,0x74, 0xE,0x12,0x87,0x8D,
|
||||
0xE9,0x34,0xED,0x73,0xC4,0xF8,0x61,0x5B, 5,0xDF,0x59,0x4C,0x97,0x79,0x83,0x18,
|
||||
0xA4,0x55,0x95,0xEB,0xBD,0x53,0xF5,0xF1,0x57,0x66,0x46,0x9F,0xB2,0x81, 9,0x51,
|
||||
0x86,0x22,0x16,0xDD,0x23,0x93,0x76,0x29,0xC2,0xD7,0x1D,0xD4,0xBF,0x36,0x3F,0xEA,
|
||||
0x4B,0x11,0x32,0xB9,0x62,0x54,0x60,0xD6,0x6D,0x43,0x9A, 0xD,0x92,0x9C,0xB0,0xEF,
|
||||
0x58,0x6C,0x9D,0x77,0x2D,0x70,0xFA,0xF3,0xB3, 0xB,0xE2,0x40,0x7E,0xF4,0x8A,0xE5,
|
||||
0x8C,0x3C,0x56,0x71,0xD1,0x64,0xE1,0x82, 0xA,0xCB,0x13,0x15,0x90,0xEC, 3,0x99,
|
||||
0xAF,0x14,0x5D, 0xF,0x33,0x4A,0x94,0xA5,0xA8,0x35,0x1B,0xE3,0x6A,0xC6,0x28,0xFF,
|
||||
0x4D,0xE7,0x25,0x84,0xAC, 8,0xAE,0xC5,0xA2,0x2A,0xB8,0x37, 0xC,0x7A,0xA0,0xC3,
|
||||
0xCE,0xAD, 6,0x1A,0x9E,0x8B,0xFB,0xD5,0xD0,0xC1,0x1E,0xD0,0xB4,0x9B,0xB1,0x44,
|
||||
0xF2,0x47,0xC7,0x68,0xCF,0x72,0xBB,0x4F,0x5A,0xF9,0xDC,0x6B,0xDB,0xD2,0xE8,0x7C,
|
||||
0xC8,0xEE,0x98,0xA1,0xE6,0xD8,0x39, 7,0x5F,0xFD,0x8E,0x19,0xB7,0x3B,0xBC,0xCD,
|
||||
},
|
||||
{
|
||||
0x7C,0xE3,0x81,0x73,0xB2,0x11,0xBF,0x6F,0x20,0x98,0xFE,0x75,0x96,0xEF,0x6C,0xDA,
|
||||
0x50,0xE1, 9,0x72,0x54,0x45,0xBA,0x34,0x80,0x5B,0xED,0x3E,0x53,0x2C,0x87,0xA4,
|
||||
0x57,0xF3,0x33,0x3F,0x3C,0xB7,0x67,0xB4,0xA3,0x25,0x60,0x4F, 7,0x6B,0x1B,0x47,
|
||||
0x15, 0xF,0xE4, 0xA,0xEA,0xD1,0x32,0x78,0x36,0x49,0x8D,0x4B,0xD2,0xBC,0xA5,0xDC,
|
||||
0x1D, 0xD,0x4D,0xCD,0x9A,0x82,0x5F,0xFC,0x94,0x65,0xBE,0xE2,0xF4,0xC9,0x1E,0x44,
|
||||
0xCB,0x9E, 0xC,0x64,0x71,0x26,0x63,0xB3,0x14,0xE8,0x40,0x70,0x8A, 0xE,0x19,0x42,
|
||||
0x6D,0xAC,0x88,0x10,0x5C,0xDF,0x41,0xA9,0xAD,0xE5,0xFB,0x74,0xCC,0xD5, 6,0x8E,
|
||||
0x59,0x86,0xCE,0x1F,0x3D,0x76,0xE0,0x8F,0xB9,0x77,0x27,0x7B,0xA6,0xD8,0x29,0xD3,
|
||||
0xEC,0xB8,0x13,0xF7,0xFA,0xC3,0x51,0x6A,0xDE,0x4A,0x5A,0xEB,0xC2,0x8B,0x23,0x48,
|
||||
0x92,0xCF,0x62,0xA8,0x99,0xF8,0xD0,0x2E,0x85,0x61,0x43,0xC8,0xBD,0xF0, 5,0x93,
|
||||
0xCA,0x4E,0xF1,0x7D,0x30,0xFD,0xC4,0x69,0x66,0x2F, 8,0xB1,0x52,0xF9,0x21,0xE6,
|
||||
0x7A,0x2B,0xDD,0x39,0x84,0xFF,0xC0,0x91,0xD6,0x37,0xD4,0x7F,0x2D,0x9B,0x5D,0xA1,
|
||||
0x3B,0x6E,0xB5,0xC5,0x46, 4,0xF5,0x90,0xEE,0x7E,0x83,0x1C, 3,0x56,0xB6,0xAA,
|
||||
0,0x17, 1,0x35,0x55,0x79, 0xB,0x12,0xBB,0x1A,0x31,0xE7, 2,0x28,0x16,0xC1,
|
||||
0xF6,0xA2,0xDB,0x18,0x9C,0x89,0x68,0x38,0x97,0xAB,0xC7,0x2A,0xD7,0x3A,0xF2,0xC6,
|
||||
0x24,0x4C,0xB0,0x58,0xA0,0x22,0x5E,0x9D,0xD9,0xA7,0xE9,0xAE,0xAF,0x8C,0x95,0x9F,
|
||||
},
|
||||
{
|
||||
0x28,0xB7,0x20,0xD7,0xB0,0x30,0xC3, 9,0x19,0xC0,0x67,0xD6, 0,0x3C,0x7E,0xE7,
|
||||
0xE9,0xF4, 8,0x5A,0xF8,0xB8,0x2E, 5,0xA6,0x25,0x9E,0x5C,0xD8,0x15, 0xD,0xE1,
|
||||
0xF6,0x11,0x54,0x6B,0xCD,0x21,0x46,0x66,0x5E,0x84,0xAD, 6,0x38,0x29,0x44,0xC5,
|
||||
0xA2,0xCE,0xF1,0xAA,0xC1,0x40,0x71,0x86,0xB5,0xEF,0xFC,0x36,0xA8,0xCB, 0xA,0x48,
|
||||
0x27,0x45,0x64,0xA3,0xAF,0x8C,0xB2,0xC6,0x9F, 7,0x89,0xDC,0x17,0xD3,0x49,0x79,
|
||||
0xFB,0xFE,0x1D,0xD0,0xB9,0x88,0x43,0x52,0xBC, 1,0x78,0x2B,0x7D,0x94,0xC7, 0xE,
|
||||
0xDE,0xA5,0xD5,0x9B,0xCC,0xF7,0x61,0x7A,0xC2,0x74,0x81,0x39, 3,0xAB,0x96,0xA0,
|
||||
0x37,0xBD,0x2D,0x72,0x75,0x3F,0xC9,0xD4,0x8E,0x6F,0xF9,0x8D,0xED,0x62,0xDB,0x1C,
|
||||
0xDF, 4,0xAC,0x1B,0x6C,0x14,0x4B,0x63,0xD0,0xBF,0xB4,0x82,0xEC,0x7B,0x1A,0x59,
|
||||
0x92,0xD2,0x10,0x60,0xB6,0x3D,0x5F,0xE6,0x80,0x6E,0x70,0xC4,0xF2,0x35,0xD9,0x7C,
|
||||
0xEE,0xE5,0x41,0xA4,0x5B,0x50,0xDD,0xBB,0x4C,0xF3,0x1F,0x9D,0x5D,0x57,0x55,0x51,
|
||||
0x97,0xE3,0x58,0x42,0x4D,0x9C,0x73,0xBA,0xC8,0x77,0x31,0x69,0x26,0xAE,0xEA,0x8A,
|
||||
0xDA,0x22,0xB3,0x87,0x56,0xFA,0x93, 0xB,0x34,0x16,0x33,0xE8,0xE4,0x53,0xBE,0xA9,
|
||||
0xB1,0x3A,0x3E,0xF5,0x90,0x6A,0xCF,0x3B,0x12,0xFD,0x8F,0x9A,0xA7,0x47,0x91,0x99,
|
||||
0xEB, 0xF,0x24,0xFF,0x23,0x18,0x85,0x4E,0x7F, 0xC,0xE0,0xA1,0xD2,0xD1,0x2C,0x2A,
|
||||
0x4A, 2,0x4F,0x1E,0x95,0x68,0x8B,0x98,0x83,0x6D,0x76,0xCA,0x65,0x32,0x13,0x2F,
|
||||
},
|
||||
{
|
||||
0xC3,0x82,0x9A,0xA4,0xBA,0x81,0x60,0x37,0x34,0x35,0xFC,0x80,0xA8,0x51,0x65,0x67,
|
||||
0xED,0x30,0x5F,0x10,0xD3,0x4A,0x27,0x2F,0x13,0xB9,0x2A,0xD2,0xCC,0xE1,0xEF,0xAE,
|
||||
0xEB,0xBE,0xF4,0xBD,0xCF,0x43,0xB3,0xC5,0x88,0x84,0xB7,0xDD,0x39,0x40,0xCE,0x48,
|
||||
0x6D,0x9B,0x72,0x61,0x7E,0xE7,0xA1,0x4E,0x53,0x2E,0x77,0x3B,0xE2,0xC9,0x36,0x22,
|
||||
0x1B,0x6E,0x73,0xB1, 3,0xB2,0x4C,0x87,0xA9,0xD4,0x4D, 0xF,0xD8,0x15,0x6C,0xAA,
|
||||
0x18,0xF6,0x49,0x57,0x5D,0xFB,0x7A,0x14,0x94,0x63,0xA0,0x11,0xB0,0x9E,0xDE, 5,
|
||||
0x46,0xC8,0xEE,0x47,0xDB,0xDC,0x24,0x89,0x9C,0x91,0x97,0x29,0xE9,0x7B,0xC1, 7,
|
||||
0x1E,0xB8,0xFD,0xFE,0xAC,0xC6,0x62,0x98,0x4F,0xF1,0x79,0xE0,0xE8,0x6B,0x78,0x56,
|
||||
0xB6,0x8D, 4,0x50,0x86,0xCA,0x6F,0x20,0xE6,0xEA,0xE5,0x76,0x17,0x1C,0x74,0x7F,
|
||||
0xBC, 0xD,0x2C,0x85,0xF7,0x66,0x96,0xE4,0x8B,0x75,0x3F,0x4B,0xD9,0x38,0xAF,0x7C,
|
||||
0xDA, 0xB,0x83,0x2D,0x31,0x32,0xA2,0xF5,0x1D,0x59,0x41,0x45,0xBF,0x3C,0x1F,0xF8,
|
||||
0xF9,0x8A,0xD0,0x16,0x25,0x69,0x12,0x99,0x9D,0x21,0x95,0xAB, 1,0xA6,0xD7,0xB5,
|
||||
0xC0,0x7D,0xFF,0x58, 0xE,0x3A,0x92,0xD1,0x55,0xE3, 8,0x9F,0xD6,0x3E,0x52,0x8E,
|
||||
0xFA,0xA3,0xC7, 2,0xCD,0xDF,0x8F,0x64,0x19,0x8C,0xF3,0xA7, 0xC,0x5E, 0xA,0x6A,
|
||||
9,0xF0,0x93,0x5B,0x42,0xC2, 6,0x23,0xEC,0x71,0xAD,0xB4,0xCB,0xBB,0x70,0x28,
|
||||
0xD5,0x1A,0x5C,0x33,0x68,0x5A, 0,0x44,0x90,0xA5,0xC4,0x26,0x3D,0x2B,0xF2,0x54,
|
||||
},
|
||||
{
|
||||
0x96,0xAD,0xDA,0x1F,0xED,0x33,0xE1,0x81,0x69, 8, 0xD, 0xA,0xDB,0x35,0x77,0x9A,
|
||||
0x64,0xD1,0xFC,0x78,0xAA,0x1B,0xD0,0x67,0xA0,0xDD,0xFA,0x6C,0x63,0x71, 5,0x84,
|
||||
0x17,0x6A,0x89,0x4F,0x66,0x7F,0xC6,0x50,0x55,0x92,0x6F,0xBD,0xE7,0xD2,0x40,0x72,
|
||||
0x8D,0xBB,0xEC, 6,0x42,0x8A,0xE4,0x88,0x9D,0x7E,0x7A,0x82,0x27,0x13,0x41,0x1A,
|
||||
0xAF,0xC8,0xA4,0x76,0xB4,0xC2,0xFE,0x6D,0x1C,0xD9,0x61,0x30,0xB3,0x7C,0xEA,0xF7,
|
||||
0x29, 0xF,0xF2,0x3B,0x51,0xC1,0xDE,0x5F,0xE5,0x2A,0x2F,0x99, 0xB,0x5D,0xA3,0x2B,
|
||||
0x4A,0xAB,0x95,0xA5,0xD3,0x58,0x56,0xEE,0x28,0x31, 0,0xCC,0x15,0x46,0xCA,0xE6,
|
||||
0x86,0x38,0x3C,0x65,0xF5,0xE3,0x9F,0xD6,0x5B, 9,0x49,0x83,0x70,0x2D,0x53,0xA9,
|
||||
0x7D,0xE2,0xC4,0xAC,0x8E,0x5E,0xB8,0x25,0xF4,0xB9,0x57,0xF3,0xF1,0x68,0x47,0xB2,
|
||||
0xA2,0x59,0x20,0xCE,0x34,0x79,0x5C,0x90, 0xE,0x1E,0xBE,0xD5,0x22,0x23,0xB1,0xC9,
|
||||
0x18,0x62,0x16,0x2E,0x91,0x3E, 7,0x8F,0xD8,0x3F,0x93,0x3D,0xD4,0x9B,0xDF,0x85,
|
||||
0x21,0xFB,0x11,0x74,0x97,0xC7,0xD7,0xDC,0x4C,0x19,0x45,0x98,0xE9,0x43, 2,0x4B,
|
||||
0xBC,0xC3, 4,0x9C,0x6B,0xF0,0x75,0x52,0xA7,0x26,0xF6,0xC5,0xBA,0xCF,0xB0,0xB7,
|
||||
0xAE,0x5A,0xA1,0xBF, 3,0x8B,0x80,0x12,0x6E, 0xC,0xEB,0xF9,0xC0,0x44,0x24,0xEF,
|
||||
0x10,0xF8,0xA8,0x8C,0xE8,0x7B,0xFF,0x9E,0x2C,0xCD,0x60,0x36,0x87,0xB5,0x94,0xA6,
|
||||
0x54,0x73,0x3A,0x14,0x4E, 1,0x1D,0xB6,0xFD,0x37,0x48,0x4D,0x39,0xCB,0xE0,0x32,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static inline u8 ror8(u8 a, u8 b) {
|
||||
return (a>>b) | ((a<<(8-b))&0xff);
|
||||
}
|
||||
|
||||
|
||||
void genkey(u8 *rand, u8 idx, u8 *key)
|
||||
{
|
||||
u8 *ans = ans_tbl[idx];
|
||||
u8 t0[10];
|
||||
int i;
|
||||
|
||||
for(i=0;i<10;i++)
|
||||
t0[i] = tsbox[rand[i]];
|
||||
|
||||
key[0] = ((ror8((ans[0]^t0[5]),(t0[2]%8)) - t0[9]) ^ t0[4]);
|
||||
key[1] = ((ror8((ans[1]^t0[1]),(t0[0]%8)) - t0[5]) ^ t0[7]);
|
||||
key[2] = ((ror8((ans[2]^t0[6]),(t0[8]%8)) - t0[2]) ^ t0[0]);
|
||||
key[3] = ((ror8((ans[3]^t0[4]),(t0[7]%8)) - t0[3]) ^ t0[2]);
|
||||
key[4] = ((ror8((ans[4]^t0[1]),(t0[6]%8)) - t0[3]) ^ t0[4]);
|
||||
key[5] = ((ror8((ans[5]^t0[7]),(t0[8]%8)) - t0[5]) ^ t0[9]);
|
||||
}
|
||||
|
||||
|
||||
void gentabs(u8 *rand, u8 *key, u8 idx, u8 *ft, u8 *sb)
|
||||
{
|
||||
ft[0] = sboxes[idx][key[4]] ^ sboxes[(idx+1)%8][rand[3]];
|
||||
ft[1] = sboxes[idx][key[2]] ^ sboxes[(idx+1)%8][rand[5]];
|
||||
ft[2] = sboxes[idx][key[5]] ^ sboxes[(idx+1)%8][rand[7]];
|
||||
ft[3] = sboxes[idx][key[0]] ^ sboxes[(idx+1)%8][rand[2]];
|
||||
ft[4] = sboxes[idx][key[1]] ^ sboxes[(idx+1)%8][rand[4]];
|
||||
ft[5] = sboxes[idx][key[3]] ^ sboxes[(idx+1)%8][rand[9]];
|
||||
ft[6] = sboxes[idx][rand[0]] ^ sboxes[(idx+1)%8][rand[6]];
|
||||
ft[7] = sboxes[idx][rand[1]] ^ sboxes[(idx+1)%8][rand[8]];
|
||||
|
||||
sb[0] = sboxes[idx][key[0]] ^ sboxes[(idx+1)%8][rand[1]];
|
||||
sb[1] = sboxes[idx][key[5]] ^ sboxes[(idx+1)%8][rand[4]];
|
||||
sb[2] = sboxes[idx][key[3]] ^ sboxes[(idx+1)%8][rand[0]];
|
||||
sb[3] = sboxes[idx][key[2]] ^ sboxes[(idx+1)%8][rand[9]];
|
||||
sb[4] = sboxes[idx][key[4]] ^ sboxes[(idx+1)%8][rand[7]];
|
||||
sb[5] = sboxes[idx][key[1]] ^ sboxes[(idx+1)%8][rand[8]];
|
||||
sb[6] = sboxes[idx][rand[3]] ^ sboxes[(idx+1)%8][rand[5]];
|
||||
sb[7] = sboxes[idx][rand[2]] ^ sboxes[(idx+1)%8][rand[6]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Generate key from the 0x40-0x4c data in g_RegExt */
|
||||
void wiimote_gen_key(wiimote_key *key, u8 *keydata)
|
||||
{
|
||||
u8 rand[10];
|
||||
u8 skey[6];
|
||||
u8 testkey[6];
|
||||
int idx;
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
rand[9-i] = keydata[i];
|
||||
for(int i=0;i<6;i++)
|
||||
skey[5-i] = keydata[i+10];
|
||||
|
||||
//DEBUG_LOG(WIIMOTE, "rand: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", rand[0], rand[1], rand[2], rand[3], rand[4], rand[5], rand[6], rand[7], rand[8], rand[9]);
|
||||
//DEBUG_LOG(WIIMOTE, "key: %02x %02x %02x %02x %02x %02x", skey[0], skey[1], skey[2], skey[3], skey[4], skey[5]);
|
||||
|
||||
for(idx = 0; idx < 7; idx++)
|
||||
{
|
||||
genkey(rand, idx, testkey);
|
||||
if(!memcmp(testkey, skey, 6))
|
||||
break;
|
||||
}
|
||||
// default case is idx = 7 which is valid (homebrew uses it for the 0x17 case)
|
||||
//DEBUG_LOG(WIIMOTE, "idx: %d", idx);
|
||||
|
||||
gentabs(rand, skey, idx, key->ft, key->sb);
|
||||
|
||||
//DEBUG_LOG(WIIMOTE, "ft: %02x %02x %02x %02x %02x %02x %02x %02x", key->ft[0], key->ft[1], key->ft[2], key->ft[3], key->ft[4], key->ft[5], key->ft[6], key->ft[7]);
|
||||
//DEBUG_LOG(WIIMOTE, "sb: %02x %02x %02x %02x %02x %02x %02x %02x", key->sb[0], key->sb[1], key->sb[2], key->sb[3], key->sb[4], key->sb[5], key->sb[6], key->sb[7]);
|
||||
|
||||
// for homebrew, ft and sb are all 0x97 which is equivalent to 0x17
|
||||
}
|
||||
|
||||
|
||||
/* Encrypt data */
|
||||
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
||||
{
|
||||
for(int i = 0; i < len; i++, addr++)
|
||||
data[i] = (data[i] - key->ft[addr%8]) ^ key->sb[addr%8];
|
||||
}
|
||||
|
||||
|
||||
/* Decrypt data */
|
||||
void wiimote_decrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
||||
{
|
||||
for(int i = 0; i < len; i++, addr++)
|
||||
data[i] = (data[i] ^ key->sb[addr%8]) + key->ft[addr%8];
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2003 Dolphin Project.
|
||||
// Copyright (C) Hector Martin "marcan" (hector@marcansoft.com)
|
||||
|
||||
// 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/
|
||||
|
||||
|
||||
#ifndef WIIMOTE_EXTENSION_ENCRYPTION_H
|
||||
#define WIIMOTE_EXTENSION_ENCRYPTION_H
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* They key structure to use with wiimote_gen_key() */
|
||||
// ----------------
|
||||
struct wiimote_key
|
||||
{
|
||||
u8 ft[8];
|
||||
u8 sb[8];
|
||||
};
|
||||
|
||||
|
||||
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len);
|
||||
void wiimote_decrypt(wiimote_key *key, u8 *data, int addr, u8 len);
|
||||
|
||||
void wiimote_gen_key(wiimote_key *key, u8 *keydata);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,492 @@
|
|||
|
||||
#include "Attachment/Classic.h"
|
||||
#include "Attachment/Nunchuk.h"
|
||||
|
||||
#include "WiimoteEmu.h"
|
||||
#include "WiimoteHid.h"
|
||||
|
||||
#include <Timer.h>
|
||||
#include <Common.h>
|
||||
|
||||
// buttons
|
||||
|
||||
#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
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
/* An example of a factory default first bytes of the Eeprom memory. There are differences between
|
||||
different Wiimotes, my Wiimote had different neutral values for the accelerometer. */
|
||||
static const u8 eeprom_data_0[] = {
|
||||
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3,
|
||||
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30, 0xA7, 0x74, 0xD3,
|
||||
// Accelerometer neutral values
|
||||
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E,
|
||||
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E
|
||||
};
|
||||
static const u8 eeprom_data_16D0[] = {
|
||||
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
|
||||
0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99,
|
||||
0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13
|
||||
};
|
||||
|
||||
// array of accel data to emulate shaking
|
||||
static const u8 shake_data[8] = { 0x80, 0x40, 0x01, 0x40, 0x80, 0xC0, 0xFF, 0xC0 };
|
||||
|
||||
const u16 button_bitmasks[] =
|
||||
{
|
||||
WIIMOTE_A, WIIMOTE_B, WIIMOTE_ONE, WIIMOTE_TWO, WIIMOTE_MINUS, WIIMOTE_PLUS, WIIMOTE_HOME
|
||||
};
|
||||
|
||||
const u16 dpad_bitmasks[] =
|
||||
{
|
||||
WIIMOTE_PAD_UP, WIIMOTE_PAD_DOWN, WIIMOTE_PAD_LEFT, WIIMOTE_PAD_RIGHT
|
||||
};
|
||||
const u16 dpad_sideways_bitmasks[] =
|
||||
{
|
||||
WIIMOTE_PAD_RIGHT, WIIMOTE_PAD_LEFT, WIIMOTE_PAD_UP, WIIMOTE_PAD_DOWN
|
||||
};
|
||||
|
||||
const char* const named_buttons[] =
|
||||
{
|
||||
"A",
|
||||
"B",
|
||||
"One",
|
||||
"Two",
|
||||
"Minus",
|
||||
"Plus",
|
||||
"Home",
|
||||
};
|
||||
|
||||
void Wiimote::Reset()
|
||||
{
|
||||
m_reporting_mode = WM_REPORT_CORE;
|
||||
// i think these two are good
|
||||
m_reporting_channel = 0;
|
||||
m_reporting_auto = false;
|
||||
|
||||
// eeprom
|
||||
memset( m_eeprom, 0, sizeof(m_eeprom) );
|
||||
// calibration data
|
||||
memcpy( m_eeprom, eeprom_data_0, sizeof(eeprom_data_0) );
|
||||
// dunno what this is for, copied from old plugin
|
||||
memcpy( m_eeprom + 0x16D0, eeprom_data_16D0, sizeof(eeprom_data_16D0) );
|
||||
|
||||
// set up the register
|
||||
m_register.clear();
|
||||
m_register[0xa20000].resize(WIIMOTE_REG_SPEAKER_SIZE,0);
|
||||
m_register[0xa40000].resize(WIIMOTE_REG_EXT_SIZE,0);
|
||||
m_register[0xa60000].resize(WIIMOTE_REG_EXT_SIZE,0);
|
||||
m_register[0xB00000].resize(WIIMOTE_REG_IR_SIZE,0);
|
||||
|
||||
//m_reg_speaker = &m_register[0xa20000][0];
|
||||
m_reg_ext = &m_register[0xa40000][0];
|
||||
//m_reg_motion_plus = &m_register[0xa60000][0];
|
||||
//m_reg_ir = &m_register[0xB00000][0];
|
||||
|
||||
// status
|
||||
memset( &m_status, 0, sizeof(m_status) );
|
||||
// Battery levels in voltage
|
||||
// 0x00 - 0x32: level 1
|
||||
// 0x33 - 0x43: level 2
|
||||
// 0x33 - 0x54: level 3
|
||||
// 0x55 - 0xff: level 4
|
||||
m_status.battery = 0x5f;
|
||||
}
|
||||
|
||||
Wiimote::Wiimote( const unsigned int index, SWiimoteInitialize* const wiimote_initialize )
|
||||
: m_index(index)
|
||||
, m_wiimote_init( wiimote_initialize )
|
||||
{
|
||||
// reset eeprom/register/values to default
|
||||
Reset();
|
||||
|
||||
// ---- set up all the controls ----
|
||||
|
||||
// buttons
|
||||
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
||||
for ( unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i )
|
||||
m_buttons->controls.push_back( new ControlGroup::Input( named_buttons[i] ) );
|
||||
|
||||
// ir
|
||||
//groups.push_back( m_rumble = new ControlGroup( "IR" ) );
|
||||
//m_rumble->controls.push_back( new ControlGroup::Output( "X" ) );
|
||||
//m_rumble->controls.push_back( new ControlGroup::Output( "Y" ) );
|
||||
//m_rumble->controls.push_back( new ControlGroup::Output( "Distance" ) );
|
||||
//m_rumble->controls.push_back( new ControlGroup::Output( "Hide" ) );
|
||||
|
||||
// forces
|
||||
groups.push_back( m_tilt = new Tilt( "Pitch and Roll" ) );
|
||||
//groups.push_back( m_tilt = new Tilt( "Tilt" ) );
|
||||
//groups.push_back( m_swing = new Force( "Swing" ) );
|
||||
|
||||
// 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( "Y" ) );
|
||||
m_shake->controls.push_back( new ControlGroup::Input( "Z" ) );
|
||||
|
||||
// extension
|
||||
groups.push_back( m_extension = new Extension( "Extension" ) );
|
||||
m_extension->attachments.push_back( new WiimoteEmu::None() );
|
||||
m_extension->attachments.push_back( new WiimoteEmu::Nunchuk() );
|
||||
m_extension->attachments.push_back( new WiimoteEmu::Classic() );
|
||||
//m_extension->attachments.push_back( new Attachment::GH3() );
|
||||
|
||||
// dpad
|
||||
groups.push_back( m_dpad = new Buttons( "D-Pad" ) );
|
||||
for ( unsigned int i=0; i < 4; ++i )
|
||||
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) );
|
||||
|
||||
// rumble
|
||||
groups.push_back( m_rumble = new ControlGroup( "Rumble" ) );
|
||||
m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) );
|
||||
|
||||
// options
|
||||
groups.push_back( options = new ControlGroup( "Options" ) );
|
||||
options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||
options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) );
|
||||
}
|
||||
|
||||
std::string Wiimote::GetName() const
|
||||
{
|
||||
return std::string("Wiimote") + char('1'+m_index);
|
||||
}
|
||||
|
||||
void Wiimote::Update()
|
||||
{
|
||||
const bool is_sideways = options->settings[1]->value > 0;
|
||||
|
||||
// update buttons in status struct
|
||||
m_status.buttons = 0;
|
||||
m_buttons->GetState( &m_status.buttons, button_bitmasks );
|
||||
m_dpad->GetState( &m_status.buttons, is_sideways ? dpad_sideways_bitmasks : dpad_bitmasks );
|
||||
|
||||
if ( false == m_reporting_auto )
|
||||
return;
|
||||
|
||||
// handle extension switching
|
||||
if ( m_extension->active_extension != m_extension->switch_extension )
|
||||
{
|
||||
RequestStatus( m_reporting_channel, NULL );
|
||||
// games don't seem to like me sending the status report and the data report
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out what data we need
|
||||
size_t rpt_size = 0;
|
||||
size_t rpt_core = 0;
|
||||
size_t rpt_accel = 0;
|
||||
size_t rpt_ir = 0;
|
||||
size_t rpt_ext = 0;
|
||||
|
||||
switch ( m_reporting_mode )
|
||||
{
|
||||
//(a1) 30 BB BB
|
||||
case WM_REPORT_CORE :
|
||||
rpt_size = 2 + 2;
|
||||
rpt_core = 2;
|
||||
break;
|
||||
//(a1) 31 BB BB AA AA AA
|
||||
case WM_REPORT_CORE_ACCEL :
|
||||
rpt_size = 2 + 2 + 3;
|
||||
rpt_core = 2;
|
||||
rpt_accel = 2 + 2;
|
||||
break;
|
||||
//(a1) 33 BB BB AA AA AA II II II II II II II II II II II II
|
||||
case WM_REPORT_CORE_ACCEL_IR12 :
|
||||
rpt_size = 2 + 2 + 3 + 12;
|
||||
rpt_core = 2;
|
||||
rpt_accel = 2 + 2;
|
||||
rpt_ir = 2 + 2 + 3;
|
||||
break;
|
||||
//(a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
|
||||
case WM_REPORT_CORE_ACCEL_EXT16 :
|
||||
rpt_size = 2 + 2 + 3 + 16;
|
||||
rpt_core = 2;
|
||||
rpt_accel = 2 + 2;
|
||||
rpt_ext = 2 + 2 + 3;
|
||||
break;
|
||||
//(a1) 37 BB BB AA AA AA II II II II II II II II II II EE EE EE EE EE EE
|
||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6 :
|
||||
rpt_size = 2 + 2 + 3 + 10 + 6;
|
||||
rpt_core = 2;
|
||||
rpt_accel = 2 + 2;
|
||||
rpt_ir = 2 + 2 + 3;
|
||||
rpt_ext = 2 + 2 + 3 + 10;
|
||||
break;
|
||||
default :
|
||||
//PanicAlert( "Unsupported Reporting Mode" );
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
// set up output report
|
||||
u8* const rpt = new u8[rpt_size];
|
||||
memset( rpt, 0, rpt_size );
|
||||
|
||||
rpt[0] = 0xA1;
|
||||
rpt[1] = m_reporting_mode;
|
||||
|
||||
// core buttons - always 2
|
||||
if (rpt_core)
|
||||
*(wm_core*)(rpt + rpt_core) = m_status.buttons;
|
||||
|
||||
// accelerometer
|
||||
if (rpt_accel)
|
||||
{
|
||||
// tilt
|
||||
float x, y;
|
||||
m_tilt->GetState( &x, &y, 0, (PI / 2) ); // 90 degrees
|
||||
|
||||
// this isn't doing anything with those low bits in the calib data, o well
|
||||
|
||||
const accel_cal* const cal = (accel_cal*)&m_eeprom[0x16];
|
||||
const u8* const zero_g = &cal->zero_g.x;
|
||||
u8 one_g[3];
|
||||
for ( unsigned int i=0; i<3; ++i )
|
||||
one_g[i] = (&cal->one_g.x)[i] - zero_g[i];
|
||||
|
||||
// this math should be good enough :P
|
||||
rpt[rpt_accel + 2] = u8(sin( (PI / 2) - std::max( abs(x), abs(y) ) ) * one_g[2] + zero_g[2]);
|
||||
|
||||
if (is_sideways)
|
||||
{
|
||||
rpt[rpt_accel + 0] = u8(sin(y) * -one_g[1] + zero_g[1]);
|
||||
rpt[rpt_accel + 1] = u8(sin(x) * -one_g[0] + zero_g[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rpt[rpt_accel + 0] = u8(sin(x) * -one_g[0] + zero_g[0]);
|
||||
rpt[rpt_accel + 1] = u8(sin(y) * one_g[1] + zero_g[1]);
|
||||
}
|
||||
|
||||
// shake
|
||||
const unsigned int btns[] = { 0x01, 0x02, 0x04 };
|
||||
unsigned int shake = 0;
|
||||
m_shake->GetState( &shake, btns );
|
||||
static unsigned int shake_step = 0;
|
||||
if (shake)
|
||||
{
|
||||
shake_step = (shake_step + 1) % sizeof(shake_data);
|
||||
for ( unsigned int i=0; i<3; ++i )
|
||||
if ( shake & (1 << i) )
|
||||
rpt[rpt_accel + i] = shake_data[shake_step];
|
||||
}
|
||||
else
|
||||
shake_step = 0;
|
||||
}
|
||||
|
||||
// TODO: IR
|
||||
if (rpt_ir)
|
||||
{
|
||||
}
|
||||
|
||||
// extension
|
||||
if (rpt_ext)
|
||||
{
|
||||
// temporary
|
||||
m_extension->GetState(rpt + rpt_ext);
|
||||
wiimote_encrypt(&m_ext_key, rpt + rpt_ext, 0x00, sizeof(wm_extension));
|
||||
|
||||
// i dont think anything accesses the extension data like this, but ill support it
|
||||
memcpy( m_reg_ext + 8, rpt + rpt_ext, sizeof(wm_extension));
|
||||
}
|
||||
|
||||
// send input report
|
||||
m_wiimote_init->pWiimoteInput( m_index, m_reporting_channel, rpt, (u32)rpt_size );
|
||||
|
||||
delete[] rpt;
|
||||
}
|
||||
|
||||
void Wiimote::ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
|
||||
// Check for custom communication
|
||||
if (99 == _channelID)
|
||||
{
|
||||
// wiimote disconnected
|
||||
//PanicAlert( "Wiimote Disconnected" );
|
||||
|
||||
// reset eeprom/register/reporting mode
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
hid_packet* hidp = (hid_packet*)_pData;
|
||||
|
||||
INFO_LOG(WIIMOTE, "Emu ControlChannel (page: %i, type: 0x%02x, param: 0x%02x)", m_index, hidp->type, hidp->param);
|
||||
|
||||
switch(hidp->type)
|
||||
{
|
||||
case HID_TYPE_HANDSHAKE :
|
||||
PanicAlert("HID_TYPE_HANDSHAKE - %s", (hidp->param == HID_PARAM_INPUT) ? "INPUT" : "OUPUT");
|
||||
break;
|
||||
|
||||
case HID_TYPE_SET_REPORT :
|
||||
if (HID_PARAM_INPUT == hidp->param)
|
||||
{
|
||||
PanicAlert("HID_TYPE_SET_REPORT - INPUT");
|
||||
}
|
||||
else
|
||||
{
|
||||
// AyuanX: My experiment shows Control Channel is never used
|
||||
// shuffle2: but homebrew uses this, so we'll do what we must :)
|
||||
HidOutputReport(_channelID, (wm_report*)hidp->data);
|
||||
|
||||
u8 handshake = HID_HANDSHAKE_SUCCESS;
|
||||
m_wiimote_init->pWiimoteInput(m_index, _channelID, &handshake, 1);
|
||||
|
||||
PanicAlert("HID_TYPE_DATA - OUTPUT: Ambiguous Control Channel Report!");
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_TYPE_DATA :
|
||||
PanicAlert("HID_TYPE_DATA - %s", (hidp->param == HID_PARAM_INPUT) ? "INPUT" : "OUTPUT");
|
||||
break;
|
||||
|
||||
default :
|
||||
PanicAlert("HidControlChannel: Unknown type %x and param %x", hidp->type, hidp->param);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Wiimote::InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
hid_packet* hidp = (hid_packet*)_pData;
|
||||
|
||||
switch (hidp->type)
|
||||
{
|
||||
case HID_TYPE_DATA:
|
||||
switch (hidp->param)
|
||||
{
|
||||
case HID_PARAM_OUTPUT :
|
||||
{
|
||||
wm_report* sr = (wm_report*)hidp->data;
|
||||
HidOutputReport(_channelID, sr);
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
PanicAlert("HidInput: HID_TYPE_DATA - param 0x%02x", hidp->type, hidp->param);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlert("HidInput: Unknown type 0x%02x and param 0x%02x", hidp->type, hidp->param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: i need to test this
|
||||
void Wiimote::Register::Read( size_t address, void* dst, size_t length )
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
const std::vector<u8>* block = NULL;
|
||||
size_t addr_start = 0;
|
||||
size_t addr_end = address+length;
|
||||
|
||||
// TODO: don't need to start at begin() each time
|
||||
// find block and start of next block
|
||||
const_iterator
|
||||
i = begin(),
|
||||
e = end();
|
||||
for ( ; i!=e; ++i )
|
||||
if ( address >= i->first )
|
||||
{
|
||||
block = &i->second;
|
||||
addr_start = i->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_end = std::min( i->first, addr_end );
|
||||
break;
|
||||
}
|
||||
|
||||
// read bytes from a mapped block
|
||||
if (block)
|
||||
{
|
||||
const size_t offset = std::min( address - addr_start, block->size() );
|
||||
const size_t amt = std::min( block->size()-offset, length );
|
||||
|
||||
memcpy( dst, &block->operator[](offset), amt );
|
||||
|
||||
address += amt;
|
||||
dst = ((u8*)dst) + amt;
|
||||
length -= amt;
|
||||
}
|
||||
|
||||
// read zeros for unmapped regions
|
||||
const size_t amt = addr_end - address;
|
||||
|
||||
memset( dst, 0, amt );
|
||||
|
||||
address += amt;
|
||||
dst = ((u8*)dst) + amt;
|
||||
length -= amt;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: i need to test this
|
||||
void Wiimote::Register::Write( size_t address, void* src, size_t length )
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
std::vector<u8>* block = NULL;
|
||||
size_t addr_start = 0;
|
||||
size_t addr_end = address+length;
|
||||
|
||||
// TODO: don't need to start at begin() each time
|
||||
// find block and start of next block
|
||||
iterator
|
||||
i = begin(),
|
||||
e = end();
|
||||
for ( ; i!=e; ++i )
|
||||
if ( address >= i->first )
|
||||
{
|
||||
block = &i->second;
|
||||
addr_start = i->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_end = std::min( i->first, addr_end );
|
||||
break;
|
||||
}
|
||||
|
||||
// write bytes to a mapped block
|
||||
if (block)
|
||||
{
|
||||
const size_t offset = std::min( address - addr_start, block->size() );
|
||||
const size_t amt = std::min( block->size()-offset, length );
|
||||
|
||||
memcpy( &block->operator[](offset), src, amt );
|
||||
|
||||
address += amt;
|
||||
src = ((u8*)src) + amt;
|
||||
length -= amt;
|
||||
}
|
||||
|
||||
// do nothing for unmapped regions
|
||||
const size_t amt = addr_end - address;
|
||||
|
||||
address += amt;
|
||||
src = ((u8*)src) + amt;
|
||||
length -= amt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef _CONEMU_WIIMOTE_H_
|
||||
#define _CONEMU_WIIMOTE_H_
|
||||
|
||||
#include <ControllerEmu.h>
|
||||
|
||||
#include "WiimoteHid.h"
|
||||
#include "Encryption.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
// Registry sizes
|
||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||
#define WIIMOTE_EEPROM_FREE_SIZE 0x16ff
|
||||
#define WIIMOTE_REG_SPEAKER_SIZE 10
|
||||
#define WIIMOTE_REG_EXT_SIZE 0x100
|
||||
#define WIIMOTE_REG_IR_SIZE 0x34
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
extern const u8 shake_data[8];
|
||||
|
||||
class Wiimote : public ControllerEmu
|
||||
{
|
||||
public:
|
||||
|
||||
Wiimote( const unsigned int index, SWiimoteInitialize* const wiimote_initialize );
|
||||
void Reset();
|
||||
|
||||
void Update();
|
||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||
|
||||
void ReportMode(u16 _channelID, wm_report_mode* dr);
|
||||
void HidOutputReport(u16 _channelID, wm_report* sr);
|
||||
void SendAck(u16 _channelID, u8 _reportID);
|
||||
void RequestStatus(u16 _channelID, wm_request_status* rs, int Extension = -1);
|
||||
|
||||
void WriteData(u16 _channelID, wm_write_data* wd);
|
||||
void ReadData(u16 _channelID, wm_read_data* rd);
|
||||
void SendReadDataReply(u16 _channelID, const void* _Base, unsigned int _Address, unsigned int _Size);
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
private:
|
||||
|
||||
SWiimoteInitialize* const m_wiimote_init;
|
||||
|
||||
Buttons* m_buttons;
|
||||
Buttons* m_dpad;
|
||||
Buttons* m_shake;
|
||||
Tilt* m_tilt;
|
||||
Force* m_swing;
|
||||
ControlGroup* m_rumble;
|
||||
Extension* m_extension;
|
||||
// TODO: add ir
|
||||
|
||||
const unsigned int m_index;
|
||||
|
||||
bool m_reporting_auto;
|
||||
unsigned int m_reporting_mode;
|
||||
unsigned int m_reporting_channel;
|
||||
|
||||
wm_status_report m_status;
|
||||
|
||||
class Register : public std::map< size_t, std::vector<u8> >
|
||||
{
|
||||
public:
|
||||
void Write( size_t address, void* src, size_t length );
|
||||
void Read( size_t address, void* dst, size_t length );
|
||||
|
||||
} m_register;
|
||||
|
||||
//u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
|
||||
//u8* m_reg_speaker;
|
||||
//u8* m_reg_motion_plus;
|
||||
//u8* m_reg_ir;
|
||||
u8* m_reg_ext;
|
||||
|
||||
wiimote_key m_ext_key;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,339 @@
|
|||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// 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/
|
||||
|
||||
#ifndef WIIMOTE_HID_H
|
||||
#define WIIMOTE_HID_H
|
||||
|
||||
#include "CommonTypes.h"
|
||||
|
||||
// what is this ?
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4200)
|
||||
#endif
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Source: HID_010_SPC_PFL/1.0 (official HID specification)
|
||||
|
||||
struct hid_packet {
|
||||
u8 param : 4;
|
||||
u8 type : 4;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
#define HID_TYPE_HANDSHAKE 0
|
||||
#define HID_TYPE_SET_REPORT 5
|
||||
#define HID_TYPE_DATA 0xA
|
||||
|
||||
#define HID_HANDSHAKE_SUCCESS 0
|
||||
|
||||
#define HID_PARAM_INPUT 1
|
||||
#define HID_PARAM_OUTPUT 2
|
||||
|
||||
//source: http://wiibrew.org/wiki/Wiimote
|
||||
|
||||
typedef u16 wm_core;
|
||||
|
||||
struct wm_accel
|
||||
{
|
||||
u8 x, y, z;
|
||||
};
|
||||
|
||||
// Four bytes for two objects. Filled with 0xFF if empty
|
||||
struct wm_ir_basic
|
||||
{
|
||||
u8 x1;
|
||||
u8 y1;
|
||||
u8 x2hi : 2;
|
||||
u8 y2hi : 2;
|
||||
u8 x1hi : 2;
|
||||
u8 y1hi : 2;
|
||||
u8 x2;
|
||||
u8 y2;
|
||||
};
|
||||
|
||||
// Three bytes for one object
|
||||
struct wm_ir_extended
|
||||
{
|
||||
u8 x;
|
||||
u8 y;
|
||||
u8 size : 4;
|
||||
u8 xhi : 2;
|
||||
u8 yhi : 2;
|
||||
};
|
||||
|
||||
struct wm_extension
|
||||
{
|
||||
u8 jx; // joystick x, y
|
||||
u8 jy;
|
||||
u8 ax; // accelerometer
|
||||
u8 ay;
|
||||
u8 az;
|
||||
u8 bt; // buttons
|
||||
};
|
||||
|
||||
struct wm_classic_extension
|
||||
{
|
||||
u8 lx : 6; // byte 0
|
||||
u8 rx3 : 2;
|
||||
u8 ly : 6; // byte 1
|
||||
u8 rx2 : 2;
|
||||
u8 ry : 5; // byte 2
|
||||
u8 lt2 : 2;
|
||||
u8 rx1 : 1;
|
||||
u8 rt : 5; // byte 3
|
||||
u8 lt1 : 3;
|
||||
u16 bt; // byte 4, 5
|
||||
};
|
||||
|
||||
struct wm_GH3_extension
|
||||
{
|
||||
u8 sx : 6;
|
||||
u8 pad1 : 2; // 1 on gh3, 0 on ghwt
|
||||
|
||||
u8 sy : 6;
|
||||
u8 pad2 : 2; // 1 on gh3, 0 on ghwt
|
||||
|
||||
u8 tb : 5; // not used in gh3
|
||||
u8 pad3 : 3; // always 0
|
||||
|
||||
u8 whammy : 5;
|
||||
u8 pad4 : 3; // always 0
|
||||
|
||||
u8 pad5 : 2; // always 1
|
||||
u8 plus : 1;
|
||||
u8 pad6 : 1; // always 1
|
||||
u8 minus : 1;
|
||||
u8 pad7 : 1; // always 1
|
||||
u8 strumdown : 1;
|
||||
u8 pad8 : 1; // always 1
|
||||
|
||||
u8 strumup : 1;
|
||||
u8 pad9 : 2; // always 1
|
||||
u8 yellow : 1;
|
||||
u8 green : 1;
|
||||
u8 blue : 1;
|
||||
u8 red : 1;
|
||||
u8 orange : 1;
|
||||
};
|
||||
|
||||
|
||||
struct wm_report {
|
||||
u8 wm;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
#define WM_RUMBLE 0x10
|
||||
|
||||
#define WM_LEDS 0x11
|
||||
struct wm_leds {
|
||||
u8 rumble : 1;
|
||||
u8 : 3;
|
||||
u8 leds : 4;
|
||||
};
|
||||
|
||||
#define WM_REPORT_MODE 0x12
|
||||
struct wm_report_mode {
|
||||
u8 rumble : 1;
|
||||
u8 continuous : 1;
|
||||
u8 all_the_time : 1;
|
||||
u8 : 5;
|
||||
u8 mode;
|
||||
};
|
||||
|
||||
#define WM_IR_PIXEL_CLOCK 0x13
|
||||
#define WM_IR_LOGIC 0x1A
|
||||
|
||||
#define WM_REQUEST_STATUS 0x15
|
||||
struct wm_request_status {
|
||||
u8 rumble : 1;
|
||||
u8 : 7;
|
||||
};
|
||||
|
||||
#define WM_STATUS_REPORT 0x20
|
||||
struct wm_status_report {
|
||||
wm_core buttons;
|
||||
u8 battery_low : 1;
|
||||
u8 extension : 1;
|
||||
u8 speaker : 1;
|
||||
u8 ir : 1;
|
||||
u8 leds : 4;
|
||||
u8 padding2[2]; // two 00, TODO: this needs more investigation
|
||||
u8 battery;
|
||||
};
|
||||
|
||||
#define WM_WRITE_DATA 0x16
|
||||
struct wm_write_data
|
||||
{
|
||||
u8 rumble : 1;
|
||||
u8 space : 2; //see WM_SPACE_*
|
||||
u8 : 5;
|
||||
u8 address[3];
|
||||
u8 size;
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
#define WM_ACK_DATA 0x22
|
||||
struct wm_acknowledge
|
||||
{
|
||||
wm_core buttons;
|
||||
u8 reportID;
|
||||
u8 errorID;
|
||||
};
|
||||
|
||||
#define WM_READ_DATA 0x17
|
||||
struct wm_read_data {
|
||||
u8 rumble : 1;
|
||||
u8 space : 2; //see WM_SPACE_*
|
||||
u8 : 5;
|
||||
u8 address[3];
|
||||
u8 size[2];
|
||||
};
|
||||
|
||||
#define WM_SPACE_EEPROM 0
|
||||
#define WM_SPACE_REGS1 1
|
||||
#define WM_SPACE_REGS2 2
|
||||
#define WM_SPACE_INVALID 3
|
||||
|
||||
#define WM_READ_DATA_REPLY 0x21
|
||||
struct wm_read_data_reply {
|
||||
wm_core buttons;
|
||||
u8 error : 4; //see WM_RDERR_*
|
||||
u8 size : 4;
|
||||
u16 address;
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
#define WM_RDERR_WOREG 7
|
||||
#define WM_RDERR_NOMEM 8
|
||||
|
||||
|
||||
// Data reports
|
||||
|
||||
#define WM_REPORT_CORE 0x30
|
||||
struct wm_report_core {
|
||||
wm_core c;
|
||||
};
|
||||
|
||||
#define WM_REPORT_CORE_ACCEL 0x31
|
||||
struct wm_report_core_accel {
|
||||
wm_core c;
|
||||
wm_accel a;
|
||||
};
|
||||
|
||||
#define WM_REPORT_CORE_EXT8 0x32
|
||||
|
||||
#define WM_REPORT_CORE_ACCEL_IR12 0x33
|
||||
struct wm_report_core_accel_ir12 {
|
||||
wm_core c;
|
||||
wm_accel a;
|
||||
wm_ir_extended ir[4];
|
||||
};
|
||||
|
||||
#define WM_REPORT_CORE_EXT19 0x34
|
||||
#define WM_REPORT_CORE_ACCEL_EXT16 0x35
|
||||
struct wm_report_core_accel_ext16
|
||||
{
|
||||
wm_core c;
|
||||
wm_accel a;
|
||||
wm_extension ext;
|
||||
//wm_ir_basic ir[2];
|
||||
u8 pad[10];
|
||||
|
||||
};
|
||||
|
||||
#define WM_REPORT_CORE_IR10_EXT9 0x36
|
||||
|
||||
#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37
|
||||
struct wm_report_core_accel_ir10_ext6
|
||||
{
|
||||
wm_core c;
|
||||
wm_accel a;
|
||||
wm_ir_basic ir[2];
|
||||
//u8 ext[6];
|
||||
wm_extension ext;
|
||||
};
|
||||
|
||||
#define WM_REPORT_EXT21 0x3d // never used?
|
||||
struct wm_report_ext21
|
||||
{
|
||||
u8 ext[21];
|
||||
};
|
||||
|
||||
#define WM_REPORT_INTERLEAVE1 0x3e
|
||||
#define WM_REPORT_INTERLEAVE2 0x3f
|
||||
|
||||
#define WM_SPEAKER_ENABLE 0x14
|
||||
#define WM_SPEAKER_MUTE 0x19
|
||||
#define WM_WRITE_SPEAKER_DATA 0x18
|
||||
|
||||
|
||||
// Custom structs
|
||||
|
||||
/**
|
||||
* @struct accel_t
|
||||
* @brief Accelerometer struct. For any device with an accelerometer.
|
||||
*/
|
||||
struct accel_cal
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 x, y, z;
|
||||
u8 xlo : 2;
|
||||
u8 ylo : 2;
|
||||
u8 zlo : 2;
|
||||
} zero_g;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 x, y, z;
|
||||
u8 xlo : 2;
|
||||
u8 ylo : 2;
|
||||
u8 zlo : 2;
|
||||
} one_g;
|
||||
};
|
||||
|
||||
struct nu_js {
|
||||
u8 max, min, center;
|
||||
};
|
||||
struct cc_trigger {
|
||||
u8 neutral;
|
||||
};
|
||||
struct nu_cal
|
||||
{
|
||||
wm_accel cal_zero; // zero calibratio
|
||||
wm_accel cal_g; // g size
|
||||
nu_js jx; //
|
||||
nu_js jy; //
|
||||
};
|
||||
struct cc_cal
|
||||
{
|
||||
nu_js Lx; //
|
||||
nu_js Ly; //
|
||||
nu_js Rx; //
|
||||
nu_js Ry; //
|
||||
cc_trigger Tl; //
|
||||
cc_trigger Tr; //
|
||||
};
|
||||
struct gh3_cal
|
||||
{
|
||||
nu_js Lx;
|
||||
nu_js Ly;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //WIIMOTE_HID_H
|
|
@ -0,0 +1,348 @@
|
|||
|
||||
#include <math.h>
|
||||
#include "Common.h"
|
||||
#include "pluginspecs_wiimote.h"
|
||||
|
||||
#include "ControllerInterface/ControllerInterface.h"
|
||||
#include "WiimoteEmu/WiimoteEmu.h"
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "ConfigDiag.h"
|
||||
#endif
|
||||
#include "Config.h"
|
||||
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
#include <X11/Xlib.h>
|
||||
Display* GCdisplay;
|
||||
#endif
|
||||
|
||||
#define PLUGIN_VERSION 0x0100
|
||||
|
||||
#define PLUGIN_NAME "Dolphin Wiimote New Incomplete"
|
||||
#ifdef DEBUGFAST
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME" (DebugFast)"
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME" (Debug)"
|
||||
#else
|
||||
#define PLUGIN_FULL_NAME PLUGIN_NAME
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
class wxDLLApp : public wxApp
|
||||
{
|
||||
bool OnInit()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
};
|
||||
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
|
||||
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
||||
#endif
|
||||
// copied from GCPad
|
||||
SWiimoteInitialize g_WiimoteInitialize;
|
||||
// Check if Dolphin is in focus
|
||||
// ----------------
|
||||
bool IsFocus()
|
||||
{
|
||||
// TODO: this
|
||||
return true;
|
||||
}
|
||||
|
||||
// copied from GCPad
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
// copied from GCPad
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
wxWindow* GetParentedWxWindow(HWND Parent)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wxSetInstance((HINSTANCE)g_hInstance);
|
||||
#endif
|
||||
wxWindow *win = new wxWindow();
|
||||
#ifdef _WIN32
|
||||
win->SetHWND((WXHWND)Parent);
|
||||
win->AdoptAttributesFromHWND();
|
||||
#endif
|
||||
return win;
|
||||
}
|
||||
#endif
|
||||
// /
|
||||
|
||||
// the plugin
|
||||
Plugin g_plugin( "WiimoteNew", "Wiimote", "Wiimote" );
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
||||
{
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
wxSetInstance(hinstDLL);
|
||||
wxInitialize();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
wxUninitialize();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_hInstance = hinstDLL;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DeInitPlugin()
|
||||
{
|
||||
if ( g_plugin.controller_interface.IsInit() )
|
||||
{
|
||||
std::vector<ControllerEmu*>::const_iterator
|
||||
i = g_plugin.controllers.begin(),
|
||||
e = g_plugin.controllers.end();
|
||||
for ( ; i!=e; ++i )
|
||||
delete *i;
|
||||
g_plugin.controllers.clear();
|
||||
|
||||
g_plugin.controller_interface.DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
// if plugin isn't initialized, init and load config
|
||||
void InitPlugin( void* const hwnd )
|
||||
{
|
||||
if ( false == g_plugin.controller_interface.IsInit() )
|
||||
{
|
||||
// add 4 wiimotes
|
||||
for ( unsigned int i = 0; i<4; ++i )
|
||||
g_plugin.controllers.push_back( new WiimoteEmu::Wiimote( i, &g_WiimoteInitialize ) );
|
||||
|
||||
// load the saved controller config
|
||||
g_plugin.LoadConfig();
|
||||
|
||||
// needed for Xlib and exclusive dinput
|
||||
g_plugin.controller_interface.SetHwnd( hwnd );
|
||||
g_plugin.controller_interface.Init();
|
||||
|
||||
// update control refs
|
||||
std::vector<ControllerEmu*>::const_iterator i = g_plugin.controllers.begin(),
|
||||
e = g_plugin.controllers.end();
|
||||
for ( ; i!=e; ++i )
|
||||
(*i)->UpdateReferences( g_plugin.controller_interface );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// I N T E R F A C E
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// Function: Wiimote_Output
|
||||
// Purpose: An L2CAP packet is passed from the Core to the Wiimote,
|
||||
// on the HID CONTROL channel.
|
||||
// input: Da pakket.
|
||||
// output: none
|
||||
//
|
||||
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
//PanicAlert( "Wiimote_ControlChannel" );
|
||||
|
||||
// TODO: change this to a TryEnter, and make it give empty input on failure
|
||||
g_plugin.controls_crit.Enter();
|
||||
|
||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->ControlChannel( _channelID, _pData, _Size );
|
||||
|
||||
g_plugin.controls_crit.Leave();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// Function: Wiimote_Input
|
||||
// Purpose: An L2CAP packet is passed from the Core to the Wiimote,
|
||||
// on the HID INTERRUPT channel.
|
||||
// input: Da pakket.
|
||||
// output: none
|
||||
//
|
||||
void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
//PanicAlert( "Wiimote_InterruptChannel" );
|
||||
|
||||
// TODO: change this to a TryEnter, and make it give empty input on failure
|
||||
g_plugin.controls_crit.Enter();
|
||||
|
||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->InterruptChannel( _channelID, _pData, _Size );
|
||||
|
||||
g_plugin.controls_crit.Leave();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// Function: Wiimote_Update
|
||||
// Purpose: This function is called periodically by the Core.
|
||||
// input: none
|
||||
// output: none
|
||||
//
|
||||
void Wiimote_Update(int _number)
|
||||
{
|
||||
//PanicAlert( "Wiimote_Update" );
|
||||
|
||||
// TODO: change this to a TryEnter, and make it give empty input on failure
|
||||
g_plugin.controls_crit.Enter();
|
||||
|
||||
static int _last_number = 4;
|
||||
if ( _number <= _last_number && g_plugin.interface_crit.TryEnter() )
|
||||
{
|
||||
g_plugin.controller_interface.UpdateOutput();
|
||||
g_plugin.controller_interface.UpdateInput();
|
||||
g_plugin.interface_crit.Leave();
|
||||
}
|
||||
_last_number = _number;
|
||||
|
||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->Update();
|
||||
|
||||
g_plugin.controls_crit.Leave();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// Function: PAD_GetAttachedPads
|
||||
// Purpose: Get mask of attached pads (eg: controller 1 & 4 -> 0x9)
|
||||
// input: none
|
||||
// output: number of pads
|
||||
//
|
||||
unsigned int Wiimote_GetAttachedControllers()
|
||||
{
|
||||
//PanicAlert( "Wiimote_GetAttachedControllers" );
|
||||
// temporary
|
||||
//return 0x0F;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GLOBAL I N T E R F A C E
|
||||
// Function: GetDllInfo
|
||||
// Purpose: This function allows the emulator to gather information
|
||||
// about the DLL by filling in the PluginInfo structure.
|
||||
// input: A pointer to a PLUGIN_INFO structure that needs to be
|
||||
// filled by the function. (see def above)
|
||||
// output: none
|
||||
//
|
||||
void GetDllInfo(PLUGIN_INFO* _pPluginInfo)
|
||||
{
|
||||
// don't feel like messing around with all those strcpy functions and warnings
|
||||
//char *s1 = CIFACE_PLUGIN_FULL_NAME, *s2 = _pPluginInfo->Name;
|
||||
//while ( *s2++ = *s1++ );
|
||||
memcpy( _pPluginInfo->Name, PLUGIN_FULL_NAME, sizeof(PLUGIN_FULL_NAME) );
|
||||
_pPluginInfo->Type = PLUGIN_TYPE_WIIMOTE;
|
||||
_pPluginInfo->Version = PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: DllConfig
|
||||
// Purpose: This function is optional function that is provided
|
||||
// to allow the user to configure the DLL
|
||||
// input: A handle to the window that calls this function
|
||||
// output: none
|
||||
//
|
||||
void DllConfig(HWND _hParent)
|
||||
{
|
||||
bool was_init = false;
|
||||
if ( g_plugin.controller_interface.IsInit() ) // hack for showing dialog when game isnt running
|
||||
was_init = true;
|
||||
else
|
||||
InitPlugin( _hParent );
|
||||
|
||||
// copied from GCPad
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
wxWindow *frame = GetParentedWxWindow(_hParent);
|
||||
ConfigDialog* m_ConfigFrame = new ConfigDialog( frame, g_plugin, PLUGIN_FULL_NAME, was_init );
|
||||
|
||||
#ifdef _WIN32
|
||||
frame->Disable();
|
||||
m_ConfigFrame->ShowModal();
|
||||
frame->Enable();
|
||||
#else
|
||||
m_ConfigFrame->ShowModal();
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
wxMilliSleep( 50 ); // hooray for hacks
|
||||
frame->SetFocus();
|
||||
frame->SetHWND(NULL);
|
||||
#endif
|
||||
|
||||
m_ConfigFrame->Destroy();
|
||||
m_ConfigFrame = NULL;
|
||||
frame->Destroy();
|
||||
#endif
|
||||
// /
|
||||
|
||||
if ( false == was_init ) // hack for showing dialog when game isnt running
|
||||
DeInitPlugin();
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: DllDebugger
|
||||
// Purpose: Open the debugger
|
||||
// input: a handle to the window that calls this function
|
||||
// output: none
|
||||
//
|
||||
void DllDebugger(HWND _hParent, bool Show)
|
||||
{
|
||||
// wut?
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: DllSetGlobals
|
||||
// Purpose: Set the pointer for globals variables
|
||||
// input: a pointer to the global struct
|
||||
// output: none
|
||||
//
|
||||
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
||||
{
|
||||
// wut?
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: Initialize
|
||||
// Purpose: Initialize the plugin
|
||||
// input: Init
|
||||
// output: none
|
||||
//
|
||||
void Initialize(void *init)
|
||||
{
|
||||
g_WiimoteInitialize = *(SWiimoteInitialize*)init;
|
||||
if ( false == g_plugin.controller_interface.IsInit() )
|
||||
InitPlugin( ((SPADInitialize*)init)->hWnd );
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: Shutdown
|
||||
// Purpose: This function is called when the emulator is shutting down
|
||||
// a game allowing the dll to de-initialise.
|
||||
// input: none
|
||||
// output: none
|
||||
//
|
||||
void Shutdown(void)
|
||||
{
|
||||
if ( g_plugin.controller_interface.IsInit() )
|
||||
DeInitPlugin();
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: DoState
|
||||
// Purpose: Saves/load state
|
||||
// input/output: ptr
|
||||
// input: mode
|
||||
//
|
||||
void DoState(unsigned char **ptr, int mode)
|
||||
{
|
||||
// prolly won't need this
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Function: EmuStateChange
|
||||
// Purpose: Notifies the plugin of a change in emulation state
|
||||
// input: newState
|
||||
// output: none
|
||||
//
|
||||
void EmuStateChange(PLUGIN_EMUSTATE newState)
|
||||
{
|
||||
// maybe use this later
|
||||
}
|
Loading…
Reference in New Issue