Fix compile, removed wiimote-testing as people prefer to work live on wiimote so I will also
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3710 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
afa6372d96
commit
9588c84475
|
@ -1,659 +0,0 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9.00"
|
|
||||||
Name="Plugin_Wiimote"
|
|
||||||
ProjectGUID="{8D612734-FAA5-4B8A-804F-4DEA2367D495}"
|
|
||||||
RootNamespace="Plugin_Wiimote"
|
|
||||||
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="2"
|
|
||||||
>
|
|
||||||
<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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\Win32/Plugins\Plugin_WiimoteD.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\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="2"
|
|
||||||
>
|
|
||||||
<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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_WiimoteD.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\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="2"
|
|
||||||
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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_Wiimote.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\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="2"
|
|
||||||
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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_Wiimote.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\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="2"
|
|
||||||
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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="DEBUGFAST;WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_WiimoteDF.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\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="2"
|
|
||||||
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;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\WiiUse\inc"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_WIIMOTE_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"
|
|
||||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_WiimoteDF.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\WiiUse\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="Debugging"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Logging.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Logging.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Emulated Wiimote"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\DataReports.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuDefinitions.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuDefinitions.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuDynamics.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuMain.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuMain.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuPad.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuSubroutines.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\EmuSubroutines.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Encryption.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Encryption.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\FillReport.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\wiimote_hid.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Real Wiimote"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ReadWiimote.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\wiimote_real.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\wiimote_real.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Config"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Config.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Config.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ConfigDlg.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ConfigDlg.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ConfigGamepad.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\ConfigRecording.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\main.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\main.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\PluginSpecs\pluginspecs_wiimote.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\SConscript"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
|
@ -1,356 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "StringUtil.h"
|
|
||||||
|
|
||||||
#include "Config.h"
|
|
||||||
#include "EmuDefinitions.h" // for PadMapping
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
// TODO: Figure out what to do for non-Win32
|
|
||||||
#ifndef _WIN32
|
|
||||||
#define VK_LEFT 0
|
|
||||||
#define VK_RIGHT 0
|
|
||||||
#define VK_UP 0
|
|
||||||
#define VK_DOWN 0
|
|
||||||
#define VK_NUMPAD4 0
|
|
||||||
#define VK_NUMPAD6 0
|
|
||||||
#define VK_NUMPAD8 0
|
|
||||||
#define VK_NUMPAD5 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Config g_Config;
|
|
||||||
|
|
||||||
Config::Config()
|
|
||||||
{
|
|
||||||
// Set all default values to zero
|
|
||||||
memset(this, 0, sizeof(Config));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::Load(bool ChangePad)
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
IniFile iniFile;
|
|
||||||
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
|
|
||||||
|
|
||||||
// General
|
|
||||||
iniFile.Get("Settings", "SidewaysDPad", &bSidewaysDPad, false);
|
|
||||||
iniFile.Get("Settings", "NunchuckConnected", &bNunchuckConnected, false);
|
|
||||||
iniFile.Get("Settings", "ClassicControllerConnected", &bClassicControllerConnected, false);
|
|
||||||
|
|
||||||
// Real Wiimote
|
|
||||||
iniFile.Get("Real", "Connect", &bConnectRealWiimote, true);
|
|
||||||
iniFile.Get("Real", "Use", &bUseRealWiimote, true);
|
|
||||||
iniFile.Get("Real", "UpdateStatus", &bUpdateRealWiimote, true);
|
|
||||||
iniFile.Get("Real", "AccNeutralX", &iAccNeutralX, 0);
|
|
||||||
iniFile.Get("Real", "AccNeutralY", &iAccNeutralY, 0);
|
|
||||||
iniFile.Get("Real", "AccNeutralZ", &iAccNeutralZ, 0);
|
|
||||||
iniFile.Get("Real", "AccNunNeutralX", &iAccNunNeutralX, 0);
|
|
||||||
iniFile.Get("Real", "AccNunNeutralY", &iAccNunNeutralY, 0);
|
|
||||||
iniFile.Get("Real", "AccNunNeutralZ", &iAccNunNeutralZ, 0);
|
|
||||||
|
|
||||||
// Default controls
|
|
||||||
int WmA = 65, WmB = 66,
|
|
||||||
Wm1 = 49, Wm2 = 50,
|
|
||||||
WmP = 80, WmM = 77, WmH = 72,
|
|
||||||
WmL = VK_LEFT, WmR = VK_RIGHT, WmU = VK_UP, WmD = VK_DOWN, // Regular directional keys
|
|
||||||
WmShake = 83, // S
|
|
||||||
WmPitchL = 51, WmPitchR = 52, // 3 and 4
|
|
||||||
|
|
||||||
NcZ = 90, NcC = 67, // C, Z
|
|
||||||
NcL = VK_NUMPAD4, NcR = VK_NUMPAD6, NcU = VK_NUMPAD8, NcD = VK_NUMPAD5, // Numpad
|
|
||||||
NcShake = 68, // D
|
|
||||||
|
|
||||||
CcA = 90, CcB = 67, CcX = 0x58, CcY = 0x59, // C, Z, X, Y
|
|
||||||
CcP = 0x4f, CcM = 0x4e, CcH = 0x55, // O instead of P, N instead of M, U instead of H
|
|
||||||
CcTl = 0x37, CcZl = 0x38, CcZr = 0x39, CcTr = 0x30, // 7, 8, 9, 0
|
|
||||||
CcDl = VK_NUMPAD4, CcDu = VK_NUMPAD8, CcDr = VK_NUMPAD6, CcDd = VK_NUMPAD5, // Numpad
|
|
||||||
CcLl = 0x4a, CcLu = 0x49, CcLr = 0x4c, CcLd = 0x4b, // J, I, L, K
|
|
||||||
CcRl = 0x44, CcRu = 0x52, CcRr = 0x47, CcRd = 0x46; // D, R, G, F
|
|
||||||
|
|
||||||
for (int i = 0; i < 1; i++)
|
|
||||||
{
|
|
||||||
// ==================================================================
|
|
||||||
// Slot specific settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
std::string SectionName = StringFromFormat("Wiimote%i", i + 1);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NoTriggerFilter", &bNoTriggerFilter, false);
|
|
||||||
iniFile.Get(SectionName.c_str(), "TriggerType", &Trigger.Type, Trigger.TRIGGER_OFF);
|
|
||||||
iniFile.Get(SectionName.c_str(), "TriggerRollRange", &Trigger.Range.Roll, 50);
|
|
||||||
iniFile.Get(SectionName.c_str(), "TriggerPitchRange", &Trigger.Range.Pitch, false);
|
|
||||||
|
|
||||||
// Wiimote
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmA", &WiiMoteEmu::PadMapping[i].Wm.A, WmA);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmB", &WiiMoteEmu::PadMapping[i].Wm.B, WmB);
|
|
||||||
iniFile.Get(SectionName.c_str(), "Wm1", &WiiMoteEmu::PadMapping[i].Wm.One, Wm1);
|
|
||||||
iniFile.Get(SectionName.c_str(), "Wm2", &WiiMoteEmu::PadMapping[i].Wm.Two, Wm2);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmP", &WiiMoteEmu::PadMapping[i].Wm.P, WmP);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmM", &WiiMoteEmu::PadMapping[i].Wm.M, WmM);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmH", &WiiMoteEmu::PadMapping[i].Wm.H, WmH);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmL", &WiiMoteEmu::PadMapping[i].Wm.L, WmL);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmR", &WiiMoteEmu::PadMapping[i].Wm.R, WmR);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmU", &WiiMoteEmu::PadMapping[i].Wm.U, WmU);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmD", &WiiMoteEmu::PadMapping[i].Wm.D, WmD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmShake", &WiiMoteEmu::PadMapping[i].Wm.Shake, WmShake);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmPitchL", &WiiMoteEmu::PadMapping[i].Wm.PitchL, WmPitchL);
|
|
||||||
iniFile.Get(SectionName.c_str(), "WmPitchR", &WiiMoteEmu::PadMapping[i].Wm.PitchR, WmPitchR);
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
iniFile.Get(SectionName.c_str(), "NunchuckStick", &Nunchuck.Type, Nunchuck.KEYBOARD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcZ", &WiiMoteEmu::PadMapping[i].Nc.Z, NcZ);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcC", &WiiMoteEmu::PadMapping[i].Nc.C, NcC);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcL", &WiiMoteEmu::PadMapping[i].Nc.L, NcL);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcR", &WiiMoteEmu::PadMapping[i].Nc.R, NcR);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcU", &WiiMoteEmu::PadMapping[i].Nc.U, NcU);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcD", &WiiMoteEmu::PadMapping[i].Nc.D, NcD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "NcShake", &WiiMoteEmu::PadMapping[i].Nc.Shake, NcShake);
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcLeftStick", &ClassicController.LType, ClassicController.KEYBOARD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcRightStick", &ClassicController.RType, ClassicController.KEYBOARD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcTriggers", &ClassicController.TType, ClassicController.KEYBOARD);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcA", &WiiMoteEmu::PadMapping[i].Cc.A, CcA);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcB", &WiiMoteEmu::PadMapping[i].Cc.B, CcB);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcX", &WiiMoteEmu::PadMapping[i].Cc.X, CcX);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcY", &WiiMoteEmu::PadMapping[i].Cc.Y, CcY);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcP", &WiiMoteEmu::PadMapping[i].Cc.P, CcP);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcM", &WiiMoteEmu::PadMapping[i].Cc.M, CcM);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcH", &WiiMoteEmu::PadMapping[i].Cc.H, CcH);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcTl", &WiiMoteEmu::PadMapping[i].Cc.Tl, CcTl);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcZl", &WiiMoteEmu::PadMapping[i].Cc.Zl, CcZl);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcZr", &WiiMoteEmu::PadMapping[i].Cc.Zr, CcZr);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcTr", &WiiMoteEmu::PadMapping[i].Cc.Tr, CcTr);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcDl", &WiiMoteEmu::PadMapping[i].Cc.Dl, CcDl);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcDu", &WiiMoteEmu::PadMapping[i].Cc.Du, CcDu);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcDr", &WiiMoteEmu::PadMapping[i].Cc.Dr, CcDr);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcDd", &WiiMoteEmu::PadMapping[i].Cc.Dd, CcDd);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcLl", &WiiMoteEmu::PadMapping[i].Cc.Ll, CcLl);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcLu", &WiiMoteEmu::PadMapping[i].Cc.Lu, CcLu);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcLr", &WiiMoteEmu::PadMapping[i].Cc.Lr, CcLr);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcLd", &WiiMoteEmu::PadMapping[i].Cc.Ld, CcLd);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcRl", &WiiMoteEmu::PadMapping[i].Cc.Rl, CcRl);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcRu", &WiiMoteEmu::PadMapping[i].Cc.Ru, CcRu);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcRr", &WiiMoteEmu::PadMapping[i].Cc.Rr, CcRr);
|
|
||||||
iniFile.Get(SectionName.c_str(), "CcRd", &WiiMoteEmu::PadMapping[i].Cc.Rd, CcRd);
|
|
||||||
|
|
||||||
// Don't update this when we are loading settings from the ConfigBox
|
|
||||||
if(!ChangePad)
|
|
||||||
{
|
|
||||||
/* This pad Id could possibly be higher than the number of pads that are connected,
|
|
||||||
but we check later, when needed, that that is not the case */
|
|
||||||
iniFile.Get(SectionName.c_str(), "DeviceID", &WiiMoteEmu::PadMapping[i].ID, 0);
|
|
||||||
iniFile.Get(SectionName.c_str(), "Enabled", &WiiMoteEmu::PadMapping[i].enabled, true);
|
|
||||||
}
|
|
||||||
// ===================
|
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
// Joypad specific settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
// Current joypad device ID: PadMapping[i].ID
|
|
||||||
// Current joypad name: joyinfo[PadMapping[i].ID].Name
|
|
||||||
|
|
||||||
/* Prevent a crash from illegal access to joyinfo that will only have values for
|
|
||||||
the current amount of connected PadMapping */
|
|
||||||
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
|
|
||||||
|
|
||||||
// Create a section name
|
|
||||||
SectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
|
|
||||||
|
|
||||||
iniFile.Get(SectionName.c_str(), "left_x", &WiiMoteEmu::PadMapping[i].Axis.Lx, 0);
|
|
||||||
iniFile.Get(SectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1);
|
|
||||||
iniFile.Get(SectionName.c_str(), "right_x", &WiiMoteEmu::PadMapping[i].Axis.Rx, 2);
|
|
||||||
iniFile.Get(SectionName.c_str(), "right_y", &WiiMoteEmu::PadMapping[i].Axis.Ry, 3);
|
|
||||||
iniFile.Get(SectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 1004);
|
|
||||||
iniFile.Get(SectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 1005);
|
|
||||||
iniFile.Get(SectionName.c_str(), "DeadZoneL", &WiiMoteEmu::PadMapping[i].DeadZoneL, 0);
|
|
||||||
iniFile.Get(SectionName.c_str(), "DeadZoneR", &WiiMoteEmu::PadMapping[i].DeadZoneR, 0);
|
|
||||||
iniFile.Get(SectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
|
|
||||||
iniFile.Get(SectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
|
|
||||||
iniFile.Get(SectionName.c_str(), "Circle2Square", &WiiMoteEmu::PadMapping[i].bCircle2Square, false);
|
|
||||||
iniFile.Get(SectionName.c_str(), "RollInvert", &WiiMoteEmu::PadMapping[i].bRollInvert, false);
|
|
||||||
iniFile.Get(SectionName.c_str(), "PitchInvert", &WiiMoteEmu::PadMapping[i].bPitchInvert, false);
|
|
||||||
}
|
|
||||||
// =============================
|
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
// Load the IR cursor settings if it's avaliable, if not load the default settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini");
|
|
||||||
std::string TmpSection;
|
|
||||||
if (g_ISOId) TmpSection = Hex2Ascii(g_ISOId); else TmpSection = "Default";
|
|
||||||
iniFile.Get(TmpSection.c_str(), "IRLeft", &iIRLeft, LEFT);
|
|
||||||
iniFile.Get(TmpSection.c_str(), "IRTop", &iIRTop, TOP);
|
|
||||||
iniFile.Get(TmpSection.c_str(), "IRWidth", &iIRWidth, RIGHT - LEFT);
|
|
||||||
iniFile.Get(TmpSection.c_str(), "IRHeight", &iIRHeight, BOTTOM - TOP);
|
|
||||||
// =============================
|
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
/* Load a few screen settings to. If these are added to the DirectX plugin it's probably
|
|
||||||
better to place them in the main Dolphin.ini file */
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
|
|
||||||
iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false);
|
|
||||||
iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false);
|
|
||||||
iniFile.Get("Settings", "Crop", &bCrop, false);
|
|
||||||
// =============================
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
INFO_LOG(CONSOLE, "Load()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::Save(int Slot)
|
|
||||||
{
|
|
||||||
IniFile iniFile;
|
|
||||||
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
|
|
||||||
iniFile.Set("Settings", "SidewaysDPad", bSidewaysDPad);
|
|
||||||
iniFile.Set("Settings", "NunchuckConnected", bNunchuckConnected);
|
|
||||||
iniFile.Set("Settings", "ClassicControllerConnected", bClassicControllerConnected);
|
|
||||||
|
|
||||||
iniFile.Set("Real", "Connect", bConnectRealWiimote);
|
|
||||||
iniFile.Set("Real", "Use", bUseRealWiimote);
|
|
||||||
iniFile.Set("Real", "UpdateStatus", bUpdateRealWiimote);
|
|
||||||
iniFile.Set("Real", "AccNeutralX", iAccNeutralX);
|
|
||||||
iniFile.Set("Real", "AccNeutralY", iAccNeutralY);
|
|
||||||
iniFile.Set("Real", "AccNeutralZ", iAccNeutralZ);
|
|
||||||
iniFile.Set("Real", "AccNunNeutralX", iAccNunNeutralX);
|
|
||||||
iniFile.Set("Real", "AccNunNeutralY", iAccNunNeutralY);
|
|
||||||
iniFile.Set("Real", "AccNunNeutralZ", iAccNunNeutralZ);
|
|
||||||
|
|
||||||
for (int i = 0; i < 1; i++)
|
|
||||||
{
|
|
||||||
// ==================================================================
|
|
||||||
// Slot specific settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
std::string SectionName = StringFromFormat("Wiimote%i", i + 1);
|
|
||||||
iniFile.Set(SectionName.c_str(), "Enabled", WiiMoteEmu::PadMapping[i].enabled);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NoTriggerFilter", bNoTriggerFilter);
|
|
||||||
iniFile.Set(SectionName.c_str(), "TriggerType", Trigger.Type);
|
|
||||||
iniFile.Set(SectionName.c_str(), "TriggerRollRange", Trigger.Range.Roll);
|
|
||||||
iniFile.Set(SectionName.c_str(), "TriggerPitchRange", Trigger.Range.Pitch);
|
|
||||||
|
|
||||||
// Wiimote
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmA", WiiMoteEmu::PadMapping[i].Wm.A);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmB", WiiMoteEmu::PadMapping[i].Wm.B);
|
|
||||||
iniFile.Set(SectionName.c_str(), "Wm1", WiiMoteEmu::PadMapping[i].Wm.One);
|
|
||||||
iniFile.Set(SectionName.c_str(), "Wm2", WiiMoteEmu::PadMapping[i].Wm.Two);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmP", WiiMoteEmu::PadMapping[i].Wm.P);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmM", WiiMoteEmu::PadMapping[i].Wm.M);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmH", WiiMoteEmu::PadMapping[i].Wm.H);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmL", WiiMoteEmu::PadMapping[i].Wm.L);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmR", WiiMoteEmu::PadMapping[i].Wm.R);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmU", WiiMoteEmu::PadMapping[i].Wm.U);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmD", WiiMoteEmu::PadMapping[i].Wm.D);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmShake", WiiMoteEmu::PadMapping[i].Wm.Shake);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmPitchL", WiiMoteEmu::PadMapping[i].Wm.PitchL);
|
|
||||||
iniFile.Set(SectionName.c_str(), "WmPitchR", WiiMoteEmu::PadMapping[i].Wm.PitchR);
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
iniFile.Set(SectionName.c_str(), "NunchuckStick", Nunchuck.Type);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcZ", WiiMoteEmu::PadMapping[i].Nc.Z);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcC", WiiMoteEmu::PadMapping[i].Nc.C);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcL", WiiMoteEmu::PadMapping[i].Nc.L);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcR", WiiMoteEmu::PadMapping[i].Nc.R);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcU", WiiMoteEmu::PadMapping[i].Nc.U);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcD", WiiMoteEmu::PadMapping[i].Nc.D);
|
|
||||||
iniFile.Set(SectionName.c_str(), "NcShake", WiiMoteEmu::PadMapping[i].Nc.Shake);
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcLeftStick", ClassicController.LType);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcRightStick", ClassicController.RType);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcTriggers", ClassicController.TType);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcA", WiiMoteEmu::PadMapping[i].Cc.A);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcB", WiiMoteEmu::PadMapping[i].Cc.B);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcX", WiiMoteEmu::PadMapping[i].Cc.X);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcY", WiiMoteEmu::PadMapping[i].Cc.Y);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcP", WiiMoteEmu::PadMapping[i].Cc.P);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcM", WiiMoteEmu::PadMapping[i].Cc.M);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcH", WiiMoteEmu::PadMapping[i].Cc.H);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcTl", WiiMoteEmu::PadMapping[i].Cc.Tl);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcZl", WiiMoteEmu::PadMapping[i].Cc.Zl);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcZr", WiiMoteEmu::PadMapping[i].Cc.Zr);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcTr", WiiMoteEmu::PadMapping[i].Cc.Tr);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcDl", WiiMoteEmu::PadMapping[i].Cc.Dl);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcDu", WiiMoteEmu::PadMapping[i].Cc.Du);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcDr", WiiMoteEmu::PadMapping[i].Cc.Dr);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcDd", WiiMoteEmu::PadMapping[i].Cc.Dd);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcLl", WiiMoteEmu::PadMapping[i].Cc.Ll);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcLu", WiiMoteEmu::PadMapping[i].Cc.Lu);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcLr", WiiMoteEmu::PadMapping[i].Cc.Lr);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcLd", WiiMoteEmu::PadMapping[i].Cc.Ld);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcRl", WiiMoteEmu::PadMapping[i].Cc.Rl);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcRu", WiiMoteEmu::PadMapping[i].Cc.Ru);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcRr", WiiMoteEmu::PadMapping[i].Cc.Rr);
|
|
||||||
iniFile.Set(SectionName.c_str(), "CcRd", WiiMoteEmu::PadMapping[i].Cc.Rd);
|
|
||||||
|
|
||||||
// Save the physical device ID number
|
|
||||||
iniFile.Set(SectionName.c_str(), "DeviceID", WiiMoteEmu::PadMapping[i].ID);
|
|
||||||
// ===================
|
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
// Joypad specific settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
// Current joypad device ID: PadMapping[i].ID
|
|
||||||
// Current joypad name: joyinfo[PadMapping[i].ID].Name
|
|
||||||
|
|
||||||
/* Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
|
|
||||||
avoid reading a joyinfo that does't exist */
|
|
||||||
if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
|
|
||||||
|
|
||||||
// Create a new section name after the joypad name
|
|
||||||
SectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
|
|
||||||
|
|
||||||
iniFile.Set(SectionName.c_str(), "left_x", WiiMoteEmu::PadMapping[i].Axis.Lx);
|
|
||||||
iniFile.Set(SectionName.c_str(), "left_y", WiiMoteEmu::PadMapping[i].Axis.Ly);
|
|
||||||
iniFile.Set(SectionName.c_str(), "right_x", WiiMoteEmu::PadMapping[i].Axis.Rx);
|
|
||||||
iniFile.Set(SectionName.c_str(), "right_y", WiiMoteEmu::PadMapping[i].Axis.Ry);
|
|
||||||
iniFile.Set(SectionName.c_str(), "l_trigger", WiiMoteEmu::PadMapping[i].Axis.Tl);
|
|
||||||
iniFile.Set(SectionName.c_str(), "r_trigger", WiiMoteEmu::PadMapping[i].Axis.Tr);
|
|
||||||
|
|
||||||
iniFile.Set(SectionName.c_str(), "DeadZoneL", WiiMoteEmu::PadMapping[i].DeadZoneL);
|
|
||||||
iniFile.Set(SectionName.c_str(), "DeadZoneR", WiiMoteEmu::PadMapping[i].DeadZoneR);
|
|
||||||
//iniFile.Set(SectionName.c_str(), "controllertype", WiiMoteEmu::PadMapping[i].controllertype);
|
|
||||||
iniFile.Set(SectionName.c_str(), "TriggerType", WiiMoteEmu::PadMapping[i].triggertype);
|
|
||||||
iniFile.Set(SectionName.c_str(), "Diagonal", WiiMoteEmu::PadMapping[i].SDiagonal);
|
|
||||||
iniFile.Set(SectionName.c_str(), "Circle2Square", WiiMoteEmu::PadMapping[i].bCircle2Square);
|
|
||||||
iniFile.Set(SectionName.c_str(), "RollInvert", WiiMoteEmu::PadMapping[i].bRollInvert);
|
|
||||||
iniFile.Set(SectionName.c_str(), "PitchInvert", WiiMoteEmu::PadMapping[i].bPitchInvert);
|
|
||||||
// ======================================
|
|
||||||
}
|
|
||||||
|
|
||||||
iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini");
|
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
// Save the IR cursor settings if it's avaliable, if not save the default settings
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini");
|
|
||||||
std::string TmpSection;
|
|
||||||
if (g_ISOId) TmpSection = Hex2Ascii(g_ISOId); else TmpSection = "Default";
|
|
||||||
iniFile.Set(TmpSection.c_str(), "IRLeft", iIRLeft);
|
|
||||||
iniFile.Set(TmpSection.c_str(), "IRTop", iIRTop);
|
|
||||||
iniFile.Set(TmpSection.c_str(), "IRWidth", iIRWidth);
|
|
||||||
iniFile.Set(TmpSection.c_str(), "IRHeight", iIRHeight);
|
|
||||||
iniFile.Save(FULL_CONFIG_DIR "IR Pointer.ini");
|
|
||||||
// =============================
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
INFO_LOG(CONSOLE, "Save()\n");
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright (C) 2003-2009 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 _PLUGIN_WIIMOTE_CONFIG_H
|
|
||||||
#define _PLUGIN_WIIMOTE_CONFIG_H
|
|
||||||
|
|
||||||
|
|
||||||
struct Config
|
|
||||||
{
|
|
||||||
Config();
|
|
||||||
void Load(bool ChangePad = false);
|
|
||||||
void Save(int Slot = -1);
|
|
||||||
|
|
||||||
struct PadRange
|
|
||||||
{
|
|
||||||
int Roll;
|
|
||||||
int Pitch;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PadTrigger
|
|
||||||
{
|
|
||||||
enum ETriggerType
|
|
||||||
{
|
|
||||||
TRIGGER_OFF = 0,
|
|
||||||
KEYBOARD,
|
|
||||||
ANALOG1,
|
|
||||||
ANALOG2,
|
|
||||||
TRIGGER
|
|
||||||
};
|
|
||||||
int Type;
|
|
||||||
PadRange Range;
|
|
||||||
};
|
|
||||||
struct PadNunchuck
|
|
||||||
{
|
|
||||||
enum ENunchuckStick
|
|
||||||
{
|
|
||||||
KEYBOARD,
|
|
||||||
ANALOG1,
|
|
||||||
ANALOG2
|
|
||||||
};
|
|
||||||
int Type;
|
|
||||||
};
|
|
||||||
struct PadClassicController
|
|
||||||
{
|
|
||||||
enum ECcStick
|
|
||||||
{
|
|
||||||
KEYBOARD,
|
|
||||||
ANALOG1,
|
|
||||||
ANALOG2,
|
|
||||||
TRIGGER
|
|
||||||
};
|
|
||||||
int LType;
|
|
||||||
int RType;
|
|
||||||
int TType;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Emulated Wiimote
|
|
||||||
bool bSidewaysDPad;
|
|
||||||
bool bWideScreen;
|
|
||||||
bool bNunchuckConnected, bClassicControllerConnected;
|
|
||||||
|
|
||||||
// Real Wiimote
|
|
||||||
bool bConnectRealWiimote, bUseRealWiimote, bUpdateRealWiimote;
|
|
||||||
int iIRLeft, iIRTop, iIRWidth, iIRHeight;
|
|
||||||
int iAccNeutralX, iAccNeutralY, iAccNeutralZ;
|
|
||||||
int iAccNunNeutralX, iAccNunNeutralY, iAccNunNeutralZ;
|
|
||||||
|
|
||||||
// Gamepad
|
|
||||||
bool bNoTriggerFilter;
|
|
||||||
PadTrigger Trigger;
|
|
||||||
PadNunchuck Nunchuck;
|
|
||||||
PadClassicController ClassicController;
|
|
||||||
|
|
||||||
// Screen size settings
|
|
||||||
bool bKeepAR43, bKeepAR169, bCrop;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Config g_Config;
|
|
||||||
|
|
||||||
#endif // _PLUGIN_WIIMOTE_CONFIG_H
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,275 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 __CONFIGDIALOG_h__
|
|
||||||
#define __CONFIGDIALOG_h__
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <wx/wx.h>
|
|
||||||
#include <wx/dialog.h>
|
|
||||||
#include <wx/textctrl.h>
|
|
||||||
#include <wx/button.h>
|
|
||||||
#include <wx/stattext.h>
|
|
||||||
#include <wx/combobox.h>
|
|
||||||
#include <wx/checkbox.h>
|
|
||||||
#include <wx/notebook.h>
|
|
||||||
#include <wx/panel.h>
|
|
||||||
#include <wx/filepicker.h>
|
|
||||||
#include <wx/gbsizer.h>
|
|
||||||
#include <wx/progdlg.h>
|
|
||||||
|
|
||||||
class ConfigDialog : public wxDialog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConfigDialog(wxWindow *parent, wxWindowID id = 1,
|
|
||||||
const wxString &title = wxT("Wii Remote Plugin Configuration"),
|
|
||||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
|
||||||
long style = wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS);
|
|
||||||
virtual ~ConfigDialog();
|
|
||||||
|
|
||||||
// General open, close and event functions
|
|
||||||
void CloseClick(wxCommandEvent& event);
|
|
||||||
void UpdateGUI(int Slot = 0); void UpdateGUIButtonMapping(int controller); void UpdateControls();
|
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
|
||||||
void LoadFile(); void SaveFile();
|
|
||||||
|
|
||||||
// Timers
|
|
||||||
wxTimer *m_TimeoutTimer, *m_ShutDownTimer, *m_TimeoutOnce, *m_ButtonMappingTimer, *m_UpdatePad;
|
|
||||||
|
|
||||||
// General status
|
|
||||||
wxStaticText * m_TextUpdateRate;
|
|
||||||
|
|
||||||
// Wiimote status
|
|
||||||
wxGauge *m_GaugeBattery, *m_GaugeRoll[2], *m_GaugeGForce[3], *m_GaugeAccel[3];
|
|
||||||
wxStaticBitmap *m_bmpDotLeftIn[4], *m_bmpDotLeftOut[4], *m_bmpDotRightIn[4], *m_bmpDotRightOut[4],
|
|
||||||
*m_bmpDeadZoneLeftIn[4], *m_bmpDeadZoneRightIn[4];
|
|
||||||
wxStaticText *m_TextIR;
|
|
||||||
bool m_bWaitForRecording, m_bRecording, m_bAllowA;
|
|
||||||
int m_iRecordTo;
|
|
||||||
void RecordMovement(wxCommandEvent& event);
|
|
||||||
void DoRecordMovement(int _x, int _y, int _z, const u8 *_IR, int IRBytes);
|
|
||||||
void DoRecordA(bool Pressed);
|
|
||||||
void Convert2Box(int &x);
|
|
||||||
void ConvertToString();
|
|
||||||
void Update(wxTimerEvent& WXUNUSED(event));
|
|
||||||
void ShutDown(wxTimerEvent& WXUNUSED(event));
|
|
||||||
void UpdateOnce(wxTimerEvent& event);
|
|
||||||
|
|
||||||
// Gamepad configuration
|
|
||||||
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
|
|
||||||
void UpdatePad(wxTimerEvent& WXUNUSED(event));
|
|
||||||
|
|
||||||
private:
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
|
|
||||||
bool ControlsCreated, m_bEnableUseRealWiimote; int Page, BoxW, BoxH, g_Pressed;
|
|
||||||
|
|
||||||
wxNotebook *m_Notebook;
|
|
||||||
wxPanel *m_Controller[4], *m_PageRecording;
|
|
||||||
wxButton *m_About, *m_Close, *m_Apply;
|
|
||||||
wxBoxSizer *m_MainSizer, *m_sMain[4], *m_SizeParent[4], *m_sRecordingMain;
|
|
||||||
|
|
||||||
// Emulated Wiimote key settings
|
|
||||||
wxBoxSizer *m_SizerIRPointerWidth[4], *m_SizerIRPointerHeight[4], *m_SizerIRPointerScreen[4],
|
|
||||||
*m_SizeBasicPadding[4], *m_SizeEmuPadding[4], *m_SizeRealPadding[4], *m_SizeExtensionsPadding[4],
|
|
||||||
*m_SizeBasicGeneral[4], *m_SizeBasicGeneralLeft[4], *m_SizeBasicGeneralRight[4],
|
|
||||||
*m_HorizControllers[4], *m_gC2SDeadZone[4], *m_gCircle2Square[4], *m_gCircle2SquareVert[4], *m_gDeadZone[4], *m_gDeadZoneHoriz[4], *m_HorizControllerTiltParent[4], *m_HorizControllerTilt[4], *m_TiltHoriz[4],
|
|
||||||
*m_SizeAnalogLeft[4], *m_SizeAnalogLeftHorizX[4], *m_SizeAnalogLeftHorizY[4], *m_SizeAnalogRight[4], *m_SizeAnalogRightHorizX[4], *m_SizeAnalogRightHorizY[4],
|
|
||||||
*m_SizeAnalogTriggerVertLeft[4], *m_SizeAnalogTriggerVertRight[4], *m_SizeAnalogTriggerHorizInput[4],
|
|
||||||
// Nunchuck
|
|
||||||
*m_SNcShake[4], *m_SNcZ[4], *m_SNcC[4], *m_SNcL[4], *m_SNcR[4], *m_SNcU[4], *m_SNcD[4],
|
|
||||||
// Wiimote
|
|
||||||
*m_SWmVertLeft[4], *m_SWmVertRight[4], *m_SWmShake[4], *m_SWmPitchL[4], *m_SWmPitchR[4], *m_SWmA[4], *m_SWmB[4], *m_SWm1[4], *m_SWm2[4], *m_SWmP[4], *m_SWmM[4], *m_SWmH[4], *m_SWmL[4], *m_SWmR[4], *m_SWmU[4], *m_SWmD[4],
|
|
||||||
*m_HorizControllerMapping[4], *m_NunchuckStick[4],
|
|
||||||
// Classic Controller
|
|
||||||
*m_SCcVertLeft[4], *m_SCcVertMiddle[4], *m_SCcVertRight[4],
|
|
||||||
*m_SCcLeftStick[4], *m_SCcRightStick[4], *m_SCcTriggers[4],
|
|
||||||
*m_SCcA[4], *m_SCcB[4], *m_SCcX[4], *m_SCcY[4],
|
|
||||||
*m_SCcP[4], *m_SCcM[4], *m_SCcH[4],
|
|
||||||
*m_SCcTl[4], *m_SCcZl[4], *m_SCcZr[4], *m_SCcTr[4],
|
|
||||||
*m_SCcDl[4], *m_SCcDu[4], *m_SCcDr[4], *m_SCcDd[4],
|
|
||||||
*m_SCcLl[4], *m_SCcLu[4], *m_SCcLr[4], *m_SCcLd[4],
|
|
||||||
*m_SCcRl[4], *m_SCcRu[4], *m_SCcRr[4], *m_SCcRd[4];
|
|
||||||
wxGridBagSizer *m_SizeAnalogTriggerHorizConfig[4], *m_SizeAnalogTriggerStatusBox[4], *m_TiltGrid[4],
|
|
||||||
*m_GridLeftStick[4], *m_GridRightStick[4];
|
|
||||||
wxStaticBoxSizer *m_SizeBasic[4], *m_SizeEmu[4], *m_SizeReal[4], *m_SizeExtensions[4], *m_SizerIRPointer[4], *m_gTilt[4], *m_gJoyname[4];
|
|
||||||
wxTextCtrl *m_AnalogLeftX[4], *m_AnalogLeftY[4], *m_AnalogRightX[4], *m_AnalogRightY[4],
|
|
||||||
*m_AnalogTriggerL[4], *m_AnalogTriggerR[4];
|
|
||||||
wxButton *m_bAnalogLeftX[4], *m_bAnalogLeftY[4], *m_bAnalogRightX[4], *m_bAnalogRightY[4],
|
|
||||||
*m_bAnalogTriggerL[4], *m_bAnalogTriggerR[4],
|
|
||||||
// Nunchuck
|
|
||||||
*m_bNcShake[4], *m_bNcZ[4], *m_bNcC[4], *m_bNcL[4], *m_bNcR[4], *m_bNcU[4], *m_bNcD[4],
|
|
||||||
// Wiimote
|
|
||||||
*m_bWmShake[4], *m_bWmPitchL[4], *m_bWmPitchR[4], *m_bWmA[4], *m_bWmB[4], *m_bWm1[4], *m_bWm2[4], *m_bWmP[4], *m_bWmM[4], *m_bWmH[4], *m_bWmD[4], *m_bWmU[4], *m_bWmR[4], *m_bWmL[4],
|
|
||||||
// Classic Controller
|
|
||||||
*m_bCcA[4], *m_bCcB[4], *m_bCcX[4], *m_bCcY[4],
|
|
||||||
*m_bCcP[4], *m_bCcM[4], *m_bCcH[4],
|
|
||||||
*m_bCcTl[4], *m_bCcZl[4], *m_bCcZr[4], *m_bCcTr[4],
|
|
||||||
*m_bCcDl[4], *m_bCcDu[4], *m_bCcDr[4], *m_bCcDd[4],
|
|
||||||
*m_bCcLl[4], *m_bCcLu[4], *m_bCcLr[4], *m_bCcLd[4],
|
|
||||||
*m_bCcRl[4], *m_bCcRu[4], *m_bCcRr[4], *m_bCcRd[4];
|
|
||||||
wxStaticText *m_TextScreenWidth[4], *m_TextScreenHeight[4], *m_TextScreenLeft[4], *m_TextScreenTop[4], *m_TextAR[4],
|
|
||||||
*m_tAnalogX[8], *m_tAnalogY[8], *m_TiltTextRoll[4], *m_TiltTextPitch[4],
|
|
||||||
*m_CheckC2SLabel[4], *m_ComboDeadZoneLabel[4], *m_TStatusLeftIn[4], *m_TStatusLeftOut[4], *m_TStatusRightIn[4], *m_TStatusRightOut[4],
|
|
||||||
*m_TriggerStatusL[4], *m_TriggerStatusR[4], *m_TriggerStatusLx[4], *m_TriggerStatusRx[4],
|
|
||||||
*m_tAnalogTriggerInput[4], *m_tAnalogTriggerL[4], *m_tAnalogTriggerR[4],
|
|
||||||
// Nunchuck
|
|
||||||
*m_tNcShake[4], *m_tNcZ[4], *m_tNcC[4], *m_tNcL[4], *m_tNcR[4], *m_tNcU[4], *m_tNcD[4],
|
|
||||||
// Wiimote
|
|
||||||
*m_tWmShake[4], *m_tWmPitchL[4], *m_tWmPitchR[4], *m_tWmA[4], *m_tWmB[4], *m_tWm1[4], *m_tWm2[4], *m_tWmP[4], *m_tWmM[4], *m_tWmH[4], *m_tWmL[4], *m_tWmR[4], *m_tWmU[4],*m_tWmD[4],
|
|
||||||
*m_NunchuckTextStick[5],
|
|
||||||
// Classic Controller
|
|
||||||
*m_tCcA[4], *m_tCcB[4], *m_tCcX[4], *m_tCcY[4],
|
|
||||||
*m_tCcP[4], *m_tCcM[4], *m_tCcH[4],
|
|
||||||
*m_tCcTl[4], *m_tCcZl[4], *m_tCcZr[4], *m_tCcTr[4],
|
|
||||||
*m_tCcDl[4], *m_tCcDu[4], *m_tCcDr[4], *m_tCcDd[4],
|
|
||||||
*m_tCcLl[4], *m_tCcLu[4], *m_tCcLr[4], *m_tCcLd[4],
|
|
||||||
*m_tCcRl[4], *m_tCcRu[4], *m_tCcRr[4], *m_tCcRd[4],
|
|
||||||
*m_CcTextLeftStick[4], *m_CcTextRightStick[4], *m_CcTextTriggers[4];
|
|
||||||
wxButton *ClickedButton;
|
|
||||||
wxString OldLabel;
|
|
||||||
wxSlider *m_SliderWidth[4], *m_SliderHeight[4], *m_SliderLeft[4], *m_SliderTop[4];
|
|
||||||
|
|
||||||
// Emulated Wiimote settings
|
|
||||||
wxCheckBox *m_SidewaysDPad[4], *m_WiimoteOnline[4],
|
|
||||||
*m_CheckC2S[4], *m_TiltInvertRoll[4], *m_TiltInvertPitch[4],
|
|
||||||
*m_WiiMotionPlusConnected[4], *m_NunchuckConnected[4], *m_ClassicControllerConnected[4], *m_BalanceBoardConnected[4], *m_GuitarHeroGuitarConnected[4], *m_GuitarHeroWorldTourDrumsConnected[4],
|
|
||||||
*m_CheckAR43[4], *m_CheckAR169[4], *m_Crop[4];
|
|
||||||
wxComboBox *m_TiltComboInput[4], *m_TiltComboRangeRoll[4], *m_TiltComboRangePitch[4], *m_Joyname[4], *m_ComboDiagonal[4], *m_ComboDeadZoneLeft[4], *m_ComboDeadZoneRight[4], *m_TriggerType[4],
|
|
||||||
*m_NunchuckComboStick[4], *m_CcComboLeftStick[4], *m_CcComboRightStick[4], *m_CcComboTriggers[4];
|
|
||||||
|
|
||||||
// Real Wiimote settings
|
|
||||||
wxCheckBox *m_ConnectRealWiimote[4], *m_UseRealWiimote[4], *m_UpdateMeters;
|
|
||||||
|
|
||||||
wxPanel *m_pLeftInStatus[4], *m_pLeftOutStatus[4], *m_pRightInStatus[4], *m_pRightOutStatus[4];
|
|
||||||
wxStaticBitmap *m_bmpSquareLeftIn[4], *m_bmpSquareLeftOut[4], *m_bmpSquareRightIn[4], *m_bmpSquareRightOut[4];
|
|
||||||
wxStaticBoxSizer *m_gAnalogLeft[4], *m_gAnalogRight[4], *m_gTrigger[4],
|
|
||||||
*m_gWiimote[4], *m_gNunchuck[4], *m_gClassicController[4];
|
|
||||||
wxBitmap CreateBitmapDot(), CreateBitmap(), CreateBitmapDeadZone(int Radius), CreateBitmapClear();
|
|
||||||
|
|
||||||
wxButton * m_RecordButton[RECORDING_ROWS + 1];
|
|
||||||
wxChoice * m_RecordHotKeySwitch[RECORDING_ROWS + 1];
|
|
||||||
wxChoice * m_RecordHotKeyWiimote[RECORDING_ROWS + 1];
|
|
||||||
wxChoice * m_RecordHotKeyNunchuck[RECORDING_ROWS + 1];
|
|
||||||
wxChoice * m_RecordHotKeyIR[RECORDING_ROWS + 1];
|
|
||||||
wxTextCtrl * m_RecordText[RECORDING_ROWS + 1];
|
|
||||||
wxTextCtrl * m_RecordGameText[RECORDING_ROWS + 1];
|
|
||||||
wxTextCtrl * m_RecordIRBytesText[RECORDING_ROWS + 1];
|
|
||||||
wxTextCtrl * m_RecordSpeed[RECORDING_ROWS + 1];
|
|
||||||
wxChoice * m_RecordPlayBackSpeed[RECORDING_ROWS + 1];
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct m_sRecording
|
|
||||||
{
|
|
||||||
u8 x;
|
|
||||||
u8 y;
|
|
||||||
u8 z;
|
|
||||||
double Time;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
std::vector<SRecording> m_vRecording;
|
|
||||||
int IRBytes;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ID_CLOSE = 1000,
|
|
||||||
ID_APPLY,
|
|
||||||
ID_ABOUTOGL,
|
|
||||||
IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATE_ONCE, IDTM_BUTTON, IDTM_UPDATE_PAD, // Timer
|
|
||||||
|
|
||||||
ID_NOTEBOOK, ID_CONTROLLERPAGE1, ID_CONTROLLERPAGE2, ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, ID_PAGE_RECORDING,
|
|
||||||
|
|
||||||
// Emulated Wiimote
|
|
||||||
ID_SIDEWAYSDPAD,
|
|
||||||
ID_NUNCHUCKCONNECTED, ID_CLASSICCONTROLLERCONNECTED,
|
|
||||||
IDC_WIMOTE_ON,
|
|
||||||
|
|
||||||
// Gamepad <It's important that the internal ordering of these are unchanged>
|
|
||||||
IDB_ANALOG_LEFT_X, IDB_ANALOG_LEFT_Y,
|
|
||||||
IDB_ANALOG_RIGHT_X, IDB_ANALOG_RIGHT_Y,
|
|
||||||
IDB_TRIGGER_L, IDB_TRIGGER_R,
|
|
||||||
|
|
||||||
ID_ANALOG_LEFT_X, ID_ANALOG_LEFT_Y,
|
|
||||||
ID_ANALOG_RIGHT_X, ID_ANALOG_RIGHT_Y,
|
|
||||||
ID_TRIGGER_L, ID_TRIGGER_R,
|
|
||||||
|
|
||||||
// Wiimote
|
|
||||||
IDS_WIDTH, IDS_HEIGHT, IDS_LEFT, IDS_TOP,
|
|
||||||
IDB_WM_A, IDB_WM_B,
|
|
||||||
IDB_WM_1, IDB_WM_2,
|
|
||||||
IDB_WM_P, IDB_WM_M, IDB_WM_H,
|
|
||||||
IDB_WM_L, IDB_WM_R, IDB_WM_U, IDB_WM_D,
|
|
||||||
IDB_WM_SHAKE, IDB_WM_PITCH_L, IDB_WM_PITCH_R,
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
IDB_NC_Z, IDB_NC_C, IDB_NC_L, IDB_NC_R, IDB_NC_U, IDB_NC_D,
|
|
||||||
IDB_NC_SHAKE,
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
IDB_CC_A, IDB_CC_B,
|
|
||||||
IDB_CC_X, IDB_CC_Y,
|
|
||||||
IDB_CC_P, IDB_CC_M, IDB_CC_H,
|
|
||||||
IDB_CC_TL, IDB_CC_ZL, IDB_CC_ZR, IDB_CC_TR,
|
|
||||||
IDB_CC_DL, IDB_CC_DU, IDB_CC_DR, IDB_CC_DD, // Digital pad
|
|
||||||
IDB_CC_LL, IDB_CC_LU, IDB_CC_LR, IDB_CC_LD, // Left analog stick
|
|
||||||
IDB_CC_RL, IDB_CC_RU, IDB_CC_RR, IDB_CC_RD, // Right analog stick
|
|
||||||
|
|
||||||
// Gamepad settings
|
|
||||||
IDC_JOYNAME, IDC_LEFT_C2S, IDCB_LEFT_DIAGONAL, IDCB_DEAD_ZONE_LEFT, IDCB_DEAD_ZONE_RIGHT,
|
|
||||||
ID_TRIGGER_TYPE, ID_TILT_INPUT, ID_TILT_RANGE_ROLL, ID_TILT_RANGE_PITCH, ID_TILT_INVERT_ROLL, ID_TILT_INVERT_PITCH,
|
|
||||||
IDCB_NUNCHUCK_STICK, IDCB_CC_LEFT_STICK, IDCB_CC_RIGHT_STICK, IDCB_CC_TRIGGERS,
|
|
||||||
|
|
||||||
// Real
|
|
||||||
ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS,
|
|
||||||
IDB_RECORD = 2000,
|
|
||||||
IDC_RECORD = 3000,
|
|
||||||
IDC_PLAY_WIIMOTE, IDC_PLAY_NUNCHUCK, IDC_PLAY_IR, IDT_RECORD_TEXT, IDT_RECORD_GAMETEXT, IDT_RECORD_IRBYTESTEXT, IDT_RECORD_SPEED, IDT_RECORD_PLAYSPEED
|
|
||||||
};
|
|
||||||
|
|
||||||
void OnClose(wxCloseEvent& event);
|
|
||||||
void CreateGUIControls();
|
|
||||||
void CreateGUIControlsRecording();
|
|
||||||
void AboutClick(wxCommandEvent& event);
|
|
||||||
void GeneralSettingsChanged(wxCommandEvent& event);
|
|
||||||
void GeneralSettingsChangedScroll(wxScrollEvent& event);
|
|
||||||
|
|
||||||
void DoConnectReal(); // Real
|
|
||||||
void DoUseReal();
|
|
||||||
|
|
||||||
void DoExtensionConnectedDisconnected(int Extension = -1); // Emulated
|
|
||||||
|
|
||||||
// Gamepad configuration
|
|
||||||
void SetButtonText(int id, char text[128], int _Page = -1); void SetButtonTextAll(int id, char text[128]);
|
|
||||||
wxString GetButtonText(int id, int Page = -1);
|
|
||||||
void GetButtons(wxCommandEvent& event); void DoGetButtons(int);
|
|
||||||
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void SaveButtonMappingAll(int Slot);
|
|
||||||
void SaveKeyboardMapping(int Controller, int Id, int Key);
|
|
||||||
void ToBlank(bool ToBlank = true);
|
|
||||||
void PadGetStatus();
|
|
||||||
void DoSave(bool ChangePad = false, int Slot = -1);
|
|
||||||
void DoChangeJoystick(); void PadOpen(int Open); void PadClose(int Close); void DoChangeDeadZone(bool Left);
|
|
||||||
void OnButtonClick(wxCommandEvent& event);
|
|
||||||
|
|
||||||
// Configure buttons
|
|
||||||
int GetButtonWaitingID, GetButtonWaitingTimer;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern ConfigDialog *frame;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,815 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
#include "CommonTypes.h" // for u16
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include "wiimote_real.h" // Local
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "ConfigDlg.h"
|
|
||||||
#include "Config.h"
|
|
||||||
#include "EmuMain.h" // for LoadRecordedMovements()
|
|
||||||
#include "EmuSubroutines.h" // for WmRequestStatus
|
|
||||||
#include "EmuDefinitions.h" // for joyinfo
|
|
||||||
|
|
||||||
|
|
||||||
// Change Joystick
|
|
||||||
/* Function: When changing the joystick we save and load the settings and
|
|
||||||
update the PadMapping and PadState array. PadState[].joy is the gamepad
|
|
||||||
handle that is used to access the pad throughout the plugin. Joyinfo[].joy
|
|
||||||
is only used the first time the pads are checked. */
|
|
||||||
void ConfigDialog::DoChangeJoystick()
|
|
||||||
{
|
|
||||||
// Close the current pad, unless it's used by another slot
|
|
||||||
//if (PadMapping[notebookpage].enabled) PadClose(notebookpage);
|
|
||||||
|
|
||||||
// Before changing the pad we save potential changes to the current pad
|
|
||||||
DoSave(true);
|
|
||||||
|
|
||||||
// Load the settings for the new Id
|
|
||||||
g_Config.Load(true);
|
|
||||||
UpdateGUI(Page); // Update the GUI
|
|
||||||
|
|
||||||
// Open the new pad
|
|
||||||
if (WiiMoteEmu::PadMapping[Page].enabled) PadOpen(Page);
|
|
||||||
}
|
|
||||||
void ConfigDialog::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
|
|
||||||
{
|
|
||||||
// Check that we got a good pad
|
|
||||||
if (!WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Open].ID).Good)
|
|
||||||
{
|
|
||||||
INFO_LOG(CONSOLE, "A bad pad was selected\n");
|
|
||||||
WiiMoteEmu::PadState[Open].joy = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "Update the Slot %i handle to Id %i\n", Page, WiiMoteEmu::PadMapping[Open].ID);
|
|
||||||
WiiMoteEmu::PadState[Open].joy = SDL_JoystickOpen(WiiMoteEmu::PadMapping[Open].ID);
|
|
||||||
}
|
|
||||||
void ConfigDialog::PadClose(int _Close) // Close for slot 1, 2, 3 or 4
|
|
||||||
{
|
|
||||||
if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[_Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[_Close].joy);
|
|
||||||
WiiMoteEmu::PadState[_Close].joy = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigDialog::DoChangeDeadZone(bool Left)
|
|
||||||
{
|
|
||||||
if(Left)
|
|
||||||
{
|
|
||||||
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL * ((float)BoxW / 100.0) * 0.5;
|
|
||||||
m_bmpDeadZoneLeftIn[Page]->SetBitmap(CreateBitmapClear());
|
|
||||||
m_bmpDeadZoneLeftIn[Page]->SetSize(0, 0);
|
|
||||||
m_bmpDeadZoneLeftIn[Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
|
|
||||||
m_bmpDeadZoneLeftIn[Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
|
|
||||||
m_bmpDeadZoneLeftIn[Page]->Refresh();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float Rad = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR * ((float)BoxW / 100.0) * 0.5;
|
|
||||||
m_bmpDeadZoneRightIn[Page]->SetBitmap(CreateBitmapClear());
|
|
||||||
m_bmpDeadZoneRightIn[Page]->SetSize(0, 0);
|
|
||||||
m_bmpDeadZoneRightIn[Page]->SetBitmap(CreateBitmapDeadZone((int)Rad));
|
|
||||||
m_bmpDeadZoneRightIn[Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad));
|
|
||||||
m_bmpDeadZoneRightIn[Page]->Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Change settings
|
|
||||||
|
|
||||||
// Set the button text for all four Wiimotes
|
|
||||||
void ConfigDialog::SetButtonTextAll(int id, char text[128])
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 1; i++)
|
|
||||||
{
|
|
||||||
// Safety check to avoid crash
|
|
||||||
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
|
|
||||||
if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Page].ID].Name)
|
|
||||||
SetButtonText(id, text, i);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ConfigDialog::SaveButtonMappingAll(int Slot)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "SaveButtonMappingAll()\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
// This can occur when no gamepad is detected
|
|
||||||
if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
|
|
||||||
if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Slot].ID].Name)
|
|
||||||
SaveButtonMapping(i, false, Slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set dialog items from saved values
|
|
||||||
void ConfigDialog::UpdateGUIButtonMapping(int controller)
|
|
||||||
{
|
|
||||||
// Temporary storage
|
|
||||||
wxString tmp;
|
|
||||||
|
|
||||||
// Update selected gamepad
|
|
||||||
m_Joyname[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].ID);
|
|
||||||
|
|
||||||
// Update the enabled checkbox
|
|
||||||
//m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false);
|
|
||||||
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Lx; m_AnalogLeftX[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Ly; m_AnalogLeftY[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Rx; m_AnalogRightX[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Ry; m_AnalogRightY[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Tl; m_AnalogTriggerL[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
tmp << WiiMoteEmu::PadMapping[controller].Axis.Tr; m_AnalogTriggerR[controller]->SetValue(tmp); tmp.clear();
|
|
||||||
|
|
||||||
// Update the deadzone and controller type controls
|
|
||||||
m_TriggerType[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].triggertype);
|
|
||||||
m_ComboDeadZoneLeft[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].DeadZoneL);
|
|
||||||
m_ComboDeadZoneRight[controller]->SetSelection(WiiMoteEmu::PadMapping[controller].DeadZoneR);
|
|
||||||
m_ComboDiagonal[controller]->SetValue(wxString::FromAscii(WiiMoteEmu::PadMapping[controller].SDiagonal.c_str()));
|
|
||||||
m_CheckC2S[controller]->SetValue(WiiMoteEmu::PadMapping[controller].bCircle2Square);
|
|
||||||
m_TiltInvertRoll[controller]->SetValue(WiiMoteEmu::PadMapping[controller].bRollInvert);
|
|
||||||
m_TiltInvertPitch[controller]->SetValue(WiiMoteEmu::PadMapping[controller].bPitchInvert);
|
|
||||||
|
|
||||||
// Wiimote
|
|
||||||
#ifdef _WIN32
|
|
||||||
m_bWmA[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.A).c_str()));
|
|
||||||
m_bWmB[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.B).c_str()));
|
|
||||||
m_bWm1[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.One).c_str()));
|
|
||||||
m_bWm2[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.Two).c_str()));
|
|
||||||
m_bWmP[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.P).c_str()));
|
|
||||||
m_bWmM[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.M).c_str()));
|
|
||||||
m_bWmH[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.H).c_str()));
|
|
||||||
m_bWmL[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.L).c_str()));
|
|
||||||
m_bWmR[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.R).c_str()));
|
|
||||||
m_bWmU[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.U).c_str()));
|
|
||||||
m_bWmD[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.D).c_str()));
|
|
||||||
m_bWmShake[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.Shake).c_str()));
|
|
||||||
m_bWmPitchL[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.PitchL).c_str()));
|
|
||||||
m_bWmPitchR[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.PitchR).c_str()));
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
m_bNcZ[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.Z).c_str()));
|
|
||||||
m_bNcC[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.C).c_str()));
|
|
||||||
m_bNcL[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.L).c_str()));
|
|
||||||
m_bNcR[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.R).c_str()));
|
|
||||||
m_bNcU[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.U).c_str()));
|
|
||||||
m_bNcD[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.D).c_str()));
|
|
||||||
m_bNcShake[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Nc.Shake).c_str()));
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
m_bCcA[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.A).c_str()));
|
|
||||||
m_bCcB[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.B).c_str()));
|
|
||||||
m_bCcX[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.X).c_str()));
|
|
||||||
m_bCcY[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Y).c_str()));
|
|
||||||
m_bCcP[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.P).c_str()));
|
|
||||||
m_bCcM[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.M).c_str()));
|
|
||||||
m_bCcH[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.H).c_str()));
|
|
||||||
m_bCcTl[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Tl).c_str()));
|
|
||||||
m_bCcZl[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Zl).c_str()));
|
|
||||||
m_bCcZr[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Zr).c_str()));
|
|
||||||
m_bCcTr[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Tr).c_str()));
|
|
||||||
m_bCcDl[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Dl).c_str()));
|
|
||||||
m_bCcDu[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Du).c_str()));
|
|
||||||
m_bCcDr[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Dr).c_str()));
|
|
||||||
m_bCcDd[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Dd).c_str()));
|
|
||||||
m_bCcLl[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Ll).c_str()));
|
|
||||||
m_bCcLu[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Lu).c_str()));
|
|
||||||
m_bCcLr[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Lr).c_str()));
|
|
||||||
m_bCcLd[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Ld).c_str()));
|
|
||||||
m_bCcRl[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Rl).c_str()));
|
|
||||||
m_bCcRu[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Ru).c_str()));
|
|
||||||
m_bCcRr[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Rr).c_str()));
|
|
||||||
m_bCcRd[controller]->SetLabel(wxString::FromAscii(InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Cc.Rd).c_str()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "m_bWmA[%i] = %i = %s\n", controller, WiiMoteEmu::PadMapping[controller].Wm.A, InputCommon::VKToString(WiiMoteEmu::PadMapping[controller].Wm.A).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Populate the PadMapping array with the dialog items settings (for example
|
|
||||||
selected joystick, enabled or disabled status and so on) */
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
void ConfigDialog::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
|
|
||||||
{
|
|
||||||
// Temporary storage
|
|
||||||
wxString tmp;
|
|
||||||
long value;
|
|
||||||
|
|
||||||
// Save from or to the same or different slots
|
|
||||||
if (FromSlot == -1) FromSlot = controller;
|
|
||||||
|
|
||||||
// Replace "" with "-1" in the GUI controls
|
|
||||||
ToBlank(false);
|
|
||||||
|
|
||||||
/* Set physical device Id. GetSelection() should never be -1 here so we don't check that it's zero or higher. If it's possible that it can be
|
|
||||||
-1 that's a bug that should be fixed. Because the m_Joyname[] combo box should always show <No Gamepad Detected>, or a gamepad name, not a
|
|
||||||
a blank selection. */
|
|
||||||
if (!DontChangeId)
|
|
||||||
WiiMoteEmu::PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
|
|
||||||
// Set enabled or disable status
|
|
||||||
if (FromSlot == controller)
|
|
||||||
WiiMoteEmu::PadMapping[controller].enabled = true; //m_Joyattach[FromSlot]->GetValue(); // Only enable one
|
|
||||||
// Set other settings
|
|
||||||
//WiiMoteEmu::PadMapping[controller].controllertype = m_ControlType[FromSlot]->GetSelection();
|
|
||||||
WiiMoteEmu::PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
|
|
||||||
WiiMoteEmu::PadMapping[controller].DeadZoneL = m_ComboDeadZoneLeft[FromSlot]->GetSelection();
|
|
||||||
WiiMoteEmu::PadMapping[controller].DeadZoneR = m_ComboDeadZoneRight[FromSlot]->GetSelection();
|
|
||||||
WiiMoteEmu::PadMapping[controller].SDiagonal = m_ComboDiagonal[FromSlot]->GetLabel().mb_str();
|
|
||||||
WiiMoteEmu::PadMapping[controller].bCircle2Square = m_CheckC2S[FromSlot]->IsChecked();
|
|
||||||
WiiMoteEmu::PadMapping[controller].bRollInvert = m_TiltInvertRoll[FromSlot]->IsChecked();
|
|
||||||
WiiMoteEmu::PadMapping[controller].bPitchInvert = m_TiltInvertPitch[FromSlot]->IsChecked();
|
|
||||||
|
|
||||||
// The analog buttons
|
|
||||||
m_AnalogLeftX[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Lx = value; tmp.clear();
|
|
||||||
m_AnalogLeftY[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Ly = value; tmp.clear();
|
|
||||||
m_AnalogRightX[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Rx = value; tmp.clear();
|
|
||||||
m_AnalogRightY[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Ry = value; tmp.clear();
|
|
||||||
|
|
||||||
// The shoulder buttons
|
|
||||||
m_AnalogTriggerL[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Tl = value;
|
|
||||||
m_AnalogTriggerR[FromSlot]->GetValue().ToLong(&value); WiiMoteEmu::PadMapping[controller].Axis.Tr = value;
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "WiiMoteEmu::PadMapping[%i].ID = %i, m_Joyname[%i]->GetSelection() = %i\n",
|
|
||||||
// controller, WiiMoteEmu::PadMapping[controller].ID, FromSlot, m_Joyname[FromSlot]->GetSelection());
|
|
||||||
|
|
||||||
// Replace "-1" with ""
|
|
||||||
ToBlank();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save keyboard key mapping
|
|
||||||
void ConfigDialog::SaveKeyboardMapping(int Controller, int Id, int Key)
|
|
||||||
{
|
|
||||||
switch(Id)
|
|
||||||
{
|
|
||||||
// Wiimote
|
|
||||||
case IDB_WM_A: WiiMoteEmu::PadMapping[Controller].Wm.A = Key; break;
|
|
||||||
case IDB_WM_B: WiiMoteEmu::PadMapping[Controller].Wm.B = Key; break;
|
|
||||||
case IDB_WM_1: WiiMoteEmu::PadMapping[Controller].Wm.One = Key; break;
|
|
||||||
case IDB_WM_2: WiiMoteEmu::PadMapping[Controller].Wm.Two = Key; break;
|
|
||||||
case IDB_WM_P: WiiMoteEmu::PadMapping[Controller].Wm.P = Key; break;
|
|
||||||
case IDB_WM_M: WiiMoteEmu::PadMapping[Controller].Wm.M = Key; break;
|
|
||||||
case IDB_WM_H: WiiMoteEmu::PadMapping[Controller].Wm.H = Key; break;
|
|
||||||
case IDB_WM_L: WiiMoteEmu::PadMapping[Controller].Wm.L = Key; break;
|
|
||||||
case IDB_WM_R: WiiMoteEmu::PadMapping[Controller].Wm.R = Key; break;
|
|
||||||
case IDB_WM_U: WiiMoteEmu::PadMapping[Controller].Wm.U = Key; break;
|
|
||||||
case IDB_WM_D: WiiMoteEmu::PadMapping[Controller].Wm.D = Key; break;
|
|
||||||
case IDB_WM_SHAKE: WiiMoteEmu::PadMapping[Controller].Wm.Shake = Key; break;
|
|
||||||
case IDB_WM_PITCH_L: WiiMoteEmu::PadMapping[Controller].Wm.PitchL = Key; break;
|
|
||||||
case IDB_WM_PITCH_R: WiiMoteEmu::PadMapping[Controller].Wm.PitchR = Key; break;
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
case IDB_NC_Z: WiiMoteEmu::PadMapping[Controller].Nc.Z = Key; break;
|
|
||||||
case IDB_NC_C: WiiMoteEmu::PadMapping[Controller].Nc.C = Key; break;
|
|
||||||
case IDB_NC_L: WiiMoteEmu::PadMapping[Controller].Nc.L = Key; break;
|
|
||||||
case IDB_NC_R: WiiMoteEmu::PadMapping[Controller].Nc.R = Key; break;
|
|
||||||
case IDB_NC_U: WiiMoteEmu::PadMapping[Controller].Nc.U = Key; break;
|
|
||||||
case IDB_NC_D: WiiMoteEmu::PadMapping[Controller].Nc.D = Key; break;
|
|
||||||
case IDB_NC_SHAKE: WiiMoteEmu::PadMapping[Controller].Nc.Shake = Key; break;
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
case IDB_CC_A: WiiMoteEmu::PadMapping[Controller].Cc.A = Key; break;
|
|
||||||
case IDB_CC_B: WiiMoteEmu::PadMapping[Controller].Cc.B = Key; break;
|
|
||||||
case IDB_CC_X: WiiMoteEmu::PadMapping[Controller].Cc.X = Key; break;
|
|
||||||
case IDB_CC_Y: WiiMoteEmu::PadMapping[Controller].Cc.Y = Key; break;
|
|
||||||
case IDB_CC_P: WiiMoteEmu::PadMapping[Controller].Cc.P = Key; break;
|
|
||||||
case IDB_CC_M: WiiMoteEmu::PadMapping[Controller].Cc.M = Key; break;
|
|
||||||
case IDB_CC_H: WiiMoteEmu::PadMapping[Controller].Cc.H = Key; break;
|
|
||||||
case IDB_CC_TL: WiiMoteEmu::PadMapping[Controller].Cc.Tl = Key; break;
|
|
||||||
case IDB_CC_ZL: WiiMoteEmu::PadMapping[Controller].Cc.Zl = Key; break;
|
|
||||||
case IDB_CC_ZR: WiiMoteEmu::PadMapping[Controller].Cc.Zr = Key; break;
|
|
||||||
case IDB_CC_TR: WiiMoteEmu::PadMapping[Controller].Cc.Tr = Key; break;
|
|
||||||
case IDB_CC_DL: WiiMoteEmu::PadMapping[Controller].Cc.Dl = Key; break;
|
|
||||||
case IDB_CC_DU: WiiMoteEmu::PadMapping[Controller].Cc.Du = Key; break;
|
|
||||||
case IDB_CC_DR: WiiMoteEmu::PadMapping[Controller].Cc.Dr = Key; break;
|
|
||||||
case IDB_CC_DD: WiiMoteEmu::PadMapping[Controller].Cc.Dd = Key; break;
|
|
||||||
case IDB_CC_LL: WiiMoteEmu::PadMapping[Controller].Cc.Ll = Key; break;
|
|
||||||
case IDB_CC_LU: WiiMoteEmu::PadMapping[Controller].Cc.Lu = Key; break;
|
|
||||||
case IDB_CC_LR: WiiMoteEmu::PadMapping[Controller].Cc.Lr = Key; break;
|
|
||||||
case IDB_CC_LD: WiiMoteEmu::PadMapping[Controller].Cc.Ld = Key; break;
|
|
||||||
case IDB_CC_RL: WiiMoteEmu::PadMapping[Controller].Cc.Rl = Key; break;
|
|
||||||
case IDB_CC_RU: WiiMoteEmu::PadMapping[Controller].Cc.Ru = Key; break;
|
|
||||||
case IDB_CC_RR: WiiMoteEmu::PadMapping[Controller].Cc.Rr = Key; break;
|
|
||||||
case IDB_CC_RD: WiiMoteEmu::PadMapping[Controller].Cc.Rd = Key; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "WiiMoteEmu::PadMapping[%i].Wm.A = %i", Controller, WiiMoteEmu::PadMapping[Controller].Wm.A);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the harder to understand -1 with "" for the sake of user friendliness
|
|
||||||
void ConfigDialog::ToBlank(bool _ToBlank)
|
|
||||||
{
|
|
||||||
if (!ControlsCreated) return;
|
|
||||||
|
|
||||||
for (int j = 0; j < 1; j++)
|
|
||||||
{
|
|
||||||
if(_ToBlank)
|
|
||||||
{
|
|
||||||
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
|
|
||||||
#ifndef _WIN32
|
|
||||||
if(GetButtonText(i, j).ToAscii() == "-1")
|
|
||||||
SetButtonText(i, (char *)"", j);
|
|
||||||
#else
|
|
||||||
if(GetButtonText(i, j) == "-1") SetButtonText(i, "", j);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
|
|
||||||
if(GetButtonText(i, j).IsEmpty()) SetButtonText(i, (char *)"-1", j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Update the textbox for the buttons
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
void ConfigDialog::SetButtonText(int id, char text[128], int _Page)
|
|
||||||
{
|
|
||||||
// Set controller value
|
|
||||||
int controller;
|
|
||||||
if (_Page == -1) controller = Page; else controller = _Page;
|
|
||||||
|
|
||||||
switch(id)
|
|
||||||
{
|
|
||||||
case IDB_ANALOG_LEFT_X: m_AnalogLeftX[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_ANALOG_LEFT_Y: m_AnalogLeftY[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_ANALOG_RIGHT_X: m_AnalogRightX[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_ANALOG_RIGHT_Y: m_AnalogRightY[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
|
|
||||||
case IDB_TRIGGER_L: m_AnalogTriggerL[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_TRIGGER_R: m_AnalogTriggerR[controller]->SetValue(wxString::FromAscii(text)); break;
|
|
||||||
|
|
||||||
// Wiimote
|
|
||||||
case IDB_WM_A: m_bWmA[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_B: m_bWmB[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_1: m_bWm1[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_2: m_bWm2[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_P: m_bWmP[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_M: m_bWmM[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_H: m_bWmH[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_L: m_bWmL[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_R: m_bWmR[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_U: m_bWmU[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_D: m_bWmD[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_SHAKE: m_bWmShake[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_PITCH_L: m_bWmPitchL[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_WM_PITCH_R: m_bWmPitchR[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
|
|
||||||
// Nunchuck
|
|
||||||
case IDB_NC_Z: m_bNcZ[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_C: m_bNcC[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_L: m_bNcL[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_R: m_bNcR[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_U: m_bNcU[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_D: m_bNcD[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_NC_SHAKE: m_bNcShake[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
|
|
||||||
// Classic Controller
|
|
||||||
case IDB_CC_A: m_bCcA[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_B: m_bCcB[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_X: m_bCcX[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_Y: m_bCcY[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_P: m_bCcP[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_M: m_bCcM[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_H: m_bCcH[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_TL: m_bCcTl[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_ZL: m_bCcZl[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_ZR: m_bCcZr[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_TR: m_bCcTr[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_DL: m_bCcDl[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_DU: m_bCcDu[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_DR: m_bCcDr[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_DD: m_bCcDd[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_LL: m_bCcLl[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_LU: m_bCcLu[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_LR: m_bCcLr[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_LD: m_bCcLd[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_RL: m_bCcRl[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_RU: m_bCcRu[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_RR: m_bCcRr[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
case IDB_CC_RD: m_bCcRd[controller]->SetLabel(wxString::FromAscii(text)); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
//INFO_LOG(CONSOLE, "SetButtonText: %s\n", text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the text in the textbox for the buttons
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
wxString ConfigDialog::GetButtonText(int id, int _Page)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "GetButtonText: %i\n", id);
|
|
||||||
|
|
||||||
// Set controller value
|
|
||||||
int controller;
|
|
||||||
if (_Page == -1) controller = Page; else controller = _Page;
|
|
||||||
|
|
||||||
switch(id)
|
|
||||||
{
|
|
||||||
// Analog Stick
|
|
||||||
case IDB_ANALOG_LEFT_X: return m_AnalogLeftX[controller]->GetValue();
|
|
||||||
case IDB_ANALOG_LEFT_Y: return m_AnalogLeftY[controller]->GetValue();
|
|
||||||
case IDB_ANALOG_RIGHT_X: return m_AnalogRightX[controller]->GetValue();
|
|
||||||
case IDB_ANALOG_RIGHT_Y: return m_AnalogRightY[controller]->GetValue();
|
|
||||||
|
|
||||||
// Shoulder Buttons
|
|
||||||
case IDB_TRIGGER_L: return m_AnalogTriggerL[controller]->GetValue();
|
|
||||||
case IDB_TRIGGER_R: return m_AnalogTriggerR[controller]->GetValue();
|
|
||||||
|
|
||||||
default: return wxString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Configure button mapping
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯
|
|
||||||
|
|
||||||
|
|
||||||
// Wait for button press
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
/* Loop or timer: There are basically two ways to do this. With a while() or
|
|
||||||
for() loop, or with a timer. The downside with the while() or for() loop is
|
|
||||||
that there is no way to stop it if the user should select to configure
|
|
||||||
another button while we are still in an old loop. What will happen then is
|
|
||||||
that we start another parallel loop (at least in Windows) that blocks the
|
|
||||||
old loop. And our only option to wait for the old loop to finish is with a
|
|
||||||
new loop, and that will block the old loop for as long as it's going
|
|
||||||
on. Therefore a timer is easier to control. */
|
|
||||||
void ConfigDialog::GetButtons(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
DoGetButtons(event.GetId());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigDialog::DoGetButtons(int _GetId)
|
|
||||||
{
|
|
||||||
// =============================================
|
|
||||||
// Collect the starting values
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// Get the current controller
|
|
||||||
int Controller = Page;
|
|
||||||
int PadID = WiiMoteEmu::PadMapping[Controller].ID;
|
|
||||||
|
|
||||||
// Get the controller and trigger type
|
|
||||||
int TriggerType = WiiMoteEmu::PadMapping[Controller].triggertype;
|
|
||||||
|
|
||||||
// Collect the accepted buttons for this slot
|
|
||||||
bool LeftRight = (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R);
|
|
||||||
|
|
||||||
bool Axis = (_GetId >= IDB_ANALOG_LEFT_X && _GetId <= IDB_TRIGGER_R)
|
|
||||||
// Don't allow SDL axis input for the shoulder buttons if XInput is selected
|
|
||||||
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R) );
|
|
||||||
|
|
||||||
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
|
|
||||||
|
|
||||||
bool Button = false; // No digital buttons allowed
|
|
||||||
|
|
||||||
bool Hat = false; // No hats allowed
|
|
||||||
|
|
||||||
bool NoTriggerFilter = g_Config.bNoTriggerFilter;
|
|
||||||
|
|
||||||
// Values used in this function
|
|
||||||
char format[128];
|
|
||||||
int Seconds = 4; // Seconds to wait for
|
|
||||||
int TimesPerSecond = 40; // How often to run the check
|
|
||||||
|
|
||||||
// Values returned from InputCommon::GetButton()
|
|
||||||
int value; // Axis value
|
|
||||||
int type; // Button type
|
|
||||||
int pressed = 0;
|
|
||||||
bool Succeed = false;
|
|
||||||
bool Stop = false; // Stop the timer
|
|
||||||
// =======================
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "Before (%i) Id:%i %i IsRunning:%i\n",
|
|
||||||
// GetButtonWaitingTimer, GetButtonWaitingID, _GetId, m_ButtonMappingTimer->IsRunning());
|
|
||||||
|
|
||||||
// If the Id has changed or the timer is not running we should start one
|
|
||||||
if( GetButtonWaitingID != _GetId || !m_ButtonMappingTimer->IsRunning() )
|
|
||||||
{
|
|
||||||
if(m_ButtonMappingTimer->IsRunning())
|
|
||||||
{
|
|
||||||
m_ButtonMappingTimer->Stop();
|
|
||||||
GetButtonWaitingTimer = 0;
|
|
||||||
|
|
||||||
// Update the old textbox
|
|
||||||
SetButtonText(GetButtonWaitingID, (char *)"");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the button Id
|
|
||||||
GetButtonWaitingID = _GetId;
|
|
||||||
|
|
||||||
// Reset the key in case we happen to have an old one
|
|
||||||
g_Pressed = 0;
|
|
||||||
|
|
||||||
// Update the text box
|
|
||||||
sprintf(format, "[%d]", Seconds);
|
|
||||||
SetButtonText(_GetId, format);
|
|
||||||
|
|
||||||
// Start the timer
|
|
||||||
#if wxUSE_TIMER
|
|
||||||
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
|
|
||||||
#endif
|
|
||||||
INFO_LOG(CONSOLE, "Timer Started for Pad:%i _GetId:%i\n"
|
|
||||||
"Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i\n",
|
|
||||||
WiiMoteEmu::PadMapping[Controller].ID, _GetId,
|
|
||||||
Axis, LeftRight, XInput, Button, Hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===============================================
|
|
||||||
// Check for buttons
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// If there is a timer but we should not create a new one
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InputCommon::GetButton(
|
|
||||||
WiiMoteEmu::joyinfo[PadID].joy, PadID, WiiMoteEmu::joyinfo[PadID].NumButtons, WiiMoteEmu::joyinfo[PadID].NumAxes, WiiMoteEmu::joyinfo[PadID].NumHats,
|
|
||||||
g_Pressed, value, type, pressed, Succeed, Stop,
|
|
||||||
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
|
|
||||||
}
|
|
||||||
// ========================= Check for keys
|
|
||||||
|
|
||||||
|
|
||||||
// ===============================================
|
|
||||||
// Process results
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// Count each time
|
|
||||||
GetButtonWaitingTimer++;
|
|
||||||
|
|
||||||
// This is run every second
|
|
||||||
if(GetButtonWaitingTimer % TimesPerSecond == 0)
|
|
||||||
{
|
|
||||||
// Current time
|
|
||||||
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
|
|
||||||
|
|
||||||
// Update text
|
|
||||||
sprintf(format, "[%d]", TmpTime);
|
|
||||||
SetButtonText(_GetId, format);
|
|
||||||
|
|
||||||
/* Debug
|
|
||||||
INFO_LOG(CONSOLE, "Keyboard: %i\n", g_Pressed);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time's up
|
|
||||||
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
|
|
||||||
{
|
|
||||||
Stop = true;
|
|
||||||
// Leave a blank mapping
|
|
||||||
SetButtonTextAll(_GetId, (char *)"-1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got a button
|
|
||||||
if(Succeed)
|
|
||||||
{
|
|
||||||
Stop = true;
|
|
||||||
// Write the number of the pressed button to the text box
|
|
||||||
sprintf(format, "%d", pressed);
|
|
||||||
SetButtonTextAll(_GetId, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the timer
|
|
||||||
if(Stop)
|
|
||||||
{
|
|
||||||
m_ButtonMappingTimer->Stop();
|
|
||||||
GetButtonWaitingTimer = 0;
|
|
||||||
|
|
||||||
/* Update the button mapping for all slots that use this device. (It
|
|
||||||
doesn't make sense to have several slots controlled by the same
|
|
||||||
device, but several DirectInput instances of different but identical
|
|
||||||
devices may possible have the same id, I don't know. So we have to
|
|
||||||
do this. The user may also have selected the same device for several
|
|
||||||
disabled slots. */
|
|
||||||
SaveButtonMappingAll(Controller);
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "Timer Stopped for Pad:%i _GetId:%i\n",
|
|
||||||
WiiMoteEmu::PadMapping[Controller].ID, _GetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got a bad button
|
|
||||||
if(g_Pressed == -1)
|
|
||||||
{
|
|
||||||
// Update text
|
|
||||||
SetButtonTextAll(_GetId, (char *)"-1");
|
|
||||||
|
|
||||||
// Notify the user
|
|
||||||
wxMessageBox(wxString::Format(wxT(
|
|
||||||
"You selected a key with a to low key code (%i), please"
|
|
||||||
" select another key with a higher key code."), pressed)
|
|
||||||
, wxT("Notice"), wxICON_INFORMATION);
|
|
||||||
}
|
|
||||||
// ======================== Process results
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
/*
|
|
||||||
INFO_LOG(CONSOLE, "Change: %i %i %i %i '%s' '%s' '%s' '%s'\n",
|
|
||||||
WiiMoteEmu::PadMapping[0].halfpress, WiiMoteEmu::PadMapping[1].halfpress, WiiMoteEmu::PadMapping[2].halfpress, WiiMoteEmu::PadMapping[3].halfpress,
|
|
||||||
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
|
|
||||||
);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Show current input status
|
|
||||||
// Convert the 0x8000 range values to BoxW and BoxH for the plot
|
|
||||||
void ConfigDialog::Convert2Box(int &x)
|
|
||||||
{
|
|
||||||
// Border adjustment
|
|
||||||
int BoxW_ = BoxW - 2;// int BoxH_ = BoxH - 2;
|
|
||||||
|
|
||||||
// Convert values
|
|
||||||
x = (BoxW_ / 2) + (x * BoxW_ / (32767 * 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the input status boxes
|
|
||||||
void ConfigDialog::PadGetStatus()
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "SDL_WasInit: %i\n", SDL_WasInit(0));
|
|
||||||
|
|
||||||
/* Return if it's not detected. The ID should never be less than zero here,
|
|
||||||
it can only be that because of a manual ini file change, but we make
|
|
||||||
that check anway. */
|
|
||||||
if(WiiMoteEmu::PadMapping[Page].ID < 0 || WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks())
|
|
||||||
{
|
|
||||||
m_TStatusLeftIn[Page]->SetLabel(wxT("Not connected"));
|
|
||||||
m_TStatusLeftOut[Page]->SetLabel(wxT("Not connected"));
|
|
||||||
m_TStatusRightIn[Page]->SetLabel(wxT("Not connected"));
|
|
||||||
m_TStatusRightOut[Page]->SetLabel(wxT("Not connected"));
|
|
||||||
m_TriggerStatusLx[Page]->SetLabel(wxT("0"));
|
|
||||||
m_TriggerStatusRx[Page]->SetLabel(wxT("0"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return if it's not enabled
|
|
||||||
if (!WiiMoteEmu::PadMapping[Page].enabled)
|
|
||||||
{
|
|
||||||
m_TStatusLeftIn[Page]->SetLabel(wxT("Not enabled"));
|
|
||||||
m_TStatusLeftOut[Page]->SetLabel(wxT("Not enabled"));
|
|
||||||
m_TStatusRightIn[Page]->SetLabel(wxT("Not enabled"));
|
|
||||||
m_TStatusRightOut[Page]->SetLabel(wxT("Not enabled"));
|
|
||||||
m_TriggerStatusLx[Page]->SetLabel(wxT("0"));
|
|
||||||
m_TriggerStatusRx[Page]->SetLabel(wxT("0"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get physical device status
|
|
||||||
// int PhysicalDevice = WiiMoteEmu::PadMapping[Page].ID;
|
|
||||||
// int TriggerType = WiiMoteEmu::PadMapping[Page].triggertype;
|
|
||||||
|
|
||||||
// Check that Dolphin is in focus, otherwise don't update the pad status
|
|
||||||
//if (IsFocus())
|
|
||||||
WiiMoteEmu::GetJoyState(WiiMoteEmu::PadState[Page], WiiMoteEmu::PadMapping[Page], Page, WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Page].ID).NumButtons);
|
|
||||||
|
|
||||||
|
|
||||||
// Analog stick
|
|
||||||
// Set Deadzones perhaps out of function
|
|
||||||
//int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
|
|
||||||
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
|
|
||||||
|
|
||||||
// Get original values
|
|
||||||
int main_x = WiiMoteEmu::PadState[Page].Axis.Lx;
|
|
||||||
int main_y = WiiMoteEmu::PadState[Page].Axis.Ly;
|
|
||||||
int right_x = WiiMoteEmu::PadState[Page].Axis.Rx;
|
|
||||||
int right_y = WiiMoteEmu::PadState[Page].Axis.Ry;
|
|
||||||
|
|
||||||
// Get adjusted values
|
|
||||||
int main_x_after = main_x, main_y_after = main_y;
|
|
||||||
int right_x_after = right_x, right_y_after = right_y;
|
|
||||||
// Produce square
|
|
||||||
if(WiiMoteEmu::PadMapping[Page].bCircle2Square)
|
|
||||||
{
|
|
||||||
std::vector<int> main_xy = InputCommon::Square2Circle(main_x, main_y, Page, WiiMoteEmu::PadMapping[Page].SDiagonal, true);
|
|
||||||
main_x_after = main_xy.at(0);
|
|
||||||
main_y_after = main_xy.at(1);
|
|
||||||
//main_x = main_xy.at(0);
|
|
||||||
//main_y = main_xy.at(1);
|
|
||||||
}
|
|
||||||
// Check dead zone
|
|
||||||
float DeadZoneLeft = (float)WiiMoteEmu::PadMapping[Page].DeadZoneL / 100.0;
|
|
||||||
float DeadZoneRight = (float)WiiMoteEmu::PadMapping[Page].DeadZoneR / 100.0;
|
|
||||||
if (InputCommon::IsDeadZone(DeadZoneLeft, main_x_after, main_y_after))
|
|
||||||
{
|
|
||||||
main_x_after = 0;
|
|
||||||
main_y_after = 0;
|
|
||||||
}
|
|
||||||
if (InputCommon::IsDeadZone(DeadZoneRight, right_x_after, right_y_after))
|
|
||||||
{
|
|
||||||
right_x_after = 0;
|
|
||||||
right_y_after = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the adjusted angles in the status box
|
|
||||||
// Change 0x8000 to 180
|
|
||||||
/*
|
|
||||||
float x8000 = 0x8000;
|
|
||||||
main_x_after = main_x_after * (180 / x8000);
|
|
||||||
main_y_after = main_y_after * (180 / x8000);
|
|
||||||
float f_main_x_after = (float)main_x_after;
|
|
||||||
float f_main_y_after = (float)main_y_after;
|
|
||||||
WiiMoteEmu::AdjustAngles(f_main_x_after, f_main_y_after);
|
|
||||||
//WiiMoteEmu::AdjustAngles(f_main_x_after, f_main_y_after, true);
|
|
||||||
main_x_after = (int)f_main_x_after;
|
|
||||||
main_y_after = (int)f_main_y_after;
|
|
||||||
// Change back 180 to 0x8000
|
|
||||||
main_x_after = main_x_after * (x8000 / 180);
|
|
||||||
main_y_after = main_y_after * (x8000 / 180);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Convert the values to fractions
|
|
||||||
float f_x = main_x / 32767.0;
|
|
||||||
float f_y = main_y / 32767.0;
|
|
||||||
float f_x_aft = main_x_after / 32767.0;
|
|
||||||
float f_y_aft = main_y_after / 32767.0;
|
|
||||||
|
|
||||||
float f_Rx = right_x / 32767.0;
|
|
||||||
float f_Ry = right_y / 32767.0;
|
|
||||||
float f_Rx_aft = right_x_after / 32767.0;
|
|
||||||
float f_Ry_aft = right_y_after / 32767.0;
|
|
||||||
|
|
||||||
m_TStatusLeftIn[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("x:%1.2f y:%1.2f"), f_x, f_y
|
|
||||||
));
|
|
||||||
m_TStatusLeftOut[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("x:%1.2f y:%1.2f"), f_x_aft, f_y_aft
|
|
||||||
));
|
|
||||||
m_TStatusRightIn[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("x:%1.2f y:%1.2f"), f_Rx, f_Ry
|
|
||||||
));
|
|
||||||
m_TStatusRightOut[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("x:%1.2f y:%1.2f"), f_Rx_aft, f_Ry_aft
|
|
||||||
));
|
|
||||||
|
|
||||||
// Adjust the values for the plot
|
|
||||||
Convert2Box(main_x); Convert2Box(main_y);
|
|
||||||
Convert2Box(right_x); Convert2Box(right_y);
|
|
||||||
|
|
||||||
Convert2Box(main_x_after); Convert2Box(main_y_after);
|
|
||||||
Convert2Box(right_x_after); Convert2Box(right_y_after);
|
|
||||||
|
|
||||||
// Adjust the dot
|
|
||||||
m_bmpDotLeftIn[Page]->SetPosition(wxPoint(main_x, main_y));
|
|
||||||
m_bmpDotLeftOut[Page]->SetPosition(wxPoint(main_x_after, main_y_after));
|
|
||||||
m_bmpDotRightIn[Page]->SetPosition(wxPoint(right_x, right_y));
|
|
||||||
m_bmpDotRightOut[Page]->SetPosition(wxPoint(right_x_after, right_y_after));
|
|
||||||
|
|
||||||
|
|
||||||
// Triggers
|
|
||||||
|
|
||||||
// Get the selected keys
|
|
||||||
long Left, Right;
|
|
||||||
m_AnalogTriggerL[Page]->GetValue().ToLong(&Left);
|
|
||||||
m_AnalogTriggerR[Page]->GetValue().ToLong(&Right);
|
|
||||||
|
|
||||||
// Get the trigger values
|
|
||||||
int TriggerLeft = WiiMoteEmu::PadState[Page].Axis.Tl;
|
|
||||||
int TriggerRight = WiiMoteEmu::PadState[Page].Axis.Tr;
|
|
||||||
|
|
||||||
// Convert the triggers values
|
|
||||||
if (WiiMoteEmu::PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
|
|
||||||
{
|
|
||||||
TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
|
|
||||||
TriggerRight = InputCommon::Pad_Convert(TriggerRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TriggerStatusLx[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("%03i"), TriggerLeft));
|
|
||||||
m_TriggerStatusRx[Page]->SetLabel(wxString::Format(
|
|
||||||
wxT("%03i"), TriggerRight));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the advanced tab
|
|
||||||
void ConfigDialog::UpdatePad(wxTimerEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
// Show the current status
|
|
||||||
/*
|
|
||||||
#ifdef SHOW_PAD_STATUS
|
|
||||||
m_pStatusBar->SetLabel(wxString::Format(
|
|
||||||
"%s", ShowStatus(notebookpage).c_str()
|
|
||||||
));
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
|
|
||||||
|
|
||||||
PadGetStatus();
|
|
||||||
}
|
|
|
@ -1,504 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
#include "CommonTypes.h" // for u16
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include "wiimote_real.h" // Local
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "ConfigDlg.h"
|
|
||||||
#include "Config.h"
|
|
||||||
#include "EmuMain.h" // for LoadRecordedMovements()
|
|
||||||
#include "EmuSubroutines.h" // for WmRequestStatus
|
|
||||||
|
|
||||||
void ConfigDialog::LoadFile()
|
|
||||||
{
|
|
||||||
INFO_LOG(CONSOLE, "LoadFile()\n");
|
|
||||||
|
|
||||||
IniFile file;
|
|
||||||
file.Load(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
|
|
||||||
for (int i = 1; i < (RECORDING_ROWS + 1); i++)
|
|
||||||
{
|
|
||||||
// Temporary storage
|
|
||||||
int iTmp;
|
|
||||||
std::string STmp;
|
|
||||||
|
|
||||||
// Get row name
|
|
||||||
std::string SaveName = StringFromFormat("Recording%i", i);
|
|
||||||
|
|
||||||
// HotKey
|
|
||||||
file.Get(SaveName.c_str(), "HotKeySwitch", &iTmp, 3); m_RecordHotKeySwitch[i]->SetSelection(iTmp);
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyWiimote", &iTmp, 10); m_RecordHotKeyWiimote[i]->SetSelection(iTmp);
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyNunchuck", &iTmp, 10); m_RecordHotKeyNunchuck[i]->SetSelection(iTmp);
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyIR", &iTmp, 10); m_RecordHotKeyIR[i]->SetSelection(iTmp);
|
|
||||||
|
|
||||||
// Movement name
|
|
||||||
file.Get(SaveName.c_str(), "MovementName", &STmp, ""); m_RecordText[i]->SetValue(wxString::FromAscii(STmp.c_str()));
|
|
||||||
|
|
||||||
// Game name
|
|
||||||
file.Get(SaveName.c_str(), "GameName", &STmp, ""); m_RecordGameText[i]->SetValue(wxString::FromAscii(STmp.c_str()));
|
|
||||||
|
|
||||||
// IR Bytes
|
|
||||||
file.Get(SaveName.c_str(), "IRBytes", &STmp, ""); m_RecordIRBytesText[i]->SetValue(wxString::FromAscii(STmp.c_str()));
|
|
||||||
|
|
||||||
// Recording speed
|
|
||||||
file.Get(SaveName.c_str(), "RecordingSpeed", &iTmp, -1);
|
|
||||||
if(iTmp != -1)
|
|
||||||
m_RecordSpeed[i]->SetValue(wxString::Format(wxT("%i"), iTmp));
|
|
||||||
else
|
|
||||||
m_RecordSpeed[i]->SetValue(wxT(""));
|
|
||||||
|
|
||||||
// Playback speed (currently always saved directly after a recording)
|
|
||||||
file.Get(SaveName.c_str(), "PlaybackSpeed", &iTmp, -1); m_RecordPlayBackSpeed[i]->SetSelection(iTmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ConfigDialog::SaveFile()
|
|
||||||
{
|
|
||||||
INFO_LOG(CONSOLE, "SaveFile\n");
|
|
||||||
|
|
||||||
IniFile file;
|
|
||||||
file.Load(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
|
|
||||||
for(int i = 1; i < (RECORDING_ROWS + 1); i++)
|
|
||||||
{
|
|
||||||
// Get row name
|
|
||||||
std::string SaveName = StringFromFormat("Recording%i", i);
|
|
||||||
|
|
||||||
// HotKey
|
|
||||||
file.Set(SaveName.c_str(), "HotKeySwitch", m_RecordHotKeySwitch[i]->GetSelection());
|
|
||||||
file.Set(SaveName.c_str(), "HotKeyWiimote", m_RecordHotKeyWiimote[i]->GetSelection());
|
|
||||||
file.Set(SaveName.c_str(), "HotKeyNunchuck", m_RecordHotKeyNunchuck[i]->GetSelection());
|
|
||||||
file.Set(SaveName.c_str(), "HotKeyIR", m_RecordHotKeyIR[i]->GetSelection());
|
|
||||||
|
|
||||||
// Movement name
|
|
||||||
file.Set(SaveName.c_str(), "MovementName", m_RecordText[i]->GetValue().c_str());
|
|
||||||
|
|
||||||
// Game name
|
|
||||||
file.Set(SaveName.c_str(), "GameName", m_RecordGameText[i]->GetValue().c_str());
|
|
||||||
|
|
||||||
// Recording speed (currently always saved directly after a recording)
|
|
||||||
/*
|
|
||||||
wxString TmpRecordSpeed = m_RecordSpeed[i]->GetValue();
|
|
||||||
if(TmpRecordSpeed.length() > 0)
|
|
||||||
int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", TmpRecordSpeed);
|
|
||||||
else
|
|
||||||
int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", "-1");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Playback speed (currently always saved directly after a recording)
|
|
||||||
file.Set(SaveName.c_str(), "PlaybackSpeed", m_RecordPlayBackSpeed[i]->GetSelection());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.Save(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
INFO_LOG(CONSOLE, "SaveFile()\n");
|
|
||||||
}
|
|
||||||
/////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create GUI
|
|
||||||
void ConfigDialog::CreateGUIControlsRecording()
|
|
||||||
{
|
|
||||||
// Real Wiimote
|
|
||||||
|
|
||||||
// Status
|
|
||||||
m_TextUpdateRate = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Update rate: 000 times/s"));
|
|
||||||
m_UpdateMeters = new wxCheckBox(m_PageRecording, ID_UPDATE_REAL, wxT("Update gauges"));
|
|
||||||
|
|
||||||
m_UpdateMeters->SetValue(g_Config.bUpdateRealWiimote);
|
|
||||||
|
|
||||||
m_UpdateMeters->SetToolTip(wxT(
|
|
||||||
"You can turn this off when a game is running to avoid a potential slowdown that may come from redrawing the\n"
|
|
||||||
"configuration screen. Remember that you also need to press '+' on your Wiimote before you can record movements."
|
|
||||||
));
|
|
||||||
|
|
||||||
// Width and height of the gauges
|
|
||||||
static const int Gw = 35, Gh = 110;
|
|
||||||
|
|
||||||
m_GaugeBattery = new wxGauge( m_PageRecording, wxID_ANY, 100, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeRoll[0] = new wxGauge( m_PageRecording, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeRoll[1] = new wxGauge( m_PageRecording, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeGForce[0] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeGForce[1] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeGForce[2] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeAccel[0] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeAccel[1] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
m_GaugeAccel[2] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
|
||||||
|
|
||||||
// The text controls
|
|
||||||
m_TextIR = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Cursor: 000 000\nDistance: 0000"));
|
|
||||||
|
|
||||||
// The sizers for all gauges together with their label
|
|
||||||
wxBoxSizer * sBoxBattery = new wxBoxSizer(wxVERTICAL);
|
|
||||||
wxBoxSizer * sBoxRoll[2];
|
|
||||||
sBoxRoll[0] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sBoxRoll[1] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
wxBoxSizer * sBoxGForce[3];
|
|
||||||
sBoxGForce[0] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sBoxGForce[1] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sBoxGForce[2] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
wxBoxSizer * sBoxAccel[3];
|
|
||||||
sBoxAccel[0] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sBoxAccel[1] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sBoxAccel[2] = new wxBoxSizer(wxVERTICAL);
|
|
||||||
|
|
||||||
wxStaticText * m_TextBattery = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Batt."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextRoll = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Roll"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextPitch = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Pitch"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
wxStaticText *m_TextX[2], *m_TextY[2], *m_TextZ[2];
|
|
||||||
m_TextX[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextX[1] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
m_TextY[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextY[1] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
m_TextZ[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextZ[1] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
|
||||||
|
|
||||||
// Row 1 Sizers
|
|
||||||
sBoxBattery->Add(m_GaugeBattery, 0, wxEXPAND | (wxALL), 0); sBoxBattery->Add(m_TextBattery, 0, wxEXPAND | (wxUP), 5);
|
|
||||||
|
|
||||||
sBoxRoll[0]->Add(m_GaugeRoll[0], 0, wxEXPAND | (wxUP | wxDOWN | wxLEFT), 0); sBoxRoll[0]->Add(m_TextRoll, 0, wxEXPAND | (wxUP), 5);
|
|
||||||
sBoxRoll[1]->Add(m_GaugeRoll[1], 0, wxEXPAND | (wxUP | wxDOWN | wxRIGHT), 0); sBoxRoll[1]->Add(m_TextPitch, 0, wxEXPAND | (wxUP), 5);
|
|
||||||
|
|
||||||
sBoxGForce[0]->Add(m_GaugeGForce[0], 0, wxEXPAND | (wxUP | wxDOWN | wxLEFT), 0); sBoxGForce[0]->Add(m_TextX[0], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
sBoxGForce[1]->Add(m_GaugeGForce[1], 0, wxEXPAND | (wxUP | wxDOWN), 0); sBoxGForce[1]->Add(m_TextY[0], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
sBoxGForce[2]->Add(m_GaugeGForce[2], 0, wxEXPAND | (wxUP | wxDOWN | wxRIGHT), 0); sBoxGForce[2]->Add(m_TextZ[0], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
|
|
||||||
sBoxAccel[0]->Add(m_GaugeAccel[0], 0, wxEXPAND | (wxUP | wxDOWN | wxLEFT), 0); sBoxAccel[0]->Add(m_TextX[1], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
sBoxAccel[1]->Add(m_GaugeAccel[1], 0, wxEXPAND | (wxUP | wxDOWN), 0); sBoxAccel[1]->Add(m_TextY[1], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
sBoxAccel[2]->Add(m_GaugeAccel[2], 0, wxEXPAND | (wxUP | wxDOWN | wxRIGHT), 0); sBoxAccel[2]->Add(m_TextZ[1], 0, wxEXPAND | (wxUP), 5);
|
|
||||||
|
|
||||||
wxStaticBoxSizer * sbRealStatus = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Status"));
|
|
||||||
wxStaticBoxSizer * sbRealIR = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("IR"));
|
|
||||||
wxStaticBoxSizer * sbRealBattery = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Battery"));
|
|
||||||
wxStaticBoxSizer * sbRealRoll = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("Roll and Pitch"));
|
|
||||||
wxStaticBoxSizer * sbRealGForce = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("G-Force"));
|
|
||||||
wxStaticBoxSizer * sbRealAccel = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("Accelerometer"));
|
|
||||||
|
|
||||||
// Status
|
|
||||||
sbRealStatus->Add(m_TextUpdateRate, 0, wxEXPAND | (wxALL), 5);
|
|
||||||
sbRealStatus->Add(m_UpdateMeters, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
|
|
||||||
|
|
||||||
sbRealIR->Add(m_TextIR, 0, wxEXPAND | (wxALL), 5);
|
|
||||||
sbRealBattery->Add(sBoxBattery, 0, wxEXPAND | (wxALL), 5);
|
|
||||||
sbRealRoll->Add(sBoxRoll[0], 0, wxEXPAND | (wxALL), 5); sbRealRoll->Add(sBoxRoll[1], 0, wxEXPAND | (wxALL), 5);
|
|
||||||
sbRealGForce->Add(sBoxGForce[0], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[1], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[2], 0, wxEXPAND | (wxALL), 5);
|
|
||||||
sbRealAccel->Add(sBoxAccel[0], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[1], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[2], 0, wxEXPAND | (wxALL), 5);
|
|
||||||
|
|
||||||
// Vertical leftmost status
|
|
||||||
wxBoxSizer * sbStatusLeft = new wxBoxSizer(wxVERTICAL);
|
|
||||||
sbStatusLeft->Add(sbRealStatus, 0, wxEXPAND | (wxLEFT), 0);
|
|
||||||
sbStatusLeft->Add(sbRealIR, 0, wxEXPAND | (wxLEFT), 0);
|
|
||||||
|
|
||||||
wxBoxSizer * sbRealWiimoteStatus = new wxBoxSizer(wxHORIZONTAL);
|
|
||||||
sbRealWiimoteStatus->Add(sbStatusLeft, 0, wxEXPAND | (wxLEFT), 0);
|
|
||||||
sbRealWiimoteStatus->Add(sbRealBattery, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sbRealWiimoteStatus->Add(sbRealRoll, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sbRealWiimoteStatus->Add(sbRealGForce, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sbRealWiimoteStatus->Add(sbRealAccel, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
|
|
||||||
// Tool tips
|
|
||||||
m_GaugeBattery->SetToolTip(wxT("Press '+' to show the current status. Press '-' to stop recording the status."));
|
|
||||||
|
|
||||||
|
|
||||||
// Record movement
|
|
||||||
wxStaticBoxSizer * sbRealRecord = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Record movements"));
|
|
||||||
|
|
||||||
wxArrayString StrHotKeySwitch;
|
|
||||||
StrHotKeySwitch.Add(wxT("Shift"));
|
|
||||||
StrHotKeySwitch.Add(wxT("Ctrl"));
|
|
||||||
StrHotKeySwitch.Add(wxT("Alt"));
|
|
||||||
StrHotKeySwitch.Add(wxT(""));
|
|
||||||
|
|
||||||
wxArrayString StrHotKey;
|
|
||||||
for(int i = 0; i < 10; i++) StrHotKey.Add(wxString::Format(wxT("%i"), i));
|
|
||||||
StrHotKey.Add(wxT(""));
|
|
||||||
|
|
||||||
wxArrayString StrPlayBackSpeed;
|
|
||||||
for(int i = 1; i <= 20; i++) StrPlayBackSpeed.Add(wxString::Format(wxT("%i"), i*25));
|
|
||||||
|
|
||||||
wxBoxSizer * sRealRecord[RECORDING_ROWS + 1];
|
|
||||||
|
|
||||||
wxStaticText * m_TextRec = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Rec."), wxDefaultPosition, wxSize(80, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextHotKeyWm = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Wiim."), wxDefaultPosition, wxSize(32, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextHotKeyNc = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Nunc."), wxDefaultPosition, wxSize(32, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextHotKeyIR = new wxStaticText(m_PageRecording, wxID_ANY, wxT("IR"), wxDefaultPosition, wxSize(32, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextMovement = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Movement name"), wxDefaultPosition, wxSize(200, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextGame = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Game name"), wxDefaultPosition, wxSize(200, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextIRBytes = new wxStaticText(m_PageRecording, wxID_ANY, wxT("IR"), wxDefaultPosition, wxSize(20, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextRecSpeed = new wxStaticText(m_PageRecording, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(33, -1), wxALIGN_CENTRE);
|
|
||||||
wxStaticText * m_TextPlaySpeed = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Pl. s."), wxDefaultPosition, wxSize(40, -1), wxALIGN_CENTRE);
|
|
||||||
|
|
||||||
// Tool tips
|
|
||||||
m_TextRec->SetToolTip(wxT(
|
|
||||||
"To record a movement first press this button, then start the recording by pressing 'A' on the Wiimote and stop the recording\n"
|
|
||||||
"by letting go of 'A'"));
|
|
||||||
m_TextHotKeyWm->SetToolTip(wxT(
|
|
||||||
"Select a hotkey for playback of Wiimote movements. You can combine it with an"
|
|
||||||
" optional Shift, Ctrl, or Alt switch."
|
|
||||||
));
|
|
||||||
m_TextHotKeyNc->SetToolTip(wxT(
|
|
||||||
"Select a hotkey for playback of Nunchuck movements"));
|
|
||||||
m_TextHotKeyIR->SetToolTip(wxT(
|
|
||||||
"Select a hotkey for playback of Nunchuck movements"));
|
|
||||||
m_TextRecSpeed->SetToolTip(wxT(
|
|
||||||
"Recording speed in average measurements per second"));
|
|
||||||
m_TextPlaySpeed->SetToolTip(wxT(
|
|
||||||
"Playback speed: A playback speed of 100 means that the playback occurs at the same rate as it was recorded. (You can see the\n"
|
|
||||||
"current update rate in the Status window above when a game is running.) However, if your framerate is only at 50% of full speed\n"
|
|
||||||
"you may want to select a playback rate of 50, because then the game might perceive the playback as a full speed playback. (This\n"
|
|
||||||
"holds if Wiimote_Update() is tied to the framerate, I'm not sure that this is the case. It seemed to vary somewhat with different\n"
|
|
||||||
"framerates but perhaps not enough to say that it was exactly tied to the framerate.) So until this is better understood you'll have\n"
|
|
||||||
"to try different playback rates and see which one that works."
|
|
||||||
));
|
|
||||||
|
|
||||||
sRealRecord[0] = new wxBoxSizer(wxHORIZONTAL);
|
|
||||||
sRealRecord[0]->Add(m_TextRec, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextHotKeyWm, 0, wxEXPAND | (wxLEFT), 62);
|
|
||||||
sRealRecord[0]->Add(m_TextHotKeyNc, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextHotKeyIR, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextMovement, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextGame, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextIRBytes, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextRecSpeed, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[0]->Add(m_TextPlaySpeed, 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sbRealRecord->Add(sRealRecord[0], 0, wxEXPAND | (wxALL), 0);
|
|
||||||
|
|
||||||
for(int i = 1; i < (RECORDING_ROWS + 1); i++)
|
|
||||||
{
|
|
||||||
sRealRecord[i] = new wxBoxSizer(wxHORIZONTAL);
|
|
||||||
m_RecordButton[i] = new wxButton(m_PageRecording, IDB_RECORD + i, wxEmptyString, wxDefaultPosition, wxSize(80, 20), 0, wxDefaultValidator, wxEmptyString);
|
|
||||||
m_RecordHotKeySwitch[i] = new wxChoice(m_PageRecording, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKeySwitch);
|
|
||||||
m_RecordHotKeyWiimote[i] = new wxChoice(m_PageRecording, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
|
||||||
m_RecordHotKeyNunchuck[i] = new wxChoice(m_PageRecording, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
|
||||||
m_RecordHotKeyIR[i] = new wxChoice(m_PageRecording, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
|
||||||
m_RecordText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_TEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
|
||||||
m_RecordGameText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_GAMETEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
|
||||||
m_RecordIRBytesText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_IRBYTESTEXT, wxT(""), wxDefaultPosition, wxSize(25, 19));
|
|
||||||
m_RecordSpeed[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_SPEED, wxT(""), wxDefaultPosition, wxSize(30, 19), wxTE_READONLY | wxTE_CENTRE);
|
|
||||||
m_RecordPlayBackSpeed[i] = new wxChoice(m_PageRecording, IDT_RECORD_PLAYSPEED, wxDefaultPosition, wxDefaultSize, StrPlayBackSpeed);
|
|
||||||
|
|
||||||
m_RecordText[i]->SetMaxLength(35);
|
|
||||||
m_RecordGameText[i]->SetMaxLength(35);
|
|
||||||
m_RecordIRBytesText[i]->Enable(false);
|
|
||||||
m_RecordSpeed[i]->Enable(false);
|
|
||||||
|
|
||||||
// Row 2 Sizers
|
|
||||||
sRealRecord[i]->Add(m_RecordButton[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordHotKeySwitch[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordHotKeyWiimote[i], 0, wxEXPAND | (wxLEFT), 2);
|
|
||||||
sRealRecord[i]->Add(m_RecordHotKeyNunchuck[i], 0, wxEXPAND | (wxLEFT), 2);
|
|
||||||
sRealRecord[i]->Add(m_RecordHotKeyIR[i], 0, wxEXPAND | (wxLEFT), 2);
|
|
||||||
sRealRecord[i]->Add(m_RecordText[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordGameText[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordIRBytesText[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordSpeed[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
sRealRecord[i]->Add(m_RecordPlayBackSpeed[i], 0, wxEXPAND | (wxLEFT), 5);
|
|
||||||
|
|
||||||
sbRealRecord->Add(sRealRecord[i], 0, wxEXPAND | (wxTOP), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up sizers for the whole page
|
|
||||||
m_sRecordingMain = new wxBoxSizer(wxVERTICAL);
|
|
||||||
m_sRecordingMain->Add(sbRealWiimoteStatus, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxUP), 5);
|
|
||||||
m_sRecordingMain->Add(sbRealRecord, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
|
|
||||||
|
|
||||||
m_PageRecording->SetSizer(m_sRecordingMain);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Record movement */
|
|
||||||
void ConfigDialog::ConvertToString()
|
|
||||||
{
|
|
||||||
// Load ini file
|
|
||||||
IniFile file;
|
|
||||||
file.Load(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
std::string TmpStr = "", TmpIR = "", TmpTime = "";
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)m_vRecording.size(); i++)
|
|
||||||
{
|
|
||||||
// Write the movement data
|
|
||||||
TmpStr += StringFromFormat("%s", m_vRecording.at(i).x >= 0 ? StringFromFormat("+%03i", m_vRecording.at(i).x).c_str() : StringFromFormat("%04i", m_vRecording.at(i).x).c_str());
|
|
||||||
TmpStr += StringFromFormat("%s", m_vRecording.at(i).y >= 0 ? StringFromFormat("+%03i", m_vRecording.at(i).y).c_str() : StringFromFormat("%04i", m_vRecording.at(i).y).c_str());
|
|
||||||
TmpStr += StringFromFormat("%s", m_vRecording.at(i).z >= 0 ? StringFromFormat("+%03i", m_vRecording.at(i).z).c_str() : StringFromFormat("%04i", m_vRecording.at(i).z).c_str());
|
|
||||||
if (i < ((int)m_vRecording.size() - 1)) TmpStr += ",";
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "%s\n", TmpStr.c_str());
|
|
||||||
|
|
||||||
// Write the IR data
|
|
||||||
TmpIR += ArrayToString(m_vRecording.at(i).IR, IRBytes, 0, 30, false);
|
|
||||||
if (i < ((int)m_vRecording.size() - 1)) TmpIR += ",";
|
|
||||||
|
|
||||||
// Write the timestamps. The upper limit is 99 seconds.
|
|
||||||
int Time = (int)((m_vRecording.at(i).Time - m_vRecording.at(0).Time) * 1000);
|
|
||||||
TmpTime += StringFromFormat("%05i", Time);
|
|
||||||
if (i < ((int)m_vRecording.size() - 1)) TmpTime += ",";
|
|
||||||
|
|
||||||
/* Break just short of the IniFile.cpp byte limit so that we don't
|
|
||||||
crash file.Load() the next time. This limit should never be hit
|
|
||||||
because of the recording limit below. I keep it here just in
|
|
||||||
case. */
|
|
||||||
if(TmpStr.length() > (1024*10 - 10) || TmpIR.length() > (1024*10 - 10) || TmpTime.length() > (1024*10 - 10))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
PanicAlert("Your recording was to long, the entire recording was not saved.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
INFO_LOG(CONSOLE, "Saved: [%i / %i] %03i %03i %03i\n", i, m_vRecording.size(), m_vRecording.at(i).x, m_vRecording.at(i).y, m_vRecording.at(i).z);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recordings per second
|
|
||||||
double Recordings = (double)m_vRecording.size();
|
|
||||||
double Time = m_vRecording.at(m_vRecording.size() - 1).Time - m_vRecording.at(0).Time;
|
|
||||||
int Rate = (int)(Recordings / Time);
|
|
||||||
|
|
||||||
// If time or the number of recordings are zero we set the Rate to zero
|
|
||||||
if (Time == 0 || m_vRecording.size() == 0) Rate = 0;
|
|
||||||
|
|
||||||
// Update GUI
|
|
||||||
m_RecordIRBytesText[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), IRBytes));
|
|
||||||
m_RecordSpeed[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), Rate));
|
|
||||||
|
|
||||||
// Save file
|
|
||||||
std::string SaveName = StringFromFormat("Recording%i", m_iRecordTo);
|
|
||||||
file.Set(SaveName.c_str(), "Movement", TmpStr.c_str());
|
|
||||||
file.Set(SaveName.c_str(), "IR", TmpIR.c_str());
|
|
||||||
file.Set(SaveName.c_str(), "Time", TmpTime.c_str());
|
|
||||||
file.Set(SaveName.c_str(), "IRBytes", IRBytes);
|
|
||||||
file.Set(SaveName.c_str(), "RecordingSpeed", Rate);
|
|
||||||
|
|
||||||
// Set a default playback speed if none is set already
|
|
||||||
int TmpPlaySpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaySpeed, -1);
|
|
||||||
if (TmpPlaySpeed == -1)
|
|
||||||
{
|
|
||||||
file.Set(SaveName.c_str(), "PlaybackSpeed", 3);
|
|
||||||
m_RecordPlayBackSpeed[m_iRecordTo]->SetSelection(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.Save(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "Save recording to WiimoteMovement.ini\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timeout the recording
|
|
||||||
void ConfigDialog::Update(wxTimerEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
m_bWaitForRecording = false;
|
|
||||||
m_bRecording = false;
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT(""));
|
|
||||||
UpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigDialog::RecordMovement(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
m_iRecordTo = event.GetId() - 2000;
|
|
||||||
|
|
||||||
if(WiiMoteReal::g_MotionSensing)
|
|
||||||
{
|
|
||||||
// Check if there already is a recording here
|
|
||||||
if(m_RecordSpeed[m_iRecordTo]->GetLineLength(0) > 0)
|
|
||||||
{
|
|
||||||
if(!AskYesNo("Do you want to replace the current recording?")) return;
|
|
||||||
}
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Hold A"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +"));
|
|
||||||
// This is for usability purposes, it may not be obvious at all that
|
|
||||||
// this must be unchecked for the recording to work
|
|
||||||
for(int i = 0; i < 1; i++) m_UseRealWiimote[i]->SetValue(false); g_Config.bUseRealWiimote = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bWaitForRecording = true;
|
|
||||||
m_bAllowA = true;
|
|
||||||
m_bRecording = false;
|
|
||||||
|
|
||||||
UpdateGUI();
|
|
||||||
|
|
||||||
m_TimeoutTimer->Start(5000, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigDialog::DoRecordA(bool Pressed)
|
|
||||||
{
|
|
||||||
// Return if we are not waiting or recording
|
|
||||||
if (! (m_bWaitForRecording || m_bRecording)) return;
|
|
||||||
|
|
||||||
// Return if we are waiting but have not pressed A
|
|
||||||
if (m_bWaitForRecording && !Pressed) return;
|
|
||||||
|
|
||||||
// Return if we are recording but are still pressing A
|
|
||||||
if (m_bRecording && Pressed) return;
|
|
||||||
|
|
||||||
//m_bAllowA = false;
|
|
||||||
m_bRecording = Pressed;
|
|
||||||
|
|
||||||
// Start recording, only run this once
|
|
||||||
if(m_bRecording && m_bWaitForRecording)
|
|
||||||
{
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Recording..."));
|
|
||||||
m_vRecording.clear(); // Clear the list
|
|
||||||
m_TimeoutTimer->Stop();
|
|
||||||
m_bWaitForRecording = false;
|
|
||||||
}
|
|
||||||
// The recording is done
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done"));
|
|
||||||
INFO_LOG(CONSOLE, "Done: %i %i\n", m_bWaitForRecording, m_bRecording);
|
|
||||||
//m_bAllowA = true;
|
|
||||||
ConvertToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigDialog::DoRecordMovement(int _x, int _y, int _z, const u8 *_IR, int _IRBytes)
|
|
||||||
{
|
|
||||||
//std::string Tmp1 = ArrayToString(_IR, 20, 0, 30);
|
|
||||||
//INFO_LOG(CONSOLE, "DoRecordMovement: %s\n", Tmp1.c_str());
|
|
||||||
|
|
||||||
if (!m_bRecording) return;
|
|
||||||
|
|
||||||
//INFO_LOG(CONSOLE, "DoRecordMovement: %03i %03i %03i\n", _x, _y, _z);
|
|
||||||
|
|
||||||
SRecording Tmp;
|
|
||||||
Tmp.x = _x;
|
|
||||||
Tmp.y = _y;
|
|
||||||
Tmp.z = _z;
|
|
||||||
Tmp.Time = GetDoubleTime();
|
|
||||||
memcpy(Tmp.IR, _IR, _IRBytes);
|
|
||||||
m_vRecording.push_back(Tmp);
|
|
||||||
|
|
||||||
// Save the number of IR bytes
|
|
||||||
IRBytes = _IRBytes;
|
|
||||||
|
|
||||||
/* The upper limit of a recording coincides with the IniFile.cpp limit, each list element
|
|
||||||
is 7 bytes, therefore be divide by 7 */
|
|
||||||
if (m_vRecording.size() > (10*1024 / 7 - 2) )
|
|
||||||
{
|
|
||||||
m_bRecording = false;
|
|
||||||
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done"));
|
|
||||||
ConvertToString();
|
|
||||||
UpdateGUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,272 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Data reports guide. The different structures location in the Input
|
|
||||||
reports. The ? in the IR coordinates is the High coordinates that are four
|
|
||||||
in one byte.
|
|
||||||
|
|
||||||
0x37: For the data reportingmode 0x37 there are five unused IR bytes in the
|
|
||||||
end (represented) by "..." below, it seems like they can be set to either
|
|
||||||
0xff or 0x00 without affecting the IR emulation. */
|
|
||||||
|
|
||||||
/* 0x33 [c.left etc] [c.a etc] acc.x y z ir0.x y ? ir1.x y ? ir2.x y ? ir3.x y
|
|
||||||
?
|
|
||||||
|
|
||||||
0x37 [c.left etc] [c.a etc] acc.x y z ir0.x1 y1 ? x2 y2 ir1.x1 y1 ? x2 y2
|
|
||||||
... ext.jx jy ax ay az bt
|
|
||||||
|
|
||||||
|
|
||||||
The Data Report's path from here is
|
|
||||||
WII_IPC_HLE_WiiMote.cpp:
|
|
||||||
Callback_WiimoteInput()
|
|
||||||
CWII_IPC_HLE_WiiMote::SendL2capData()
|
|
||||||
WII_IPC_HLE_Device_usb.cpp:
|
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame()
|
|
||||||
at that point the message is queued and will be sent by the next
|
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "Common.h" // Common
|
|
||||||
#include "StringUtil.h" // for ArrayToString
|
|
||||||
|
|
||||||
#include "wiimote_hid.h" // Local
|
|
||||||
#include "main.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "EmuSubroutines.h"
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
#include "Encryption.h" // for extension encryption
|
|
||||||
#include "Config.h" // for g_Config
|
|
||||||
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Subroutines
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
/* Update the data reporting mode */
|
|
||||||
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
|
|
||||||
INFO_LOG(CONSOLE, "Data reporting:\n");
|
|
||||||
INFO_LOG(CONSOLE, " Continuous: %x\n", dr->continuous);
|
|
||||||
INFO_LOG(CONSOLE, " All The Time: %x (not only on data change)\n", dr->all_the_time);
|
|
||||||
INFO_LOG(CONSOLE, " Mode: 0x%02x\n", dr->mode);
|
|
||||||
INFO_LOG(CONSOLE, " Channel: 0x%04x\n", _channelID);
|
|
||||||
|
|
||||||
g_ReportingMode = dr->mode;
|
|
||||||
g_ReportingChannel = _channelID;
|
|
||||||
switch(dr->mode) // See Wiimote_Update()
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// WmSendAck(_channelID, WM_DATA_REPORTING);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Case 0x30: Core Buttons */
|
|
||||||
void SendReportCore(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE);
|
|
||||||
|
|
||||||
wm_report_core* pReport = (wm_report_core*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core));
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReportCore()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 0x31: Core Buttons and Accelerometer */
|
|
||||||
void SendReportCoreAccel(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL);
|
|
||||||
|
|
||||||
wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel));
|
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReportCoreAccel (0x31)");
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Channel: %04x", _channelID);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Offset: %08x", Offset);
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Case 0x33: Core Buttons and Accelerometer with 12 IR bytes */
|
|
||||||
void SendReportCoreAccelIr12(u16 _channelID) {
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12);
|
|
||||||
|
|
||||||
wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel_ir12);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
|
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
|
|
||||||
// We settle with emulating two objects, not all four. We leave object 2 and 3 with 0xff.
|
|
||||||
FillReportIR(pReport->ir[0], pReport->ir[1]);
|
|
||||||
#endif
|
|
||||||
memset(&pReport->ir[2], 0xff, sizeof(wm_ir_extended));
|
|
||||||
memset(&pReport->ir[3], 0xff, sizeof(wm_ir_extended));
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr12()");
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Offset: %08x", Offset);
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Case 0x35: Core Buttons and Accelerometer with 16 Extension Bytes */
|
|
||||||
void SendReportCoreAccelExt16(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_EXT16);
|
|
||||||
|
|
||||||
wm_report_core_accel_ext16* pReport = (wm_report_core_accel_ext16*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel_ext16);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel_ext16));
|
|
||||||
|
|
||||||
// Make a classic extension struct
|
|
||||||
wm_classic_extension _ext;
|
|
||||||
memset(&_ext, 0, sizeof(wm_classic_extension));
|
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(g_Config.bNunchuckConnected)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportExtension(pReport->ext);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if(g_Config.bClassicControllerConnected)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportClassicExtension(_ext);
|
|
||||||
#endif
|
|
||||||
// Copy _ext to pReport->ext
|
|
||||||
memcpy(&pReport->ext, &_ext, sizeof(_ext));
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelExt16 (0x35)");
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Channel: %04x", _channelID);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Offset: %08x", Offset);
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Case 0x37: Core Buttons and Accelerometer with 10 IR bytes and 6 Extension Bytes */
|
|
||||||
void SendReportCoreAccelIr10Ext(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR10_EXT6);
|
|
||||||
|
|
||||||
wm_report_core_accel_ir10_ext6* pReport = (wm_report_core_accel_ir10_ext6*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel_ir10_ext6);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6));
|
|
||||||
|
|
||||||
// Make a classic extension struct
|
|
||||||
wm_classic_extension _ext;
|
|
||||||
memset(&_ext, 0, sizeof(wm_classic_extension));
|
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(g_Config.bNunchuckConnected)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportExtension(pReport->ext);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if(g_Config.bClassicControllerConnected)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
FillReportClassicExtension(_ext);
|
|
||||||
#endif
|
|
||||||
// Copy _ext to pReport->ext
|
|
||||||
memcpy(&pReport->ext, &_ext, sizeof(_ext));
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr10Ext()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace
|
|
|
@ -1,72 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 _EMU_DEFINITIONS_
|
|
||||||
#define _EMU_DEFINITIONS_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
#include "Common.h"
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
#include "Encryption.h"
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Definitions and variable declarations
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
u8 g_Leds;
|
|
||||||
u8 g_Speaker;
|
|
||||||
u8 g_SpeakerVoice;
|
|
||||||
u8 g_IR;
|
|
||||||
|
|
||||||
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
|
||||||
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
|
||||||
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
|
||||||
u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
|
||||||
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
|
||||||
|
|
||||||
u8 g_ReportingMode; // The reporting mode and channel id
|
|
||||||
u16 g_ReportingChannel;
|
|
||||||
|
|
||||||
std::vector<wm_ackdelay> AckDelay; // Ackk delay
|
|
||||||
|
|
||||||
wiimote_key g_ExtKey; // The extension encryption key
|
|
||||||
bool g_Encryption; // Encryption on or off
|
|
||||||
|
|
||||||
// Gamepad input
|
|
||||||
int NumPads = 0, NumGoodPads = 0; // Number of goods pads
|
|
||||||
std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
|
||||||
InputCommon::CONTROLLER_STATE_NEW PadState[4];
|
|
||||||
InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
|
|
||||||
|
|
||||||
// Keyboard input
|
|
||||||
KeyboardWiimote g_Wm;
|
|
||||||
KeyboardNunchuck g_Nc;
|
|
||||||
KeyboardClassicController g_Cc;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif //_EMU_DECLARATIONS_
|
|
||||||
|
|
|
@ -1,248 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 _EMU_DECLARATIONS_
|
|
||||||
#define _EMU_DECLARATIONS_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
|
||||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "wiimote_hid.h" // Local
|
|
||||||
#include "Encryption.h"
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Definitions and variable declarations
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
/* The Libogc bounding box in smoothed IR coordinates is 232,284 792,704. However, there is no
|
|
||||||
universal standard that works with all games. They all use their own calibration. Also,
|
|
||||||
there is no widescreen mode for the calibration, at least not in the games I tried, the
|
|
||||||
game decides for example that a horizontal value of 500 is 50% from the left of the screen,
|
|
||||||
and then that's the same regardless if we use the widescreen mode or not.*/
|
|
||||||
#define LEFT 266
|
|
||||||
#define TOP 215
|
|
||||||
#define RIGHT 752
|
|
||||||
#define BOTTOM 705
|
|
||||||
/* Since the width of the entire virtual screen is 1024 a reasonable sensor bar width is perhaps 200,
|
|
||||||
given how small most sensor bars are compared to the total TV width. When I tried the distance with
|
|
||||||
my Wiimote from around three meters distance from the sensor bar (that has around 15 cm beteen the
|
|
||||||
IR lights) I got a dot distance of around 110 (and a dot size of between 1 and 2). */
|
|
||||||
#define SENSOR_BAR_RADIUS 100
|
|
||||||
|
|
||||||
// Movement recording
|
|
||||||
extern int g_RecordingPlaying[3];
|
|
||||||
extern int g_RecordingCounter[3];
|
|
||||||
extern int g_RecordingPoint[3];
|
|
||||||
extern double g_RecordingStart[3];
|
|
||||||
extern double g_RecordingCurrentTime[3];
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
extern u8 g_Leds;
|
|
||||||
extern u8 g_Speaker;
|
|
||||||
extern u8 g_SpeakerVoice;
|
|
||||||
extern u8 g_IR;
|
|
||||||
|
|
||||||
extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
|
||||||
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
|
||||||
extern u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
|
||||||
extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
|
||||||
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
|
||||||
|
|
||||||
extern u8 g_ReportingMode;
|
|
||||||
extern u16 g_ReportingChannel;
|
|
||||||
|
|
||||||
// Ack delay
|
|
||||||
struct wm_ackdelay
|
|
||||||
{
|
|
||||||
u8 Delay;
|
|
||||||
u8 ReportID;
|
|
||||||
u16 ChannelID;
|
|
||||||
bool Sent;
|
|
||||||
};
|
|
||||||
extern std::vector<wm_ackdelay> AckDelay;
|
|
||||||
|
|
||||||
extern wiimote_key g_ExtKey; // extension encryption key
|
|
||||||
extern bool g_Encryption;
|
|
||||||
|
|
||||||
/* 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 EepromData_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 EepromData_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
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
0xff, 0x00, 0x80, 0xff, // 0x80 = analog stick x and y axis center
|
|
||||||
0x00, 0x80, 0xee, 0x43 // checksum on the last two bytes
|
|
||||||
};
|
|
||||||
static const u8 wireless_nunchuck_calibration[] =
|
|
||||||
{
|
|
||||||
128, 128, 128, 0x00,
|
|
||||||
181, 181, 181, 0x00,
|
|
||||||
255, 0, 125, 255,
|
|
||||||
0, 126, 0xed, 0x43
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Classic Controller calibration */
|
|
||||||
static const u8 classic_calibration[] =
|
|
||||||
{
|
|
||||||
0xff,0x00,0x80, 0xff,0x00,0x80, 0xff,0x00,0x80, 0xff,0x00,0x80,
|
|
||||||
0x00,0x00, 0x51,0xa6
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The Nunchuck id. It should be written to the last bytes of the
|
|
||||||
extension register */
|
|
||||||
static const u8 nunchuck_id[] =
|
|
||||||
{
|
|
||||||
0x00, 0x00, 0xa4, 0x20, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The Classic Controller id. It should be written to the last bytes of the
|
|
||||||
extension register */
|
|
||||||
static const u8 classic_id[] =
|
|
||||||
{
|
|
||||||
0x00, 0x00, 0xa4, 0x20, 0x01, 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
};
|
|
||||||
|
|
||||||
// Gamepad input
|
|
||||||
extern int NumPads, NumGoodPads; // Number of goods pads
|
|
||||||
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
|
||||||
extern InputCommon::CONTROLLER_STATE_NEW PadState[4];
|
|
||||||
extern InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
|
|
||||||
|
|
||||||
// Wiimote status
|
|
||||||
struct SDot
|
|
||||||
{
|
|
||||||
int Rx, Ry, X, Y;
|
|
||||||
bool Visible;
|
|
||||||
int Size; // Size of the IR dot (0-15)
|
|
||||||
int Order; // Increasing order from low to higher x-axis values
|
|
||||||
};
|
|
||||||
struct SIR
|
|
||||||
{
|
|
||||||
SDot Dot[4];
|
|
||||||
int Distance;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keyboard input
|
|
||||||
struct KeyboardWiimote
|
|
||||||
{
|
|
||||||
enum EKeyboardWiimote
|
|
||||||
{
|
|
||||||
A = 0, MA, // Keyboard A and Mouse A
|
|
||||||
B, MB,
|
|
||||||
ONE, TWO,
|
|
||||||
P, M, H,
|
|
||||||
L, R, U, D,
|
|
||||||
PITCH_L, PITCH_R,
|
|
||||||
SHAKE,
|
|
||||||
LAST_CONSTANT
|
|
||||||
};
|
|
||||||
|
|
||||||
// Raw X and Y coordinate and processed X and Y coordinates
|
|
||||||
SIR IR;
|
|
||||||
};
|
|
||||||
extern KeyboardWiimote g_Wm;
|
|
||||||
struct KeyboardNunchuck
|
|
||||||
{
|
|
||||||
enum EKeyboardNunchuck
|
|
||||||
{
|
|
||||||
// This is not allowed in Linux so we have to set the starting value manually
|
|
||||||
#ifdef _WIN32
|
|
||||||
Z = g_Wm.LAST_CONSTANT,
|
|
||||||
#else
|
|
||||||
Z = 16,
|
|
||||||
#endif
|
|
||||||
C,
|
|
||||||
L, R, U, D,
|
|
||||||
SHAKE,
|
|
||||||
LAST_CONSTANT
|
|
||||||
};
|
|
||||||
};
|
|
||||||
extern KeyboardNunchuck g_Nc;
|
|
||||||
struct KeyboardClassicController
|
|
||||||
{
|
|
||||||
enum EKeyboardClassicController
|
|
||||||
{
|
|
||||||
// This is not allowed in Linux so we have to set the starting value manually
|
|
||||||
#ifdef _WIN32
|
|
||||||
A = g_Nc.LAST_CONSTANT,
|
|
||||||
#else
|
|
||||||
A = 23,
|
|
||||||
#endif
|
|
||||||
B, X, Y,
|
|
||||||
P, M, H,
|
|
||||||
Dl, Dr, Du, Dd,
|
|
||||||
Tl, Tr, Zl, Zr,
|
|
||||||
Ll, Lr, Lu, Ld,
|
|
||||||
Rl, Rr, Ru, Rd,
|
|
||||||
SHAKE
|
|
||||||
};
|
|
||||||
};
|
|
||||||
extern KeyboardClassicController g_Cc;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif //_EMU_DEFINITIONS_
|
|
|
@ -1,357 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
|
||||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
|
||||||
|
|
||||||
#include "Common.h" // Common
|
|
||||||
#include "MathUtil.h"
|
|
||||||
#include "StringUtil.h" // for ArrayToString()
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "EmuDefinitions.h" // Local
|
|
||||||
#include "main.h"
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuSubroutines.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "Encryption.h" // for extension encryption
|
|
||||||
#include "Config.h" // for g_Config
|
|
||||||
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Accelerometer functions
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
// Test the calculations
|
|
||||||
void TiltTest(u8 x, u8 y, u8 z)
|
|
||||||
{
|
|
||||||
int Roll, Pitch, RollAdj, PitchAdj;
|
|
||||||
PitchAccelerometerToDegree(x, y, z, Roll, Pitch, RollAdj, PitchAdj);
|
|
||||||
std::string From = StringFromFormat("From: X:%i Y:%i Z:%i Roll:%s Pitch:%s", x, y, z,
|
|
||||||
(Roll >= 0) ? StringFromFormat(" %03i", Roll).c_str() : StringFromFormat("%04i", Roll).c_str(),
|
|
||||||
(Pitch >= 0) ? StringFromFormat(" %03i", Pitch).c_str() : StringFromFormat("%04i", Pitch).c_str());
|
|
||||||
|
|
||||||
float _Roll = (float)Roll, _Pitch = (float)Pitch;
|
|
||||||
PitchDegreeToAccelerometer(_Roll, _Pitch, x, y, z);
|
|
||||||
std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z,
|
|
||||||
(_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(),
|
|
||||||
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
|
|
||||||
INFO_LOG(CONSOLE, "%s\n", To.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Angles adjustment for the upside down state when both roll and pitch is
|
|
||||||
used. When the absolute values of the angles go over 90° the Wiimote is
|
|
||||||
upside down and these adjustments are needed. */
|
|
||||||
void AdjustAngles(float &Roll, float &Pitch)
|
|
||||||
{
|
|
||||||
float OldPitch = Pitch;
|
|
||||||
|
|
||||||
if (abs(Roll) > 90)
|
|
||||||
{
|
|
||||||
if (Pitch >= 0)
|
|
||||||
Pitch = 180 - Pitch; // 15 to 165
|
|
||||||
else if (Pitch < 0)
|
|
||||||
Pitch = -180 - Pitch; // -15 to -165
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abs(OldPitch) > 90)
|
|
||||||
{
|
|
||||||
if (Roll >= 0)
|
|
||||||
Roll = 180 - Roll; // 15 to 165
|
|
||||||
else if (Roll < 0)
|
|
||||||
Roll = -180 - Roll; // -15 to -165
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Angles to accelerometer values
|
|
||||||
void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z)
|
|
||||||
{
|
|
||||||
// We need radiands for the math functions
|
|
||||||
_Roll = InputCommon::Deg2Rad(_Roll);
|
|
||||||
_Pitch = InputCommon::Deg2Rad(_Pitch);
|
|
||||||
// We need decimal values
|
|
||||||
float x = (float)_x, y = (float)_y, z = (float)_z;
|
|
||||||
|
|
||||||
// In these cases we can use the simple and accurate formula
|
|
||||||
if(g_Config.Trigger.Range.Pitch == 0)
|
|
||||||
{
|
|
||||||
x = sin(_Roll);
|
|
||||||
z = cos(_Roll);
|
|
||||||
}
|
|
||||||
else if (g_Config.Trigger.Range.Roll == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
y = sin(_Pitch);
|
|
||||||
z = cos(_Pitch);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// ====================================================
|
|
||||||
/* This seems to always produce the exact same combination of x, y, z
|
|
||||||
and Roll and Pitch that the real Wiimote produce. There is an
|
|
||||||
unlimited amount of x, y, z combinations for any combination of Roll
|
|
||||||
and Pitch. But if we select a Z from the smallest of the absolute
|
|
||||||
value of cos(Roll) and cos (Pitch) we get the right values. */
|
|
||||||
// ---------
|
|
||||||
if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
|
|
||||||
/* I got these from reversing the calculation in
|
|
||||||
PitchAccelerometerToDegree() in a math program I don't know if we
|
|
||||||
can derive these from some kind of matrix or something */
|
|
||||||
float x_num = 2 * tanf(0.5f * _Roll) * z;
|
|
||||||
float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
|
|
||||||
x = - (x_num / x_den);
|
|
||||||
float y_num = 2 * tanf(0.5f * _Pitch) * z;
|
|
||||||
float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
|
|
||||||
y = - (y_num / y_den);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiply with the neutral of z and its g
|
|
||||||
float xg = g_wm.cal_g.x;
|
|
||||||
float yg = g_wm.cal_g.y;
|
|
||||||
float zg = g_wm.cal_g.z;
|
|
||||||
float x_zero = g_wm.cal_zero.x;
|
|
||||||
float y_zero = g_wm.cal_zero.y;
|
|
||||||
float z_zero = g_wm.cal_zero.z;
|
|
||||||
int ix = (int) (x_zero + xg * x);
|
|
||||||
int iy = (int) (y_zero + yg * y);
|
|
||||||
int iz = (int) (z_zero + zg * z);
|
|
||||||
|
|
||||||
// Boundaries
|
|
||||||
if (ix < 0) ix = 0; if (ix > 255) ix = 255;
|
|
||||||
if (iy < 0) iy = 0; if (iy > 255) iy = 255;
|
|
||||||
if (iz < 0) iz = 0; if (iz > 255) iz = 255;
|
|
||||||
if(g_Config.Trigger.Range.Roll != 0) _x = ix;
|
|
||||||
if(g_Config.Trigger.Range.Pitch != 0) _y = iy;
|
|
||||||
_z = iz;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accelerometer to roll and pitch angles
|
|
||||||
float AccelerometerToG(float Current, float Neutral, float G)
|
|
||||||
{
|
|
||||||
float _G = (Current - Neutral) / G;
|
|
||||||
return _G;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int &_RollAdj, int &_PitchAdj)
|
|
||||||
{
|
|
||||||
// Definitions
|
|
||||||
float Roll = 0, Pitch = 0;
|
|
||||||
|
|
||||||
// Calculate how many g we are from the neutral
|
|
||||||
float x = AccelerometerToG((float)_x, (float)g_wm.cal_zero.x, (float)g_wm.cal_g.x);
|
|
||||||
float y = AccelerometerToG((float)_y, (float)g_wm.cal_zero.y, (float)g_wm.cal_g.y);
|
|
||||||
float z = AccelerometerToG((float)_z, (float)g_wm.cal_zero.z, (float)g_wm.cal_g.z);
|
|
||||||
|
|
||||||
// If it is over 1g then it is probably accelerating and may not reliable
|
|
||||||
//if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x)
|
|
||||||
{
|
|
||||||
// Calculate the degree
|
|
||||||
Roll = InputCommon::Rad2Deg(atan2(x, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (abs(_y - g_wm.cal_zero.y) <= g_wm.cal_g.y)
|
|
||||||
{
|
|
||||||
// Calculate the degree
|
|
||||||
Pitch = InputCommon::Rad2Deg(atan2(y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
_Roll = (int)Roll;
|
|
||||||
_Pitch = (int)Pitch;
|
|
||||||
|
|
||||||
/* Don't allow forces bigger than 1g */
|
|
||||||
if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0;
|
|
||||||
if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0;
|
|
||||||
if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0;
|
|
||||||
Roll = InputCommon::Rad2Deg(atan2(x, z));
|
|
||||||
Pitch = InputCommon::Rad2Deg(atan2(y, z));
|
|
||||||
|
|
||||||
_RollAdj = (int)Roll;
|
|
||||||
_PitchAdj = (int)Pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// IR data functions
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
// Calculate dot positions from the basic 10 byte IR data
|
|
||||||
void IRData2DotsBasic(u8 *Data)
|
|
||||||
{
|
|
||||||
struct SDot* Dot = g_Wm.IR.Dot;
|
|
||||||
|
|
||||||
Dot[0].Rx = 1023 - (Data[0] | ((Data[2] & 0x30) << 4));
|
|
||||||
Dot[0].Ry = Data[1] | ((Data[2] & 0xc0) << 2);
|
|
||||||
|
|
||||||
Dot[1].Rx = 1023 - (Data[3] | ((Data[2] & 0x03) << 8));
|
|
||||||
Dot[1].Ry = Data[4] | ((Data[2] & 0x0c) << 6);
|
|
||||||
|
|
||||||
Dot[2].Rx = 1023 - (Data[5] | ((Data[7] & 0x30) << 4));
|
|
||||||
Dot[2].Ry = Data[6] | ((Data[7] & 0xc0) << 2);
|
|
||||||
|
|
||||||
Dot[3].Rx = 1023 - (Data[8] | ((Data[7] & 0x03) << 8));
|
|
||||||
Dot[3].Ry = Data[9] | ((Data[7] & 0x0c) << 6);
|
|
||||||
|
|
||||||
/* set each IR spot to visible if spot is in range */
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
if (Dot[i].Ry == 1023)
|
|
||||||
{
|
|
||||||
Dot[i].Visible = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dot[i].Visible = 1;
|
|
||||||
Dot[i].Size = 0; /* since we don't know the size, set it as 0 */
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now we let our virtual resolution be the same as the default one
|
|
||||||
Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the other values
|
|
||||||
ReorderIRDots();
|
|
||||||
IRData2Distance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate dot positions from the extented 12 byte IR data
|
|
||||||
void IRData2Dots(u8 *Data)
|
|
||||||
{
|
|
||||||
struct SDot* Dot = g_Wm.IR.Dot;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
//Console::Print("Rx: %i\n", Dot[i].Rx);
|
|
||||||
|
|
||||||
Dot[i].Rx = 1023 - (Data[3*i] | ((Data[(3*i)+2] & 0x30) << 4));
|
|
||||||
Dot[i].Ry = Data[(3*i)+1] | ((Data[(3*i)+2] & 0xc0) << 2);
|
|
||||||
|
|
||||||
Dot[i].Size = Data[(3*i)+2] & 0x0f;
|
|
||||||
|
|
||||||
/* if in range set to visible */
|
|
||||||
if (Dot[i].Ry == 1023)
|
|
||||||
Dot[i].Visible = false;
|
|
||||||
else
|
|
||||||
Dot[i].Visible = true;
|
|
||||||
|
|
||||||
//Console::Print("Rx: %i\n", Dot[i].Rx);
|
|
||||||
|
|
||||||
// For now we let our virtual resolution be the same as the default one
|
|
||||||
Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the other values
|
|
||||||
ReorderIRDots();
|
|
||||||
IRData2Distance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Reorder the IR dots according to their x-axis value
|
|
||||||
void ReorderIRDots()
|
|
||||||
{
|
|
||||||
// Create a shortcut
|
|
||||||
struct SDot* Dot = g_Wm.IR.Dot;
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
int i, j, order;
|
|
||||||
|
|
||||||
// Reset the dot ordering to zero
|
|
||||||
for (i = 0; i < 4; ++i)
|
|
||||||
Dot[i].Order = 0;
|
|
||||||
|
|
||||||
for (order = 1; order < 5; ++order)
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
for (; !Dot[i].Visible || Dot[i].Order; ++i)
|
|
||||||
if (i > 4) return;
|
|
||||||
|
|
||||||
//
|
|
||||||
for (j = 0; j < 4; ++j)
|
|
||||||
{
|
|
||||||
if (Dot[j].Visible && !Dot[j].Order && (Dot[j].X < Dot[i].X))
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dot[i].Order = order;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate dot positions from the extented 12 byte IR data
|
|
||||||
void IRData2Distance()
|
|
||||||
{
|
|
||||||
// Create a shortcut
|
|
||||||
struct SDot* Dot = g_Wm.IR.Dot;
|
|
||||||
|
|
||||||
// Make these ones global
|
|
||||||
int i1, i2;
|
|
||||||
|
|
||||||
for (i1 = 0; i1 < 4; ++i1)
|
|
||||||
if (Dot[i1].Visible) break;
|
|
||||||
|
|
||||||
// Only one dot was visible, we can not calculate the distance
|
|
||||||
if (i1 == 4) { g_Wm.IR.Distance = 0; return; }
|
|
||||||
|
|
||||||
// Look at the next dot
|
|
||||||
for (i2 = i1 + 1; i2 < 4; ++i2)
|
|
||||||
if (Dot[i2].Visible) break;
|
|
||||||
|
|
||||||
// Only one dot was visible, we can not calculate the distance
|
|
||||||
if (i2 == 4) { g_Wm.IR.Distance = 0; return; }
|
|
||||||
|
|
||||||
/* For the emulated Wiimote the y distance is always zero so then the distance is the
|
|
||||||
simple distance between the x dots, i.e. the sensor bar width */
|
|
||||||
int xd = Dot[i2].X - Dot[i1].X;
|
|
||||||
int yd = Dot[i2].Y - Dot[i1].Y;
|
|
||||||
|
|
||||||
// Save the distance
|
|
||||||
g_Wm.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Classic Controller functions
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
std::string CCData2Values(u8 *Data)
|
|
||||||
{
|
|
||||||
return StringFromFormat(
|
|
||||||
"Tl:%03i Tr:%03i Lx:%03i Ly:%03i Rx:%03i Ry:%03i",
|
|
||||||
(((Data[2] & 0x60) >> 2) | ((Data[3] & 0xe0) >> 5)),
|
|
||||||
(Data[3] & 0x1f),
|
|
||||||
(Data[0] & 0x3f),
|
|
||||||
(Data[1] & 0x3f),
|
|
||||||
((Data[0] & 0xc0) >> 3) | ((Data[1] & 0xc0) >> 5) | ((Data[2] & 0x80) >> 7),
|
|
||||||
(Data[2] & 0x1f));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // WiiMoteEmu
|
|
|
@ -1,714 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
|
||||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
|
||||||
|
|
||||||
#include "Common.h" // Common
|
|
||||||
#include "StringUtil.h" // for ArrayToString()
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "EmuDefinitions.h" // Local
|
|
||||||
#include "main.h"
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuSubroutines.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "Encryption.h" // for extension encryption
|
|
||||||
#include "Config.h" // for g_Config
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
/* 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];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */
|
|
||||||
void GetMousePos(float& x, float& y)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
POINT point;
|
|
||||||
// Get the cursor position for the entire screen
|
|
||||||
GetCursorPos(&point);
|
|
||||||
// Get the cursor position relative to the upper left corner of the rendering window
|
|
||||||
ScreenToClient(g_WiimoteInitialize.hWnd, &point);
|
|
||||||
|
|
||||||
// Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.)
|
|
||||||
RECT Rect;
|
|
||||||
GetClientRect(g_WiimoteInitialize.hWnd, &Rect);
|
|
||||||
// Width and height is the size of the rendering window
|
|
||||||
float WinWidth = (float)(Rect.right - Rect.left);
|
|
||||||
float WinHeight = (float)(Rect.bottom - Rect.top);
|
|
||||||
float XOffset = 0, YOffset = 0;
|
|
||||||
float PictureWidth = WinWidth, PictureHeight = WinHeight;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
/* Calculate the actual picture size and location */
|
|
||||||
// Output: PictureWidth, PictureHeight, XOffset, YOffset
|
|
||||||
// ------------------
|
|
||||||
if (g_Config.bKeepAR43 || g_Config.bKeepAR169)
|
|
||||||
{
|
|
||||||
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
|
|
||||||
float Ratio = WinWidth / WinHeight / (g_Config.bKeepAR43 ? (4.0f / 3.0f) : (16.0f / 9.0f));
|
|
||||||
|
|
||||||
// Check if height or width is the limiting factor. If ratio > 1 the picture is to wide and have to limit the width.
|
|
||||||
if (Ratio > 1)
|
|
||||||
{
|
|
||||||
// ------------------------------------------------
|
|
||||||
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
|
|
||||||
// ----------------
|
|
||||||
PictureWidth = WinWidth / Ratio;
|
|
||||||
// --------------------
|
|
||||||
|
|
||||||
// ------------------------------------------------
|
|
||||||
// Calculate the new X offset
|
|
||||||
// ----------------
|
|
||||||
// Move the left of the picture to the middle of the screen
|
|
||||||
XOffset = XOffset + WinWidth / 2.0f;
|
|
||||||
// Then remove half the picture height to move it to the horizontal center
|
|
||||||
XOffset = XOffset - PictureWidth / 2.0f;
|
|
||||||
// --------------------
|
|
||||||
}
|
|
||||||
// The window is to high, we have to limit the height
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// ------------------------------------------------
|
|
||||||
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
|
|
||||||
// ----------------
|
|
||||||
// Invert the ratio to make it > 1
|
|
||||||
Ratio = 1.0f / Ratio;
|
|
||||||
PictureHeight = WinHeight / Ratio;
|
|
||||||
// --------------------
|
|
||||||
|
|
||||||
// ------------------------------------------------
|
|
||||||
// Calculate the new Y offset
|
|
||||||
// ----------------
|
|
||||||
// Move the top of the picture to the middle of the screen
|
|
||||||
YOffset = YOffset + WinHeight / 2.0f;
|
|
||||||
// Then remove half the picture height to move it to the vertical center
|
|
||||||
YOffset = YOffset - PictureHeight / 2.0f;
|
|
||||||
// --------------------
|
|
||||||
}
|
|
||||||
// Logging
|
|
||||||
/*
|
|
||||||
// Console::ClearScreen();
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Screen Width:%4.0f Height:%4.0f Ratio:%1.2f\n", WinWidth, WinHeight, Ratio);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "----------------------------------------------------------------\n");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
// -------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
/* Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10. */
|
|
||||||
// Output: PictureWidth, PictureHeight, XOffset, YOffset
|
|
||||||
// ------------------
|
|
||||||
if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop)
|
|
||||||
{
|
|
||||||
float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
|
|
||||||
|
|
||||||
// The width and height we will add (calculate this before PictureWidth and PictureHeight is adjusted)
|
|
||||||
float IncreasedWidth = (Ratio - 1.0f) * PictureWidth;
|
|
||||||
float IncreasedHeight = (Ratio - 1.0f) * PictureHeight;
|
|
||||||
|
|
||||||
// The new width and height
|
|
||||||
PictureWidth = PictureWidth * Ratio;
|
|
||||||
PictureHeight = PictureHeight * Ratio;
|
|
||||||
|
|
||||||
// Adjust the X and Y offset
|
|
||||||
XOffset = float(XOffset - (IncreasedWidth / 2.0));
|
|
||||||
YOffset = float(YOffset - (IncreasedHeight / 2.0));
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
/*
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Crop Ratio:%1.2f IncrWidth:%3.0f IncrHeight:%3.0f\n", Ratio, IncreasedWidth, IncreasedHeight);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "----------------------------------------------------------------\n");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
// -------------------------------------
|
|
||||||
|
|
||||||
// Return the mouse position as a fraction of one, inside the picture, with (0.0, 0.0) being the upper left corner of the picture
|
|
||||||
x = ((float)point.x - XOffset) / PictureWidth;
|
|
||||||
y = ((float)point.y - YOffset) / PictureHeight;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
// Logging
|
|
||||||
// -------------
|
|
||||||
/*
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "GetCursorPos: %i %i\n", point.x, point.y);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "GetClientRect: %i %i %i %i\n", Rect.left, Rect.right, Rect.top, Rect.bottom);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Position X:%1.2f Y:%1.2f\n", x, y);
|
|
||||||
*/
|
|
||||||
// ---------------------------
|
|
||||||
|
|
||||||
#else
|
|
||||||
// TODO fix on linux
|
|
||||||
x = 0.5f;
|
|
||||||
y = 0.5f;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Homebrew encryption for 16 byte zero keys. */
|
|
||||||
void CryptBuffer(u8* _buffer, u8 _size)
|
|
||||||
{
|
|
||||||
for (int i=0; i<_size; i++)
|
|
||||||
{
|
|
||||||
_buffer[i] = ((_buffer[i] - 0x17) ^ 0x17) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
|
|
||||||
{
|
|
||||||
u16 cryptedValue = _value;
|
|
||||||
CryptBuffer((u8*)&cryptedValue, sizeof(u16));
|
|
||||||
|
|
||||||
*(u16*)(_baseBlock + _address) = cryptedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Calculate Extenstion Regisister Calibration Checksum */
|
|
||||||
// This function is not currently used, it's just here to show how the values
|
|
||||||
// in EmuDefinitions.h are calculated.
|
|
||||||
void GetCalibrationChecksum()
|
|
||||||
{
|
|
||||||
u8 sum = 0;
|
|
||||||
for (u32 i = 0; i < sizeof(nunchuck_calibration) - 2; i++)
|
|
||||||
sum += nunchuck_calibration[i];
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "0x%02x 0x%02x", (sum + 0x55), (sum + 0xaa));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Load pre-recorded movements */
|
|
||||||
void LoadRecordedMovements()
|
|
||||||
{
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "LoadRecordedMovements()\n");
|
|
||||||
|
|
||||||
IniFile file;
|
|
||||||
file.Load(FULL_CONFIG_DIR "WiimoteMovement.ini");
|
|
||||||
|
|
||||||
for(int i = 0; i < RECORDING_ROWS; i++)
|
|
||||||
{
|
|
||||||
// Logging
|
|
||||||
//INFO_LOG(WII_IPC_WIIMOTE, "Recording%i ", i + 1);
|
|
||||||
|
|
||||||
// Temporary storage
|
|
||||||
int iTmp;
|
|
||||||
std::string STmp;
|
|
||||||
|
|
||||||
// First clear the list
|
|
||||||
VRecording.at(i).Recording.clear();
|
|
||||||
|
|
||||||
// Get row name
|
|
||||||
std::string SaveName = StringFromFormat("Recording%i", i + 1);
|
|
||||||
|
|
||||||
// Get movement
|
|
||||||
std::string TmpMovement; file.Get(SaveName.c_str(), "Movement", &TmpMovement, "");
|
|
||||||
|
|
||||||
// Get IR
|
|
||||||
std::string TmpIR; file.Get(SaveName.c_str(), "IR", &TmpIR, "");
|
|
||||||
|
|
||||||
// Get time
|
|
||||||
std::string TmpTime; file.Get(SaveName.c_str(), "Time", &TmpTime, "");
|
|
||||||
|
|
||||||
// Get IR bytes
|
|
||||||
int TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, 0);
|
|
||||||
VRecording.at(i).IRBytes = TmpIRBytes;
|
|
||||||
|
|
||||||
SRecording Tmp;
|
|
||||||
for (int j = 0, k = 0, l = 0; (u32)j < TmpMovement.length(); j+=13)
|
|
||||||
{
|
|
||||||
// Skip blank savings
|
|
||||||
if (TmpMovement.length() < 3) continue;
|
|
||||||
|
|
||||||
// Avoid going to far, this can only happen with modified ini files, but we check for it anyway
|
|
||||||
if (TmpMovement.length() < (u32)j + 12) continue;
|
|
||||||
|
|
||||||
// Skip old style recordings
|
|
||||||
if (TmpMovement.substr(j, 1) != "-" && TmpMovement.substr(j, 1) != "+") continue;
|
|
||||||
|
|
||||||
std::string StrX = TmpMovement.substr(j, 4);
|
|
||||||
std::string StrY = TmpMovement.substr(j + 4, 4);
|
|
||||||
std::string StrZ = TmpMovement.substr(j + 8, 4);
|
|
||||||
Tmp.x = atoi(StrX.c_str());
|
|
||||||
Tmp.y = atoi(StrY.c_str());
|
|
||||||
Tmp.z = atoi(StrZ.c_str());
|
|
||||||
|
|
||||||
// Go to next set of IR values
|
|
||||||
|
|
||||||
// If there is no IR data saving we fill the array with
|
|
||||||
// zeroes. This should only be able to occur from manual ini
|
|
||||||
// editing but we check for it anyway
|
|
||||||
if (TmpIRBytes == 0) for(int n = 0; n < 12; n++) Tmp.IR[n] = 0;
|
|
||||||
for(int ii = 0; ii < TmpIRBytes; ii++)
|
|
||||||
{
|
|
||||||
if(TmpIR.length() < (u32)(k + i + TmpIRBytes)) continue; // Safety check
|
|
||||||
std::string TmpStr = TmpIR.substr(k + ii*2, 2);
|
|
||||||
u32 TmpU32;
|
|
||||||
AsciiToHex(TmpStr.c_str(), TmpU32);
|
|
||||||
Tmp.IR[ii] = (u8)TmpU32;
|
|
||||||
}
|
|
||||||
if (TmpIRBytes == 10) k += (10*2 + 1); else k += (12*2 + 1);
|
|
||||||
|
|
||||||
// Go to next set of time values
|
|
||||||
double Time = (double)atoi(TmpTime.substr(l, 5).c_str());
|
|
||||||
Tmp.Time = (double)(Time/1000);
|
|
||||||
l += 6;
|
|
||||||
|
|
||||||
// Save the values
|
|
||||||
VRecording.at(i).Recording.push_back(Tmp);
|
|
||||||
|
|
||||||
// Log results
|
|
||||||
/*INFO_LOG(WII_IPC_WIIMOTE, "Time:%f\n", Tmp.Time);
|
|
||||||
std::string TmpIRLog = ArrayToString(Tmp.IR, TmpIRBytes, 0, 30);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "IR: %s\n", TmpIRLog.c_str());
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "\n");*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get HotKey
|
|
||||||
file.Get(SaveName.c_str(), "HotKeySwitch", &iTmp, 3); VRecording.at(i).HotKeySwitch = iTmp;
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyWiimote", &iTmp, 10); VRecording.at(i).HotKeyWiimote = iTmp;
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyNunchuck", &iTmp, 10); VRecording.at(i).HotKeyNunchuck = iTmp;
|
|
||||||
file.Get(SaveName.c_str(), "HotKeyIR", &iTmp, 10); VRecording.at(i).HotKeyIR = iTmp;
|
|
||||||
|
|
||||||
// Get Recording speed
|
|
||||||
int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1);
|
|
||||||
VRecording.at(i).PlaybackSpeed = TmpPlaybackSpeed;
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
/*std::string TmpIRLog;
|
|
||||||
if(TmpIRBytes > 0 && VRecording.size() > i)
|
|
||||||
TmpIRLog = ArrayToString(VRecording.at(i).Recording.at(0).IR, TmpIRBytes, 0, 30);
|
|
||||||
else
|
|
||||||
TmpIRLog = "";
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Size:%i HotKey:%i PlSpeed:%i IR:%s X:%i Y:%i Z:%i\n",
|
|
||||||
VRecording.at(i).Recording.size(), VRecording.at(i).HotKeyWiimote, VRecording.at(i).PlaybackSpeed,
|
|
||||||
TmpIRLog.c_str(),
|
|
||||||
VRecording.at(i).Recording.at(0).x, VRecording.at(i).Recording.at(0).y, VRecording.at(i).Recording.at(0).z
|
|
||||||
);*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the accelerometer neutral values
|
|
||||||
void UpdateEeprom()
|
|
||||||
{
|
|
||||||
g_wm.cal_zero.x = g_Eeprom[22];
|
|
||||||
g_wm.cal_zero.y = g_Eeprom[23];
|
|
||||||
g_wm.cal_zero.z = g_Eeprom[24];
|
|
||||||
g_wm.cal_g.x = g_Eeprom[26] - g_Eeprom[22];
|
|
||||||
g_wm.cal_g.y = g_Eeprom[27] - g_Eeprom[24];
|
|
||||||
g_wm.cal_g.z = g_Eeprom[28] - g_Eeprom[24];
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "\nUpdateEeprom: %i %i %i\n",
|
|
||||||
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[28]);
|
|
||||||
|
|
||||||
if(g_Config.bNunchuckConnected)
|
|
||||||
{
|
|
||||||
g_nu.cal_zero.x = g_RegExt[0x20];
|
|
||||||
g_nu.cal_zero.y = g_RegExt[0x21];
|
|
||||||
g_nu.cal_zero.z = g_RegExt[0x22];
|
|
||||||
g_nu.cal_g.x = g_RegExt[0x24] - g_RegExt[0x20];
|
|
||||||
g_nu.cal_g.y = g_RegExt[0x25] - g_RegExt[0x21];
|
|
||||||
g_nu.cal_g.z = g_RegExt[0x26] - g_RegExt[0x22];
|
|
||||||
g_nu.jx.max = g_RegExt[0x28];
|
|
||||||
g_nu.jx.min = g_RegExt[0x29];
|
|
||||||
g_nu.jx.center = g_RegExt[0x2a];
|
|
||||||
g_nu.jy.max = g_RegExt[0x2b];
|
|
||||||
g_nu.jy.min = g_RegExt[0x2c];
|
|
||||||
g_nu.jy.center = g_RegExt[0x2d];
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "UpdateNunchuck: %i %i %i %i %i\n\n",
|
|
||||||
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
|
|
||||||
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
|
|
||||||
}
|
|
||||||
else if(g_Config.bClassicControllerConnected)
|
|
||||||
{
|
|
||||||
g_cc.Lx.max = g_RegExt[0x20];
|
|
||||||
g_cc.Lx.min = g_RegExt[0x21];
|
|
||||||
g_cc.Lx.center = g_RegExt[0x22];
|
|
||||||
g_cc.Ly.max = g_RegExt[0x23];
|
|
||||||
g_cc.Ly.min = g_RegExt[0x24];
|
|
||||||
g_cc.Ly.center = g_RegExt[0x25];
|
|
||||||
|
|
||||||
g_cc.Rx.max = g_RegExt[0x26];
|
|
||||||
g_cc.Rx.min = g_RegExt[0x27];
|
|
||||||
g_cc.Rx.center = g_RegExt[0x28];
|
|
||||||
g_cc.Ry.max = g_RegExt[0x29];
|
|
||||||
g_cc.Ry.min = g_RegExt[0x2a];
|
|
||||||
g_cc.Ry.center = g_RegExt[0x2b];
|
|
||||||
|
|
||||||
g_cc.Tl.neutral = g_RegExt[0x2c];
|
|
||||||
g_cc.Tr.neutral = g_RegExt[0x2d];
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "UpdateCC: %i %i %i %i %i\n\n",
|
|
||||||
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
|
|
||||||
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate checksum for the nunchuck calibration. The last two bytes.
|
|
||||||
void ExtensionChecksum(u8 * Calibration)
|
|
||||||
{
|
|
||||||
u8 sum = 0; //u8 Byte15, Byte16;
|
|
||||||
for (u32 i = 0; i < sizeof(Calibration) - 2; i++)
|
|
||||||
{
|
|
||||||
sum += Calibration[i];
|
|
||||||
printf("Plus 0x%02x\n", Calibration[i]);
|
|
||||||
}
|
|
||||||
// Byte15 = sum + 0x55; // Byte 15
|
|
||||||
// Byte16 = sum + 0xaa; // Byte 16
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial valuesm this done both in Init and Shutdown
|
|
||||||
void ResetVariables()
|
|
||||||
{
|
|
||||||
g_ReportingMode = 0;
|
|
||||||
g_ReportingChannel = 0;
|
|
||||||
g_Encryption = false;
|
|
||||||
|
|
||||||
// Set default recording values
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
g_RecordingPlaying[i] = -1;
|
|
||||||
g_RecordingCounter[i] = 0;
|
|
||||||
g_RecordingPoint[i] = 0;
|
|
||||||
g_RecordingStart[i] = 0;
|
|
||||||
g_RecordingCurrentTime[i] = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
g_EmulatedWiiMoteInitialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the extension calibration values with our default values
|
|
||||||
void SetDefaultExtensionRegistry()
|
|
||||||
{
|
|
||||||
// Copy extension id and calibration to its register
|
|
||||||
if(g_Config.bNunchuckConnected)
|
|
||||||
{
|
|
||||||
memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
|
|
||||||
memcpy(g_RegExt + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration));
|
|
||||||
memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id));
|
|
||||||
}
|
|
||||||
else if(g_Config.bClassicControllerConnected)
|
|
||||||
{
|
|
||||||
memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration));
|
|
||||||
memcpy(g_RegExt + 0x30, classic_calibration, sizeof(classic_calibration));
|
|
||||||
memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "\nSetDefaultExtensionRegistry()\n\n");
|
|
||||||
|
|
||||||
UpdateEeprom();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Write initial values to Eeprom and registers. */
|
|
||||||
void Initialize()
|
|
||||||
{
|
|
||||||
if (g_EmulatedWiiMoteInitialized) return;
|
|
||||||
|
|
||||||
// Reset variables
|
|
||||||
ResetVariables();
|
|
||||||
|
|
||||||
// Write default Eeprom data to g_Eeprom[], this may be overwritten by
|
|
||||||
// WiiMoteReal::Initialize() after this function.
|
|
||||||
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
|
|
||||||
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
|
|
||||||
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
|
|
||||||
|
|
||||||
/* Populate joyinfo for all attached devices and do g_Config.Load() if the
|
|
||||||
configuration window is not already open, if it's already open we
|
|
||||||
continue with the settings we have */
|
|
||||||
if(!g_FrameOpen)
|
|
||||||
{
|
|
||||||
Search_Devices(joyinfo, NumPads, NumGoodPads);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy extension id and calibration to its register, g_Config.Load() is needed before this
|
|
||||||
SetDefaultExtensionRegistry();
|
|
||||||
|
|
||||||
// The emulated Wiimote is initialized
|
|
||||||
g_EmulatedWiiMoteInitialized = true;
|
|
||||||
|
|
||||||
// Load pre-recorded movements
|
|
||||||
LoadRecordedMovements();
|
|
||||||
|
|
||||||
/* The Nuncheck extension ID for homebrew applications that use the zero
|
|
||||||
key. This writes 0x0000 in encrypted form (0xfefe) to 0xfe in the
|
|
||||||
extension register. */
|
|
||||||
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
|
|
||||||
|
|
||||||
// I forgot what these were for? Is this the zero key encrypted 0xa420?
|
|
||||||
// g_RegExt[0xfd] = 0x1e;
|
|
||||||
// g_RegExt[0xfc] = 0x9a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DoState(void* ptr, int mode)
|
|
||||||
{
|
|
||||||
//TODO: implement
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's
|
|
||||||
not called we need to reset these variables. */
|
|
||||||
void Shutdown(void)
|
|
||||||
{
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "ShutDown\n");
|
|
||||||
|
|
||||||
ResetVariables();
|
|
||||||
|
|
||||||
/* Close all devices carefully. We must check that we are not accessing any
|
|
||||||
undefined vector elements or any bad devices */
|
|
||||||
for (int i = 0; i < 1; i++)
|
|
||||||
{
|
|
||||||
if (PadMapping[i].enabled && joyinfo.size() > (u32)PadMapping[i].ID)
|
|
||||||
if (joyinfo.at(PadMapping[i].ID).Good)
|
|
||||||
{
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "ShutDown: %i\n", PadState[i].joy);
|
|
||||||
/* SDL_JoystickClose() crashes for some reason so I avoid this
|
|
||||||
for now, SDL_Quit() should close the pads to I think */
|
|
||||||
//if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
|
|
||||||
//PadState[i].joy = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the physical device info
|
|
||||||
joyinfo.clear();
|
|
||||||
NumPads = 0;
|
|
||||||
NumGoodPads = 0;
|
|
||||||
|
|
||||||
// Finally close SDL
|
|
||||||
if (SDL_WasInit(0)) SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* An ack delay of 1 was not small enough, but 2 seemed to work, that was about
|
|
||||||
between 20 ms and 100 ms in my case in Zelda - TP. You may have to increase
|
|
||||||
this value for other things to work, for example in the wpad demo I had to
|
|
||||||
set it to at least 3 for the Sound to be able to turned on (I have an update
|
|
||||||
rate of around 150 fps in the wpad demo) */
|
|
||||||
void CreateAckDelay(u8 _ChannelID, u16 _ReportID)
|
|
||||||
{
|
|
||||||
// Settings
|
|
||||||
int GlobalDelay = 2;
|
|
||||||
|
|
||||||
// Queue an acknowledgment
|
|
||||||
wm_ackdelay Tmp;
|
|
||||||
Tmp.Delay = GlobalDelay;
|
|
||||||
Tmp.ChannelID = _ChannelID;
|
|
||||||
Tmp.ReportID = (u8)_ReportID;
|
|
||||||
AckDelay.push_back(Tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CheckAckDelay()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (int)AckDelay.size(); i++)
|
|
||||||
{
|
|
||||||
// See if there are any acks to send
|
|
||||||
if (AckDelay.at(i).Delay >= 0)
|
|
||||||
{
|
|
||||||
if(AckDelay.at(i).Delay == 0)
|
|
||||||
{
|
|
||||||
WmSendAck(AckDelay.at(i).ChannelID, AckDelay.at(i).ReportID, 0);
|
|
||||||
AckDelay.erase(AckDelay.begin() + i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AckDelay.at(i).Delay--;
|
|
||||||
|
|
||||||
//INFO_LOG(WII_IPC_WIIMOTE, "%i 0x%04x 0x%02x", i, AckDelay.at(i).ChannelID, AckDelay.at(i).ReportID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This function produce Wiimote Input, i.e. reports from the Wiimote in
|
|
||||||
response to Output from the Wii. */
|
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
//INFO_LOG(WII_IPC_WIIMOTE, "Emu InterruptChannel\n");
|
|
||||||
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote_Input");
|
|
||||||
const u8* data = (const u8*)_pData;
|
|
||||||
|
|
||||||
/* Debugging. We have not yet decided how much of 'data' we will use, it's
|
|
||||||
not determined by sizeof(data). We have to determine it by looking at
|
|
||||||
the data cases. */
|
|
||||||
InterruptDebugging(true, data);
|
|
||||||
|
|
||||||
hid_packet* hidp = (hid_packet*) data;
|
|
||||||
switch(hidp->type)
|
|
||||||
{
|
|
||||||
case HID_TYPE_DATA:
|
|
||||||
{
|
|
||||||
switch(hidp->param)
|
|
||||||
{
|
|
||||||
case HID_PARAM_OUTPUT:
|
|
||||||
{
|
|
||||||
wm_report* sr = (wm_report*)hidp->data;
|
|
||||||
HidOutputReport(_channelID, sr);
|
|
||||||
|
|
||||||
/* This is the 0x22 answer to all Inputs. In most games it
|
|
||||||
didn't matter if it was written before or after
|
|
||||||
HidOutputReport(), but Wii Sports and Mario Galaxy would
|
|
||||||
stop working if it was placed before
|
|
||||||
HidOutputReport(). Zelda - TP is even more sensitive and
|
|
||||||
require a delay after the Input for the Nunchuck to
|
|
||||||
work. It seemed to be enough to delay only the Nunchuck
|
|
||||||
registry reads and writes but for now I'm delaying all
|
|
||||||
inputs. Both for status changes and Eeprom and registry
|
|
||||||
reads and writes. */
|
|
||||||
|
|
||||||
// There are no 0x22 replys to these report from the real
|
|
||||||
// wiimote from what I could see Report 0x10 that seems to
|
|
||||||
// be only used for rumble, and we don't need to answer
|
|
||||||
// that, also if we do *we should update the 0x22 to have
|
|
||||||
// the core keys* otherwise the game will think we release
|
|
||||||
// the key every time it rumbles
|
|
||||||
if(!(data[1] == WM_READ_DATA && data[2] == 0x00)
|
|
||||||
&& !(data[1] == WM_REQUEST_STATUS)
|
|
||||||
&& !(data[1] == WM_WRITE_SPEAKER_DATA)
|
|
||||||
&& !(data[1] == WM_RUMBLE))
|
|
||||||
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
//INFO_LOG(WII_IPC_WIIMOTE, "Emu ControlChannel\n");
|
|
||||||
|
|
||||||
const u8* data = (const u8*)_pData;
|
|
||||||
// Dump raw data
|
|
||||||
{
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote_ControlChannel");
|
|
||||||
std::string Temp = ArrayToString(data, 0, _Size);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
hid_packet* hidp = (hid_packet*) data;
|
|
||||||
switch(hidp->type)
|
|
||||||
{
|
|
||||||
case HID_TYPE_HANDSHAKE:
|
|
||||||
if (hidp->param == HID_PARAM_INPUT)
|
|
||||||
{
|
|
||||||
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_INPUT");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HID_TYPE_SET_REPORT:
|
|
||||||
if (hidp->param == HID_PARAM_INPUT)
|
|
||||||
{
|
|
||||||
PanicAlert("HID_TYPE_SET_REPORT input");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HidOutputReport(_channelID, (wm_report*)hidp->data);
|
|
||||||
|
|
||||||
// Return handshake
|
|
||||||
u8 handshake = 0;
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, &handshake, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HID_TYPE_DATA:
|
|
||||||
PanicAlert("HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PanicAlert("HidControlChannel: Unknown type %x and param %x", hidp->type, hidp->param);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This is called from Wiimote_Update(). See SystemTimers.cpp for a
|
|
||||||
documentation. I'm not sure exactly how often this function is called but I
|
|
||||||
think it's tied to the frame rate of the game rather than a certain amount
|
|
||||||
of times per second. */
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
|
|
||||||
//INFO_LOG(WII_IPC_WIIMOTE, "Emu Update: %i\n", g_ReportingMode);
|
|
||||||
|
|
||||||
// Check if the pad state should be updated
|
|
||||||
if ((g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2
|
|
||||||
|| g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1 || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG2
|
|
||||||
|| g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG2
|
|
||||||
|| g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG2)
|
|
||||||
&& NumGoodPads > 0 && joyinfo.size() > (u32)PadMapping[0].ID)
|
|
||||||
{
|
|
||||||
const int Page = 0;
|
|
||||||
WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page, joyinfo[PadMapping[Page].ID].NumButtons);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(g_ReportingMode)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
|
|
||||||
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
|
|
||||||
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel); break;
|
|
||||||
case WM_REPORT_CORE_ACCEL_EXT16: SendReportCoreAccelExt16(g_ReportingChannel); break;
|
|
||||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Potentially send a delayed acknowledgement to an InterruptChannel() Output
|
|
||||||
CheckAckDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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_EMU_H
|
|
||||||
#define WIIMOTE_EMU_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
|
||||||
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
u32 convert24bit(const u8* src);
|
|
||||||
u16 convert16bit(const u8* src);
|
|
||||||
void GetMousePos(float& x, float& y);
|
|
||||||
|
|
||||||
// General functions
|
|
||||||
void Initialize();
|
|
||||||
void DoState(void* ptr, int mode);
|
|
||||||
void Shutdown(void);
|
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
|
||||||
void Update();
|
|
||||||
|
|
||||||
// Recordings
|
|
||||||
void LoadRecordedMovements();
|
|
||||||
|
|
||||||
// Registers and calibration values
|
|
||||||
void ResetVariables();
|
|
||||||
void UpdateEeprom();
|
|
||||||
void SetDefaultExtensionRegistry();
|
|
||||||
|
|
||||||
// Gamepad
|
|
||||||
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
|
|
||||||
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons);
|
|
||||||
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr);
|
|
||||||
|
|
||||||
// Accelerometer
|
|
||||||
void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z);
|
|
||||||
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&);
|
|
||||||
float AccelerometerToG(float Current, float Neutral, float G);
|
|
||||||
void TiltTest(u8 x, u8 y, u8 z);
|
|
||||||
void Tilt(u8 &_x, u8 &_y, u8 &_z);
|
|
||||||
void AdjustAngles(float &Roll, float &Pitch);
|
|
||||||
|
|
||||||
// IR data
|
|
||||||
void IRData2Dots(u8 *Data);
|
|
||||||
void IRData2DotsBasic(u8 *Data);
|
|
||||||
void ReorderIRDots();
|
|
||||||
void IRData2Distance();
|
|
||||||
|
|
||||||
// Classic Controller data
|
|
||||||
std::string CCData2Values(u8 *Data);
|
|
||||||
|
|
||||||
}; // WiiMoteEmu
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,179 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
|
||||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
|
||||||
|
|
||||||
#include "Common.h" // Common
|
|
||||||
#include "StringUtil.h" // for ArrayToString()
|
|
||||||
#include "IniFile.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "EmuDefinitions.h" // Local
|
|
||||||
#include "main.h"
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuSubroutines.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "Encryption.h" // for extension encryption
|
|
||||||
#include "Config.h" // for g_Config
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
// Fill joyinfo with the current connected devices
|
|
||||||
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
|
|
||||||
{
|
|
||||||
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
|
|
||||||
|
|
||||||
// Warn the user if no gamepads are detected
|
|
||||||
if (_NumGoodPads == 0 && g_EmulatorRunning)
|
|
||||||
{
|
|
||||||
//PanicAlert("nJoy: No Gamepad Detected");
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load PadMapping[] etc
|
|
||||||
g_Config.Load();
|
|
||||||
|
|
||||||
// Update the PadState[].joy handle
|
|
||||||
for (int i = 0; i < 1; i++)
|
|
||||||
{
|
|
||||||
if (PadMapping[i].enabled && joyinfo.size() > (u32)PadMapping[i].ID)
|
|
||||||
if(joyinfo.at(PadMapping[i].ID).Good)
|
|
||||||
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return adjusted input values
|
|
||||||
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
|
|
||||||
{
|
|
||||||
// This has to be changed if multiple Wiimotes are to be supported later
|
|
||||||
const int Page = 0;
|
|
||||||
|
|
||||||
// Copy all states to a local variable
|
|
||||||
Lx = PadState[Page].Axis.Lx;
|
|
||||||
Ly = PadState[Page].Axis.Ly;
|
|
||||||
Rx = PadState[Page].Axis.Rx;
|
|
||||||
Ry = PadState[Page].Axis.Ry;
|
|
||||||
Tl = PadState[Page].Axis.Tl;
|
|
||||||
Tr = PadState[Page].Axis.Tr;
|
|
||||||
|
|
||||||
// Check the circle to square option
|
|
||||||
if(PadMapping[Page].bCircle2Square)
|
|
||||||
{
|
|
||||||
std::vector<int> main_xy = InputCommon::Square2Circle(Lx, Ly, Page, PadMapping[Page].SDiagonal, true);
|
|
||||||
|
|
||||||
Lx = main_xy.at(0);
|
|
||||||
Ly = main_xy.at(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dead zone adjustment
|
|
||||||
float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0f;
|
|
||||||
float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0f;
|
|
||||||
if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly))
|
|
||||||
{
|
|
||||||
Lx = 0;
|
|
||||||
Ly = 0;
|
|
||||||
}
|
|
||||||
if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry))
|
|
||||||
{
|
|
||||||
Rx = 0;
|
|
||||||
Ry = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Downsize the values from 0x8000 to 0x80
|
|
||||||
Lx = InputCommon::Pad_Convert(Lx);
|
|
||||||
Ly = InputCommon::Pad_Convert(Ly);
|
|
||||||
Rx = InputCommon::Pad_Convert(Rx);
|
|
||||||
Ry = InputCommon::Pad_Convert(Ry);
|
|
||||||
// The XInput range is already 0 to 0x80
|
|
||||||
if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
|
|
||||||
{
|
|
||||||
Tl = InputCommon::Pad_Convert(PadState[Page].Axis.Tl);
|
|
||||||
Tr = InputCommon::Pad_Convert(PadState[Page].Axis.Tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Request joystick state
|
|
||||||
/* Called from: PAD_GetStatus() Input: The virtual device 0, 1, 2 or 3
|
|
||||||
Function: Updates the PadState struct with the current pad status. The input
|
|
||||||
value "controller" is for a virtual controller 0 to 3. */
|
|
||||||
|
|
||||||
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
|
|
||||||
{
|
|
||||||
// Return if we have no pads
|
|
||||||
if (NumGoodPads == 0) return;
|
|
||||||
|
|
||||||
// Update the gamepad status
|
|
||||||
SDL_JoystickUpdate();
|
|
||||||
|
|
||||||
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
|
|
||||||
_PadState.Axis.Lx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Lx);
|
|
||||||
_PadState.Axis.Ly = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ly);
|
|
||||||
_PadState.Axis.Rx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Rx);
|
|
||||||
_PadState.Axis.Ry = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ry);
|
|
||||||
|
|
||||||
// Update the analog trigger axis values
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (_PadMapping.triggertype == InputCommon::CTL_TRIGGER_SDL)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
|
|
||||||
// We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has
|
|
||||||
// no good way of handling that
|
|
||||||
if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000);
|
|
||||||
if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000);
|
|
||||||
#ifdef _WIN32
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_PadState.Axis.Tl = XInput::GetXI(0, _PadMapping.Axis.Tl - 1000);
|
|
||||||
_PadState.Axis.Tr = XInput::GetXI(0, _PadMapping.Axis.Tr - 1000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Debugging
|
|
||||||
// Console::ClearScreen();
|
|
||||||
DEBUG_LOG(CONSOLE,
|
|
||||||
"Controller and handle: %i %i\n"
|
|
||||||
|
|
||||||
"Triggers:%i %i %i %i %i\n"
|
|
||||||
|
|
||||||
"Analog:%06i %06i \n",
|
|
||||||
|
|
||||||
controller, (int)_PadState.joy,
|
|
||||||
|
|
||||||
_PadMapping.triggertype,
|
|
||||||
_PadMapping.Axis.Tl, _PadMapping.Axis.Tr,
|
|
||||||
_PadState.Axis.Tl, _PadState.Axis.Tr,
|
|
||||||
|
|
||||||
_PadState.Axis.Lx, _PadState.Axis.Ly
|
|
||||||
);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace WiiMoteEmu
|
|
||||||
|
|
|
@ -1,556 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 "StringUtil.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "EmuMain.h" // Local
|
|
||||||
#include "EmuSubroutines.h"
|
|
||||||
#include "Config.h" // for g_Config
|
|
||||||
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Subroutines
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
/* 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 lights and speaker enable/disable and mute/unmute values are
|
|
||||||
0x2 = Disable
|
|
||||||
0x6 = Enable
|
|
||||||
*/
|
|
||||||
void HidOutputReport(u16 _channelID, wm_report* sr) {
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "HidOutputReport (0x%02x)", sr->channel);
|
|
||||||
std::string Temp;
|
|
||||||
|
|
||||||
switch(sr->channel)
|
|
||||||
{
|
|
||||||
case WM_RUMBLE:
|
|
||||||
// TODO: Implement rumble for real wiimotes
|
|
||||||
break;
|
|
||||||
case WM_LEDS: // 0x11
|
|
||||||
WmLeds(_channelID, (wm_leds*)sr->data);
|
|
||||||
break;
|
|
||||||
case WM_DATA_REPORTING: // 0x12
|
|
||||||
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
|
|
||||||
break;
|
|
||||||
case WM_REQUEST_STATUS: // 0x15
|
|
||||||
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) WmRequestStatus(_channelID, (wm_request_status*)sr->data);
|
|
||||||
//Temp = ArrayToString(sr->data, sizeof(wm_request_status), 0);
|
|
||||||
//INFO_LOG(CONSOLE, "\n%s: InterruptChannel: %s\n", Tm().c_str(), Temp.c_str());
|
|
||||||
break;
|
|
||||||
case WM_READ_DATA: // 0x17
|
|
||||||
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) WmReadData(_channelID, (wm_read_data*)sr->data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* This enables or disables the IR lights, we update the global variable
|
|
||||||
g_IR so that WmRequestStatus() knows about it */
|
|
||||||
case WM_IR_PIXEL_CLOCK: // 0x13
|
|
||||||
case WM_IR_LOGIC: // 0x1a
|
|
||||||
WARN_LOG(WII_IPC_WIIMOTE, " IR Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
|
|
||||||
INFO_LOG(CONSOLE, "IR Enable/Disable 0x%02x: 0x%02x\n", sr->channel, sr->data[0]);
|
|
||||||
if(sr->data[0] == 0x02) g_IR = 0;
|
|
||||||
else if(sr->data[0] == 0x06) g_IR = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_WRITE_DATA: // 0x16
|
|
||||||
WmWriteData(_channelID, (wm_write_data*)sr->data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SPEAKER_ENABLE: // 0x14
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " WM Speaker Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
|
|
||||||
//INFO_LOG(CONSOLE, "Speaker Enable/Disable 0x%02x: 0x%02x\n", sr->channel, sr->data[0]);
|
|
||||||
if(sr->data[0] == 0x02) g_Speaker = 0;
|
|
||||||
else if(sr->data[0] == 0x06) g_Speaker = 1;
|
|
||||||
break;
|
|
||||||
case WM_SPEAKER_MUTE: // 0x19
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " WM Mute Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
|
|
||||||
//INFO_LOG(CONSOLE, "Speaker Mute/Unmute 0x%02x: 0x%02x\n", sr->channel, sr->data[0]);
|
|
||||||
if(sr->data[0] == 0x02) g_SpeakerVoice = 0; // g_SpeakerVoice
|
|
||||||
else if(sr->data[0] == 0x06) g_SpeakerVoice = 1;
|
|
||||||
break;
|
|
||||||
case WM_WRITE_SPEAKER_DATA: // 0x18
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generate the right header for wm reports. The returned values is the length
|
|
||||||
of the header before the data begins. It's always two for all reports 0x20 -
|
|
||||||
0x22, 0x30 - 0x37 */
|
|
||||||
int WriteWmReport(u8* dst, u8 channel)
|
|
||||||
{
|
|
||||||
// Update the first byte to 0xa1
|
|
||||||
u32 Offset = 0;
|
|
||||||
hid_packet* pHidHeader = (hid_packet*)(dst + Offset);
|
|
||||||
Offset += sizeof(hid_packet);
|
|
||||||
pHidHeader->type = HID_TYPE_DATA;
|
|
||||||
pHidHeader->param = HID_PARAM_INPUT;
|
|
||||||
|
|
||||||
// Update the second byte to the current report type 0x20 - 0x22, 0x30 - 0x37
|
|
||||||
wm_report* pReport = (wm_report*)(dst + Offset);
|
|
||||||
Offset += sizeof(wm_report);
|
|
||||||
pReport->channel = channel;
|
|
||||||
return Offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* LED (blue lights) report. */
|
|
||||||
void WmLeds(u16 _channelID, wm_leds* leds) {
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Set LEDs Leds: %x Rumble: %x", leds->leds, leds->rumble);
|
|
||||||
|
|
||||||
g_Leds = leds->leds;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This will generate the 0x22 acknowledgment after all Input reports. It will
|
|
||||||
have the form a1 22 00 00 _reportID 00. The first two bytes are the core
|
|
||||||
buttons data, they are 00 00 when nothing is pressed. The last byte is the
|
|
||||||
success code 00. */
|
|
||||||
void WmSendAck(u16 _channelID, u8 _reportID, u32 address)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = 0;
|
|
||||||
|
|
||||||
// Header
|
|
||||||
hid_packet* pHidHeader = (hid_packet*)(DataFrame + Offset);
|
|
||||||
pHidHeader->type = HID_TYPE_DATA;
|
|
||||||
pHidHeader->param = HID_PARAM_INPUT;
|
|
||||||
Offset += sizeof(hid_packet);
|
|
||||||
|
|
||||||
wm_acknowledge* pData = (wm_acknowledge*)(DataFrame + Offset);
|
|
||||||
pData->Channel = WM_WRITE_DATA_REPLY;
|
|
||||||
pData->unk0 = 0;
|
|
||||||
pData->unk1 = 0;
|
|
||||||
pData->reportID = _reportID;
|
|
||||||
pData->errorID = 0;
|
|
||||||
Offset += sizeof(wm_acknowledge);
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " WMSendAck()");
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Report ID: %02x", _reportID);
|
|
||||||
//std::string Temp = ArrayToString(DataFrame, Offset, 0);
|
|
||||||
//LOGV(WII_IPC_WIIMOTE, 2, " Data: %s", Temp.c_str());
|
|
||||||
//INFO_LOG(CONSOLE, "%s: WMSendAck: %s\n", Tm(true).c_str(), Temp.c_str());
|
|
||||||
|
|
||||||
/* Debug. Write the report for extension registry writes.
|
|
||||||
if((_reportID == 0x16 || _reportID == 0x17) && ((address >> 16) & 0xfe) == 0xa4)
|
|
||||||
{
|
|
||||||
INFO_LOG(CONSOLE, "\nWMSendAck Report ID: %02x Encryption: %02x\n", _reportID, g_RegExt[0xf0]);
|
|
||||||
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());
|
|
||||||
}*/
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read data from Wiimote and Extensions registers. */
|
|
||||||
void WmReadData(u16 _channelID, wm_read_data* rd)
|
|
||||||
{
|
|
||||||
u32 address = convert24bit(rd->address);
|
|
||||||
u16 size = convert16bit(rd->size);
|
|
||||||
std::string Temp;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Read data Address space: %x", rd->space);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Read data Address: 0x%06x", address);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Read data Size: 0x%04x", size);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Read data Rumble: %x", rd->rumble);
|
|
||||||
|
|
||||||
//u32 _address = address;
|
|
||||||
std::string Tmp; // Debugging
|
|
||||||
|
|
||||||
/* Now we determine what address space we are reading from. Space 0 is
|
|
||||||
Eeprom and space 1 and 2 is the registers. */
|
|
||||||
if(rd->space == WM_SPACE_EEPROM)
|
|
||||||
{
|
|
||||||
if (address + size > WIIMOTE_EEPROM_SIZE)
|
|
||||||
{
|
|
||||||
PanicAlert("WmReadData: address + size out of bounds");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SendReadDataReply(_channelID, g_Eeprom + address, address, (u8)size);
|
|
||||||
/*INFO_LOG(CONSOLE, "Read RegEeprom: Size: %i, Address: %08x, Offset: %08x\n",
|
|
||||||
size, address, (address & 0xffff));*/
|
|
||||||
}
|
|
||||||
else if(rd->space == WM_SPACE_REGS1 || rd->space == WM_SPACE_REGS2)
|
|
||||||
{
|
|
||||||
u8* block;
|
|
||||||
u32 blockSize;
|
|
||||||
switch((address >> 16) & 0xFE)
|
|
||||||
{
|
|
||||||
case 0xA2:
|
|
||||||
block = g_RegSpeaker;
|
|
||||||
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xa2: g_RegSpeaker");
|
|
||||||
/*Tmp = ArrayToString(g_RegSpeaker, size, (address & 0xffff));
|
|
||||||
//LOGV(WII_IPC_WIIMOTE, 0, " Data: %s", Temp.c_str());
|
|
||||||
INFO_LOG(CONSOLE, "Read RegSpkr: Size %i Address %08x Offset %08x\nData %s\n",
|
|
||||||
size, address, (address & 0xffff), Tmp.c_str());*/
|
|
||||||
break;
|
|
||||||
case 0xA4:
|
|
||||||
block = g_RegExt;
|
|
||||||
blockSize = WIIMOTE_REG_EXT_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xa4: Read ExtReg");
|
|
||||||
/*Tmp = ArrayToString(g_RegExt, size, (address & 0xffff), 40);
|
|
||||||
//LOGV(WII_IPC_WIIMOTE, 0, " Data: %s", Temp.c_str());
|
|
||||||
INFO_LOG(CONSOLE, "Read RegExt: Size %i Address %08x Offset %08x\nData %s\n",
|
|
||||||
size, address, (address & 0xffff), Tmp.c_str());*/
|
|
||||||
break;
|
|
||||||
case 0xB0:
|
|
||||||
block = g_RegIr;
|
|
||||||
blockSize = WIIMOTE_REG_IR_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case: 0xb0 g_RegIr");
|
|
||||||
/*Tmp = ArrayToString(g_RegIr, size, (address & 0xffff));
|
|
||||||
//LOGV(WII_IPC_WIIMOTE, 0, " Data: %s", Temp.c_str());
|
|
||||||
INFO_LOG(CONSOLE, "Read RegIR: Size %i Address %08x Offset %08x\nData %s\n",
|
|
||||||
size, address, (address & 0xffff), Tmp.c_str());*/
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: bad register block!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Encrypt data that is read from the Wiimote Extension Register
|
|
||||||
if(((address >> 16) & 0xfe) == 0xa4)
|
|
||||||
{
|
|
||||||
/* Debugging
|
|
||||||
INFO_LOG(CONSOLE, "\n\nWmReadData Address: %08x Offset: %08x Size: %i byte\n",
|
|
||||||
address, address & 0xffff, (u8)size);
|
|
||||||
// Debugging
|
|
||||||
u32 offset = address & 0xffff;
|
|
||||||
std::string Temp = ArrayToString(g_RegExt, size, offset);
|
|
||||||
INFO_LOG(CONSOLE, "Unencrypted data:\n%s\n", Temp.c_str());*/
|
|
||||||
|
|
||||||
// Check if encrypted reads is on
|
|
||||||
if(g_RegExt[0xf0] == 0xaa)
|
|
||||||
{
|
|
||||||
/* Copy the registry to a temporary space. We don't want to change the unencrypted
|
|
||||||
data in the registry */
|
|
||||||
memcpy(g_RegExtTmp, g_RegExt, sizeof(g_RegExt));
|
|
||||||
|
|
||||||
// Encrypt g_RegExtTmp at that location
|
|
||||||
wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[address & 0xffff], (address & 0xffff), (u8)size);
|
|
||||||
|
|
||||||
// Update the block that SendReadDataReply will eventually send to the Wii
|
|
||||||
block = g_RegExtTmp;
|
|
||||||
|
|
||||||
/* Debugging: Show the encrypted data
|
|
||||||
std::string Temp = ArrayToString(g_RegExtTmp, size, offset);
|
|
||||||
INFO_LOG(CONSOLE, "Encrypted data:\n%s\n", Temp.c_str());*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//-------------
|
|
||||||
|
|
||||||
address &= 0xFFFF;
|
|
||||||
if(address + size > blockSize) {
|
|
||||||
PanicAlert("WmReadData: address + size out of bounds!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let this function process the message and send it to the Wii
|
|
||||||
SendReadDataReply(_channelID, block + address, address, (u8)size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x!", size, rd->space);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
|
||||||
{
|
|
||||||
int dataOffset = 0;
|
|
||||||
const u8* data = (const u8*)_Base;
|
|
||||||
|
|
||||||
while (_Size > 0)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
// Write the first two bytes to DataFrame
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_READ_DATA_REPLY);
|
|
||||||
|
|
||||||
// Limit the size to 16 bytes
|
|
||||||
int copySize = _Size;
|
|
||||||
if (copySize > 16) copySize = 16;
|
|
||||||
|
|
||||||
// Connect pReply->data to the almost empty DataFrame
|
|
||||||
wm_read_data_reply* pReply = (wm_read_data_reply*)(DataFrame + Offset);
|
|
||||||
// Now we increase Offset to the final size of the report
|
|
||||||
Offset += sizeof(wm_read_data_reply);
|
|
||||||
// Add header values
|
|
||||||
pReply->buttons = 0;
|
|
||||||
pReply->error = 0;
|
|
||||||
// 0x1 means two bytes, 0xf means 16 bytes
|
|
||||||
pReply->size = (copySize - 1) & 0xf;
|
|
||||||
pReply->address = Common::swap16(_Address + dataOffset);
|
|
||||||
|
|
||||||
// Write a pice of _Base to DataFrame
|
|
||||||
memcpy(pReply->data, data + dataOffset, copySize);
|
|
||||||
|
|
||||||
// Check if we have less than 16 bytes left to send
|
|
||||||
if(copySize < 16) memset(pReply->data + copySize, 0, 16 - copySize);
|
|
||||||
|
|
||||||
// Update DataOffset for the next loop
|
|
||||||
dataOffset += copySize;
|
|
||||||
|
|
||||||
/* 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 capibration 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 (Common::swap16(pReply->address + pReply->size) > WIIMOTE_EEPROM_FREE_SIZE)
|
|
||||||
{
|
|
||||||
pReply->size = 0x0f;
|
|
||||||
pReply->error = 0x08;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendReadDataReply()");
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Size: 0x%x", pReply->size);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Address: 0x%04x", pReply->address);
|
|
||||||
/*INFO_LOG(CONSOLE, " SendReadDataReply()\n");
|
|
||||||
INFO_LOG(CONSOLE, " Offset: 0x%x\n", Offset);
|
|
||||||
INFO_LOG(CONSOLE, " dataOffset: 0x%x\n", dataOffset);
|
|
||||||
INFO_LOG(CONSOLE, " copySize: 0x%x\n", copySize);
|
|
||||||
INFO_LOG(CONSOLE, " Size: 0x%x\n", pReply->size);
|
|
||||||
INFO_LOG(CONSOLE, " Address: 0x%04x\n", Common::swap16(pReply->address));*/
|
|
||||||
//std::string Temp = ArrayToString(data, 0x40);
|
|
||||||
//INFO_LOG(CONSOLE, "Data:\n%s\n", Temp.c_str());
|
|
||||||
|
|
||||||
// Send a piece
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
// Update the size that is left
|
|
||||||
_Size -= copySize;
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_Size != 0) {
|
|
||||||
PanicAlert("WiiMote-Plugin: SendReadDataReply() failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Write data to Wiimote and Extensions registers. */
|
|
||||||
void WmWriteData(u16 _channelID, wm_write_data* wd)
|
|
||||||
{
|
|
||||||
u32 address = convert24bit(wd->address);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, "Write data");
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Address space: %x", wd->space);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Size: 0x%02x", wd->size);
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, " Rumble: %x", wd->rumble);
|
|
||||||
//std::string Temp = ArrayToString(wd->data, wd->size);
|
|
||||||
//LOGV(WII_IPC_WIIMOTE, 0, " Data: %s", Temp.c_str());
|
|
||||||
|
|
||||||
// Write to EEPROM
|
|
||||||
if(wd->size <= 16 && wd->space == WM_SPACE_EEPROM)
|
|
||||||
{
|
|
||||||
if(address + wd->size > WIIMOTE_EEPROM_SIZE) {
|
|
||||||
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: address + size out of bounds!");
|
|
||||||
PanicAlert("WmWriteData: address + size out of bounds!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(g_Eeprom + address, wd->data, wd->size);
|
|
||||||
/*INFO_LOG(CONSOLE, "Write RegEeprom: Size: %i, Address: %08x, Offset: %08x\n",
|
|
||||||
wd->size, address, (address & 0xffff));*/
|
|
||||||
}
|
|
||||||
// Write to registers
|
|
||||||
else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2))
|
|
||||||
{
|
|
||||||
u8* block;
|
|
||||||
u32 blockSize;
|
|
||||||
switch((address >> 16) & 0xFE)
|
|
||||||
{
|
|
||||||
case 0xA2:
|
|
||||||
block = g_RegSpeaker;
|
|
||||||
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xa2: RegSpeaker");
|
|
||||||
/*INFO_LOG(CONSOLE, "Write RegSpeaker: Size: %i, Address: %08x, Offset: %08x\n",
|
|
||||||
wd->size, address, (address & 0xffff));
|
|
||||||
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());*/
|
|
||||||
break;
|
|
||||||
case 0xA4:
|
|
||||||
block = g_RegExt; // Extension Controller register
|
|
||||||
blockSize = WIIMOTE_REG_EXT_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xa4: ExtReg");
|
|
||||||
/*INFO_LOG(CONSOLE, "Write RegExt Size: %i Address: %08x Offset: %08x \n",
|
|
||||||
wd->size, address, (address & 0xffff));
|
|
||||||
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());*/
|
|
||||||
break;
|
|
||||||
case 0xB0:
|
|
||||||
block = g_RegIr;
|
|
||||||
blockSize = WIIMOTE_REG_IR_SIZE;
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xb0: RegIr");
|
|
||||||
/*INFO_LOG(CONSOLE, "Write RegIR Size: %i Address: %08x Offset: %08x \n",
|
|
||||||
wd->size, address, (address & 0xffff));
|
|
||||||
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());*/
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: bad register block!");
|
|
||||||
PanicAlert("WmWriteData: bad register block!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove for example 0xa40000 from the address
|
|
||||||
address &= 0xFFFF;
|
|
||||||
|
|
||||||
// Check if the address is within bounds
|
|
||||||
if(address + wd->size > blockSize) {
|
|
||||||
PanicAlert("WmWriteData: address + size out of bounds!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally write the registers to the right structure
|
|
||||||
memcpy(block + address, wd->data, wd->size);
|
|
||||||
|
|
||||||
|
|
||||||
// Generate key for the Wiimote Extension
|
|
||||||
if(blockSize == WIIMOTE_REG_EXT_SIZE)
|
|
||||||
{
|
|
||||||
/* Debugging. Write the data.
|
|
||||||
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());
|
|
||||||
INFO_LOG(CONSOLE, "Current address: %08x\n", address); */
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
if(address >= 0x40 && address <= 0x4c)
|
|
||||||
wiimote_gen_key(&g_ExtKey, &g_RegExt[0x40]);
|
|
||||||
}
|
|
||||||
// -------------
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
PanicAlert("WmWriteData: unimplemented parameters!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just added for home brew... Isn't it enough that we call this from
|
|
||||||
InterruptChannel()? Or is there a separate route here that don't pass
|
|
||||||
though InterruptChannel()? */
|
|
||||||
//WmSendAck(_channelID, WM_WRITE_DATA, _address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
|
|
||||||
{
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Request Status: Rumble: %x Channel: %04x",
|
|
||||||
rs->rumble, _channelID);
|
|
||||||
|
|
||||||
//SendStatusReport();
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_STATUS_REPORT);
|
|
||||||
|
|
||||||
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_status_report);
|
|
||||||
memset(pStatus, 0, sizeof(wm_status_report)); // fill the status report with zeroes
|
|
||||||
|
|
||||||
// Status values
|
|
||||||
pStatus->battery_low = 0; // battery is okay
|
|
||||||
pStatus->leds = g_Leds; // leds are 4 bit
|
|
||||||
pStatus->ir = g_IR; // 1 bit
|
|
||||||
pStatus->speaker = g_Speaker; // 1 bit
|
|
||||||
/* Battery levels in voltage
|
|
||||||
0x00 - 0x32: level 1
|
|
||||||
0x33 - 0x43: level 2
|
|
||||||
0x33 - 0x54: level 3
|
|
||||||
0x55 - 0xff: level 4 */
|
|
||||||
pStatus->battery = 0x5f; // fully charged
|
|
||||||
|
|
||||||
// Check if we have a specific order about the extension status
|
|
||||||
if (Extension == -1)
|
|
||||||
{
|
|
||||||
// Read config value for this one
|
|
||||||
if(g_Config.bNunchuckConnected || g_Config.bClassicControllerConnected)
|
|
||||||
pStatus->extension = 1;
|
|
||||||
else
|
|
||||||
pStatus->extension = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(Extension)
|
|
||||||
pStatus->extension = 1;
|
|
||||||
else
|
|
||||||
pStatus->extension = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Extension: %x", pStatus->extension);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " SendStatusReport() Flags: 0x%02x Battery: %d"
|
|
||||||
,pStatus->padding1[2], pStatus->battery);
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
ReadDebugging(true, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // WiiMoteEmu
|
|
|
@ -1,68 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 _EMU_SUBFUNCTIONS_
|
|
||||||
#define _EMU_SUBFUNCTIONS_
|
|
||||||
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "Common.h" // Common
|
|
||||||
#include "main.h"
|
|
||||||
#include "wiimote_hid.h" // Local
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
#include "Encryption.h"
|
|
||||||
|
|
||||||
// Declarations and definitions
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
|
||||||
{
|
|
||||||
|
|
||||||
void HidOutputReport(u16 _channelID, wm_report* sr);
|
|
||||||
|
|
||||||
void WmLeds(u16 _channelID, wm_leds* leds);
|
|
||||||
void WmReadData(u16 _channelID, wm_read_data* rd);
|
|
||||||
void WmWriteData(u16 _channelID, wm_write_data* wd);
|
|
||||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension = -1);
|
|
||||||
void WmRequestStatus_(u16 _channelID, int a);
|
|
||||||
void WmDataReporting(u16 _channelID, wm_data_reporting* dr);
|
|
||||||
|
|
||||||
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size);
|
|
||||||
void SendReportCoreAccel(u16 _channelID);
|
|
||||||
void SendReportCoreAccelIr12(u16 _channelID);
|
|
||||||
void SendReportCore(u16 _channelID);
|
|
||||||
void SendReportCoreAccelExt16(u16 _channelID);
|
|
||||||
void SendReportCoreAccelIr10Ext(u16 _channelID);
|
|
||||||
|
|
||||||
int WriteWmReport(u8* dst, u8 channel);
|
|
||||||
void WmSendAck(u16 _channelID, u8 _reportID, u32 address);
|
|
||||||
|
|
||||||
void FillReportAcc(wm_accel& _acc);
|
|
||||||
void FillReportInfo(wm_core& _core);
|
|
||||||
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1);
|
|
||||||
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
|
|
||||||
void FillReportExtension(wm_extension& _ext);
|
|
||||||
void FillReportClassicExtension(wm_classic_extension& _ext);
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif //_EMU_DECLARATIONS_
|
|
|
@ -1,296 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 "pluginspecs_wiimote.h"
|
|
||||||
#include "Common.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];
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "rand: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", rand[0], rand[1], rand[2], rand[3], rand[4], rand[5], rand[6], rand[7], rand[8], rand[9]);
|
|
||||||
INFO_LOG(CONSOLE, "key: %02x %02x %02x %02x %02x %02x\n", 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)
|
|
||||||
INFO_LOG(CONSOLE, "idx: %d\n", idx);
|
|
||||||
|
|
||||||
gentabs(rand, skey, idx, key->ft, key->sb);
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "ft: %02x %02x %02x %02x %02x %02x %02x %02x\n", key->ft[0], key->ft[1], key->ft[2], key->ft[3], key->ft[4], key->ft[5], key->ft[6], key->ft[7]);
|
|
||||||
INFO_LOG(CONSOLE, "sb: %02x %02x %02x %02x %02x %02x %02x %02x\n", 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];
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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() */
|
|
||||||
// ----------------
|
|
||||||
typedef struct {
|
|
||||||
u8 ft[8];
|
|
||||||
u8 sb[8];
|
|
||||||
} wiimote_key;
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,387 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Includes
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
#include <iostream> // System
|
|
||||||
|
|
||||||
#include "wiiuse.h" // Externals
|
|
||||||
|
|
||||||
#include "StringUtil.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "wiimote_real.h" // Local
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "main.h"
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
#include "ConfigDlg.h"
|
|
||||||
#endif
|
|
||||||
#include "Config.h"
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace WiiMoteReal
|
|
||||||
{
|
|
||||||
int GetReportSize(struct wiimote_t* wm)
|
|
||||||
{
|
|
||||||
// The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte
|
|
||||||
if(WIIUSE_USING_EXP(wm)) return 22; else return 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_ctrl_status(struct wiimote_t* wm)
|
|
||||||
{
|
|
||||||
INFO_LOG(CONSOLE, "\n\n--- CONTROLLER STATUS [wiimote id %i] ---\n", wm->unid);
|
|
||||||
|
|
||||||
INFO_LOG(CONSOLE, "attachment: %i\n", wm->exp.type);
|
|
||||||
INFO_LOG(CONSOLE, "speaker: %i\n", WIIUSE_USING_SPEAKER(wm));
|
|
||||||
INFO_LOG(CONSOLE, "ir: %i\n", WIIUSE_USING_IR(wm));
|
|
||||||
INFO_LOG(CONSOLE, "leds: %i %i %i %i\n", WIIUSE_IS_LED_SET(wm, 1), WIIUSE_IS_LED_SET(wm, 2), WIIUSE_IS_LED_SET(wm, 3), WIIUSE_IS_LED_SET(wm, 4));
|
|
||||||
INFO_LOG(CONSOLE, "battery: %f %%\n", wm->battery_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IRDataOK(struct wiimote_t* wm)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "IRDataOK: ");
|
|
||||||
// The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte
|
|
||||||
int ReportSize = GetReportSize(wm);
|
|
||||||
for(int i = 0; i < ReportSize; i++)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "%02x ", wm->event_buf[i]);
|
|
||||||
if (wm->event_buf[i] > 0)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_event(struct wiimote_t* wm)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "\n\n--- EVENT [id %i] ---\n", wm->unid);
|
|
||||||
|
|
||||||
// if a button is pressed, report it
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) INFO_LOG(CONSOLE, "A pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)) INFO_LOG(CONSOLE, "B pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) INFO_LOG(CONSOLE, "UP pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) INFO_LOG(CONSOLE, "DOWN pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT)) INFO_LOG(CONSOLE, "LEFT pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT)) INFO_LOG(CONSOLE, "RIGHT pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) INFO_LOG(CONSOLE, "MINUS pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) INFO_LOG(CONSOLE, "PLUS pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) INFO_LOG(CONSOLE, "ONE pressed\n");
|
|
||||||
//if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) g_Run = false;
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_TWO)) INFO_LOG(CONSOLE, "TWO pressed\n");
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_HOME)) INFO_LOG(CONSOLE, "HOME pressed\n");
|
|
||||||
|
|
||||||
|
|
||||||
// Pressing minus will tell the wiimote we are no longer interested in movement.
|
|
||||||
// This is useful because it saves battery power.
|
|
||||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
|
|
||||||
{
|
|
||||||
wiiuse_motion_sensing(wm, 0);
|
|
||||||
wiiuse_set_ir(wm, 0);
|
|
||||||
g_MotionSensing = false;
|
|
||||||
}
|
|
||||||
// Turn aceelerometer and IR reporting on, there is some kind of bug that prevents us from turing these on
|
|
||||||
// directly after each other, so we have to wait for another wiiuse_poll() this way
|
|
||||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
|
|
||||||
{
|
|
||||||
wiiuse_motion_sensing(wm, 1);
|
|
||||||
g_MotionSensing = true;
|
|
||||||
}
|
|
||||||
// Turn IR reporting on
|
|
||||||
if (g_MotionSensing && !WIIUSE_USING_IR(wm))
|
|
||||||
wiiuse_set_ir(wm, 1);
|
|
||||||
|
|
||||||
// Print battery status
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
if(frame && g_Config.bUpdateRealWiimote)
|
|
||||||
frame->m_GaugeBattery->SetValue((int)floor((wm->battery_level * 100) + 0.5));
|
|
||||||
#endif
|
|
||||||
// Create shortcut to the nunchuck
|
|
||||||
struct nunchuk_t* nc = NULL;
|
|
||||||
if (wm->exp.type == EXP_NUNCHUK)
|
|
||||||
nc = (nunchuk_t*)&wm->exp.nunchuk;
|
|
||||||
|
|
||||||
// If the accelerometer is turned on then print angles
|
|
||||||
if (WIIUSE_USING_ACC(wm) && WIIUSE_USING_IR(wm))
|
|
||||||
{
|
|
||||||
std::string Tmp;
|
|
||||||
Tmp += StringFromFormat("Roll: %2.1f ", wm->orient.roll);
|
|
||||||
Tmp += StringFromFormat("Pitch: %2.1f ", wm->orient.pitch);
|
|
||||||
Tmp += StringFromFormat("Battery: %1.2f\n", wm->battery_level);
|
|
||||||
Tmp += StringFromFormat("G-Force x, y, z: %1.2f %1.2f %1.2f\n", wm->gforce.x, wm->gforce.y, wm->gforce.z);
|
|
||||||
Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z);
|
|
||||||
|
|
||||||
// The report size is 0x33 = 18, 0x37 = 22
|
|
||||||
int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18;
|
|
||||||
|
|
||||||
// wm->event_buf is cleared at the end of all wiiuse_poll(), so wm->event_buf will always be zero
|
|
||||||
// after that. To get the raw IR data we need to read the wiimote again. This seems to work most of the time,
|
|
||||||
// it seems to fails with a regular interval about each tenth read.
|
|
||||||
if(wiiuse_io_read(wm))
|
|
||||||
{
|
|
||||||
// Check that it's not zero
|
|
||||||
if (IRDataOK(wm)) memcpy(g_EventBuffer, wm->event_buf, ReportSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each of the 4 possible IR sources
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
// Check if the source is visible
|
|
||||||
if (wm->ir.dot[i].visible)
|
|
||||||
Tmp += StringFromFormat("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tmp += "\n";
|
|
||||||
Tmp += StringFromFormat("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y);
|
|
||||||
Tmp += StringFromFormat("IR z distance: %f\n", wm->ir.z);
|
|
||||||
|
|
||||||
if(wm->exp.type == EXP_NUNCHUK)
|
|
||||||
{
|
|
||||||
Tmp += "\n";
|
|
||||||
Tmp += StringFromFormat("Nunchuck accel x, y, z: %03i %03i %03i\n", nc->accel.x, nc->accel.y, nc->accel.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Tmp += "\n";
|
|
||||||
//std::string TmpData = ArrayToString(g_EventBuffer, ReportSize, 0, 30);
|
|
||||||
//Tmp += "Data: " + TmpData;
|
|
||||||
|
|
||||||
//Console::ClearScreen();
|
|
||||||
//INFO_LOG(CONSOLE, "%s\n\n", Tmp.c_str());
|
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
if(frame)
|
|
||||||
{
|
|
||||||
// Produce adjusted accelerometer values
|
|
||||||
float _Gx = (float)(wm->accel.x - wm->accel_calib.cal_zero.x) / (float)wm->accel_calib.cal_g.x;
|
|
||||||
float _Gy = (float)(wm->accel.y - wm->accel_calib.cal_zero.y) / (float)wm->accel_calib.cal_g.y;
|
|
||||||
float _Gz = (float)(wm->accel.z - wm->accel_calib.cal_zero.z) / (float)wm->accel_calib.cal_g.z;
|
|
||||||
|
|
||||||
// Conver the data to integers
|
|
||||||
int Gx = (int)(_Gx * 100);
|
|
||||||
int Gy = (int)(_Gy * 100);
|
|
||||||
int Gz = (int)(_Gz * 100);
|
|
||||||
|
|
||||||
// And for the Nunchuck
|
|
||||||
u8 AccelNX = 0, AccelNY = 0, AccelNZ = 0;
|
|
||||||
if(wm->exp.type == EXP_NUNCHUK)
|
|
||||||
{
|
|
||||||
if((nc->accel.x + g_Config.iAccNunNeutralX) <= 255) AccelNX = nc->accel.x + g_Config.iAccNunNeutralX;
|
|
||||||
if((nc->accel.y + g_Config.iAccNunNeutralY) <= 255) AccelNY = nc->accel.y + g_Config.iAccNunNeutralY;
|
|
||||||
if((nc->accel.z + g_Config.iAccNunNeutralZ) <= 255) AccelNZ = nc->accel.z + g_Config.iAccNunNeutralZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_Config.bUpdateRealWiimote)
|
|
||||||
{
|
|
||||||
// Update gauges
|
|
||||||
frame->m_GaugeRoll[0]->SetValue(wm->orient.roll + 180);
|
|
||||||
frame->m_GaugeRoll[1]->SetValue(wm->orient.pitch + 180);
|
|
||||||
|
|
||||||
// Show g. forces between -3 and 3
|
|
||||||
frame->m_GaugeGForce[0]->SetValue((int)floor((wm->gforce.x * 100) + 300.5));
|
|
||||||
frame->m_GaugeGForce[1]->SetValue((int)floor((wm->gforce.y * 100) + 300.5));
|
|
||||||
frame->m_GaugeGForce[2]->SetValue((int)floor((wm->gforce.z * 100) + 300.5));
|
|
||||||
|
|
||||||
frame->m_GaugeAccel[0]->SetValue(wm->accel.x);
|
|
||||||
frame->m_GaugeAccel[1]->SetValue(wm->accel.y);
|
|
||||||
frame->m_GaugeAccel[2]->SetValue(wm->accel.z);
|
|
||||||
|
|
||||||
frame->m_TextIR->SetLabel(wxString::Format(
|
|
||||||
wxT("Cursor: %03u %03u\nDistance:%4.0f"), wm->ir.x, wm->ir.y, wm->ir.z));
|
|
||||||
|
|
||||||
//frame->m_TextAccNeutralCurrent->SetLabel(wxString::Format(
|
|
||||||
// wxT("Current: %03u %03u %03u"), Gx, Gy, Gz));
|
|
||||||
|
|
||||||
if(frame->m_bRecording)
|
|
||||||
INFO_LOG(CONSOLE, "Wiiuse Recorded accel x, y, z: %03i %03i %03i\n", Gx, Gy, Gz);
|
|
||||||
//INFO_LOG(CONSOLE, "Wiiuse Recorded accel x, y, z: %02x %02x %02x\n", Gx, Gy, Gz);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the data to be saved
|
|
||||||
//const u8* data = (const u8*)wm->event_buf;
|
|
||||||
frame->DoRecordMovement(Gx, Gy, Gz, (g_EventBuffer + 6),
|
|
||||||
(WIIUSE_USING_EXP(wm) ? 10 : 12));
|
|
||||||
|
|
||||||
// Turn recording on and off
|
|
||||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) frame->DoRecordA(true);
|
|
||||||
else frame->DoRecordA(false);
|
|
||||||
|
|
||||||
// ------------------------------------
|
|
||||||
// Show roll and pitch in the status box
|
|
||||||
// --------------
|
|
||||||
/*
|
|
||||||
if(!g_DebugData)
|
|
||||||
{
|
|
||||||
// Console::ClearScreen();
|
|
||||||
INFO_LOG(CONSOLE, "Roll:%03i Pitch:%03i\n", (int)wm->orient.roll, (int)wm->orient.pitch);
|
|
||||||
}
|
|
||||||
// Convert Roll and Pitch from 180 to 0x8000
|
|
||||||
int Roll = (int)wm->orient.roll * (0x8000 / 180);
|
|
||||||
int Pitch = (int)wm->orient.pitch * (0x8000 / 180);
|
|
||||||
// Convert it to the box
|
|
||||||
frame->Convert2Box(Roll);
|
|
||||||
frame->Convert2Box(Pitch);
|
|
||||||
// Show roll and pitch in the axis boxes
|
|
||||||
frame->m_bmpDotRightOut[0]->SetPosition(wxPoint(Roll, Pitch));*/
|
|
||||||
// ---------------------
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Otherwise remove the values
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
if (frame)
|
|
||||||
{
|
|
||||||
frame->m_GaugeRoll[0]->SetValue(0);
|
|
||||||
frame->m_GaugeRoll[1]->SetValue(0);
|
|
||||||
|
|
||||||
frame->m_GaugeGForce[0]->SetValue(0);
|
|
||||||
frame->m_GaugeGForce[1]->SetValue(0);
|
|
||||||
frame->m_GaugeGForce[2]->SetValue(0);
|
|
||||||
|
|
||||||
frame->m_GaugeAccel[0]->SetValue(0);
|
|
||||||
frame->m_GaugeAccel[1]->SetValue(0);
|
|
||||||
frame->m_GaugeAccel[2]->SetValue(0);
|
|
||||||
|
|
||||||
frame->m_TextIR->SetLabel(wxT("Cursor:\nDistance:"));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadWiimote()
|
|
||||||
{
|
|
||||||
/* I place this outside wiiuse_poll() to produce a continous recording regardless of the status
|
|
||||||
change of the Wiimote, wiiuse_poll() is only true if the status has changed. However, this the
|
|
||||||
timing functions for recording playback that checks the time of the recording this should not
|
|
||||||
be needed. But I still use it becase it seemed like state_changed() or the threshold values or
|
|
||||||
something else might fail so that only huge status changed were reported. */
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
handle_event(g_WiiMotesFromWiiUse[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declaration
|
|
||||||
std::string Temp;
|
|
||||||
|
|
||||||
/* Timeout for data reading. This is used in Initialize() to read the Eeprom, if we have not gotten
|
|
||||||
what we wanted in the WIIUSE_READ_DATA case we stop this loop and enable the regular
|
|
||||||
wiiuse_io_read() and wiiuse_io_write() loop again. */
|
|
||||||
if (g_RunTemporary)
|
|
||||||
{
|
|
||||||
// The SecondsToWait holds if the update rate of wiiuse_poll() is kept at the default value of 10 ms
|
|
||||||
static const int SecondsToWait = 2;
|
|
||||||
g_RunTemporaryCountdown++;
|
|
||||||
if(g_RunTemporaryCountdown > (SecondsToWait * 100))
|
|
||||||
{
|
|
||||||
g_RunTemporaryCountdown = 0;
|
|
||||||
g_RunTemporary = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read formatted Wiimote data
|
|
||||||
if (wiiuse_poll(g_WiiMotesFromWiiUse, MAX_WIIMOTES))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This happens if something happened on any wiimote.
|
|
||||||
* So go through each one and check if anything happened.
|
|
||||||
*/
|
|
||||||
int i = 0;
|
|
||||||
for (; i < MAX_WIIMOTES; ++i)
|
|
||||||
{
|
|
||||||
switch (g_WiiMotesFromWiiUse[i]->event)
|
|
||||||
{
|
|
||||||
case WIIUSE_EVENT:
|
|
||||||
/* a generic event occured */
|
|
||||||
//handle_event(g_WiiMotesFromWiiUse[i]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_STATUS:
|
|
||||||
/* a status event occured */
|
|
||||||
//handle_ctrl_status(g_WiiMotesFromWiiUse[i]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_DISCONNECT:
|
|
||||||
case WIIUSE_UNEXPECTED_DISCONNECT:
|
|
||||||
/* the wiimote disconnected */
|
|
||||||
//handle_disconnect(wiimotes[i]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_READ_DATA:
|
|
||||||
/*
|
|
||||||
* Data we requested to read was returned.
|
|
||||||
* Take a look at wiimotes[i]->read_req
|
|
||||||
* for the data.
|
|
||||||
*/
|
|
||||||
if(g_WiiMotesFromWiiUse[i]->read_req->size == sizeof(WiiMoteEmu::EepromData_0)
|
|
||||||
&& g_WiiMotesFromWiiUse[i]->read_req->addr == 0)
|
|
||||||
{
|
|
||||||
Temp = ArrayToString(g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30);
|
|
||||||
memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0));
|
|
||||||
INFO_LOG(CONSOLE, "EEPROM: %s\n", Temp.c_str());
|
|
||||||
WiiMoteEmu::UpdateEeprom();
|
|
||||||
g_RunTemporary = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_NUNCHUK_INSERTED:
|
|
||||||
/*
|
|
||||||
* a nunchuk was inserted
|
|
||||||
* This is a good place to set any nunchuk specific
|
|
||||||
* threshold values. By default they are the same
|
|
||||||
* as the wiimote.
|
|
||||||
*/
|
|
||||||
//wiiuse_set_nunchuk_orient_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 90.0f);
|
|
||||||
//wiiuse_set_nunchuk_accel_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 100);
|
|
||||||
INFO_LOG(CONSOLE, "Nunchuk inserted.\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_CLASSIC_CTRL_INSERTED:
|
|
||||||
INFO_LOG(CONSOLE, "Classic controller inserted.\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED:
|
|
||||||
// some expansion was inserted
|
|
||||||
//handle_ctrl_status(wiimotes[i]);
|
|
||||||
INFO_LOG(CONSOLE, "Guitar Hero 3 controller inserted.\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WIIUSE_NUNCHUK_REMOVED:
|
|
||||||
case WIIUSE_CLASSIC_CTRL_REMOVED:
|
|
||||||
case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED:
|
|
||||||
// some expansion was removed
|
|
||||||
//handle_ctrl_status(wiimotes[i]);
|
|
||||||
INFO_LOG(CONSOLE, "An expansion was removed.\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}; // end of namespace
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
# -*- python -*-
|
|
||||||
|
|
||||||
Import('env')
|
|
||||||
import sys
|
|
||||||
|
|
||||||
wiienv = env.Clone()
|
|
||||||
name = "Plugin_Wiimote-testing"
|
|
||||||
|
|
||||||
files = [
|
|
||||||
"Config.cpp",
|
|
||||||
"DataReports.cpp",
|
|
||||||
"EmuDefinitions.cpp",
|
|
||||||
"EmuDynamics.cpp",
|
|
||||||
"EmuMain.cpp",
|
|
||||||
"EmuPad.cpp",
|
|
||||||
"EmuSubroutines.cpp",
|
|
||||||
"Encryption.cpp",
|
|
||||||
"main.cpp",
|
|
||||||
]
|
|
||||||
if wiienv['HAVE_WX']:
|
|
||||||
files += [
|
|
||||||
"ConfigDlg.cpp",
|
|
||||||
"ConfigGamepad.cpp",
|
|
||||||
"ConfigRecording.cpp",
|
|
||||||
"FillReport.cpp",
|
|
||||||
]
|
|
||||||
|
|
||||||
libs = [ 'common', 'inputcommon' ]
|
|
||||||
|
|
||||||
|
|
||||||
cxxflags = [ '-fPIC' ]
|
|
||||||
|
|
||||||
if wiienv['HAVE_WIIUSE']:
|
|
||||||
libs += [ 'wiiuse' ]
|
|
||||||
files += [ "wiimote_real.cpp" ]
|
|
||||||
files += [ "ReadWiimote.cpp" ]
|
|
||||||
cxxflags += ['-DHAVE_WIIUSE']
|
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
|
||||||
wiienv.Append(
|
|
||||||
CXXFLAGS = cxxflags,
|
|
||||||
LINKFLAGS = ['-framework' ,'IOBluetooth'],
|
|
||||||
LIBS = libs,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
wiienv.Append(
|
|
||||||
CXXFLAGS = cxxflags,
|
|
||||||
LIBS = libs,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
wiienv.SharedLibrary(env['plugin_dir']+name, files)
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,109 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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 MAIN_H
|
|
||||||
#define MAIN_H
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Includes
|
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
|
||||||
#include <iostream> // System
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Definitions and declarations
|
|
||||||
// ¯¯¯¯¯¯¯¯¯
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define sleep(x) Sleep(x)
|
|
||||||
#else
|
|
||||||
#define sleep(x) usleep(x*1000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void DoInitialize();
|
|
||||||
double GetDoubleTime();
|
|
||||||
int GetUpdateRate();
|
|
||||||
void InterruptDebugging(bool Emu, const void* _pData);
|
|
||||||
void ReadDebugging(bool Emu, const void* _pData, int Size);
|
|
||||||
bool IsFocus();
|
|
||||||
|
|
||||||
|
|
||||||
// Movement recording
|
|
||||||
#define RECORDING_ROWS 15
|
|
||||||
#define WM_RECORDING_WIIMOTE 0
|
|
||||||
#define WM_RECORDING_NUNCHUCK 1
|
|
||||||
#define WM_RECORDING_IR 2
|
|
||||||
struct SRecording
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
double Time;
|
|
||||||
u8 IR[12];
|
|
||||||
};
|
|
||||||
struct SRecordingAll
|
|
||||||
{
|
|
||||||
std::vector<SRecording> Recording;
|
|
||||||
int HotKeySwitch, HotKeyWiimote, HotKeyNunchuck, HotKeyIR;
|
|
||||||
int PlaybackSpeed;
|
|
||||||
int IRBytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef EXCLUDEMAIN_H
|
|
||||||
// General
|
|
||||||
extern bool g_EmulatorRunning;
|
|
||||||
extern u32 g_ISOId;
|
|
||||||
extern bool g_FrameOpen;
|
|
||||||
extern bool g_RealWiiMotePresent;
|
|
||||||
extern bool g_RealWiiMoteInitialized;
|
|
||||||
extern bool g_EmulatedWiiMoteInitialized;
|
|
||||||
extern bool g_WiimoteUnexpectedDisconnect;
|
|
||||||
#ifdef _WIN32
|
|
||||||
extern HWND g_ParentHWND;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Settings
|
|
||||||
extern accel_cal g_wm;
|
|
||||||
extern nu_cal g_nu;
|
|
||||||
extern cc_cal g_cc;
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
extern bool g_DebugAccelerometer;
|
|
||||||
extern bool g_DebugData;
|
|
||||||
extern bool g_DebugComm;
|
|
||||||
extern bool g_DebugSoundData;
|
|
||||||
extern bool g_DebugCustom;
|
|
||||||
|
|
||||||
// Update speed
|
|
||||||
extern int g_UpdateCounter;
|
|
||||||
extern double g_UpdateTime;
|
|
||||||
extern int g_UpdateWriteScreen;
|
|
||||||
extern int g_UpdateRate;
|
|
||||||
extern std::vector<int> g_UpdateTimeList;
|
|
||||||
|
|
||||||
// Movement recording
|
|
||||||
extern std::vector<SRecordingAll> VRecording;
|
|
||||||
|
|
||||||
//#if defined(HAVE_WX) && HAVE_WX && defined(__CONFIGDIALOG_h__)
|
|
||||||
// extern ConfigDialog *frame;
|
|
||||||
//#endif
|
|
||||||
#endif
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
#endif // MAIN_H
|
|
|
@ -1,330 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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>
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
struct wm_report {
|
|
||||||
u8 channel;
|
|
||||||
u8 data[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define WM_RUMBLE 0x10
|
|
||||||
#define WM_LEDS 0x11
|
|
||||||
struct wm_leds {
|
|
||||||
u8 rumble : 1;
|
|
||||||
u8 : 3;
|
|
||||||
u8 leds : 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define WM_DATA_REPORTING 0x12
|
|
||||||
struct wm_data_reporting {
|
|
||||||
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 {
|
|
||||||
u8 padding1[2]; // two 00
|
|
||||||
u8 battery_low : 1;
|
|
||||||
u8 extension : 1;
|
|
||||||
u8 speaker : 1;
|
|
||||||
u8 ir : 1;
|
|
||||||
u8 leds : 4;
|
|
||||||
u8 padding2[2]; // two 00
|
|
||||||
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_WRITE_DATA_REPLY 0x22 //empty, afaik
|
|
||||||
struct wm_acknowledge
|
|
||||||
{
|
|
||||||
u8 Channel;
|
|
||||||
u8 unk0; // Core buttons state (wm_core), can be zero
|
|
||||||
u8 unk1;
|
|
||||||
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 {
|
|
||||||
u16 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
|
|
||||||
|
|
||||||
struct wm_core {
|
|
||||||
u8 left : 1;
|
|
||||||
u8 right : 1;
|
|
||||||
u8 down : 1;
|
|
||||||
u8 up : 1;
|
|
||||||
u8 plus : 1;
|
|
||||||
u8 : 3;
|
|
||||||
u8 two : 1;
|
|
||||||
u8 one : 1;
|
|
||||||
u8 b : 1;
|
|
||||||
u8 a : 1;
|
|
||||||
u8 minus : 1;
|
|
||||||
u8 : 2;
|
|
||||||
u8 home : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
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_cc_4
|
|
||||||
{
|
|
||||||
u8 padding : 1;
|
|
||||||
u8 bRT : 1;
|
|
||||||
u8 bP : 1;
|
|
||||||
u8 bH : 1;
|
|
||||||
u8 bM : 1;
|
|
||||||
u8 bLT : 1;
|
|
||||||
u8 bdD : 1;
|
|
||||||
u8 bdR : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wm_cc_5
|
|
||||||
{
|
|
||||||
u8 bdU : 1;
|
|
||||||
u8 bdL : 1;
|
|
||||||
u8 bZR : 1;
|
|
||||||
u8 bX : 1;
|
|
||||||
u8 bA : 1;
|
|
||||||
u8 bY : 1;
|
|
||||||
u8 bB : 1;
|
|
||||||
u8 bZL : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
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 Rx : 1;
|
|
||||||
u8 rT : 5; // byte 3
|
|
||||||
u8 lT : 3;
|
|
||||||
wm_cc_4 b1; // byte 4
|
|
||||||
wm_cc_5 b2; // byte 5
|
|
||||||
};
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
wm_accel cal_zero; /**< zero calibration */
|
|
||||||
wm_accel cal_g; /**< 1g difference around 0cal */
|
|
||||||
};
|
|
||||||
|
|
||||||
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; //
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif //WIIMOTE_HID_H
|
|
|
@ -1,456 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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/
|
|
||||||
|
|
||||||
|
|
||||||
// Includes
|
|
||||||
#include <iostream> // System
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#include "wiiuse.h"
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "StringUtil.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "pluginspecs_wiimote.h"
|
|
||||||
|
|
||||||
#include "wiimote_hid.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "Config.h"
|
|
||||||
#include "EmuMain.h"
|
|
||||||
#include "EmuDefinitions.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "wiimote_real.h"
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
|
||||||
#include "ConfigDlg.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
|
||||||
|
|
||||||
namespace WiiMoteReal
|
|
||||||
{
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Forwarding
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
class CWiiMote;
|
|
||||||
|
|
||||||
THREAD_RETURN ReadWiimote_ThreadFunc(void* arg);
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Variable declarations
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
wiimote_t** g_WiiMotesFromWiiUse = NULL;
|
|
||||||
Common::Thread* g_pReadThread = NULL;
|
|
||||||
int g_NumberOfWiiMotes;
|
|
||||||
CWiiMote* g_WiiMotes[MAX_WIIMOTES];
|
|
||||||
bool g_Shutdown = false;
|
|
||||||
bool g_ThreadGoing = false;
|
|
||||||
bool g_LocalThread = true;
|
|
||||||
bool g_IRSensing = false;
|
|
||||||
bool g_MotionSensing = false;
|
|
||||||
u64 g_UpdateTime = 0;
|
|
||||||
int g_UpdateCounter = 0;
|
|
||||||
bool g_RunTemporary = false;
|
|
||||||
int g_RunTemporaryCountdown = 0;
|
|
||||||
u8 g_EventBuffer[32];
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Probably this class should be in its own file
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
class CWiiMote
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
CWiiMote(u8 _WiimoteNumber, wiimote_t* _pWiimote)
|
|
||||||
: m_WiimoteNumber(_WiimoteNumber)
|
|
||||||
, m_channelID(0)
|
|
||||||
, m_pCriticalSection(NULL)
|
|
||||||
, m_LastReportValid(false)
|
|
||||||
, m_pWiiMote(_pWiimote)
|
|
||||||
{
|
|
||||||
m_pCriticalSection = new Common::CriticalSection();
|
|
||||||
|
|
||||||
//wiiuse_set_leds(m_pWiiMote, WIIMOTE_LED_4);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// F|RES: i dunno if we really need this
|
|
||||||
CancelIo(m_pWiiMote->dev_handle);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CWiiMote()
|
|
||||||
{
|
|
||||||
delete m_pCriticalSection;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Queue raw HID data from the core to the wiimote
|
|
||||||
void SendData(u16 _channelID, const u8* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
m_channelID = _channelID;
|
|
||||||
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
{
|
|
||||||
SEvent WriteEvent;
|
|
||||||
memcpy(WriteEvent.m_PayLoad, _pData + 1, _Size - 1);
|
|
||||||
m_EventWriteQueue.push(WriteEvent);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
//std::string Temp = ArrayToString(WriteEvent.m_PayLoad, 28, 0, 30);
|
|
||||||
//INFO_LOG(CONSOLE, "Wiimote Write:\n%s\n", Temp.c_str());
|
|
||||||
}
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read and write data to the Wiimote */
|
|
||||||
void ReadData()
|
|
||||||
{
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
// Send data to the Wiimote
|
|
||||||
if (!m_EventWriteQueue.empty())
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "Writing data to the Wiimote\n");
|
|
||||||
SEvent& rEvent = m_EventWriteQueue.front();
|
|
||||||
wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, MAX_PAYLOAD);
|
|
||||||
m_EventWriteQueue.pop();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Debugging. Move the data one step to the right first.
|
|
||||||
memcpy(rEvent.m_PayLoad + 1, rEvent.m_PayLoad, sizeof(rEvent.m_PayLoad) - 1);
|
|
||||||
rEvent.m_PayLoad[0] = 0xa2;
|
|
||||||
InterruptDebugging(false, rEvent.m_PayLoad);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
|
|
||||||
// Read data from wiimote (but don't send it to the core, just filter and queue)
|
|
||||||
if (wiiuse_io_read(m_pWiiMote))
|
|
||||||
{
|
|
||||||
const byte* pBuffer = m_pWiiMote->event_buf;
|
|
||||||
// Check if we have a channel (connection) if so save the data...
|
|
||||||
if (m_channelID > 0)
|
|
||||||
{
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
// Filter out data reports
|
|
||||||
if (pBuffer[0] >= 0x30)
|
|
||||||
{
|
|
||||||
// Copy Buffer to LastReport
|
|
||||||
memcpy(m_LastReport.m_PayLoad, pBuffer, MAX_PAYLOAD);
|
|
||||||
m_LastReportValid = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy Buffer to ImportantEvent
|
|
||||||
SEvent ImportantEvent;
|
|
||||||
memcpy(ImportantEvent.m_PayLoad, pBuffer, MAX_PAYLOAD);
|
|
||||||
|
|
||||||
// Put it in the read queue right away
|
|
||||||
m_EventReadQueue.push(ImportantEvent);
|
|
||||||
}
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Send queued data to the core
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
// Thread function
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
if (m_EventReadQueue.empty())
|
|
||||||
{
|
|
||||||
// Send the data report
|
|
||||||
if (m_LastReportValid) SendEvent(m_LastReport);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Send a 0x20, 0x21 or 0x22 report
|
|
||||||
SendEvent(m_EventReadQueue.front());
|
|
||||||
m_EventReadQueue.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Clear events
|
|
||||||
void ClearEvents()
|
|
||||||
{
|
|
||||||
while (!m_EventReadQueue.empty())
|
|
||||||
m_EventReadQueue.pop();
|
|
||||||
while (!m_EventWriteQueue.empty())
|
|
||||||
m_EventWriteQueue.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct SEvent
|
|
||||||
{
|
|
||||||
SEvent()
|
|
||||||
{
|
|
||||||
memset(m_PayLoad, 0, MAX_PAYLOAD);
|
|
||||||
}
|
|
||||||
byte m_PayLoad[MAX_PAYLOAD];
|
|
||||||
};
|
|
||||||
typedef std::queue<SEvent> CEventQueue;
|
|
||||||
|
|
||||||
u8 m_WiimoteNumber; // Just for debugging
|
|
||||||
u16 m_channelID;
|
|
||||||
CEventQueue m_EventReadQueue; // Read from Wiimote
|
|
||||||
CEventQueue m_EventWriteQueue; // Write to Wiimote
|
|
||||||
Common::CriticalSection* m_pCriticalSection;
|
|
||||||
bool m_LastReportValid;
|
|
||||||
SEvent m_LastReport;
|
|
||||||
wiimote_t* m_pWiiMote; // This is g_WiiMotesFromWiiUse[]
|
|
||||||
|
|
||||||
// Send queued data to the core
|
|
||||||
void SendEvent(SEvent& _rEvent)
|
|
||||||
{
|
|
||||||
// We don't have an answer channel
|
|
||||||
if (m_channelID == 0) return;
|
|
||||||
|
|
||||||
// Check event buffer
|
|
||||||
u8 Buffer[1024];
|
|
||||||
u32 Offset = 0;
|
|
||||||
hid_packet* pHidHeader = (hid_packet*)(Buffer + Offset);
|
|
||||||
Offset += sizeof(hid_packet);
|
|
||||||
pHidHeader->type = HID_TYPE_DATA;
|
|
||||||
pHidHeader->param = HID_PARAM_INPUT;
|
|
||||||
|
|
||||||
// Create the buffer
|
|
||||||
memcpy(&Buffer[Offset], _rEvent.m_PayLoad, MAX_PAYLOAD);
|
|
||||||
/* This Offset value is not exactly correct like it is for the emulated
|
|
||||||
Wiimote reports. It's often to big, but I guess that's okay. The game
|
|
||||||
will know how big the actual data is. */
|
|
||||||
Offset += MAX_PAYLOAD;
|
|
||||||
|
|
||||||
// Send it
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(m_channelID, Buffer, Offset);
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
// ReadDebugging(false, Buffer, Offset);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************************
|
|
||||||
// Function Definitions
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
void SendAcc(u8 _ReportID)
|
|
||||||
{
|
|
||||||
byte DataAcc[MAX_PAYLOAD];
|
|
||||||
|
|
||||||
DataAcc[0] = 0x22; // Report 0x12
|
|
||||||
DataAcc[1] = 0x00; // Core buttons
|
|
||||||
DataAcc[2] = 0x00;
|
|
||||||
DataAcc[3] = _ReportID; // Reporting mode
|
|
||||||
|
|
||||||
// TODO: Update for multiple wiimotes?
|
|
||||||
wiiuse_io_write(WiiMoteReal::g_WiiMotesFromWiiUse[0], (byte*)DataAcc, MAX_PAYLOAD);
|
|
||||||
|
|
||||||
std::string Temp = ArrayToString(DataAcc, 28, 0, 30);
|
|
||||||
INFO_LOG(CONSOLE, "SendAcc: %s\n", Temp.c_str());
|
|
||||||
|
|
||||||
//22 00 00 _reportID 00
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear any potential queued events
|
|
||||||
void ClearEvents()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
g_WiiMotes[i]->ClearEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flash lights, and if connecting, also rumble
|
|
||||||
void FlashLights(bool Connect)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
if(Connect) wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[i], 1);
|
|
||||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[i], WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4);
|
|
||||||
}
|
|
||||||
sleep(100);
|
|
||||||
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
if(Connect)
|
|
||||||
{
|
|
||||||
wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[i], 0);
|
|
||||||
|
|
||||||
// End with light 1 or 4
|
|
||||||
wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[i], WIIMOTE_LED_1);
|
|
||||||
}
|
|
||||||
else wiiuse_set_leds(WiiMoteReal::g_WiiMotesFromWiiUse[i], WIIMOTE_LED_4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Initialize()
|
|
||||||
{
|
|
||||||
// Return if already initialized
|
|
||||||
if (g_RealWiiMoteInitialized) return g_NumberOfWiiMotes;
|
|
||||||
|
|
||||||
// Clear the wiimote classes
|
|
||||||
memset(g_WiiMotes, 0, sizeof(CWiiMote*) * MAX_WIIMOTES);
|
|
||||||
|
|
||||||
// Call Wiiuse.dll
|
|
||||||
g_WiiMotesFromWiiUse = wiiuse_init(MAX_WIIMOTES);
|
|
||||||
g_NumberOfWiiMotes = wiiuse_find(g_WiiMotesFromWiiUse, MAX_WIIMOTES, 5);
|
|
||||||
if (g_NumberOfWiiMotes > 0) g_RealWiiMotePresent = true;
|
|
||||||
INFO_LOG(CONSOLE, "Found No of Wiimotes: %i\n", g_NumberOfWiiMotes);
|
|
||||||
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
// Remove the wiiuse_poll() threshold
|
|
||||||
wiiuse_set_accel_threshold(g_WiiMotesFromWiiUse[i], 0);
|
|
||||||
|
|
||||||
// Set the sensor bar position, this should only affect the internal wiiuse api functions
|
|
||||||
wiiuse_set_ir_position(g_WiiMotesFromWiiUse[i], WIIUSE_IR_ABOVE);
|
|
||||||
|
|
||||||
// Set flags
|
|
||||||
//wiiuse_set_flags(g_WiiMotesFromWiiUse[i], NULL, WIIUSE_SMOOTHING);
|
|
||||||
}
|
|
||||||
// I don't seem to need wiiuse_connect() in Windows. But Linux needs it.
|
|
||||||
#ifndef _WIN32
|
|
||||||
int Connect = wiiuse_connect(g_WiiMotesFromWiiUse, MAX_WIIMOTES);
|
|
||||||
INFO_LOG(CONSOLE, "Connected: %i\n", Connect);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If we are connecting from the config window without a game running we flash the lights
|
|
||||||
if (!g_EmulatorRunning && g_RealWiiMotePresent) FlashLights(true);
|
|
||||||
|
|
||||||
// Create Wiimote classes
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
g_WiiMotes[i] = new CWiiMote(i + 1, g_WiiMotesFromWiiUse[i]);
|
|
||||||
|
|
||||||
// Create a new thread and start listening for Wiimote data
|
|
||||||
if (g_NumberOfWiiMotes > 0)
|
|
||||||
g_pReadThread = new Common::Thread(ReadWiimote_ThreadFunc, NULL);
|
|
||||||
|
|
||||||
// If we are not using the emulated wiimote we can run the thread temporary until the data has beeen copied
|
|
||||||
if(g_Config.bUseRealWiimote) g_RunTemporary = true;
|
|
||||||
|
|
||||||
/* Allocate memory and copy the Wiimote eeprom accelerometer neutral values
|
|
||||||
to g_Eeprom. Unlike with and extension we have to do this here, because
|
|
||||||
this data is only read once when the Wiimote is connected. Also, we
|
|
||||||
can't change the neutral values the wiimote will report, I think, unless
|
|
||||||
we update its eeprom? In any case it's probably better to let the
|
|
||||||
current calibration be where it is and adjust the global values after
|
|
||||||
that to avoid overwriting critical data on any Wiimote. */
|
|
||||||
// TODO: Update for multiple wiimotes?
|
|
||||||
byte *data = (byte*)malloc(sizeof(byte) * sizeof(WiiMoteEmu::EepromData_0));
|
|
||||||
wiiuse_read_data(g_WiiMotesFromWiiUse[0], data, 0, sizeof(WiiMoteEmu::EepromData_0));
|
|
||||||
|
|
||||||
// Don't run the Wiimote thread if no wiimotes were found
|
|
||||||
if (g_NumberOfWiiMotes > 0) g_Shutdown = false;
|
|
||||||
|
|
||||||
// Initialized, even if we didn't find a Wiimote
|
|
||||||
g_RealWiiMoteInitialized = true;
|
|
||||||
|
|
||||||
return g_NumberOfWiiMotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoState(void* ptr, int mode) {}
|
|
||||||
|
|
||||||
void Shutdown(void)
|
|
||||||
{
|
|
||||||
// Stop the loop in the thread
|
|
||||||
g_Shutdown = true;
|
|
||||||
|
|
||||||
// Stop the thread
|
|
||||||
if (g_pReadThread != NULL)
|
|
||||||
{
|
|
||||||
delete g_pReadThread;
|
|
||||||
g_pReadThread = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the wiimotes
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
delete g_WiiMotes[i];
|
|
||||||
g_WiiMotes[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flash flights
|
|
||||||
if (!g_EmulatorRunning && g_RealWiiMotePresent)
|
|
||||||
FlashLights(false);
|
|
||||||
|
|
||||||
// Clean up wiiuse
|
|
||||||
wiiuse_cleanup(g_WiiMotesFromWiiUse, g_NumberOfWiiMotes);
|
|
||||||
|
|
||||||
// Uninitialized
|
|
||||||
g_RealWiiMoteInitialized = false;
|
|
||||||
g_RealWiiMotePresent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "Real InterruptChannel\n");
|
|
||||||
// TODO: Update for multiple Wiimotes
|
|
||||||
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "Real ControlChannel\n");
|
|
||||||
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Read the Wiimote once
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
//INFO_LOG(CONSOLE, "Real Update\n");
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
g_WiiMotes[i]->Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continuously read the Wiimote status. However, the actual sending of data
|
|
||||||
occurs in Update(). If we are not currently using the real Wiimote we allow
|
|
||||||
the separate ReadWiimote() function to run. Wo don't use them at the same
|
|
||||||
time to avoid a potential collision. */
|
|
||||||
THREAD_RETURN ReadWiimote_ThreadFunc(void* arg)
|
|
||||||
{
|
|
||||||
while (!g_Shutdown)
|
|
||||||
{
|
|
||||||
// We need g_ThreadGoing to do a manual WaitForSingleObject() from the configuration window
|
|
||||||
g_ThreadGoing = true;
|
|
||||||
if(g_Config.bUseRealWiimote && !g_RunTemporary)
|
|
||||||
for (int i = 0; i < g_NumberOfWiiMotes; i++) g_WiiMotes[i]->ReadData();
|
|
||||||
else
|
|
||||||
ReadWiimote();
|
|
||||||
g_ThreadGoing = false;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // end of namespace
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright (C) 2003-2008 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_REAL_H
|
|
||||||
#define WIIMOTE_REAL_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "wiiuse.h"
|
|
||||||
|
|
||||||
namespace WiiMoteReal
|
|
||||||
{
|
|
||||||
|
|
||||||
#define MAX_WIIMOTES 1
|
|
||||||
|
|
||||||
int Initialize();
|
|
||||||
void DoState(void* ptr, int mode);
|
|
||||||
void Shutdown(void);
|
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);
|
|
||||||
void Update();
|
|
||||||
|
|
||||||
void SendAcc(u8 _ReportID);
|
|
||||||
void SetDataReportingMode(u8 ReportingMode = 0);
|
|
||||||
void ClearEvents();
|
|
||||||
|
|
||||||
// The alternative Wiimote loop
|
|
||||||
void ReadWiimote();
|
|
||||||
bool IRDataOK(struct wiimote_t* wm);
|
|
||||||
|
|
||||||
extern wiimote_t** g_WiiMotesFromWiiUse;
|
|
||||||
extern bool g_Shutdown;
|
|
||||||
extern bool g_ThreadGoing;
|
|
||||||
extern int g_NumberOfWiiMotes;
|
|
||||||
extern bool g_MotionSensing;
|
|
||||||
extern bool g_IRSensing;
|
|
||||||
extern u64 g_UpdateTime;
|
|
||||||
extern int g_UpdateCounter;
|
|
||||||
extern bool g_RunTemporary;
|
|
||||||
extern int g_RunTemporaryCountdown;
|
|
||||||
extern u8 g_EventBuffer[32];
|
|
||||||
|
|
||||||
}; // WiiMoteReal
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -195,10 +195,12 @@ static int wmDefaultControls[] =
|
||||||
80, // WmP
|
80, // WmP
|
||||||
77, // WmM
|
77, // WmM
|
||||||
72, // WmH
|
72, // WmH
|
||||||
|
#ifdef _WIN32
|
||||||
VK_LEFT, // Regular directional keys
|
VK_LEFT, // Regular directional keys
|
||||||
VK_RIGHT,
|
VK_RIGHT,
|
||||||
VK_UP,
|
VK_UP,
|
||||||
VK_DOWN,
|
VK_DOWN,
|
||||||
|
#endif
|
||||||
83, // WmShake (S)
|
83, // WmShake (S)
|
||||||
51, // WmPitchL (3)
|
51, // WmPitchL (3)
|
||||||
52, // WmPitchR (4)
|
52, // WmPitchR (4)
|
||||||
|
@ -207,11 +209,13 @@ static int nCDefaultControls[] =
|
||||||
{
|
{
|
||||||
90, // NcZ Z
|
90, // NcZ Z
|
||||||
67, // NcC C
|
67, // NcC C
|
||||||
|
#ifdef _WIN32
|
||||||
VK_NUMPAD4, // NcL
|
VK_NUMPAD4, // NcL
|
||||||
VK_NUMPAD6, // NcR
|
VK_NUMPAD6, // NcR
|
||||||
VK_NUMPAD8, // NcU
|
VK_NUMPAD8, // NcU
|
||||||
VK_NUMPAD5, // NcD
|
VK_NUMPAD5, // NcD
|
||||||
68, // NcShake D
|
#endif
|
||||||
|
68, // NcShake D
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ccDefaultControls[] =
|
static int ccDefaultControls[] =
|
||||||
|
@ -227,10 +231,12 @@ static int ccDefaultControls[] =
|
||||||
0x38, // CcZl 8
|
0x38, // CcZl 8
|
||||||
0x39, // CcZr 9
|
0x39, // CcZr 9
|
||||||
0x30, // CcTr 0
|
0x30, // CcTr 0
|
||||||
|
#ifdef _WIN32
|
||||||
VK_NUMPAD4, //CcDl
|
VK_NUMPAD4, //CcDl
|
||||||
VK_NUMPAD8, // CcDu
|
VK_NUMPAD8, // CcDu
|
||||||
VK_NUMPAD6, // CcDr
|
VK_NUMPAD6, // CcDr
|
||||||
VK_NUMPAD5, // CcDd
|
VK_NUMPAD5, // CcDd
|
||||||
|
#endif
|
||||||
0x4a, // CcLl J
|
0x4a, // CcLl J
|
||||||
0x49, // CcLu I
|
0x49, // CcLu I
|
||||||
0x4c, // CcLr L
|
0x4c, // CcLr L
|
||||||
|
|
Loading…
Reference in New Issue