From a3c96ac42c4c2ce4a4cf2f5ca09a5ae9dd4bd303 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Thu, 3 Jun 2010 18:05:08 +0000 Subject: [PATCH] Warp back to 5578. Sorry for the lost changes, please re-apply. Reason: 5579 is a complete disaster. Not only does it change tons of files to switch to a new and non-working (it doesn't parse my ini files, at least) ini parser, it also reshuffles a lot of code and removes a plugin. The latter part is fine, but doing these two major switches in one revision, one of which is broken, is completely unacceptable. I said to merge tiny changes, not massive reworkings. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5589 8ced0084-cf51-0410-be5f-012b33b47a6e --- SConstruct | 19 +- .../AudioCommon/Src/AudioCommonConfig.cpp | 26 +- Source/Core/Common/Common.vcproj | 16 + Source/Core/Common/Src/ChunkFile.cpp | 22 + Source/Core/Common/Src/CommonPaths.h | 1 + Source/Core/Common/Src/IniFile.cpp | 627 +++++++++---- Source/Core/Common/Src/IniFile.h | 135 ++- Source/Core/Common/Src/PluginPAD.cpp | 40 + Source/Core/Common/Src/PluginPAD.h | 47 + Source/Core/Common/Src/SConscript | 4 +- Source/Core/Core/Core.vcproj | 20 - Source/Core/Core/Src/ActionReplay.cpp | 6 +- Source/Core/Core/Src/ConfigManager.cpp | 297 +++---- Source/Core/Core/Src/ConfigManager.h | 1 + Source/Core/Core/Src/Core.cpp | 25 +- Source/Core/Core/Src/CoreParameter.h | 2 + Source/Core/Core/Src/CoreRerecording.cpp | 8 +- Source/Core/Core/Src/HW/GCPad.cpp | 100 --- Source/Core/Core/Src/HW/GCPad.h | 55 -- Source/Core/Core/Src/HW/HW.cpp | 5 +- .../Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp | 14 +- .../Core/Src/HW/SI_DeviceGCController.cpp | 14 +- .../Core/Core/Src/HW/SI_DeviceGCController.h | 43 +- .../IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp | 2 +- Source/Core/Core/Src/LuaInterface.cpp | 9 +- Source/Core/Core/Src/OnFrame.h | 2 +- Source/Core/Core/Src/PatchEngine.cpp | 25 +- Source/Core/Core/Src/PluginManager.cpp | 79 +- Source/Core/Core/Src/PluginManager.h | 5 + Source/Core/Core/Src/SConscript | 2 - Source/Core/Core/Src/State.cpp | 1 + Source/Core/DSPCore/DSPCore.vcproj | 4 + Source/Core/DSPCore/Src/DSPBreakpoints.cpp | 19 + Source/Core/DSPCore/Src/SConscript | 1 + .../Core/DebuggerWX/Src/BreakpointWindow.cpp | 10 +- .../DebuggerWX/Src/CodeWindowFunctions.cpp | 124 ++- Source/Core/DebuggerWX/Src/MemoryWindow.cpp | 24 +- Source/Core/DiscIO/Src/FileMonitor.cpp | 2 +- Source/Core/DolphinWX/DolphinWX.vcproj | 12 +- Source/Core/DolphinWX/Src/BootManager.cpp | 9 +- Source/Core/DolphinWX/Src/ConfigMain.cpp | 19 + Source/Core/DolphinWX/Src/ConfigMain.h | 8 + Source/Core/DolphinWX/Src/Frame.cpp | 15 +- Source/Core/DolphinWX/Src/Frame.h | 2 +- Source/Core/DolphinWX/Src/FrameAui.cpp | 31 +- Source/Core/DolphinWX/Src/FrameTools.cpp | 79 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 13 +- Source/Core/DolphinWX/Src/Globals.h | 2 +- Source/Core/DolphinWX/Src/ISOProperties.cpp | 176 ++-- Source/Core/DolphinWX/Src/LogWindow.cpp | 39 +- Source/Core/DolphinWX/Src/Main.cpp | 21 + Source/Core/DolphinWX/Src/MainNoGUI.cpp | 2 + Source/Core/DolphinWX/Src/MemcardManager.cpp | 57 +- Source/Core/DolphinWX/Src/NetPlay.cpp | 7 +- Source/Core/DolphinWX/Src/NetPlay.h | 2 +- Source/Core/DolphinWX/Src/SConscript | 2 +- Source/Core/InputCommon/InputCommon.vcproj | 86 +- Source/Core/InputCommon/Src/Configuration.cpp | 7 +- .../DirectInput/DirectInputKeyboardMouse.cpp | 7 +- .../DirectInput/DirectInputKeyboardMouse.h | 4 +- .../Src/ControllerInterface/XInput/XInput.cpp | 2 - .../Core/InputCommon/Src/DirectInputBase.cpp | 229 +++++ Source/Core/InputCommon/Src/DirectInputBase.h | 53 ++ Source/Core/InputCommon/Src/Event.hpp | 264 ++++++ Source/Core/InputCommon/Src/EventHandler.cpp | 318 +++++++ Source/Core/InputCommon/Src/EventHandler.h | 64 ++ Source/Core/InputCommon/Src/InputCommon.cpp | 16 + Source/Core/InputCommon/Src/InputCommon.h | 6 + Source/Core/InputCommon/Src/SConscript | 9 +- .../InputCommon}/Src/WXInputBase.cpp | 254 +++--- .../InputCommon}/Src/WXInputBase.h | 56 +- Source/Core/InputCommon/Src/X11InputBase.h | 2 +- Source/Core/VideoCommon/Src/VideoConfig.cpp | 238 ++--- Source/Dolphin.sln | 53 +- Source/Dolphin.xcodeproj/project.pbxproj | 12 + Source/PluginSpecs/pluginspecs_pad.h | 88 ++ .../InputPluginCommon.vcproj} | 34 +- .../InputPluginCommon/Src/Config.cpp} | 114 +-- .../InputPluginCommon/Src/Config.h} | 69 +- .../Src/ConfigDiag.cpp | 23 +- .../Src/ConfigDiag.h | 2 +- .../Src/ConfigDiagBitmaps.cpp | 0 .../InputPluginCommon}/Src/ControllerEmu.cpp | 682 +++++++-------- .../InputPluginCommon}/Src/ControllerEmu.h | 790 ++++++++--------- .../Plugins/InputPluginCommon/Src/IniFile.cpp | 156 ++++ .../Plugins/InputPluginCommon/Src/IniFile.h | 61 ++ .../Plugins/InputPluginCommon/Src/SConscript | 20 + Source/Plugins/InputUICommon/Src/SConscript | 13 - Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp | 4 +- .../Plugins/Plugin_GCPad/Plugin_GCPad.vcproj | 559 ++++++++++++ Source/Plugins/Plugin_GCPad/Src/Config.cpp | 261 ++++++ Source/Plugins/Plugin_GCPad/Src/Config.h | 49 ++ Source/Plugins/Plugin_GCPad/Src/ConfigBox.cpp | 823 ++++++++++++++++++ Source/Plugins/Plugin_GCPad/Src/ConfigBox.h | 243 ++++++ .../Plugins/Plugin_GCPad/Src/ConfigJoypad.cpp | 329 +++++++ Source/Plugins/Plugin_GCPad/Src/GCPad.cpp | 651 ++++++++++++++ Source/Plugins/Plugin_GCPad/Src/GCPad.h | 165 ++++ .../Plugins/Plugin_GCPad/Src/ReRecording.cpp | 181 ++++ Source/Plugins/Plugin_GCPad/Src/Rumble.cpp | 407 +++++++++ Source/Plugins/Plugin_GCPad/Src/SConscript | 31 + .../Plugin_GCPadNew/Plugin_GCPadNew.vcproj | 532 +++++++++++ .../Plugin_GCPadNew/Src}/GCPadEmu.cpp | 216 ++--- .../Plugin_GCPadNew/Src}/GCPadEmu.h | 63 +- .../Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp | 349 ++++++++ Source/Plugins/Plugin_GCPadNew/Src/SConscript | 21 + .../Plugin_VideoDX9/Src/Debugger/Debugger.cpp | 24 +- .../Plugin_VideoOGL/Src/Debugger/Debugger.cpp | 24 +- Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp | 2 +- .../Plugin_VideoSoftware/Src/VideoConfig.cpp | 10 +- Source/Plugins/Plugin_Wiimote/Src/Config.cpp | 245 +++--- .../Plugin_Wiimote/Src/ConfigRecording.cpp | 54 +- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 24 +- .../Plugin_WiimoteNew.vcproj | 14 +- .../Plugins/Plugin_WiimoteNew/Src/SConscript | 2 +- .../Src/WiimoteEmu/EmuSubroutines.cpp | 2 +- .../Src/WiimoteEmu/WiimoteEmu.cpp | 44 +- .../Plugin_WiimoteNew/Src/WiimoteNew.cpp | 4 +- Source/UnitTests/UnitTests.cpp | 1 + 118 files changed, 8868 insertions(+), 2530 deletions(-) create mode 100644 Source/Core/Common/Src/ChunkFile.cpp create mode 100644 Source/Core/Common/Src/PluginPAD.cpp create mode 100644 Source/Core/Common/Src/PluginPAD.h delete mode 100644 Source/Core/Core/Src/HW/GCPad.cpp delete mode 100644 Source/Core/Core/Src/HW/GCPad.h create mode 100644 Source/Core/DSPCore/Src/DSPBreakpoints.cpp create mode 100644 Source/Core/InputCommon/Src/DirectInputBase.cpp create mode 100644 Source/Core/InputCommon/Src/DirectInputBase.h create mode 100755 Source/Core/InputCommon/Src/Event.hpp create mode 100644 Source/Core/InputCommon/Src/EventHandler.cpp create mode 100644 Source/Core/InputCommon/Src/EventHandler.h create mode 100644 Source/Core/InputCommon/Src/InputCommon.cpp rename Source/{Plugins/InputUICommon => Core/InputCommon}/Src/WXInputBase.cpp (97%) rename Source/{Plugins/InputUICommon => Core/InputCommon}/Src/WXInputBase.h (96%) create mode 100644 Source/PluginSpecs/pluginspecs_pad.h rename Source/Plugins/{InputUICommon/InputUICommon.vcproj => InputPluginCommon/InputPluginCommon.vcproj} (96%) rename Source/{Core/InputCommon/Src/InputConfig.cpp => Plugins/InputPluginCommon/Src/Config.cpp} (94%) rename Source/{Core/InputCommon/Src/InputConfig.h => Plugins/InputPluginCommon/Src/Config.h} (86%) rename Source/Plugins/{InputUICommon => InputPluginCommon}/Src/ConfigDiag.cpp (98%) rename Source/Plugins/{InputUICommon => InputPluginCommon}/Src/ConfigDiag.h (99%) rename Source/Plugins/{InputUICommon => InputPluginCommon}/Src/ConfigDiagBitmaps.cpp (100%) rename Source/{Core/InputCommon => Plugins/InputPluginCommon}/Src/ControllerEmu.cpp (88%) rename Source/{Core/InputCommon => Plugins/InputPluginCommon}/Src/ControllerEmu.h (92%) create mode 100644 Source/Plugins/InputPluginCommon/Src/IniFile.cpp create mode 100644 Source/Plugins/InputPluginCommon/Src/IniFile.h create mode 100644 Source/Plugins/InputPluginCommon/Src/SConscript delete mode 100644 Source/Plugins/InputUICommon/Src/SConscript create mode 100644 Source/Plugins/Plugin_GCPad/Plugin_GCPad.vcproj create mode 100644 Source/Plugins/Plugin_GCPad/Src/Config.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/Config.h create mode 100644 Source/Plugins/Plugin_GCPad/Src/ConfigBox.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/ConfigBox.h create mode 100644 Source/Plugins/Plugin_GCPad/Src/ConfigJoypad.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/GCPad.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/GCPad.h create mode 100644 Source/Plugins/Plugin_GCPad/Src/ReRecording.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/Rumble.cpp create mode 100644 Source/Plugins/Plugin_GCPad/Src/SConscript create mode 100644 Source/Plugins/Plugin_GCPadNew/Plugin_GCPadNew.vcproj rename Source/{Core/Core/Src/HW => Plugins/Plugin_GCPadNew/Src}/GCPadEmu.cpp (88%) rename Source/{Core/Core/Src/HW => Plugins/Plugin_GCPadNew/Src}/GCPadEmu.h (81%) create mode 100644 Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp create mode 100644 Source/Plugins/Plugin_GCPadNew/Src/SConscript diff --git a/SConstruct b/SConstruct index 1438ff3521..960b06805a 100644 --- a/SConstruct +++ b/SConstruct @@ -26,6 +26,10 @@ warnings = [ 'packed', 'no-conversion', ] +# XXX check for the availability of these (in GCC 4.3 or newer) +if sys.platform != 'darwin': + warnings.append('no-array-bounds') + warnings.append('no-unused-result') compileFlags = [ '-fno-exceptions', @@ -53,10 +57,10 @@ include_paths = [ basedir + 'Externals/WiiUseSrc/Src', basedir + 'Source/Core/VideoCommon/Src', basedir + 'Source/Core/InputCommon/Src', + basedir + 'Source/Plugins/InputPluginCommon/Src', basedir + 'Source/Core/AudioCommon/Src', basedir + 'Source/Core/DebuggerUICommon/Src', basedir + 'Source/Core/DSPCore/Src', - basedir + 'Source/Plugins/InputUICommon/Src', ] dirs = [ @@ -76,11 +80,13 @@ dirs = [ 'Source/Plugins/Plugin_VideoSoftware/Src', 'Source/Plugins/Plugin_DSP_HLE/Src', 'Source/Plugins/Plugin_DSP_LLE/Src', + 'Source/Plugins/Plugin_GCPad/Src', + 'Source/Plugins/Plugin_GCPadNew/Src', 'Source/Plugins/Plugin_Wiimote/Src', - 'Source/Plugins/InputUICommon/Src', 'Source/Core/DolphinWX/Src', 'Source/Core/DebuggerWX/Src', 'Source/UnitTests/', + 'Source/Plugins/InputPluginCommon/Src/', 'Source/Plugins/Plugin_WiimoteNew/Src/', ] @@ -159,8 +165,7 @@ else: variables = vars, ENV = { 'PATH' : os.environ['PATH'], - 'HOME' : os.environ['HOME'], - 'PKG_CONFIG_PATH' : os.environ.get('PKG_CONFIG_PATH') + 'HOME' : os.environ['HOME'] }, BUILDERS = builders, DESCRIPTION = description, @@ -204,11 +209,11 @@ elif (flavour == 'prof'): elif (flavour == 'release'): compileFlags.append('-O3') compileFlags.append('-fomit-frame-pointer'); + warnings.append('error') # more warnings if env['lint']: - warnings.append('error') - #warnings.append('unreachable-code') - #warnings.append('float-equal') + warnings.append('unreachable-code') + warnings.append('float-equal') # add the warnings to the compile flags compileFlags += [ ('-W' + warning) for warning in warnings ] diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp index 75e4c56c63..f62e4b3863 100644 --- a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp +++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp @@ -20,30 +20,28 @@ AudioCommonConfig ac_Config; // Load from given file void AudioCommonConfig::Load(IniFile &file) { - Section& config = file["Config"]; - config.Get("EnableDTKMusic", &m_EnableDTKMusic, true); - config.Get("EnableThrottle", &m_EnableThrottle, true); - config.Get("EnableJIT", &m_EnableJIT, true); - config.Get("Volume", &m_Volume, 75); + file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true); + file.Get("Config", "EnableThrottle", &m_EnableThrottle, true); + file.Get("Config", "EnableJIT", &m_EnableJIT, true); + file.Get("Config", "Volume", &m_Volume, 75); #ifdef _WIN32 - config.Get("Backend", &sBackend, BACKEND_DIRECTSOUND); + file.Get("Config", "Backend", &sBackend, BACKEND_DIRECTSOUND); #elif defined(__APPLE__) std::string temp; - config.Get("Backend", &temp, BACKEND_COREAUDIO); + file.Get("Config", "Backend", &temp, BACKEND_COREAUDIO); strncpy(sBackend, temp.c_str(), 128); #else // linux - config.Get("Backend", &sBackend, BACKEND_ALSA); + file.Get("Config", "Backend", &sBackend, BACKEND_ALSA); #endif } // Set the values for the file void AudioCommonConfig::Set(IniFile &file) { - Section& config = file["Config"]; - config.Set("EnableDTKMusic", m_EnableDTKMusic); - config.Set("EnableThrottle", m_EnableThrottle); - config.Set("EnableJIT", m_EnableJIT); - config.Set("Backend", sBackend); - config.Set("Volume", m_Volume); + file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic); + file.Set("Config", "EnableThrottle", m_EnableThrottle); + file.Set("Config", "EnableJIT", m_EnableJIT); + file.Set("Config", "Backend", sBackend); + file.Set("Config", "Volume", m_Volume); } // Update according to the values (stream/mixer) diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj index 62a31a6219..d10537c069 100644 --- a/Source/Core/Common/Common.vcproj +++ b/Source/Core/Common/Common.vcproj @@ -471,6 +471,14 @@ RelativePath=".\Src\PluginDSP.h" > + + + + @@ -506,6 +514,10 @@ RelativePath="..\..\PluginSpecs\pluginspecs_dsp.h" > + + @@ -608,6 +620,10 @@ RelativePath=".\Src\CDUtils.h" > + + diff --git a/Source/Core/Common/Src/ChunkFile.cpp b/Source/Core/Common/Src/ChunkFile.cpp new file mode 100644 index 0000000000..dc9b9b66a5 --- /dev/null +++ b/Source/Core/Common/Src/ChunkFile.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "ChunkFile.h" + +#include + diff --git a/Source/Core/Common/Src/CommonPaths.h b/Source/Core/Common/Src/CommonPaths.h index 5adff7038e..1a3b5168d1 100644 --- a/Source/Core/Common/Src/CommonPaths.h +++ b/Source/Core/Common/Src/CommonPaths.h @@ -132,6 +132,7 @@ // Plugin files #define DEFAULT_GFX_PLUGIN PLUGIN_PREFIX "Plugin_VideoOGL" PLUGIN_SUFFIX #define DEFAULT_DSP_PLUGIN PLUGIN_PREFIX "Plugin_DSP_HLE" PLUGIN_SUFFIX +#define DEFAULT_PAD_PLUGIN PLUGIN_PREFIX "Plugin_GCPadNew" PLUGIN_SUFFIX #define DEFAULT_WIIMOTE_PLUGIN PLUGIN_PREFIX "Plugin_Wiimote" PLUGIN_SUFFIX // Sys files diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp index e604f70ab7..04f08168a9 100644 --- a/Source/Core/Common/Src/IniFile.cpp +++ b/Source/Core/Common/Src/IniFile.cpp @@ -16,239 +16,510 @@ // http://code.google.com/p/dolphin-emu/ // see IniFile.h +#include +#include + +#include +#include +#include +#include +#include + +#include "StringUtil.h" #include "IniFile.h" -template -void StripChars(std::string& str, const S space) -{ - const size_t start = str.find_first_not_of(space); +IniFile::IniFile() +{} - if (str.npos == start) - str.clear(); - else - str = str.substr(start, str.find_last_not_of(space) - start + 1); +IniFile::~IniFile() +{} + +Section::Section() + : lines(), name(""), comment("") {} + + +Section::Section(const std::string& _name) + : lines(), name(_name), comment("") {} + + +Section::Section(const Section& other) +{ + name = other.name; + comment = other.comment; + lines = other.lines; } -bool Section::Get(const std::string& key, std::string* const val, const std::string& def) const +const Section* IniFile::GetSection(const char* sectionName) const { - const const_iterator f = find(key); - if (f != end()) + for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) + if (!strcasecmp(iter->name.c_str(), sectionName)) + return (&(*iter)); + return 0; +} + +Section* IniFile::GetSection(const char* sectionName) +{ + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + if (!strcasecmp(iter->name.c_str(), sectionName)) + return (&(*iter)); + return 0; +} + +Section* IniFile::GetOrCreateSection(const char* sectionName) +{ + Section* section = GetSection(sectionName); + + if (!section) { - *val = f->second; - return true; + sections.push_back(Section(sectionName)); + section = §ions[sections.size() - 1]; } - if (false == def.empty()) - *val = def; + + return(section); +} + + +bool IniFile::DeleteSection(const char* sectionName) +{ + Section* s = GetSection(sectionName); + + if (!s) + { + return false; + } + + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + if (&(*iter) == s) + { + sections.erase(iter); + return true; + } + } + return false; } -void Section::Set(const std::string& key, const std::string& val, const std::string& def) +void IniFile::ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) const { - if (val != def) - operator[](key) = val; - else - { - iterator f = find(key); - if (f != end()) - erase(f); - } -} + // + int FirstEquals = (int)line.find("=", 0); + int FirstCommentChar = -1; + // Comments + //if (FirstCommentChar < 0) {FirstCommentChar = (int)line.find(";", FirstEquals > 0 ? FirstEquals : 0);} + if (FirstCommentChar < 0) {FirstCommentChar = (int)line.find("#", FirstEquals > 0 ? FirstEquals : 0);} + if (FirstCommentChar < 0) {FirstCommentChar = (int)line.find("//", FirstEquals > 0 ? FirstEquals : 0);} -bool IniFile::Save(const std::string& filename) const -{ - return Save(filename.c_str()); -} - -bool IniFile::Save(const char filename[]) const -{ - std::ofstream file; - file.open(filename); - if (file.is_open()) + // Allow preservation of spacing before comment + if (FirstCommentChar > 0) { - Save(file); - file.close(); - return true; - } - else - return false; -} - -void IniFile::Save(std::ostream& file) const -{ - const_iterator - si = begin(), - se = end(); - for ( ; si != se; ++si ) - { - // skip a line at new sections - file << "\n[" << si->first << "]\n"; - si->second.Save(file); - } -} - -void Section::Save(std::ostream& file) const -{ - if (m_use_lines) // this is used when GetLines or SetLines has been called - { - std::vector::const_iterator - i = m_lines.begin(), - e = m_lines.end(); - for ( ; i!=e; ++i) - file << *i << '\n'; - } - else - { - Section::const_iterator - vi = begin(), - ve = end(); - for ( ; vi!=ve; ++vi) + while (line[FirstCommentChar - 1] == ' ' || line[FirstCommentChar - 1] == 9) // 9 == tab { - file << vi->first << " = "; - // if value has quotes or whitespace, surround it with quotes - if (vi->second.find_first_of("\"\t ") != std::string::npos) - file << '"' << vi->second << '"'; - else - file << vi->second; - file << '\n'; + FirstCommentChar--; } } -} -bool IniFile::Load(const std::string& filename) -{ - return Load(filename.c_str()); -} - -bool IniFile::Load(const char filename[]) -{ - std::ifstream file; - file.open(filename); - if (file.is_open()) + if ((FirstEquals >= 0) && ((FirstCommentChar < 0) || (FirstEquals < FirstCommentChar))) { - Load(file); - file.close(); - return true; + // Yes, a valid line! + *keyOut = StripSpaces(line.substr(0, FirstEquals)); + if (commentOut) *commentOut = FirstCommentChar > 0 ? line.substr(FirstCommentChar) : std::string(""); + if (valueOut) *valueOut = StripQuotes(StripSpaces(line.substr(FirstEquals + 1, FirstCommentChar - FirstEquals - 1))); } - else - return false; } -void IniFile::Load(std::istream& file) +std::string* IniFile::GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut) { - std::vector lines; - - Section sectmp; - Section* section = §mp; - - std::string line; - while (std::getline(file, line)) // read a line + for (std::vector::iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) { - if (line.size()) + std::string& line = *iter; + std::string lineKey; + ParseLine(line, &lineKey, valueOut, commentOut); + + if (!strcasecmp(lineKey.c_str(), key)) { - switch (line[0]) + return &line; + } + } + + return 0; +} + +bool IniFile::Exists(const char* const sectionName, const char* key) const +{ + + const Section* const section = GetSection(sectionName); + if (!section) + return false; + + for (std::vector::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) + { + std::string lineKey; + ParseLine(*iter, &lineKey, NULL, NULL); + + if (!strcasecmp(lineKey.c_str(), key)) + { + return true; + } + } + + return false; +} + +void IniFile::SetLines(const char* sectionName, const std::vector &lines) +{ + Section* section = GetOrCreateSection(sectionName); + section->lines.clear(); + + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + section->lines.push_back(*iter); + } +} + + +bool IniFile::DeleteKey(const char* sectionName, const char* key) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + return false; + } + + std::string* line = GetLine(section, key, 0, 0); + + for (std::vector::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + if (line == &(*liter)) + { + section->lines.erase(liter); + return true; + } + } + + return false; //shouldn't happen +} + +// Return a list of all keys in a section +bool IniFile::GetKeys(const char* sectionName, std::vector& keys) const +{ + const Section* section = GetSection(sectionName); + + if (!section) + { + return false; + } + + keys.clear(); + + for (std::vector::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + std::string key; + ParseLine(*liter, &key, 0, 0); + keys.push_back(key); + } + + return true; +} + +// Return a list of all lines in a section +bool IniFile::GetLines(const char* sectionName, std::vector& lines) const +{ + const Section* section = GetSection(sectionName); + if (!section) + return false; + + lines.clear(); + for (std::vector::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) + { + std::string line = StripSpaces(*iter); + int commentPos = (int)line.find('#'); + if (commentPos == 0) + { + continue; + } + + if (commentPos != (int)std::string::npos) + { + line = StripSpaces(line.substr(0, commentPos)); + } + + lines.push_back(line); + } + + return true; +} + + +void IniFile::SortSections() +{ + std::sort(sections.begin(), sections.end()); +} + +bool IniFile::Load(const char* filename) +{ + // Maximum number of letters in a line + static const int MAX_BYTES = 1024*32; + + sections.clear(); + sections.push_back(Section("")); + // first section consists of the comments before the first real section + + // Open file + std::ifstream in; + in.open(filename, std::ios::in); + + if (in.fail()) return false; + + while (!in.eof()) + { + char templine[MAX_BYTES]; + in.getline(templine, MAX_BYTES); + std::string line = templine; + +#ifndef _WIN32 + // Check for CRLF eol and convert it to LF + if (!line.empty() && line.at(line.size()-1) == '\r') + { + line.erase(line.size()-1); + } +#endif + + if (in.eof()) break; + + if (line.size() > 0) + { + if (line[0] == '[') { - // section - case '[' : - section->m_lines = lines; - // kinda odd trimming - StripChars(line, "][\t\r "); - section = &(*this)[line]; - lines.clear(); - break; + size_t endpos = line.find("]"); - // key/value - default : + if (endpos != std::string::npos) { - std::istringstream ss(line); + // New section! + std::string sub = line.substr(1, endpos - 1); + sections.push_back(Section(sub)); - std::string key; std::getline(ss, key, '='); - std::string val; std::getline(ss, val); - - StripChars(val, "\t\r "); - // handle quote surrounded values - if (val.length() > 1) - if ('"' == val[0]) - val.assign(val.begin()+1, val.end()-1); - - StripChars(key, "\t\r "); - (*section)[key] = val; + if (endpos + 1 < line.size()) + { + sections[sections.size() - 1].comment = line.substr(endpos + 1); + } } - //break; // no break - - // comment - case '#' : - case ';' : - lines.push_back(line); - break; + } + else + { + sections[sections.size() - 1].lines.push_back(line); } } } - //Clean(); + + in.close(); + return true; } -// -// IniFile :: Clean -// -// remove empty key/values and sections -// after trying to access ini sections/values with the [] operator, they are automatically allocated -// this deletes the empty stuff -// -void IniFile::Clean() +bool IniFile::Save(const char* filename) { - iterator - i = begin(), - e = end(); - for ( ; i != e; ) + std::ofstream out; + out.open(filename, std::ios::out); + + if (out.fail()) { - Section::iterator - si = i->second.begin(), - se = i->second.end(); - for ( ; si != se; ) - { - if (si->second.empty()) - i->second.erase( si++ ); - else - ++si; + return false; + } + + for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + const Section& section = *iter; + + if (section.name != "") + { + out << "[" << section.name << "]" << section.comment << std::endl; } - if (i->second.empty() && i->second.m_lines.empty()) - erase( i++ ); - else - ++i; + + for (std::vector::const_iterator liter = section.lines.begin(); liter != section.lines.end(); ++liter) + { + std::string s = *liter; + out << s << std::endl; + } + } + + out.close(); + return true; +} + +void IniFile::Set(const char* sectionName, const char* key, const char* newValue) +{ + Section* section = GetOrCreateSection(sectionName); + std::string value, comment; + std::string* line = GetLine(section, key, &value, &comment); + + if (line) + { + // Change the value - keep the key and comment + *line = StripSpaces(key) + " = " + newValue + comment; + } + else + { + // The key did not already exist in this section - let's add it. + section->lines.push_back(std::string(key) + " = " + newValue); } } -bool IniFile::Exists(const std::string& section) const +void IniFile::Set(const char* sectionName, const char* key, const std::vector& newValues) { - return find(section) != end(); + std::string temp; + + // Join the strings with , + std::vector::const_iterator it; + for (it = newValues.begin(); it != newValues.end(); ++it) { + + temp = (*it) + ","; + } + + // remove last , + temp.resize(temp.length() - 1); + + Set(sectionName, key, temp.c_str()); } -void IniFile::Delete(const std::string& section) +void IniFile::Set(const char* sectionName, const char* key, u32 newValue) { - const iterator f = find(section); - if (end() != f) - erase(f); + Set(sectionName, key, StringFromFormat("0x%08x", newValue).c_str()); } -bool Section::Exists(const std::string& key) const + +void IniFile::Set(const char* sectionName, const char* key, int newValue) { - return find(key) != end(); + Set(sectionName, key, StringFromInt(newValue).c_str()); } -void Section::Delete(const std::string& key) + +void IniFile::Set(const char* sectionName, const char* key, bool newValue) { - const iterator f = find(key); - if (end() != f) - erase(f); + Set(sectionName, key, StringFromBool(newValue).c_str()); } -void Section::SetLines(const std::vector& lines) +bool IniFile::Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue) { - m_lines = lines; - m_use_lines = true; + Section* section = GetSection(sectionName); + + if (!section) + { + if (defaultValue) + { + *value = defaultValue; + } + return false; + } + + std::string* line = GetLine(section, key, value, 0); + + if (!line) + { + if (defaultValue) + { + *value = defaultValue; + } + return false; + } + + return true; } -void Section::GetLines(std::vector& lines) + +bool IniFile::Get(const char* sectionName, const char* key, std::vector& values) { - lines = m_lines; - m_use_lines = true; + + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (! retval || temp.empty()) { + return false; + } + + + // ignore starting , if any + size_t subStart = temp.find_first_not_of(","); + size_t subEnd; + + // split by , + while (subStart != std::string::npos) { + + // Find next , + subEnd = temp.find_first_of(",", subStart); + if (subStart != subEnd) + // take from first char until next , + values.push_back(StripSpaces(temp.substr(subStart, subEnd - subStart))); + + // Find the next non , char + subStart = temp.find_first_not_of(",", subEnd); + } + + return true; } + +bool IniFile::Get(const char* sectionName, const char* key, int* value, int defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseInt(temp.c_str(), value)) + { + return true; + } + + *value = defaultValue; + return false; +} + + +bool IniFile::Get(const char* sectionName, const char* key, u32* value, u32 defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseUInt(temp.c_str(), value)) + { + return true; + } + + *value = defaultValue; + return false; +} + + +bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseBool(temp.c_str(), value)) + { + return true; + } + + *value = defaultValue; + return false; +} + + +// TODO: Keep this code below? +/* + int main() + { + IniFile ini; + ini.Load("my.ini"); + ini.Set("Hej", "A", "amaskdfl"); + ini.Set("Mossa", "A", "amaskdfl"); + ini.Set("Aissa", "A", "amaskdfl"); + //ini.Read("my.ini"); + std::string x; + ini.Get("Hej", "B", &x, "boo"); + ini.DeleteKey("Mossa", "A"); + ini.DeleteSection("Mossa"); + ini.SortSections(); + ini.Save("my.ini"); + //UpdateVars(ini); + return 0; + } + */ diff --git a/Source/Core/Common/Src/IniFile.h b/Source/Core/Common/Src/IniFile.h index 19a5bb78a6..599939731b 100644 --- a/Source/Core/Common/Src/IniFile.h +++ b/Source/Core/Common/Src/IniFile.h @@ -18,105 +18,74 @@ #ifndef _INIFILE_H_ #define _INIFILE_H_ -#include "CommonTypes.h" - -#include -#include #include -#include +#include -// some things that include IniFile.h rely on this being here #include "StringUtil.h" -class IniFile; - -class Section : public std::map +class Section { - friend class IniFile; - public: - Section() : m_use_lines(false) {} + Section(); + Section(const std::string& _name); + Section(const Section& other); + std::vectorlines; + std::string name; + std::string comment; - bool Exists(const std::string& key) const; - void Delete(const std::string& key); - - void SetLines(const std::vector& lines); - void GetLines(std::vector& lines); - - bool Get(const std::string& key, std::string* const val, const std::string& def = "") const; - void Set(const std::string& key, const std::string& val, const std::string& def = ""); - - template - void Set(const std::string& key, const V val) + bool operator<(const Section& other) const { - std::ostringstream ss; - ss << val; - operator[](key) = ss.str(); + return(name < other.name); } - - // if val doesn't match def, set the key's value to val - // otherwise delete that key - // - // this removed a lot of redundant code in the game-properties stuff - template - void Set(const std::string& key, const V val, const D def) - { - if (val != def) - Set(key, val); - else - { - iterator f = find(key); - if (f != end()) - erase(f); - } - } - - template - bool Get(const std::string& key, V* const val) const - { - const const_iterator f = find(key); - if (f != end()) - { - std::istringstream ss(f->second); - ss >> *val; - return true; - } - return false; - } - - template - bool Get(const std::string& key, V* const val, const D def) const - { - if (Get(key, val)) - return true; - *val = def; - return false; - } - -protected: - void Save(std::ostream& file) const; - - std::vector m_lines; - -private: - bool m_use_lines; }; -class IniFile : public std::map +class IniFile { public: - void Clean(); - bool Exists(const std::string& section) const; - void Delete(const std::string& section); + IniFile(); + ~IniFile(); - bool Save(const char filename[]) const; - bool Load(const char filename[]); + bool Load(const char* filename); + bool Save(const char* filename); - bool Save(const std::string& filename) const; - bool Load(const std::string& filename); + void Set(const char* sectionName, const char* key, const char* newValue); + void Set(const char* sectionName, const char* key, int newValue); + void Set(const char* sectionName, const char* key, u32 newValue); + void Set(const char* sectionName, const char* key, bool newValue); + void Set(const char* sectionName, const char* key, const std::string& newValue) {Set(sectionName, key, newValue.c_str());} + void Set(const char* sectionName, const char* key, const std::vector& newValues); - void Save(std::ostream& file) const; - void Load(std::istream& file); + void SetLines(const char* sectionName, const std::vector &lines); + + // Returns true if exists key in section + bool Exists(const char* sectionName, const char* key) const; + + // getter should be const + bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = ""); + bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0); + bool Get(const char* sectionName, const char* key, u32* value, u32 defaultValue = 0); + bool Get(const char* sectionName, const char* key, bool* value, bool defaultValue = false); + bool Get(const char* sectionName, const char* key, std::vector& values); + + bool GetKeys(const char* sectionName, std::vector& keys) const; + bool GetLines(const char* sectionName, std::vector& lines) const; + + bool DeleteKey(const char* sectionName, const char* key); + bool DeleteSection(const char* sectionName); + + void SortSections(); + + void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) const; + std::string* GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut); + +private: + std::vector
sections; + + const Section* GetSection(const char* section) const; + Section* GetSection(const char* section); + Section* GetOrCreateSection(const char* section); + std::string* GetLine(const char* section, const char* key); + void CreateSection(const char* section); }; #endif // _INIFILE_H_ diff --git a/Source/Core/Common/Src/PluginPAD.cpp b/Source/Core/Common/Src/PluginPAD.cpp new file mode 100644 index 0000000000..2fbc6d1a0f --- /dev/null +++ b/Source/Core/Common/Src/PluginPAD.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "PluginPAD.h" + +namespace Common +{ + +PluginPAD::PluginPAD(const char *_Filename) : CPlugin(_Filename), validPAD(false) +{ + PAD_GetStatus = reinterpret_cast + (LoadSymbol("PAD_GetStatus")); + PAD_Input = reinterpret_cast + (LoadSymbol("PAD_Input")); + PAD_Rumble = reinterpret_cast + (LoadSymbol("PAD_Rumble")); + + if ((PAD_GetStatus != 0) && + (PAD_Input != 0) && + (PAD_Rumble != 0)) + validPAD = true; +} + +PluginPAD::~PluginPAD() {} + +} // Namespace diff --git a/Source/Core/Common/Src/PluginPAD.h b/Source/Core/Common/Src/PluginPAD.h new file mode 100644 index 0000000000..07417ec807 --- /dev/null +++ b/Source/Core/Common/Src/PluginPAD.h @@ -0,0 +1,47 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _PLUGINPAD_H_ +#define _PLUGINPAD_H_ + +#include "pluginspecs_pad.h" +#include "Plugin.h" + +namespace Common { + +typedef void (__cdecl* TPAD_GetStatus)(u8, SPADStatus*); +typedef void (__cdecl* TPAD_Input)(u16, u8); +typedef void (__cdecl* TPAD_Rumble)(u8, unsigned int, unsigned int); + +class PluginPAD : public CPlugin { +public: + PluginPAD(const char *_Filename); + virtual ~PluginPAD(); + virtual bool IsValid() {return validPAD;}; + + TPAD_GetStatus PAD_GetStatus; + TPAD_Input PAD_Input; + TPAD_Rumble PAD_Rumble; + +private: + bool validPAD; + +}; + +} // namespace + +#endif // _PLUGINPAD_H_ diff --git a/Source/Core/Common/Src/SConscript b/Source/Core/Common/Src/SConscript index ae9f29bc94..8c3aba54c0 100644 --- a/Source/Core/Common/Src/SConscript +++ b/Source/Core/Common/Src/SConscript @@ -7,10 +7,12 @@ files = [ "ABI.cpp", "BreakPoints.cpp", "CDUtils.cpp", + "ChunkFile.cpp", "ColorUtil.cpp", "ConsoleListener.cpp", "CPUDetect.cpp", "DynamicLibrary.cpp", + "ExtendedTrace.cpp", "FileSearch.cpp", "FileUtil.cpp", "Hash.cpp", @@ -26,6 +28,7 @@ files = [ "PluginDSP.cpp", "PluginWiimote.cpp", "PluginVideo.cpp", + "PluginPAD.cpp", "SDCardUtil.cpp", "StringUtil.cpp", "SymbolDB.cpp", @@ -43,7 +46,6 @@ files = [ ] if sys.platform == 'win32': - files += [ "ExtendedTrace.cpp" ] files += [ "stdafx.cpp" ] env_common = env.Clone() diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index de22f9c0ab..4c890cf6a4 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -773,26 +773,6 @@ > - - - - - - - - - - lines; std::vector encryptedLines; ARCode currentCode; arCodes.clear(); - std::vector lines; - ini["ActionReplay"].GetLines(lines); + if (!ini.GetLines("ActionReplay", lines)) + return; // no codes found. + for (std::vector::const_iterator it = lines.begin(); it != lines.end(); ++it) { std::string line = *it; diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 5c6bff0137..8f88b00545 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -73,108 +73,103 @@ void SConfig::SaveSettings() ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); // load first to not kill unknown stuff // General - Section& general = ini["General"]; - general.Set("LastFilename", m_LastFilename); + ini.Set("General", "LastFilename", m_LastFilename); // ISO folders - general.Set("GCMPathes", (int)m_ISOFolder.size()); + ini.Set("General", "GCMPathes", (int)m_ISOFolder.size()); for (size_t i = 0; i < m_ISOFolder.size(); i++) { TCHAR tmp[16]; sprintf(tmp, "GCMPath%i", (int)i); - general.Set(tmp, m_ISOFolder[i]); + ini.Set("General", tmp, m_ISOFolder[i]); } - general.Set("RecersiveGCMPaths", m_RecursiveISOFolder); + ini.Set("General", "RecersiveGCMPaths", m_RecursiveISOFolder); - // Interface - Section& iface = ini["Interface"]; - iface.Set("ConfirmStop", m_LocalCoreStartupParameter.bConfirmStop); - iface.Set("UsePanicHandlers", m_LocalCoreStartupParameter.bUsePanicHandlers); - iface.Set("HideCursor", m_LocalCoreStartupParameter.bHideCursor); - iface.Set("AutoHideCursor", m_LocalCoreStartupParameter.bAutoHideCursor); - iface.Set("Theme", m_LocalCoreStartupParameter.iTheme); - iface.Set("MainWindowPosX", m_LocalCoreStartupParameter.iPosX); - iface.Set("MainWindowPosY", m_LocalCoreStartupParameter.iPosY); - iface.Set("MainWindowWidth", m_LocalCoreStartupParameter.iWidth); - iface.Set("MainWindowHeight", m_LocalCoreStartupParameter.iHeight); - iface.Set("Language", m_InterfaceLanguage); - iface.Set("ShowToolbar", m_InterfaceToolbar); - iface.Set("ShowStatusbar", m_InterfaceStatusbar); - iface.Set("ShowLogWindow", m_InterfaceLogWindow); - iface.Set("ShowConsole", m_InterfaceConsole); + // Interface + ini.Set("Interface", "ConfirmStop", m_LocalCoreStartupParameter.bConfirmStop); + ini.Set("Interface", "UsePanicHandlers", m_LocalCoreStartupParameter.bUsePanicHandlers); + ini.Set("Interface", "HideCursor", m_LocalCoreStartupParameter.bHideCursor); + ini.Set("Interface", "AutoHideCursor", m_LocalCoreStartupParameter.bAutoHideCursor); + ini.Set("Interface", "Theme", m_LocalCoreStartupParameter.iTheme); + ini.Set("Interface", "MainWindowPosX", m_LocalCoreStartupParameter.iPosX); + ini.Set("Interface", "MainWindowPosY", m_LocalCoreStartupParameter.iPosY); + ini.Set("Interface", "MainWindowWidth", m_LocalCoreStartupParameter.iWidth); + ini.Set("Interface", "MainWindowHeight", m_LocalCoreStartupParameter.iHeight); + ini.Set("Interface", "Language", m_InterfaceLanguage); + ini.Set("Interface", "ShowToolbar", m_InterfaceToolbar); + ini.Set("Interface", "ShowStatusbar", m_InterfaceStatusbar); + ini.Set("Interface", "ShowLogWindow", m_InterfaceLogWindow); + ini.Set("Interface", "ShowConsole", m_InterfaceConsole); // Hotkeys - Section& hotkeys = ini["Hotkeys"]; for (int i = HK_FULLSCREEN; i < NUM_HOTKEYS; i++) { - hotkeys.Set(g_HKData[i].IniText, m_LocalCoreStartupParameter.iHotkey[i]); - hotkeys.Set((std::string(g_HKData[i].IniText) + "Modifier").c_str(), + ini.Set("Hotkeys", g_HKData[i].IniText, m_LocalCoreStartupParameter.iHotkey[i]); + ini.Set("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier").c_str(), m_LocalCoreStartupParameter.iHotkeyModifier[i]); } // Display - Section& display = ini["Display"]; - display.Set("FullscreenResolution", m_LocalCoreStartupParameter.strFullscreenResolution); - display.Set("Fullscreen", m_LocalCoreStartupParameter.bFullscreen); - display.Set("RenderToMain", m_LocalCoreStartupParameter.bRenderToMain); - display.Set("RenderWindowXPos", m_LocalCoreStartupParameter.iRenderWindowXPos); - display.Set("RenderWindowYPos", m_LocalCoreStartupParameter.iRenderWindowYPos); - display.Set("RenderWindowWidth", m_LocalCoreStartupParameter.iRenderWindowWidth); - display.Set("RenderWindowHeight", m_LocalCoreStartupParameter.iRenderWindowHeight); + ini.Set("Display", "FullscreenResolution", m_LocalCoreStartupParameter.strFullscreenResolution); + ini.Set("Display", "Fullscreen", m_LocalCoreStartupParameter.bFullscreen); + ini.Set("Display", "RenderToMain", m_LocalCoreStartupParameter.bRenderToMain); + ini.Set("Display", "RenderWindowXPos", m_LocalCoreStartupParameter.iRenderWindowXPos); + ini.Set("Display", "RenderWindowYPos", m_LocalCoreStartupParameter.iRenderWindowYPos); + ini.Set("Display", "RenderWindowWidth", m_LocalCoreStartupParameter.iRenderWindowWidth); + ini.Set("Display", "RenderWindowHeight", m_LocalCoreStartupParameter.iRenderWindowHeight); // Game List Control - Section& gamelist = ini["GameList"]; - gamelist.Set("ListDrives", m_ListDrives); - gamelist.Set("ListWad", m_ListWad); - gamelist.Set("ListWii", m_ListWii); - gamelist.Set("ListGC", m_ListGC); - gamelist.Set("ListJap", m_ListJap); - gamelist.Set("ListPal", m_ListPal); - gamelist.Set("ListUsa", m_ListUsa); - gamelist.Set("ListFrance", m_ListFrance); - gamelist.Set("ListItaly", m_ListItaly); - gamelist.Set("ListKorea", m_ListKorea); - gamelist.Set("ListTaiwan", m_ListTaiwan); - gamelist.Set("ListUnknown", m_ListUnknown); + ini.Set("GameList", "ListDrives", m_ListDrives); + ini.Set("GameList", "ListWad", m_ListWad); + ini.Set("GameList", "ListWii", m_ListWii); + ini.Set("GameList", "ListGC", m_ListGC); + ini.Set("GameList", "ListJap", m_ListJap); + ini.Set("GameList", "ListPal", m_ListPal); + ini.Set("GameList", "ListUsa", m_ListUsa); + ini.Set("GameList", "ListFrance", m_ListFrance); + ini.Set("GameList", "ListItaly", m_ListItaly); + ini.Set("GameList", "ListKorea", m_ListKorea); + ini.Set("GameList", "ListTaiwan", m_ListTaiwan); + ini.Set("GameList", "ListUnknown", m_ListUnknown); // Core - Section& core = ini["Core"]; - core.Set("HLE_BS2", m_LocalCoreStartupParameter.bHLE_BS2); - core.Set("CPUCore", m_LocalCoreStartupParameter.iCPUCore); - core.Set("CPUThread", m_LocalCoreStartupParameter.bCPUThread); - core.Set("DSPThread", m_LocalCoreStartupParameter.bDSPThread); - core.Set("SkipIdle", m_LocalCoreStartupParameter.bSkipIdle); - core.Set("LockThreads", m_LocalCoreStartupParameter.bLockThreads); - core.Set("DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM); - core.Set("DVDRoot", m_LocalCoreStartupParameter.m_strDVDRoot); - core.Set("Apploader", m_LocalCoreStartupParameter.m_strApploader); - core.Set("EnableCheats", m_LocalCoreStartupParameter.bEnableCheats); - core.Set("SelectedLanguage",m_LocalCoreStartupParameter.SelectedLanguage); - core.Set("MemcardA", m_strMemoryCardA); - core.Set("MemcardB", m_strMemoryCardB); - core.Set("SlotA", m_EXIDevice[0]); - core.Set("SlotB", m_EXIDevice[1]); - core.Set("SerialPort1", m_EXIDevice[2]); + ini.Set("Core", "HLE_BS2", m_LocalCoreStartupParameter.bHLE_BS2); + ini.Set("Core", "CPUCore", m_LocalCoreStartupParameter.iCPUCore); + ini.Set("Core", "CPUThread", m_LocalCoreStartupParameter.bCPUThread); + ini.Set("Core", "DSPThread", m_LocalCoreStartupParameter.bDSPThread); + ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle); + ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads); + ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM); + ini.Set("Core", "DVDRoot", m_LocalCoreStartupParameter.m_strDVDRoot); + ini.Set("Core", "Apploader", m_LocalCoreStartupParameter.m_strApploader); + ini.Set("Core", "EnableCheats", m_LocalCoreStartupParameter.bEnableCheats); + ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage); + ini.Set("Core", "MemcardA", m_strMemoryCardA); + ini.Set("Core", "MemcardB", m_strMemoryCardB); + ini.Set("Core", "SlotA", m_EXIDevice[0]); + ini.Set("Core", "SlotB", m_EXIDevice[1]); + ini.Set("Core", "SerialPort1", m_EXIDevice[2]); char sidevicenum[16]; for (int i = 0; i < 4; ++i) { sprintf(sidevicenum, "SIDevice%i", i); - core.Set(sidevicenum, m_SIDevice[i]); + ini.Set("Core", sidevicenum, m_SIDevice[i]); } - core.Set("WiiSDCard", m_WiiSDCard); - core.Set("WiiKeyboard", m_WiiKeyboard); - core.Set("RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); - core.Set("RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); - core.Set("FrameLimit", m_Framelimit); - core.Set("UseFPS", b_UseFPS); + ini.Set("Core", "WiiSDCard", m_WiiSDCard); + ini.Set("Core", "WiiKeyboard", m_WiiKeyboard); + ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); + ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); + ini.Set("Core", "FrameLimit", m_Framelimit); + ini.Set("Core", "UseFPS", b_UseFPS); // Plugins - core.Set("GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin); - core.Set("DSPPlugin", m_LocalCoreStartupParameter.m_strDSPPlugin); - core.Set("WiiMotePlugin",m_LocalCoreStartupParameter.m_strWiimotePlugin[0]); + ini.Set("Core", "GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin); + ini.Set("Core", "DSPPlugin", m_LocalCoreStartupParameter.m_strDSPPlugin); + ini.Set("Core", "PadPlugin", m_LocalCoreStartupParameter.m_strPadPlugin[0]); + ini.Set("Core", "WiiMotePlugin",m_LocalCoreStartupParameter.m_strWiimotePlugin[0]); ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX)); m_SYSCONF->Save(); @@ -192,121 +187,119 @@ void SConfig::LoadSettings() // Hard coded default m_DefaultGFXPlugin = PluginsDir + DEFAULT_GFX_PLUGIN; m_DefaultDSPPlugin = PluginsDir + DEFAULT_DSP_PLUGIN; + m_DefaultPADPlugin = PluginsDir + DEFAULT_PAD_PLUGIN; m_DefaultWiiMotePlugin = PluginsDir + DEFAULT_WIIMOTE_PLUGIN; // General { - Section& general = ini["General"]; - general.Get("LastFilename", &m_LastFilename); + ini.Get("General", "LastFilename", &m_LastFilename); m_ISOFolder.clear(); + int numGCMPaths; - unsigned int numGCMPaths; - general.Get("GCMPathes", &numGCMPaths, 0); - for (unsigned int i = 0; i < numGCMPaths; i++) + if (ini.Get("General", "GCMPathes", &numGCMPaths, 0)) { - TCHAR tmp[16]; - sprintf(tmp, "GCMPath%i", i); - std::string tmpPath; - general.Get(tmp, &tmpPath, ""); - m_ISOFolder.push_back(tmpPath); + for (int i = 0; i < numGCMPaths; i++) + { + TCHAR tmp[16]; + sprintf(tmp, "GCMPath%i", i); + std::string tmpPath; + ini.Get("General", tmp, &tmpPath, ""); + m_ISOFolder.push_back(tmpPath); + } } - general.Get("RecersiveGCMPaths", &m_RecursiveISOFolder, false); + ini.Get("General", "RecersiveGCMPaths", &m_RecursiveISOFolder, false); } { // Interface - Section& iface = ini["Interface"]; - iface.Get("ConfirmStop", &m_LocalCoreStartupParameter.bConfirmStop, false); - iface.Get("UsePanicHandlers", &m_LocalCoreStartupParameter.bUsePanicHandlers, true); - iface.Get("HideCursor", &m_LocalCoreStartupParameter.bHideCursor, false); - iface.Get("AutoHideCursor", &m_LocalCoreStartupParameter.bAutoHideCursor, false); - iface.Get("Theme", &m_LocalCoreStartupParameter.iTheme, 0); - iface.Get("MainWindowPosX", &m_LocalCoreStartupParameter.iPosX, 100); - iface.Get("MainWindowPosY", &m_LocalCoreStartupParameter.iPosY, 100); - iface.Get("MainWindowWidth", &m_LocalCoreStartupParameter.iWidth, 800); - iface.Get("MainWindowHeight", &m_LocalCoreStartupParameter.iHeight, 600); - iface.Get("Language", (int*)&m_InterfaceLanguage, 0); - iface.Get("ShowToolbar", &m_InterfaceToolbar, true); - iface.Get("ShowStatusbar", &m_InterfaceStatusbar, true); - iface.Get("ShowLogWindow", &m_InterfaceLogWindow, false); - iface.Get("ShowConsole", &m_InterfaceConsole, false); + ini.Get("Interface", "ConfirmStop", &m_LocalCoreStartupParameter.bConfirmStop, false); + ini.Get("Interface", "UsePanicHandlers", &m_LocalCoreStartupParameter.bUsePanicHandlers, true); + ini.Get("Interface", "HideCursor", &m_LocalCoreStartupParameter.bHideCursor, false); + ini.Get("Interface", "AutoHideCursor", &m_LocalCoreStartupParameter.bAutoHideCursor, false); + ini.Get("Interface", "Theme", &m_LocalCoreStartupParameter.iTheme, 0); + ini.Get("Interface", "MainWindowPosX", &m_LocalCoreStartupParameter.iPosX, 100); + ini.Get("Interface", "MainWindowPosY", &m_LocalCoreStartupParameter.iPosY, 100); + ini.Get("Interface", "MainWindowWidth", &m_LocalCoreStartupParameter.iWidth, 800); + ini.Get("Interface", "MainWindowHeight", &m_LocalCoreStartupParameter.iHeight, 600); + ini.Get("Interface", "Language", (int*)&m_InterfaceLanguage, 0); + ini.Get("Interface", "ShowToolbar", &m_InterfaceToolbar, true); + ini.Get("Interface", "ShowStatusbar", &m_InterfaceStatusbar, true); + ini.Get("Interface", "ShowLogWindow", &m_InterfaceLogWindow, false); + ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false); // Hotkeys - Section& hotkeys = ini["Hotkeys"]; for (int i = HK_FULLSCREEN; i < NUM_HOTKEYS; i++) { - hotkeys.Get(g_HKData[i].IniText, + ini.Get("Hotkeys", g_HKData[i].IniText, &m_LocalCoreStartupParameter.iHotkey[i], g_HKData[i].DefaultKey); - hotkeys.Get((std::string(g_HKData[i].IniText) + "Modifier").c_str(), + ini.Get("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier").c_str(), &m_LocalCoreStartupParameter.iHotkeyModifier[i], g_HKData[i].DefaultModifier); } // Display - Section& display = ini["Display"]; - display.Get("Fullscreen", &m_LocalCoreStartupParameter.bFullscreen, false); - display.Get("FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "640x480"); - display.Get("RenderToMain", &m_LocalCoreStartupParameter.bRenderToMain, false); - display.Get("RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, 0); - display.Get("RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, 0); - display.Get("RenderWindowWidth", &m_LocalCoreStartupParameter.iRenderWindowWidth, 640); - display.Get("RenderWindowHeight", &m_LocalCoreStartupParameter.iRenderWindowHeight, 480); + ini.Get("Display", "Fullscreen", &m_LocalCoreStartupParameter.bFullscreen, false); + ini.Get("Display", "FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "640x480"); + ini.Get("Display", "RenderToMain", &m_LocalCoreStartupParameter.bRenderToMain, false); + ini.Get("Display", "RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, 0); + ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, 0); + ini.Get("Display", "RenderWindowWidth", &m_LocalCoreStartupParameter.iRenderWindowWidth, 640); + ini.Get("Display", "RenderWindowHeight", &m_LocalCoreStartupParameter.iRenderWindowHeight, 480); // Game List Control - Section& gamelist = ini["GameList"]; - gamelist.Get("ListDrives", &m_ListDrives, false); - gamelist.Get("ListWad", &m_ListWad, true); - gamelist.Get("ListWii", &m_ListWii, true); - gamelist.Get("ListGC", &m_ListGC, true); - gamelist.Get("ListJap", &m_ListJap, true); - gamelist.Get("ListPal", &m_ListPal, true); - gamelist.Get("ListUsa", &m_ListUsa, true); + ini.Get("GameList", "ListDrives", &m_ListDrives, false); + ini.Get("GameList", "ListWad", &m_ListWad, true); + ini.Get("GameList", "ListWii", &m_ListWii, true); + ini.Get("GameList", "ListGC", &m_ListGC, true); + ini.Get("GameList", "ListJap", &m_ListJap, true); + ini.Get("GameList", "ListPal", &m_ListPal, true); + ini.Get("GameList", "ListUsa", &m_ListUsa, true); - gamelist.Get("ListFrance", &m_ListFrance, true); - gamelist.Get("ListItaly", &m_ListItaly, true); - gamelist.Get("ListKorea", &m_ListKorea, true); - gamelist.Get("ListTaiwan", &m_ListTaiwan, true); - gamelist.Get("ListUnknown", &m_ListUnknown, true); + ini.Get("GameList", "ListFrance", &m_ListFrance, true); + ini.Get("GameList", "ListItaly", &m_ListItaly, true); + ini.Get("GameList", "ListKorea", &m_ListKorea, true); + ini.Get("GameList", "ListTaiwan", &m_ListTaiwan, true); + ini.Get("GameList", "ListUnknown", &m_ListUnknown, true); // Core - Section& core = ini["Core"]; - core.Get("HLE_BS2", &m_LocalCoreStartupParameter.bHLE_BS2, true); - core.Get("CPUCore", &m_LocalCoreStartupParameter.iCPUCore, 1); - core.Get("DSPThread", &m_LocalCoreStartupParameter.bDSPThread, false); - core.Get("CPUThread", &m_LocalCoreStartupParameter.bCPUThread, true); - core.Get("SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true); - core.Get("LockThreads", &m_LocalCoreStartupParameter.bLockThreads, false); - core.Get("DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM); - core.Get("DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot); - core.Get("Apploader", &m_LocalCoreStartupParameter.m_strApploader); - core.Get("EnableCheats", &m_LocalCoreStartupParameter.bEnableCheats, false); - core.Get("SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0); - core.Get("MemcardA", &m_strMemoryCardA); - core.Get("MemcardB", &m_strMemoryCardB); - core.Get("SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD_A); - core.Get("SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_MEMORYCARD_B); - core.Get("SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE); - core.Get("ProfiledReJIT", &m_LocalCoreStartupParameter.bJITProfiledReJIT, false); + ini.Get("Core", "HLE_BS2", &m_LocalCoreStartupParameter.bHLE_BS2, true); + ini.Get("Core", "CPUCore", &m_LocalCoreStartupParameter.iCPUCore, 1); + ini.Get("Core", "DSPThread", &m_LocalCoreStartupParameter.bDSPThread, false); + ini.Get("Core", "CPUThread", &m_LocalCoreStartupParameter.bCPUThread, true); + ini.Get("Core", "SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true); + ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, false); + ini.Get("Core", "DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM); + ini.Get("Core", "DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot); + ini.Get("Core", "Apploader", &m_LocalCoreStartupParameter.m_strApploader); + ini.Get("Core", "EnableCheats", &m_LocalCoreStartupParameter.bEnableCheats, false); + ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0); + ini.Get("Core", "MemcardA", &m_strMemoryCardA); + ini.Get("Core", "MemcardB", &m_strMemoryCardB); + ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD_A); + ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_MEMORYCARD_B); + ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE); + ini.Get("Core", "ProfiledReJIT",&m_LocalCoreStartupParameter.bJITProfiledReJIT, false); char sidevicenum[16]; for (int i = 0; i < 4; ++i) { sprintf(sidevicenum, "SIDevice%i", i); - core.Get(sidevicenum, (u32*)&m_SIDevice[i], i==0 ? SI_GC_CONTROLLER:SI_NONE); + ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i], i==0 ? SI_GC_CONTROLLER:SI_NONE); } - core.Get("WiiSDCard", &m_WiiSDCard, false); - core.Get("WiiKeyboard", &m_WiiKeyboard, false); - core.Get("RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); - core.Get("RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); - core.Get("TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); - core.Get("FrameLimit", &m_Framelimit, 1); // auto frame limit by default - core.Get("UseFPS", &b_UseFPS, false); // use vps as default + ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false); + ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false); + ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); + ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); + ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); + ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default + ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default // Plugins - core.Get("GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); - core.Get("DSPPlugin", &m_LocalCoreStartupParameter.m_strDSPPlugin, m_DefaultDSPPlugin.c_str()); - core.Get("WiiMotePlugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[0], m_DefaultWiiMotePlugin.c_str()); + ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); + ini.Get("Core", "DSPPlugin", &m_LocalCoreStartupParameter.m_strDSPPlugin, m_DefaultDSPPlugin.c_str()); + ini.Get("Core", "PadPlugin", &m_LocalCoreStartupParameter.m_strPadPlugin[0], m_DefaultPADPlugin.c_str()); + ini.Get("Core", "WiiMotePlugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[0], m_DefaultWiiMotePlugin.c_str()); } @@ -322,6 +315,6 @@ void SConfig::LoadSettingsWii() { char SectionName[32]; sprintf(SectionName, "Wiimote%i", i + 1); - ini[SectionName].Get("AutoReconnectRealWiimote", &m_WiiAutoReconnect[i], false); + ini.Get(SectionName, "AutoReconnectRealWiimote", &m_WiiAutoReconnect[i], false); } } diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index cb775b0520..2b975c204b 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -49,6 +49,7 @@ struct SConfig // hard coded default plugins ... std::string m_DefaultGFXPlugin; std::string m_DefaultDSPPlugin; + std::string m_DefaultPADPlugin; std::string m_DefaultWiiMotePlugin; // name of the last used filename diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 2bd72e88b7..1fb2c4e1be 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -77,6 +77,7 @@ void Callback_VideoCopiedToXFB(bool video_update); void Callback_DSPLog(const TCHAR* _szMessage, int _v); const char *Callback_ISOName(void); void Callback_DSPInterrupt(); +void Callback_PADLog(const TCHAR* _szMessage); void Callback_WiimoteLog(const TCHAR* _szMessage, int _v); void Callback_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size); bool Callback_RendererHasFocus(void); @@ -348,7 +349,7 @@ THREAD_RETURN EmuThread(void *pArg) { IniFile gameIni; gameIni.Load(_CoreParameter.m_strGameIni.c_str()); - gameIni["Wii"].Get("Widescreen", &aspectWide, !!SConfig::GetInstance().m_SYSCONF->GetData("IPL.AR")); + gameIni.Get("Wii", "Widescreen", &aspectWide, !!SConfig::GetInstance().m_SYSCONF->GetData("IPL.AR")); } VideoInitialize.bAutoAspectIs16_9 = aspectWide; @@ -380,6 +381,18 @@ THREAD_RETURN EmuThread(void *pArg) dspInit.bOnThread = _CoreParameter.bDSPThread; Plugins.GetDSP()->Initialize((void *)&dspInit); + + // Load and init GCPadPlugin + SPADInitialize PADInitialize; + PADInitialize.hWnd = g_pWindowHandle; +#if defined(HAVE_X11) && HAVE_X11 + PADInitialize.pXWindow = g_pXWindow; +#endif + PADInitialize.pLog = Callback_PADLog; + PADInitialize.pRendererHasFocus = Callback_RendererHasFocus; + // This is may be needed to avoid a SDL problem + //Plugins.FreeWiimote(); + Plugins.GetPad(0)->Initialize(&PADInitialize); // Load and Init WiimotePlugin - only if we are booting in wii mode if (_CoreParameter.bWii) @@ -725,6 +738,16 @@ void Callback_DSPInterrupt() DSP::GenerateDSPInterruptFromPlugin(DSP::INT_DSP); } + +// Callback_PADLog +// +void Callback_PADLog(const TCHAR* _szMessage) +{ + // FIXME add levels + INFO_LOG(SERIALINTERFACE, _szMessage); +} + + // Callback_ISOName: Let the DSP plugin get the game name // const char *Callback_ISOName() diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index cc92d84cb8..0a6c073877 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -21,6 +21,7 @@ #include "IniFile.h" #include +#define MAXPADS 1 #define MAXWIIMOTES 1 enum Hotkey { @@ -120,6 +121,7 @@ struct SCoreStartupParameter // files std::string m_strVideoPlugin; + std::string m_strPadPlugin[MAXPADS]; std::string m_strDSPPlugin; std::string m_strWiimotePlugin[MAXWIIMOTES]; diff --git a/Source/Core/Core/Src/CoreRerecording.cpp b/Source/Core/Core/Src/CoreRerecording.cpp index 2a5d49452d..e382351df5 100644 --- a/Source/Core/Core/Src/CoreRerecording.cpp +++ b/Source/Core/Core/Src/CoreRerecording.cpp @@ -17,9 +17,9 @@ #include "Setup.h" -#ifndef RERECORDING -bool rerecording = false; -#else +#ifdef RERECORDING + + // Include // -------------- @@ -44,7 +44,7 @@ bool rerecording = false; #include "HW/GPFifo.h" #include "HW/CPU.h" #include "HW/HW.h" -#include "HW/DSPInterface.h" +#include "HW/DSP.h" #include "HW/GPFifo.h" #include "HW/AudioInterface.h" #include "HW/VideoInterface.h" diff --git a/Source/Core/Core/Src/HW/GCPad.cpp b/Source/Core/Core/Src/HW/GCPad.cpp deleted file mode 100644 index 8ec01eb8f4..0000000000 --- a/Source/Core/Core/Src/HW/GCPad.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include "GCPadEmu.h" -#include -#include "../ConfigManager.h" - -/*staticTODOSHUFFLE*/ Plugin g_GCPad( "GCPad", "Pad", "GCPad" ); - -void PAD_Init() -{ - // i realize i am checking IsInit() twice, just too lazy to change it - if ( false == g_GCPad.controller_interface.IsInit() ) - { - // add 4 gcpads - for ( unsigned int i = 0; i<4; ++i ) - g_GCPad.controllers.push_back( new GCPad( i ) ); - - // load the saved controller config - g_GCPad.LoadConfig(); - - // needed for Xlib and exclusive dinput - g_GCPad.controller_interface.SetHwnd( SConfig::GetInstance().m_LocalCoreStartupParameter.hMainWindow ); - g_GCPad.controller_interface.Init(); - - // update control refs - std::vector::const_iterator i = g_GCPad.controllers.begin(), - e = g_GCPad.controllers.end(); - for ( ; i!=e; ++i ) - (*i)->UpdateReferences( g_GCPad.controller_interface ); - - } -} - -void PAD_Shutdown() -{ - if ( g_GCPad.controller_interface.IsInit() ) - { - std::vector::const_iterator - i = g_GCPad.controllers.begin(), - e = g_GCPad.controllers.end(); - for ( ; i!=e; ++i ) - delete *i; - g_GCPad.controllers.clear(); - - g_GCPad.controller_interface.DeInit(); - } -} - -void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) -{ - memset( _pPADStatus, 0, sizeof(*_pPADStatus) ); - _pPADStatus->err = PAD_ERR_NONE; - // wtf is this? - _pPADStatus->button |= PAD_USE_ORIGIN; - - // try lock - if ( false == g_GCPad.controls_crit.TryEnter() ) - { - // if gui has lock (messing with controls), skip this input cycle - // center axes and return - memset( &_pPADStatus->stickX, 0x80, 4 ); - return; - } - - // if we are on the next input cycle, update output and input - // if we can get a lock - static int _last_numPAD = 4; - if ( _numPAD <= _last_numPAD && g_GCPad.interface_crit.TryEnter() ) - { - g_GCPad.controller_interface.UpdateOutput(); - g_GCPad.controller_interface.UpdateInput(); - g_GCPad.interface_crit.Leave(); - } - _last_numPAD = _numPAD; - - // get input - ((GCPad*)g_GCPad.controllers[ _numPAD ])->GetInput( _pPADStatus ); - - // leave - g_GCPad.controls_crit.Leave(); - -} - -void PAD_Input(u16 _Key, u8 _UpDown) -{ - // nofin -} - -void PAD_Rumble(u8 _numPAD, u8 _uType, u8 _uStrength) -{ - // enter - if ( g_GCPad.controls_crit.TryEnter() ) - { - // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time - // set rumble - ((GCPad*)g_GCPad.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 ); - - // leave - g_GCPad.controls_crit.Leave(); - } -} diff --git a/Source/Core/Core/Src/HW/GCPad.h b/Source/Core/Core/Src/HW/GCPad.h deleted file mode 100644 index a480579c0a..0000000000 --- a/Source/Core/Core/Src/HW/GCPad.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#define PAD_ERR_NONE 0 -#define PAD_ERR_NO_CONTROLLER -1 -#define PAD_ERR_NOT_READY -2 -#define PAD_ERR_TRANSFER -3 - -#define PAD_USE_ORIGIN 0x0080 - -#define PAD_BUTTON_LEFT 0x0001 -#define PAD_BUTTON_RIGHT 0x0002 -#define PAD_BUTTON_DOWN 0x0004 -#define PAD_BUTTON_UP 0x0008 -#define PAD_TRIGGER_Z 0x0010 -#define PAD_TRIGGER_R 0x0020 -#define PAD_TRIGGER_L 0x0040 -#define PAD_BUTTON_A 0x0100 -#define PAD_BUTTON_B 0x0200 -#define PAD_BUTTON_X 0x0400 -#define PAD_BUTTON_Y 0x0800 -#define PAD_BUTTON_START 0x1000 - -struct SPADStatus -{ - u16 button; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits - u8 stickX; // 0 <= stickX <= 255 - u8 stickY; // 0 <= stickY <= 255 - u8 substickX; // 0 <= substickX <= 255 - u8 substickY; // 0 <= substickY <= 255 - u8 triggerLeft; // 0 <= triggerLeft <= 255 - u8 triggerRight; // 0 <= triggerRight <= 255 - u8 analogA; // 0 <= analogA <= 255 - u8 analogB; // 0 <= analogB <= 255 - u8 err; // one of PAD_ERR_* number - bool MicButton; // This is hax for the mic device input... -}; - -// if plugin isn't initialized, init and load config -void PAD_Init(); - -void PAD_Shutdown(); - -void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus); - -// Function: Send keyboard input to the plugin -// Purpose: -// input: The key and if it's pressed or released -// output: None -void PAD_Input(u16 _Key, u8 _UpDown); - -// Function: PAD_Rumble -// Purpose: Pad rumble! -// input: PAD number, Command type (Stop=0, Rumble=1, Stop Hard=2) and strength of Rumble -// output: none -void PAD_Rumble(u8 _numPAD, u8 _uType, u8 _uStrength); diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp index 72a7023590..70f6ae21fd 100644 --- a/Source/Core/Core/Src/HW/HW.cpp +++ b/Source/Core/Core/Src/HW/HW.cpp @@ -28,7 +28,6 @@ #include "Memmap.h" #include "ProcessorInterface.h" #include "SI.h" -#include "GCPad.h" #include "AudioInterface.h" #include "VideoInterface.h" #include "WII_IPC.h" @@ -51,7 +50,6 @@ namespace HW // Init the whole Hardware AudioInterface::Init(); VideoInterface::Init(); - PAD_Init(); SerialInterface::Init(); ProcessorInterface::Init(); Memory::Init(); @@ -77,7 +75,6 @@ namespace HW DSP::Shutdown(); Memory::Shutdown(); SerialInterface::Shutdown(); - PAD_Shutdown(); AudioInterface::Shutdown(); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) @@ -85,7 +82,7 @@ namespace HW WII_IPCInterface::Shutdown(); WII_IPC_HLE_Interface::Shutdown(); } - + State_Shutdown(); CoreTiming::Shutdown(); } diff --git a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp index 2df3fb3dbe..3737a6f899 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp @@ -19,7 +19,7 @@ #include "SI_Device.h" #include "SI_DeviceAMBaseboard.h" -#include "GCPad.h" // for pad state +#include "../PluginManager.h" // for pad state // where to put baseboard debug #define AMBASEBOARDDEBUG OSREPORT @@ -142,11 +142,10 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) case 0x10: { DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 10, %02x (READ STATUS&SWITCHES)", ptr(1)); - SPADStatus PadStatus; memset(&PadStatus, 0 ,sizeof(PadStatus)); - PAD_GetStatus(0, &PadStatus); - + CPluginManager::GetInstance().GetPad(0) + ->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); res[resp++] = 0x10; res[resp++] = 0x2; int d10_0 = 0xdf; @@ -311,8 +310,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) for (i=0; iPAD_GetStatus(i, &PadStatus); unsigned char player_data[2] = {0,0}; if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; @@ -349,7 +348,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) int slots = *jvs_io++; msg.addData(1); SPADStatus PadStatus; - PAD_GetStatus(0, &PadStatus); + CPluginManager::GetInstance().GetPad(0) + ->PAD_GetStatus(0, &PadStatus); while (slots--) { msg.addData(0); diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp index 04f56f74db..b1036d9a8d 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp @@ -21,7 +21,6 @@ #include "SI.h" #include "SI_Device.h" #include "SI_DeviceGCController.h" -#include "GCPad.h" #include "EXI_Device.h" #include "EXI_DeviceMic.h" @@ -61,7 +60,7 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength) while (iPosition < _iLength) { // Read the command - GCPADCommands command = static_cast(_pBuffer[iPosition ^ 3]); + EBufferCommands command = static_cast(_pBuffer[iPosition ^ 3]); iPosition++; // Handle it @@ -129,7 +128,8 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) { SPADStatus PadStatus; memset(&PadStatus, 0, sizeof(PadStatus)); - PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); + Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(0); + pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); u32 netValues[2] = {0}; int NetPlay = 2; @@ -258,6 +258,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) // SendCommand void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) { + Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(0); UCommand command(_Cmd); switch (command.Command) @@ -268,8 +269,8 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) case CMD_WRITE: { - u8 uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard - u8 uStrength = command.Parameter2; + unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard + unsigned int uStrength = command.Parameter2; #if defined(HAVE_WX) && HAVE_WX // get the correct pad number that should rumble locally when using netplay @@ -279,7 +280,8 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) #endif if (numPAD < 4) - PAD_Rumble(numPAD, uType, uStrength); + if (pad->PAD_Rumble) + pad->PAD_Rumble(numPAD, uType, uStrength); if (!_Poll) { diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.h b/Source/Core/Core/Src/HW/SI_DeviceGCController.h index cc2180970e..8a8dd0efb7 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.h @@ -18,36 +18,24 @@ #ifndef _SI_DEVICEGCCONTROLLER_H #define _SI_DEVICEGCCONTROLLER_H +#include "../PluginManager.h" #include "SI_Device.h" -#include "GCPad.h" + // standard gamecube controller class CSIDevice_GCController : public ISIDevice { private: - enum GCPADCommands + + // Commands + enum EBufferCommands { CMD_INVALID = 0xFFFFFFFF, CMD_RESET = 0x00, - CMD_WRITE = 0x40, CMD_ORIGIN = 0x41, CMD_RECALIBRATE = 0x42, }; - union UCommand - { - u32 Hex; - struct - { - unsigned Parameter1 : 8; - unsigned Parameter2 : 8; - unsigned Command : 8; - unsigned : 8; - }; - UCommand() {Hex = 0;} - UCommand(u32 _iValue) {Hex = _iValue;} - }; - struct SOrigin { u8 uCommand;// Maybe should be button bits? @@ -64,6 +52,25 @@ private: u8 unk_7; }; + enum EDirectCommands + { + CMD_WRITE = 0x40 + }; + + union UCommand + { + u32 Hex; + struct + { + unsigned Parameter1 : 8; + unsigned Parameter2 : 8; + unsigned Command : 8; + unsigned : 8; + }; + UCommand() {Hex = 0;} + UCommand(u32 _iValue) {Hex = _iValue;} + }; + enum EButtonCombo { COMBO_NONE = 0, @@ -87,6 +94,8 @@ private: EButtonCombo m_LastButtonCombo; public: + + // Constructor CSIDevice_GCController(int _iDeviceNumber); // Run the SI Buffer diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp index 918e062428..cc4f2e586a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp @@ -37,7 +37,7 @@ bool CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mode) INFO_LOG(WII_IPC_STM, "CWII_IPC_HLE_Device_usb_kbd: Open"); IniFile ini; ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); - ini["USB Keyboard"].Get("Layout", &m_KeyboardLayout, (int)KBD_LAYOUT_QWERTY); + ini.Get("USB Keyboard", "Layout", &m_KeyboardLayout, KBD_LAYOUT_QWERTY); for(int i = 0; i < 256; i++) m_OldKeyBuffer[i] = false; diff --git a/Source/Core/Core/Src/LuaInterface.cpp b/Source/Core/Core/Src/LuaInterface.cpp index 89c6422363..d70436ffa0 100644 --- a/Source/Core/Core/Src/LuaInterface.cpp +++ b/Source/Core/Core/Src/LuaInterface.cpp @@ -2794,11 +2794,10 @@ DEFINE_LUA_FUNCTION(emulua_loadrom, "filename") if (unique_id.size() == 6 && game_ini.Load(StartUp.m_strGameIni.c_str())) { // General settings - Section& core = game_ini["Core"]; - core.Get("CPUOnThread", &StartUp.bCPUThread, StartUp.bCPUThread); - core.Get("SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle); - core.Get("EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF); - core.Get("TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); + game_ini.Get("Core", "CPUOnThread", &StartUp.bCPUThread, StartUp.bCPUThread); + game_ini.Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle); + game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF); + game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); // Wii settings if (StartUp.bWii) { diff --git a/Source/Core/Core/Src/OnFrame.h b/Source/Core/Core/Src/OnFrame.h index 7d79c81dc9..416e4dc188 100644 --- a/Source/Core/Core/Src/OnFrame.h +++ b/Source/Core/Core/Src/OnFrame.h @@ -19,7 +19,7 @@ #define __FRAME_H #include "Common.h" -#include "HW/GCPad.h" +#include "pluginspecs_pad.h" #include diff --git a/Source/Core/Core/Src/PatchEngine.cpp b/Source/Core/Core/Src/PatchEngine.cpp index d1f00cb3f3..ca90c4491a 100644 --- a/Source/Core/Core/Src/PatchEngine.cpp +++ b/Source/Core/Core/Src/PatchEngine.cpp @@ -55,13 +55,12 @@ std::vector discList; void LoadPatchSection(const char *section, std::vector &patches, IniFile &ini) { - //if (!ini.Exists(section)) - //return; + std::vector lines; + if (!ini.GetLines(section, lines)) + return; Patch currentPatch; - std::vector lines; - ini[section].GetLines(lines); for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string line = *iter; @@ -100,14 +99,15 @@ void LoadPatchSection(const char *section, std::vector &patches, IniFile } } } - if (currentPatch.name.size()) - patches.push_back(currentPatch); + if (currentPatch.name.size()) patches.push_back(currentPatch); } static void LoadDiscList(const char *section, std::vector &_discList, IniFile &ini) { std::vector lines; - ini[section].GetLines(lines); + if (!ini.GetLines(section, lines)) + return; + for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string line = *iter; @@ -117,18 +117,19 @@ static void LoadDiscList(const char *section, std::vector &_discLis } static void LoadSpeedhacks(const char *section, std::map &hacks, IniFile &ini) { - Section& sect = ini[section]; - for (Section::const_iterator iter = sect.begin(); iter != sect.end(); ++iter) + std::vector keys; + ini.GetKeys(section, keys); + for (std::vector::const_iterator iter = keys.begin(); iter != keys.end(); ++iter) { - const std::string& key = iter->first; + std::string key = *iter; std::string value; - sect.Get(key, &value, "BOGUS"); + ini.Get(section, key.c_str(), &value, "BOGUS"); if (value != "BOGUS") { u32 address; u32 cycles; bool success = true; - success = success && TryParseUInt(std::string(key.c_str()), &address); // std::string(.c_str()); // what? + success = success && TryParseUInt(std::string(key.c_str()), &address); success = success && TryParseUInt(value, &cycles); if (success) { speedHacks[address] = (int)cycles; diff --git a/Source/Core/Core/Src/PluginManager.cpp b/Source/Core/Core/Src/PluginManager.cpp index f83efac035..43eb23831e 100644 --- a/Source/Core/Core/Src/PluginManager.cpp +++ b/Source/Core/Core/Src/PluginManager.cpp @@ -64,12 +64,15 @@ CPluginManager::CPluginManager() // Start LogManager m_PluginGlobals->logManager = LogManager::GetInstance(); + m_PluginGlobals->eventHandler = EventHandler::GetInstance(); m_params = &(SConfig::GetInstance().m_LocalCoreStartupParameter); // Set initial values to NULL. m_video = NULL; m_dsp = NULL; + for (int i = 0; i < MAXPADS; i++) + m_pad[i] = NULL; for (int i = 0; i < MAXWIIMOTES; i++) m_wiimote[i] = NULL; } @@ -82,6 +85,15 @@ CPluginManager::~CPluginManager() delete m_PluginGlobals; delete m_dsp; + for (int i = 0; i < MAXPADS; i++) + { + if (m_pad[i]) + { + delete m_pad[i]; + m_pad[i] = NULL; + } + } + for (int i = 0; i < MAXWIIMOTES; i++) { if (m_wiimote[i]) @@ -100,7 +112,7 @@ CPluginManager::~CPluginManager() // Init and Shutdown Plugins // ------------ -// Function: Point the m_wiimote[] and other variables to a certain plugin +// Function: Point the m_pad[] and other variables to a certain plugin bool CPluginManager::InitPlugins() { // Update pluginglobals. @@ -122,9 +134,26 @@ bool CPluginManager::InitPlugins() } INFO_LOG(CONSOLE, "After GetVideo\n"); - // Check if we get at least one wiimote + // Check if we get at least one pad or wiimote + bool pad = false; bool wiimote = false; + // Init pad + for (int i = 0; i < MAXPADS; i++) + { + // Check that the plugin has a name + if (!m_params->m_strPadPlugin[i].empty()) + GetPad(i); + // Check that GetPad succeeded + if (m_pad[i] != NULL) + pad = true; + } + if (!pad) + { + PanicAlert("Can't init any PAD Plugins"); + return false; + } + // Init wiimote if (m_params->bWii) { @@ -151,6 +180,15 @@ bool CPluginManager::InitPlugins() // for an explanation about the current LoadLibrary() and FreeLibrary() behavior. void CPluginManager::ShutdownPlugins() { + for (int i = 0; i < MAXPADS; i++) + { + if (m_pad[i]) + { + m_pad[i]->Shutdown(); + FreePad(i); + } + } + for (int i = 0; i < MAXWIIMOTES; i++) { if (m_wiimote[i]) @@ -266,6 +304,10 @@ void *CPluginManager::LoadPlugin(const char *_rFilename) plugin = new Common::PluginDSP(_rFilename); break; + case PLUGIN_TYPE_PAD: + plugin = new Common::PluginPAD(_rFilename); + break; + case PLUGIN_TYPE_WIIMOTE: plugin = new Common::PluginWiimote(_rFilename); break; @@ -340,12 +382,28 @@ void CPluginManager::ScanForPlugins() /* Create or return the already created plugin pointers. This will be called - often for the Wiimote from the SI_.cpp files. + often for the Pad and Wiimote from the SI_.cpp files. And often for the DSP + from the DSP files. We don't need to check if [Plugin]->IsValid() here because it will not be set by LoadPlugin() if it's not valid. */ // ------------ +Common::PluginPAD *CPluginManager::GetPad(int controller) +{ + if (m_pad[controller] != NULL) + { + if (m_pad[controller]->GetFilename() == m_params->m_strPadPlugin[controller]) + return m_pad[controller]; + else + FreePad(controller); + } + + // Else load a new plugin + m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params->m_strPadPlugin[controller].c_str()); + return m_pad[controller]; +} + Common::PluginWiimote *CPluginManager::GetWiimote(int controller) { if (m_wiimote[controller] != NULL) @@ -412,6 +470,15 @@ void CPluginManager::FreeDSP() m_dsp = NULL; } +void CPluginManager::FreePad(u32 Pad) +{ + if (Pad < MAXPADS) + { + delete m_pad[Pad]; + m_pad[Pad] = NULL; + } +} + void CPluginManager::FreeWiimote(u32 Wiimote) { if (Wiimote < MAXWIIMOTES) @@ -429,6 +496,7 @@ void CPluginManager::EmuStateChange(PLUGIN_EMUSTATE newState) // Would we need to call all plugins? // If yes, how would one check if the plugin was not // just created by GetXxx(idx) because there was none? + GetPad(0)->EmuStateChange(newState); GetWiimote(0)->EmuStateChange(newState); } @@ -453,6 +521,9 @@ void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TY case PLUGIN_TYPE_DSP: GetDSP()->Config((HWND)_Parent); break; + case PLUGIN_TYPE_PAD: + GetPad(0)->Config((HWND)_Parent); + break; case PLUGIN_TYPE_WIIMOTE: GetWiimote(0)->Config((HWND)_Parent); break; @@ -461,7 +532,7 @@ void CPluginManager::OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TY } } -// Open debugging window. Type = Video. Show = Show or hide window. +// Open debugging window. Type = Video or DSP. Show = Show or hide window. void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show) { if (!File::Exists(_rFilename)) diff --git a/Source/Core/Core/Src/PluginManager.h b/Source/Core/Core/Src/PluginManager.h index 32c147e4de..38b0420908 100644 --- a/Source/Core/Core/Src/PluginManager.h +++ b/Source/Core/Core/Src/PluginManager.h @@ -20,8 +20,10 @@ #include "Plugin.h" #include "PluginDSP.h" +#include "PluginPAD.h" #include "PluginVideo.h" #include "PluginWiimote.h" +#include "EventHandler.h" #include "CoreParameter.h" class CPluginInfo @@ -50,10 +52,12 @@ public: Common::PluginVideo *GetVideo(); Common::PluginDSP *GetDSP(); + Common::PluginPAD *GetPad(int controller); Common::PluginWiimote *GetWiimote(int controller); void FreeVideo(); void FreeDSP(); + void FreePad(u32 Pad); void FreeWiimote(u32 Wiimote); void EmuStateChange(PLUGIN_EMUSTATE newState); @@ -71,6 +75,7 @@ private: CPluginInfos m_PluginInfos; PLUGIN_GLOBALS *m_PluginGlobals; + Common::PluginPAD *m_pad[4]; Common::PluginVideo *m_video; Common::PluginWiimote *m_wiimote[4]; Common::PluginDSP *m_dsp; diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index 2cee7e70a3..d90a40efc7 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -41,8 +41,6 @@ files = ["ActionReplay.cpp", "HW/EXI_DeviceMemoryCard.cpp", "HW/EXI_DeviceMic.cpp", "HW/EXI_DeviceEthernet.cpp", - "HW/GCPad.cpp", - "HW/GCPadEmu.cpp", "HW/GPFifo.cpp", "HW/HW.cpp", "HW/Memmap.cpp", diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index a549124134..1da95de50f 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -92,6 +92,7 @@ void DoState(PointerWrap &p) CPluginManager &pm = CPluginManager::GetInstance(); pm.GetVideo()->DoState(p.GetPPtr(), p.GetMode()); pm.GetDSP()->DoState(p.GetPPtr(), p.GetMode()); + pm.GetPad(0)->DoState(p.GetPPtr(), p.GetMode()); if (Core::g_CoreStartupParameter.bWii) pm.GetWiimote(0)->DoState(p.GetPPtr(), p.GetMode()); PowerPC::DoState(p); diff --git a/Source/Core/DSPCore/DSPCore.vcproj b/Source/Core/DSPCore/DSPCore.vcproj index a532fb8094..b21a5760eb 100644 --- a/Source/Core/DSPCore/DSPCore.vcproj +++ b/Source/Core/DSPCore/DSPCore.vcproj @@ -502,6 +502,10 @@ RelativePath=".\Src\DSPAnalyzer.h" > + + diff --git a/Source/Core/DSPCore/Src/DSPBreakpoints.cpp b/Source/Core/DSPCore/Src/DSPBreakpoints.cpp new file mode 100644 index 0000000000..0ab7de9abf --- /dev/null +++ b/Source/Core/DSPCore/Src/DSPBreakpoints.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "DSPBreakpoints.h" + diff --git a/Source/Core/DSPCore/Src/SConscript b/Source/Core/DSPCore/Src/SConscript index c63f995e19..1c091cb5c7 100644 --- a/Source/Core/DSPCore/Src/SConscript +++ b/Source/Core/DSPCore/Src/SConscript @@ -6,6 +6,7 @@ files = [ "assemble.cpp", "disassemble.cpp", "DSPAccelerator.cpp", + "DSPBreakpoints.cpp", "DSPIntCCUtil.cpp", "DSPIntExtOps.cpp", "DSPHWInterface.cpp", diff --git a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp index c413813842..8198247038 100644 --- a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp +++ b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp @@ -142,14 +142,13 @@ void CBreakPointWindow::OnAddBreakPointMany() if (ini.Load(filename.c_str())) // check if there is any file there { // get lines from a certain section - if (!ini.Exists("BreakPoints")) + std::vector lines; + if (!ini.GetLines("BreakPoints", lines)) { wxMessageBox(_T("You have no [BreakPoints] line in your file")); return; } - std::vector lines; - ini["BreakPoints"].GetLines(lines); for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string line = StripSpaces(*iter); @@ -189,14 +188,13 @@ void CBreakPointWindow::OnAddMemoryCheckMany() if (ini.Load(filename.c_str())) { // get lines from a certain section - if (!ini.Exists("MemoryChecks")) + std::vector lines; + if (!ini.GetLines("MemoryChecks", lines)) { wxMessageBox(_T("You have no [MemoryChecks] line in your file")); return; } - std::vector lines; - ini["MemoryChecks"].GetLines(lines); for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string line = StripSpaces(*iter); diff --git a/Source/Core/DebuggerWX/Src/CodeWindowFunctions.cpp b/Source/Core/DebuggerWX/Src/CodeWindowFunctions.cpp index 3b050b60c8..f8c1310aee 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindowFunctions.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindowFunctions.cpp @@ -88,93 +88,89 @@ void CCodeWindow::Load() // The font to override DebuggerFont with std::string fontDesc; - Section& showonstart = ini["ShowOnStart"]; - showonstart.Get("DebuggerFont", &fontDesc); + ini.Get("ShowOnStart", "DebuggerFont", &fontDesc); if (!fontDesc.empty()) DebuggerFont.SetNativeFontInfoUserDesc(wxString::FromAscii(fontDesc.c_str())); // Decide what windows to use // This stuff really doesn't belong in CodeWindow anymore, does it? It should be // in Frame.cpp somewhere, even though it's debugger stuff. - showonstart.Get("Code", &bCodeWindow, true); - showonstart.Get("Registers", &bRegisterWindow, false); - showonstart.Get("Breakpoints", &bBreakpointWindow, false); - showonstart.Get("Memory", &bMemoryWindow, false); - showonstart.Get("JIT", &bJitWindow, false); - showonstart.Get("Sound", &bSoundWindow, false); - showonstart.Get("Video", &bVideoWindow, false); + ini.Get("ShowOnStart", "Code", &bCodeWindow, true); + ini.Get("ShowOnStart", "Registers", &bRegisterWindow, false); + ini.Get("ShowOnStart", "Breakpoints", &bBreakpointWindow, false); + ini.Get("ShowOnStart", "Memory", &bMemoryWindow, false); + ini.Get("ShowOnStart", "JIT", &bJitWindow, false); + ini.Get("ShowOnStart", "Sound", &bSoundWindow, false); + ini.Get("ShowOnStart", "Video", &bVideoWindow, false); // Get notebook affiliation - Section& section = ini[StringFromFormat("P - %s", + std::string _Section = StringFromFormat("P - %s", (Parent->ActivePerspective < Parent->Perspectives.size()) - ? Parent->Perspectives.at(Parent->ActivePerspective).Name.c_str() : "")]; - section.Get("Log", &iLogWindow, 1); - section.Get("Console", &iConsoleWindow, 1); - section.Get("Code", &iCodeWindow, 1); - section.Get("Registers", &iRegisterWindow, 1); - section.Get("Breakpoints", &iBreakpointWindow, 0); - section.Get("Memory", &iMemoryWindow, 1); - section.Get("JIT", &iJitWindow, 1); - section.Get("Sound", &iSoundWindow, 0); - section.Get("Video", &iVideoWindow, 0); + ? Parent->Perspectives.at(Parent->ActivePerspective).Name.c_str() : ""); + ini.Get(_Section.c_str(), "Log", &iLogWindow, 1); + ini.Get(_Section.c_str(), "Console", &iConsoleWindow, 1); + ini.Get(_Section.c_str(), "Code", &iCodeWindow, 1); + ini.Get(_Section.c_str(), "Registers", &iRegisterWindow, 1); + ini.Get(_Section.c_str(), "Breakpoints", &iBreakpointWindow, 0); + ini.Get(_Section.c_str(), "Memory", &iMemoryWindow, 1); + ini.Get(_Section.c_str(), "JIT", &iJitWindow, 1); + ini.Get(_Section.c_str(), "Sound", &iSoundWindow, 0); + ini.Get(_Section.c_str(), "Video", &iVideoWindow, 0); // Get floating setting - Section& flt = ini["Float"]; - flt.Get("Log", &Parent->bFloatLogWindow, false); - flt.Get("Console", &Parent->bFloatConsoleWindow, false); - flt.Get("Code", &bFloatCodeWindow, false); - flt.Get("Registers", &bFloatRegisterWindow, false); - flt.Get("Breakpoints", &bFloatBreakpointWindow, false); - flt.Get("Memory", &bFloatMemoryWindow, false); - flt.Get("JIT", &bFloatJitWindow, false); - flt.Get("Sound", &bFloatSoundWindow, false); - flt.Get("Video", &bFloatVideoWindow, false); + ini.Get("Float", "Log", &Parent->bFloatLogWindow, false); + ini.Get("Float", "Console", &Parent->bFloatConsoleWindow, false); + ini.Get("Float", "Code", &bFloatCodeWindow, false); + ini.Get("Float", "Registers", &bFloatRegisterWindow, false); + ini.Get("Float", "Breakpoints", &bFloatBreakpointWindow, false); + ini.Get("Float", "Memory", &bFloatMemoryWindow, false); + ini.Get("Float", "JIT", &bFloatJitWindow, false); + ini.Get("Float", "Sound", &bFloatSoundWindow, false); + ini.Get("Float", "Video", &bFloatVideoWindow, false); // Boot to pause or not - showonstart.Get("AutomaticStart", &bAutomaticStart, false); - showonstart.Get("BootToPause", &bBootToPause, true); + ini.Get("ShowOnStart", "AutomaticStart", &bAutomaticStart, false); + ini.Get("ShowOnStart", "BootToPause", &bBootToPause, true); } void CCodeWindow::Save() { IniFile ini; ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& showonstart = ini["ShowOnStart"]; - showonstart.Set("DebuggerFont", std::string(DebuggerFont.GetNativeFontInfoUserDesc().mb_str())); + ini.Set("ShowOnStart", "DebuggerFont", std::string(DebuggerFont.GetNativeFontInfoUserDesc().mb_str())); // Boot to pause or not - showonstart.Set("AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART)); - showonstart.Set("BootToPause", GetMenuBar()->IsChecked(IDM_BOOTTOPAUSE)); + ini.Set("ShowOnStart", "AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART)); + ini.Set("ShowOnStart", "BootToPause", GetMenuBar()->IsChecked(IDM_BOOTTOPAUSE)); // Save windows settings - //showonstart.Set("Code", GetMenuBar()->IsChecked(IDM_CODEWINDOW)); - showonstart.Set("Registers", GetMenuBar()->IsChecked(IDM_REGISTERWINDOW)); - showonstart.Set("Breakpoints", GetMenuBar()->IsChecked(IDM_BREAKPOINTWINDOW)); - showonstart.Set("Memory", GetMenuBar()->IsChecked(IDM_MEMORYWINDOW)); - showonstart.Set("JIT", GetMenuBar()->IsChecked(IDM_JITWINDOW)); - showonstart.Set("Sound", GetMenuBar()->IsChecked(IDM_SOUNDWINDOW)); - showonstart.Set("Video", GetMenuBar()->IsChecked(IDM_VIDEOWINDOW)); - Section& section = ini[StringFromFormat("P - %s", + //ini.Set("ShowOnStart", "Code", GetMenuBar()->IsChecked(IDM_CODEWINDOW)); + ini.Set("ShowOnStart", "Registers", GetMenuBar()->IsChecked(IDM_REGISTERWINDOW)); + ini.Set("ShowOnStart", "Breakpoints", GetMenuBar()->IsChecked(IDM_BREAKPOINTWINDOW)); + ini.Set("ShowOnStart", "Memory", GetMenuBar()->IsChecked(IDM_MEMORYWINDOW)); + ini.Set("ShowOnStart", "JIT", GetMenuBar()->IsChecked(IDM_JITWINDOW)); + ini.Set("ShowOnStart", "Sound", GetMenuBar()->IsChecked(IDM_SOUNDWINDOW)); + ini.Set("ShowOnStart", "Video", GetMenuBar()->IsChecked(IDM_VIDEOWINDOW)); + std::string _Section = StringFromFormat("P - %s", (Parent->ActivePerspective < Parent->Perspectives.size()) - ? Parent->Perspectives.at(Parent->ActivePerspective).Name.c_str() : "")]; - section.Set("Log", iLogWindow); - section.Set("Console", iConsoleWindow); - section.Set("Code", iCodeWindow); - section.Set("Registers", iRegisterWindow); - section.Set("Breakpoints", iBreakpointWindow); - section.Set("Memory", iMemoryWindow); - section.Set("JIT", iJitWindow); - section.Set("Sound", iSoundWindow); - section.Set("Video", iVideoWindow); + ? Parent->Perspectives.at(Parent->ActivePerspective).Name.c_str() : ""); + ini.Set(_Section.c_str(), "Log", iLogWindow); + ini.Set(_Section.c_str(), "Console", iConsoleWindow); + ini.Set(_Section.c_str(), "Code", iCodeWindow); + ini.Set(_Section.c_str(), "Registers", iRegisterWindow); + ini.Set(_Section.c_str(), "Breakpoints", iBreakpointWindow); + ini.Set(_Section.c_str(), "Memory", iMemoryWindow); + ini.Set(_Section.c_str(), "JIT", iJitWindow); + ini.Set(_Section.c_str(), "Sound", iSoundWindow); + ini.Set(_Section.c_str(), "Video", iVideoWindow); // Save floating setting - Section& flt = ini["Float"]; - flt.Set("Log", !!FindWindowById(IDM_LOGWINDOW_PARENT)); - flt.Set("Console", !!FindWindowById(IDM_CONSOLEWINDOW_PARENT)); - flt.Set("Code", !!FindWindowById(IDM_CODEWINDOW_PARENT)); - flt.Set("Registers", !!FindWindowById(IDM_REGISTERWINDOW_PARENT)); - flt.Set("Breakpoints", !!FindWindowById(IDM_BREAKPOINTWINDOW_PARENT)); - flt.Set("Memory", !!FindWindowById(IDM_MEMORYWINDOW_PARENT)); - flt.Set("JIT", !!FindWindowById(IDM_JITWINDOW_PARENT)); - flt.Set("Sound", !!FindWindowById(IDM_SOUNDWINDOW_PARENT)); - flt.Set("Video", !!FindWindowById(IDM_VIDEOWINDOW_PARENT)); + ini.Set("Float", "Log", !!FindWindowById(IDM_LOGWINDOW_PARENT)); + ini.Set("Float", "Console", !!FindWindowById(IDM_CONSOLEWINDOW_PARENT)); + ini.Set("Float", "Code", !!FindWindowById(IDM_CODEWINDOW_PARENT)); + ini.Set("Float", "Registers", !!FindWindowById(IDM_REGISTERWINDOW_PARENT)); + ini.Set("Float", "Breakpoints", !!FindWindowById(IDM_BREAKPOINTWINDOW_PARENT)); + ini.Set("Float", "Memory", !!FindWindowById(IDM_MEMORYWINDOW_PARENT)); + ini.Set("Float", "JIT", !!FindWindowById(IDM_JITWINDOW_PARENT)); + ini.Set("Float", "Sound", !!FindWindowById(IDM_SOUNDWINDOW_PARENT)); + ini.Set("Float", "Video", !!FindWindowById(IDM_VIDEOWINDOW_PARENT)); ini.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); } diff --git a/Source/Core/DebuggerWX/Src/MemoryWindow.cpp b/Source/Core/DebuggerWX/Src/MemoryWindow.cpp index d24701975a..61e0468fe0 100644 --- a/Source/Core/DebuggerWX/Src/MemoryWindow.cpp +++ b/Source/Core/DebuggerWX/Src/MemoryWindow.cpp @@ -129,23 +129,21 @@ void CMemoryWindow::Save(IniFile& _IniFile) const // Prevent these bad values that can happen after a crash or hanging if(GetPosition().x != -32000 && GetPosition().y != -32000) { - Section& memwin = _IniFile["MemoryWindow"]; - memwin.Set("x", GetPosition().x); - memwin.Set("y", GetPosition().y); - memwin.Set("w", GetSize().GetWidth()); - memwin.Set("h", GetSize().GetHeight()); + _IniFile.Set("MemoryWindow", "x", GetPosition().x); + _IniFile.Set("MemoryWindow", "y", GetPosition().y); + _IniFile.Set("MemoryWindow", "w", GetSize().GetWidth()); + _IniFile.Set("MemoryWindow", "h", GetSize().GetHeight()); } } void CMemoryWindow::Load(IniFile& _IniFile) { - int x, y, w, h; - Section& memwin = _IniFile["MemoryWindow"]; - memwin.Get("x", &x, GetPosition().x); - memwin.Get("y", &y, GetPosition().y); - memwin.Get("w", &w, GetSize().GetWidth()); - memwin.Get("h", &h, GetSize().GetHeight()); + int x,y,w,h; + _IniFile.Get("MemoryWindow", "x", &x, GetPosition().x); + _IniFile.Get("MemoryWindow", "y", &y, GetPosition().y); + _IniFile.Get("MemoryWindow", "w", &w, GetSize().GetWidth()); + _IniFile.Get("MemoryWindow", "h", &h, GetSize().GetHeight()); SetSize(x, y, w, h); } @@ -324,12 +322,12 @@ void CMemoryWindow::onSearch(wxCommandEvent& event) { //memview->cu wxString rawData=valbox->GetValue(); std::vector Dest;//May need a better name - size_t size=0; + u32 size=0; int pad=rawData.size()%2;//If it's uneven unsigned long i=0; long count=0; char copy[3]={0}; - size_t newsize=0; + long newsize=0; unsigned char *tmp2=0; char* tmpstr=0; switch (chkHex->GetValue()){ diff --git a/Source/Core/DiscIO/Src/FileMonitor.cpp b/Source/Core/DiscIO/Src/FileMonitor.cpp index 7bd8ec2118..06f4a7b789 100644 --- a/Source/Core/DiscIO/Src/FileMonitor.cpp +++ b/Source/Core/DiscIO/Src/FileMonitor.cpp @@ -142,7 +142,7 @@ void FindFilename(u64 offset) if (!fname || (strlen(fname) == 512)) return; - CheckFile(fname, (int)pFileSystem->GetFileSize(fname)); + CheckFile(fname, pFileSystem->GetFileSize(fname)); } void Close() diff --git a/Source/Core/DolphinWX/DolphinWX.vcproj b/Source/Core/DolphinWX/DolphinWX.vcproj index 25420388b9..d6a8f228a8 100644 --- a/Source/Core/DolphinWX/DolphinWX.vcproj +++ b/Source/Core/DolphinWX/DolphinWX.vcproj @@ -56,7 +56,7 @@ Optimization="3" InlineFunctionExpansion="0" FavorSizeOrSpeed="1" - AdditionalIncludeDirectories="..\Common\Src;..\Core\Src;..\DebuggerWX\src;..\DebuggerUICommon\src;..\DiscIO\Src;..\InputCommon\Src;..\..\Plugins\InputUICommon\Src;..\..\PluginSpecs;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\SFML\include" + AdditionalIncludeDirectories="..\Common\Src;..\Core\Src;..\DebuggerWX\src;..\DebuggerUICommon\src;..\DiscIO\Src;..\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\SFML\include" PreprocessorDefinitions="WIN32;__WXMSW__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" StringPooling="false" RuntimeLibrary="0" @@ -174,7 +174,7 @@ EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" OmitFramePointers="false" - AdditionalIncludeDirectories="..\Common\Src;..\Core\Src;..\DebuggerWX\src;..\DebuggerUICommon\src;..\DiscIO\Src;..\InputCommon\Src;..\..\Plugins\InputUICommon\Src;..\..\PluginSpecs;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\SFML\include" + AdditionalIncludeDirectories="..\Common\Src;..\Core\Src;..\DebuggerWX\src;..\DebuggerUICommon\src;..\DiscIO\Src;..\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc;..\..\..\Externals\SFML\include" PreprocessorDefinitions="WIN32;__WXMSW__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" StringPooling="true" RuntimeLibrary="0" @@ -286,7 +286,7 @@ Disable(); DSPSelection->Disable(); + PADSelection->Disable(); WiimoteSelection->Disable(); } } @@ -279,6 +282,8 @@ void CConfigMain::InitializeGUIValues() // Plugins FillChoiceBox(GraphicSelection, PLUGIN_TYPE_VIDEO, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin); FillChoiceBox(DSPSelection, PLUGIN_TYPE_DSP, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin); + for (int i = 0; i < MAXPADS; i++) + FillChoiceBox(PADSelection, PLUGIN_TYPE_PAD, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin[i]); for (int i=0; i < MAXWIIMOTES; i++) FillChoiceBox(WiimoteSelection, PLUGIN_TYPE_WIIMOTE, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strWiimotePlugin[i]); } @@ -670,6 +675,10 @@ void CConfigMain::CreateGUIControls() DSPSelection = new wxChoice(PluginPage, ID_DSP_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); DSPConfig = new wxButton(PluginPage, ID_DSP_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + sbPadPlugin = new wxStaticBoxSizer(wxHORIZONTAL, PluginPage, wxT("Gamecube Pad")); + PADSelection = new wxChoice(PluginPage, ID_PAD_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); + PADConfig = new wxButton(PluginPage, ID_PAD_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + sbWiimotePlugin = new wxStaticBoxSizer(wxHORIZONTAL, PluginPage, wxT("Wiimote")); WiimoteSelection = new wxChoice(PluginPage, ID_WIIMOTE_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); WiimoteConfig = new wxButton(PluginPage, ID_WIIMOTE_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); @@ -684,6 +693,10 @@ void CConfigMain::CreateGUIControls() sbDSPPlugin->Add(DSPConfig, 0, wxALL, 5); sPlugins->Add(sbDSPPlugin, 0, wxEXPAND|wxALL, 5); + sbPadPlugin->Add(PADSelection, 1, wxEXPAND|wxALL, 5); + sbPadPlugin->Add(PADConfig, 0, wxALL, 5); + sPlugins->Add(sbPadPlugin, 0, wxEXPAND|wxALL, 5); + sbWiimotePlugin->Add(WiimoteSelection, 1, wxEXPAND|wxALL, 5); sbWiimotePlugin->Add(WiimoteConfig, 0, wxALL, 5); sPlugins->Add(sbWiimotePlugin, 0, wxEXPAND|wxALL, 5); @@ -1066,6 +1079,9 @@ void CConfigMain::OnSelectionChanged(wxCommandEvent& WXUNUSED (event)) { // Update plugin filenames GetFilename(GraphicSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin); + GetFilename(DSPSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin); + for (int i = 0; i < MAXPADS; i++) + GetFilename(PADSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin[i]); for (int i = 0; i < MAXWIIMOTES; i++) GetFilename(WiimoteSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strWiimotePlugin[i]); } @@ -1080,6 +1096,9 @@ void CConfigMain::OnConfig(wxCommandEvent& event) case ID_DSP_CONFIG: CallConfig(DSPSelection); break; + case ID_PAD_CONFIG: + CallConfig(PADSelection); + break; case ID_WIIMOTE_CONFIG: CallConfig(WiimoteSelection); break; diff --git a/Source/Core/DolphinWX/Src/ConfigMain.h b/Source/Core/DolphinWX/Src/ConfigMain.h index 644736b5e8..a24824a7d9 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.h +++ b/Source/Core/DolphinWX/Src/ConfigMain.h @@ -99,6 +99,7 @@ private: wxBoxSizer* sPlugins; wxStaticBoxSizer* sbGraphicsPlugin; wxStaticBoxSizer* sbDSPPlugin; + wxStaticBoxSizer* sbPadPlugin; wxStaticBoxSizer* sbWiimotePlugin; wxNotebook *Notebook; @@ -137,6 +138,9 @@ private: wxStaticText* ApploaderPathText; wxFilePickerCtrl* ApploaderPath; + wxStaticText* PADText; + wxButton* PADConfig; + wxChoice* PADSelection; wxButton* DSPConfig; wxStaticText* DSPText; wxChoice* DSPSelection; @@ -235,6 +239,10 @@ private: ID_WIIMOTE_CONFIG, ID_WIIMOTE_TEXT, ID_WIIMOTE_CB, + ID_PAD_TEXT, + ID_PAD_ABOUT , + ID_PAD_CONFIG, + ID_PAD_CB, ID_DSP_ABOUT, ID_DSP_CONFIG, ID_DSP_TEXT, diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index ee8c5ddf76..4795bcf0cc 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -45,7 +45,6 @@ #include "IPC_HLE/WII_IPC_HLE_Device_usb.h" #include "State.h" #include "VolumeHandler.h" -#include "HW/GCPad.h" #include // wxWidgets @@ -252,7 +251,7 @@ EVT_MENU(IDM_SCREENSHOT, CFrame::OnScreenshot) EVT_MENU(wxID_PREFERENCES, CFrame::OnConfigMain) EVT_MENU(IDM_CONFIG_GFX_PLUGIN, CFrame::OnPluginGFX) EVT_MENU(IDM_CONFIG_DSP_PLUGIN, CFrame::OnPluginDSP) -EVT_MENU(IDM_CONFIG_GCPAD, CFrame::OnPluginGCPad) +EVT_MENU(IDM_CONFIG_PAD_PLUGIN, CFrame::OnPluginPAD) EVT_MENU(IDM_CONFIG_WIIMOTE_PLUGIN, CFrame::OnPluginWiimote) EVT_MENU(IDM_SAVE_PERSPECTIVE, CFrame::OnToolBar) @@ -442,7 +441,7 @@ CFrame::CFrame(wxFrame* parent, { IniFile ini; int winpos; ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX)); - ini["LogWindow"].Get("pos", &winpos, 2); + ini.Get("LogWindow", "pos", &winpos, 2); m_Mgr->GetPane(wxT("Pane 0")).Show().PaneBorder(false).CaptionVisible(false).Layer(0).Center(); m_Mgr->GetPane(wxT("Pane 1")).Hide().PaneBorder(false).CaptionVisible(true).Layer(0) @@ -713,6 +712,12 @@ void CFrame::OnCustomHostMessage(int Id) { DoRemovePage(Win, false); + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), + PLUGIN_TYPE_DSP, false + ); + //Win->Reparent(NULL); //g_pCodeWindow->OnToggleDLLWindow(false, 0); GetMenuBar()->FindItem(IDM_SOUNDWINDOW)->Check(false); @@ -878,7 +883,7 @@ void CFrame::OnKeyDown(wxKeyEvent& event) #endif // Send the keyboard status to the Input plugin - PAD_Input(event.GetKeyCode(), 1); // 1 = Down + CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down } else event.Skip(); @@ -889,7 +894,7 @@ void CFrame::OnKeyUp(wxKeyEvent& event) event.Skip(); if(Core::GetState() != Core::CORE_UNINITIALIZED) - PAD_Input(event.GetKeyCode(), 0); // 0 = Up*/ + CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 0); // 0 = Up } // -------- diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h index 5e22b03051..d01c4b812b 100644 --- a/Source/Core/DolphinWX/Src/Frame.h +++ b/Source/Core/DolphinWX/Src/Frame.h @@ -320,7 +320,7 @@ class CFrame : public CRenderFrame void OnConfigMain(wxCommandEvent& event); // Options void OnPluginGFX(wxCommandEvent& event); void OnPluginDSP(wxCommandEvent& event); - void OnPluginGCPad(wxCommandEvent& event); + void OnPluginPAD(wxCommandEvent& event); void OnPluginWiimote(wxCommandEvent& event); void OnToggleFullscreen(wxCommandEvent& event); diff --git a/Source/Core/DolphinWX/Src/FrameAui.cpp b/Source/Core/DolphinWX/Src/FrameAui.cpp index 397ee95d6f..45da0a4716 100644 --- a/Source/Core/DolphinWX/Src/FrameAui.cpp +++ b/Source/Core/DolphinWX/Src/FrameAui.cpp @@ -772,9 +772,8 @@ void CFrame::SetSimplePaneSize() IniFile ini; ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX)); - Section& logwin = ini["LogWindow"]; - logwin.Get("x", &x, Size); - logwin.Get("y", &y, Size); + ini.Get("LogWindow", "x", &x, Size); + ini.Get("LogWindow", "y", &y, Size); // Update size m_Mgr->GetPane(wxT("Pane 0")).BestSize(x, y).MinSize(x, y).MaxSize(x, y); @@ -895,9 +894,8 @@ void CFrame::SaveLocal() IniFile ini; ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& perspectives = ini["Perspectives"]; - perspectives.Get("Perspectives", &_Perspectives, ""); - perspectives.Get("Active", &ActivePerspective, 5); + ini.Get("Perspectives", "Perspectives", &_Perspectives, ""); + ini.Get("Perspectives", "Active", &ActivePerspective, 5); SplitString(_Perspectives, ",", VPerspectives); for (u32 i = 0; i < VPerspectives.size(); i++) @@ -910,10 +908,10 @@ void CFrame::SaveLocal() if (Tmp.Name == "") continue; //if (!ini.Exists(_Section.c_str(), "Width")) continue; - Section& section = ini[StringFromFormat("P - %s", Tmp.Name.c_str())]; - section.Get("Perspective", &_Perspective, ""); - section.Get("Width", &_Width, ""); - section.Get("Height", &_Height, ""); + _Section = StringFromFormat("P - %s", Tmp.Name.c_str()); + ini.Get(_Section.c_str(), "Perspective", &_Perspective, ""); + ini.Get(_Section.c_str(), "Width", &_Width, ""); + ini.Get(_Section.c_str(), "Height", &_Height, ""); Tmp.Perspective = wxString::FromAscii(_Perspective.c_str()); @@ -948,8 +946,8 @@ void CFrame::Save() IniFile ini; ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& section = ini[StringFromFormat("P - %s", Perspectives.at(ActivePerspective).Name.c_str())]; - section.Set("Perspective", m_Mgr->SavePerspective().mb_str()); + std::string _Section = StringFromFormat("P - %s", Perspectives.at(ActivePerspective).Name.c_str()); + ini.Set(_Section.c_str(), "Perspective", m_Mgr->SavePerspective().mb_str()); std::string SWidth = "", SHeight = ""; for (u32 i = 0; i < m_Mgr->GetAllPanes().GetCount(); i++) @@ -964,8 +962,8 @@ void CFrame::Save() // Remove the ending "," SWidth = SWidth.substr(0, SWidth.length()-1); SHeight = SHeight.substr(0, SHeight.length()-1); - section.Set("Width", SWidth.c_str()); - section.Set("Height", SHeight.c_str()); + ini.Set(_Section.c_str(), "Width", SWidth.c_str()); + ini.Set(_Section.c_str(), "Height", SHeight.c_str()); // Save perspective names std::string STmp = ""; @@ -974,9 +972,8 @@ void CFrame::Save() STmp += Perspectives.at(i).Name + ","; } STmp = STmp.substr(0, STmp.length()-1); - Section& perspectives = ini["Perspectives"]; - perspectives.Set("Perspectives", STmp.c_str()); - perspectives.Set("Active", ActivePerspective); + ini.Set("Perspectives", "Perspectives", STmp.c_str()); + ini.Set("Perspectives", "Active", ActivePerspective); ini.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); // Save notebook affiliations diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 7de9e51365..8bafc8aa15 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -27,44 +27,42 @@ window handle that is returned by CreateWindow() can be accessed from Core::GetWindowHandle(). */ -// Common -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include +#include "Setup.h" // Common #include "NetWindow.h" -#include "Globals.h" +#include "Common.h" // Common +#include "FileUtil.h" +#include "FileSearch.h" +#include "Timer.h" + +#include "Globals.h" // Local #include "Frame.h" #include "ConfigMain.h" +#include "PluginManager.h" #include "MemcardManager.h" #include "CheatsWindow.h" #include "LuaWindow.h" #include "AboutDolphin.h" #include "GameListCtrl.h" +#include "BootManager.h" #include "LogWindow.h" #include "WxUtils.h" -#include "BootManager.h" + +#include "ConfigManager.h" // Core +#include "Core.h" +#include "OnFrame.h" +#include "HW/CPU.h" +#include "PowerPC/PowerPC.h" +#include "HW/DVDInterface.h" +#include "HW/ProcessorInterface.h" +#include "IPC_HLE/WII_IPC_HLE_Device_usb.h" +#include "State.h" +#include "VolumeHandler.h" +#include "NANDContentLoader.h" +#include "WXInputBase.h" + +#include // wxWidgets // Resources @@ -172,7 +170,7 @@ void CFrame::CreateMenu() pOptionsMenu->AppendSeparator(); pOptionsMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&Graphics Settings")); pOptionsMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&DSP Settings")); - pOptionsMenu->Append(IDM_CONFIG_GCPAD, _T("&GCPad Settings")); + pOptionsMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&Gamecube Pad Settings")); pOptionsMenu->Append(IDM_CONFIG_WIIMOTE_PLUGIN, _T("&Wiimote Settings")); if (g_pCodeWindow) { @@ -334,10 +332,8 @@ void CFrame::PopulateToolbar(wxAuiToolBar* ToolBar) ToolBar->AddTool(wxID_PREFERENCES, _T("Config"), m_Bitmaps[Toolbar_PluginOptions], _T("Configure...")); ToolBar->AddTool(IDM_CONFIG_GFX_PLUGIN, _T("Graphics"), m_Bitmaps[Toolbar_PluginGFX], _T("Graphics settings")); ToolBar->AddTool(IDM_CONFIG_DSP_PLUGIN, _T("DSP"), m_Bitmaps[Toolbar_PluginDSP], _T("DSP settings")); - ToolBar->AddTool(IDM_CONFIG_GCPAD, _T("GCPad"), m_Bitmaps[Toolbar_PluginPAD], _T("GCPad settings")); + ToolBar->AddTool(IDM_CONFIG_PAD_PLUGIN, _T("GCPad"), m_Bitmaps[Toolbar_PluginPAD], _T("Gamecube Pad settings")); ToolBar->AddTool(IDM_CONFIG_WIIMOTE_PLUGIN, _T("Wiimote"), m_Bitmaps[Toolbar_Wiimote], _T("Wiimote settings")); - ToolBar->AddSeparator(); - ToolBar->AddTool(wxID_ABOUT, _T("About"), m_Bitmaps[Toolbar_Help], _T("About Dolphin")); // after adding the buttons to the toolbar, must call Realize() to reflect // the changes @@ -944,25 +940,14 @@ void CFrame::OnPluginDSP(wxCommandEvent& WXUNUSED (event)) ); } -extern Plugin g_GCPad; //TODOSHUFFLE -void CFrame::OnPluginGCPad(wxCommandEvent& WXUNUSED (event)) +void CFrame::OnPluginPAD(wxCommandEvent& WXUNUSED (event)) { - bool was_init = false; - - if ( g_GCPad.controller_interface.IsInit() ) // check if game is running - was_init = true; - else - PAD_Init(); - - ConfigDialog* configDiag = new ConfigDialog( this, g_GCPad, g_GCPad.gui_name, was_init ); - - configDiag->ShowModal(); - configDiag->Destroy(); - - if ( !was_init ) // if game isn't running - PAD_Shutdown(); + CPluginManager::GetInstance().OpenConfig( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin[0].c_str(), + PLUGIN_TYPE_PAD + ); } - void CFrame::OnPluginWiimote(wxCommandEvent& WXUNUSED (event)) { CPluginManager::GetInstance().OpenConfig( diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 064c28c1bf..3b1e080dc1 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -357,7 +357,7 @@ void CGameListCtrl::OnPaintDrawImages(wxPaintEvent& event) m_imageListSmall->Draw(m_FlagImageIndex[rISOFile.GetCountry()], dc, flagOffset, itemY); ini.Load((std::string(File::GetUserPath(D_GAMECONFIG_IDX)) + (rISOFile.GetUniqueID()) + ".ini").c_str()); - ini["EmuState"].Get("EmulationStateId", &nState); + ini.Get("EmuState", "EmulationStateId", &nState); m_imageListSmall->Draw(m_EmuStateImageIndex[nState], dc, stateOffset, itemY); } } @@ -439,7 +439,7 @@ void CGameListCtrl::InsertItemInReportView(long _Index) // Emulation status int nState; - ini["EmuState"].Get("EmulationStateId", &nState); + ini.Get("EmuState", "EmulationStateId", &nState); // Emulation state SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[nState]); @@ -701,9 +701,9 @@ int wxCALLBACK wxListCompare(long item1, long item2, long sortData) std::string GameIni2 = std::string(File::GetUserPath(D_GAMECONFIG_IDX)) + iso2->GetUniqueID() + ".ini"; ini.Load(GameIni1.c_str()); - ini["EmuState"].Get("EmulationStateId", &nState1); + ini.Get("EmuState", "EmulationStateId", &nState1); ini.Load(GameIni2.c_str()); - ini["EmuState"].Get("EmulationStateId", &nState2); + ini.Get("EmuState", "EmulationStateId", &nState2); if(nState1 > nState2) return 1 *t; if(nState1 < nState2) return -1 *t; @@ -809,9 +809,8 @@ void CGameListCtrl::OnMouseMotion(wxMouseEvent& event) std::string emuState[5] = {"Broken", "Intro", "In-Game", "Playable", "Perfect"}, issues; int nState; - Section& emustate = ini["EmuState"]; - emustate.Get("EmulationStateId", &nState); - emustate.Get("EmulationIssues", &issues, ""); + ini.Get("EmuState", "EmulationStateId", &nState); + ini.Get("EmuState", "EmulationIssues", &issues, ""); // Get item Coords then convert from wxWindow coord to Screen coord wxRect Rect; diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h index 9581baba3f..c530df24bd 100644 --- a/Source/Core/DolphinWX/Src/Globals.h +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -121,7 +121,7 @@ enum IDM_CONFIG_GFX_PLUGIN, IDM_CONFIG_DSP_PLUGIN, - IDM_CONFIG_GCPAD, + IDM_CONFIG_PAD_PLUGIN, IDM_CONFIG_WIIMOTE_PLUGIN, // -------------------------------------------------------------- diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 09ef8870da..cb65e72a00 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -782,57 +782,77 @@ void CISOProperties::SetRefresh(wxCommandEvent& event) void CISOProperties::LoadGameConfig() { + bool bTemp; int iTemp; std::string sTemp; - Section& core = GameIni["Core"]; - Section& wii = GameIni["Wii"]; - Section& video = GameIni["Video"]; - Section& emustate = GameIni["EmuState"]; + if (GameIni.Get("Core", "CPUThread", &bTemp)) + CPUThread->Set3StateValue((wxCheckBoxState)bTemp); + else + CPUThread->Set3StateValue(wxCHK_UNDETERMINED); - core.Get("CPUThread", &iTemp, (int)wxCHK_UNDETERMINED); - CPUThread->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Core", "SkipIdle", &bTemp)) + SkipIdle->Set3StateValue((wxCheckBoxState)bTemp); + else + SkipIdle->Set3StateValue(wxCHK_UNDETERMINED); - core.Get("SkipIdle", &iTemp, (int)wxCHK_UNDETERMINED); - SkipIdle->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Core", "TLBHack", &bTemp)) + TLBHack->Set3StateValue((wxCheckBoxState)bTemp); + else + TLBHack->Set3StateValue(wxCHK_UNDETERMINED); - core.Get("TLBHack", &iTemp, (int)wxCHK_UNDETERMINED); - TLBHack->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Wii", "ProgressiveScan", &bTemp)) + EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp); + else + EnableProgressiveScan->Set3StateValue(wxCHK_UNDETERMINED); - wii.Get("ProgressiveScan", &iTemp, (int)wxCHK_UNDETERMINED); - EnableProgressiveScan->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Wii", "Widescreen", &bTemp)) + EnableWideScreen->Set3StateValue((wxCheckBoxState)bTemp); + else + EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED); - wii.Get("Widescreen", &iTemp, (int)wxCHK_UNDETERMINED); - EnableWideScreen->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "ForceFiltering", &bTemp)) + ForceFiltering->Set3StateValue((wxCheckBoxState)bTemp); + else + ForceFiltering->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("ForceFiltering", &iTemp, (int)wxCHK_UNDETERMINED); - ForceFiltering->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "EFBCopyDisable", &bTemp)) + EFBCopyDisable->Set3StateValue((wxCheckBoxState)bTemp); + else + EFBCopyDisable->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("EFBCopyDisable", &iTemp, (int)wxCHK_UNDETERMINED); - EFBCopyDisable->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "EFBToTextureEnable", &bTemp)) + EFBToTextureEnable->Set3StateValue((wxCheckBoxState)bTemp); + else + EFBToTextureEnable->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("EFBToTextureEnable", &iTemp, (int)wxCHK_UNDETERMINED); - EFBToTextureEnable->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "SafeTextureCache", &bTemp)) + SafeTextureCache->Set3StateValue((wxCheckBoxState)bTemp); + else + SafeTextureCache->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("SafeTextureCache", &iTemp, (int)wxCHK_UNDETERMINED); - SafeTextureCache->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "DstAlphaPass", &bTemp)) + DstAlphaPass->Set3StateValue((wxCheckBoxState)bTemp); + else + DstAlphaPass->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("DstAlphaPass", &iTemp, (int)wxCHK_UNDETERMINED); - DstAlphaPass->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "UseXFB", &bTemp)) + UseXFB->Set3StateValue((wxCheckBoxState)bTemp); + else + UseXFB->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("UseXFB", &iTemp, (int)wxCHK_UNDETERMINED); - UseXFB->Set3StateValue((wxCheckBoxState)iTemp); + if (GameIni.Get("Video", "FIFOBPHack", &bTemp)) + BPHack->Set3StateValue((wxCheckBoxState)bTemp); + else + BPHack->Set3StateValue(wxCHK_UNDETERMINED); - video.Get("FIFOBPHack", &iTemp, (int)wxCHK_UNDETERMINED); - BPHack->Set3StateValue((wxCheckBoxState)iTemp); - - video.Get("ProjectionHack", &iTemp, -1); + GameIni.Get("Video", "ProjectionHack", &iTemp, -1); Hack->SetSelection(iTemp); - emustate.Get("EmulationStateId", &iTemp, -1); + GameIni.Get("EmuState", "EmulationStateId", &iTemp, -1); EmuState->SetSelection(iTemp); - emustate.Get("EmulationIssues", &sTemp); + GameIni.Get("EmuState", "EmulationIssues", &sTemp); if (!sTemp.empty()) { EmuIssues->SetValue(wxString(sTemp.c_str(), *wxConvCurrent)); @@ -846,29 +866,77 @@ void CISOProperties::LoadGameConfig() bool CISOProperties::SaveGameConfig() { - Section& core = GameIni["Core"]; - Section& wii = GameIni["Wii"]; - Section& video = GameIni["Video"]; - Section& emustate = GameIni["EmuState"]; + if (CPUThread->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Core", "CPUThread"); + else + GameIni.Set("Core", "CPUThread", CPUThread->Get3StateValue()); - core.Set("CPUThread", CPUThread->Get3StateValue(), wxCHK_UNDETERMINED); - core.Set("SkipIdle", SkipIdle->Get3StateValue(), wxCHK_UNDETERMINED); - core.Set("TLBHack", TLBHack->Get3StateValue(), wxCHK_UNDETERMINED); + if (SkipIdle->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Core", "SkipIdle"); + else + GameIni.Set("Core", "SkipIdle", SkipIdle->Get3StateValue()); - wii.Set("ProgressiveScan", EnableProgressiveScan->Get3StateValue(), wxCHK_UNDETERMINED); - wii.Set("Widescreen", EnableWideScreen->Get3StateValue(), wxCHK_UNDETERMINED); + if (TLBHack->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Core", "TLBHack"); + else + GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue()); - video.Set("ForceFiltering", ForceFiltering->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("EFBCopyDisable", EFBCopyDisable->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("EFBToTextureEnable", EFBToTextureEnable->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("SafeTextureCache", SafeTextureCache->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("DstAlphaPass", DstAlphaPass->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("UseXFB", UseXFB->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("FIFOBPHack", BPHack->Get3StateValue(), wxCHK_UNDETERMINED); - video.Set("ProjectionHack", Hack->GetSelection(), wxCHK_UNDETERMINED); + if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Wii", "ProgressiveScan"); + else + GameIni.Set("Wii", "ProgressiveScan", EnableProgressiveScan->Get3StateValue()); - emustate.Set("EmulationStateId", EmuState->GetSelection()); - emustate.Set("EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent)); + if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Wii", "Widescreen"); + else + GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue()); + + if (ForceFiltering->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "ForceFiltering"); + else + GameIni.Set("Video", "ForceFiltering", ForceFiltering->Get3StateValue()); + + if (EFBCopyDisable->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "EFBCopyDisable"); + else + GameIni.Set("Video", "EFBCopyDisable", EFBCopyDisable->Get3StateValue()); + + if (EFBToTextureEnable->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "EFBToTextureEnable"); + else + GameIni.Set("Video", "EFBToTextureEnable", EFBToTextureEnable->Get3StateValue()); + + if (SafeTextureCache->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "SafeTextureCache"); + else + GameIni.Set("Video", "SafeTextureCache", SafeTextureCache->Get3StateValue()); + + if (DstAlphaPass->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "DstAlphaPass"); + else + GameIni.Set("Video", "DstAlphaPass", DstAlphaPass->Get3StateValue()); + + if (UseXFB->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "UseXFB"); + else + GameIni.Set("Video", "UseXFB", UseXFB->Get3StateValue()); + + if (BPHack->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Video", "FIFOBPHack"); + else + GameIni.Set("Video", "FIFOBPHack", BPHack->Get3StateValue()); + + if (Hack->GetSelection() == -1) + GameIni.DeleteKey("Video", "ProjectionHack"); + else + GameIni.Set("Video", "ProjectionHack", Hack->GetSelection()); + + if (EmuState->GetSelection() == -1) + GameIni.DeleteKey("EmuState", "EmulationStateId"); + else + GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection()); + + GameIni.Set("EmuState", "EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent)); PatchList_Save(); ActionReplayList_Save(); @@ -950,7 +1018,6 @@ void CISOProperties::PatchList_Load() void CISOProperties::PatchList_Save() { std::vector lines; - lines.clear(); u32 index = 0; for (std::vector::const_iterator onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it) { @@ -965,7 +1032,8 @@ void CISOProperties::PatchList_Save() } ++index; } - GameIni["OnFrame"].SetLines(lines); + GameIni.SetLines("OnFrame", lines); + lines.clear(); } void CISOProperties::PatchButtonClicked(wxCommandEvent& event) @@ -1036,7 +1104,7 @@ void CISOProperties::ActionReplayList_Save() } ++index; } - GameIni["ActionReplay"].SetLines(lines); + GameIni.SetLines("ActionReplay", lines); } void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event) diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp index 450b902367..c96daf99e3 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogWindow.cpp @@ -168,22 +168,16 @@ void CLogWindow::OnClose(wxCloseEvent& event) void CLogWindow::SaveSettings() { IniFile ini; - - Section& logwin = ini["LogWindow"]; - logwin.Set("x", Parent->m_Mgr->GetPane(wxT("Pane 1")).rect.GetWidth()); - logwin.Set("y", Parent->m_Mgr->GetPane(wxT("Pane 1")).rect.GetHeight()); - logwin.Set("pos", Parent->m_Mgr->GetPane(wxT("Pane 1")).dock_direction); - - Section& options = ini["Options"]; - options.Set("Verbosity", m_verbosity->GetSelection() + 1); - options.Set("Font", m_FontChoice->GetSelection()); - options.Set("WriteToFile", m_writeFile); - options.Set("WriteToConsole", m_writeConsole); - options.Set("WriteToWindow", m_writeWindow); - - Section& logs = ini["Logs"]; + ini.Set("LogWindow", "x", Parent->m_Mgr->GetPane(wxT("Pane 1")).rect.GetWidth()); + ini.Set("LogWindow", "y", Parent->m_Mgr->GetPane(wxT("Pane 1")).rect.GetHeight()); + ini.Set("LogWindow", "pos", Parent->m_Mgr->GetPane(wxT("Pane 1")).dock_direction); + ini.Set("Options", "Verbosity", m_verbosity->GetSelection() + 1); + ini.Set("Options", "Font", m_FontChoice->GetSelection()); + ini.Set("Options", "WriteToFile", m_writeFile); + ini.Set("Options", "WriteToConsole", m_writeConsole); + ini.Set("Options", "WriteToWindow", m_writeWindow); for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) - logs.Set(m_LogManager->getShortName((LogTypes::LOG_TYPE)i), m_checks->IsChecked(i)); + ini.Set("Logs", m_LogManager->getShortName((LogTypes::LOG_TYPE)i), m_checks->IsChecked(i)); ini.Save(File::GetUserPath(F_LOGGERCONFIG_IDX)); } @@ -191,28 +185,25 @@ void CLogWindow::LoadSettings() { IniFile ini; ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX)); - Section& options = ini["Options"]; int verbosity,font; - options.Get("Verbosity", &verbosity, 0); + ini.Get("Options", "Verbosity", &verbosity, 0); if (verbosity < 1) verbosity = 1; if (verbosity > MAX_LOGLEVEL) verbosity = MAX_LOGLEVEL; m_verbosity->SetSelection(verbosity - 1); - options.Get("Font", &font, 0); + ini.Get("Options", "Font", &font, 0); m_FontChoice->SetSelection(font); if (m_FontChoice->GetSelection() < (int)Font.size()) m_Log->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, Font.at(m_FontChoice->GetSelection()))); - options.Get("WriteToFile", &m_writeFile, true); + ini.Get("Options", "WriteToFile", &m_writeFile, true); m_writeFileCB->SetValue(m_writeFile); - options.Get("WriteToConsole", &m_writeConsole, true); + ini.Get("Options", "WriteToConsole", &m_writeConsole, true); m_writeConsoleCB->SetValue(m_writeConsole); - options.Get("WriteToWindow", &m_writeWindow, true); + ini.Get("Options", "WriteToWindow", &m_writeWindow, true); m_writeWindowCB->SetValue(m_writeWindow); - - Section& logs = ini["Logs"]; for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) { bool enable; - logs.Get(m_LogManager->getShortName((LogTypes::LOG_TYPE)i), &enable, true); + ini.Get("Logs", m_LogManager->getShortName((LogTypes::LOG_TYPE)i), &enable, true); if (m_writeWindow && enable) m_LogManager->addListener((LogTypes::LOG_TYPE)i, this); diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index ffc9c85aaa..16093e4a09 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -95,6 +95,7 @@ bool DolphinApp::OnInit() bool LoadElf = false; bool selectVideoPlugin = false; bool selectAudioPlugin = false; + bool selectPadPlugin = false; bool selectWiimotePlugin = false; wxString ElfFile; @@ -129,6 +130,10 @@ bool DolphinApp::OnInit() wxCMD_LINE_OPTION, "A", "audio_plugin","Specify an audio plugin", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { + wxCMD_LINE_OPTION, "P", "pad_plugin","Specify a pad plugin", + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL + }, { wxCMD_LINE_OPTION, "W", "wiimote_plugin","Specify a wiimote plugin", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL @@ -163,6 +168,10 @@ bool DolphinApp::OnInit() wxCMD_LINE_OPTION, _("A"), _("audio_plugin"), wxT("Specify an audio plugin"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { + wxCMD_LINE_OPTION, _("P"), _("pad_plugin"), wxT("Specify a pad plugin"), + wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL + }, { wxCMD_LINE_OPTION, _("W"), _("wiimote_plugin"), wxT("Specify a wiimote plugin"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL @@ -192,10 +201,12 @@ bool DolphinApp::OnInit() #if wxCHECK_VERSION(2, 9, 0) selectVideoPlugin = parser.Found("video_plugin", &videoPluginFilename); selectAudioPlugin = parser.Found("audio_plugin", &audioPluginFilename); + selectPadPlugin = parser.Found("pad_plugin", &padPluginFilename); selectWiimotePlugin = parser.Found("wiimote_plugin", &wiimotePluginFilename); #else selectVideoPlugin = parser.Found(_T("video_plugin"), &videoPluginFilename); selectAudioPlugin = parser.Found(_T("audio_plugin"), &audioPluginFilename); + selectPadPlugin = parser.Found(_T("pad_plugin"), &padPluginFilename); selectWiimotePlugin = parser.Found(_T("wiimote_plugin"), &wiimotePluginFilename); #endif #endif // wxUSE_CMDLINE_PARSER @@ -331,6 +342,7 @@ bool DolphinApp::OnInit() #endif LogManager::Init(); + EventHandler::Init(); SConfig::Init(); CPluginManager::Init(); @@ -342,6 +354,14 @@ bool DolphinApp::OnInit() SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin = std::string(audioPluginFilename.mb_str()); + if (selectPadPlugin && padPluginFilename != wxEmptyString) + { + int k; + for(k=0;k -#include "HW/GCPad.h" +#include "pluginspecs_pad.h" #include "svnrev.h" //#include diff --git a/Source/Core/DolphinWX/Src/SConscript b/Source/Core/DolphinWX/Src/SConscript index a4605c6886..c352f14f64 100644 --- a/Source/Core/DolphinWX/Src/SConscript +++ b/Source/Core/DolphinWX/Src/SConscript @@ -13,7 +13,7 @@ files = [ libs = [ 'core', 'lzo2', 'discio', 'bdisasm', 'videocommon', - 'inputuicommon', 'inputcommon', 'common', 'lua', 'z', 'sfml-network' + 'inputcommon', 'common', 'lua', 'z', 'sfml-network' ] if wxenv['HAVE_WX']: diff --git a/Source/Core/InputCommon/InputCommon.vcproj b/Source/Core/InputCommon/InputCommon.vcproj index 692a50b37b..eaa33a78ca 100644 --- a/Source/Core/InputCommon/InputCommon.vcproj +++ b/Source/Core/InputCommon/InputCommon.vcproj @@ -45,7 +45,7 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/Source/Core/InputCommon/Src/Configuration.cpp b/Source/Core/InputCommon/Src/Configuration.cpp index 7f4972ea11..c48e48d05f 100644 --- a/Source/Core/InputCommon/Src/Configuration.cpp +++ b/Source/Core/InputCommon/Src/Configuration.cpp @@ -18,10 +18,13 @@ #include // System #include -#define _USE_MATH_DEFINES -#include +#include #include "Common.h" // Common +#if defined HAVE_WX && HAVE_WX + #include +#endif + #ifdef _WIN32 #define NOMINMAX #include diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp index 98e199c24f..071a233887 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp @@ -2,7 +2,6 @@ #ifdef CIFACE_USE_DIRECTINPUT_KBM -#include #include "DirectInputKeyboardMouse.h" // TODO: maybe add a ClearInputState function to this device @@ -96,7 +95,7 @@ KeyboardMouse::KeyboardMouse( const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRE : m_kb_device(kb_device) , m_mo_device(mo_device) { - m_last_update = Common::Timer::GetLocalTimeSinceJan1970(); + m_last_update = wxGetLocalTimeMillis(); ZeroMemory( &m_state_in, sizeof(m_state_in) ); ZeroMemory( m_state_out, sizeof(m_state_out) ); @@ -134,7 +133,7 @@ bool KeyboardMouse::UpdateInput() DIMOUSESTATE2 tmp_mouse; // if mouse position hasn't been updated in a short while, skip a dev state - u64 cur_time = Common::Timer::GetLocalTimeSinceJan1970(); + wxLongLong cur_time = wxGetLocalTimeMillis(); if ( cur_time - m_last_update > DROP_INPUT_TIME ) { // set axes to zero @@ -179,7 +178,7 @@ bool KeyboardMouse::UpdateOutput() { bool want_on = false; if ( m_state_out[i] ) - want_on = m_state_out[i] > Common::Timer::GetLocalTimeSinceJan1970() % 255 ; // light should flash when output is 0.5 + want_on = m_state_out[i] > wxGetLocalTimeMillis() % 255 ; // light should flash when output is 0.5 // lights are set to their original state when output is zero if ( want_on ^ m_current_state_out[i] ) diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h index e57e8d7e97..6af5fb10d0 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h @@ -9,6 +9,8 @@ #include #include +#include +#include namespace ciface { @@ -111,7 +113,7 @@ private: const LPDIRECTINPUTDEVICE8 m_kb_device; const LPDIRECTINPUTDEVICE8 m_mo_device; - u64 m_last_update; + wxLongLong m_last_update; State m_state_in; unsigned char m_state_out[3]; // NUM CAPS SCROLL bool m_current_state_out[3]; // NUM CAPS SCROLL diff --git a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp index 61a7b724f6..a2b6c638c9 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp @@ -4,8 +4,6 @@ #include "XInput.h" -#pragma comment(lib, "xinput.lib") - namespace ciface { namespace XInput diff --git a/Source/Core/InputCommon/Src/DirectInputBase.cpp b/Source/Core/InputCommon/Src/DirectInputBase.cpp new file mode 100644 index 0000000000..b9a7fee33d --- /dev/null +++ b/Source/Core/InputCommon/Src/DirectInputBase.cpp @@ -0,0 +1,229 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + + +// Include +// ------------------- +#include "DirectInputBase.h" + + + +DInput::DInput() + : g_pDI(NULL), + g_pKeyboard(NULL) +{} + + +DInput::~DInput() +{ + Free(); +} + +void DInput::DIKToString(unsigned int keycode, char *keyStr) +{ + switch(keycode) { + case DIK_RETURN: + sprintf(keyStr, "Enter"); + break; + case DIK_LCONTROL: + sprintf(keyStr, "Left Ctrl"); + break; + case DIK_RCONTROL: + strcpy(keyStr, "Right Ctrl"); + break; + case DIK_LSHIFT: + sprintf(keyStr, "Left Shift"); + break; + case DIK_RSHIFT: + sprintf(keyStr, "Right Shift"); + break; + case DIK_LMENU: + sprintf(keyStr, "Left Alt"); + break; + case DIK_RMENU: + strcpy(keyStr, "Right Alt"); + break; + case DIK_UP: + sprintf(keyStr, "Up"); + break; + case DIK_DOWN: + sprintf(keyStr, "Down"); + break; + case DIK_LEFT: + sprintf(keyStr, "Left"); + break; + case DIK_RIGHT: + sprintf(keyStr, "Right"); + break; + case DIK_HOME: + strcpy(keyStr, "Home"); + break; + case DIK_END: + strcpy(keyStr, "End"); + break; + case DIK_INSERT: + strcpy(keyStr, "Ins"); + break; + case DIK_DELETE: + strcpy(keyStr, "Del"); + break; + case DIK_PGUP: + strcpy(keyStr, "PgUp"); + break; + case DIK_PGDN: + strcpy(keyStr, "PgDn"); + break; + case DIK_NUMLOCK: + strcpy(keyStr, "Num Lock"); + break; + case DIK_NUMPAD0: + strcpy(keyStr, "Num 0"); + break; + case DIK_NUMPAD1: + strcpy(keyStr, "Num 1"); + break; + case DIK_NUMPAD2: + strcpy(keyStr, "Num 2"); + break; + case DIK_NUMPAD3: + strcpy(keyStr, "Num 3"); + break; + case DIK_NUMPAD4: + strcpy(keyStr, "Num 4"); + break; + case DIK_NUMPAD5: + strcpy(keyStr, "Num 5"); + break; + case DIK_NUMPAD6: + strcpy(keyStr, "Num 6"); + break; + case DIK_NUMPAD7: + strcpy(keyStr, "Num 7"); + break; + case DIK_NUMPAD8: + strcpy(keyStr, "Num 8"); + break; + case DIK_NUMPAD9: + strcpy(keyStr, "Num 9"); + break; + case DIK_DIVIDE: + strcpy(keyStr, "Num /"); + break; + case DIK_NUMPADENTER: + strcpy(keyStr, "Num Enter"); + break; + case DIK_DECIMAL: + strcpy(keyStr, "Num Decimal"); + break; + case DIK_NUMPADCOMMA: + case DIK_ABNT_C2: + strcpy(keyStr, "Num Separator"); + break; + case DIK_NUMPADEQUALS: + strcpy(keyStr, "Num ="); + break; + default: + // TODO: Switch to unicode GetKeyNameText? + GetKeyNameTextA(keycode << 16, keyStr, 64); + break; + } +} + +HRESULT DInput::Init(HWND hWnd) +{ + HRESULT hr; + DWORD dwCoopFlags; + dwCoopFlags = DISCL_FOREGROUND | DISCL_NOWINKEY; + + // Create a DInput object + if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, + IID_IDirectInput8, (VOID* *)&g_pDI, NULL))) + { + MessageBox(0, L"Direct Input Create Failed", 0, MB_ICONERROR); + return(hr); + } + + if (FAILED(hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL))) + { + MessageBox(0, L"Couldn't access keyboard", 0, MB_ICONERROR); + Free(); + return(hr); + } + + g_pKeyboard->SetDataFormat(&c_dfDIKeyboard); + g_pKeyboard->SetCooperativeLevel(hWnd, dwCoopFlags); + g_pKeyboard->Acquire(); + + return(S_OK); +} + +void DInput::Free() +{ + if (g_pKeyboard) + { + g_pKeyboard->Unacquire(); + g_pKeyboard->Release(); + g_pKeyboard = 0; + } + + if (g_pDI) + { + g_pDI->Release(); + g_pDI = 0; + } +} + +// Desc: Read the input device's state when in immediate mode and display it. +HRESULT DInput::Read() +{ + HRESULT hr; + + if (NULL == g_pKeyboard) + { + return(S_OK); + } + + // Get the input's device state, and put the state in dims + ZeroMemory(diks, sizeof(diks)); + hr = g_pKeyboard->GetDeviceState(sizeof(diks), diks); + + //for (int i=0; i<256; i++) + // if (diks[i]) MessageBox(0,"DSFJDKSF|",0,0); + if (FAILED(hr)) + { + // DirectInput may be telling us that the input stream has been + // interrupted. We aren't tracking any state between polls, so + // we don't have any special reset that needs to be done. + // We just re-acquire and try again. + + // If input is lost then acquire and keep trying + hr = g_pKeyboard->Acquire(); + + while (hr == DIERR_INPUTLOST) + { + hr = g_pKeyboard->Acquire(); + } + + // hr may be DIERR_OTHERAPPHASPRIO or other errors. This + // may occur when the app is minimized or in the process of + // switching, so just try again later + return(S_OK); + } + + return(S_OK); +} diff --git a/Source/Core/InputCommon/Src/DirectInputBase.h b/Source/Core/InputCommon/Src/DirectInputBase.h new file mode 100644 index 0000000000..22f7fb5d2e --- /dev/null +++ b/Source/Core/InputCommon/Src/DirectInputBase.h @@ -0,0 +1,53 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _DIRECTINPUTBASE_H +#define _DIRECTINPUTBASE_H + + +#include // System +#include + +#define DIRECTINPUT_VERSION 0x0800 // DirectInput +#include + + + +class DInput +{ + public: + + DInput(); + ~DInput(); + + static void DInput::DIKToString(unsigned int keycode, char *keyStr); + + HRESULT Init(HWND hWnd); + void Free(); + HRESULT Read(); + + + BYTE diks[256]; // DirectInput keyboard state buffer + + private: + + LPDIRECTINPUT8 g_pDI; // The DirectInput object + LPDIRECTINPUTDEVICE8 g_pKeyboard; // The keyboard device +}; + +#endif + diff --git a/Source/Core/InputCommon/Src/Event.hpp b/Source/Core/InputCommon/Src/Event.hpp new file mode 100755 index 0000000000..7f84265c3d --- /dev/null +++ b/Source/Core/InputCommon/Src/Event.hpp @@ -0,0 +1,264 @@ +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +#ifndef SFML_EVENT_HPP +#define SFML_EVENT_HPP + + +namespace sf +{ + namespace Key + { + enum Code + { + A = 'a', + B = 'b', + C = 'c', + D = 'd', + E = 'e', + F = 'f', + G = 'g', + H = 'h', + I = 'i', + J = 'j', + K = 'k', + L = 'l', + M = 'm', + N = 'n', + O = 'o', + P = 'p', + Q = 'q', + R = 'r', + S = 's', + T = 't', + U = 'u', + V = 'v', + W = 'w', + X = 'x', + Y = 'y', + Z = 'z', + Num0 = '0', + Num1 = '1', + Num2 = '2', + Num3 = '3', + Num4 = '4', + Num5 = '5', + Num6 = '6', + Num7 = '7', + Num8 = '8', + Num9 = '9', + Escape = 256, + LControl, + LShift, + LAlt, + LSystem, + RControl, + RShift, + RAlt, + RSystem, + Menu, + LBracket, + RBracket, + SemiColon, + Comma, + Period, + Quote, + Slash, + BackSlash, + Tilde, + Equal, + Dash, + Space, + Return, + Back, + Tab, + PageUp, + PageDown, + End, + Home, + Insert, + Delete, + Add, + Subtract, + Multiply, + Divide, + Left, + Right, + Up, + Down, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + Pause, + + Count // For internal use + }; + } + + + namespace Mouse + { + enum Button + { + Left, + Right, + Middle, + XButton1, + XButton2, + + Count // For internal use + }; + } + + + namespace Joy + { + enum Axis + { + AxisX, + AxisY, + AxisZ, + AxisR, + AxisU, + AxisV, + AxisPOV, + + Count // For internal use + }; + } + + + class Event + { + public : + + struct KeyEvent + { + Key::Code Code; + bool Alt; + bool Control; + bool Shift; + }; + + struct TextEvent + { + // I'm not sure we need this... + unsigned short Unicode; + }; + + struct MouseMoveEvent + { + int X; + int Y; + }; + + struct MouseButtonEvent + { + Mouse::Button Button; + int X; + int Y; + }; + + struct MouseWheelEvent + { + int Delta; + }; + + struct JoyMoveEvent + { + unsigned int JoystickId; + Joy::Axis Axis; + float Position; + }; + + struct JoyButtonEvent + { + unsigned int JoystickId; + unsigned int Button; + }; + + struct SizeEvent + { + unsigned int Width; + unsigned int Height; + }; + + enum EventType + { + Closed, + Resized, + LostFocus, + GainedFocus, + TextEntered, + KeyPressed, + KeyReleased, + MouseWheelMoved, + MouseButtonPressed, + MouseButtonReleased, + MouseMoved, + MouseEntered, + MouseLeft, + JoyButtonPressed, + JoyButtonReleased, + JoyMoved + }; + + // Member data + EventType Type; + + union + { + KeyEvent Key; + TextEvent Text; + MouseMoveEvent MouseMove; + MouseButtonEvent MouseButton; + MouseWheelEvent MouseWheel; + JoyMoveEvent JoyMove; + JoyButtonEvent JoyButton; + SizeEvent Size; + }; + }; + +} // namespace sf + + +#endif // SFML_EVENT_HPP diff --git a/Source/Core/InputCommon/Src/EventHandler.cpp b/Source/Core/InputCommon/Src/EventHandler.cpp new file mode 100644 index 0000000000..19dc819baf --- /dev/null +++ b/Source/Core/InputCommon/Src/EventHandler.cpp @@ -0,0 +1,318 @@ +#include "EventHandler.h" +#include +#include + +#if defined HAVE_WX && HAVE_WX +#include +#endif + +EventHandler *EventHandler::m_Instance = 0; + +EventHandler::EventHandler() { + memset(keys, 0, sizeof(keys)); + memset(mouse, 0, sizeof(mouse)); + memset(joys, 0, sizeof(joys)); +} + +EventHandler::~EventHandler() { +} + +EventHandler *EventHandler::GetInstance() { + // fprintf(stderr, "handler instance %p\n", m_Instance); + return m_Instance; +} + +void EventHandler::Init() +{ + m_Instance = new EventHandler(); +} + +void EventHandler::Shutdown() { + if (m_Instance) + delete m_Instance; + // fprintf(stderr, "deleting instance %p\n", m_Instance); + m_Instance = 0; +} + +bool EventHandler::RegisterEventListener(listenFuncPtr func, Keys key) { + if (key.inputType == KeyboardInput) { + // fprintf(stderr, "Registering %d:%d %p %p \n", key.keyCode, key.mods, func, this); + if (key.keyCode == sf::Key::Count || key.mods >= NUMMODS || + key.keyCode >= NUMKEYS) + return false; + if (keys[key.keyCode][key.mods] && keys[key.keyCode][key.mods] != func) + return false +; + keys[key.keyCode][key.mods] = func; + } else if (key.inputType == MouseInput) { + if (mouse[key.mouseButton]) + return false; + mouse[key.mouseButton] = func; + } + + return true; +} + +bool EventHandler::RemoveEventListener(Keys key) { + if (key.inputType == KeyboardInput) { + if ((key.keyCode == sf::Key::Count || key.keyCode >= NUMKEYS + || key.mods >= NUMMODS) && ! keys[key.keyCode][key.mods]) + return false; + keys[key.keyCode][key.mods] = NULL; + } else if (key.inputType == MouseInput) { + if (! mouse[key.mouseButton]) + return false; + mouse[key.mouseButton] = NULL; + } + + return true; +} + +void EventHandler::Update() { + for (unsigned int i = 0; i < eventQueue.size();i++) { + sf::Event ev = eventQueue.front(); + eventQueue.pop(); + fprintf(stderr, "Updating event type %d code %d mod %d func %p %p\n", ev.Type, ev.Key.Code, ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control, keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control], this); + if(keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control]) + keys[ev.Key.Code][ev.Key.Alt+2*ev.Key.Shift+4*ev.Key.Control](ev); + } +} + +bool EventHandler::addEvent(sf::Event *ev) { + eventQueue.push(*ev); + fprintf(stderr, "Got event type %d code %d %p\n", ev->Type, ev->Key.Code, this); + return true; +} + + +bool EventHandler::TestEvent (Keys k, sf::Event e) +{ + //Mouse event + if (k.inputType==MouseInput && k.eventType==e.Type && k.mouseButton==e.MouseButton.Button) + { + return (true); + } + //Keyboard event + if (k.inputType==KeyboardInput && k.eventType==e.Type && k.keyCode==e.Key.Code) + { + return (true); + } + return (false); +} + +#if defined HAVE_WX && HAVE_WX +// Taken from wxw source code +sf::Key::Code EventHandler::wxCharCodeToSF(int id) +{ + sf::Key::Code sfKey; + + switch (id) { +// case WXK_CANCEL: sfKey = sf::Key::Cancel; break; +// case WXK_BACK: sfKey = sf::Key::BackSpace; break; + case WXK_TAB: sfKey = sf::Key::Tab; break; +// case WXK_CLEAR: sfKey = sf::Key::Clear; break; + case WXK_RETURN: sfKey = sf::Key::Return; break; + case WXK_SHIFT: sfKey = sf::Key::LShift; break; + case WXK_CONTROL: sfKey = sf::Key::LControl; break; + case WXK_ALT: sfKey = sf::Key::LAlt; break; +// case WXK_CAPITAL: sfKey = sf::Key::Caps_Lock; break; + case WXK_MENU : sfKey = sf::Key::Menu; break; + case WXK_PAUSE: sfKey = sf::Key::Pause; break; + case WXK_ESCAPE: sfKey = sf::Key::Escape; break; + case WXK_SPACE: sfKey = sf::Key::Space; break; + case WXK_PAGEUP: sfKey = sf::Key::PageUp; break; + case WXK_PAGEDOWN: sfKey = sf::Key::PageDown; break; + case WXK_END: sfKey = sf::Key::End; break; + case WXK_HOME : sfKey = sf::Key::Home; break; + case WXK_LEFT : sfKey = sf::Key::Left; break; + case WXK_UP: sfKey = sf::Key::Up; break; + case WXK_RIGHT: sfKey = sf::Key::Right; break; + case WXK_DOWN : sfKey = sf::Key::Down; break; +// case WXK_SELECT: sfKey = sf::Key::Select; break; +// case WXK_PRINT: sfKey = sf::Key::Print; break; +// case WXK_EXECUTE: sfKey = sf::Key::Execute; break; + case WXK_INSERT: sfKey = sf::Key::Insert; break; + case WXK_DELETE: sfKey = sf::Key::Delete; break; +// case WXK_HELP : sfKey = sf::Key::Help; break; + case WXK_NUMPAD0: sfKey = sf::Key::Numpad0; break; + case WXK_NUMPAD_INSERT: sfKey = sf::Key::Insert; break; + case WXK_NUMPAD1: sfKey = sf::Key::Numpad1; break; + case WXK_NUMPAD_END: sfKey = sf::Key::End; break; + case WXK_NUMPAD2: sfKey = sf::Key::Numpad2; break; + case WXK_NUMPAD_DOWN: sfKey = sf::Key::Down; break; + case WXK_NUMPAD3: sfKey = sf::Key::Numpad3; break; + case WXK_NUMPAD_PAGEDOWN: sfKey = sf::Key::PageDown; break; + case WXK_NUMPAD4: sfKey = sf::Key::Numpad4; break; + case WXK_NUMPAD_LEFT: sfKey = sf::Key::Left; break; + case WXK_NUMPAD5: sfKey = sf::Key::Numpad5; break; + case WXK_NUMPAD6: sfKey = sf::Key::Numpad6; break; + case WXK_NUMPAD_RIGHT: sfKey = sf::Key::Right; break; + case WXK_NUMPAD7: sfKey = sf::Key::Numpad7; break; + case WXK_NUMPAD_HOME: sfKey = sf::Key::Home; break; + case WXK_NUMPAD8: sfKey = sf::Key::Numpad8; break; + case WXK_NUMPAD_UP: sfKey = sf::Key::Up; break; + case WXK_NUMPAD9: sfKey = sf::Key::Numpad9; break; + case WXK_NUMPAD_PAGEUP: sfKey = sf::Key::PageUp; break; +// case WXK_NUMPAD_DECIMAL: sfKey = sf::Key::Decimal; break; + case WXK_NUMPAD_DELETE: sfKey = sf::Key::Delete; break; + case WXK_NUMPAD_MULTIPLY: sfKey = sf::Key::Multiply; break; + case WXK_NUMPAD_ADD: sfKey = sf::Key::Add; break; + case WXK_NUMPAD_SUBTRACT: sfKey = sf::Key::Subtract; break; + case WXK_NUMPAD_DIVIDE: sfKey = sf::Key::Divide; break; + case WXK_NUMPAD_ENTER: sfKey = sf::Key::Return; break; +// case WXK_NUMPAD_SEPARATOR:sfKey = sf::Key::Separator; break; + case WXK_F1: sfKey = sf::Key::F1; break; + case WXK_F2: sfKey = sf::Key::F2; break; + case WXK_F3: sfKey = sf::Key::F3; break; + case WXK_F4: sfKey = sf::Key::F4; break; + case WXK_F5: sfKey = sf::Key::F5; break; + case WXK_F6: sfKey = sf::Key::F6; break; + case WXK_F7: sfKey = sf::Key::F7; break; + case WXK_F8: sfKey = sf::Key::F8; break; + case WXK_F9: sfKey = sf::Key::F9; break; + case WXK_F10: sfKey = sf::Key::F10; break; + case WXK_F11: sfKey = sf::Key::F11; break; + case WXK_F12: sfKey = sf::Key::F12; break; + case WXK_F13: sfKey = sf::Key::F13; break; + case WXK_F14: sfKey = sf::Key::F14; break; + case WXK_F15: sfKey = sf::Key::F15; break; +// case WXK_NUMLOCK: sfKey = sf::Key::Num_Lock; break; +// case WXK_SCROLL: sfKey = sf::Key::Scroll_Lock; break; + default: + + // To lower (will tolower work on windows?) + if (id >= 'A' && id <= 'Z') + id = id - 'A' + 'a'; + + if ((id >= 'a' && id <= 'z') || + (id >= '0' && id <= '9')) + sfKey = (sf::Key::Code)id; + else + sfKey = sf::Key::Count; // Invalid key + + } + + return sfKey; +} +#endif + +void EventHandler::SFKeyToString(sf::Key::Code keycode, char *keyStr) { + switch (keycode) { +/* case sf::Key::A = 'a': sprintf(keyStr, "UP"); break; + case sf::Key::B = 'b': sprintf(keyStr, "UP"); break; + case sf::Key::C = 'c': sprintf(keyStr, "UP"); break; + case sf::Key::D = 'd': sprintf(keyStr, "UP"); break; + case sf::Key::E = 'e': sprintf(keyStr, "UP"); break; + case sf::Key::F = 'f': sprintf(keyStr, "UP"); break; + case sf::Key::G = 'g': sprintf(keyStr, "UP"); break; + case sf::Key::H = 'h': sprintf(keyStr, "UP"); break; + case sf::Key::I = 'i': sprintf(keyStr, "UP"); break; + case sf::Key::J = 'j': sprintf(keyStr, "UP"); break; + case sf::Key::K = 'k': sprintf(keyStr, "UP"); break; + case sf::Key::L = 'l': sprintf(keyStr, "UP"); break; + case sf::Key::M = 'm': sprintf(keyStr, "UP"); break; + case sf::Key::N = 'n': sprintf(keyStr, "UP"); break; + case sf::Key::O = 'o': sprintf(keyStr, "UP"); break; + case sf::Key::P = 'p': sprintf(keyStr, "UP"); break; + case sf::Key::Q = 'q': sprintf(keyStr, "UP"); break; + case sf::Key::R = 'r': sprintf(keyStr, "UP"); break; + case sf::Key::S = 's': sprintf(keyStr, "UP"); break; + case sf::Key::T = 't': sprintf(keyStr, "UP"); break; + case sf::Key::U = 'u': sprintf(keyStr, "UP"); break; + case sf::Key::V = 'v': sprintf(keyStr, "UP"); break; + case sf::Key::W = 'w': sprintf(keyStr, "UP"); break; + case sf::Key::X = 'x': sprintf(keyStr, "UP"); break; + case sf::Key::Y = 'y': sprintf(keyStr, "UP"); break; + case sf::Key::Z = 'z': sprintf(keyStr, "UP"); break; + case sf::Key::Num0 = '0': sprintf(keyStr, "UP"); break; + case sf::Key::Num1 = '1': sprintf(keyStr, "UP"); break; + case sf::Key::Num2 = '2': sprintf(keyStr, "UP"); break; + case sf::Key::Num3 = '3': sprintf(keyStr, "UP"); break; + case sf::Key::Num4 = '4': sprintf(keyStr, "UP"); break; + case sf::Key::Num5 = '5': sprintf(keyStr, "UP"); break; + case sf::Key::Num6 = '6': sprintf(keyStr, "UP"); break; + case sf::Key::Num7 = '7': sprintf(keyStr, "UP"); break; + case sf::Key::Num8 = '8': sprintf(keyStr, "UP"); break; + case sf::Key::Num9 = '9': sprintf(keyStr, "UP"); break;*/ + case sf::Key::Escape: sprintf(keyStr, "Escape"); break; + case sf::Key::LControl: sprintf(keyStr, "LControl"); break; + case sf::Key::LShift: sprintf(keyStr, "LShift"); break; + case sf::Key::LAlt: sprintf(keyStr, "LAlt"); break; + case sf::Key::LSystem: sprintf(keyStr, "LSystem"); break; + case sf::Key::RControl: sprintf(keyStr, "RControl"); break; + case sf::Key::RShift: sprintf(keyStr, "RShift"); break; + case sf::Key::RAlt: sprintf(keyStr, "RAlt"); break; + case sf::Key::RSystem: sprintf(keyStr, "RSystem"); break; + case sf::Key::Menu: sprintf(keyStr, "Menu"); break; + case sf::Key::LBracket: sprintf(keyStr, "LBracket"); break; + case sf::Key::RBracket: sprintf(keyStr, "RBracket"); break; + case sf::Key::SemiColon: sprintf(keyStr, ";"); break; + case sf::Key::Comma: sprintf(keyStr, ","); break; + case sf::Key::Period: sprintf(keyStr, "."); break; + case sf::Key::Quote: sprintf(keyStr, "\'"); break; + case sf::Key::Slash: sprintf(keyStr, "/"); break; + case sf::Key::BackSlash: sprintf(keyStr, "\\"); break; + case sf::Key::Tilde: sprintf(keyStr, "~"); break; + case sf::Key::Equal: sprintf(keyStr, "="); break; + case sf::Key::Dash: sprintf(keyStr, "-"); break; + case sf::Key::Space: sprintf(keyStr, "Space"); break; + case sf::Key::Return: sprintf(keyStr, "Return"); break; + case sf::Key::Back: sprintf(keyStr, "Back"); break; + case sf::Key::Tab: sprintf(keyStr, "Tab"); break; + case sf::Key::PageUp: sprintf(keyStr, "Page Up"); break; + case sf::Key::PageDown: sprintf(keyStr, "Page Down"); break; + case sf::Key::End: sprintf(keyStr, "End"); break; + case sf::Key::Home: sprintf(keyStr, "Home"); break; + case sf::Key::Insert: sprintf(keyStr, "Insert"); break; + case sf::Key::Delete: sprintf(keyStr, "Delete"); break; + case sf::Key::Add: sprintf(keyStr, "+"); break; + case sf::Key::Subtract: sprintf(keyStr, "-"); break; + case sf::Key::Multiply: sprintf(keyStr, "*"); break; + case sf::Key::Divide: sprintf(keyStr, "/"); break; + case sf::Key::Left: sprintf(keyStr, "Left"); break; + case sf::Key::Right: sprintf(keyStr, "Right"); break; + case sf::Key::Up: sprintf(keyStr, "Up"); break; + case sf::Key::Down: sprintf(keyStr, "Down"); break; + case sf::Key::Numpad0: sprintf(keyStr, "NP 0"); break; + case sf::Key::Numpad1: sprintf(keyStr, "NP 1"); break; + case sf::Key::Numpad2: sprintf(keyStr, "NP 2"); break; + case sf::Key::Numpad3: sprintf(keyStr, "NP 3"); break; + case sf::Key::Numpad4: sprintf(keyStr, "NP 4"); break; + case sf::Key::Numpad5: sprintf(keyStr, "NP 5"); break; + case sf::Key::Numpad6: sprintf(keyStr, "NP 6"); break; + case sf::Key::Numpad7: sprintf(keyStr, "NP 7"); break; + case sf::Key::Numpad8: sprintf(keyStr, "NP 8"); break; + case sf::Key::Numpad9: sprintf(keyStr, "NP 9"); break; + case sf::Key::F1: sprintf(keyStr, "F1"); break; + case sf::Key::F2: sprintf(keyStr, "F2"); break; + case sf::Key::F3: sprintf(keyStr, "F3"); break; + case sf::Key::F4: sprintf(keyStr, "F4"); break; + case sf::Key::F5: sprintf(keyStr, "F5"); break; + case sf::Key::F6: sprintf(keyStr, "F6"); break; + case sf::Key::F7: sprintf(keyStr, "F7"); break; + case sf::Key::F8: sprintf(keyStr, "F8"); break; + case sf::Key::F9: sprintf(keyStr, "F9"); break; + case sf::Key::F10: sprintf(keyStr, "F10"); break; + case sf::Key::F11: sprintf(keyStr, "F11"); break; + case sf::Key::F12: sprintf(keyStr, "F12"); break; + case sf::Key::F13: sprintf(keyStr, "F13"); break; + case sf::Key::F14: sprintf(keyStr, "F14"); break; + case sf::Key::F15: sprintf(keyStr, "F15"); break; + case sf::Key::Pause: sprintf(keyStr, "Pause"); break; + default: + if (keycode > sf::Key::Escape) + sprintf(keyStr, "Invalid Key"); + else + sprintf(keyStr, "%c", toupper(keycode)); + break; + } +} + +class EventHandlerCleaner +{ +public: + ~EventHandlerCleaner() + { + //EventHandler::Destroy(); + } +} EventHandlerCleanerInst; diff --git a/Source/Core/InputCommon/Src/EventHandler.h b/Source/Core/InputCommon/Src/EventHandler.h new file mode 100644 index 0000000000..bde6bbf430 --- /dev/null +++ b/Source/Core/InputCommon/Src/EventHandler.h @@ -0,0 +1,64 @@ +#ifndef EVENTHANDER_H +#define EVENTHANDER_H 1 +#include "Common.h" +#include +#include "Event.hpp" + +#define NUMKEYS 300 +#define NUMMODS 8 + +typedef bool (*listenFuncPtr) (sf::Event); +enum InputType +{ + KeyboardInput, + MouseInput, + JoystickInput +}; + +enum Modifiers { + UseAlt = 1, + UseShift = 2, + UseCtrl = 4 +}; + +struct Keys { + InputType inputType; + sf::Event::EventType eventType; + sf::Key::Code keyCode; + int mods; + sf::Mouse::Button mouseButton; +}; + +class EventHandler { + +private: + listenFuncPtr keys[NUMKEYS][NUMMODS]; + listenFuncPtr mouse[sf::Mouse::Count+1]; + listenFuncPtr joys[sf::Joy::Count+1]; + std::queue eventQueue; + static EventHandler *m_Instance; + +protected: + EventHandler(const EventHandler&); + EventHandler& operator= (const EventHandler&); + + EventHandler(); + ~EventHandler(); + +public: + + bool RegisterEventListener(listenFuncPtr func, Keys key); + bool RemoveEventListener(Keys key); + void Update(); + static EventHandler *GetInstance(); + static void Init(); + static void Shutdown(); + bool addEvent(sf::Event *e); + static bool TestEvent (Keys k, sf::Event e); +#if defined HAVE_WX && HAVE_WX + static sf::Key::Code wxCharCodeToSF(int id); +#endif + static void SFKeyToString(sf::Key::Code keycode, char *keyStr); +}; + +#endif diff --git a/Source/Core/InputCommon/Src/InputCommon.cpp b/Source/Core/InputCommon/Src/InputCommon.cpp new file mode 100644 index 0000000000..beed506f8e --- /dev/null +++ b/Source/Core/InputCommon/Src/InputCommon.cpp @@ -0,0 +1,16 @@ +#include "EventHandler.h" + +//EventHandler *eventHandler = NULL; + +namespace InputCommon +{ + void Init() { + // init the event handler + //EventHandler::GetInstance(); + } + + void Shutdown() { + //if (eventHandler) + // delete eventHandler; + } +} diff --git a/Source/Core/InputCommon/Src/InputCommon.h b/Source/Core/InputCommon/Src/InputCommon.h index 52b75e0f0f..5b930fb217 100644 --- a/Source/Core/InputCommon/Src/InputCommon.h +++ b/Source/Core/InputCommon/Src/InputCommon.h @@ -1,3 +1,7 @@ +#include "EventHandler.h" + +//extern EventHandler *eventHandler; + namespace InputCommon { enum EButtonType @@ -20,4 +24,6 @@ enum EXInputTrigger XI_TRIGGER_R, }; + void Init(); + void Shutdown(); } diff --git a/Source/Core/InputCommon/Src/SConscript b/Source/Core/InputCommon/Src/SConscript index 59796940d7..d80a43f3c3 100644 --- a/Source/Core/InputCommon/Src/SConscript +++ b/Source/Core/InputCommon/Src/SConscript @@ -5,8 +5,8 @@ icenv = env.Clone() files = [ 'Configuration.cpp', - 'InputConfig.cpp', - 'ControllerEmu.cpp', + 'EventHandler.cpp', + 'InputCommon.cpp', 'SDL_Util.cpp', 'ControllerInterface/ControllerInterface.cpp', ] @@ -16,6 +16,11 @@ if env['HAVE_X11']: "X11InputBase.cpp", ] +if env['HAVE_WX']: + files += [ + "WXInputBase.cpp", + ] + if icenv['HAVE_SDL']: files += [ 'ControllerInterface/SDL/SDL.cpp' diff --git a/Source/Plugins/InputUICommon/Src/WXInputBase.cpp b/Source/Core/InputCommon/Src/WXInputBase.cpp similarity index 97% rename from Source/Plugins/InputUICommon/Src/WXInputBase.cpp rename to Source/Core/InputCommon/Src/WXInputBase.cpp index 7067d3fd27..f89f813e97 100644 --- a/Source/Plugins/InputUICommon/Src/WXInputBase.cpp +++ b/Source/Core/InputCommon/Src/WXInputBase.cpp @@ -1,127 +1,127 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include -#include "WXInputBase.h" -//#include -//#include -//#include - -namespace InputCommon -{ - -const wxChar *WXKeyToString(int keycode) -{ - switch (keycode) - { - case WXK_CANCEL: return wxT("Cancel"); break; - case WXK_BACK: return wxT("Back"); break; - case WXK_TAB: return wxT("Tab"); break; - case WXK_CLEAR: return wxT("Clear"); break; - case WXK_RETURN: return wxT("Return"); break; - case WXK_SHIFT: return wxT("Shift"); break; - case WXK_CONTROL: return wxT("Control"); break; - case WXK_ALT: return wxT("Alt"); break; - case WXK_CAPITAL: return wxT("CapsLock"); break; - case WXK_MENU : return wxT("Menu"); break; - case WXK_PAUSE: return wxT("Pause"); break; - case WXK_ESCAPE: return wxT("Escape"); break; - case WXK_SPACE: return wxT("Space"); break; - case WXK_PAGEUP: return wxT("PgUp"); break; - case WXK_PAGEDOWN: return wxT("PgDn"); break; - case WXK_END: return wxT("End"); break; - case WXK_HOME : return wxT("Home"); break; - case WXK_LEFT : return wxT("Left"); break; - case WXK_UP: return wxT("Up"); break; - case WXK_RIGHT: return wxT("Right"); break; - case WXK_DOWN : return wxT("Down"); break; - case WXK_SELECT: return wxT("Select"); break; - case WXK_PRINT: return wxT("Print"); break; - case WXK_EXECUTE: return wxT("Execute"); break; - case WXK_INSERT: return wxT("Insert"); break; - case WXK_DELETE: return wxT("Delete"); break; - case WXK_HELP : return wxT("Help"); break; - case WXK_NUMPAD0: return wxT("NP 0"); break; - case WXK_NUMPAD1: return wxT("NP 1"); break; - case WXK_NUMPAD2: return wxT("NP 2"); break; - case WXK_NUMPAD3: return wxT("NP 3"); break; - case WXK_NUMPAD4: return wxT("NP 4"); break; - case WXK_NUMPAD5: return wxT("NP 5"); break; - case WXK_NUMPAD6: return wxT("NP 6"); break; - case WXK_NUMPAD7: return wxT("NP 7"); break; - case WXK_NUMPAD8: return wxT("NP 8"); break; - case WXK_NUMPAD9: return wxT("NP 9"); break; - case WXK_NUMPAD_DECIMAL: return wxT("NP ."); break; - case WXK_NUMPAD_DELETE: return wxT("NP Delete"); break; - case WXK_NUMPAD_INSERT: return wxT("NP Insert"); break; - case WXK_NUMPAD_END: return wxT("NP End"); break; - case WXK_NUMPAD_DOWN: return wxT("NP Down"); break; - case WXK_NUMPAD_PAGEDOWN: return wxT("NP Pagedown"); break; - case WXK_NUMPAD_LEFT: return wxT("NP Left"); break; - case WXK_NUMPAD_RIGHT: return wxT("NP Right"); break; - case WXK_NUMPAD_HOME: return wxT("NP Home"); break; - case WXK_NUMPAD_UP: return wxT("NP Up"); break; - case WXK_NUMPAD_PAGEUP: return wxT("NP Pageup"); break; - case WXK_NUMPAD_MULTIPLY: return wxT("NP *"); break; - case WXK_NUMPAD_ADD: return wxT("NP +"); break; - case WXK_NUMPAD_SUBTRACT: return wxT("NP -"); break; - case WXK_NUMPAD_DIVIDE: return wxT("NP /"); break; - case WXK_NUMPAD_ENTER: return wxT("NP Enter"); break; - case WXK_NUMPAD_SEPARATOR: return wxT("NP Separator"); break; - case WXK_F1: return wxT("F1"); break; - case WXK_F2: return wxT("F2"); break; - case WXK_F3: return wxT("F3"); break; - case WXK_F4: return wxT("F4"); break; - case WXK_F5: return wxT("F5"); break; - case WXK_F6: return wxT("F6"); break; - case WXK_F7: return wxT("F7"); break; - case WXK_F8: return wxT("F8"); break; - case WXK_F9: return wxT("F9"); break; - case WXK_F10: return wxT("F10"); break; - case WXK_F11: return wxT("F11"); break; - case WXK_F12: return wxT("F12"); break; - case WXK_F13: return wxT("F13"); break; - case WXK_F14: return wxT("F14"); break; - case WXK_F15: return wxT("F15"); break; - case WXK_F16: return wxT("F16"); break; - case WXK_F17: return wxT("F17"); break; - case WXK_F18: return wxT("F19"); break; - case WXK_F19: return wxT("F20"); break; - case WXK_F20: return wxT("F21"); break; - case WXK_F21: return wxT("F22"); break; - case WXK_F22: return wxT("F23"); break; - case WXK_F23: return wxT("F24"); break; - case WXK_F24: return wxT("F25"); break; - case WXK_NUMLOCK: return wxT("Numlock"); break; - case WXK_SCROLL: return wxT("Scrolllock"); break; - default: return wxString::FromAscii(keycode); - } -} - -const wxChar *WXKeymodToString(int modifier) -{ - switch (modifier) - { - case wxMOD_ALT: return wxT("Alt"); break; - case wxMOD_CMD: return wxT("Ctrl"); break; - case wxMOD_ALTGR: return wxT("Ctrl+Alt"); break; - case wxMOD_SHIFT: return wxT("Shift"); break; - default: return wxT(""); break; - } -} - -} +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include "WXInputBase.h" +//#include +//#include +//#include + +namespace InputCommon +{ + +const wxChar *WXKeyToString(int keycode) +{ + switch (keycode) + { + case WXK_CANCEL: return wxT("Cancel"); break; + case WXK_BACK: return wxT("Back"); break; + case WXK_TAB: return wxT("Tab"); break; + case WXK_CLEAR: return wxT("Clear"); break; + case WXK_RETURN: return wxT("Return"); break; + case WXK_SHIFT: return wxT("Shift"); break; + case WXK_CONTROL: return wxT("Control"); break; + case WXK_ALT: return wxT("Alt"); break; + case WXK_CAPITAL: return wxT("CapsLock"); break; + case WXK_MENU : return wxT("Menu"); break; + case WXK_PAUSE: return wxT("Pause"); break; + case WXK_ESCAPE: return wxT("Escape"); break; + case WXK_SPACE: return wxT("Space"); break; + case WXK_PAGEUP: return wxT("PgUp"); break; + case WXK_PAGEDOWN: return wxT("PgDn"); break; + case WXK_END: return wxT("End"); break; + case WXK_HOME : return wxT("Home"); break; + case WXK_LEFT : return wxT("Left"); break; + case WXK_UP: return wxT("Up"); break; + case WXK_RIGHT: return wxT("Right"); break; + case WXK_DOWN : return wxT("Down"); break; + case WXK_SELECT: return wxT("Select"); break; + case WXK_PRINT: return wxT("Print"); break; + case WXK_EXECUTE: return wxT("Execute"); break; + case WXK_INSERT: return wxT("Insert"); break; + case WXK_DELETE: return wxT("Delete"); break; + case WXK_HELP : return wxT("Help"); break; + case WXK_NUMPAD0: return wxT("NP 0"); break; + case WXK_NUMPAD1: return wxT("NP 1"); break; + case WXK_NUMPAD2: return wxT("NP 2"); break; + case WXK_NUMPAD3: return wxT("NP 3"); break; + case WXK_NUMPAD4: return wxT("NP 4"); break; + case WXK_NUMPAD5: return wxT("NP 5"); break; + case WXK_NUMPAD6: return wxT("NP 6"); break; + case WXK_NUMPAD7: return wxT("NP 7"); break; + case WXK_NUMPAD8: return wxT("NP 8"); break; + case WXK_NUMPAD9: return wxT("NP 9"); break; + case WXK_NUMPAD_DECIMAL: return wxT("NP ."); break; + case WXK_NUMPAD_DELETE: return wxT("NP Delete"); break; + case WXK_NUMPAD_INSERT: return wxT("NP Insert"); break; + case WXK_NUMPAD_END: return wxT("NP End"); break; + case WXK_NUMPAD_DOWN: return wxT("NP Down"); break; + case WXK_NUMPAD_PAGEDOWN: return wxT("NP Pagedown"); break; + case WXK_NUMPAD_LEFT: return wxT("NP Left"); break; + case WXK_NUMPAD_RIGHT: return wxT("NP Right"); break; + case WXK_NUMPAD_HOME: return wxT("NP Home"); break; + case WXK_NUMPAD_UP: return wxT("NP Up"); break; + case WXK_NUMPAD_PAGEUP: return wxT("NP Pageup"); break; + case WXK_NUMPAD_MULTIPLY: return wxT("NP *"); break; + case WXK_NUMPAD_ADD: return wxT("NP +"); break; + case WXK_NUMPAD_SUBTRACT: return wxT("NP -"); break; + case WXK_NUMPAD_DIVIDE: return wxT("NP /"); break; + case WXK_NUMPAD_ENTER: return wxT("NP Enter"); break; + case WXK_NUMPAD_SEPARATOR: return wxT("NP Separator"); break; + case WXK_F1: return wxT("F1"); break; + case WXK_F2: return wxT("F2"); break; + case WXK_F3: return wxT("F3"); break; + case WXK_F4: return wxT("F4"); break; + case WXK_F5: return wxT("F5"); break; + case WXK_F6: return wxT("F6"); break; + case WXK_F7: return wxT("F7"); break; + case WXK_F8: return wxT("F8"); break; + case WXK_F9: return wxT("F9"); break; + case WXK_F10: return wxT("F10"); break; + case WXK_F11: return wxT("F11"); break; + case WXK_F12: return wxT("F12"); break; + case WXK_F13: return wxT("F13"); break; + case WXK_F14: return wxT("F14"); break; + case WXK_F15: return wxT("F15"); break; + case WXK_F16: return wxT("F16"); break; + case WXK_F17: return wxT("F17"); break; + case WXK_F18: return wxT("F19"); break; + case WXK_F19: return wxT("F20"); break; + case WXK_F20: return wxT("F21"); break; + case WXK_F21: return wxT("F22"); break; + case WXK_F22: return wxT("F23"); break; + case WXK_F23: return wxT("F24"); break; + case WXK_F24: return wxT("F25"); break; + case WXK_NUMLOCK: return wxT("Numlock"); break; + case WXK_SCROLL: return wxT("Scrolllock"); break; + default: return wxString::FromAscii(keycode); + } +} + +const wxChar *WXKeymodToString(int modifier) +{ + switch (modifier) + { + case wxMOD_ALT: return wxT("Alt"); break; + case wxMOD_CMD: return wxT("Ctrl"); break; + case wxMOD_ALTGR: return wxT("Ctrl+Alt"); break; + case wxMOD_SHIFT: return wxT("Shift"); break; + default: return wxT(""); break; + } +} + +} diff --git a/Source/Plugins/InputUICommon/Src/WXInputBase.h b/Source/Core/InputCommon/Src/WXInputBase.h similarity index 96% rename from Source/Plugins/InputUICommon/Src/WXInputBase.h rename to Source/Core/InputCommon/Src/WXInputBase.h index c249309699..8c1e74aafc 100644 --- a/Source/Plugins/InputUICommon/Src/WXInputBase.h +++ b/Source/Core/InputCommon/Src/WXInputBase.h @@ -1,28 +1,28 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef WXINPUTBASE_H -#define WXINPUTBASE_H - -#include - -namespace InputCommon -{ -const wxChar *WXKeyToString(int keycode); -const wxChar *WXKeymodToString(int modifier); -} -#endif +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef WXINPUTBASE_H +#define WXINPUTBASE_H + +#include + +namespace InputCommon +{ +const wxChar *WXKeyToString(int keycode); +const wxChar *WXKeymodToString(int modifier); +} +#endif diff --git a/Source/Core/InputCommon/Src/X11InputBase.h b/Source/Core/InputCommon/Src/X11InputBase.h index eaf8475e50..13c6717f86 100644 --- a/Source/Core/InputCommon/Src/X11InputBase.h +++ b/Source/Core/InputCommon/Src/X11InputBase.h @@ -20,7 +20,7 @@ #include #include -#include "InputConfig.h" +#include "Config.h" #if defined(HAVE_WX) && HAVE_WX #include #endif diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 8a91283860..a956a53cf2 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -47,68 +47,63 @@ void VideoConfig::Load(const char *ini_file) IniFile iniFile; iniFile.Load(ini_file); - Section& hardware = iniFile["Hardware"]; - hardware.Get("VSync", &bVSync, false); // Hardware - - Section& settings = iniFile["Settings"]; - settings.Get("StretchToFit", &bNativeResolution, true); - settings.Get("2xResolution", &b2xResolution, false); - settings.Get("wideScreenHack", &bWidescreenHack, false); - settings.Get("AspectRatio", &iAspectRatio, (int)ASPECT_AUTO); - settings.Get("Crop", &bCrop, false); - settings.Get("UseXFB", &bUseXFB, true); - settings.Get("UseRealXFB", &bUseRealXFB, false); - settings.Get("AutoScale", &bAutoScale, true); - settings.Get("UseNativeMips", &bUseNativeMips, true); + iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware + iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true); + iniFile.Get("Settings", "2xResolution", &b2xResolution, false); + iniFile.Get("Settings", "wideScreenHack", &bWidescreenHack, false); + iniFile.Get("Settings", "AspectRatio", &iAspectRatio, (int)ASPECT_AUTO); + iniFile.Get("Settings", "Crop", &bCrop, false); + iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); + iniFile.Get("Settings", "UseRealXFB", &bUseRealXFB, 0); + iniFile.Get("Settings", "AutoScale", &bAutoScale, true); + iniFile.Get("Settings", "UseNativeMips", &bUseNativeMips, true); - settings.Get("SafeTextureCache", &bSafeTextureCache, false); // Settings + iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings //Safe texture cache params - settings.Get("SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples,512); + iniFile.Get("Settings", "SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples,512); - settings.Get("ShowFPS", &bShowFPS, false); // Settings - settings.Get("OverlayStats", &bOverlayStats, false); - settings.Get("OverlayProjStats", &bOverlayProjStats, false); - settings.Get("ShowEFBCopyRegions", &bShowEFBCopyRegions, false); - settings.Get("DLOptimize", &iCompileDLsLevel, 0); - settings.Get("DumpTextures", &bDumpTextures, false); - settings.Get("HiresTextures", &bHiresTextures, false); - settings.Get("DumpEFBTarget", &bDumpEFBTarget, false); - settings.Get("DumpFrames", &bDumpFrames, false); - settings.Get("FreeLook", &bFreeLook, false); - settings.Get("ShowShaderErrors", &bShowShaderErrors, false); - settings.Get("MSAA", &iMultisampleMode, 0); - settings.Get("DstAlphaPass", &bDstAlphaPass, false); + iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings + iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); + iniFile.Get("Settings", "OverlayProjStats", &bOverlayProjStats, false); + iniFile.Get("Settings", "ShowEFBCopyRegions", &bShowEFBCopyRegions, false); + iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); + iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); + iniFile.Get("Settings", "HiresTextures", &bHiresTextures, 0); + iniFile.Get("Settings", "DumpEFBTarget", &bDumpEFBTarget, 0); + iniFile.Get("Settings", "DumpFrames", &bDumpFrames, 0); + iniFile.Get("Settings", "FreeLook", &bFreeLook, 0); + iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); + iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); + iniFile.Get("Settings", "DstAlphaPass", &bDstAlphaPass, false); - settings.Get("TexFmtOverlayEnable", &bTexFmtOverlayEnable, false); - settings.Get("TexFmtOverlayCenter", &bTexFmtOverlayCenter, false); - settings.Get("WireFrame", &bWireFrame, false); - settings.Get("DisableLighting", &bDisableLighting, false); - settings.Get("DisableTexturing", &bDisableTexturing, false); - settings.Get("DisableFog", &bDisableFog, false); + iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0); + iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0); + iniFile.Get("Settings", "WireFrame", &bWireFrame, 0); + iniFile.Get("Settings", "DisableLighting", &bDisableLighting, 0); + iniFile.Get("Settings", "DisableTexturing", &bDisableTexturing, 0); + iniFile.Get("Settings", "DisableFog", &bDisableFog, 0); + + iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0); + iniFile.Get("Enhancements", "MaxAnisotropy", &iMaxAnisotropy, 1); // NOTE - this is x in (1 << x) + iniFile.Get("Enhancements", "PostProcessingShader", &sPostProcessingShader, ""); + + iniFile.Get("Hacks", "EFBAccessEnable", &bEFBAccessEnable, true); + iniFile.Get("Hacks", "EFBCopyDisable", &bEFBCopyDisable, false); + iniFile.Get("Hacks", "EFBCopyDisableHotKey", &bOSDHotKey, 0); + iniFile.Get("Hacks", "EFBToTextureEnable", &bCopyEFBToTexture, false); + iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); + iniFile.Get("Hacks", "FIFOBPHack", &bFIFOBPhack, false); + iniFile.Get("Hacks", "ProjectionHack", &iPhackvalue, 0); - Section& enhancements = iniFile["Enhancements"]; - enhancements.Get("ForceFiltering", &bForceFiltering, false); - enhancements.Get("MaxAnisotropy", &iMaxAnisotropy, 1); // NOTE - this is x in (1 << x) - enhancements.Get("PostProcessingShader", &sPostProcessingShader, ""); - - Section& hacks = iniFile["Hacks"]; - hacks.Get("EFBAccessEnable", &bEFBAccessEnable, true); - hacks.Get("EFBCopyDisable", &bEFBCopyDisable, false); - hacks.Get("EFBCopyDisableHotKey", &bOSDHotKey, false); - hacks.Get("EFBToTextureEnable", &bCopyEFBToTexture, false); - hacks.Get("EFBScaledCopy", &bCopyEFBScaled, true); - hacks.Get("FIFOBPHack", &bFIFOBPhack, false); - hacks.Get("ProjectionHack", &iPhackvalue, 0); - - hardware.Get("Adapter", &iAdapter, 0); + iniFile.Get("Hardware", "Adapter", &iAdapter, 0); if (iAdapter == -1) iAdapter = 0; - hardware.Get("SimpleFB", &bSimpleFB, false); + iniFile.Get("Hardware", "SimpleFB", &bSimpleFB, false); // Load common settings iniFile.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)); bool bTmp; - iniFile["Interface"].Get("UsePanicHandlers", &bTmp, true); + iniFile.Get("Interface", "UsePanicHandlers", &bTmp, true); SetEnableAlert(bTmp); } @@ -117,87 +112,94 @@ void VideoConfig::GameIniLoad(const char *ini_file) IniFile iniFile; iniFile.Load(ini_file); - Section& video = iniFile["Video"]; - - video.Get("ForceFiltering", &bForceFiltering, bForceFiltering); - video.Get("MaxAnisotropy", &iMaxAnisotropy, iMaxAnisotropy); // NOTE - this is x in (1 << x) - video.Get("EFBCopyDisable", &bEFBCopyDisable, bEFBCopyDisable); - video.Get("EFBCopyDisableHotKey", &bOSDHotKey, bOSDHotKey); - video.Get("EFBToTextureEnable", &bCopyEFBToTexture, bCopyEFBToTexture); - video.Get("EFBScaledCopy", &bCopyEFBScaled, bCopyEFBScaled); - video.Get("SafeTextureCache", &bSafeTextureCache, bSafeTextureCache); + if (iniFile.Exists("Video", "ForceFiltering")) + iniFile.Get("Video", "ForceFiltering", &bForceFiltering, 0); + if (iniFile.Exists("Video", "MaxAnisotropy")) + iniFile.Get("Video", "MaxAnisotropy", &iMaxAnisotropy, 3); // NOTE - this is x in (1 << x) + if (iniFile.Exists("Video", "EFBCopyDisable")) + iniFile.Get("Video", "EFBCopyDisable", &bEFBCopyDisable, 0); + if (iniFile.Exists("Video", "EFBCopyDisableHotKey")) + iniFile.Get("Video", "EFBCopyDisableHotKey", &bOSDHotKey, 0); + if (iniFile.Exists("Video", "EFBToTextureEnable")) + iniFile.Get("Video", "EFBToTextureEnable", &bCopyEFBToTexture, 0); + if (iniFile.Exists("Video", "EFBScaledCopy")) + iniFile.Get("Video", "EFBScaledCopy", &bCopyEFBScaled, 0); + if (iniFile.Exists("Video", "SafeTextureCache")) + iniFile.Get("Video", "SafeTextureCache", &bSafeTextureCache, false); //Safe texture cache params - video.Get("SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples, iSafeTextureCache_ColorSamples); + if (iniFile.Exists("Video", "SafeTextureCacheColorSamples")) + iniFile.Get("Video", "SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples,512); - video.Get("MSAA", &iMultisampleMode, iMultisampleMode); - video.Get("DstAlphaPass", &bDstAlphaPass, bDstAlphaPass); - video.Get("UseXFB", &bUseXFB, bUseXFB); - video.Get("UseRealXFB", &bUseRealXFB, bUseRealXFB); - video.Get("FIFOBPHack", &bFIFOBPhack, bFIFOBPhack); - video.Get("ProjectionHack", &iPhackvalue, iPhackvalue); - video.Get("UseNativeMips", &bUseNativeMips, bUseNativeMips); + if (iniFile.Exists("Video", "MSAA")) + iniFile.Get("Video", "MSAA", &iMultisampleMode, 0); + if (iniFile.Exists("Video", "DstAlphaPass")) + iniFile.Get("Video", "DstAlphaPass", &bDstAlphaPass, false); + if (iniFile.Exists("Video", "UseXFB")) + iniFile.Get("Video", "UseXFB", &bUseXFB, 0); + if (iniFile.Exists("Video", "UseRealXFB")) + iniFile.Get("Video", "UseRealXFB", &bUseRealXFB, 0); + if (iniFile.Exists("Video", "FIFOBPHack")) + iniFile.Get("Video", "FIFOBPHack", &bFIFOBPhack, false); + if (iniFile.Exists("Video", "ProjectionHack")) + iniFile.Get("Video", "ProjectionHack", &iPhackvalue, 0); + if (iniFile.Exists("Video", "UseNativeMips")) + iniFile.Get("Video", "UseNativeMips", &bUseNativeMips, true); } void VideoConfig::Save(const char *ini_file) { IniFile iniFile; iniFile.Load(ini_file); + iniFile.Set("Hardware", "VSync", bVSync); + iniFile.Set("Settings", "StretchToFit", bNativeResolution); + iniFile.Set("Settings", "2xResolution", b2xResolution); + iniFile.Set("Settings", "AspectRatio", iAspectRatio); + iniFile.Set("Settings", "Crop", bCrop); + iniFile.Set("Settings", "wideScreenHack", bWidescreenHack); + iniFile.Set("Settings", "UseXFB", bUseXFB); + iniFile.Set("Settings", "UseRealXFB", bUseRealXFB); + iniFile.Set("Settings", "AutoScale", bAutoScale); + iniFile.Set("Settings", "UseNativeMips", bUseNativeMips); - Section& hardware = iniFile["Hardware"]; - hardware.Set("VSync", bVSync); - - Section& settings = iniFile["Settings"]; - settings.Set("StretchToFit", bNativeResolution); - settings.Set("2xResolution", b2xResolution); - settings.Set("AspectRatio", iAspectRatio); - settings.Set("Crop", bCrop); - settings.Set("wideScreenHack", bWidescreenHack); - settings.Set("UseXFB", bUseXFB); - settings.Set("UseRealXFB", bUseRealXFB); - settings.Set("AutoScale", bAutoScale); - settings.Set("UseNativeMips", bUseNativeMips); - - settings.Set("SafeTextureCache", bSafeTextureCache); + iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); //safe texture cache params - settings.Set("SafeTextureCacheColorSamples", iSafeTextureCache_ColorSamples); + iniFile.Set("Settings", "SafeTextureCacheColorSamples", iSafeTextureCache_ColorSamples); - settings.Set("ShowFPS", bShowFPS); - settings.Set("OverlayStats", bOverlayStats); - settings.Set("OverlayProjStats", bOverlayProjStats); - settings.Set("DLOptimize", iCompileDLsLevel); - settings.Set("Show", iCompileDLsLevel); - settings.Set("DumpTextures", bDumpTextures); - settings.Set("HiresTextures", bHiresTextures); - settings.Set("DumpEFBTarget", bDumpEFBTarget); - settings.Set("DumpFrames", bDumpFrames); - settings.Set("FreeLook", bFreeLook); - settings.Set("ShowEFBCopyRegions", bShowEFBCopyRegions); - settings.Set("ShowShaderErrors", bShowShaderErrors); - settings.Set("MSAA", iMultisampleMode); - settings.Set("TexFmtOverlayEnable", bTexFmtOverlayEnable); - settings.Set("TexFmtOverlayCenter", bTexFmtOverlayCenter); - settings.Set("Wireframe", bWireFrame); - settings.Set("DisableLighting", bDisableLighting); - settings.Set("DisableTexturing", bDisableTexturing); - settings.Set("DstAlphaPass", bDstAlphaPass); - settings.Set("DisableFog", bDisableFog); + iniFile.Set("Settings", "ShowFPS", bShowFPS); + iniFile.Set("Settings", "OverlayStats", bOverlayStats); + iniFile.Set("Settings", "OverlayProjStats", bOverlayProjStats); + iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); + iniFile.Set("Settings", "Show", iCompileDLsLevel); + iniFile.Set("Settings", "DumpTextures", bDumpTextures); + iniFile.Set("Settings", "HiresTextures", bHiresTextures); + iniFile.Set("Settings", "DumpEFBTarget", bDumpEFBTarget); + iniFile.Set("Settings", "DumpFrames", bDumpFrames); + iniFile.Set("Settings", "FreeLook", bFreeLook); + iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); + iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); + iniFile.Set("Settings", "MSAA", iMultisampleMode); + iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable); + iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter); + iniFile.Set("Settings", "Wireframe", bWireFrame); + iniFile.Set("Settings", "DisableLighting", bDisableLighting); + iniFile.Set("Settings", "DisableTexturing", bDisableTexturing); + iniFile.Set("Settings", "DstAlphaPass", bDstAlphaPass); + iniFile.Set("Settings", "DisableFog", bDisableFog); - Section& enhancements = iniFile["Enhancements"]; - enhancements.Set("ForceFiltering", bForceFiltering); - enhancements.Set("MaxAnisotropy", iMaxAnisotropy); - enhancements.Set("PostProcessingShader", sPostProcessingShader); + iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering); + iniFile.Set("Enhancements", "MaxAnisotropy", iMaxAnisotropy); + iniFile.Set("Enhancements", "PostProcessingShader", sPostProcessingShader); - Section& hacks = iniFile["Hacks"]; - hacks.Set("EFBAccessEnable", bEFBAccessEnable); - hacks.Set("EFBCopyDisable", bEFBCopyDisable); - hacks.Set("EFBCopyDisableHotKey", bOSDHotKey); - hacks.Set("EFBToTextureEnable", bCopyEFBToTexture); - hacks.Set("EFBScaledCopy", bCopyEFBScaled); - hacks.Set("FIFOBPHack", bFIFOBPhack); - hacks.Set("ProjectionHack", iPhackvalue); + iniFile.Set("Hacks", "EFBAccessEnable", bEFBAccessEnable); + iniFile.Set("Hacks", "EFBCopyDisable", bEFBCopyDisable); + iniFile.Set("Hacks", "EFBCopyDisableHotKey", bOSDHotKey); + iniFile.Set("Hacks", "EFBToTextureEnable", bCopyEFBToTexture); + iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); + iniFile.Set("Hacks", "FIFOBPHack", bFIFOBPhack); + iniFile.Set("Hacks", "ProjectionHack", iPhackvalue); - hardware.Set("Adapter", iAdapter); - hardware.Set("SimpleFB", bSimpleFB); + iniFile.Set("Hardware", "Adapter", iAdapter); + iniFile.Set("Hardware", "SimpleFB", bSimpleFB); iniFile.Save(ini_file); } diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index 939329ca5d..66bd93866b 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -7,7 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core\Core.vcpr {33546D62-7F34-4EA6-A88E-D538B36E16BF} = {33546D62-7F34-4EA6-A88E-D538B36E16BF} {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} {823DDC98-42D5-4A38-88CF-9DC06C788AE4} = {823DDC98-42D5-4A38-88CF-9DC06C788AE4} - {838A89A3-3AA0-4A45-ACBE-3D1E0980C2ED} = {838A89A3-3AA0-4A45-ACBE-3D1E0980C2ED} {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} @@ -64,8 +63,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\D {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} = {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684} - {660BB3F7-ED8F-4027-A460-8E4EDA8189BE} = {660BB3F7-ED8F-4027-A460-8E4EDA8189BE} {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + {9FF603F8-B3BB-4144-9688-B2B802FA0F16} = {9FF603F8-B3BB-4144-9688-B2B802FA0F16} {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} EndProjectSection EndProject @@ -105,9 +104,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_Wiimote", "Plugins\P EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputCommon", "Core\InputCommon\InputCommon.vcproj", "{C7E5D50A-2916-464B-86A7-E10B3CC88ADA}" - ProjectSection(ProjectDependencies) = postProject - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCommon", "Core\AudioCommon\AudioCommon.vcproj", "{FBAFB369-07EB-4460-9CAD-08BE5789DAB6}" EndProject @@ -188,6 +184,27 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoSoftware", "Plu {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_GCPad", "Plugins\Plugin_GCPad\Plugin_GCPad.vcproj", "{9FF603F8-B3BB-4144-9688-B2B802FA0F16}" + ProjectSection(ProjectDependencies) = postProject + {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} + {05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75} + {11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED} + {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_GCPadNew", "Plugins\Plugin_GCPadNew\Plugin_GCPadNew.vcproj", "{1C3A7A91-A97F-4C7C-B45D-26F2242904D7}" + ProjectSection(ProjectDependencies) = postProject + {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} + {05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75} + {11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED} + {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} + {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} + {660BB3F7-ED8F-4027-A460-8E4EDA8189BE} = {660BB3F7-ED8F-4027-A460-8E4EDA8189BE} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_WiimoteNew", "Plugins\Plugin_WiimoteNew\Plugin_WiimoteNew.vcproj", "{BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}" ProjectSection(ProjectDependencies) = postProject {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} @@ -199,7 +216,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_WiimoteNew", "Plugin {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputUICommon", "Plugins\InputUICommon\InputUICommon.vcproj", "{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputPluginCommon", "Plugins\InputPluginCommon\InputPluginCommon.vcproj", "{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}" ProjectSection(ProjectDependencies) = postProject {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} {05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75} @@ -557,6 +574,30 @@ Global {66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|Win32.Build.0 = Release|Win32 {66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|x64.ActiveCfg = Release|x64 {66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|x64.Build.0 = Release|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Debug|Win32.ActiveCfg = Debug|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Debug|Win32.Build.0 = Debug|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Debug|x64.ActiveCfg = Debug|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Debug|x64.Build.0 = Debug|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.DebugFast|x64.Build.0 = DebugFast|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Release|Win32.ActiveCfg = Release|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Release|Win32.Build.0 = Release|Win32 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Release|x64.ActiveCfg = Release|x64 + {9FF603F8-B3BB-4144-9688-B2B802FA0F16}.Release|x64.Build.0 = Release|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Debug|Win32.Build.0 = Debug|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Debug|x64.ActiveCfg = Debug|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Debug|x64.Build.0 = Debug|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.DebugFast|x64.Build.0 = DebugFast|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|Win32.ActiveCfg = Release|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|Win32.Build.0 = Release|Win32 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|x64.ActiveCfg = Release|x64 + {1C3A7A91-A97F-4C7C-B45D-26F2242904D7}.Release|x64.Build.0 = Release|x64 {BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|Win32.ActiveCfg = Debug|Win32 {BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|Win32.Build.0 = Debug|Win32 {BB6CE47B-C676-44BB-AE93-2CF59B8C8BD4}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/Source/Dolphin.xcodeproj/project.pbxproj b/Source/Dolphin.xcodeproj/project.pbxproj index e04c133408..7f75c81114 100644 --- a/Source/Dolphin.xcodeproj/project.pbxproj +++ b/Source/Dolphin.xcodeproj/project.pbxproj @@ -39,6 +39,7 @@ 292AC1FC11838FD700B8790B /* BreakPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABD9B11838FD400B8790B /* BreakPoints.h */; }; 292AC1FD11838FD700B8790B /* CDUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABD9C11838FD400B8790B /* CDUtils.cpp */; }; 292AC1FE11838FD700B8790B /* CDUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABD9D11838FD400B8790B /* CDUtils.h */; }; + 292AC1FF11838FD700B8790B /* ChunkFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABD9E11838FD400B8790B /* ChunkFile.cpp */; }; 292AC20011838FD700B8790B /* ChunkFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABD9F11838FD400B8790B /* ChunkFile.h */; }; 292AC20111838FD700B8790B /* ColorUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABDA011838FD400B8790B /* ColorUtil.cpp */; }; 292AC20211838FD700B8790B /* ColorUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABDA111838FD400B8790B /* ColorUtil.h */; }; @@ -61,6 +62,7 @@ 292AC21311838FD700B8790B /* DebugInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABDB311838FD400B8790B /* DebugInterface.h */; }; 292AC21411838FD700B8790B /* DynamicLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABDB411838FD400B8790B /* DynamicLibrary.cpp */; }; 292AC21511838FD700B8790B /* DynamicLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABDB511838FD400B8790B /* DynamicLibrary.h */; }; + 292AC21611838FD700B8790B /* ExtendedTrace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABDB611838FD400B8790B /* ExtendedTrace.cpp */; }; 292AC21711838FD700B8790B /* ExtendedTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABDB711838FD400B8790B /* ExtendedTrace.h */; }; 292AC21811838FD700B8790B /* FileSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABDB811838FD400B8790B /* FileSearch.cpp */; }; 292AC21911838FD700B8790B /* FileSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABDB911838FD400B8790B /* FileSearch.h */; }; @@ -499,6 +501,7 @@ 292AC3D211838FD700B8790B /* DSPAccelerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABFCA11838FD600B8790B /* DSPAccelerator.h */; }; 292AC3D311838FD700B8790B /* DSPAnalyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABFCB11838FD600B8790B /* DSPAnalyzer.cpp */; }; 292AC3D411838FD700B8790B /* DSPAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABFCC11838FD600B8790B /* DSPAnalyzer.h */; }; + 292AC3D511838FD700B8790B /* DSPBreakpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABFCD11838FD600B8790B /* DSPBreakpoints.cpp */; }; 292AC3D611838FD700B8790B /* DSPBreakpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABFCE11838FD600B8790B /* DSPBreakpoints.h */; }; 292AC3D711838FD700B8790B /* DSPCodeUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292ABFCF11838FD600B8790B /* DSPCodeUtil.cpp */; }; 292AC3D811838FD700B8790B /* DSPCodeUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 292ABFD011838FD600B8790B /* DSPCodeUtil.h */; }; @@ -1297,6 +1300,7 @@ 292ABD9B11838FD400B8790B /* BreakPoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakPoints.h; sourceTree = ""; }; 292ABD9C11838FD400B8790B /* CDUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDUtils.cpp; sourceTree = ""; }; 292ABD9D11838FD400B8790B /* CDUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDUtils.h; sourceTree = ""; }; + 292ABD9E11838FD400B8790B /* ChunkFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChunkFile.cpp; sourceTree = ""; }; 292ABD9F11838FD400B8790B /* ChunkFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChunkFile.h; sourceTree = ""; }; 292ABDA011838FD400B8790B /* ColorUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorUtil.cpp; sourceTree = ""; }; 292ABDA111838FD400B8790B /* ColorUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorUtil.h; sourceTree = ""; }; @@ -1319,6 +1323,7 @@ 292ABDB311838FD400B8790B /* DebugInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugInterface.h; sourceTree = ""; }; 292ABDB411838FD400B8790B /* DynamicLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLibrary.cpp; sourceTree = ""; }; 292ABDB511838FD400B8790B /* DynamicLibrary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLibrary.h; sourceTree = ""; }; + 292ABDB611838FD400B8790B /* ExtendedTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendedTrace.cpp; sourceTree = ""; }; 292ABDB711838FD400B8790B /* ExtendedTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedTrace.h; sourceTree = ""; }; 292ABDB811838FD400B8790B /* FileSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSearch.cpp; sourceTree = ""; }; 292ABDB911838FD400B8790B /* FileSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSearch.h; sourceTree = ""; }; @@ -1817,6 +1822,7 @@ 292ABFCA11838FD600B8790B /* DSPAccelerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPAccelerator.h; sourceTree = ""; }; 292ABFCB11838FD600B8790B /* DSPAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPAnalyzer.cpp; sourceTree = ""; }; 292ABFCC11838FD600B8790B /* DSPAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPAnalyzer.h; sourceTree = ""; }; + 292ABFCD11838FD600B8790B /* DSPBreakpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPBreakpoints.cpp; sourceTree = ""; }; 292ABFCE11838FD600B8790B /* DSPBreakpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPBreakpoints.h; sourceTree = ""; }; 292ABFCF11838FD600B8790B /* DSPCodeUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPCodeUtil.cpp; sourceTree = ""; }; 292ABFD011838FD600B8790B /* DSPCodeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPCodeUtil.h; sourceTree = ""; }; @@ -2694,6 +2700,7 @@ 292ABD9B11838FD400B8790B /* BreakPoints.h */, 292ABD9C11838FD400B8790B /* CDUtils.cpp */, 292ABD9D11838FD400B8790B /* CDUtils.h */, + 292ABD9E11838FD400B8790B /* ChunkFile.cpp */, 292ABD9F11838FD400B8790B /* ChunkFile.h */, 292ABDA011838FD400B8790B /* ColorUtil.cpp */, 292ABDA111838FD400B8790B /* ColorUtil.h */, @@ -2710,6 +2717,7 @@ 292ABDB311838FD400B8790B /* DebugInterface.h */, 292ABDB411838FD400B8790B /* DynamicLibrary.cpp */, 292ABDB511838FD400B8790B /* DynamicLibrary.h */, + 292ABDB611838FD400B8790B /* ExtendedTrace.cpp */, 292ABDB711838FD400B8790B /* ExtendedTrace.h */, 292ABDB811838FD400B8790B /* FileSearch.cpp */, 292ABDB911838FD400B8790B /* FileSearch.h */, @@ -3442,6 +3450,7 @@ 292ABFCA11838FD600B8790B /* DSPAccelerator.h */, 292ABFCB11838FD600B8790B /* DSPAnalyzer.cpp */, 292ABFCC11838FD600B8790B /* DSPAnalyzer.h */, + 292ABFCD11838FD600B8790B /* DSPBreakpoints.cpp */, 292ABFCE11838FD600B8790B /* DSPBreakpoints.h */, 292ABFCF11838FD600B8790B /* DSPCodeUtil.cpp */, 292ABFD011838FD600B8790B /* DSPCodeUtil.h */, @@ -5398,6 +5407,7 @@ 292AC1F611838FD700B8790B /* ABI.cpp in Sources */, 292AC1FB11838FD700B8790B /* BreakPoints.cpp in Sources */, 292AC1FD11838FD700B8790B /* CDUtils.cpp in Sources */, + 292AC1FF11838FD700B8790B /* ChunkFile.cpp in Sources */, 292AC20111838FD700B8790B /* ColorUtil.cpp in Sources */, 292AC20811838FD700B8790B /* ConsoleListener.cpp in Sources */, 292AC20A11838FD700B8790B /* CPUDetect.cpp in Sources */, @@ -5406,6 +5416,7 @@ 292AC20E11838FD700B8790B /* md5.cpp in Sources */, 292AC21011838FD700B8790B /* sha1.cpp in Sources */, 292AC21411838FD700B8790B /* DynamicLibrary.cpp in Sources */, + 292AC21611838FD700B8790B /* ExtendedTrace.cpp in Sources */, 292AC21811838FD700B8790B /* FileSearch.cpp in Sources */, 292AC21A11838FD700B8790B /* FileUtil.cpp in Sources */, 292AC21D11838FD700B8790B /* Hash.cpp in Sources */, @@ -5640,6 +5651,7 @@ 292AC3CF11838FD700B8790B /* disassemble.cpp in Sources */, 292AC3D111838FD700B8790B /* DSPAccelerator.cpp in Sources */, 292AC3D311838FD700B8790B /* DSPAnalyzer.cpp in Sources */, + 292AC3D511838FD700B8790B /* DSPBreakpoints.cpp in Sources */, 292AC3D711838FD700B8790B /* DSPCodeUtil.cpp in Sources */, 292AC3DA11838FD700B8790B /* DSPCore.cpp in Sources */, 292AC3DC11838FD700B8790B /* DSPEmitter.cpp in Sources */, diff --git a/Source/PluginSpecs/pluginspecs_pad.h b/Source/PluginSpecs/pluginspecs_pad.h new file mode 100644 index 0000000000..45237b7dc7 --- /dev/null +++ b/Source/PluginSpecs/pluginspecs_pad.h @@ -0,0 +1,88 @@ +//__________________________________________________________________________________________________ +// Common pad plugin spec, version #1.0 maintained by F|RES +// + +#ifndef _PAD_H_INCLUDED__ +#define _PAD_H_INCLUDED__ + +#include "PluginSpecs.h" + +#include "ExportProlog.h" + +#define PAD_ERR_NONE 0 +#define PAD_ERR_NO_CONTROLLER -1 +#define PAD_ERR_NOT_READY -2 +#define PAD_ERR_TRANSFER -3 + +#define PAD_USE_ORIGIN 0x0080 + +#define PAD_BUTTON_LEFT 0x0001 +#define PAD_BUTTON_RIGHT 0x0002 +#define PAD_BUTTON_DOWN 0x0004 +#define PAD_BUTTON_UP 0x0008 +#define PAD_TRIGGER_Z 0x0010 +#define PAD_TRIGGER_R 0x0020 +#define PAD_TRIGGER_L 0x0040 +#define PAD_BUTTON_A 0x0100 +#define PAD_BUTTON_B 0x0200 +#define PAD_BUTTON_X 0x0400 +#define PAD_BUTTON_Y 0x0800 +#define PAD_BUTTON_START 0x1000 + +typedef void (*TLog)(const char* _pMessage); +typedef bool (*TRendererHasFocus)(void); + +typedef struct +{ + HWND hWnd; +#if defined HAVE_X11 && HAVE_X11 + void *pXWindow; +#endif + TLog pLog; + TRendererHasFocus pRendererHasFocus; +} SPADInitialize; + +typedef struct +{ + unsigned short button; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits + unsigned char stickX; // 0 <= stickX <= 255 + unsigned char stickY; // 0 <= stickY <= 255 + unsigned char substickX; // 0 <= substickX <= 255 + unsigned char substickY; // 0 <= substickY <= 255 + unsigned char triggerLeft; // 0 <= triggerLeft <= 255 + unsigned char triggerRight; // 0 <= triggerRight <= 255 + unsigned char analogA; // 0 <= analogA <= 255 + unsigned char analogB; // 0 <= analogB <= 255 + bool MicButton; // HAX + signed char err; // one of PAD_ERR_* number +} SPADStatus; + + +// I N T E R F A C E + +// __________________________________________________________________________________________________ +// Function: +// Purpose: +// input: +// output: +// +EXPORT void CALL PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus); + +// __________________________________________________________________________________________________ +// Function: Send keyboard input to the plugin +// Purpose: +// input: The key and if it's pressed or released +// output: None +// +EXPORT void CALL PAD_Input(u16 _Key, u8 _UpDown); + +// __________________________________________________________________________________________________ +// Function: PAD_Rumble +// Purpose: Pad rumble! +// input: PAD number, Command type (Stop=0, Rumble=1, Stop Hard=2) and strength of Rumble +// output: none +// +EXPORT void CALL PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength); + +#include "ExportEpilog.h" +#endif diff --git a/Source/Plugins/InputUICommon/InputUICommon.vcproj b/Source/Plugins/InputPluginCommon/InputPluginCommon.vcproj similarity index 96% rename from Source/Plugins/InputUICommon/InputUICommon.vcproj rename to Source/Plugins/InputPluginCommon/InputPluginCommon.vcproj index b64cb4c9b1..d7df1fea37 100644 --- a/Source/Plugins/InputUICommon/InputUICommon.vcproj +++ b/Source/Plugins/InputPluginCommon/InputPluginCommon.vcproj @@ -2,7 +2,7 @@ - - - - - - + + + @@ -433,7 +429,19 @@ > + + + + + + diff --git a/Source/Core/InputCommon/Src/InputConfig.cpp b/Source/Plugins/InputPluginCommon/Src/Config.cpp similarity index 94% rename from Source/Core/InputCommon/Src/InputConfig.cpp rename to Source/Plugins/InputPluginCommon/Src/Config.cpp index f01a723360..417867c175 100644 --- a/Source/Core/InputCommon/Src/InputConfig.cpp +++ b/Source/Plugins/InputPluginCommon/Src/Config.cpp @@ -1,57 +1,57 @@ - -#include "InputConfig.h" - -Plugin::Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name ) - : ini_name(_ini_name) - , gui_name(_gui_name) - , profile_name(_profile_name) -{ - // GCPads - //for ( unsigned int i = 0; i<4; ++i ) - //controllers.push_back( new GCPad( i ) ); - // Wiimotes / disabled, cause it only the GUI half is done - //for ( unsigned int i = 0; i<4; ++i ) - // controllers.push_back( new Wiimote( i ) ); -}; - -Plugin::~Plugin() -{ - // delete pads - std::vector::const_iterator i = controllers.begin(), - e = controllers.end(); - for ( ; i != e; ++i ) - delete *i; -} - -void Plugin::LoadConfig() -{ - IniFile inifile; - - std::ifstream file; - file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() ); - inifile.Load( file ); - file.close(); - - std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), - e = controllers.end(); - for ( ; i!=e; ++i ) - (*i)->LoadConfig( inifile[ (*i)->GetName() ] ); -} - -void Plugin::SaveConfig() -{ - IniFile inifile; - - std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), - e = controllers.end(); - for ( ; i!=e; ++i ) - (*i)->SaveConfig( inifile[ (*i)->GetName() ] ); - - // dont need to save empty values - //inifile.Clean(); - - std::ofstream file; - file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() ); - inifile.Save( file ); - file.close(); -} + +#include "Config.h" + +Plugin::Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name ) + : ini_name(_ini_name) + , gui_name(_gui_name) + , profile_name(_profile_name) +{ + // GCPads + //for ( unsigned int i = 0; i<4; ++i ) + //controllers.push_back( new GCPad( i ) ); + // Wiimotes / disabled, cause it only the GUI half is done + //for ( unsigned int i = 0; i<4; ++i ) + // controllers.push_back( new Wiimote( i ) ); +}; + +Plugin::~Plugin() +{ + // delete pads + std::vector::const_iterator i = controllers.begin(), + e = controllers.end(); + for ( ; i != e; ++i ) + delete *i; +} + +void Plugin::LoadConfig() +{ + IniFile inifile; + + std::ifstream file; + file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() ); + inifile.Load( file ); + file.close(); + + std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), + e = controllers.end(); + for ( ; i!=e; ++i ) + (*i)->LoadConfig( inifile[ (*i)->GetName() ] ); +} + +void Plugin::SaveConfig() +{ + IniFile inifile; + + std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), + e = controllers.end(); + for ( ; i!=e; ++i ) + (*i)->SaveConfig( inifile[ (*i)->GetName() ] ); + + // dont need to save empty values + //inifile.Clean(); + + std::ofstream file; + file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() ); + inifile.Save( file ); + file.close(); +} diff --git a/Source/Core/InputCommon/Src/InputConfig.h b/Source/Plugins/InputPluginCommon/Src/Config.h similarity index 86% rename from Source/Core/InputCommon/Src/InputConfig.h rename to Source/Plugins/InputPluginCommon/Src/Config.h index 51379a33fc..8ab222efc2 100644 --- a/Source/Core/InputCommon/Src/InputConfig.h +++ b/Source/Plugins/InputPluginCommon/Src/Config.h @@ -1,33 +1,36 @@ -#pragma once - -#include "ControllerInterface/ControllerInterface.h" -#include "Thread.h" -#include "FileUtil.h" -#include "IniFile.h" - -#include "ControllerEmu.h" - -#include -#include -#include -#include - -class Plugin -{ -public: - - Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name ); - ~Plugin(); - - void LoadConfig(); - void SaveConfig(); - - std::vector< ControllerEmu* > controllers; - - Common::CriticalSection controls_crit, interface_crit; // lock controls first - ControllerInterface controller_interface; - - const char * const ini_name; - const char * const gui_name; - const char * const profile_name; -}; +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#include +#include "Thread.h" +#include "FileUtil.h" +#include "IniFile.h" + +#include "ControllerEmu.h" + +#include +#include +#include +#include + +class Plugin +{ +public: + + Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name ); + ~Plugin(); + + void LoadConfig(); + void SaveConfig(); + + std::vector< ControllerEmu* > controllers; + + Common::CriticalSection controls_crit, interface_crit; // lock controls first + ControllerInterface controller_interface; + + const char * const ini_name; + const char * const gui_name; + const char * const profile_name; +}; + +#endif diff --git a/Source/Plugins/InputUICommon/Src/ConfigDiag.cpp b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp similarity index 98% rename from Source/Plugins/InputUICommon/Src/ConfigDiag.cpp rename to Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp index 73ae592a38..fa6e490c3b 100644 --- a/Source/Plugins/InputUICommon/Src/ConfigDiag.cpp +++ b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp @@ -3,7 +3,7 @@ #define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s ); -static Plugin* g_plugin;//WTF?TODOSHUFFLE +static Plugin* g_plugin; void GamepadPage::ConfigExtension( wxCommandEvent& event ) { @@ -283,7 +283,7 @@ void GamepadPage::ClearAll( wxCommandEvent& event ) g_plugin->controls_crit.Enter(); // enter // just load an empty ini section to clear everything :P - Section section; + IniSection section; controller->LoadConfig( section ); // no point in using the real ControllerInterface i guess @@ -516,26 +516,29 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con UpdateListContents(); } -void GamepadPage::LoadProfile(wxCommandEvent& event) +void GamepadPage::LoadProfile( wxCommandEvent& event ) { // TODO: check for dumb characters maybe - if (profile_cbox->GetValue().empty()) + if ( profile_cbox->GetValue().empty() ) return; g_plugin->controls_crit.Enter(); + std::ifstream file; std::string fname( File::GetUserPath(D_CONFIG_IDX) ); fname += PROFILES_PATH; fname += g_plugin->profile_name; fname += '/'; fname += profile_cbox->GetValue().ToAscii(); fname += ".ini"; - if (false == File::Exists(fname.c_str())) + if ( false == File::Exists( fname.c_str() ) ) return; + file.open( fname.c_str() ); IniFile inifile; - inifile.Load(fname); - controller->LoadConfig(inifile["Profile"]); + inifile.Load( file ); + controller->LoadConfig( inifile["Profile"] ); + file.close(); - controller->UpdateReferences(g_plugin->controller_interface); + controller->UpdateReferences( g_plugin->controller_interface ); g_plugin->controls_crit.Leave(); @@ -560,7 +563,9 @@ void GamepadPage::SaveProfile( wxCommandEvent& event ) fname += profile_cbox->GetValue().ToAscii(); fname += ".ini"; - inifile.Save(fname); + file.open( fname.c_str() ); + inifile.Save( file ); + file.close(); m_config_dialog->UpdateProfileComboBox(); } diff --git a/Source/Plugins/InputUICommon/Src/ConfigDiag.h b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h similarity index 99% rename from Source/Plugins/InputUICommon/Src/ConfigDiag.h rename to Source/Plugins/InputPluginCommon/Src/ConfigDiag.h index b5f7f2e072..9a2219b228 100644 --- a/Source/Plugins/InputUICommon/Src/ConfigDiag.h +++ b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h @@ -22,7 +22,7 @@ #include #include -#include +#include "Config.h" #include "FileSearch.h" class PadSetting diff --git a/Source/Plugins/InputUICommon/Src/ConfigDiagBitmaps.cpp b/Source/Plugins/InputPluginCommon/Src/ConfigDiagBitmaps.cpp similarity index 100% rename from Source/Plugins/InputUICommon/Src/ConfigDiagBitmaps.cpp rename to Source/Plugins/InputPluginCommon/Src/ConfigDiagBitmaps.cpp diff --git a/Source/Core/InputCommon/Src/ControllerEmu.cpp b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp similarity index 88% rename from Source/Core/InputCommon/Src/ControllerEmu.cpp rename to Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp index e94a9b70d8..6422f59eb4 100644 --- a/Source/Core/InputCommon/Src/ControllerEmu.cpp +++ b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp @@ -1,350 +1,344 @@ -#include "ControllerEmu.h" - -#if defined(HAVE_X11) && HAVE_X11 -#include -#endif - -ControllerEmu::~ControllerEmu() -{ - // control groups - std::vector::const_iterator - i = groups.begin(), - e = groups.end(); - for ( ; i!=e; ++i ) - delete *i; -} - -ControllerEmu::ControlGroup::~ControlGroup() -{ - // controls - std::vector::const_iterator - ci = controls.begin(), - ce = controls.end(); - for ( ; ci!=ce; ++ci ) - delete *ci; - - // settings - std::vector::const_iterator - si = settings.begin(), - se = settings.end(); - for ( ; si!=se; ++si ) - delete *si; -} - -ControllerEmu::Extension::~Extension() -{ - // attachments - std::vector::const_iterator - ai = attachments.begin(), - ae = attachments.end(); - for ( ; ai!=ae; ++ai ) - delete *ai; -} -ControllerEmu::ControlGroup::Control::~Control() -{ - delete control_ref; -} - -void ControllerEmu::UpdateReferences( ControllerInterface& devi ) -{ - std::vector::const_iterator - i = groups.begin(), - e = groups.end(); - for ( ; i!=e; ++i ) - { - std::vector::const_iterator - ci = (*i)->controls.begin(), - ce = (*i)->controls.end(); - for ( ; ci!=ce; ++ci ) - devi.UpdateReference( (*ci)->control_ref ); - - // extension - if ( GROUP_TYPE_EXTENSION == (*i)->type ) - { - std::vector::const_iterator - ai = ((Extension*)*i)->attachments.begin(), - ae = ((Extension*)*i)->attachments.end(); - for ( ; ai!=ae; ++ai ) - (*ai)->UpdateReferences( devi ); - } - } -} - -void ControllerEmu::UpdateDefaultDevice() -{ - std::vector::const_iterator - i = groups.begin(), - e = groups.end(); - for ( ; i!=e; ++i ) - { - std::vector::const_iterator - ci = (*i)->controls.begin(), - ce = (*i)->controls.end(); - for ( ; ci!=ce; ++ci ) - (*ci)->control_ref->device_qualifier = default_device; - - // extension - if ( GROUP_TYPE_EXTENSION == (*i)->type ) - { - std::vector::const_iterator - ai = ((Extension*)*i)->attachments.begin(), - ae = ((Extension*)*i)->attachments.end(); - for ( ; ai!=ae; ++ai ) - { - (*ai)->default_device = default_device; - (*ai)->UpdateDefaultDevice(); - } - } - } -} - -void ControllerEmu::ControlGroup::LoadConfig( Section& sec, const std::string& defdev, const std::string& base ) -{ - std::string group( base + name ); group += "/"; - - // settings - std::vector::const_iterator - si = settings.begin(), - se = settings.end(); - for ( ; si!=se; ++si ) +#include "ControllerEmu.h" + +#if defined(HAVE_X11) && HAVE_X11 +#include +#endif + +ControllerEmu::~ControllerEmu() +{ + // control groups + std::vector::const_iterator + i = groups.begin(), + e = groups.end(); + for ( ; i!=e; ++i ) + delete *i; +} + +ControllerEmu::ControlGroup::~ControlGroup() +{ + // controls + std::vector::const_iterator + ci = controls.begin(), + ce = controls.end(); + for ( ; ci!=ce; ++ci ) + delete *ci; + + // settings + std::vector::const_iterator + si = settings.begin(), + se = settings.end(); + for ( ; si!=se; ++si ) + delete *si; +} + +ControllerEmu::Extension::~Extension() +{ + // attachments + std::vector::const_iterator + ai = attachments.begin(), + ae = attachments.end(); + for ( ; ai!=ae; ++ai ) + delete *ai; +} +ControllerEmu::ControlGroup::Control::~Control() +{ + delete control_ref; +} + +void ControllerEmu::UpdateReferences( ControllerInterface& devi ) +{ + std::vector::const_iterator + i = groups.begin(), + e = groups.end(); + for ( ; i!=e; ++i ) { - sec.Get(group+(*si)->name, &(*si)->value, (*si)->default_value*100); - (*si)->value /= 100; - } - - // controls - std::vector::const_iterator - ci = controls.begin(), - ce = controls.end(); - for ( ; ci!=ce; ++ci ) - { - // control and dev qualifier - (*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name]; - std::string tmpdevstr; - sec.Get( group+(*ci)->name+"/Device", &tmpdevstr, defdev ); - (*ci)->control_ref->device_qualifier.FromString(tmpdevstr); + std::vector::const_iterator + ci = (*i)->controls.begin(), + ce = (*i)->controls.end(); + for ( ; ci!=ce; ++ci ) + devi.UpdateReference( (*ci)->control_ref ); + + // extension + if ( GROUP_TYPE_EXTENSION == (*i)->type ) + { + std::vector::const_iterator + ai = ((Extension*)*i)->attachments.begin(), + ae = ((Extension*)*i)->attachments.end(); + for ( ; ai!=ae; ++ai ) + (*ai)->UpdateReferences( devi ); + } + } +} + +void ControllerEmu::UpdateDefaultDevice() +{ + std::vector::const_iterator + i = groups.begin(), + e = groups.end(); + for ( ; i!=e; ++i ) + { + std::vector::const_iterator + ci = (*i)->controls.begin(), + ce = (*i)->controls.end(); + for ( ; ci!=ce; ++ci ) + (*ci)->control_ref->device_qualifier = default_device; + + // extension + if ( GROUP_TYPE_EXTENSION == (*i)->type ) + { + std::vector::const_iterator + ai = ((Extension*)*i)->attachments.begin(), + ae = ((Extension*)*i)->attachments.end(); + for ( ; ai!=ae; ++ai ) + { + (*ai)->default_device = default_device; + (*ai)->UpdateDefaultDevice(); + } + } + } +} + +void ControllerEmu::ControlGroup::LoadConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base ) +{ + std::string group( base + name ); group += "/"; + + // settings + std::vector::const_iterator + si = settings.begin(), + se = settings.end(); + for ( ; si!=se; ++si ) + (*si)->value = sec.Get(group+(*si)->name, (*si)->default_value*100) / 100; + + // controls + std::vector::const_iterator + ci = controls.begin(), + ce = controls.end(); + for ( ; ci!=ce; ++ci ) + { + // control and dev qualifier + (*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name]; + (*ci)->control_ref->device_qualifier.FromString( sec.Get( group+(*ci)->name+"/Device", defdev ) ); // range - sec.Get( group+(*ci)->name+"/Range", &(*ci)->control_ref->range, 100.0f ); - (*ci)->control_ref->range /= 100; + (*ci)->control_ref->range = sec.Get( group+(*ci)->name+"/Range", 100.0f ) / 100; // input mode if ( (*ci)->control_ref->is_input ) - sec.Get( group+(*ci)->name+"/Mode", - &((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, 0 ); - } - - // extensions - if ( GROUP_TYPE_EXTENSION == type ) - { - Extension* const ex = ((Extension*)this); - - ex->switch_extension = 0; - unsigned int n = 0; - const std::string extname = sec[ base + name ]; - - std::vector::const_iterator - ai = ((Extension*)this)->attachments.begin(), - ae = ((Extension*)this)->attachments.end(); - for ( ; ai!=ae; ++ai,++n ) - { - (*ai)->default_device.FromString( defdev ); - (*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" ); - - if ( (*ai)->GetName() == extname ) - ex->switch_extension = n; - } - } -} - -void ControllerEmu::LoadConfig( Section& sec, const std::string& base ) -{ - std::string defdev = default_device.ToString(); - if ( base.empty() ) - { - defdev = sec[ base + "Device" ]; - default_device.FromString( defdev ); - } - - std::vector::const_iterator i = groups.begin(), - e = groups.end(); - for ( ; i!=e; ++i ) - (*i)->LoadConfig( sec, defdev, base ); -} - -void ControllerEmu::ControlGroup::SaveConfig( Section& sec, const std::string& defdev, const std::string& base ) -{ - std::string group( base + name ); group += "/"; - - // settings - std::vector::const_iterator - si = settings.begin(), - se = settings.end(); - for ( ; si!=se; ++si ) - sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 ); - - // controls - std::vector::const_iterator - ci = controls.begin(), - ce = controls.end(); - for ( ; ci!=ce; ++ci ) - { - // control and dev qualifier - sec.Set( group+(*ci)->name, (*ci)->control_ref->control_qualifier.name ); - sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), defdev ); - - // range - sec.Set( group+(*ci)->name+"/Range", (*ci)->control_ref->range*100, 100 ); - - // input mode - if ( (*ci)->control_ref->is_input ) - sec.Set( group+(*ci)->name+"/Mode", - ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, (unsigned int)0 ); - } - - // extensions - if ( GROUP_TYPE_EXTENSION == type ) - { - Extension* const ext = ((Extension*)this); - sec.Set( base + name, ext->attachments[ext->switch_extension]->GetName(), std::string("None") ); - - std::vector::const_iterator - ai = ((Extension*)this)->attachments.begin(), - ae = ((Extension*)this)->attachments.end(); - for ( ; ai!=ae; ++ai ) - (*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" ); - } -} - -void ControllerEmu::SaveConfig( Section& sec, const std::string& base ) -{ - const std::string defdev = default_device.ToString(); - if ( base.empty() ) - sec.Set( std::string(" ") + base + "Device", defdev ); - - std::vector::const_iterator i = groups.begin(), - e = groups.end(); - for ( ; i!=e; ++i ) - (*i)->SaveConfig( sec, defdev, base ); -} - -ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK ) -{ - for ( unsigned int i = 0; i < 4; ++i ) - controls.push_back( new Input( named_directions[i] ) ); - - controls.push_back( new Input( "Modifier" ) ); - - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); - settings.push_back( new Setting("Square Stick", 0 ) ); - -} - -ControllerEmu::Buttons::Buttons( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_BUTTONS ) -{ - settings.push_back( new Setting("Threshold", 0.5f ) ); -} - -ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_MIXED_TRIGGERS ) -{ - settings.push_back( new Setting("Threshold", 0.9f ) ); -} - -ControllerEmu::Triggers::Triggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TRIGGERS ) -{ - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); -} - -ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE ) -{ - controls.push_back( new Input( "Up" ) ); - controls.push_back( new Input( "Down" ) ); - controls.push_back( new Input( "Left" ) ); - controls.push_back( new Input( "Right" ) ); - controls.push_back( new Input( "Forward" ) ); - controls.push_back( new Input( "Backward" ) ); - controls.push_back( new Input( "Modifier" ) ); - - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); -} - -ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TILT ) -{ - //for ( unsigned int i = 0; i < 4; ++i ) - //controls.push_back( new Input( named_directions[i] ) ); - controls.push_back( new Input( "Forward" ) ); - controls.push_back( new Input( "Backward" ) ); - controls.push_back( new Input( "Left" ) ); - controls.push_back( new Input( "Right" ) ); - - controls.push_back( new Input( "Modifier" ) ); - - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); - settings.push_back( new Setting("Circle Stick", 0 ) ); -} - -ControllerEmu::Cursor::Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize ) - : ControlGroup( _name, GROUP_TYPE_CURSOR ) - //, z(0) - , wiimote_initialize(_wiimote_initialize) -{ - for ( unsigned int i = 0; i < 4; ++i ) - controls.push_back( new Input( named_directions[i] ) ); - controls.push_back( new Input( "Forward" ) ); - controls.push_back( new Input( "Hide" ) ); - - settings.push_back( new Setting("Center", 0.5f ) ); - settings.push_back( new Setting("Width", 0.5f ) ); - settings.push_back( new Setting("Height", 0.5f ) ); - -} - -void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize) -{ -#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11)) - unsigned int win_width = 2, win_height = 2; -#endif - -#ifdef _WIN32 - // Get the cursor position for the entire screen - POINT point = { 1, 1 }; - GetCursorPos(&point); - // Get the cursor position relative to the upper left corner of the rendering window - ScreenToClient(wiimote_initialize->hWnd, &point); - - // Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.) - RECT Rect; - GetClientRect(wiimote_initialize->hWnd, &Rect); - // Width and height is the size of the rendering window - win_width = Rect.right - Rect.left; - win_height = Rect.bottom - Rect.top; - -#elif defined(HAVE_X11) && HAVE_X11 - int root_x, root_y; - struct - { - int x, y; - } point = { 1, 1 }; - - Display* const wm_display = (Display*)wiimote_initialize->hWnd; - Window glwin = *(Window *)wiimote_initialize->pXWindow; - - XWindowAttributes win_attribs; - XGetWindowAttributes (wm_display, glwin, &win_attribs); - win_width = win_attribs.width; - win_height = win_attribs.height; - Window root_dummy, child_win; - unsigned int mask; - XQueryPointer(wm_display, glwin, &root_dummy, &child_win, &root_x, &root_y, &point.x, &point.y, &mask); -#endif - -#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11)) - // Return the mouse position as a range from -1 to 1 - x = (float)point.x / (float)win_width * 2 - 1; - y = (float)point.y / (float)win_height * 2 - 1; -#else - x = 0; - y = 0; -#endif - -} + ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode + = sec.Get( group+(*ci)->name+"/Mode", 0 ); + } + + // extensions + if ( GROUP_TYPE_EXTENSION == type ) + { + Extension* const ex = ((Extension*)this); + + ex->switch_extension = 0; + unsigned int n = 0; + const std::string extname = sec[ base + name ]; + + std::vector::const_iterator + ai = ((Extension*)this)->attachments.begin(), + ae = ((Extension*)this)->attachments.end(); + for ( ; ai!=ae; ++ai,++n ) + { + (*ai)->default_device.FromString( defdev ); + (*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" ); + + if ( (*ai)->GetName() == extname ) + ex->switch_extension = n; + } + } +} + +void ControllerEmu::LoadConfig( IniFile::Section& sec, const std::string& base ) +{ + std::string defdev = default_device.ToString(); + if ( base.empty() ) + { + defdev = sec[ base + "Device" ]; + default_device.FromString( defdev ); + } + + std::vector::const_iterator i = groups.begin(), + e = groups.end(); + for ( ; i!=e; ++i ) + (*i)->LoadConfig( sec, defdev, base ); +} + +void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base ) +{ + std::string group( base + name ); group += "/"; + + // settings + std::vector::const_iterator + si = settings.begin(), + se = settings.end(); + for ( ; si!=se; ++si ) + sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 ); + + // controls + std::vector::const_iterator + ci = controls.begin(), + ce = controls.end(); + for ( ; ci!=ce; ++ci ) + { + // control and dev qualifier + sec.Set( group+(*ci)->name, (*ci)->control_ref->control_qualifier.name ); + sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), defdev ); + + // range + sec.Set( group+(*ci)->name+"/Range", (*ci)->control_ref->range*100, 100 ); + + // input mode + if ( (*ci)->control_ref->is_input ) + sec.Set( group+(*ci)->name+"/Mode", + ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, (unsigned int)0 ); + } + + // extensions + if ( GROUP_TYPE_EXTENSION == type ) + { + Extension* const ext = ((Extension*)this); + sec.Set( base + name, ext->attachments[ext->switch_extension]->GetName(), std::string("None") ); + + std::vector::const_iterator + ai = ((Extension*)this)->attachments.begin(), + ae = ((Extension*)this)->attachments.end(); + for ( ; ai!=ae; ++ai ) + (*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" ); + } +} + +void ControllerEmu::SaveConfig( IniFile::Section& sec, const std::string& base ) +{ + const std::string defdev = default_device.ToString(); + if ( base.empty() ) + sec.Set( std::string(" ") + base + "Device", defdev ); + + std::vector::const_iterator i = groups.begin(), + e = groups.end(); + for ( ; i!=e; ++i ) + (*i)->SaveConfig( sec, defdev, base ); +} + +ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK ) +{ + for ( unsigned int i = 0; i < 4; ++i ) + controls.push_back( new Input( named_directions[i] ) ); + + controls.push_back( new Input( "Modifier" ) ); + + settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); + settings.push_back( new Setting("Square Stick", 0 ) ); + +} + +ControllerEmu::Buttons::Buttons( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_BUTTONS ) +{ + settings.push_back( new Setting("Threshold", 0.5f ) ); +} + +ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_MIXED_TRIGGERS ) +{ + settings.push_back( new Setting("Threshold", 0.9f ) ); +} + +ControllerEmu::Triggers::Triggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TRIGGERS ) +{ + settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); +} + +ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE ) +{ + controls.push_back( new Input( "Up" ) ); + controls.push_back( new Input( "Down" ) ); + controls.push_back( new Input( "Left" ) ); + controls.push_back( new Input( "Right" ) ); + controls.push_back( new Input( "Forward" ) ); + controls.push_back( new Input( "Backward" ) ); + controls.push_back( new Input( "Modifier" ) ); + + settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); +} + +ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TILT ) +{ + //for ( unsigned int i = 0; i < 4; ++i ) + //controls.push_back( new Input( named_directions[i] ) ); + controls.push_back( new Input( "Forward" ) ); + controls.push_back( new Input( "Backward" ) ); + controls.push_back( new Input( "Left" ) ); + controls.push_back( new Input( "Right" ) ); + + controls.push_back( new Input( "Modifier" ) ); + + settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); + settings.push_back( new Setting("Circle Stick", 0 ) ); +} + +ControllerEmu::Cursor::Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize ) + : ControlGroup( _name, GROUP_TYPE_CURSOR ) + //, z(0) + , wiimote_initialize(_wiimote_initialize) +{ + for ( unsigned int i = 0; i < 4; ++i ) + controls.push_back( new Input( named_directions[i] ) ); + controls.push_back( new Input( "Forward" ) ); + controls.push_back( new Input( "Hide" ) ); + + settings.push_back( new Setting("Center", 0.5f ) ); + settings.push_back( new Setting("Width", 0.5f ) ); + settings.push_back( new Setting("Height", 0.5f ) ); + +} + +void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize) +{ +#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11)) + unsigned int win_width = 2, win_height = 2; +#endif + +#ifdef _WIN32 + // Get the cursor position for the entire screen + POINT point = { 1, 1 }; + GetCursorPos(&point); + // Get the cursor position relative to the upper left corner of the rendering window + ScreenToClient(wiimote_initialize->hWnd, &point); + + // Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.) + RECT Rect; + GetClientRect(wiimote_initialize->hWnd, &Rect); + // Width and height is the size of the rendering window + win_width = Rect.right - Rect.left; + win_height = Rect.bottom - Rect.top; + +#elif defined(HAVE_X11) && HAVE_X11 + int root_x, root_y; + struct + { + int x, y; + } point = { 1, 1 }; + + Display* const wm_display = (Display*)wiimote_initialize->hWnd; + Window glwin = *(Window *)wiimote_initialize->pXWindow; + + XWindowAttributes win_attribs; + XGetWindowAttributes (wm_display, glwin, &win_attribs); + win_width = win_attribs.width; + win_height = win_attribs.height; + Window root_dummy, child_win; + unsigned int mask; + XQueryPointer(wm_display, glwin, &root_dummy, &child_win, &root_x, &root_y, &point.x, &point.y, &mask); +#endif + +#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11)) + // Return the mouse position as a range from -1 to 1 + x = (float)point.x / (float)win_width * 2 - 1; + y = (float)point.y / (float)win_height * 2 - 1; +#else + x = 0; + y = 0; +#endif + +} diff --git a/Source/Core/InputCommon/Src/ControllerEmu.h b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h similarity index 92% rename from Source/Core/InputCommon/Src/ControllerEmu.h rename to Source/Plugins/InputPluginCommon/Src/ControllerEmu.h index 875cb0ffeb..d5eeee962d 100644 --- a/Source/Core/InputCommon/Src/ControllerEmu.h +++ b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h @@ -1,392 +1,398 @@ -#pragma once - -// windows crap -#define NOMINMAX - -#include "../../../PluginSpecs/pluginspecs_wiimote.h" -#include - -#include "ControllerInterface/ControllerInterface.h" -#include "IniFile.h" - -#include -#include -#include - -#define sign(x) ((x)?(x)<0?-1:1:0) - -enum -{ - GROUP_TYPE_OTHER, - GROUP_TYPE_STICK, - GROUP_TYPE_MIXED_TRIGGERS, - GROUP_TYPE_BUTTONS, - GROUP_TYPE_FORCE, - GROUP_TYPE_EXTENSION, - GROUP_TYPE_TILT, - GROUP_TYPE_CURSOR, - GROUP_TYPE_TRIGGERS, -}; - -const char * const named_directions[] = -{ - "Up", - "Down", - "Left", - "Right" -}; - -void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize); - -class ControllerEmu -{ -public: - - class ControlGroup - { - public: - - class Control - { - protected: - Control( ControllerInterface::ControlReference* const _ref, const char * const _name ) - : control_ref(_ref), name(_name){} - public: - - virtual ~Control(); - ControllerInterface::ControlReference* const control_ref; - const char * const name; - - }; - - class Input : public Control - { - public: - - Input( const char * const _name ) - : Control( new ControllerInterface::InputReference, _name ) {} - - }; - - class Output : public Control - { - public: - - Output( const char * const _name ) - : Control( new ControllerInterface::OutputReference, _name ) {} - - }; - - class Setting - { - public: - - Setting(const char* const _name, const ControlState def_value - , const unsigned int _low = 1, const unsigned int _high = 100 ) - : name(_name) - , value(def_value) - , default_value(def_value) - , low(_low) - , high(_high){} - - const char* const name; - ControlState value; - const ControlState default_value; - const unsigned int low, high; - }; - - ControlGroup( const char* const _name, const unsigned int _type = GROUP_TYPE_OTHER ) : name(_name), type(_type) {} - virtual ~ControlGroup(); - - void LoadConfig( Section& sec, const std::string& defdev = "", const std::string& base = "" ); - void SaveConfig( Section& sec, const std::string& defdev = "", const std::string& base = "" ); - - const char* const name; - const unsigned int type; - - std::vector< Control* > controls; - std::vector< Setting* > settings; - - }; - - class AnalogStick : public ControlGroup - { - public: - - template - void GetState( C* const x, C* const y, const unsigned int base, const unsigned int range ) - { - // this is all a mess - - ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); - ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); - - ControlState deadzone = settings[0]->value; - ControlState square = settings[1]->value; - ControlState m = controls[4]->control_ref->State(); - - // modifier code - if ( m ) - { - yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2); - xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2); - } - - // deadzone / square stick code - if ( deadzone || square ) - { - // this section might be all wrong, but its working good enough, i think - - ControlState ang = atan2( yy, xx ); - ControlState ang_sin = sin(ang); - ControlState ang_cos = cos(ang); - - // the amt a full square stick would have at current angle - ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 ); - - // the amt a full stick would have that was ( user setting squareness) at current angle - // i think this is more like a pointed circle rather than a rounded square like it should be - ControlState stick_full = ( 1 + ( square_full - 1 ) * square ); - - ControlState dist = sqrt(xx*xx + yy*yy); - - // dead zone code - dist = std::max( 0.0f, dist - deadzone * stick_full ); - dist /= ( 1 - deadzone ); - - // square stick code - ControlState amt = dist / stick_full; - dist -= ((square_full - 1) * amt * square); - - yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) ); - xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) ); - } - - *y = C( yy * range + base ); - *x = C( xx * range + base ); - } - - AnalogStick( const char* const _name ); - - }; - - class Buttons : public ControlGroup - { - public: - Buttons( const char* const _name ); - - template - void GetState( C* const buttons, const C* bitmasks ) - { - std::vector::iterator i = controls.begin(), - e = controls.end(); - for ( ; i!=e; ++i, ++bitmasks ) - if ( (*i)->control_ref->State() > settings[0]->value ) // threshold - *buttons |= *bitmasks; - } - - }; - - class MixedTriggers : public ControlGroup - { - public: - - template - void GetState( C* const digital, const C* bitmasks, S* analog, const unsigned int range ) - { - const unsigned int trig_count = ((unsigned int) (controls.size() / 2)); - for ( unsigned int i=0; icontrol_ref->State() > settings[0]->value ) //threshold - { - *analog = range; - *digital |= *bitmasks; - } - else - *analog = S(controls[i+trig_count]->control_ref->State() * range); - - } - } - - MixedTriggers( const char* const _name ); - - }; - - class Triggers : public ControlGroup - { - public: - - template - void GetState( S* analog, const unsigned int range ) - { - const unsigned int trig_count = ((unsigned int) (controls.size())); - const ControlState deadzone = settings[0]->value; - for ( unsigned int i=0; icontrol_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range ); - } - - Triggers( const char* const _name ); - - }; - - class Force : public ControlGroup - { - public: - Force( const char* const _name ); - - template - void GetState( C* axis, const u8 base, const R range ) - { - const float deadzone = settings[0]->value; - for ( unsigned int i=0; i<6; i+=2 ) - { - const float state = controls[i+1]->control_ref->State() - controls[i]->control_ref->State(); - if (abs(state) > deadzone) - *axis++ = (C)((state - (deadzone * sign(state))) / (1 - deadzone) * range + base); - //*axis++ = state * range + base; - else - *axis++ = (C)(base); - } - } - }; - - class Tilt : public ControlGroup - { - public: - Tilt( const char* const _name ); - - template - void GetState( C* const x, C* const y, const unsigned int base, const R range ) - { - // this is all a mess - - ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); - ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); - - ControlState deadzone = settings[0]->value; - ControlState circle = settings[1]->value; - ControlState m = controls[4]->control_ref->State(); - - // modifier code - if ( m ) - { - yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2); - xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2); - } - - // deadzone / circle stick code - if ( deadzone || circle ) - { - // this section might be all wrong, but its working good enough, i think - - ControlState ang = atan2( yy, xx ); - ControlState ang_sin = sin(ang); - ControlState ang_cos = cos(ang); - - // the amt a full square stick would have at current angle - ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 ); - - // the amt a full stick would have that was ( user setting circular ) at current angle - // i think this is more like a pointed circle rather than a rounded square like it should be - ControlState stick_full = (square_full * (1 - circle)) + (circle); - - ControlState dist = sqrt(xx*xx + yy*yy); - - // dead zone code - dist = std::max( 0.0f, dist - deadzone * stick_full ); - dist /= (1 - deadzone); - - // circle stick code - ControlState amt = dist / stick_full; - dist += (square_full - 1) * amt * circle; - - yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) ); - xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) ); - } - - *y = C( yy * range + base ); - *x = C( xx * range + base ); - } - }; - - class Cursor : public ControlGroup - { - public: - Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize ); - - template - void GetState( C* const x, C* const y, C* const forward, const bool adjusted = false ) - { - const ControlState z = controls[4]->control_ref->State(); - - // hide - if (controls[5]->control_ref->State() > 0.5f) - { - *x = 10000; *y = 0; *forward = 0; - } - else - { - *forward = z; - float xx, yy; - GetMousePos(xx, yy, wiimote_initialize); - - // use mouse cursor, or user defined mapping if they have something mapped - // this if seems horrible - if ( controls[0]->control_ref->control_qualifier.name.size() || controls[1]->control_ref->control_qualifier.name.size() ) - yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); - else - yy = -yy; - - if ( controls[2]->control_ref->control_qualifier.name.size() || controls[3]->control_ref->control_qualifier.name.size() ) - xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); - - // adjust cursor according to settings - if (adjusted) - { - xx *= ( settings[1]->value * 2 ); - yy *= ( settings[2]->value * 2 ); - yy += ( settings[0]->value - 0.5f ); - } - - *x = xx; - *y = yy; - } - } - - private: - const SWiimoteInitialize* const wiimote_initialize; - - }; - - class Extension : public ControlGroup - { - public: - Extension( const char* const _name ) - : ControlGroup( _name, GROUP_TYPE_EXTENSION ) - , switch_extension(0) - , active_extension(0) {} - ~Extension(); - - void GetState( u8* const data, const bool focus = true ); - - std::vector attachments; - - int switch_extension; - int active_extension; - }; - - virtual ~ControllerEmu(); - - virtual std::string GetName() const = 0; - - void LoadConfig( Section& sec, const std::string& base = "" ); - void SaveConfig( Section& sec, const std::string& base = "" ); - void UpdateDefaultDevice(); - - void UpdateReferences( ControllerInterface& devi ); - - std::vector< ControlGroup* > groups; - - ControllerInterface::DeviceQualifier default_device; - -}; +#ifndef _CONTROLLEREMU_H_ +#define _CONTROLLEREMU_H_ + +// windows crap +#define NOMINMAX + +#include "pluginspecs_pad.h" +#include "pluginspecs_wiimote.h" +//#include +#include + +#include +#include "IniFile.h" + +#include +#include +#include + +#define sign(x) ((x)?(x)<0?-1:1:0) + +enum +{ + GROUP_TYPE_OTHER, + GROUP_TYPE_STICK, + GROUP_TYPE_MIXED_TRIGGERS, + GROUP_TYPE_BUTTONS, + GROUP_TYPE_FORCE, + GROUP_TYPE_EXTENSION, + GROUP_TYPE_TILT, + GROUP_TYPE_CURSOR, + GROUP_TYPE_TRIGGERS, +}; + +const char * const named_directions[] = +{ + "Up", + "Down", + "Left", + "Right" +}; + +void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize); + +class ControllerEmu +{ +public: + + class ControlGroup + { + public: + + class Control + { + protected: + Control( ControllerInterface::ControlReference* const _ref, const char * const _name ) + : control_ref(_ref), name(_name){} + public: + + virtual ~Control(); + ControllerInterface::ControlReference* const control_ref; + const char * const name; + + }; + + class Input : public Control + { + public: + + Input( const char * const _name ) + : Control( new ControllerInterface::InputReference, _name ) {} + + }; + + class Output : public Control + { + public: + + Output( const char * const _name ) + : Control( new ControllerInterface::OutputReference, _name ) {} + + }; + + class Setting + { + public: + + Setting(const char* const _name, const ControlState def_value + , const unsigned int _low = 1, const unsigned int _high = 100 ) + : name(_name) + , value(def_value) + , default_value(def_value) + , low(_low) + , high(_high){} + + const char* const name; + ControlState value; + const ControlState default_value; + const unsigned int low, high; + }; + + ControlGroup( const char* const _name, const unsigned int _type = GROUP_TYPE_OTHER ) : name(_name), type(_type) {} + virtual ~ControlGroup(); + + void LoadConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" ); + void SaveConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" ); + + const char* const name; + const unsigned int type; + + std::vector< Control* > controls; + std::vector< Setting* > settings; + + }; + + class AnalogStick : public ControlGroup + { + public: + + template + void GetState( C* const x, C* const y, const unsigned int base, const unsigned int range ) + { + // this is all a mess + + ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); + ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); + + ControlState deadzone = settings[0]->value; + ControlState square = settings[1]->value; + ControlState m = controls[4]->control_ref->State(); + + // modifier code + if ( m ) + { + yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2); + xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2); + } + + // deadzone / square stick code + if ( deadzone || square ) + { + // this section might be all wrong, but its working good enough, i think + + ControlState ang = atan2( yy, xx ); + ControlState ang_sin = sin(ang); + ControlState ang_cos = cos(ang); + + // the amt a full square stick would have at current angle + ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 ); + + // the amt a full stick would have that was ( user setting squareness) at current angle + // i think this is more like a pointed circle rather than a rounded square like it should be + ControlState stick_full = ( 1 + ( square_full - 1 ) * square ); + + ControlState dist = sqrt(xx*xx + yy*yy); + + // dead zone code + dist = std::max( 0.0f, dist - deadzone * stick_full ); + dist /= ( 1 - deadzone ); + + // square stick code + ControlState amt = dist / stick_full; + dist -= ((square_full - 1) * amt * square); + + yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) ); + xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) ); + } + + *y = C( yy * range + base ); + *x = C( xx * range + base ); + } + + AnalogStick( const char* const _name ); + + }; + + class Buttons : public ControlGroup + { + public: + Buttons( const char* const _name ); + + template + void GetState( C* const buttons, const C* bitmasks ) + { + std::vector::iterator i = controls.begin(), + e = controls.end(); + for ( ; i!=e; ++i, ++bitmasks ) + if ( (*i)->control_ref->State() > settings[0]->value ) // threshold + *buttons |= *bitmasks; + } + + }; + + class MixedTriggers : public ControlGroup + { + public: + + template + void GetState( C* const digital, const C* bitmasks, S* analog, const unsigned int range ) + { + const unsigned int trig_count = ((unsigned int) (controls.size() / 2)); + for ( unsigned int i=0; icontrol_ref->State() > settings[0]->value ) //threshold + { + *analog = range; + *digital |= *bitmasks; + } + else + *analog = S(controls[i+trig_count]->control_ref->State() * range); + + } + } + + MixedTriggers( const char* const _name ); + + }; + + class Triggers : public ControlGroup + { + public: + + template + void GetState( S* analog, const unsigned int range ) + { + const unsigned int trig_count = ((unsigned int) (controls.size())); + const ControlState deadzone = settings[0]->value; + for ( unsigned int i=0; icontrol_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range ); + } + + Triggers( const char* const _name ); + + }; + + class Force : public ControlGroup + { + public: + Force( const char* const _name ); + + template + void GetState( C* axis, const u8 base, const R range ) + { + const float deadzone = settings[0]->value; + for ( unsigned int i=0; i<6; i+=2 ) + { + const float state = controls[i+1]->control_ref->State() - controls[i]->control_ref->State(); + if (abs(state) > deadzone) + *axis++ = (C)((state - (deadzone * sign(state))) / (1 - deadzone) * range + base); + //*axis++ = state * range + base; + else + *axis++ = (C)(base); + } + } + }; + + class Tilt : public ControlGroup + { + public: + Tilt( const char* const _name ); + + template + void GetState( C* const x, C* const y, const unsigned int base, const R range ) + { + // this is all a mess + + ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); + ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); + + ControlState deadzone = settings[0]->value; + ControlState circle = settings[1]->value; + ControlState m = controls[4]->control_ref->State(); + + // modifier code + if ( m ) + { + yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2); + xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2); + } + + // deadzone / circle stick code + if ( deadzone || circle ) + { + // this section might be all wrong, but its working good enough, i think + + ControlState ang = atan2( yy, xx ); + ControlState ang_sin = sin(ang); + ControlState ang_cos = cos(ang); + + // the amt a full square stick would have at current angle + ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 ); + + // the amt a full stick would have that was ( user setting circular ) at current angle + // i think this is more like a pointed circle rather than a rounded square like it should be + ControlState stick_full = (square_full * (1 - circle)) + (circle); + + ControlState dist = sqrt(xx*xx + yy*yy); + + // dead zone code + dist = std::max( 0.0f, dist - deadzone * stick_full ); + dist /= (1 - deadzone); + + // circle stick code + ControlState amt = dist / stick_full; + dist += (square_full - 1) * amt * circle; + + yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) ); + xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) ); + } + + *y = C( yy * range + base ); + *x = C( xx * range + base ); + } + }; + + class Cursor : public ControlGroup + { + public: + Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize ); + + template + void GetState( C* const x, C* const y, C* const forward, const bool adjusted = false ) + { + const ControlState z = controls[4]->control_ref->State(); + + // hide + if (controls[5]->control_ref->State() > 0.5f) + { + *x = 10000; *y = 0; *forward = 0; + } + else + { + *forward = z; + float xx, yy; + GetMousePos(xx, yy, wiimote_initialize); + + // use mouse cursor, or user defined mapping if they have something mapped + // this if seems horrible + if ( controls[0]->control_ref->control_qualifier.name.size() || controls[1]->control_ref->control_qualifier.name.size() ) + yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); + else + yy = -yy; + + if ( controls[2]->control_ref->control_qualifier.name.size() || controls[3]->control_ref->control_qualifier.name.size() ) + xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); + + // adjust cursor according to settings + if (adjusted) + { + xx *= ( settings[1]->value * 2 ); + yy *= ( settings[2]->value * 2 ); + yy += ( settings[0]->value - 0.5f ); + } + + *x = xx; + *y = yy; + } + } + + private: + const SWiimoteInitialize* const wiimote_initialize; + + }; + + class Extension : public ControlGroup + { + public: + Extension( const char* const _name ) + : ControlGroup( _name, GROUP_TYPE_EXTENSION ) + , switch_extension(0) + , active_extension(0) {} + ~Extension(); + + void GetState( u8* const data, const bool focus = true ); + + std::vector attachments; + + int switch_extension; + int active_extension; + }; + + virtual ~ControllerEmu(); + + virtual std::string GetName() const = 0; + + void LoadConfig( IniFile::Section& sec, const std::string& base = "" ); + void SaveConfig( IniFile::Section& sec, const std::string& base = "" ); + void UpdateDefaultDevice(); + + void UpdateReferences( ControllerInterface& devi ); + + std::vector< ControlGroup* > groups; + + ControllerInterface::DeviceQualifier default_device; + +}; + + +#endif diff --git a/Source/Plugins/InputPluginCommon/Src/IniFile.cpp b/Source/Plugins/InputPluginCommon/Src/IniFile.cpp new file mode 100644 index 0000000000..0f10b25452 --- /dev/null +++ b/Source/Plugins/InputPluginCommon/Src/IniFile.cpp @@ -0,0 +1,156 @@ + +#include "IniFile.h" + +// +// TrimChars +// +// trim whitespace, or any, chars from both ends +// +template +std::string TrimChars( const std::string& str, const S space ) +{ + const size_t start = str.find_first_not_of( space ); + + if ( str.npos == start ) + return ""; + + return str.substr( start, str.find_last_not_of( space ) - start + 1 ); +} + +// +// IniSection :: Set +// +// set key's value if it doesn't match the default +// otherwise remove the key from the section if it exists +// +void IniSection::Set( const std::string& key, const std::string& val, const std::string& def ) +{ + if ( val != def ) + operator[](key) = val; + else + { + iterator f = find(key); + if ( f != end() ) + erase( f ); + } +} + +// +// IniSection :: Get +// +// return a key's value if it exists +// otherwise return the default +// +std::string IniSection::Get( const std::string& key, const std::string& def ) +{ + const const_iterator f = find(key); + if ( f != end() ) + if ( false == f->second.empty() ) + return f->second; + return def; +} + +// +// IniFile :: Save +// +// save a file +// +void IniFile::Save( std::ostream& file ) +{ + const_iterator i = begin(), + e = end(); + for ( ; i != e; ++i ) + { + // skip a line at new sections + file << "\n[" << i->first << "]\n"; + Section::const_iterator si = i->second.begin(), + se = i->second.end(); + for ( ; si != se; ++si ) + { + file << si->first << " = "; + // if value has quotes or whitespace, surround it with quotes + if (si->second.find_first_of("\"\t ") != std::string::npos) + file << '"' << si->second << '"'; + else + file << si->second; + file << '\n'; + } + } +} + +// +// IniFile :: Load +// +// load a file +// +void IniFile::Load( std::istream& file ) +{ + const char* const space = "\t\r "; + std::string line; + // start off with an empty section + Section* section = &(*this)[""]; + while ( std::getline( file, line ).good() ) // read a line + { + line = TrimChars(line,space); + if ( line.size() ) + { + switch ( line[0] ) + { + // comment + case '#' : + case ';' : + break; + // section + case '[' : + // kinda odd trimming + section = &(*this)[ TrimChars(line,"][\t\r ") ]; + break; + // key/value + default : + { + std::istringstream ss(line); + std::string key; std::getline( ss, key, '=' ); + std::string val; std::getline( ss, val ); + val = TrimChars(val,space); + // handle quote surrounded values + if (val.length() > 1) + if ('"' == val[0]) + val = val.substr(1, val.length()-2); + + (*section)[ TrimChars(key,space) ] = val; + break; + } + } + } + } + Clean(); +} + +// +// IniFile :: Clean +// +// remove empty key/values and sections +// after trying to access ini sections/values, they are automatically allocated +// this deletes the empty stuff +// +void IniFile::Clean() +{ + iterator i = begin(), + e = end(); + for ( ; i != e; ) + { + Section::iterator si = i->second.begin(), + se = i->second.end(); + for ( ; si != se; ) + { + if ( si->second.empty() ) + i->second.erase( si++ ); + else + ++si; + } + if ( i->second.empty() ) + erase( i++ ); + else + ++i; + } +} diff --git a/Source/Plugins/InputPluginCommon/Src/IniFile.h b/Source/Plugins/InputPluginCommon/Src/IniFile.h new file mode 100644 index 0000000000..583a87bdd1 --- /dev/null +++ b/Source/Plugins/InputPluginCommon/Src/IniFile.h @@ -0,0 +1,61 @@ +#ifndef _INIFILE_H_ +#define _INIFILE_H_ + +#include +#include +#include +#include + +// +// IniFile +// +class IniSection : public std::map< std::string, std::string > +{ +public: + void Set( const std::string& key, const std::string& val, const std::string& def = "" ); + std::string Get( const std::string& key, const std::string& def = "" ); + + template + void Set( const std::string& key, const V& val, const D& def = 0 ) + { + if ( val != def ) + { + std::ostringstream ss; + ss << long(val); + operator[](key) = ss.str(); + } + else + { + iterator f = find(key); + if ( f != end() ) + erase( f ); + } + } + template + V Get( const std::string& key, const V& def = 0 ) + { + const const_iterator f = find(key); + if ( f != end() ) + if ( false == f->second.empty() ) + { + std::istringstream ss(f->second); + int val; + ss >> val; + return V(val); + } + return def; + } +}; + +class IniFile : public std::map< std::string, IniSection > +{ +public: + typedef IniSection Section; + + void Clean(); + void Save( std::ostream& file ); + void Load( std::istream& file ); +}; + + +#endif diff --git a/Source/Plugins/InputPluginCommon/Src/SConscript b/Source/Plugins/InputPluginCommon/Src/SConscript new file mode 100644 index 0000000000..54bd044d8f --- /dev/null +++ b/Source/Plugins/InputPluginCommon/Src/SConscript @@ -0,0 +1,20 @@ +# -*- python -*- + +Import('env') + +files = [ + 'Config.cpp', + 'ControllerEmu.cpp', + 'IniFile.cpp', + ] + +if env['HAVE_WX']: + files += [ + 'ConfigDiagBitmaps.cpp', + 'ConfigDiag.cpp', + ] + + + +env_inputpc = env.Clone() +env_inputpc.StaticLibrary(env['local_libs'] + "inputplugincommon", files) diff --git a/Source/Plugins/InputUICommon/Src/SConscript b/Source/Plugins/InputUICommon/Src/SConscript deleted file mode 100644 index d4d265eefd..0000000000 --- a/Source/Plugins/InputUICommon/Src/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -# -*- python -*- - -Import('env') -if env['HAVE_WX']: - - files = [ - 'ConfigDiagBitmaps.cpp', - 'ConfigDiag.cpp', - 'WXInputBase.cpp' - ] - - env_inputpc = env.Clone() - env_inputpc.StaticLibrary(env['local_libs'] + "inputuicommon", files) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp index 95672a0200..a879ace92b 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp @@ -34,7 +34,7 @@ void CConfig::Load() // first load defaults IniFile file; file.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "DSP.ini").c_str()); - file["Config"].Get("EnableHLEAudio", &m_EnableHLEAudio, true); // Sound Settings + file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, true); // Sound Settings ac_Config.Load(file); } @@ -42,7 +42,7 @@ void CConfig::Save() { IniFile file; file.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "DSP.ini").c_str()); - file["Config"].Set("EnableHLEAudio", m_EnableHLEAudio); // Sound Settings + file.Set("Config", "EnableHLEAudio", m_EnableHLEAudio); // Sound Settings ac_Config.Set(file); file.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "DSP.ini").c_str()); diff --git a/Source/Plugins/Plugin_GCPad/Plugin_GCPad.vcproj b/Source/Plugins/Plugin_GCPad/Plugin_GCPad.vcproj new file mode 100644 index 0000000000..274a960117 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Plugin_GCPad.vcproj @@ -0,0 +1,559 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Plugins/Plugin_GCPad/Src/Config.cpp b/Source/Plugins/Plugin_GCPad/Src/Config.cpp new file mode 100644 index 0000000000..f417349d83 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/Config.cpp @@ -0,0 +1,261 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include + +#include "Common.h" +#include "IniFile.h" +#include "Config.h" +#include "GCPad.h" +#include "FileUtil.h" + +static const char* gcControlNames[] = +{ + "Button_A", + "Button_B", + "Button_X", + "Button_Y", + "Button_Z", + "Button_Start", + + "DPad_Up", + "DPad_Down", + "DPad_Left", + "DPad_Right", + + "Stick_Up", + "Stick_Down", + "Stick_Left", + "Stick_Right", + "Stick_Semi", + + "CStick_Up", + "CStick_Down", + "CStick_Left", + "CStick_Right", + "CStick_Semi", + + "Shoulder_L", + "Shoulder_R", + "Shoulder_Semi_L", + "Shoulder_Semi_R", +}; + +static const int gcDefaultControls[] = +#ifdef _WIN32 + { + 'X', + 'Z', + 'C', + 'S', + 'D', + VK_RETURN, + 'T', + 'G', + 'F', + 'H', + VK_UP, + VK_DOWN, + VK_LEFT, + VK_RIGHT, + VK_LSHIFT, + 'I', + 'K', + 'J', + 'L', + VK_LCONTROL, + 'Q', + 'W', + 0x00, + 0x00, + }; +#elif defined(HAVE_X11) && HAVE_X11 + { + XK_x, // A + XK_z, // B + XK_c, // X + XK_s, // Y + XK_d, // Z + XK_Return, // Start + XK_t, // D-pad up + XK_g, // D-pad down + XK_f, // D-pad left + XK_h, // D-pad right + XK_Up, // Main stick up + XK_Down, // Main stick down + XK_Left, // Main stick left + XK_Right, // Main stick right + XK_Shift_L, // Main stick semi + XK_i, // C-stick up + XK_k, // C-stick down + XK_j, // C-stick left + XK_l, // C-stick right + XK_Control_L, // C-stick semi + XK_q, // L + XK_w, // R + 0x00, // L semi-press + 0x00, // R semi-press + }; +#elif defined(__APPLE__) + // Reference for Cocoa key codes: + // http://boredzo.org/blog/archives/2007-05-22/virtual-key-codes + { + 7, // A (x) + 6, // B (z) + 8, // X (c) + 1, // Y (s) + 2, // Z (d) + 36, // Start (return) + 17, // D-pad up (t) + 5, // D-pad down (g) + 3, // D-pad left (f) + 4, // D-pad right (h) + 126, // Main stick up (up) + 125, // Main stick down (down) + 123, // Main stick left (left) + 124, // Main stick right (right) + 56, // Main stick semi (left shift) + 34, // C-stick up (i) + 40, // C-stick down (k) + 38, // C-stick left (j) + 37, // C-stick right (l) + 59, // C-stick semi (left control) + 12, // L (q) + 13, // R (w) + -1, // L semi-press (none) + -1, // R semi-press (none) + }; +#endif + + +Config g_Config; + +// Run when created +// ----------------- +Config::Config() +{ +} + +// Save settings to file +// --------------------- +void Config::Save() +{ + // Load ini file + IniFile file; + file.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "GCPad.ini").c_str()); + + // ================================================================== + // Global settings + file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter); +#ifdef RERECORDING + file.Set("General", "Recording", g_Config.bRecording); + file.Set("General", "Playback", g_Config.bPlayback); +#endif + + for (int i = 0; i < 4; i++) + { + // ================================================================== + // Slot specific settings only + std::string SectionName = StringFromFormat("GCPad%i", i+1); + file.Set(SectionName.c_str(), "DeviceID", GCMapping[i].ID); + file.Set(SectionName.c_str(), "Axis_Lx", GCMapping[i].AxisMapping.Lx); + file.Set(SectionName.c_str(), "Axis_Ly", GCMapping[i].AxisMapping.Ly); + file.Set(SectionName.c_str(), "Axis_Rx", GCMapping[i].AxisMapping.Rx); + file.Set(SectionName.c_str(), "Axis_Ry", GCMapping[i].AxisMapping.Ry); + file.Set(SectionName.c_str(), "Trigger_L", GCMapping[i].AxisMapping.Tl); + file.Set(SectionName.c_str(), "Trigger_R", GCMapping[i].AxisMapping.Tr); + file.Set(SectionName.c_str(), "DeadZoneL", GCMapping[i].DeadZoneL); + file.Set(SectionName.c_str(), "DeadZoneR", GCMapping[i].DeadZoneR); + file.Set(SectionName.c_str(), "Diagonal", GCMapping[i].Diagonal); + file.Set(SectionName.c_str(), "Square2Circle", GCMapping[i].bSquare2Circle); + file.Set(SectionName.c_str(), "Rumble", GCMapping[i].Rumble); + file.Set(SectionName.c_str(), "RumbleStrength", GCMapping[i].RumbleStrength); + file.Set(SectionName.c_str(), "TriggerType", GCMapping[i].TriggerType); + + file.Set(SectionName.c_str(), "Source_Stick", GCMapping[i].Stick.Main); + file.Set(SectionName.c_str(), "Source_CStick", GCMapping[i].Stick.Sub); + file.Set(SectionName.c_str(), "Source_Shoulder", GCMapping[i].Stick.Shoulder); + + file.Set(SectionName.c_str(), "Pressure_Stick", GCMapping[i].Pressure.Main); + file.Set(SectionName.c_str(), "Pressure_CStick", GCMapping[i].Pressure.Sub); + file.Set(SectionName.c_str(), "Pressure_Shoulder", GCMapping[i].Pressure.Shoulder); + + // ButtonMapping + for (int x = 0; x < LAST_CONSTANT; x++) + file.Set(SectionName.c_str(), gcControlNames[x], GCMapping[i].Button[x]); + } + + file.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "GCPad.ini").c_str()); +} + +// Load settings from file +// ----------------------- +void Config::Load() +{ + // Load file + IniFile file; + file.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "GCPad.ini").c_str()); + + // ================================================================== + // Global settings + file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false); + + for (int i = 0; i < 4; i++) + { + std::string SectionName = StringFromFormat("GCPad%i", i+1); + + file.Get(SectionName.c_str(), "DeviceID", &GCMapping[i].ID, 0); + file.Get(SectionName.c_str(), "Axis_Lx", &GCMapping[i].AxisMapping.Lx, 0); + file.Get(SectionName.c_str(), "Axis_Ly", &GCMapping[i].AxisMapping.Ly, 1); + file.Get(SectionName.c_str(), "Axis_Rx", &GCMapping[i].AxisMapping.Rx, 2); + file.Get(SectionName.c_str(), "Axis_Ry", &GCMapping[i].AxisMapping.Ry, 3); + file.Get(SectionName.c_str(), "Trigger_L", &GCMapping[i].AxisMapping.Tl, 1004); + file.Get(SectionName.c_str(), "Trigger_R", &GCMapping[i].AxisMapping.Tr, 1005); + file.Get(SectionName.c_str(), "DeadZoneL", &GCMapping[i].DeadZoneL, 0); + file.Get(SectionName.c_str(), "DeadZoneR", &GCMapping[i].DeadZoneR, 0); + file.Get(SectionName.c_str(), "Diagonal", &GCMapping[i].Diagonal, 100); + file.Get(SectionName.c_str(), "Square2Circle", &GCMapping[i].bSquare2Circle, false); + file.Get(SectionName.c_str(), "Rumble", &GCMapping[i].Rumble, false); + file.Get(SectionName.c_str(), "RumbleStrength", &GCMapping[i].RumbleStrength, 80); + file.Get(SectionName.c_str(), "TriggerType", &GCMapping[i].TriggerType, 0); + + file.Get(SectionName.c_str(), "Source_Stick", &GCMapping[i].Stick.Main, 0); + file.Get(SectionName.c_str(), "Source_CStick", &GCMapping[i].Stick.Sub, 0); + file.Get(SectionName.c_str(), "Source_Shoulder", &GCMapping[i].Stick.Shoulder, 0); + + file.Get(SectionName.c_str(), "Pressure_Stick", &GCMapping[i].Pressure.Main, DEF_STICK_HALF); + file.Get(SectionName.c_str(), "Pressure_CStick", &GCMapping[i].Pressure.Sub, DEF_STICK_HALF); + file.Get(SectionName.c_str(), "Pressure_Shoulder", &GCMapping[i].Pressure.Shoulder, DEF_TRIGGER_HALF); + + // ButtonMapping + for (int x = 0; x < LAST_CONSTANT; x++) + file.Get(SectionName.c_str(), gcControlNames[x], &GCMapping[i].Button[x], gcDefaultControls[x]); + } +} + diff --git a/Source/Plugins/Plugin_GCPad/Src/Config.h b/Source/Plugins/Plugin_GCPad/Src/Config.h new file mode 100644 index 0000000000..9d99c4b4d7 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/Config.h @@ -0,0 +1,49 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#ifndef _PLUGIN_GCPAD_CONFIG_H +#define _PLUGIN_GCPAD_CONFIG_H + +struct Config +{ + Config(); + void Load(); + void Save(); + + // General + bool bNoTriggerFilter; +#ifdef RERECORDING + bool bRecording; + bool bPlayback; +#endif +}; + +extern Config g_Config; + +#endif // _PLUGIN_GCPAD_CONFIG_H diff --git a/Source/Plugins/Plugin_GCPad/Src/ConfigBox.cpp b/Source/Plugins/Plugin_GCPad/Src/ConfigBox.cpp new file mode 100644 index 0000000000..76ac5477fc --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/ConfigBox.cpp @@ -0,0 +1,823 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include "math.h" // System +#include "ConfigBox.h" +#include "Config.h" +#include "GCPad.h" +#if defined(HAVE_X11) && HAVE_X11 + #include + #include + #include + #include + #include "X11InputBase.h" +#endif + +// The wxWidgets class +BEGIN_EVENT_TABLE(GCPadConfigDialog,wxDialog) + EVT_CLOSE(GCPadConfigDialog::OnClose) + EVT_BUTTON(wxID_OK, GCPadConfigDialog::OnCloseClick) + EVT_BUTTON(wxID_CANCEL, GCPadConfigDialog::OnCloseClick) + EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, GCPadConfigDialog::NotebookPageChanged) + + EVT_CHOICE(IDC_JOYNAME, GCPadConfigDialog::ChangeSettings) + EVT_CHECKBOX(IDC_RUMBLE, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_RUMBLE_STRENGTH, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_DEAD_ZONE_LEFT, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_DEAD_ZONE_RIGHT, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_STICK_DIAGONAL, GCPadConfigDialog::ChangeSettings) + EVT_CHECKBOX(IDC_STICK_S2C, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_TRIGGER_TYPE, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_STICK_SOURCE, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_CSTICK_SOURCE, GCPadConfigDialog::ChangeSettings) + EVT_CHOICE(IDC_TRIGGER_SOURCE, GCPadConfigDialog::ChangeSettings) + EVT_SLIDER(IDS_STICK_PRESS, GCPadConfigDialog::ChangeSettings) + EVT_SLIDER(IDS_CSTICK_PRESS, GCPadConfigDialog::ChangeSettings) + EVT_SLIDER(IDS_TRIGGER_PRESS, GCPadConfigDialog::ChangeSettings) + + EVT_BUTTON(IDB_ANALOG_LEFT_X, GCPadConfigDialog::OnAxisClick) + EVT_BUTTON(IDB_ANALOG_LEFT_Y, GCPadConfigDialog::OnAxisClick) + EVT_BUTTON(IDB_ANALOG_RIGHT_X, GCPadConfigDialog::OnAxisClick) + EVT_BUTTON(IDB_ANALOG_RIGHT_Y, GCPadConfigDialog::OnAxisClick) + EVT_BUTTON(IDB_TRIGGER_L, GCPadConfigDialog::OnAxisClick) + EVT_BUTTON(IDB_TRIGGER_R, GCPadConfigDialog::OnAxisClick) + + EVT_BUTTON(IDB_BTN_A, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_BTN_B, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_BTN_X, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_BTN_Y, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_BTN_Z, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_BTN_START, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_DPAD_UP, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_DPAD_DOWN, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_DPAD_LEFT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_DPAD_RIGHT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_MAIN_UP, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_MAIN_DOWN, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_MAIN_LEFT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_MAIN_RIGHT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_MAIN_SEMI, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SUB_UP, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SUB_DOWN, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SUB_LEFT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SUB_RIGHT, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SUB_SEMI, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SHDR_L, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SHDR_R, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SHDR_SEMI_L, GCPadConfigDialog::OnButtonClick) + EVT_BUTTON(IDB_SHDR_SEMI_R, GCPadConfigDialog::OnButtonClick) + +#if wxUSE_TIMER + EVT_TIMER(IDTM_UPDATE_PAD, GCPadConfigDialog::UpdatePadInfo) + EVT_TIMER(IDTM_BUTTON, GCPadConfigDialog::OnButtonTimer) +#endif +END_EVENT_TABLE() + +GCPadConfigDialog::GCPadConfigDialog(wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style) + : wxDialog(parent, id, title, position, size, style) +{ + // Define values + m_ControlsCreated = false; + m_Page = 0; + + // Create controls + CreateGUIControls(); + +#if wxUSE_TIMER + m_UpdatePadTimer = new wxTimer(this, IDTM_UPDATE_PAD); + m_ButtonMappingTimer = new wxTimer(this, IDTM_BUTTON); + + // Reset values + g_Pressed = 0; + ClickedButton = NULL; + GetButtonWaitingID = 0; + GetButtonWaitingTimer = 0; + + if (NumGoodPads) + { + // Start the constant timer + int TimesPerSecond = 10; + m_UpdatePadTimer->Start(1000 / TimesPerSecond); + } +#endif + + UpdateGUI(); +} + +GCPadConfigDialog::~GCPadConfigDialog() +{ + if (m_ButtonMappingTimer) + { + delete m_ButtonMappingTimer; + m_ButtonMappingTimer = NULL; + } + if (m_UpdatePadTimer) + { + delete m_UpdatePadTimer; + m_UpdatePadTimer = NULL; + } +} + +// Notebook page changed +void GCPadConfigDialog::NotebookPageChanged(wxNotebookEvent& event) +{ + // Update the global variable + m_Page = event.GetSelection(); + // Update GUI + UpdateGUI(); +} + +// Close window +void GCPadConfigDialog::OnClose(wxCloseEvent& event) +{ + // Allow wxWidgets to close the window + //event.Skip(); + + // Stop the timer + if (m_UpdatePadTimer) + m_UpdatePadTimer->Stop(); + if (m_ButtonMappingTimer) + m_ButtonMappingTimer->Stop(); + + EndModal(wxID_CLOSE); +} + +// Button Click +void GCPadConfigDialog::OnCloseClick(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case wxID_OK: + g_Config.Save(); + Close(); // Call OnClose() + break; + case wxID_CANCEL: + g_Config.Load(); + Close(); // Call OnClose() + break; + } +} + +void GCPadConfigDialog::SaveButtonMapping(int Id, int Key) +{ + if (IDB_ANALOG_LEFT_X <= Id && Id <= IDB_TRIGGER_R) + { + GCMapping[m_Page].AxisMapping.Code[Id - IDB_ANALOG_LEFT_X] = Key; + } + else if (IDB_BTN_A <= Id && Id <= IDB_SHDR_SEMI_R) + { + GCMapping[m_Page].Button[Id - IDB_BTN_A] = Key; + } +} + +void GCPadConfigDialog::OnKeyDown(wxKeyEvent& event) +{ + //event.Skip(); + + if(ClickedButton != NULL) + { + // Save the key + g_Pressed = event.GetKeyCode(); + // Handle the keyboard key mapping + + // Allow the escape key to set a blank key + if (g_Pressed == WXK_ESCAPE) + { + SaveButtonMapping(ClickedButton->GetId(), -1); + SetButtonText(ClickedButton->GetId(), wxString()); + } + else + { + #ifdef _WIN32 + BYTE keyState[256]; + GetKeyboardState(keyState); + for (int i = 1; i < 256; ++i) + { + if ((keyState[i] & 0x80) != 0) + { + // Use the left and right specific keys instead of the common ones + if (i == VK_SHIFT || i == VK_CONTROL || i == VK_MENU) continue; + // Update the button label + SetButtonText(ClickedButton->GetId(), + wxString::FromAscii(InputCommon::VKToString(i).c_str())); + // Save the setting + SaveButtonMapping(ClickedButton->GetId(), i); + break; + } + } + #elif defined(HAVE_X11) && HAVE_X11 + char keyStr[128] = {0}; + int XKey = InputCommon::wxCharCodeWXToX(g_Pressed); + InputCommon::XKeyToString(XKey, keyStr); + SetButtonText(ClickedButton->GetId(), + wxString::FromAscii(keyStr)); + SaveButtonMapping(ClickedButton->GetId(), XKey); + #endif + } + EndGetButtons(); + } +} + +// Configure button mapping +void GCPadConfigDialog::OnButtonClick(wxCommandEvent& event) +{ + event.Skip(); + + // Don't allow space to start a new Press Key option, that will interfer with setting a key to space + if (g_Pressed == WXK_SPACE) { g_Pressed = 0; return; } + + if (m_ButtonMappingTimer->IsRunning()) return; + + wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, // Keyboard + wxKeyEventHandler(GCPadConfigDialog::OnKeyDown), + (wxObject*)0, this); + + // Create the button object + ClickedButton = (wxButton *)event.GetEventObject(); + // Save old label so we can revert back + OldLabel = ClickedButton->GetLabel(); + ClickedButton->SetWindowStyle(wxWANTS_CHARS); + ClickedButton->SetLabel(wxT("")); + DoGetButtons(ClickedButton->GetId()); +} + +// Configure axis mapping +void GCPadConfigDialog::OnAxisClick(wxCommandEvent& event) +{ + event.Skip(); + + if (m_ButtonMappingTimer->IsRunning()) return; + + ClickedButton = NULL; + wxButton* pButton = (wxButton *)event.GetEventObject(); + OldLabel = pButton->GetLabel(); + pButton->SetWindowStyle(wxWANTS_CHARS); + pButton->SetLabel(wxT("")); + DoGetButtons(pButton->GetId()); +} + +void GCPadConfigDialog::ChangeSettings(wxCommandEvent& event) +{ + int id = event.GetId(); + + switch (id) + { + case IDC_JOYNAME: + GCMapping[m_Page].ID = m_Joyname[m_Page]->GetSelection(); + GCMapping[m_Page].joy = joyinfo.at(GCMapping[m_Page].ID).joy; + break; + case IDC_DEAD_ZONE_LEFT: + GCMapping[m_Page].DeadZoneL = m_ComboDeadZoneLeft[m_Page]->GetSelection(); + break; + case IDC_DEAD_ZONE_RIGHT: + GCMapping[m_Page].DeadZoneR = m_ComboDeadZoneRight[m_Page]->GetSelection(); + break; + case IDC_STICK_DIAGONAL: + GCMapping[m_Page].Diagonal = 100 - m_ComboDiagonal[m_Page]->GetSelection() * 5; + break; + case IDC_STICK_S2C: + GCMapping[m_Page].bSquare2Circle = m_CheckS2C[m_Page]->IsChecked(); + break; + case IDC_RUMBLE: + GCMapping[m_Page].Rumble = m_CheckRumble[m_Page]->IsChecked(); + break; + case IDC_RUMBLE_STRENGTH: + GCMapping[m_Page].RumbleStrength = m_RumbleStrength[m_Page]->GetSelection() * 10; + break; + case IDC_TRIGGER_TYPE: + GCMapping[m_Page].TriggerType = m_TriggerType[m_Page]->GetSelection(); + break; + case IDC_STICK_SOURCE: + GCMapping[m_Page].Stick.Main = m_Combo_StickSrc[m_Page]->GetSelection(); + break; + case IDC_CSTICK_SOURCE: + GCMapping[m_Page].Stick.Sub = m_Combo_CStickSrc[m_Page]->GetSelection(); + break; + case IDC_TRIGGER_SOURCE: + GCMapping[m_Page].Stick.Shoulder = m_Combo_TriggerSrc[m_Page]->GetSelection(); + break; + case IDS_STICK_PRESS: + GCMapping[m_Page].Pressure.Main = m_Slider_Stick[m_Page]->GetValue(); + break; + case IDS_CSTICK_PRESS: + GCMapping[m_Page].Pressure.Sub = m_Slider_CStick[m_Page]->GetValue(); + break; + case IDS_TRIGGER_PRESS: + GCMapping[m_Page].Pressure.Shoulder = m_Slider_Trigger[m_Page]->GetValue(); + break; + } + + UpdateGUI(); +} + +void GCPadConfigDialog::UpdateGUI() +{ + if(!m_ControlsCreated) + return; + + // Disable all pad items if no pads are detected + bool PadEnabled = NumGoodPads != 0; + + m_Joyname[m_Page]->Enable(PadEnabled); + m_ComboDeadZoneLeft[m_Page]->Enable(PadEnabled); + m_ComboDeadZoneRight[m_Page]->Enable(PadEnabled); + m_CheckS2C[m_Page]->Enable(PadEnabled); + m_ComboDiagonal[m_Page]->Enable(PadEnabled); + m_CheckRumble[m_Page]->Enable(PadEnabled); + m_RumbleStrength[m_Page]->Enable(PadEnabled); + m_TriggerType[m_Page]->Enable(PadEnabled); + for(int i = 0; i <= IDB_TRIGGER_R - IDB_ANALOG_LEFT_X; i++) + m_Button_Analog[i][m_Page]->Enable(PadEnabled); + + wxString tmp; + + m_Joyname[m_Page]->SetSelection(GCMapping[m_Page].ID); + m_ComboDeadZoneLeft[m_Page]->SetSelection(GCMapping[m_Page].DeadZoneL); + m_ComboDeadZoneRight[m_Page]->SetSelection(GCMapping[m_Page].DeadZoneR); + m_ComboDiagonal[m_Page]->SetSelection((100 - GCMapping[m_Page].Diagonal) / 5); + m_CheckS2C[m_Page]->SetValue(GCMapping[m_Page].bSquare2Circle); + m_CheckRumble[m_Page]->SetValue(GCMapping[m_Page].Rumble); + m_RumbleStrength[m_Page]->SetSelection(GCMapping[m_Page].RumbleStrength / 10); + m_TriggerType[m_Page]->SetSelection(GCMapping[m_Page].TriggerType); + + m_Combo_StickSrc[m_Page]->SetSelection(GCMapping[m_Page].Stick.Main); + m_Combo_CStickSrc[m_Page]->SetSelection(GCMapping[m_Page].Stick.Sub); + m_Combo_TriggerSrc[m_Page]->SetSelection(GCMapping[m_Page].Stick.Shoulder); + m_Slider_Stick[m_Page]->SetValue(GCMapping[m_Page].Pressure.Main); + m_Slider_CStick[m_Page]->SetValue(GCMapping[m_Page].Pressure.Sub); + m_Slider_Trigger[m_Page]->SetValue(GCMapping[m_Page].Pressure.Shoulder); + + for (int i = 0; i <= IDB_TRIGGER_R - IDB_ANALOG_LEFT_X; i++) + { + tmp << GCMapping[m_Page].AxisMapping.Code[i]; + m_Button_Analog[i][m_Page]->SetLabel(tmp); + tmp.clear(); + } + +#ifdef _WIN32 + for (int x = 0; x <= IDB_SHDR_SEMI_R - IDB_BTN_A; x++) + { + m_Button_GC[x][m_Page]->SetLabel(wxString::FromAscii( + InputCommon::VKToString(GCMapping[m_Page].Button[x + EGC_A]).c_str())); + } +#elif defined(HAVE_X11) && HAVE_X11 + char keyStr[10] = {0}; + for (int x = 0; x <= IDB_SHDR_SEMI_R - IDB_BTN_A; x++) + { + InputCommon::XKeyToString(GCMapping[m_Page].Button[x + EGC_A], keyStr); + m_Button_GC[x][m_Page]->SetLabel(wxString::FromAscii(keyStr)); + } +#endif + + DoChangeDeadZone(); +} + +void GCPadConfigDialog::CreateGUIControls() +{ + // Search for devices and add them to the device list + wxArrayString StrJoyname; // The string array + if (NumGoodPads > 0) + { + for (int i = 0; i < NumPads; i++) + StrJoyname.Add(wxString::FromAscii(joyinfo[i].Name.c_str())); + } + else + { + StrJoyname.Add(wxT("")); + } + + wxArrayString TextDeadZone; + for (int i = 0; i <= 50; i++) + TextDeadZone.Add(wxString::Format(wxT("%i%%"), i)); + + wxArrayString StrDiagonal; + for (int i = 0; i <= 10; i++) + StrDiagonal.Add(wxString::Format(wxT("%i%%"), 100 - i * 5)); + + wxArrayString StrRumble; + for (int i = 0; i <= 10; i++) + StrRumble.Add(wxString::Format(wxT("%i%%"), i * 10)); + + wxArrayString StrSource; + StrSource.Add(wxT("Keyboard")); + StrSource.Add(wxT("Analog 1")); + StrSource.Add(wxT("Analog 2")); + StrSource.Add(wxT("Triggers")); + + // The Trigger type list + wxArrayString StrTriggerType; + StrTriggerType.Add(wxT("SDL")); // -0x8000 to 0x7fff + StrTriggerType.Add(wxT("XInput")); // 0x00 to 0xff + + static const wxChar* anText[] = + { + wxT("Left X-Axis"), + wxT("Left Y-Axis"), + wxT("Right X-Axis"), + wxT("Right Y-Axis"), + wxT("Left Trigger"), + wxT("Right Trigger"), + }; + + static const wxChar* padText[] = + { + wxT("A"), + wxT("B"), + wxT("X"), + wxT("Y"), + wxT("Z"), + wxT("Start"), + + wxT("Up"), // D-Pad + wxT("Down"), + wxT("Left"), + wxT("Right"), + + wxT("Up"), // Main Stick + wxT("Down"), + wxT("Left"), + wxT("Right"), + wxT("Semi"), + + wxT("Up"), // C-Stick + wxT("Down"), + wxT("Left"), + wxT("Right"), + wxT("Semi"), + + wxT("L"), // Triggers + wxT("R"), + wxT("Semi-L"), + wxT("Semi-R"), + }; + + // Configuration controls sizes + static const int BtW = 70, BtH = 20; + // A small type font + wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + + m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); + + for (int i = 0; i < 4; i++) + { + m_Controller[i] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1 + i, wxDefaultPosition, wxDefaultSize); + m_Notebook->AddPage(m_Controller[i], wxString::Format(wxT("Gamecube Pad %d"), i+1)); + + // Controller + m_Joyname[i] = new wxChoice(m_Controller[i], IDC_JOYNAME, wxDefaultPosition, wxSize(400, -1), StrJoyname, 0, wxDefaultValidator, StrJoyname[0]); + + // Dead zone + m_ComboDeadZoneLabel[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Dead Zone")); + m_ComboDeadZoneLeft[i] = new wxChoice(m_Controller[i], IDC_DEAD_ZONE_LEFT, wxDefaultPosition, wxSize(50, -1), TextDeadZone, 0, wxDefaultValidator, TextDeadZone[0]); + m_ComboDeadZoneRight[i] = new wxChoice(m_Controller[i], IDC_DEAD_ZONE_RIGHT, wxDefaultPosition, wxSize(50, -1), TextDeadZone, 0, wxDefaultValidator, TextDeadZone[0]); + + // Circle to square + m_CheckS2C[i] = new wxCheckBox(m_Controller[i], IDC_STICK_S2C, wxT("Square To Circle")); + m_CheckS2C[i]->SetToolTip(wxT("This will convert a square stick radius to a circle stick radius, which is\n") + wxT("similar to the octagonal area that the original GameCube pad produces.")); + + // The drop down menu for the circle to square adjustment + m_DiagonalLabel[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Diagonal")); + m_DiagonalLabel[i]->SetToolTip(wxT("To produce a perfect circle in the 'Out' window you have to manually set\n") + wxT("your diagonal values here from what is shown in the 'In' window.")); + m_ComboDiagonal[i] = new wxChoice(m_Controller[i], IDC_STICK_DIAGONAL, wxDefaultPosition, wxSize(50, -1), StrDiagonal, 0, wxDefaultValidator, StrDiagonal[0]); + + // Rumble + m_CheckRumble[i] = new wxCheckBox(m_Controller[i], IDC_RUMBLE, wxT("Rumble")); + m_RumbleStrengthLabel[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Strength")); + m_RumbleStrength[i] = new wxChoice(m_Controller[i], IDC_RUMBLE_STRENGTH, wxDefaultPosition, wxSize(50, -1), StrRumble, 0, wxDefaultValidator, StrRumble[0]); + // Sizers + m_sDeadZoneHoriz[i] = new wxBoxSizer(wxHORIZONTAL); + m_sDeadZoneHoriz[i]->Add(m_ComboDeadZoneLeft[i], 0, (wxUP), 0); + m_sDeadZoneHoriz[i]->Add(m_ComboDeadZoneRight[i], 0, (wxUP), 0); + + m_sDeadZone[i] = new wxBoxSizer(wxVERTICAL); + m_sDeadZone[i]->Add(m_ComboDeadZoneLabel[i], 0, wxALIGN_CENTER | (wxUP), 0); + m_sDeadZone[i]->Add(m_sDeadZoneHoriz[i], 0, wxALIGN_CENTER | (wxUP), 2); + + m_sDiagonal[i] = new wxBoxSizer(wxHORIZONTAL); + m_sDiagonal[i]->Add(m_DiagonalLabel[i], 0, (wxUP), 4); + m_sDiagonal[i]->Add(m_ComboDiagonal[i], 0, (wxLEFT), 2); + + m_sSquare2Circle[i] = new wxBoxSizer(wxVERTICAL); + m_sSquare2Circle[i]->Add(m_CheckS2C[i], 0, wxALIGN_CENTER | (wxUP), 0); + m_sSquare2Circle[i]->Add(m_sDiagonal[i], 0, wxALIGN_CENTER | (wxUP), 2); + + m_sRumbleStrength[i] = new wxBoxSizer(wxHORIZONTAL); + m_sRumbleStrength[i]->Add(m_RumbleStrengthLabel[i], 0, (wxUP), 4); + m_sRumbleStrength[i]->Add(m_RumbleStrength[i], 0, (wxLEFT), 2); + + m_sRumble[i] = new wxBoxSizer(wxVERTICAL); + m_sRumble[i]->Add(m_CheckRumble[i], 0, wxALIGN_CENTER | (wxUP), 0); + m_sRumble[i]->Add(m_sRumbleStrength[i], 0, wxALIGN_CENTER | (wxUP), 2); + + m_sS2CDeadZone[i] = new wxBoxSizer(wxHORIZONTAL); + m_sS2CDeadZone[i]->Add(m_sDeadZone[i], 0, (wxUP), 0); + m_sS2CDeadZone[i]->Add(m_sSquare2Circle[i], 0, (wxLEFT), 40); + m_sS2CDeadZone[i]->Add(m_sRumble[i], 0, (wxLEFT), 40); + + m_gJoyPad[i] = new wxStaticBoxSizer (wxVERTICAL, m_Controller[i], wxT("Gamepad")); + m_gJoyPad[i]->AddStretchSpacer(); + m_gJoyPad[i]->Add(m_Joyname[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + m_gJoyPad[i]->Add(m_sS2CDeadZone[i], 0, wxALIGN_CENTER | (wxUP | wxDOWN), 4); + m_gJoyPad[i]->AddStretchSpacer(); + + // Row 1 Sizers: Connected pads, tilt + m_sHorizJoypad[i] = new wxBoxSizer(wxHORIZONTAL); + m_sHorizJoypad[i]->Add(m_gJoyPad[i], 0, wxEXPAND | (wxLEFT), 5); + + + // Stick Status Panels + m_tStatusLeftIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected")); + m_tStatusLeftOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected")); + m_tStatusRightIn[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected")); + m_tStatusRightOut[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Not connected")); + + m_pLeftInStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquareLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDeadZoneLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmapDeadZone(0), wxDefaultPosition, wxDefaultSize); + m_bmpDotLeftIn[i] = new wxStaticBitmap(m_pLeftInStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + m_pLeftOutStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquareLeftOut[i] = new wxStaticBitmap(m_pLeftOutStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDotLeftOut[i] = new wxStaticBitmap(m_pLeftOutStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + m_pRightInStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquareRightIn[i] = new wxStaticBitmap(m_pRightInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDeadZoneRightIn[i] = new wxStaticBitmap(m_pRightInStatus[i], wxID_ANY, CreateBitmapDeadZone(0), wxDefaultPosition, wxDefaultSize); + m_bmpDotRightIn[i] = new wxStaticBitmap(m_pRightInStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + m_pRightOutStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquareRightOut[i] = new wxStaticBitmap(m_pRightOutStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDotRightOut[i] = new wxStaticBitmap(m_pRightOutStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + // Sizers + m_sGridStickLeft[i] = new wxGridBagSizer(0, 0); + m_sGridStickLeft[i]->Add(m_pLeftInStatus[i], wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 0); + m_sGridStickLeft[i]->Add(m_pLeftOutStatus[i], wxGBPosition(0, 1), wxGBSpan(1, 1), wxLEFT, 10); + m_sGridStickLeft[i]->Add(m_tStatusLeftIn[i], wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 0); + m_sGridStickLeft[i]->Add(m_tStatusLeftOut[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxLEFT, 10); + + m_sGridStickRight[i] = new wxGridBagSizer(0, 0); + m_sGridStickRight[i]->Add(m_pRightInStatus[i], wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 0); + m_sGridStickRight[i]->Add(m_pRightOutStatus[i], wxGBPosition(0, 1), wxGBSpan(1, 1), wxLEFT, 10); + m_sGridStickRight[i]->Add(m_tStatusRightIn[i], wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 0); + m_sGridStickRight[i]->Add(m_tStatusRightOut[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxLEFT, 10); + + m_gStickLeft[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 1 Status (In) (Out)")); + m_gStickLeft[i]->Add(m_sGridStickLeft[i], 0, (wxLEFT | wxRIGHT), 5); + + m_gStickRight[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 2 Status (In) (Out)")); + m_gStickRight[i]->Add(m_sGridStickRight[i], 0, (wxLEFT | wxRIGHT), 5); + + // Trigger Status Panels + m_TriggerL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Left: ")); + m_TriggerR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Right: ")); + m_TriggerStatusL[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_TriggerStatusR[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("000"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_tTriggerSource[i]= new wxStaticText(m_Controller[i], wxID_ANY, wxT("Trigger Source")); + m_TriggerType[i] = new wxChoice(m_Controller[i], IDC_TRIGGER_TYPE, wxDefaultPosition, wxSize(70, -1), StrTriggerType, 0, wxDefaultValidator, StrTriggerType[0]); + + // Sizers + m_sGridTrigger[i] = new wxGridBagSizer(0, 0); + m_sGridTrigger[i]->Add(m_TriggerL[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxTOP), 4); + m_sGridTrigger[i]->Add(m_TriggerStatusL[i], wxGBPosition(0, 1), wxGBSpan(1, 1), (wxLEFT | wxTOP), 4); + m_sGridTrigger[i]->Add(m_TriggerR[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxTOP), 4); + m_sGridTrigger[i]->Add(m_TriggerStatusR[i], wxGBPosition(1, 1), wxGBSpan(1, 1), (wxLEFT | wxTOP), 4); + + m_gTriggers[i] = new wxStaticBoxSizer (wxVERTICAL, m_Controller[i], wxT("Triggers Status")); + m_gTriggers[i]->AddStretchSpacer(); + m_gTriggers[i]->Add(m_sGridTrigger[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5); + m_gTriggers[i]->Add(m_tTriggerSource[i], 0, wxEXPAND | (wxUP | wxLEFT | wxRIGHT), 5); + m_gTriggers[i]->Add(m_TriggerType[i], 0, wxEXPAND | (wxUP | wxLEFT | wxRIGHT), 5); + m_gTriggers[i]->AddStretchSpacer(); + + // Row 2 Sizers: Analog status + m_sHorizStatus[i] = new wxBoxSizer(wxHORIZONTAL); + m_sHorizStatus[i]->Add(m_gStickLeft[i], 0, wxEXPAND | (wxLEFT), 5); + m_sHorizStatus[i]->Add(m_gStickRight[i], 0, wxEXPAND | (wxLEFT), 5); + m_sHorizStatus[i]->Add(m_gTriggers[i], 0, wxEXPAND | (wxLEFT), 5); + + + // Analog Axes and Triggers Mapping + m_sAnalogLeft[i] = new wxBoxSizer(wxVERTICAL); + m_sAnalogMiddle[i] = new wxBoxSizer(wxVERTICAL); + m_sAnalogRight[i] = new wxBoxSizer(wxVERTICAL); + + for (int x = 0; x < 6; x++) + { + m_Text_Analog[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, anText[x]); + m_Button_Analog[x][i] = new wxButton(m_Controller[i], x + IDB_ANALOG_LEFT_X, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); + m_Button_Analog[x][i]->SetFont(m_SmallFont); + m_Sizer_Analog[x][i] = new wxBoxSizer(wxHORIZONTAL); + m_Sizer_Analog[x][i]->Add(m_Text_Analog[x][i], 0, (wxUP), 4); + m_Sizer_Analog[x][i]->Add(m_Button_Analog[x][i], 0, (wxLEFT), 2); + if (x < 2) // Make some balance + m_sAnalogLeft[i]->Add(m_Sizer_Analog[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else if (x < 4) + m_sAnalogMiddle[i]->Add(m_Sizer_Analog[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else + m_sAnalogRight[i]->Add(m_Sizer_Analog[x][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + } + + m_gAnalog[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog Axes and Triggers")); + m_gAnalog[i]->Add(m_sAnalogLeft[i], 0, wxALIGN_RIGHT | (wxALL), 0); + m_gAnalog[i]->Add(m_sAnalogMiddle[i], 0, wxALIGN_RIGHT | (wxLEFT), 5); + m_gAnalog[i]->Add(m_sAnalogRight[i], 0, wxALIGN_RIGHT | (wxLEFT), 5); + + // Row 3 Sizes: Analog Mapping + m_sHorizAnalog[i] = new wxBoxSizer(wxHORIZONTAL); + m_sHorizAnalog[i]->Add(m_gAnalog[i], 0, (wxLEFT), 5); + + + // Pad Mapping + m_gButton[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons")); + m_gDPad[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("D-Pad")); + m_gStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Main Stick")); + m_Text_StickSrc[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Source")); + m_Combo_StickSrc[i] = new wxChoice(m_Controller[i], IDC_STICK_SOURCE, wxDefaultPosition, wxSize(70, -1), StrSource, 0, wxDefaultValidator, StrSource[0]); + m_sStickSrc[i] = new wxBoxSizer(wxHORIZONTAL); + m_sStickSrc[i]->Add(m_Text_StickSrc[i], 0, (wxUP), 4); + m_sStickSrc[i]->Add(m_Combo_StickSrc[i], 0, (wxLEFT), 2); + m_gStick[i]->Add(m_sStickSrc[i], 0, wxALIGN_RIGHT | (wxALL), 2); + m_gStick[i]->AddSpacer(2); + m_gCStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("C-Stick")); + m_Text_CStickSrc[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Source")); + m_Combo_CStickSrc[i] = new wxChoice(m_Controller[i], IDC_CSTICK_SOURCE, wxDefaultPosition, wxSize(70, -1), StrSource, 0, wxDefaultValidator, StrSource[0]); + m_sCStickSrc[i] = new wxBoxSizer(wxHORIZONTAL); + m_sCStickSrc[i]->Add(m_Text_CStickSrc[i], 0, (wxUP), 4); + m_sCStickSrc[i]->Add(m_Combo_CStickSrc[i], 0, (wxLEFT), 2); + m_gCStick[i]->Add(m_sCStickSrc[i], 0, wxALIGN_RIGHT | (wxALL), 2); + m_gCStick[i]->AddSpacer(2); + m_gTrigger[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Triggers")); + m_Text_TriggerSrc[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Source")); + m_Combo_TriggerSrc[i] = new wxChoice(m_Controller[i], IDC_TRIGGER_SOURCE, wxDefaultPosition, wxSize(70, -1), StrSource, 0, wxDefaultValidator, StrSource[0]); + m_sTriggerSrc[i] = new wxBoxSizer(wxHORIZONTAL); + m_sTriggerSrc[i]->Add(m_Text_TriggerSrc[i], 0, (wxUP), 4); + m_sTriggerSrc[i]->Add(m_Combo_TriggerSrc[i], 0, (wxLEFT), 2); + m_gTrigger[i]->Add(m_sTriggerSrc[i], 0, wxALIGN_RIGHT | (wxALL), 2); + m_gTrigger[i]->AddSpacer(2); + + for (int x = 0; x <= IDB_SHDR_SEMI_R - IDB_BTN_A; x++) + { + m_Text_Pad[x][i] = new wxStaticText(m_Controller[i], wxID_ANY, padText[x]); + m_Button_GC[x][i] = new wxButton(m_Controller[i], x + IDB_BTN_A, wxEmptyString, wxDefaultPosition, wxSize(BtW, BtH)); + m_Button_GC[x][i]->SetFont(m_SmallFont); + m_Sizer_Pad[x][i] = new wxBoxSizer(wxHORIZONTAL); + m_Sizer_Pad[x][i]->Add(m_Text_Pad[x][i], 0, (wxUP), 4); + m_Sizer_Pad[x][i]->Add(m_Button_GC[x][i], 0, (wxLEFT), 2); + if (x <= IDB_BTN_START) + m_gButton[i]->Add(m_Sizer_Pad[x - IDB_BTN_A][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else if (x <= IDB_DPAD_RIGHT) + m_gDPad[i]->Add(m_Sizer_Pad[x - IDB_BTN_A][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else if (x <= IDB_MAIN_SEMI) + m_gStick[i]->Add(m_Sizer_Pad[x - IDB_BTN_A][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else if (x <= IDB_SUB_SEMI) + m_gCStick[i]->Add(m_Sizer_Pad[x - IDB_BTN_A][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + else + m_gTrigger[i]->Add(m_Sizer_Pad[x - IDB_BTN_A][i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + } + + m_Slider_Stick[i] = new wxSlider(m_Controller[i], IDS_STICK_PRESS, DEF_STICK_HALF, 0, DEF_STICK_FULL, wxDefaultPosition, wxSize(100,-1), wxSL_LABELS | wxSL_TOP); + m_gStick[i]->Add(m_Slider_Stick[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + m_Slider_CStick[i] = new wxSlider(m_Controller[i], IDS_CSTICK_PRESS, DEF_STICK_HALF, 0, DEF_STICK_FULL, wxDefaultPosition, wxSize(100,-1), wxSL_LABELS | wxSL_TOP); + m_gCStick[i]->Add(m_Slider_CStick[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + m_Slider_Trigger[i] = new wxSlider(m_Controller[i], IDS_TRIGGER_PRESS, DEF_TRIGGER_HALF, 0, DEF_TRIGGER_FULL, wxDefaultPosition, wxSize(100,-1), wxSL_LABELS | wxSL_TOP); + m_gTrigger[i]->Add(m_Slider_Trigger[i], 0, wxALIGN_RIGHT | (wxLEFT | wxRIGHT | wxDOWN), 1); + + // Row 4 Sizers: Button Mapping + m_sHorizMapping[i] = new wxBoxSizer(wxHORIZONTAL); + m_sHorizMapping[i]->Add(m_gButton[i], 0, (wxLEFT), 5); + m_sHorizMapping[i]->Add(m_gDPad[i], 0, (wxLEFT), 5); + m_sHorizMapping[i]->Add(m_gStick[i], 0, (wxLEFT), 5); + m_sHorizMapping[i]->Add(m_gCStick[i], 0, (wxLEFT), 5); + m_sHorizMapping[i]->Add(m_gTrigger[i], 0, (wxLEFT), 5); + + + // Set up sizers and layout + // The sizer m_sMain will be expanded inside m_Controller + m_sMain[i] = new wxBoxSizer(wxVERTICAL); + m_sMain[i]->Add(m_sHorizJoypad[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + m_sMain[i]->Add(m_sHorizStatus[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + m_sMain[i]->Add(m_sHorizAnalog[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + m_sMain[i]->Add(m_sHorizMapping[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + + // Set the main sizer + m_Controller[i]->SetSizer(m_sMain[i]); + } + + m_OK = new wxButton(this, wxID_OK, wxT("OK")); + m_OK->SetToolTip(wxT("Save changes and close")); + m_Cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")); + m_Cancel->SetToolTip(wxT("Discard changes and close")); + wxBoxSizer* m_DlgButton = new wxBoxSizer(wxHORIZONTAL); + m_DlgButton->AddStretchSpacer(); + m_DlgButton->Add(m_OK, 0, (wxLEFT), 5); + m_DlgButton->Add(m_Cancel, 0, (wxLEFT), 5); + + m_MainSizer = new wxBoxSizer(wxVERTICAL); + m_MainSizer->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); + m_MainSizer->Add(m_DlgButton, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + + SetSizer(m_MainSizer); + Layout(); + Fit(); + // Center the window if there is room for it + #ifdef _WIN32 + if (GetSystemMetrics(SM_CYFULLSCREEN) > 600) + Center(); + #endif + + m_ControlsCreated = true; +} + +// Bitmap box and dot +wxBitmap GCPadConfigDialog::CreateBitmap() +{ + BoxW = 70, BoxH = 70; + wxBitmap bitmap(BoxW, BoxH); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + wxPen LightBluePen(_T("#7f9db9")); // Windows XP color + dc.SetPen(LightBluePen); + dc.SetBrush(*wxWHITE_BRUSH); + + dc.Clear(); + dc.DrawRectangle(0, 0, BoxW, BoxH); + dc.SelectObject(wxNullBitmap); + return bitmap; +} + +wxBitmap GCPadConfigDialog::CreateBitmapDot() +{ + int w = 2, h = 2; + wxBitmap bitmap(w, h); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + dc.SetPen(*wxRED_PEN); + dc.SetBrush(*wxRED_BRUSH); + + dc.Clear(); + dc.DrawRectangle(0, 0, w, h); + dc.SelectObject(wxNullBitmap); + return bitmap; +} + +wxBitmap GCPadConfigDialog::CreateBitmapDeadZone(int Radius) +{ + wxBitmap bitmap(Radius*2, Radius*2); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + dc.SetPen(*wxLIGHT_GREY_PEN); + dc.SetBrush(*wxLIGHT_GREY_BRUSH); + + //dc.SetBackground(*wxGREEN_BRUSH); + dc.Clear(); + dc.DrawCircle(Radius, Radius, Radius); + dc.SelectObject(wxNullBitmap); + return bitmap; +} + +wxBitmap GCPadConfigDialog::CreateBitmapClear() +{ + wxBitmap bitmap(BoxW, BoxH); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + dc.Clear(); + dc.SelectObject(wxNullBitmap); + return bitmap; +} diff --git a/Source/Plugins/Plugin_GCPad/Src/ConfigBox.h b/Source/Plugins/Plugin_GCPad/Src/ConfigBox.h new file mode 100644 index 0000000000..6c9c1e4e06 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/ConfigBox.h @@ -0,0 +1,243 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#ifndef __GCPAD_CONFIGBOX_h__ +#define __GCPAD_CONFIGBOX_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GCPad.h" + +class GCPadConfigDialog : public wxDialog +{ + public: + GCPadConfigDialog(wxWindow *parent, wxWindowID id = wxID_ANY, + const wxString &title = wxT("Gamecube Pad Plugin Configuration"), + const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE); + virtual ~GCPadConfigDialog(); + + private: + DECLARE_EVENT_TABLE(); + + enum + { + // it's important that they are kept in this order + IDB_BTN_A = 0, + IDB_BTN_B, + IDB_BTN_X, + IDB_BTN_Y, + IDB_BTN_Z, + IDB_BTN_START, + + IDB_DPAD_UP, + IDB_DPAD_DOWN, + IDB_DPAD_LEFT, + IDB_DPAD_RIGHT, + + IDB_MAIN_UP, + IDB_MAIN_DOWN, + IDB_MAIN_LEFT, + IDB_MAIN_RIGHT, + IDB_MAIN_SEMI, + + IDB_SUB_UP, + IDB_SUB_DOWN, + IDB_SUB_LEFT, + IDB_SUB_RIGHT, + IDB_SUB_SEMI, + + IDB_SHDR_L, + IDB_SHDR_R, + IDB_SHDR_SEMI_L, + IDB_SHDR_SEMI_R, + + // Joypad + IDB_ANALOG_LEFT_X, IDB_ANALOG_LEFT_Y, + IDB_ANALOG_RIGHT_X, IDB_ANALOG_RIGHT_Y, + IDB_TRIGGER_L, IDB_TRIGGER_R, + + // Dialog controls + ID_NOTEBOOK = 1000, + ID_CONTROLLERPAGE1, + ID_CONTROLLERPAGE2, + ID_CONTROLLERPAGE3, + ID_CONTROLLERPAGE4, + + // Timers + IDTM_BUTTON, IDTM_UPDATE_PAD, + + // Gamepad settings + IDC_JOYNAME, + IDC_DEAD_ZONE_LEFT, IDC_DEAD_ZONE_RIGHT, + IDC_STICK_DIAGONAL, IDC_STICK_S2C, + IDC_RUMBLE, IDC_RUMBLE_STRENGTH, + IDC_TRIGGER_TYPE, + IDC_STICK_SOURCE, IDC_CSTICK_SOURCE, IDC_TRIGGER_SOURCE, + IDS_STICK_PRESS, IDS_CSTICK_PRESS, IDS_TRIGGER_PRESS, + }; + + wxNotebook *m_Notebook; + + wxPanel *m_Controller[4], + *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]; + + wxSlider *m_Slider_Stick[4], + *m_Slider_CStick[4], + *m_Slider_Trigger[4]; + + wxCheckBox *m_CheckS2C[4], + *m_CheckRumble[4]; + + wxButton *m_OK, *m_Cancel, *ClickedButton, + *m_Button_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][4], + *m_Button_GC[IDB_SHDR_SEMI_R - IDB_BTN_A + 1][4]; + + wxChoice *m_Joyname[4], + *m_ComboDeadZoneLeft[4], + *m_ComboDeadZoneRight[4], + *m_ComboDiagonal[4], + *m_RumbleStrength[4], + *m_TriggerType[4], + *m_Combo_StickSrc[4], + *m_Combo_CStickSrc[4], + *m_Combo_TriggerSrc[4]; + + wxGridBagSizer *m_sGridStickLeft[4], + *m_sGridStickRight[4], + *m_sGridTrigger[4]; + + wxBoxSizer *m_MainSizer, + *m_sMain[4], + *m_sDeadZoneHoriz[4], + *m_sDeadZone[4], + *m_sDiagonal[4], + *m_sSquare2Circle[4], + *m_sS2CDeadZone[4], + *m_sRumbleStrength[4], + *m_sRumble[4], + *m_sHorizJoypad[4], + *m_sHorizStatus[4], + *m_Sizer_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][4], + *m_sAnalogLeft[4], + *m_sAnalogMiddle[4], + *m_sAnalogRight[4], + *m_sHorizAnalog[4], + *m_sStickSrc[4], + *m_sCStickSrc[4], + *m_sTriggerSrc[4], + *m_Sizer_Pad[IDB_SHDR_SEMI_R - IDB_BTN_A + 1][4], + *m_sHorizMapping[4]; + + wxStaticBoxSizer *m_gJoyPad[4], + *m_gStickLeft[4], + *m_gStickRight[4], + *m_gTriggers[4], + *m_gAnalog[4], + *m_gButton[4], + *m_gDPad[4], + *m_gStick[4], + *m_gCStick[4], + *m_gTrigger[4]; + + wxStaticText *m_ComboDeadZoneLabel[4], + *m_DiagonalLabel[4], + *m_RumbleStrengthLabel[4], + *m_tStatusLeftIn[4], *m_tStatusLeftOut[4], + *m_tStatusRightIn[4], *m_tStatusRightOut[4], + *m_TriggerL[4], *m_TriggerR[4], + *m_TriggerStatusL[4], *m_TriggerStatusR[4], + *m_tTriggerSource[4], + *m_Text_Analog[IDB_TRIGGER_R - IDB_ANALOG_LEFT_X + 1][4], + *m_Text_Pad[IDB_SHDR_SEMI_R - IDB_BTN_A + 1][4], + *m_Text_StickSrc[4], + *m_Text_CStickSrc[4], + *m_Text_TriggerSrc[4]; + + wxStaticBitmap *m_bmpDotLeftIn[4], + *m_bmpDotLeftOut[4], + *m_bmpDotRightIn[4], + *m_bmpDotRightOut[4], + *m_bmpDeadZoneLeftIn[4], + *m_bmpDeadZoneRightIn[4]; + + bool m_ControlsCreated; + int m_Page, BoxW, BoxH; + int GetButtonWaitingID, GetButtonWaitingTimer, g_Pressed; + wxString OldLabel; + + #if wxUSE_TIMER + wxTimer *m_UpdatePadTimer, *m_ButtonMappingTimer; + void UpdatePadInfo(wxTimerEvent& WXUNUSED(event)); + void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); } + #endif + + wxBitmap CreateBitmap(); + wxBitmap CreateBitmapDot(); + wxBitmap CreateBitmapDeadZone(int Radius); + wxBitmap CreateBitmapClear(); + + void NotebookPageChanged(wxNotebookEvent& event); + void OnClose(wxCloseEvent& event); + void OnCloseClick(wxCommandEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnButtonClick(wxCommandEvent& event); + void OnAxisClick(wxCommandEvent& event); + void ChangeSettings(wxCommandEvent& event); + void SaveButtonMapping(int Id, int Key); + void UpdateGUI(); + void CreateGUIControls(); + + void Convert2Box(int &x); + void DoChangeDeadZone(); + void ToBlank(bool ToBlank, int Id); + + void DoGetButtons(int _GetId); + void EndGetButtons(); + void SetButtonText(int id, const wxString &str); + wxString GetButtonText(int id); +}; + +#endif // __GCPAD_CONFIGBOX_h__ diff --git a/Source/Plugins/Plugin_GCPad/Src/ConfigJoypad.cpp b/Source/Plugins/Plugin_GCPad/Src/ConfigJoypad.cpp new file mode 100644 index 0000000000..a73e45e994 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/ConfigJoypad.cpp @@ -0,0 +1,329 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Config.h" +#include "ConfigBox.h" +#include "GCPad.h" + + +// Replace the harder to understand -1 with "" for the sake of user friendliness +void GCPadConfigDialog::ToBlank(bool toBlank, int Id) +{ + if (!m_ControlsCreated) + return; + + if(toBlank) + { + if (GetButtonText(Id) == wxString(wxT("-1"))) + SetButtonText(Id, wxString()); + } + else + { + if (GetButtonText(Id).IsEmpty()) + SetButtonText(Id, wxString(wxT("-1"))); + } +} + +void GCPadConfigDialog::DoChangeDeadZone() +{ + float Rad; + + Rad = (float)GCMapping[m_Page].DeadZoneL * ((float)BoxW / 100.0) * 0.5; + m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapClear()); + m_bmpDeadZoneLeftIn[m_Page]->SetSize(0, 0); + m_bmpDeadZoneLeftIn[m_Page]->SetBitmap(CreateBitmapDeadZone((int)Rad)); + m_bmpDeadZoneLeftIn[m_Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad)); + m_bmpDeadZoneLeftIn[m_Page]->Refresh(); + + Rad = (float)GCMapping[m_Page].DeadZoneR * ((float)BoxW / 100.0) * 0.5; + m_bmpDeadZoneRightIn[m_Page]->SetBitmap(CreateBitmapClear()); + m_bmpDeadZoneRightIn[m_Page]->SetSize(0, 0); + m_bmpDeadZoneRightIn[m_Page]->SetBitmap(CreateBitmapDeadZone((int)Rad)); + m_bmpDeadZoneRightIn[m_Page]->SetPosition(wxPoint(BoxW / 2 - (int)Rad, BoxH / 2 - (int)Rad)); + m_bmpDeadZoneRightIn[m_Page]->Refresh(); +} + +// Update the textbox for the buttons +void GCPadConfigDialog::SetButtonText(int id, const wxString &str) +{ + if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R) + m_Button_Analog[id - IDB_ANALOG_LEFT_X][m_Page]->SetLabel(str); + else if (IDB_BTN_A <= id && id <= IDB_SHDR_SEMI_R) + m_Button_GC[id - IDB_BTN_A][m_Page]->SetLabel(str); +} + +// Get the text in the textbox for the buttons +wxString GCPadConfigDialog::GetButtonText(int id) +{ + if (IDB_ANALOG_LEFT_X <= id && id <= IDB_TRIGGER_R) + return m_Button_Analog[id - IDB_ANALOG_LEFT_X][m_Page]->GetLabel(); + else if (IDB_BTN_A <= id && id <= IDB_SHDR_SEMI_R) + return m_Button_GC[id - IDB_BTN_A][m_Page]->GetLabel(); + + return wxString(); +} + +void GCPadConfigDialog::DoGetButtons(int _GetId) +{ + // Collect the starting values + // Get the current controller + int PadID = GCMapping[m_Page].ID; + + // Get the controller and trigger type + int TriggerType = GCMapping[m_Page].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 = (_GetId >= IDB_BTN_A && _GetId <= IDB_SHDR_SEMI_R); + + bool Hat = (_GetId >= IDB_BTN_A && _GetId <= IDB_SHDR_SEMI_R); + + bool NoTriggerFilter = g_Config.bNoTriggerFilter; + + // Values used in this function + 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 or Hat value + int type; // Button type + + int KeyPressed = 0; + int pressed = 0; + bool Succeed = false; + bool Stop = false; // Stop the timer + + // 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(); + + // Save the button Id + GetButtonWaitingID = _GetId; + GetButtonWaitingTimer = 0; + + // Start the timer + #if wxUSE_TIMER + m_ButtonMappingTimer->Start(1000 / TimesPerSecond); + #endif + DEBUG_LOG(PAD, "Timer Started: Pad:%i _GetId:%i " + "Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i", + GCMapping[m_Page].ID, _GetId, + Axis, LeftRight, XInput, Button, Hat); + } + + // Check for buttons + // If there is a timer we should not create a new one + else if (NumGoodPads > 0) + { + InputCommon::GetButton( + GCMapping[m_Page].joy, PadID, joyinfo[PadID].NumButtons, joyinfo[PadID].NumAxes, joyinfo[PadID].NumHats, + KeyPressed, value, type, pressed, Succeed, Stop, + LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter); + } + + // Process results + // Count each time + GetButtonWaitingTimer++; + + // This is run every second + if (GetButtonWaitingTimer % TimesPerSecond == 0) + { + // Current time + int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond); + // Update text + SetButtonText(_GetId, wxString::Format(wxT("[ %d ]"), TmpTime)); + } + + // Time's up + if (GetButtonWaitingTimer / TimesPerSecond >= Seconds) + { + Stop = true; + // Revert back to old label + SetButtonText(_GetId, OldLabel); + } + + // If we got a button + if(Succeed) + { + Stop = true; + // We need to assign hat special code + if (type == InputCommon::CTL_HAT) + { + // Index of pressed starts from 0 + if (value & SDL_HAT_UP) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_UP; + else if (value & SDL_HAT_DOWN) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_DOWN; + else if (value & SDL_HAT_LEFT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_LEFT; + else if (value & SDL_HAT_RIGHT) pressed = 0x0100 + 0x0010 * pressed + SDL_HAT_RIGHT; + else pressed = -1; + } + if (IDB_BTN_A <= _GetId && _GetId <= IDB_SHDR_SEMI_R) + { + // Better make the pad button code far from virtual key code + SaveButtonMapping(_GetId, 0x1000 + pressed); + SetButtonText(_GetId, wxString::Format(wxT("PAD: %d"), pressed)); + } + else if (IDB_ANALOG_LEFT_X <= _GetId && _GetId <= IDB_TRIGGER_R) + { + SaveButtonMapping(_GetId, pressed); + SetButtonText(_GetId, wxString::Format(wxT("%d"), pressed)); + } + } + + // Stop the timer + if(Stop) + { + DEBUG_LOG(PAD, "Timer Stopped for Pad:%i _GetId:%i", GCMapping[m_Page].ID, _GetId); + + EndGetButtons(); + } + + // If we got a bad button + if(KeyPressed == -1) + { + // Update text + SetButtonText(_GetId, wxString(wxT("PAD: -1"))); + // Notify the user + wxMessageBox(wxString::Format( + wxT("You selected a key with a to low key code (%i), please") + wxT(" select another key with a higher key code."), pressed) + , wxT("Notice"), wxICON_INFORMATION); + } +} + +void GCPadConfigDialog::EndGetButtons(void) +{ + wxTheApp->Disconnect(wxID_ANY, wxEVT_KEY_DOWN, // Keyboard + wxKeyEventHandler(GCPadConfigDialog::OnKeyDown), + (wxObject*)0, this); + m_ButtonMappingTimer->Stop(); + GetButtonWaitingTimer = 0; + GetButtonWaitingID = 0; + ClickedButton = NULL; +} + +// Convert the 0x8000 range values to BoxW and BoxH for the plot +void GCPadConfigDialog::Convert2Box(int &x) +{ + // Border adjustment + int BoxW_ = BoxW - 2; + // Convert values + x = (BoxW_ / 2) + (x * BoxW_ / (32767 * 2)); +} + +// Update the input status boxes +void GCPadConfigDialog::UpdatePadInfo(wxTimerEvent& WXUNUSED(event)) +{ + if (GCMapping[m_Page].ID < 0 || GCMapping[m_Page].ID >= NumPads) + { + m_tStatusLeftIn[m_Page]->SetLabel(wxT("Not connected")); + m_tStatusLeftOut[m_Page]->SetLabel(wxT("Not connected")); + m_tStatusRightIn[m_Page]->SetLabel(wxT("Not connected")); + m_tStatusRightOut[m_Page]->SetLabel(wxT("Not connected")); + m_TriggerStatusL[m_Page]->SetLabel(wxT("000")); + m_TriggerStatusR[m_Page]->SetLabel(wxT("000")); + return; + } + + // Check that Dolphin is in focus, otherwise don't update the pad status + //if (IsFocus()) + GetAxisState(GCMapping[m_Page]); + + // Analog stick + // Get original values + int main_x = GCMapping[m_Page].AxisState.Lx; + int main_y = GCMapping[m_Page].AxisState.Ly; + int right_x = GCMapping[m_Page].AxisState.Rx; + int right_y = GCMapping[m_Page].AxisState.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(GCMapping[m_Page].bSquare2Circle) + InputCommon::Square2Circle(main_x_after, main_y_after, GCMapping[m_Page].Diagonal, false); + + // Check dead zone + float DeadZoneLeft = (float)GCMapping[m_Page].DeadZoneL / 100.0; + float DeadZoneRight = (float)GCMapping[m_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; + } + + int Lx = InputCommon::Pad_Convert(main_x); int Ly = InputCommon::Pad_Convert(main_y); + int Rx = InputCommon::Pad_Convert(right_x); int Ry = InputCommon::Pad_Convert(right_y); + int Lx_after = InputCommon::Pad_Convert(main_x_after); int Ly_after = InputCommon::Pad_Convert(main_y_after); + int Rx_after = InputCommon::Pad_Convert(right_x_after); int Ry_after = InputCommon::Pad_Convert(right_y_after); + + m_tStatusLeftIn[m_Page]->SetLabel(wxString::Format(wxT("X:%03i Y:%03i"), Lx, Ly)); + m_tStatusLeftOut[m_Page]->SetLabel(wxString::Format(wxT("X:%03i Y:%03i"), Lx_after, Ly_after)); + m_tStatusRightIn[m_Page]->SetLabel(wxString::Format(wxT("X:%03i Y:%03i"), Rx, Ry)); + m_tStatusRightOut[m_Page]->SetLabel(wxString::Format(wxT("X:%03i Y:%03i"), Rx_after, Ry_after)); + + // 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[m_Page]->SetPosition(wxPoint(main_x, main_y)); + m_bmpDotLeftOut[m_Page]->SetPosition(wxPoint(main_x_after, main_y_after)); + m_bmpDotRightIn[m_Page]->SetPosition(wxPoint(right_x, right_y)); + m_bmpDotRightOut[m_Page]->SetPosition(wxPoint(right_x_after, right_y_after)); + + // Get the trigger values + int TriggerLeft = GCMapping[m_Page].AxisState.Tl; + int TriggerRight = GCMapping[m_Page].AxisState.Tr; + + // Convert the triggers values + if (GCMapping[m_Page].TriggerType == InputCommon::CTL_TRIGGER_SDL) + { + TriggerLeft = InputCommon::Pad_Convert(TriggerLeft); + TriggerRight = InputCommon::Pad_Convert(TriggerRight); + } + + m_TriggerStatusL[m_Page]->SetLabel(wxString::Format(wxT("%03i"), TriggerLeft)); + m_TriggerStatusR[m_Page]->SetLabel(wxString::Format(wxT("%03i"), TriggerRight)); +} diff --git a/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp b/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp new file mode 100644 index 0000000000..618f782a54 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/GCPad.cpp @@ -0,0 +1,651 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include "GCPad.h" +#include "Config.h" +#include "LogManager.h" +#if defined(HAVE_WX) && HAVE_WX + #include "ConfigBox.h" +#endif + +#ifdef _WIN32 +#include "XInput.h" +#endif + +// Declare config window so that we can write debugging info to it from functions in this file +#if defined(HAVE_WX) && HAVE_WX + GCPadConfigDialog* m_ConfigFrame = NULL; +#endif + + +// Variables +// --------- +bool g_SearchDeviceDone = false; +CONTROLLER_MAPPING_GC GCMapping[4]; +std::vector joyinfo; +int NumPads = 0, NumGoodPads = 0, g_ID = 0; +#ifdef _WIN32 + HWND m_hWnd = NULL; // Handle to window +#endif +#if defined(HAVE_X11) && HAVE_X11 + Display* GCdisplay; +#endif +SPADInitialize *g_PADInitialize = NULL; +PLUGIN_GLOBALS* globals = NULL; + + +// Standard crap to make wxWidgets happy +#ifdef _WIN32 +HINSTANCE g_hInstance; + +#if defined(HAVE_WX) && HAVE_WX +class wxDLLApp : public wxApp +{ + bool OnInit() + { + return true; + } +}; +IMPLEMENT_APP_NO_MAIN(wxDLLApp) +WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); +#endif + +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle + DWORD dwReason, // reason called + LPVOID lpvReserved) // reserved +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + { +#if defined(HAVE_WX) && HAVE_WX + wxSetInstance((HINSTANCE)hinstDLL); + wxInitialize(); +#endif + } + break; + + case DLL_PROCESS_DETACH: +#if defined(HAVE_WX) && HAVE_WX + wxUninitialize(); +#endif + break; + } + + g_hInstance = hinstDLL; + return TRUE; +} +#endif + +#if defined(HAVE_WX) && HAVE_WX +wxWindow* GetParentedWxWindow(HWND Parent) +{ +#ifdef _WIN32 + wxSetInstance((HINSTANCE)g_hInstance); +#endif + wxWindow *win = new wxWindow(); +#ifdef _WIN32 + win->SetHWND((WXHWND)Parent); + win->AdoptAttributesFromHWND(); +#endif + return win; +} +#endif + + +// Input Plugin Functions (from spec's) +// ------------------------------------ + +// Get properties of plugin +// ------------------------ +void GetDllInfo(PLUGIN_INFO* _PluginInfo) +{ + _PluginInfo->Version = 0x0100; + _PluginInfo->Type = PLUGIN_TYPE_PAD; + +#ifdef DEBUGFAST + sprintf(_PluginInfo->Name, "Dolphin GCPad Plugin (DebugFast)"); +#else +#ifdef _DEBUG + sprintf(_PluginInfo->Name, "Dolphin GCPad Plugin (Debug)"); +#else + sprintf(_PluginInfo->Name, "Dolphin GCPad Plugin"); +#endif +#endif +} + +void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) +{ + globals = _pPluginGlobals; + LogManager::SetInstance((LogManager *)globals->logManager); +} + + +// Call config dialog +// ------------------ +void DllConfig(HWND _hParent) +{ + if (!g_SearchDeviceDone) + { + g_Config.Load(); // load settings + // Init Joystick + Haptic (force feedback) subsystem on SDL 1.3 + // Populate joyinfo for all attached devices + Search_Devices(joyinfo, NumPads, NumGoodPads); + g_SearchDeviceDone = true; + } + +#if defined(HAVE_WX) && HAVE_WX + wxWindow *frame = GetParentedWxWindow(_hParent); + m_ConfigFrame = new GCPadConfigDialog(frame); + +#ifdef _WIN32 + frame->Disable(); + m_ConfigFrame->ShowModal(); + frame->Enable(); +#else + m_ConfigFrame->ShowModal(); +#endif + +#ifdef _WIN32 + frame->SetFocus(); + frame->SetHWND(NULL); +#endif + + m_ConfigFrame->Destroy(); + m_ConfigFrame = NULL; + frame->Destroy(); +#endif +} + +void DllDebugger(HWND _hParent, bool Show) +{ +} + + +// Init PAD (start emulation) +// -------------------------- +void Initialize(void *init) +{ + INFO_LOG(PAD, "Initialize: %i", SDL_WasInit(0)); + g_PADInitialize = (SPADInitialize*)init; + +#ifdef _WIN32 + m_hWnd = (HWND)g_PADInitialize->hWnd; +#endif +#if defined(HAVE_X11) && HAVE_X11 + GCdisplay = (Display*)g_PADInitialize->hWnd; +#endif + + if (!g_SearchDeviceDone) + { + g_Config.Load(); // load settings + // Populate joyinfo for all attached devices + Search_Devices(joyinfo, NumPads, NumGoodPads); + g_SearchDeviceDone = true; + } +} + +// Shutdown PAD (stop emulation) +// ----------------------------- +void Shutdown() +{ + INFO_LOG(PAD, "Shutdown: %i", SDL_WasInit(0)); + + Close_Devices(); + + // Finally close SDL + if (SDL_WasInit(0)) + { + SDL_Quit(); + } + + // Remove the pointer to the initialize data + g_PADInitialize = NULL; + g_SearchDeviceDone = false; +} + +// Save state +// -------------- +void DoState(unsigned char **ptr, int mode) +{ +#ifdef RERECORDING + Recording::DoState(ptr, mode); +#endif +} + +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + +// Set buttons status from keyboard input. Currently this is done from wxWidgets in the main application. +// -------------- +void PAD_Input(u16 _Key, u8 _UpDown) +{ +} + +// Set PAD status +// -------------- +// Called from: SI_DeviceGCController.cpp +// Function: Gives the current pad status to the Core +void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) +{ + // Check if all is okay + if (_pPADStatus == NULL) return; + + // Clear pad + memset(_pPADStatus, 0, sizeof(SPADStatus)); + const int base = 0x80; + _pPADStatus->stickX = base; + _pPADStatus->stickY = base; + _pPADStatus->substickX = base; + _pPADStatus->substickY = base; + _pPADStatus->button |= PAD_USE_ORIGIN; + _pPADStatus->err = PAD_ERR_NONE; + + // Check that Dolphin is in focus, otherwise don't update the pad status + if (!IsFocus()) return; + + g_ID = _numPAD; + + if (NumGoodPads && NumPads > GCMapping[_numPAD].ID) + UpdatePadState(GCMapping[_numPAD]); + + if (IsKey(EGC_A)) + { + _pPADStatus->button |= PAD_BUTTON_A; + _pPADStatus->analogA = DEF_BUTTON_FULL; + } + if (IsKey(EGC_B)) + { + _pPADStatus->button |= PAD_BUTTON_B; + _pPADStatus->analogB = DEF_BUTTON_FULL; + } + if (IsKey(EGC_X)) _pPADStatus->button |= PAD_BUTTON_X; + if (IsKey(EGC_Y)) _pPADStatus->button |= PAD_BUTTON_Y; + if (IsKey(EGC_Z)) _pPADStatus->button |= PAD_TRIGGER_Z; + if (IsKey(EGC_START)) _pPADStatus->button |= PAD_BUTTON_START; + if (IsKey(EGC_DPAD_UP)) _pPADStatus->button |= PAD_BUTTON_UP; + if (IsKey(EGC_DPAD_DOWN)) _pPADStatus->button |= PAD_BUTTON_DOWN; + if (IsKey(EGC_DPAD_LEFT)) _pPADStatus->button |= PAD_BUTTON_LEFT; + if (IsKey(EGC_DPAD_RIGHT)) _pPADStatus->button |= PAD_BUTTON_RIGHT; + + if (GCMapping[_numPAD].Stick.Main == FROM_KEYBOARD) + { + int iMagnitude = DEF_STICK_FULL; + bool bUp = false; + bool bDown = false; + bool bLeft = false; + bool bRight = false; + if (IsKey(EGC_STICK_SEMI)) iMagnitude = GCMapping[_numPAD].Pressure.Main; + if (IsKey(EGC_STICK_UP)) bUp = true; + else if (IsKey(EGC_STICK_DOWN)) bDown = true; + if (IsKey(EGC_STICK_LEFT)) bLeft = true; + else if (IsKey(EGC_STICK_RIGHT)) bRight = true; + EmulateAnalogStick(_pPADStatus->stickX, _pPADStatus->stickY, bUp, bDown, bLeft, bRight, iMagnitude); + } + else if (GCMapping[_numPAD].Stick.Main == FROM_ANALOG1) + { + _pPADStatus->stickX = GCMapping[_numPAD].AxisState.Lx; + // Y-axis is inverted + _pPADStatus->stickY = 0xFF - (u8)GCMapping[_numPAD].AxisState.Ly; + } + else if (GCMapping[_numPAD].Stick.Main == FROM_ANALOG2) + { + _pPADStatus->stickX = GCMapping[_numPAD].AxisState.Rx; + // Y-axis is inverted + _pPADStatus->stickY = 0xFF - (u8)GCMapping[_numPAD].AxisState.Ry; + } + else + { + _pPADStatus->stickX = GCMapping[_numPAD].AxisState.Tl; + _pPADStatus->stickY = GCMapping[_numPAD].AxisState.Tr; + } + + if (GCMapping[_numPAD].Stick.Sub == FROM_KEYBOARD) + { + int iMagnitude = DEF_STICK_FULL; + bool bUp = false; + bool bDown = false; + bool bLeft = false; + bool bRight = false; + if (IsKey(EGC_CSTICK_SEMI)) iMagnitude = GCMapping[_numPAD].Pressure.Sub; + if (IsKey(EGC_CSTICK_UP)) bUp = true; + else if (IsKey(EGC_CSTICK_DOWN)) bDown = true; + if (IsKey(EGC_CSTICK_LEFT)) bLeft = true; + else if (IsKey(EGC_CSTICK_RIGHT)) bRight = true; + EmulateAnalogStick(_pPADStatus->substickX, _pPADStatus->substickY, bUp, bDown, bLeft, bRight, iMagnitude); + } + else if (GCMapping[_numPAD].Stick.Sub == FROM_ANALOG1) + { + _pPADStatus->substickX = GCMapping[_numPAD].AxisState.Lx; + // Y-axis is inverted + _pPADStatus->substickY = 0xFF - (u8)GCMapping[_numPAD].AxisState.Ly; + } + else if (GCMapping[_numPAD].Stick.Sub == FROM_ANALOG2) + { + _pPADStatus->substickX = GCMapping[_numPAD].AxisState.Rx; + // Y-axis is inverted + _pPADStatus->substickY = 0xFF - (u8)GCMapping[_numPAD].AxisState.Ry; + } + else + { + _pPADStatus->substickX = GCMapping[_numPAD].AxisState.Tl; + _pPADStatus->substickY = GCMapping[_numPAD].AxisState.Tr; + } + + if (GCMapping[_numPAD].Stick.Shoulder == FROM_KEYBOARD) + { + if (IsKey(EGC_TGR_L)) + { + _pPADStatus->triggerLeft = DEF_TRIGGER_FULL; + _pPADStatus->button |= PAD_TRIGGER_L; + } + else if (IsKey(EGC_TGR_SEMI_L)) + { + _pPADStatus->triggerLeft = GCMapping[_numPAD].Pressure.Shoulder; + if (_pPADStatus->triggerLeft > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_L; + } + + if (IsKey(EGC_TGR_R)) + { + _pPADStatus->triggerRight = DEF_TRIGGER_FULL; + _pPADStatus->button |= PAD_TRIGGER_R; + } + else if (IsKey(EGC_TGR_SEMI_R)) + { + _pPADStatus->triggerRight = GCMapping[_numPAD].Pressure.Shoulder; + if (_pPADStatus->triggerRight > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_R; + } + } + else if (GCMapping[_numPAD].Stick.Shoulder == FROM_ANALOG1) + { + _pPADStatus->triggerLeft = GCMapping[_numPAD].AxisState.Lx; + _pPADStatus->triggerRight = GCMapping[_numPAD].AxisState.Ly; + EmulateAnalogTrigger(_pPADStatus->triggerLeft, _pPADStatus->triggerRight); + if (_pPADStatus->triggerLeft > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_L; + if (_pPADStatus->triggerRight > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_R; + } + else if (GCMapping[_numPAD].Stick.Shoulder == FROM_ANALOG2) + { + _pPADStatus->triggerLeft = GCMapping[_numPAD].AxisState.Rx; + _pPADStatus->triggerRight = GCMapping[_numPAD].AxisState.Ry; + EmulateAnalogTrigger(_pPADStatus->triggerLeft, _pPADStatus->triggerRight); + if (_pPADStatus->triggerLeft > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_L; + if (_pPADStatus->triggerRight > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_R; + } + else + { + _pPADStatus->triggerLeft = GCMapping[_numPAD].AxisState.Tl; + _pPADStatus->triggerRight = GCMapping[_numPAD].AxisState.Tr; + EmulateAnalogTrigger(_pPADStatus->triggerLeft, _pPADStatus->triggerRight); + if (_pPADStatus->triggerLeft > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_L; + if (_pPADStatus->triggerRight > DEF_TRIGGER_THRESHOLD) + _pPADStatus->button |= PAD_TRIGGER_R; + } + +} + + +//****************************************************************************** +// Supporting functions +//****************************************************************************** + +// for same displacement should be sqrt(2)/2 (in theory) +// 3/4 = 0.75 is a little faster than sqrt(2)/2 = 0.7071... +// In SMS, 17/20 = 0.85 is perfect; in WW, 7/10 = 0.70 is closer. +#define DIAGONAL_SCALE 0.70710678 +void EmulateAnalogStick(unsigned char &stickX, unsigned char &stickY, bool buttonUp, bool buttonDown, bool buttonLeft, bool buttonRight, int magnitude) +{ + int mainX = 0; + int mainY = 0; + if (buttonUp) + mainY = magnitude; + else if (buttonDown) + mainY = -magnitude; + if (buttonLeft) + mainX = -magnitude; + else if (buttonRight) + mainX = magnitude; + + if ((mainX == 0) || (mainY == 0)) + { + stickX += mainX; + stickY += mainY; + } + else + { + stickX += mainX * DIAGONAL_SCALE; + stickY += mainY * DIAGONAL_SCALE; + } +} + +void EmulateAnalogTrigger(unsigned char &trL, unsigned char &trR) +{ + if (GCMapping[g_ID].TriggerType == InputCommon::CTL_TRIGGER_SDL) + { + int triggerL = abs((int)trL - 0x80) * 2; + int triggerR = abs((int)trR - 0x80) * 2; + trL = (triggerL > 0xFF) ? 0xFF : triggerL; + trR = (triggerR > 0xFF) ? 0xFF : triggerR; + } +} + +void Close_Devices() +{ + PAD_RumbleClose(); + + if (SDL_WasInit(0)) + { + for (int i = 0; i < NumPads; i++) + { + if (joyinfo.at(i).joy) + { + if(SDL_JoystickOpened(i)) + { + INFO_LOG(WIIMOTE, "Shut down Joypad: %i", i); + SDL_JoystickClose(joyinfo.at(i).joy); + } + } + } + } + + for (int i = 0; i < 4; i++) + GCMapping[i].joy = NULL; + + // Clear the physical device info + joyinfo.clear(); + NumPads = 0; + NumGoodPads = 0; +} + +// Search for SDL devices +// ---------------- +bool Search_Devices(std::vector &_joyinfo, int &_NumPads, int &_NumGoodPads) +{ + // Close opened devices first + Close_Devices(); + + bool success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads); + + if (_NumGoodPads == 0) + return false; + + for (int i = 0; i < 4; i++) + { + if (_NumPads > GCMapping[i].ID) + if(joyinfo.at(GCMapping[i].ID).Good) + { + GCMapping[i].joy = joyinfo.at(GCMapping[i].ID).joy; +#ifdef _WIN32 + XINPUT_STATE xstate; + DWORD xresult = XInputGetState(GCMapping[i].ID, &xstate); + if (xresult == ERROR_SUCCESS) + GCMapping[i].TriggerType = InputCommon::CTL_TRIGGER_XINPUT; +#endif + } + } + + return success; +} + +void GetAxisState(CONTROLLER_MAPPING_GC &_GCMapping) +{ + // Update the gamepad status + SDL_JoystickUpdate(); + + // Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here. + _GCMapping.AxisState.Lx = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Lx); + _GCMapping.AxisState.Ly = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Ly); + _GCMapping.AxisState.Rx = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Rx); + _GCMapping.AxisState.Ry = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Ry); + + // Update the analog trigger axis values +#ifdef _WIN32 + if (_GCMapping.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 ((_GCMapping.AxisMapping.Tl - 1000) >= 0) + _GCMapping.AxisState.Tl = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Tl - 1000); + if ((_GCMapping.AxisMapping.Tr - 1000) >= 0) + _GCMapping.AxisState.Tr = SDL_JoystickGetAxis(_GCMapping.joy, _GCMapping.AxisMapping.Tr - 1000); +#ifdef _WIN32 + } + else + { + _GCMapping.AxisState.Tl = XInput::GetXI(_GCMapping.ID, _GCMapping.AxisMapping.Tl - 1000); + _GCMapping.AxisState.Tr = XInput::GetXI(_GCMapping.ID, _GCMapping.AxisMapping.Tr - 1000); + } +#endif +} + +void UpdatePadState(CONTROLLER_MAPPING_GC &_GCiMapping) +{ + // Return if we have no pads + if (NumGoodPads == 0) return; + + GetAxisState(_GCiMapping); + + int &Lx = _GCiMapping.AxisState.Lx; + int &Ly = _GCiMapping.AxisState.Ly; + int &Rx = _GCiMapping.AxisState.Rx; + int &Ry = _GCiMapping.AxisState.Ry; + int &Tl = _GCiMapping.AxisState.Tl; + int &Tr = _GCiMapping.AxisState.Tr; + + // Check the circle to square option + if(_GCiMapping.bSquare2Circle) + { + InputCommon::Square2Circle(Lx, Ly, _GCiMapping.Diagonal, false); + InputCommon::Square2Circle(Rx, Ry, _GCiMapping.Diagonal, false); + } + + // Dead zone adjustment + float DeadZoneLeft = (float)_GCiMapping.DeadZoneL / 100.0f; + float DeadZoneRight = (float)_GCiMapping.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 (_GCiMapping.TriggerType == InputCommon::CTL_TRIGGER_SDL) + { + Tl = InputCommon::Pad_Convert(Tl); + Tr = InputCommon::Pad_Convert(Tr); + } +} + +// Multi System Input Status Check +bool IsKey(int Key) +{ + int Ret = NULL; + int MapKey = GCMapping[g_ID].Button[Key]; + +#ifdef _WIN32 + if (MapKey < 256) + { + Ret = GetAsyncKeyState(MapKey); // Keyboard (Windows) + } + else if (MapKey < 0x1100) +#elif defined HAVE_X11 && HAVE_X11 + if (MapKey < 256 || MapKey > 0xf000) + { + char keys[32]; + KeyCode keyCode; + XQueryKeymap(GCdisplay, keys); + keyCode = XKeysymToKeycode(GCdisplay, MapKey); + Ret = (keys[keyCode/8] & (1 << (keyCode%8))); // Keyboard (Linux) + } + else if (MapKey < 0x1100) +#else + if (MapKey < 0x1100) +#endif + { + Ret = SDL_JoystickGetButton(GCMapping[g_ID].joy, MapKey - 0x1000); // Pad button + } + else // Pad hat + { + u8 HatCode, HatKey; + HatCode = SDL_JoystickGetHat(GCMapping[g_ID].joy, (MapKey - 0x1100) / 0x0010); + HatKey = (MapKey - 0x1100) % 0x0010; + + if (HatCode & HatKey) + Ret = HatKey; + } + + return (Ret) ? true : false; +} + +// Check if Dolphin is in focus +// ---------------- +bool IsFocus() +{ + return g_PADInitialize->pRendererHasFocus(); +} diff --git a/Source/Plugins/Plugin_GCPad/Src/GCPad.h b/Source/Plugins/Plugin_GCPad/Src/GCPad.h new file mode 100644 index 0000000000..52fe385785 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/GCPad.h @@ -0,0 +1,165 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#ifndef _PLUGIN_GCPAD_H +#define _PLUGIN_GCPAD_H + + +#include // System +#include +#include "../../../Core/InputCommon/Src/InputCommon.h" // Core +#include "../../../Core/InputCommon/Src/SDL_Util.h" +#ifdef _WIN32 + #include "../../../Core/InputCommon/Src/XInput_Util.h" +#elif defined(HAVE_X11) && HAVE_X11 + #include + #include + #include + #include +#endif +#include "pluginspecs_pad.h" + + +#define DEF_BUTTON_FULL 255 +#define DEF_STICK_FULL 100 +#define DEF_STICK_HALF 50 +#define DEF_TRIGGER_FULL 255 +#define DEF_TRIGGER_HALF 128 +#define DEF_TRIGGER_THRESHOLD 230 + +// GC Pad Buttons +enum EGCPad +{ + EGC_A = 0, + EGC_B, + EGC_X, + EGC_Y, + EGC_Z, + EGC_START, + + EGC_DPAD_UP, + EGC_DPAD_DOWN, + EGC_DPAD_LEFT, + EGC_DPAD_RIGHT, + + EGC_STICK_UP, + EGC_STICK_DOWN, + EGC_STICK_LEFT, + EGC_STICK_RIGHT, + EGC_STICK_SEMI, + + EGC_CSTICK_UP, + EGC_CSTICK_DOWN, + EGC_CSTICK_LEFT, + EGC_CSTICK_RIGHT, + EGC_CSTICK_SEMI, + + EGC_TGR_L, + EGC_TGR_R, + EGC_TGR_SEMI_L, + EGC_TGR_SEMI_R, + + LAST_CONSTANT, +}; + +enum EInputType +{ + FROM_KEYBOARD, + FROM_ANALOG1, + FROM_ANALOG2, + FROM_TRIGGER, +}; + +union UAxis +{ + int Code[6]; + struct + { + int Lx; + int Ly; + int Rx; + int Ry; + int Tl; // Trigger + int Tr; // Trigger + }; +}; + +struct SStickMapping +{ + int Main; + int Sub; + int Shoulder; //Trigger +}; + +struct CONTROLLER_MAPPING_GC // PAD MAPPING GC +{ + int ID; // SDL joystick device ID + SDL_Joystick *joy; // SDL joystick device + UAxis AxisState; + UAxis AxisMapping; // 6 Axes (Main, Sub, Triggers) + int TriggerType; // SDL or XInput trigger + bool Rumble; + int RumbleStrength; + int DeadZoneL; // Analog 1 Deadzone + int DeadZoneR; // Analog 2 Deadzone + bool bSquare2Circle; + int Diagonal; + + SStickMapping Stick; + SStickMapping Pressure; + int Button[LAST_CONSTANT]; +}; + +extern CONTROLLER_MAPPING_GC GCMapping[4]; +extern int NumPads, NumGoodPads, g_ID; + +extern SPADInitialize *g_PADInitialize; +extern std::vector joyinfo; +#ifdef _WIN32 +extern HWND m_hWnd; // Handle to window +#endif +#if defined(HAVE_X11) && HAVE_X11 +extern Display* GCdisplay; +#endif + + +// Custom Functions +// ---------------- +void EmulateAnalogStick(unsigned char &stickX, unsigned char &stickY, bool buttonUp, bool buttonDown, bool buttonLeft, bool buttonRight, int magnitude); +void EmulateAnalogTrigger(unsigned char &trL, unsigned char &trR); +void Close_Devices(); +bool Search_Devices(std::vector &_joyinfo, int &_NumPads, int &_NumGoodPads); +void GetAxisState(CONTROLLER_MAPPING_GC &_GCMapping); +void UpdatePadState(CONTROLLER_MAPPING_GC &_GCMapping); +bool IsKey(int Key); +bool IsFocus(); +bool ReloadDLL(); +void PAD_RumbleClose(); + +#endif // _PLUGIN_GCPAD_H diff --git a/Source/Plugins/Plugin_GCPad/Src/ReRecording.cpp b/Source/Plugins/Plugin_GCPad/Src/ReRecording.cpp new file mode 100644 index 0000000000..19f5044815 --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/ReRecording.cpp @@ -0,0 +1,181 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include "GCPad.h" +#include "FileUtil.h" +#include "ChunkFile.h" + +// TODO : +// This is pretty much useless now with the TAS features right ? + +#ifdef RERECORDING + + +namespace Recording +{ + + + +// Definitions +// ------------- +// Pre defined maxium storage limit +#define RECORD_SIZE (1024 * 128) +SPADStatus RecordBuffer[RECORD_SIZE]; +int count = 0; + + + + + +// Recording functions +// ------------- +void RecordInput(const SPADStatus& _rPADStatus) +{ + if (count >= RECORD_SIZE) return; + RecordBuffer[count++] = _rPADStatus; + + // Logging + //u8 TmpData[sizeof(SPADStatus)]; + //memcpy(TmpData, &RecordBuffer[count - 1], sizeof(SPADStatus)); + //Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str()); + + // Auto save every ten seconds + if (count % (60 * 10) == 0) Save(); +} + +const SPADStatus& Play() +{ + // Logging + //Console::Print("PlayRecord(%i)\n", count); + if (count >= RECORD_SIZE) + { + // Todo: Make the recording size unlimited? + //PanicAlert("The recording reached its end"); + return(RecordBuffer[0]); + } + return(RecordBuffer[count++]); +} + +void Load() +{ + FILE* pStream = fopen("pad-record.bin", "rb"); + + if (pStream != NULL) + { + fread(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); + fclose(pStream); + } + else + { + PanicAlert("SimplePad: Could not open pad-record.bin"); + } + + //Console::Print("LoadRecord()"); +} + +void Save() +{ + // Open the file in a way that clears all old data + FILE* pStream = fopen("pad-record.bin", "wb"); + + if (pStream != NULL) + { + fwrite(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); + fclose(pStream); + } + else + { + PanicAlert("NJoy: Could not save pad-record.bin"); + } + //PanicAlert("SaveRecord()"); + //Console::Print("SaveRecord()"); +} + + + + +void Initialize() +{ + // ------------------------------------------- + // Rerecording + // ---------------------- + #ifdef RERECORDING + /* Check if we are starting the pad to record the input, and an old file exists. In that case ask + if we really want to start the recording and eventually overwrite the file */ + if (g_Config.bRecording && File::Exists("pad-record.bin")) + { + if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can" + " now make a copy of it before you start a new recording and overwrite the file." + " Select Yes to continue and overwrite the file. Select No to turn off the input" + " recording and continue without recording anything.", + "pad-record.bin")) + { + // Turn off recording and continue + g_Config.bRecording = false; + } + } + + // Load recorded input if we are to play it back, otherwise begin with a blank recording + if (g_Config.bPlayback) Recording::Load(); + #endif + // ---------------------- +} + + +void ShutDown() +{ + // Save recording + if (g_Config.bRecording) Recording::Save(); + // Reset the counter + count = 0; +} + +void DoState(unsigned char **ptr, int mode) +{ + // Load or save the counter + PointerWrap p(ptr, mode); + p.Do(count); + + //Console::Print("count: %i\n", count); + + // Update the frame counter for the sake of the status bar + if (mode == PointerWrap::MODE_READ) + { + #ifdef _WIN32 + // This only works when rendering to the main window, I think + PostMessage(GetParent(g_PADInitialize->hWnd), WM_USER, INPUT_FRAME_COUNTER, count); + #endif + } +} + + +} // Recording + + +#endif // RERECORDING diff --git a/Source/Plugins/Plugin_GCPad/Src/Rumble.cpp b/Source/Plugins/Plugin_GCPad/Src/Rumble.cpp new file mode 100644 index 0000000000..de232afe8c --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/Rumble.cpp @@ -0,0 +1,407 @@ +// Project description +// ------------------- +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003 Dolphin Project. +// + + +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include "GCPad.h" + +#ifdef _WIN32 +#include "XInput.h" +#endif + +// SDL Haptic fails on windows, it just doesn't work (even the sample doesn't work) +// So until i can make it work, this is all disabled >:( +#if SDL_VERSION_ATLEAST(1, 3, 0) && !defined(_WIN32) && !defined(__APPLE__) + #define SDL_RUMBLE +#else + #ifdef _WIN32 + #define RUMBLE_HACK + #define DIRECTINPUT_VERSION 0x0800 + #define WIN32_LEAN_AND_MEAN + + #pragma comment(lib, "dxguid.lib") + #pragma comment(lib, "dinput8.lib") + #pragma comment(lib, "winmm.lib") + #include + #endif +#endif + + +#ifdef RUMBLE_HACK + +struct RUMBLE // GC Pad rumble DIDevice +{ + LPDIRECTINPUTDEVICE8 g_pDevice; // 4 pads objects + LPDIRECTINPUTEFFECT g_pEffect; + DWORD g_dwNumForceFeedbackAxis; + DIEFFECT eff; +}; + +BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext); +BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); +void SetDeviceForcesXY(int pad, int nXYForce); +HRESULT InitRumble(HWND hWnd); +void Rumble_DInput(int _ID, unsigned int _Strength); +void Rumble_XInput(int _ID, unsigned int _Strength); + + +LPDIRECTINPUT8 g_Rumble; // DInput Rumble object +RUMBLE pRumble[4]; // 4 GC Rumble Pads + + +void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +{ + if (GCMapping[_numPAD].ID >= NumPads || !GCMapping[_numPAD].Rumble) + return; + + unsigned int Strength = 0; + if (_uType == 1 && _uStrength > 2) + { + Strength = GCMapping[_numPAD].RumbleStrength; + Strength = Strength > 100 ? 100 : Strength; + } + + if (GCMapping[_numPAD].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + Rumble_XInput(GCMapping[_numPAD].ID, Strength); + else + Rumble_DInput(GCMapping[_numPAD].ID, Strength); +} + +//////////////////////////////////////////////////// +// Set rumble with XInput. +void Rumble_XInput(int _ID, unsigned int _Strength) +{ +#ifdef _WIN32 + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = 0xFFFF / 100 * _Strength; + vib.wRightMotorSpeed = 0xFFFF / 100 * _Strength; + XInputSetState(_ID, &vib); +#endif +} + +//////////////////////////////////////////////////// +// Set rumble with DInput.¯¯¯¯¯¯¯¯¯¯¯¯ +void Rumble_DInput(int _ID, unsigned int _Strength) +{ + if (!g_Rumble) + { + // GetForegroundWindow() always sends the good HWND + if (FAILED(InitRumble(GetForegroundWindow()))) + PanicAlert("Could not initialize Rumble!"); + } + else + { + // Acquire gamepad + if (pRumble[_ID].g_pDevice != NULL) + pRumble[_ID].g_pDevice->Acquire(); + } + + SetDeviceForcesXY(_ID, _Strength * 100); +} + +HRESULT InitRumble(HWND hWnd) +{ + DIPROPDWORD dipdw; + HRESULT hr; + + // Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use. + if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_Rumble, NULL))) + return hr; + + // Look for a device we can use + if (FAILED(hr = g_Rumble->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK))) + return hr; + + for (int i=0; i<4; i++) + { + if (NULL == pRumble[i].g_pDevice) + GCMapping[i].Rumble = false; // Disable Rumble for this pad only. + else + { + pRumble[i].g_pDevice->SetDataFormat(&c_dfDIJoystick); + pRumble[i].g_pDevice->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND); + // Request exclusive acces for both background and foreground. + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = FALSE; + + // if Force Feedback doesn't seem to work... + if (FAILED(pRumble[i].g_pDevice->EnumObjects(EnumAxesCallback, + (void*)&pRumble[i].g_dwNumForceFeedbackAxis, DIDFT_AXIS)) + || FAILED(pRumble[i].g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph))) + { + PanicAlert("Device %d doesn't seem to work ! \nRumble for device %d is now Disabled !", i+1); + + GCMapping[i].Rumble = false; // Disable Rumble for this pad + + continue; // Next pad + } + + if (pRumble[i].g_dwNumForceFeedbackAxis > 2) + pRumble[i].g_dwNumForceFeedbackAxis = 2; + + DWORD _rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; + long rglDirection[2] = {0, 0}; + DICONSTANTFORCE cf = {0}; + + ZeroMemory(&pRumble[i].eff, sizeof(pRumble[i].eff)); + pRumble[i].eff.dwSize = sizeof(DIEFFECT); + pRumble[i].eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + pRumble[i].eff.dwDuration = INFINITE; // fixed time may be safer (X * DI_SECONDS) + pRumble[i].eff.dwSamplePeriod = 0; + pRumble[i].eff.dwGain = DI_FFNOMINALMAX; + pRumble[i].eff.dwTriggerButton = DIEB_NOTRIGGER; + pRumble[i].eff.dwTriggerRepeatInterval = 0; + pRumble[i].eff.cAxes = pRumble[i].g_dwNumForceFeedbackAxis; + pRumble[i].eff.rgdwAxes = _rgdwAxes; + pRumble[i].eff.rglDirection = rglDirection; + pRumble[i].eff.lpEnvelope = 0; + pRumble[i].eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); + pRumble[i].eff.lpvTypeSpecificParams = &cf; + pRumble[i].eff.dwStartDelay = 0; + + // Create the prepared effect + if (FAILED(hr = pRumble[i].g_pDevice->CreateEffect(GUID_ConstantForce, &pRumble[i].eff, &pRumble[i].g_pEffect, NULL))) + continue; + + if (pRumble[i].g_pEffect == NULL) + continue; + } + } + + return S_OK; +} + +void SetDeviceForcesXY(int npad, int nXYForce) +{ + // Security check + if (pRumble[npad].g_pDevice == NULL) + return; + + // If nXYForce is null, there's no point to create the effect + // Just stop the force feedback + if (nXYForce == 0) { + pRumble[npad].g_pEffect->Stop(); + return; + } + + long rglDirection[2] = {0}; + DICONSTANTFORCE cf; + + // If only one force feedback axis, then apply only one direction and keep the direction at zero + if (pRumble[npad].g_dwNumForceFeedbackAxis == 1) + { + rglDirection[0] = 0; + cf.lMagnitude = nXYForce; // max should be 10000 + } + // If two force feedback axis, then apply magnitude from both directions + else + { + rglDirection[0] = nXYForce; + rglDirection[1] = nXYForce; + cf.lMagnitude = (long)(1.4142f*nXYForce); + } + + ZeroMemory(&pRumble[npad].eff, sizeof(pRumble[npad].eff)); + pRumble[npad].eff.dwSize = sizeof(DIEFFECT); + pRumble[npad].eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + pRumble[npad].eff.cAxes = pRumble[npad].g_dwNumForceFeedbackAxis; + pRumble[npad].eff.rglDirection = rglDirection; + pRumble[npad].eff.lpEnvelope = 0; + pRumble[npad].eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + pRumble[npad].eff.lpvTypeSpecificParams = &cf; + pRumble[npad].eff.dwStartDelay = 0; + + // Now set the new parameters.. + pRumble[npad].g_pEffect->SetParameters(&pRumble[npad].eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); + // ..And start the effect immediately. + if (pRumble[npad].g_pEffect != NULL) + pRumble[npad].g_pEffect->Start(1, 0); +} + +BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext) +{ + LPDIRECTINPUTDEVICE8 pDevice; + DIPROPDWORD dipdw; + HRESULT hr; + + int JoystickID; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + + g_Rumble->CreateDevice(pInst->guidInstance, &pDevice, NULL); // Create a DInput pad device + + if (SUCCEEDED(hr = pDevice->GetProperty(DIPROP_JOYSTICKID, &dipdw.diph))) // Get DInput Device ID + JoystickID = dipdw.dwData; + else + return DIENUM_CONTINUE; + + //PanicAlert("DInput ID : %d \nSDL ID (1-4) : %d / %d / %d / %d\n", JoystickID, GCMapping[0].ID, GCMapping[1].ID, GCMapping[2].ID, GCMapping[3].ID); + + for (int i=0; i<4; i++) + { + if (GCMapping[i].ID == JoystickID) // if SDL ID = DInput ID -> we're dealing with the same device + { + // a DInput device is created even if rumble is disabled on startup + // this way, you can toggle the rumble setting while in game + pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device + } + } + + return DIENUM_CONTINUE; +} + +BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) +{ + DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext; // Enum Rumble Axis + if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) + (*pdwNumForceFeedbackAxis)++; + + return DIENUM_CONTINUE; +} + +void PAD_RumbleClose() +{ + for (int i = 0; i < 4; i++) + { + if (GCMapping[i].ID < NumPads) + if (GCMapping[i].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + { +#ifdef _WIN32 + // Kill Xpad rumble + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = 0; + vib.wRightMotorSpeed = 0; + XInputSetState(GCMapping[i].ID, &vib); +#endif + } + else + { + // It may look weird, but we don't free anything here, it was the cause of crashes + // on stop, and the DLL isn't unloaded anyway, so the pointers stay + // We just stop the rumble in case it's still playing an effect. + if (pRumble[GCMapping[i].ID].g_pDevice && pRumble[GCMapping[i].ID].g_pEffect) + pRumble[GCMapping[i].ID].g_pEffect->Stop(); + } + } +} + +#else // Multiplatform SDL Rumble code + +#ifdef SDL_RUMBLE + +struct RUMBLE // GC Pad rumble DIDevice +{ + SDL_Haptic* g_pDevice; + SDL_HapticEffect g_pEffect; + int effect_id; +}; + +RUMBLE pRumble[4] = {0}; // 4 GC Rumble Pads +#endif + + +// Use PAD rumble +// -------------- +bool PAD_Init_Rumble(u8 _numPAD, SDL_Joystick *SDL_Device) +{ +#ifdef SDL_RUMBLE + if (SDL_Device == NULL) + return false; + + pRumble[_numPAD].g_pDevice = SDL_HapticOpenFromJoystick(SDL_Device); + + if (pRumble[_numPAD].g_pDevice == NULL) + return false; // Most likely joystick isn't haptic + + if (!(SDL_HapticQuery(pRumble[_numPAD].g_pDevice) & SDL_HAPTIC_CONSTANT)) + { + SDL_HapticClose(pRumble[_numPAD].g_pDevice); // No effect + pRumble[_numPAD].g_pDevice = 0; + GCMapping[_numPAD].rumble = false; + return false; + } + + // Set the strength of the rumble effect + int Strenght = 3276 * (g_Config.RumbleStrength + 1); + Strenght = Strenght > 32767 ? 32767 : Strenght; + + // Create the effect + memset(&pRumble[_numPAD].g_pEffect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default + pRumble[_numPAD].g_pEffect.type = SDL_HAPTIC_CONSTANT; + pRumble[_numPAD].g_pEffect.constant.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates + pRumble[_numPAD].g_pEffect.constant.direction.dir[0] = 18000; // Force comes from south + pRumble[_numPAD].g_pEffect.constant.level = Strenght; + pRumble[_numPAD].g_pEffect.constant.length = 10000; // 10s long (should be INFINITE, but 10s is safer) + pRumble[_numPAD].g_pEffect.constant.attack_length = 0; // disable Fade in... + pRumble[_numPAD].g_pEffect.constant.fade_length = 0; // ...and out + + // Upload the effect + pRumble[_numPAD].effect_id = SDL_HapticNewEffect( pRumble[_numPAD].g_pDevice, &pRumble[_numPAD].g_pEffect ); +#endif + return true; +} + + +// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 +// -------------- +void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +{ +#ifdef SDL_RUMBLE + if (GCMapping[_numPAD].rumble) // rumble activated + { + if (!pRumble[_numPAD].g_pDevice) + return; + + if (_uType == 1 && _uStrength > 2) + SDL_HapticRunEffect( pRumble[_numPAD].g_pDevice, pRumble[_numPAD].effect_id, 1 ); + else + SDL_HapticStopAll(pRumble[_numPAD].g_pDevice); + } +#endif +} + +void PAD_RumbleClose() +{ +#ifdef SDL_RUMBLE + for (int i=0; i<4; i++) // Free all pads + { + if (pRumble[i].g_pDevice) { + SDL_HapticClose( pRumble[i].g_pDevice ); + pRumble[i].g_pDevice = NULL; + } + } +#endif +} + +#endif // RUMBLE_HACK diff --git a/Source/Plugins/Plugin_GCPad/Src/SConscript b/Source/Plugins/Plugin_GCPad/Src/SConscript new file mode 100644 index 0000000000..4ae051f59f --- /dev/null +++ b/Source/Plugins/Plugin_GCPad/Src/SConscript @@ -0,0 +1,31 @@ +# -*- python -*- + +Import('env') +import sys + +name = "Plugin_GCPad" +padenv = env.Clone() + +if not env['HAVE_SDL']: + print name + " must have SDL to be build" + Return() + +files = [ + 'Config.cpp', + 'GCPad.cpp', + 'Rumble.cpp', + ] +if padenv['HAVE_WX']: + files += [ + 'ConfigJoypad.cpp', + 'ConfigBox.cpp', + ] + +padenv.Append( + LIBS = [ 'inputcommon', 'common', ], + ) + +if sys.platform == 'darwin': + padenv['FRAMEWORKS'] = ['CoreFoundation', 'System' ] + +padenv.SharedLibrary(env['plugin_dir']+name, files) diff --git a/Source/Plugins/Plugin_GCPadNew/Plugin_GCPadNew.vcproj b/Source/Plugins/Plugin_GCPadNew/Plugin_GCPadNew.vcproj new file mode 100644 index 0000000000..e32ef83007 --- /dev/null +++ b/Source/Plugins/Plugin_GCPadNew/Plugin_GCPadNew.vcproj @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Core/Core/Src/HW/GCPadEmu.cpp b/Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.cpp similarity index 88% rename from Source/Core/Core/Src/HW/GCPadEmu.cpp rename to Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.cpp index ea818d2a1d..500ec666b3 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.cpp +++ b/Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.cpp @@ -1,108 +1,108 @@ -#include "../Host.h" -#include "GCPadEmu.h" - -const u16 button_bitmasks[] = -{ - PAD_BUTTON_A, - PAD_BUTTON_B, - PAD_BUTTON_X, - PAD_BUTTON_Y, - PAD_TRIGGER_Z, - PAD_BUTTON_START -}; - -const u16 trigger_bitmasks[] = -{ - PAD_TRIGGER_L, - PAD_TRIGGER_R, -}; - -const u16 dpad_bitmasks[] = -{ - PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT -}; - -const char* const named_buttons[] = -{ - "A", - "B", - "X", - "Y", - "Z", - "Start", -}; - -const char* const named_triggers[] = -{ - "L", "R", "L-Analog", "R-Analog" -}; - -GCPad::GCPad( const unsigned int index ) : m_index(index) -{ - - // buttons - groups.push_back( m_buttons = new Buttons( "Buttons" ) ); - for ( unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i ) - m_buttons->controls.push_back( new ControlGroup::Input( named_buttons[i] ) ); - - // sticks - groups.push_back( m_main_stick = new AnalogStick( "Main Stick" ) ); - groups.push_back( m_c_stick = new AnalogStick( "C-Stick" ) ); - - // triggers - groups.push_back( m_triggers = new MixedTriggers( "Triggers" ) ); - for ( unsigned int i=0; i < sizeof(named_triggers)/sizeof(*named_triggers); ++i ) - m_triggers->controls.push_back( new ControlGroup::Input( named_triggers[i] ) ); - - // rumble - groups.push_back( m_rumble = new ControlGroup( "Rumble" ) ); - m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) ); - - // dpad - groups.push_back( m_dpad = new Buttons( "D-Pad" ) ); - for ( unsigned int i=0; i < 4; ++i ) - m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) ); - - // options - groups.push_back( m_options = new ControlGroup( "Options" ) ); - m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) ); - -} - -std::string GCPad::GetName() const -{ - return std::string("GCPad") + char('1'+m_index); -} - -void GCPad::GetInput( SPADStatus* const pad ) -{ - // if window has focus or background input enabled - if (Host_RendererHasFocus() || m_options[0].settings[0]->value ) - { - // buttons - m_buttons->GetState( &pad->button, button_bitmasks ); - - // TODO: set analog A/B analog to full or w/e, prolly not needed - - // dpad - m_dpad->GetState( &pad->button, dpad_bitmasks ); - - // sticks - m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 ); - m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 ); - - // triggers - m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF ); - } - else - { - // center sticks - memset( &pad->stickX, 0x80, 4 ); - } -} - -void GCPad::SetOutput( const bool on ) -{ - // only rumble if window has focus or background input is enabled - m_rumble->controls[0]->control_ref->State( on && (Host_RendererHasFocus() || m_options[0].settings[0]->value) ); -} + +#include "GCPadEmu.h" + +const u16 button_bitmasks[] = +{ + PAD_BUTTON_A, + PAD_BUTTON_B, + PAD_BUTTON_X, + PAD_BUTTON_Y, + PAD_TRIGGER_Z, + PAD_BUTTON_START +}; + +const u16 trigger_bitmasks[] = +{ + PAD_TRIGGER_L, + PAD_TRIGGER_R, +}; + +const u16 dpad_bitmasks[] = +{ + PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT +}; + +const char* const named_buttons[] = +{ + "A", + "B", + "X", + "Y", + "Z", + "Start", +}; + +const char* const named_triggers[] = +{ + "L", "R", "L-Analog", "R-Analog" +}; + +GCPad::GCPad( const unsigned int index ) : m_index(index) +{ + + // buttons + groups.push_back( m_buttons = new Buttons( "Buttons" ) ); + for ( unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i ) + m_buttons->controls.push_back( new ControlGroup::Input( named_buttons[i] ) ); + + // sticks + groups.push_back( m_main_stick = new AnalogStick( "Main Stick" ) ); + groups.push_back( m_c_stick = new AnalogStick( "C-Stick" ) ); + + // triggers + groups.push_back( m_triggers = new MixedTriggers( "Triggers" ) ); + for ( unsigned int i=0; i < sizeof(named_triggers)/sizeof(*named_triggers); ++i ) + m_triggers->controls.push_back( new ControlGroup::Input( named_triggers[i] ) ); + + // rumble + groups.push_back( m_rumble = new ControlGroup( "Rumble" ) ); + m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) ); + + // dpad + groups.push_back( m_dpad = new Buttons( "D-Pad" ) ); + for ( unsigned int i=0; i < 4; ++i ) + m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) ); + + // options + groups.push_back( m_options = new ControlGroup( "Options" ) ); + m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) ); + +} + +std::string GCPad::GetName() const +{ + return std::string("GCPad") + char('1'+m_index); +} + +void GCPad::GetInput( SPADStatus* const pad ) +{ + // if window has focus or background input enabled + if (g_PADInitialize->pRendererHasFocus() || m_options[0].settings[0]->value ) + { + // buttons + m_buttons->GetState( &pad->button, button_bitmasks ); + + // TODO: set analog A/B analog to full or w/e, prolly not needed + + // dpad + m_dpad->GetState( &pad->button, dpad_bitmasks ); + + // sticks + m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 ); + m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 ); + + // triggers + m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF ); + } + else + { + // center sticks + memset( &pad->stickX, 0x80, 4 ); + } +} + +void GCPad::SetOutput( const bool on ) +{ + // only rumble if window has focus or background input is enabled + m_rumble->controls[0]->control_ref->State( on && (g_PADInitialize->pRendererHasFocus() || m_options[0].settings[0]->value) ); +} diff --git a/Source/Core/Core/Src/HW/GCPadEmu.h b/Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.h similarity index 81% rename from Source/Core/Core/Src/HW/GCPadEmu.h rename to Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.h index 09d2b4d2dd..6a1c916364 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.h +++ b/Source/Plugins/Plugin_GCPadNew/Src/GCPadEmu.h @@ -1,29 +1,34 @@ -#pragma once - -#include -#include "GCPad.h" - -class GCPad : public ControllerEmu -{ -public: - - GCPad( const unsigned int index ); - void GetInput( SPADStatus* const pad ); - void SetOutput( const bool on ); - - std::string GetName() const; - - -private: - - Buttons* m_buttons; - AnalogStick* m_main_stick; - AnalogStick* m_c_stick; - Buttons* m_dpad; - MixedTriggers* m_triggers; - ControlGroup* m_rumble; - ControlGroup* m_options; - - const unsigned int m_index; - -}; +#ifndef _CONEMU_GCPAD_H_ +#define _CONEMU_GCPAD_H_ + +#include + +extern SPADInitialize *g_PADInitialize; + +class GCPad : public ControllerEmu +{ +public: + + GCPad( const unsigned int index ); + void GetInput( SPADStatus* const pad ); + void SetOutput( const bool on ); + + std::string GetName() const; + + +private: + + Buttons* m_buttons; + AnalogStick* m_main_stick; + AnalogStick* m_c_stick; + Buttons* m_dpad; + MixedTriggers* m_triggers; + ControlGroup* m_rumble; + ControlGroup* m_options; + + const unsigned int m_index; + +}; + + +#endif diff --git a/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp b/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp new file mode 100644 index 0000000000..a72ac70ddd --- /dev/null +++ b/Source/Plugins/Plugin_GCPadNew/Src/GCPadNew.cpp @@ -0,0 +1,349 @@ + +#include "Common.h" +#include "pluginspecs_pad.h" + +#include "ControllerInterface/ControllerInterface.h" +#include "GCPadEmu.h" + +#if defined(HAVE_WX) && HAVE_WX +#include "ConfigDiag.h" +#endif +#include "../../InputPluginCommon/Src/Config.h" + +#if defined(HAVE_X11) && HAVE_X11 +#include +#endif + +#define PLUGIN_VERSION 0x0100 + +#define PLUGIN_NAME "Dolphin GCPad New" +#ifdef DEBUGFAST +#define PLUGIN_FULL_NAME PLUGIN_NAME" (DebugFast)" +#else +#ifdef _DEBUG +#define PLUGIN_FULL_NAME PLUGIN_NAME" (Debug)" +#else +#define PLUGIN_FULL_NAME PLUGIN_NAME +#endif +#endif + +// plugin globals +static Plugin g_plugin( "GCPadNew", "Pad", "GCPad" ); +SPADInitialize *g_PADInitialize = NULL; + +#ifdef _WIN32 +class wxDLLApp : public wxApp +{ + bool OnInit() + { + return true; + }; +}; +IMPLEMENT_APP_NO_MAIN(wxDLLApp) +WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); +#endif + +// copied from GCPad +HINSTANCE g_hInstance; + +// copied from GCPad +#if defined(HAVE_WX) && HAVE_WX +wxWindow* GetParentedWxWindow(HWND Parent) +{ +#ifdef _WIN32 + wxSetInstance((HINSTANCE)g_hInstance); +#endif + wxWindow *win = new wxWindow(); +#ifdef _WIN32 + win->SetHWND((WXHWND)Parent); + win->AdoptAttributesFromHWND(); +#endif + return win; +} +#endif +// / + +#ifdef _WIN32 +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + wxSetInstance(hinstDLL); + wxInitialize(); + break; + case DLL_PROCESS_DETACH: + wxUninitialize(); + break; + default: + break; + } + + g_hInstance = hinstDLL; + return TRUE; +} +#endif + +void DeInitPlugin() +{ + // i realize i am checking IsInit() twice, just too lazy to change it + if ( g_plugin.controller_interface.IsInit() ) + { + std::vector::const_iterator + i = g_plugin.controllers.begin(), + e = g_plugin.controllers.end(); + for ( ; i!=e; ++i ) + delete *i; + g_plugin.controllers.clear(); + + g_plugin.controller_interface.DeInit(); + } +} + +// if plugin isn't initialized, init and load config +void InitPlugin( void* const hwnd ) +{ + // i realize i am checking IsInit() twice, just too lazy to change it + if ( false == g_plugin.controller_interface.IsInit() ) + { + // add 4 gcpads + for ( unsigned int i = 0; i<4; ++i ) + g_plugin.controllers.push_back( new GCPad( i ) ); + + // load the saved controller config + g_plugin.LoadConfig(); + + // needed for Xlib and exclusive dinput + g_plugin.controller_interface.SetHwnd( hwnd ); + g_plugin.controller_interface.Init(); + + // update control refs + std::vector::const_iterator i = g_plugin.controllers.begin(), + e = g_plugin.controllers.end(); + for ( ; i!=e; ++i ) + (*i)->UpdateReferences( g_plugin.controller_interface ); + + } +} + +// I N T E R F A C E + +// __________________________________________________________________________________________________ +// Function: +// Purpose: +// input: +// output: +// +void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) +{ + memset( _pPADStatus, 0, sizeof(*_pPADStatus) ); + _pPADStatus->err = PAD_ERR_NONE; + // wtf is this? + _pPADStatus->button |= PAD_USE_ORIGIN; + + // try lock + if ( false == g_plugin.controls_crit.TryEnter() ) + { + // if gui has lock (messing with controls), skip this input cycle + // center axes and return + memset( &_pPADStatus->stickX, 0x80, 4 ); + return; + } + + // if we are on the next input cycle, update output and input + // if we can get a lock + static int _last_numPAD = 4; + if ( _numPAD <= _last_numPAD && g_plugin.interface_crit.TryEnter() ) + { + g_plugin.controller_interface.UpdateOutput(); + g_plugin.controller_interface.UpdateInput(); + g_plugin.interface_crit.Leave(); + } + _last_numPAD = _numPAD; + + // get input + ((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus ); + + // leave + g_plugin.controls_crit.Leave(); + +} + +// __________________________________________________________________________________________________ +// Function: Send keyboard input to the plugin +// Purpose: +// input: The key and if it's pressed or released +// output: None +// +void PAD_Input(u16 _Key, u8 _UpDown) +{ + // nofin +} + +// __________________________________________________________________________________________________ +// Function: PAD_Rumble +// Purpose: Pad rumble! +// input: PAD number, Command type (Stop=0, Rumble=1, Stop Hard=2) and strength of Rumble +// output: none +// +void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +{ + // enter + if ( g_plugin.controls_crit.TryEnter() ) + { + // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time + // set rumble + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 ); + + // leave + g_plugin.controls_crit.Leave(); + } +} + + +// GLOBAL I N T E R F A C E +// Function: GetDllInfo +// Purpose: This function allows the emulator to gather information +// about the DLL by filling in the PluginInfo structure. +// input: A pointer to a PLUGIN_INFO structure that needs to be +// filled by the function. (see def above) +// output: none +// +void GetDllInfo(PLUGIN_INFO* _pPluginInfo) +{ + // don't feel like messing around with all those strcpy functions and warnings + //char *s1 = CIFACE_PLUGIN_FULL_NAME, *s2 = _pPluginInfo->Name; + //while ( *s2++ = *s1++ ); + memcpy( _pPluginInfo->Name, PLUGIN_FULL_NAME, sizeof(PLUGIN_FULL_NAME) ); + _pPluginInfo->Type = PLUGIN_TYPE_PAD; + _pPluginInfo->Version = PLUGIN_VERSION; +} + +// ___________________________________________________________________________ +// Function: DllConfig +// Purpose: This function is optional function that is provided +// to allow the user to configure the DLL +// input: A handle to the window that calls this function +// output: none +// +void DllConfig(HWND _hParent) +{ + bool was_init = false; +#if defined(HAVE_X11) && HAVE_X11 + Display *dpy = NULL; +#endif + if ( g_plugin.controller_interface.IsInit() ) // check if game is running + was_init = true; + else + { +#if defined(HAVE_X11) && HAVE_X11 + dpy = XOpenDisplay(0); + InitPlugin(dpy); +#else + InitPlugin(_hParent); +#endif + } + + // copied from GCPad +#if defined(HAVE_WX) && HAVE_WX + wxWindow *frame = GetParentedWxWindow(_hParent); + ConfigDialog* m_ConfigFrame = new ConfigDialog( frame, g_plugin, PLUGIN_FULL_NAME, was_init ); + +#ifdef _WIN32 + frame->Disable(); + m_ConfigFrame->ShowModal(); + frame->Enable(); +#else + m_ConfigFrame->ShowModal(); +#endif + +#ifdef _WIN32 + wxMilliSleep( 50 ); // hooray for hacks + frame->SetFocus(); + frame->SetHWND(NULL); +#endif + + m_ConfigFrame->Destroy(); + m_ConfigFrame = NULL; + frame->Destroy(); +#endif + // / + + if ( !was_init ) // if game is running + { +#if defined(HAVE_X11) && HAVE_X11 + XCloseDisplay(dpy); +#endif + DeInitPlugin(); + } +} + +// ___________________________________________________________________________ +// Function: DllDebugger +// Purpose: Open the debugger +// input: a handle to the window that calls this function +// output: none +// +void DllDebugger(HWND _hParent, bool Show) +{ + // wut? +} + +// ___________________________________________________________________________ +// Function: DllSetGlobals +// Purpose: Set the pointer for globals variables +// input: a pointer to the global struct +// output: none +// +void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) +{ + // wut? +} + +// ___________________________________________________________________________ +// Function: Initialize +// Purpose: Initialize the plugin +// input: Init +// output: none +// +void Initialize(void *init) +{ + g_PADInitialize = (SPADInitialize*)init; + if ( false == g_plugin.controller_interface.IsInit() ) + InitPlugin( g_PADInitialize->hWnd ); +} + +// ___________________________________________________________________________ +// Function: Shutdown +// Purpose: This function is called when the emulator is shutting down +// a game allowing the dll to de-initialise. +// input: none +// output: none +// +void Shutdown(void) +{ + if ( g_plugin.controller_interface.IsInit() ) + DeInitPlugin(); +} + +// ___________________________________________________________________________ +// Function: DoState +// Purpose: Saves/load state +// input/output: ptr +// input: mode +// +void DoState(unsigned char **ptr, int mode) +{ + // prolly won't need this +} + +// ___________________________________________________________________________ +// Function: EmuStateChange +// Purpose: Notifies the plugin of a change in emulation state +// input: newState +// output: none +// +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ + // maybe use this later +} diff --git a/Source/Plugins/Plugin_GCPadNew/Src/SConscript b/Source/Plugins/Plugin_GCPadNew/Src/SConscript new file mode 100644 index 0000000000..7ce76cdaea --- /dev/null +++ b/Source/Plugins/Plugin_GCPadNew/Src/SConscript @@ -0,0 +1,21 @@ +# -*- python -*- + +Import('env') +import sys + +name = "Plugin_GCPadNew" +padenv = env.Clone() + +files = [ + 'GCPadNew.cpp', + 'GCPadEmu.cpp', + ] + +padenv.Append( + LIBS = [ 'inputplugincommon', 'inputcommon', 'common' ], + ) + +if sys.platform == 'darwin': + padenv['FRAMEWORKS'] = ['CoreFoundation', 'System', 'Cocoa', 'IOKit' ] + +padenv.SharedLibrary(env['plugin_dir']+name, files) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp index 133067fc06..194bab872c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp @@ -77,8 +77,7 @@ void GFXDebuggerDX9::SaveSettings() const { IniFile file; file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - - Section& videowindow = file["VideoWindow"]; + // TODO: make this work when we close the entire program too, currently on total close we get // weird values, perhaps because of some conflict with the rendering window // TODO: get the screen resolution and make limits from that @@ -86,13 +85,13 @@ void GFXDebuggerDX9::SaveSettings() const && GetSize().GetWidth() < 1000 && GetSize().GetHeight() < 1000) { - videowindow.Set("x", GetPosition().x); - videowindow.Set("y", GetPosition().y); - videowindow.Set("w", GetSize().GetWidth()); - videowindow.Set("h", GetSize().GetHeight()); + file.Set("VideoWindow", "x", GetPosition().x); + file.Set("VideoWindow", "y", GetPosition().y); + file.Set("VideoWindow", "w", GetSize().GetWidth()); + file.Set("VideoWindow", "h", GetSize().GetHeight()); } - videowindow.Set("WriteToFile", m_Check[0]->IsChecked()); + file.Set("VideoWindow", "WriteToFile", m_Check[0]->IsChecked()); //g_Config.iLog = bInfoLog ? CONF_LOG : 0; //g_Config.iLog |= bPrimLog ? CONF_PRIMLOG : 0; @@ -100,7 +99,7 @@ void GFXDebuggerDX9::SaveSettings() const //g_Config.iLog |= bSaveTargets ? CONF_SAVETARGETS : 0; //g_Config.iLog |= bSaveShaders ? CONF_SAVESHADERS : 0; - //videowindow.Set("ConfBits", g_Config.iLog); + //file.Set("VideoWindow", "ConfBits", g_Config.iLog); file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); } @@ -110,12 +109,11 @@ void GFXDebuggerDX9::LoadSettings() IniFile file; file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& videowindow = file["VideoWindow"]; int x = 100, y = 100, w = 100, h = 100; - videowindow.Get("x", &x, GetPosition().x); - videowindow.Get("y", &y, GetPosition().y); - videowindow.Get("w", &w, GetSize().GetWidth()); - videowindow.Get("h", &h, GetSize().GetHeight()); + file.Get("VideoWindow", "x", &x, GetPosition().x); + file.Get("VideoWindow", "y", &y, GetPosition().y); + file.Get("VideoWindow", "w", &w, GetSize().GetWidth()); + file.Get("VideoWindow", "h", &h, GetSize().GetHeight()); SetSize(x, y, w, h); //file.Get("VideoWindow", "ConfBits", &g_Config.iLog, 0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp index 086e6e3389..b6c817a262 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Debugger/Debugger.cpp @@ -68,7 +68,6 @@ void GFXDebuggerOGL::SaveSettings() const IniFile file; file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& vidwin = file["VideoWindow"]; // TODO: make this work when we close the entire program too, currently on total close we get // weird values, perhaps because of some conflict with the rendering window // TODO: get the screen resolution and make limits from that @@ -76,13 +75,13 @@ void GFXDebuggerOGL::SaveSettings() const && GetSize().GetWidth() < 1000 && GetSize().GetHeight() < 1000) { - vidwin.Set("x", GetPosition().x); - vidwin.Set("y", GetPosition().y); - vidwin.Set("w", GetSize().GetWidth()); - vidwin.Set("h", GetSize().GetHeight()); + file.Set("VideoWindow", "x", GetPosition().x); + file.Set("VideoWindow", "y", GetPosition().y); + file.Set("VideoWindow", "w", GetSize().GetWidth()); + file.Set("VideoWindow", "h", GetSize().GetHeight()); } - vidwin.Set("WriteToFile", m_Check[0]->IsChecked()); + file.Set("VideoWindow", "WriteToFile", m_Check[0]->IsChecked()); g_Config.iLog = bInfoLog ? CONF_LOG : 0; g_Config.iLog |= bPrimLog ? CONF_PRIMLOG : 0; @@ -90,7 +89,7 @@ void GFXDebuggerOGL::SaveSettings() const g_Config.iLog |= bSaveTargets ? CONF_SAVETARGETS : 0; g_Config.iLog |= bSaveShaders ? CONF_SAVESHADERS : 0; - vidwin.Set("ConfBits", g_Config.iLog); + file.Set("VideoWindow", "ConfBits", g_Config.iLog); file.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); } @@ -100,15 +99,14 @@ void GFXDebuggerOGL::LoadSettings() IniFile file; file.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); - Section& vidwin = file["VideoWindow"]; int x = 100, y = 100, w = 100, h = 100; - vidwin.Get("x", &x, GetPosition().x); - vidwin.Get("y", &y, GetPosition().y); - vidwin.Get("w", &w, GetSize().GetWidth()); - vidwin.Get("h", &h, GetSize().GetHeight()); + file.Get("VideoWindow", "x", &x, GetPosition().x); + file.Get("VideoWindow", "y", &y, GetPosition().y); + file.Get("VideoWindow", "w", &w, GetSize().GetWidth()); + file.Get("VideoWindow", "h", &h, GetSize().GetHeight()); SetSize(x, y, w, h); - vidwin.Get("ConfBits", &g_Config.iLog, 0); + file.Get("VideoWindow", "ConfBits", &g_Config.iLog, 0); bInfoLog = (g_Config.iLog & CONF_LOG) ? true : false; bPrimLog = (g_Config.iLog & CONF_PRIMLOG) ? true : false; bSaveTextures = (g_Config.iLog & CONF_SAVETEXTURES) ? true : false; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 1409566522..9a714eeed5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -406,7 +406,7 @@ bool OpenGL_MakeCurrent() #if defined(USE_WX) && USE_WX GLWin.glCanvas->SetCurrent(*GLWin.glCtxt); #elif defined(_WIN32) - return wglMakeCurrent(hDC,hRC) != 0; + return wglMakeCurrent(hDC,hRC); #elif defined(HAVE_X11) && HAVE_X11 g_VideoInitialize.pRequestWindowSize(GLWin.x, GLWin.y, (int&)GLWin.width, (int&)GLWin.height); XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfig.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfig.cpp index 05977db656..74470df1a4 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfig.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfig.cpp @@ -45,9 +45,8 @@ void Config::Load() IniFile iniFile; iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_software.ini").c_str()); - Section& hardware = iniFile["Hardware"]; - hardware.Get("Fullscreen", &bFullscreen, false); // Hardware - hardware.Get("RenderToMainframe", &renderToMainframe, false); + iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware + iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false); } @@ -57,9 +56,8 @@ void Config::Save() IniFile iniFile; iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_software.ini").c_str()); - Section& hardware = iniFile["Hardware"]; - hardware.Set("Fullscreen", bFullscreen); - hardware.Set("RenderToMainframe", renderToMainframe); + iniFile.Set("Hardware", "Fullscreen", bFullscreen); + iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe); iniFile.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_opengl.ini").c_str()); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp index beb9d7f671..16da0c008d 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp @@ -263,85 +263,82 @@ void Config::Load() iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Wiimote.ini").c_str()); // Real Wiimote - Section& real = iniFile["Real"]; - - real.Get("UpdateStatus", &bUpdateRealWiimote, true); - real.Get("Unpair", &bUnpairRealWiimote, false); - real.Get("Autopair", &bPairRealWiimote, false); - real.Get("Timeout", &bWiiReadTimeout, 10); - real.Get("AccNeutralX", &iAccNeutralX, 0); - real.Get("AccNeutralY", &iAccNeutralY, 0); - real.Get("AccNeutralZ", &iAccNeutralZ, 0); - real.Get("AccNunNeutralX", &iAccNunNeutralX, 0); - real.Get("AccNunNeutralY", &iAccNunNeutralY, 0); - real.Get("AccNunNeutralZ", &iAccNunNeutralZ, 0); + iniFile.Get("Real", "UpdateStatus", &bUpdateRealWiimote, true); + iniFile.Get("Real", "Unpair", &bUnpairRealWiimote, false); + iniFile.Get("Real", "Autopair", &bPairRealWiimote, false); + iniFile.Get("Real", "Timeout", &bWiiReadTimeout, 10); + 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); for (int i = 0; i < MAX_WIIMOTES; i++) { // Slot specific settings char SectionName[32]; sprintf(SectionName, "Wiimote%i", i + 1); - Section& section = iniFile[SectionName]; // General - section.Get("Source", &WiiMoteEmu::WiiMapping[i].Source, (i == 0) ? 1 : 0); + iniFile.Get(SectionName, "Source", &WiiMoteEmu::WiiMapping[i].Source, (i == 0) ? 1 : 0); - section.Get("Sideways", &WiiMoteEmu::WiiMapping[i].bSideways, false); - section.Get("Upright", &WiiMoteEmu::WiiMapping[i].bUpright, false); - section.Get("ExtensionConnected", &WiiMoteEmu::WiiMapping[i].iExtensionConnected, WiiMoteEmu::EXT_NONE); - section.Get("MotionPlusConnected", &WiiMoteEmu::WiiMapping[i].bMotionPlusConnected, false); + iniFile.Get(SectionName, "Sideways", &WiiMoteEmu::WiiMapping[i].bSideways, false); + iniFile.Get(SectionName, "Upright", &WiiMoteEmu::WiiMapping[i].bUpright, false); + iniFile.Get(SectionName, "ExtensionConnected", &WiiMoteEmu::WiiMapping[i].iExtensionConnected, WiiMoteEmu::EXT_NONE); + iniFile.Get(SectionName, "MotionPlusConnected", &WiiMoteEmu::WiiMapping[i].bMotionPlusConnected, false); - section.Get("TiltInputWM", &WiiMoteEmu::WiiMapping[i].Tilt.InputWM, WiiMoteEmu::FROM_KEYBOARD); - section.Get("TiltInputNC", &WiiMoteEmu::WiiMapping[i].Tilt.InputNC, WiiMoteEmu::FROM_KEYBOARD); - section.Get("TiltRollDegree", &WiiMoteEmu::WiiMapping[i].Tilt.RollDegree, 60); - section.Get("TiltRollSwing", &WiiMoteEmu::WiiMapping[i].Tilt.RollSwing, false); - section.Get("TiltRollInvert", &WiiMoteEmu::WiiMapping[i].Tilt.RollInvert, false); + iniFile.Get(SectionName, "TiltInputWM", &WiiMoteEmu::WiiMapping[i].Tilt.InputWM, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "TiltInputNC", &WiiMoteEmu::WiiMapping[i].Tilt.InputNC, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "TiltRollDegree", &WiiMoteEmu::WiiMapping[i].Tilt.RollDegree, 60); + iniFile.Get(SectionName, "TiltRollSwing", &WiiMoteEmu::WiiMapping[i].Tilt.RollSwing, false); + iniFile.Get(SectionName, "TiltRollInvert", &WiiMoteEmu::WiiMapping[i].Tilt.RollInvert, false); WiiMoteEmu::WiiMapping[i].Tilt.RollRange = (WiiMoteEmu::WiiMapping[i].Tilt.RollSwing) ? 0 : WiiMoteEmu::WiiMapping[i].Tilt.RollDegree; - section.Get("TiltPitchDegree", &WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree, 60); - section.Get("TiltPitchSwing", &WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing, false); - section.Get("TiltPitchInvert", &WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert, false); + iniFile.Get(SectionName, "TiltPitchDegree", &WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree, 60); + iniFile.Get(SectionName, "TiltPitchSwing", &WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing, false); + iniFile.Get(SectionName, "TiltPitchInvert", &WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert, false); WiiMoteEmu::WiiMapping[i].Tilt.PitchRange = (WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing) ? 0 : WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree; // StickMapping - section.Get("NCStick", &WiiMoteEmu::WiiMapping[i].Stick.NC, WiiMoteEmu::FROM_KEYBOARD); - section.Get("CCStickLeft", &WiiMoteEmu::WiiMapping[i].Stick.CCL, WiiMoteEmu::FROM_KEYBOARD); - section.Get("CCStickRight", &WiiMoteEmu::WiiMapping[i].Stick.CCR, WiiMoteEmu::FROM_KEYBOARD); - section.Get("CCTriggers", &WiiMoteEmu::WiiMapping[i].Stick.CCT, WiiMoteEmu::FROM_KEYBOARD); - section.Get("GHStick", &WiiMoteEmu::WiiMapping[i].Stick.GH, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "NCStick", &WiiMoteEmu::WiiMapping[i].Stick.NC, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "CCStickLeft", &WiiMoteEmu::WiiMapping[i].Stick.CCL, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "CCStickRight", &WiiMoteEmu::WiiMapping[i].Stick.CCR, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "CCTriggers", &WiiMoteEmu::WiiMapping[i].Stick.CCT, WiiMoteEmu::FROM_KEYBOARD); + iniFile.Get(SectionName, "GHStick", &WiiMoteEmu::WiiMapping[i].Stick.GH, WiiMoteEmu::FROM_KEYBOARD); // ButtonMapping for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; x++) - section.Get(wmControlNames[x], &WiiMoteEmu::WiiMapping[i].Button[x], wmDefaultControls[x]); + iniFile.Get(SectionName, wmControlNames[x], &WiiMoteEmu::WiiMapping[i].Button[x], wmDefaultControls[x]); // 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 - section.Get("DeviceID", &WiiMoteEmu::WiiMapping[i].ID, 0); + iniFile.Get(SectionName, "DeviceID", &WiiMoteEmu::WiiMapping[i].ID, 0); - section.Get("Axis_Lx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Lx, 0); - section.Get("Axis_Ly", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ly, 1); - section.Get("Axis_Rx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Rx, 2); - section.Get("Axis_Ry", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ry, 3); - section.Get("Trigger_L", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tl, 1004); - section.Get("Trigger_R", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tr, 1005); - section.Get("DeadZoneL", &WiiMoteEmu::WiiMapping[i].DeadZoneL, 0); - section.Get("DeadZoneR", &WiiMoteEmu::WiiMapping[i].DeadZoneR, 0); - section.Get("Diagonal", &WiiMoteEmu::WiiMapping[i].Diagonal, 100); - section.Get("Circle2Square", &WiiMoteEmu::WiiMapping[i].bCircle2Square, false); - section.Get("Rumble", &WiiMoteEmu::WiiMapping[i].Rumble, false); - section.Get("RumbleStrength", &WiiMoteEmu::WiiMapping[i].RumbleStrength, 80); - section.Get("TriggerType", &WiiMoteEmu::WiiMapping[i].TriggerType, 0); + iniFile.Get(SectionName, "Axis_Lx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Lx, 0); + iniFile.Get(SectionName, "Axis_Ly", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ly, 1); + iniFile.Get(SectionName, "Axis_Rx", &WiiMoteEmu::WiiMapping[i].AxisMapping.Rx, 2); + iniFile.Get(SectionName, "Axis_Ry", &WiiMoteEmu::WiiMapping[i].AxisMapping.Ry, 3); + iniFile.Get(SectionName, "Trigger_L", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tl, 1004); + iniFile.Get(SectionName, "Trigger_R", &WiiMoteEmu::WiiMapping[i].AxisMapping.Tr, 1005); + iniFile.Get(SectionName, "DeadZoneL", &WiiMoteEmu::WiiMapping[i].DeadZoneL, 0); + iniFile.Get(SectionName, "DeadZoneR", &WiiMoteEmu::WiiMapping[i].DeadZoneR, 0); + iniFile.Get(SectionName, "Diagonal", &WiiMoteEmu::WiiMapping[i].Diagonal, 100); + iniFile.Get(SectionName, "Circle2Square", &WiiMoteEmu::WiiMapping[i].bCircle2Square, false); + iniFile.Get(SectionName, "Rumble", &WiiMoteEmu::WiiMapping[i].Rumble, false); + iniFile.Get(SectionName, "RumbleStrength", &WiiMoteEmu::WiiMapping[i].RumbleStrength, 80); + iniFile.Get(SectionName, "TriggerType", &WiiMoteEmu::WiiMapping[i].TriggerType, 0); //UDPWii - section.Get("UDPWii_Enable", &WiiMoteEmu::WiiMapping[i].UDPWM.enable, false); + iniFile.Get(SectionName, "UDPWii_Enable", &WiiMoteEmu::WiiMapping[i].UDPWM.enable, false); std::string port; char default_port[15]; sprintf(default_port,"%d",4432+i); - section.Get("UDPWii_Port", &port, default_port); + iniFile.Get(SectionName, "UDPWii_Port", &port, default_port); strncpy(WiiMoteEmu::WiiMapping[i].UDPWM.port,port.c_str(),10); - section.Get("UDPWii_EnableAccel", &WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel, true); - section.Get("UDPWii_EnableButtons", &WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons, true); - section.Get("UDPWii_EnableIR", &WiiMoteEmu::WiiMapping[i].UDPWM.enableIR, true); - section.Get("UDPWii_EnableNunchuck", &WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck, true); + iniFile.Get(SectionName, "UDPWii_EnableAccel", &WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel, true); + iniFile.Get(SectionName, "UDPWii_EnableButtons", &WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons, true); + iniFile.Get(SectionName, "UDPWii_EnableIR", &WiiMoteEmu::WiiMapping[i].UDPWM.enableIR, true); + iniFile.Get(SectionName, "UDPWii_EnableNunchuck", &WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck, true); } iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Dolphin.ini").c_str()); @@ -349,7 +346,7 @@ void Config::Load() { char SectionName[32]; sprintf(SectionName, "Wiimote%i", i + 1); - iniFile[SectionName].Get("AutoReconnectRealWiimote", &WiiMoteEmu::WiiMapping[i].bWiiAutoReconnect, false); + iniFile.Get(SectionName, "AutoReconnectRealWiimote", &WiiMoteEmu::WiiMapping[i].bWiiAutoReconnect, false); } Config::LoadIR(); @@ -357,10 +354,9 @@ void Config::Load() // 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((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_opengl.ini").c_str()); - Section& settings = iniFile["Settings"]; - settings.Get("KeepAR_4_3", &bKeepAR43, false); - settings.Get("KeepAR_16_9", &bKeepAR169, false); - settings.Get("Crop", &bCrop, false); + iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false); + iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false); + iniFile.Get("Settings", "Crop", &bCrop, false); //DEBUG_LOG(WIIMOTE, "Load()"); } @@ -372,23 +368,21 @@ void Config::LoadIR() char TmpSection[32]; int defaultLeft, defaultTop, defaultWidth, defaultHeight; + sprintf(TmpSection, "%s", g_ISOId ? Hex2Ascii(g_ISOId).c_str() : "Default"); iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "IrPointer.ini").c_str()); //Load defaults first... - Section& def = iniFile["Default"]; - def.Get("IRLeft", &defaultLeft, LEFT); - def.Get("IRTop", &defaultTop, TOP); - def.Get("IRWidth", &defaultWidth, RIGHT - LEFT); - def.Get("IRHeight", &defaultHeight, BOTTOM - TOP); - def.Get("IRLevel", &iIRLevel, 3); + iniFile.Get("Default", "IRLeft", &defaultLeft, LEFT); + iniFile.Get("Default", "IRTop", &defaultTop, TOP); + iniFile.Get("Default", "IRWidth", &defaultWidth, RIGHT - LEFT); + iniFile.Get("Default", "IRHeight", &defaultHeight, BOTTOM - TOP); + iniFile.Get("Default", "IRLevel", &iIRLevel, 3); //...and fall back to them if the GameId is not found. //It shouldn't matter if we read Default twice, its in memory anyways. - sprintf(TmpSection, "%s", g_ISOId ? Hex2Ascii(g_ISOId).c_str() : "Default"); - Section& tmpsection = iniFile[TmpSection]; - tmpsection.Get("IRLeft", &iIRLeft, defaultLeft); - tmpsection.Get("IRTop", &iIRTop, defaultTop); - tmpsection.Get("IRWidth", &iIRWidth, defaultWidth); - tmpsection.Get("IRHeight", &iIRHeight, defaultHeight); + iniFile.Get(TmpSection, "IRLeft", &iIRLeft, defaultLeft); + iniFile.Get(TmpSection, "IRTop", &iIRTop, defaultTop); + iniFile.Get(TmpSection, "IRWidth", &iIRWidth, defaultWidth); + iniFile.Get(TmpSection, "IRHeight", &iIRHeight, defaultHeight); } void Config::Save() @@ -396,74 +390,72 @@ void Config::Save() IniFile iniFile; iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Wiimote.ini").c_str()); - Section& real = iniFile["Real"]; - real.Set("UpdateStatus", bUpdateRealWiimote); - real.Set("Unpair", bUnpairRealWiimote); - real.Set("Autopair", bPairRealWiimote); - real.Set("Timeout", bWiiReadTimeout); - real.Set("AccNeutralX", iAccNeutralX); - real.Set("AccNeutralY", iAccNeutralY); - real.Set("AccNeutralZ", iAccNeutralZ); - real.Set("AccNunNeutralX", iAccNunNeutralX); - real.Set("AccNunNeutralY", iAccNunNeutralY); - real.Set("AccNunNeutralZ", iAccNunNeutralZ); + iniFile.Set("Real", "UpdateStatus", bUpdateRealWiimote); + iniFile.Set("Real", "Unpair", bUnpairRealWiimote); + iniFile.Set("Real", "Autopair", bPairRealWiimote); + iniFile.Set("Real", "Timeout", bWiiReadTimeout); + 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 < MAX_WIIMOTES; i++) { // Slot specific settings char SectionName[32]; sprintf(SectionName, "Wiimote%i", i + 1); - Section& section = iniFile[SectionName]; - section.Set("Source", WiiMoteEmu::WiiMapping[i].Source); - section.Set("Sideways", WiiMoteEmu::WiiMapping[i].bSideways); - section.Set("Upright", WiiMoteEmu::WiiMapping[i].bUpright); - section.Set("ExtensionConnected", WiiMoteEmu::WiiMapping[i].iExtensionConnected); - section.Set("MotionPlusConnected", WiiMoteEmu::WiiMapping[i].bMotionPlusConnected); - section.Set("TiltInputWM", WiiMoteEmu::WiiMapping[i].Tilt.InputWM); - section.Set("TiltInputNC", WiiMoteEmu::WiiMapping[i].Tilt.InputNC); - section.Set("TiltRollDegree", WiiMoteEmu::WiiMapping[i].Tilt.RollDegree); - section.Set("TiltRollSwing", WiiMoteEmu::WiiMapping[i].Tilt.RollSwing); - section.Set("TiltRollInvert", WiiMoteEmu::WiiMapping[i].Tilt.RollInvert); - section.Set("TiltPitchDegree", WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree); - section.Set("TiltPitchSwing", WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing); - section.Set("TiltPitchInvert", WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert); + iniFile.Set(SectionName, "Source", WiiMoteEmu::WiiMapping[i].Source); + iniFile.Set(SectionName, "Sideways", WiiMoteEmu::WiiMapping[i].bSideways); + iniFile.Set(SectionName, "Upright", WiiMoteEmu::WiiMapping[i].bUpright); + iniFile.Set(SectionName, "ExtensionConnected", WiiMoteEmu::WiiMapping[i].iExtensionConnected); + iniFile.Set(SectionName, "MotionPlusConnected", WiiMoteEmu::WiiMapping[i].bMotionPlusConnected); + iniFile.Set(SectionName, "TiltInputWM", WiiMoteEmu::WiiMapping[i].Tilt.InputWM); + iniFile.Set(SectionName, "TiltInputNC", WiiMoteEmu::WiiMapping[i].Tilt.InputNC); + iniFile.Set(SectionName, "TiltRollDegree", WiiMoteEmu::WiiMapping[i].Tilt.RollDegree); + iniFile.Set(SectionName, "TiltRollSwing", WiiMoteEmu::WiiMapping[i].Tilt.RollSwing); + iniFile.Set(SectionName, "TiltRollInvert", WiiMoteEmu::WiiMapping[i].Tilt.RollInvert); + iniFile.Set(SectionName, "TiltPitchDegree", WiiMoteEmu::WiiMapping[i].Tilt.PitchDegree); + iniFile.Set(SectionName, "TiltPitchSwing", WiiMoteEmu::WiiMapping[i].Tilt.PitchSwing); + iniFile.Set(SectionName, "TiltPitchInvert", WiiMoteEmu::WiiMapping[i].Tilt.PitchInvert); // StickMapping - section.Set("NCStick", WiiMoteEmu::WiiMapping[i].Stick.NC); - section.Set("CCStickLeft", WiiMoteEmu::WiiMapping[i].Stick.CCL); - section.Set("CCStickRight", WiiMoteEmu::WiiMapping[i].Stick.CCR); - section.Set("CCTriggers", WiiMoteEmu::WiiMapping[i].Stick.CCT); - section.Set("GHStick", WiiMoteEmu::WiiMapping[i].Stick.GH); + iniFile.Set(SectionName, "NCStick", WiiMoteEmu::WiiMapping[i].Stick.NC); + iniFile.Set(SectionName, "CCStickLeft", WiiMoteEmu::WiiMapping[i].Stick.CCL); + iniFile.Set(SectionName, "CCStickRight", WiiMoteEmu::WiiMapping[i].Stick.CCR); + iniFile.Set(SectionName, "CCTriggers", WiiMoteEmu::WiiMapping[i].Stick.CCT); + iniFile.Set(SectionName, "GHStick", WiiMoteEmu::WiiMapping[i].Stick.GH); // ButtonMapping for (int x = 0; x < WiiMoteEmu::LAST_CONSTANT; x++) - section.Set(wmControlNames[x], WiiMoteEmu::WiiMapping[i].Button[x]); + iniFile.Set(SectionName, wmControlNames[x], WiiMoteEmu::WiiMapping[i].Button[x]); // Save the physical device ID number - section.Set("DeviceID", WiiMoteEmu::WiiMapping[i].ID); + iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::WiiMapping[i].ID); - section.Set("Axis_Lx", WiiMoteEmu::WiiMapping[i].AxisMapping.Lx); - section.Set("Axis_Ly", WiiMoteEmu::WiiMapping[i].AxisMapping.Ly); - section.Set("Axis_Rx", WiiMoteEmu::WiiMapping[i].AxisMapping.Rx); - section.Set("Axis_Ry", WiiMoteEmu::WiiMapping[i].AxisMapping.Ry); - section.Set("Trigger_L", WiiMoteEmu::WiiMapping[i].AxisMapping.Tl); - section.Set("Trigger_R", WiiMoteEmu::WiiMapping[i].AxisMapping.Tr); - section.Set("DeadZoneL", WiiMoteEmu::WiiMapping[i].DeadZoneL); - section.Set("DeadZoneR", WiiMoteEmu::WiiMapping[i].DeadZoneR); - section.Set("Diagonal", WiiMoteEmu::WiiMapping[i].Diagonal); - section.Set("Circle2Square", WiiMoteEmu::WiiMapping[i].bCircle2Square); - section.Set("Rumble", WiiMoteEmu::WiiMapping[i].Rumble); - section.Set("RumbleStrength", WiiMoteEmu::WiiMapping[i].RumbleStrength); - section.Set("TriggerType", WiiMoteEmu::WiiMapping[i].TriggerType); + iniFile.Set(SectionName, "Axis_Lx", WiiMoteEmu::WiiMapping[i].AxisMapping.Lx); + iniFile.Set(SectionName, "Axis_Ly", WiiMoteEmu::WiiMapping[i].AxisMapping.Ly); + iniFile.Set(SectionName, "Axis_Rx", WiiMoteEmu::WiiMapping[i].AxisMapping.Rx); + iniFile.Set(SectionName, "Axis_Ry", WiiMoteEmu::WiiMapping[i].AxisMapping.Ry); + iniFile.Set(SectionName, "Trigger_L", WiiMoteEmu::WiiMapping[i].AxisMapping.Tl); + iniFile.Set(SectionName, "Trigger_R", WiiMoteEmu::WiiMapping[i].AxisMapping.Tr); + iniFile.Set(SectionName, "DeadZoneL", WiiMoteEmu::WiiMapping[i].DeadZoneL); + iniFile.Set(SectionName, "DeadZoneR", WiiMoteEmu::WiiMapping[i].DeadZoneR); + iniFile.Set(SectionName, "Diagonal", WiiMoteEmu::WiiMapping[i].Diagonal); + iniFile.Set(SectionName, "Circle2Square", WiiMoteEmu::WiiMapping[i].bCircle2Square); + iniFile.Set(SectionName, "Rumble", WiiMoteEmu::WiiMapping[i].Rumble); + iniFile.Set(SectionName, "RumbleStrength", WiiMoteEmu::WiiMapping[i].RumbleStrength); + iniFile.Set(SectionName, "TriggerType", WiiMoteEmu::WiiMapping[i].TriggerType); // UDPWii - section.Set("UDPWii_Enable", WiiMoteEmu::WiiMapping[i].UDPWM.enable); - section.Set("UDPWii_Port", WiiMoteEmu::WiiMapping[i].UDPWM.port); - section.Set("UDPWii_EnableAccel", WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel); - section.Set("UDPWii_EnableButtons", WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons); - section.Set("UDPWii_EnableIR", WiiMoteEmu::WiiMapping[i].UDPWM.enableIR); - section.Set("UDPWii_EnableNunchuck", WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck); + iniFile.Set(SectionName, "UDPWii_Enable", WiiMoteEmu::WiiMapping[i].UDPWM.enable); + iniFile.Set(SectionName, "UDPWii_Port", WiiMoteEmu::WiiMapping[i].UDPWM.port); + iniFile.Set(SectionName, "UDPWii_EnableAccel", WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel); + iniFile.Set(SectionName, "UDPWii_EnableButtons", WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons); + iniFile.Set(SectionName, "UDPWii_EnableIR", WiiMoteEmu::WiiMapping[i].UDPWM.enableIR); + iniFile.Set(SectionName, "UDPWii_EnableNunchuck", WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck); } iniFile.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Wiimote.ini").c_str()); @@ -472,12 +464,11 @@ void Config::Save() iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "IrPointer.ini").c_str()); char TmpSection[32]; sprintf(TmpSection, "%s", g_ISOId ? Hex2Ascii(g_ISOId).c_str() : "Default"); - Section& tmpsection = iniFile[TmpSection]; - tmpsection.Set("IRLeft", iIRLeft); - tmpsection.Set("IRTop", iIRTop); - tmpsection.Set("IRWidth", iIRWidth); - tmpsection.Set("IRHeight", iIRHeight); - tmpsection.Set("IRLevel", iIRLevel); + iniFile.Set(TmpSection, "IRLeft", iIRLeft); + iniFile.Set(TmpSection, "IRTop", iIRTop); + iniFile.Set(TmpSection, "IRWidth", iIRWidth); + iniFile.Set(TmpSection, "IRHeight", iIRHeight); + iniFile.Set(TmpSection, "IRLevel", iIRLevel); iniFile.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "IrPointer.ini").c_str()); //Save any options that need to be accessed in Dolphin @@ -486,7 +477,7 @@ void Config::Save() { char SectionName[32]; sprintf(SectionName, "Wiimote%i", i + 1); - iniFile[SectionName].Set("AutoReconnectRealWiimote", WiiMoteEmu::WiiMapping[i].bWiiAutoReconnect); + iniFile.Set(SectionName, "AutoReconnectRealWiimote", WiiMoteEmu::WiiMapping[i].bWiiAutoReconnect); } iniFile.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Dolphin.ini").c_str()); diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp index 456c9a364e..3b07569ac6 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp @@ -42,32 +42,31 @@ void WiimoteRecordingConfigDialog::LoadFile() // Get row name std::string SaveName = StringFromFormat("Recording%i", i); - Section& section = file[SaveName.c_str()]; // HotKey - section.Get("HotKeySwitch", &iTmp, 3); m_RecordHotKeySwitch[i]->SetSelection(iTmp); - section.Get("HotKeyWiimote", &iTmp, 10); m_RecordHotKeyWiimote[i]->SetSelection(iTmp); - section.Get("HotKeyNunchuck", &iTmp, 10); m_RecordHotKeyNunchuck[i]->SetSelection(iTmp); - section.Get("HotKeyIR", &iTmp, 10); m_RecordHotKeyIR[i]->SetSelection(iTmp); + 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 - section.Get("MovementName", &STmp, ""); m_RecordText[i]->SetValue(wxString::FromAscii(STmp.c_str())); + file.Get(SaveName.c_str(), "MovementName", &STmp, ""); m_RecordText[i]->SetValue(wxString::FromAscii(STmp.c_str())); // Game name - section.Get("GameName", &STmp, ""); m_RecordGameText[i]->SetValue(wxString::FromAscii(STmp.c_str())); + file.Get(SaveName.c_str(), "GameName", &STmp, ""); m_RecordGameText[i]->SetValue(wxString::FromAscii(STmp.c_str())); // IR Bytes - section.Get("IRBytes", &STmp, ""); m_RecordIRBytesText[i]->SetValue(wxString::FromAscii(STmp.c_str())); + file.Get(SaveName.c_str(), "IRBytes", &STmp, ""); m_RecordIRBytesText[i]->SetValue(wxString::FromAscii(STmp.c_str())); // Recording speed - section.Get("RecordingSpeed", &iTmp, -1); + 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) - section.Get("PlaybackSpeed", &iTmp, -1); m_RecordPlayBackSpeed[i]->SetSelection(iTmp); + file.Get(SaveName.c_str(), "PlaybackSpeed", &iTmp, -1); m_RecordPlayBackSpeed[i]->SetSelection(iTmp); } } @@ -82,31 +81,30 @@ void WiimoteRecordingConfigDialog::SaveFile() { // Get row name std::string SaveName = StringFromFormat("Recording%i", i); - Section& section = file[SaveName.c_str()]; // HotKey - section.Set("HotKeySwitch", m_RecordHotKeySwitch[i]->GetSelection()); - section.Set("HotKeyWiimote", m_RecordHotKeyWiimote[i]->GetSelection()); - section.Set("HotKeyNunchuck", m_RecordHotKeyNunchuck[i]->GetSelection()); - section.Set("HotKeyIR", m_RecordHotKeyIR[i]->GetSelection()); + 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 - section.Set("MovementName", (const char*)m_RecordText[i]->GetValue().mb_str(wxConvUTF8)); + file.Set(SaveName.c_str(), "MovementName", (const char*)m_RecordText[i]->GetValue().mb_str(wxConvUTF8)); // Game name - section.Set("GameName", (const char*)m_RecordGameText[i]->GetValue().mb_str(wxConvUTF8)); + file.Set(SaveName.c_str(), "GameName", (const char*)m_RecordGameText[i]->GetValue().mb_str(wxConvUTF8)); // Recording speed (currently always saved directly after a recording) /* wxString TmpRecordSpeed = m_RecordSpeed[i]->GetValue(); if(TmpRecordSpeed.length() > 0) - int TmpRecordSpeed; section.Set("RecordingSpeed", TmpRecordSpeed); + int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", TmpRecordSpeed); else - int TmpRecordSpeed; section.Set("RecordingSpeed", "-1"); + int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", "-1"); */ // Playback speed (currently always saved directly after a recording) - section.Set("PlaybackSpeed", m_RecordPlayBackSpeed[i]->GetSelection()); + file.Set(SaveName.c_str(), "PlaybackSpeed", m_RecordPlayBackSpeed[i]->GetSelection()); } file.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "WiimoteMovement.ini").c_str()); @@ -421,19 +419,17 @@ void WiimoteRecordingConfigDialog::ConvertToString() // Save file std::string SaveName = StringFromFormat("Recording%i", m_iRecordTo); - Section& section = file[SaveName]; - - section.Set("Movement", TmpStr); - section.Set("IR", TmpIR); - section.Set("Time", TmpTime); - section.Set("IRBytes", IRBytes); - section.Set("RecordingSpeed", Rate); + 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; section.Get("PlaybackSpeed", &TmpPlaySpeed, -1); + int TmpPlaySpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaySpeed, -1); if (TmpPlaySpeed == -1) { - section.Set("PlaybackSpeed", 3); + file.Set(SaveName.c_str(), "PlaybackSpeed", 3); m_RecordPlayBackSpeed[m_iRecordTo]->SetSelection(3); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index d8ee299cd9..0aecd989f4 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -116,23 +116,19 @@ void LoadRecordedMovements() VRecording.at(i).Recording.clear(); // Get row name - Section& section = file[StringFromFormat("Recording%i", i + 1)]; + std::string SaveName = StringFromFormat("Recording%i", i + 1); // Get movement - std::string TmpMovement; - section.Get("Movement", &TmpMovement, ""); + std::string TmpMovement; file.Get(SaveName.c_str(), "Movement", &TmpMovement, ""); // Get IR - std::string TmpIR; - section.Get("IR", &TmpIR, ""); + std::string TmpIR; file.Get(SaveName.c_str(), "IR", &TmpIR, ""); // Get time - std::string TmpTime; - section.Get("Time", &TmpTime, ""); + std::string TmpTime; file.Get(SaveName.c_str(), "Time", &TmpTime, ""); // Get IR bytes - int TmpIRBytes; - section.Get("IRBytes", &TmpIRBytes, 0); + int TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, 0); VRecording.at(i).IRBytes = TmpIRBytes; SRecording Tmp; @@ -185,13 +181,13 @@ void LoadRecordedMovements() } // Get HotKey - section.Get("HotKeySwitch", &iTmp, 3); VRecording.at(i).HotKeySwitch = iTmp; - section.Get("HotKeyWiimote", &iTmp, 10); VRecording.at(i).HotKeyWiimote = iTmp; - section.Get("HotKeyNunchuck", &iTmp, 10); VRecording.at(i).HotKeyNunchuck = iTmp; - section.Get("HotKeyIR", &iTmp, 10); VRecording.at(i).HotKeyIR = iTmp; + 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; section.Get("PlaybackSpeed", &TmpPlaybackSpeed, -1); + int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1); VRecording.at(i).PlaybackSpeed = TmpPlaybackSpeed; // Logging diff --git a/Source/Plugins/Plugin_WiimoteNew/Plugin_WiimoteNew.vcproj b/Source/Plugins/Plugin_WiimoteNew/Plugin_WiimoteNew.vcproj index 5f5f196465..f7f5b03621 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Plugin_WiimoteNew.vcproj +++ b/Source/Plugins/Plugin_WiimoteNew/Plugin_WiimoteNew.vcproj @@ -1,7 +1,7 @@ all_the_time) PanicAlert("Wiimote: Reporting Always is set to OFF! Everything should be fine, but games never do this."); diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp index 424c205aa8..e682d9c870 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp @@ -484,8 +484,26 @@ void Wiimote::Update() } + // ----extension---- + if (rpt.ext) + { + m_extension->GetState(data + rpt.ext, is_focus); + + // i dont think anything accesses the extension data like this, but ill support it + // i think it should be unencrpyted in the register, encrypted when read + memcpy(m_reg_ext->controller_data, data + rpt.ext, sizeof(wm_extension)); + + // both of these ifs work + //if (0x55 != m_reg_ext->encryption) + if (0xAA == m_reg_ext->encryption) + wiimote_encrypt(&m_ext_key, data + rpt.ext, 0x00, sizeof(wm_extension)); + } + // ----ir---- - if (rpt.ir) + // only if camera is fully enabled. + // should send 0xFF if camera isn't enabled maybe, + // 0x00 is working fine though + if (rpt.ir && 0x08 == m_reg_ir->data[0x30]) { float xx = 10000, yy = 0, zz = 0; @@ -508,21 +526,14 @@ void Wiimote::Update() x[1] = (unsigned int)(xx + distance); x[2] = (unsigned int)(xx - 1.2f * distance); x[3] = (unsigned int)(xx + 1.2f * distance); - - //0xFF report - if (rpt.ext) - memset(data + rpt.ir, 0xFF, (rpt.ext - rpt.ir)); - else - memset(data + rpt.ir, 0xFF, (46 - rpt.ir)); - //Fill report with valid data when full handshake was done - if (m_reg_ir->data[0x30] || m_reg_ir->data[0x33]) // ir mode switch (m_reg_ir->mode) { // basic case 1 : { + memset(data + rpt.ir, 0xFF, 10); wm_ir_basic* const irdata = (wm_ir_basic*)(data + rpt.ir); if (y < 768) { @@ -551,6 +562,7 @@ void Wiimote::Update() // extended case 3 : { + memset(data + rpt.ir, 0xFF, 12); wm_ir_extended* const irdata = (wm_ir_extended*)(data + rpt.ir); if (y < 768) { @@ -572,22 +584,10 @@ void Wiimote::Update() case 5 : // UNSUPPORTED break; + } } - // ----extension---- - if (rpt.ext) - { - m_extension->GetState(data + rpt.ext, is_focus); - - // i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this. - // i think it should be unencrpyted in the register, encrypted when read. - memcpy(m_reg_ext->controller_data, data + rpt.ext, sizeof(wm_extension)); - - if (0xAA == m_reg_ext->encryption) { - wiimote_encrypt(&m_ext_key, data + rpt.ext, 0x00, sizeof(wm_extension)); - } - } // send data report g_WiimoteInitialize.pWiimoteInput( m_index, m_reporting_channel, data, rpt.size ); } diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteNew.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteNew.cpp index 72d7eca661..3776656115 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteNew.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteNew.cpp @@ -2,13 +2,13 @@ #include "Common.h" #include "pluginspecs_wiimote.h" -#include +#include "ControllerInterface/ControllerInterface.h" #include "WiimoteEmu/WiimoteEmu.h" #if defined(HAVE_WX) && HAVE_WX #include "ConfigDiag.h" #endif -#include +#include "../../InputPluginCommon/Src/Config.h" #if defined(HAVE_X11) && HAVE_X11 #include diff --git a/Source/UnitTests/UnitTests.cpp b/Source/UnitTests/UnitTests.cpp index f7ad4c4a25..c732ea3d1e 100644 --- a/Source/UnitTests/UnitTests.cpp +++ b/Source/UnitTests/UnitTests.cpp @@ -21,6 +21,7 @@ #include "StringUtil.h" #include "MathUtil.h" #include "PowerPC/PowerPC.h" +#include "HW/SI_DeviceGCController.h" void AudioJitTests();