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
This commit is contained in:
hrydgard 2010-06-03 18:05:08 +00:00
parent 3236aa9e73
commit a3c96ac42c
118 changed files with 8868 additions and 2530 deletions

View File

@ -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 ]

View File

@ -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)

View File

@ -471,6 +471,14 @@
RelativePath=".\Src\PluginDSP.h"
>
</File>
<File
RelativePath=".\Src\PluginPAD.cpp"
>
</File>
<File
RelativePath=".\Src\PluginPAD.h"
>
</File>
<File
RelativePath=".\Src\PluginVideo.cpp"
>
@ -506,6 +514,10 @@
RelativePath="..\..\PluginSpecs\pluginspecs_dsp.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_pad.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_video.h"
>
@ -608,6 +620,10 @@
RelativePath=".\Src\CDUtils.h"
>
</File>
<File
RelativePath=".\Src\ChunkFile.cpp"
>
</File>
<File
RelativePath=".\Src\ChunkFile.h"
>

View File

@ -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 <stdio.h>

View File

@ -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

View File

@ -16,239 +16,510 @@
// http://code.google.com/p/dolphin-emu/
// see IniFile.h
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include "StringUtil.h"
#include "IniFile.h"
template <typename S>
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<Section>::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<Section>::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 = &sections[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<Section>::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<std::string>::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<std::string> lines;
Section sectmp;
Section* section = &sectmp;
std::string line;
while (std::getline(file, line)) // read a line
for (std::vector<std::string>::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<std::string>::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<std::string> &lines)
{
Section* section = GetOrCreateSection(sectionName);
section->lines.clear();
for (std::vector<std::string>::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<std::string>::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<std::string>& keys) const
{
const Section* section = GetSection(sectionName);
if (!section)
{
return false;
}
keys.clear();
for (std::vector<std::string>::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<std::string>& lines) const
{
const Section* section = GetSection(sectionName);
if (!section)
return false;
lines.clear();
for (std::vector<std::string>::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<Section>::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<std::string>::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<std::string>& newValues)
{
return find(section) != end();
std::string temp;
// Join the strings with ,
std::vector<std::string>::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<std::string>& 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<std::string>& lines)
bool IniFile::Get(const char* sectionName, const char* key, std::vector<std::string>& 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;
}
*/

View File

@ -18,105 +18,74 @@
#ifndef _INIFILE_H_
#define _INIFILE_H_
#include "CommonTypes.h"
#include <fstream>
#include <map>
#include <string>
#include <sstream>
#include <vector>
// some things that include IniFile.h rely on this being here
#include "StringUtil.h"
class IniFile;
class Section : public std::map<std::string, std::string>
class Section
{
friend class IniFile;
public:
Section() : m_use_lines(false) {}
Section();
Section(const std::string& _name);
Section(const Section& other);
std::vector<std::string>lines;
std::string name;
std::string comment;
bool Exists(const std::string& key) const;
void Delete(const std::string& key);
void SetLines(const std::vector<std::string>& lines);
void GetLines(std::vector<std::string>& 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 <typename V>
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 <typename V, typename D>
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 <typename V>
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 <typename V, typename D>
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<std::string> m_lines;
private:
bool m_use_lines;
};
class IniFile : public std::map<std::string, Section>
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<std::string>& newValues);
void Save(std::ostream& file) const;
void Load(std::istream& file);
void SetLines(const char* sectionName, const std::vector<std::string> &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<std::string>& values);
bool GetKeys(const char* sectionName, std::vector<std::string>& keys) const;
bool GetLines(const char* sectionName, std::vector<std::string>& 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<Section>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_

View File

@ -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<TPAD_GetStatus>
(LoadSymbol("PAD_GetStatus"));
PAD_Input = reinterpret_cast<TPAD_Input>
(LoadSymbol("PAD_Input"));
PAD_Rumble = reinterpret_cast<TPAD_Rumble>
(LoadSymbol("PAD_Rumble"));
if ((PAD_GetStatus != 0) &&
(PAD_Input != 0) &&
(PAD_Rumble != 0))
validPAD = true;
}
PluginPAD::~PluginPAD() {}
} // Namespace

View File

@ -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_

View File

@ -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()

View File

@ -773,26 +773,6 @@
>
</File>
</Filter>
<Filter
Name="GCPad"
>
<File
RelativePath=".\Src\HW\GCPad.cpp"
>
</File>
<File
RelativePath=".\Src\HW\GCPad.h"
>
</File>
<File
RelativePath=".\Src\HW\GCPadEmu.cpp"
>
</File>
<File
RelativePath=".\Src\HW\GCPadEmu.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="PowerPC"

View File

@ -105,12 +105,14 @@ void LoadCodes(IniFile &ini, bool forceLoad)
&& !forceLoad)
return;
std::vector<std::string> lines;
std::vector<std::string> encryptedLines;
ARCode currentCode;
arCodes.clear();
std::vector<std::string> lines;
ini["ActionReplay"].GetLines(lines);
if (!ini.GetLines("ActionReplay", lines))
return; // no codes found.
for (std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
{
std::string line = *it;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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<u8>("IPL.AR"));
gameIni.Get("Wii", "Widescreen", &aspectWide, !!SConfig::GetInstance().m_SYSCONF->GetData<u8>("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()

View File

@ -21,6 +21,7 @@
#include "IniFile.h"
#include <string>
#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];

View File

@ -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"

View File

@ -1,100 +0,0 @@
#include <ControllerInterface/ControllerInterface.h>
#include "GCPadEmu.h"
#include <InputConfig.h>
#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<ControllerEmu*>::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<ControllerEmu*>::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();
}
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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; i<nr_players; ++i)
{
SPADStatus PadStatus;
PAD_GetStatus(i, &PadStatus);
CPluginManager::GetInstance().GetPad(0)
->PAD_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);

View File

@ -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<GCPADCommands>(_pBuffer[iPosition ^ 3]);
EBufferCommands command = static_cast<EBufferCommands>(_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)
{

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -19,7 +19,7 @@
#define __FRAME_H
#include "Common.h"
#include "HW/GCPad.h"
#include "pluginspecs_pad.h"
#include <string>

View File

@ -55,13 +55,12 @@ std::vector<std::string> discList;
void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
{
//if (!ini.Exists(section))
//return;
std::vector<std::string> lines;
if (!ini.GetLines(section, lines))
return;
Patch currentPatch;
std::vector<std::string> lines;
ini[section].GetLines(lines);
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string line = *iter;
@ -100,14 +99,15 @@ void LoadPatchSection(const char *section, std::vector<Patch> &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<std::string> &_discList, IniFile &ini) {
std::vector<std::string> lines;
ini[section].GetLines(lines);
if (!ini.GetLines(section, lines))
return;
for (std::vector<std::string>::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<std::string> &_discLis
}
static void LoadSpeedhacks(const char *section, std::map<u32, int> &hacks, IniFile &ini) {
Section& sect = ini[section];
for (Section::const_iterator iter = sect.begin(); iter != sect.end(); ++iter)
std::vector<std::string> keys;
ini.GetKeys(section, keys);
for (std::vector<std::string>::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;

View File

@ -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))

View File

@ -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;

View File

@ -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",

View File

@ -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);

View File

@ -502,6 +502,10 @@
RelativePath=".\Src\DSPAnalyzer.h"
>
</File>
<File
RelativePath=".\Src\DSPBreakpoints.cpp"
>
</File>
<File
RelativePath=".\Src\DSPBreakpoints.h"
>

View File

@ -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"

View File

@ -6,6 +6,7 @@ files = [
"assemble.cpp",
"disassemble.cpp",
"DSPAccelerator.cpp",
"DSPBreakpoints.cpp",
"DSPIntCCUtil.cpp",
"DSPIntExtOps.cpp",
"DSPHWInterface.cpp",

View File

@ -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<std::string> lines;
if (!ini.GetLines("BreakPoints", lines))
{
wxMessageBox(_T("You have no [BreakPoints] line in your file"));
return;
}
std::vector<std::string> lines;
ini["BreakPoints"].GetLines(lines);
for (std::vector<std::string>::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<std::string> lines;
if (!ini.GetLines("MemoryChecks", lines))
{
wxMessageBox(_T("You have no [MemoryChecks] line in your file"));
return;
}
std::vector<std::string> lines;
ini["MemoryChecks"].GetLines(lines);
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string line = StripSpaces(*iter);

View File

@ -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));
}

View File

@ -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<u8> 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()){

View File

@ -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()

View File

@ -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 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
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;_DEBUG;__WXMSW__;__WXDEBUG__;_WINDOWS;NOPCH;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -397,7 +397,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
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;_DEBUG;__WXMSW__;__WXDEBUG__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -510,7 +510,7 @@
Optimization="2"
InlineFunctionExpansion="1"
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="DEBUGFAST;WIN32;__WXMSW__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
@ -626,7 +626,7 @@
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
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="DEBUGFAST;WIN32;__WXMSW__;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"
RuntimeLibrary="0"

View File

@ -113,11 +113,10 @@ bool BootCore(const std::string& _rFilename)
if (unique_id.size() == 6 && game_ini.Load(StartUp.m_strGameIni.c_str()))
{
// General settings
Section& core = game_ini["Core"];
core.Get("CPUThread", &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", "CPUThread", &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)
{

View File

@ -110,6 +110,8 @@ EVT_CHOICE(ID_GRAPHIC_CB, CConfigMain::OnSelectionChanged)
EVT_BUTTON(ID_GRAPHIC_CONFIG, CConfigMain::OnConfig)
EVT_CHOICE(ID_DSP_CB, CConfigMain::OnSelectionChanged)
EVT_BUTTON(ID_DSP_CONFIG, CConfigMain::OnConfig)
EVT_CHOICE(ID_PAD_CB, CConfigMain::OnSelectionChanged)
EVT_BUTTON(ID_PAD_CONFIG, CConfigMain::OnConfig)
EVT_CHOICE(ID_WIIMOTE_CB, CConfigMain::OnSelectionChanged)
EVT_BUTTON(ID_WIIMOTE_CONFIG, CConfigMain::OnConfig)
@ -166,6 +168,7 @@ void CConfigMain::UpdateGUI()
GraphicSelection->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;

View File

@ -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,

View File

@ -45,7 +45,6 @@
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "State.h"
#include "VolumeHandler.h"
#include "HW/GCPad.h"
#include <wx/datetime.h> // 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
}
// --------

View File

@ -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);

View File

@ -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

View File

@ -27,44 +27,42 @@ window handle that is returned by CreateWindow() can be accessed from
Core::GetWindowHandle().
*/
// Common
#include <Common.h>
#include <Setup.h>
#include <FileUtil.h>
#include <FileSearch.h>
#include <Timer.h>
#include <Core.h>
#include <ConfigManager.h>
#include <OnFrame.h>
#include <IPC_HLE/WII_IPC_HLE_Device_usb.h>
#include <HW/CPU.h>
#include <HW/DVDInterface.h>
#include <HW/ProcessorInterface.h>
#include <PowerPC/PowerPC.h>
#include <State.h>
#include <PluginManager.h>
#include <VolumeHandler.h>
#include <NANDContentLoader.h>
#include <WXInputBase.h>
#include <ConfigDiag.h>
#include <wx/datetime.h>
#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 <wx/datetime.h> // 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(

View File

@ -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;

View File

@ -121,7 +121,7 @@ enum
IDM_CONFIG_GFX_PLUGIN,
IDM_CONFIG_DSP_PLUGIN,
IDM_CONFIG_GCPAD,
IDM_CONFIG_PAD_PLUGIN,
IDM_CONFIG_WIIMOTE_PLUGIN,
// --------------------------------------------------------------

View File

@ -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<std::string> lines;
lines.clear();
u32 index = 0;
for (std::vector<PatchEngine::Patch>::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)

View File

@ -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);

View File

@ -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<MAXPADS;k++)
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin[k] =
std::string(padPluginFilename.mb_str());
}
if (selectWiimotePlugin && wiimotePluginFilename != wxEmptyString)
{
int k;
@ -445,6 +465,7 @@ int DolphinApp::OnExit()
{
CPluginManager::Shutdown();
SConfig::Shutdown();
EventHandler::Shutdown();
LogManager::Shutdown();
return wxApp::OnExit();

View File

@ -379,6 +379,7 @@ int main(int argc, char* argv[])
updateMainFrameEvent.Init();
LogManager::Init();
EventHandler::Init();
SConfig::Init();
CPluginManager::Init();
@ -401,6 +402,7 @@ int main(int argc, char* argv[])
CPluginManager::Shutdown();
SConfig::Shutdown();
EventHandler::Shutdown();
LogManager::Shutdown();
cmdline_parser_free (&args_info);

View File

@ -110,11 +110,10 @@ CMemcardManager::CMemcardManager(wxWindow* parent, wxWindowID id, const wxString
memoryCard[SLOT_B]=NULL;
if (MemcardManagerIni.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)))
{
Section& mm = MemcardManagerIni["MemcardManager"];
mm.Get("Items per page", &itemsPerPage, 16);
mm.Get("DefaultMemcardA", &(DefaultMemcard[SLOT_A]), ".");
mm.Get("DefaultMemcardB", &(DefaultMemcard[SLOT_B]), ".");
mm.Get("DefaultIOFolder", &DefaultIOPath, "/Users/GC");
MemcardManagerIni.Get("MemcardManager", "Items per page", &itemsPerPage, 16);
MemcardManagerIni.Get("MemcardManager", "DefaultMemcardA", &(DefaultMemcard[SLOT_A]), ".");
MemcardManagerIni.Get("MemcardManager", "DefaultMemcardB", &(DefaultMemcard[SLOT_B]), ".");
MemcardManagerIni.Get("MemcardManager", "DefaultIOFolder", &DefaultIOPath, "/Users/GC");
}
else itemsPerPage = 16;
maxPages = (128 / itemsPerPage) - 1;
@ -145,12 +144,16 @@ CMemcardManager::~CMemcardManager()
}
#endif
MemcardManagerIni.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
Section& mm = MemcardManagerIni["MemcardManager"];
mm.Set("Items per page", itemsPerPage);
mm.Set("DefaultMemcardA", DefaultMemcard[SLOT_A], ".");
mm.Set("DefaultMemcardB", DefaultMemcard[SLOT_B], ".");
MemcardManagerIni.Set("MemcardManager", "Items per page", itemsPerPage);
if (!DefaultMemcard[SLOT_A].empty() && (strcmp(DefaultMemcard[SLOT_A].c_str(), ".")))
MemcardManagerIni.Set("MemcardManager", "DefaultMemcardA", DefaultMemcard[SLOT_A]);
else
MemcardManagerIni.DeleteKey("MemcardManager", "DefaultMemcardA");
if (!DefaultMemcard[SLOT_B].empty() && (strcmp(DefaultMemcard[SLOT_B].c_str(), ".")))
MemcardManagerIni.Set("MemcardManager", "DefaultMemcardB", DefaultMemcard[SLOT_B]);
else
MemcardManagerIni.DeleteKey("MemcardManager", "DefaultMemcardB");
MemcardManagerIni.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
}
@ -159,16 +162,15 @@ CMemcardManager::CMemcardListCtrl::CMemcardListCtrl(wxWindow* parent, const wxWi
{
if (MemcardManagerIni.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX)))
{
Section& mm = MemcardManagerIni["MemcardManager"];
mm.Get("Use Pages", &usePages, true);
mm.Get("cBanner", &column[COLUMN_BANNER], true);
mm.Get("cTitle", &column[COLUMN_TITLE], true);
mm.Get("cComment", &column[COLUMN_COMMENT], true);
mm.Get("cIcon", &column[COLUMN_ICON], true);
mm.Get("cBlocks", &column[COLUMN_BLOCKS], true);
mm.Get("cFirst Block", &column[COLUMN_FIRSTBLOCK], true);
MemcardManagerIni.Get("MemcardManager", "Use Pages", &usePages, true);
MemcardManagerIni.Get("MemcardManager", "cBanner", &column[COLUMN_BANNER], true);
MemcardManagerIni.Get("MemcardManager", "cTitle", &column[COLUMN_TITLE], true);
MemcardManagerIni.Get("MemcardManager", "cComment", &column[COLUMN_COMMENT], true);
MemcardManagerIni.Get("MemcardManager", "cIcon", &column[COLUMN_ICON], true);
MemcardManagerIni.Get("MemcardManager", "cBlocks", &column[COLUMN_BLOCKS], true);
MemcardManagerIni.Get("MemcardManager", "cFirst Block", &column[COLUMN_FIRSTBLOCK], true);
#ifdef DEBUG_MCM
mm.Get("cDebug", &column[NUMBER_OF_COLUMN], false);
MemcardManagerIni.Get("MemcardManager", "cDebug", &column[NUMBER_OF_COLUMN], false);
#else
column[NUMBER_OF_COLUMN] = false;
#endif
@ -195,17 +197,16 @@ CMemcardManager::CMemcardListCtrl::CMemcardListCtrl(wxWindow* parent, const wxWi
CMemcardManager::CMemcardListCtrl::~CMemcardListCtrl()
{
MemcardManagerIni.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
Section& mm = MemcardManagerIni["MemcardManager"];
mm.Set("Use Pages", usePages);
mm.Set("cBanner", column[COLUMN_BANNER]);
mm.Set("cTitle", column[COLUMN_TITLE]);
mm.Set("cComment", column[COLUMN_COMMENT]);
mm.Set("cIcon", column[COLUMN_ICON]);
mm.Set("cBlocks", column[COLUMN_BLOCKS]);
mm.Set("cFirst Block", column[COLUMN_FIRSTBLOCK]);
MemcardManagerIni.Set("MemcardManager", "Use Pages", usePages);
MemcardManagerIni.Set("MemcardManager", "cBanner", column[COLUMN_BANNER]);
MemcardManagerIni.Set("MemcardManager", "cTitle", column[COLUMN_TITLE]);
MemcardManagerIni.Set("MemcardManager", "cComment", column[COLUMN_COMMENT]);
MemcardManagerIni.Set("MemcardManager", "cIcon", column[COLUMN_ICON]);
MemcardManagerIni.Set("MemcardManager", "cBlocks", column[COLUMN_BLOCKS]);
MemcardManagerIni.Set("MemcardManager", "cFirst Block", column[COLUMN_FIRSTBLOCK]);
#ifdef DEBUG_MCM
mm.Set("cDebug", column[NUMBER_OF_COLUMN]);
MemcardManagerIni.Set("MemcardManager", "cDebug", column[NUMBER_OF_COLUMN]);
#endif
MemcardManagerIni.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
}

View File

@ -212,10 +212,6 @@ bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, Ne
// called from ---CPU--- thread
void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size)
{
// warning removing, like a boss
_number = _channelID;
// _Size = (u32)_pData;
//m_crit.players.Enter(); // lock players
//// in game mapping for this local wiimote
@ -357,8 +353,7 @@ u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
// wiimote update / used for frame counting
void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number)
{
// _number;;
//CritLocker crit(::crit_netplay_ptr);
CritLocker crit(::crit_netplay_ptr);
return;
}

View File

@ -11,7 +11,7 @@
#define _WINSOCK2API_
#include <SFML/Network.hpp>
#include "HW/GCPad.h"
#include "pluginspecs_pad.h"
#include "svnrev.h"
//#include <wx/wx.h>

View File

@ -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']:

View File

@ -45,7 +45,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -110,7 +110,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_SECURE_SCL=0;_LIB;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -175,7 +175,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
@ -244,7 +244,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="false"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
BufferSecurityCheck="false"
@ -306,7 +306,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
@ -368,7 +368,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src"
AdditionalIncludeDirectories="..\..\..\Externals\SDL\include;../../Core/Common/Src;../../PluginSpecs;..\..\..\Externals\wxWidgets\include;..\..\..\Externals\wxWidgets\lib\vc_lib\msw;..\..\..\Externals\wxWidgets\include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_SECURE_SCL=0;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
BufferSecurityCheck="false"
@ -476,52 +476,60 @@
</File>
</Filter>
</Filter>
<Filter
Name="old"
>
<File
RelativePath=".\Src\Configuration.cpp"
>
</File>
<File
RelativePath=".\Src\InputCommon.h"
>
</File>
<File
RelativePath=".\Src\SDL_Util.cpp"
>
</File>
<File
RelativePath=".\Src\SDL_Util.h"
>
</File>
<File
RelativePath=".\Src\XInput_Util.cpp"
>
</File>
<File
RelativePath=".\Src\XInput_Util.h"
>
</File>
</Filter>
<File
RelativePath=".\Src\ControllerEmu.cpp"
RelativePath=".\Src\Configuration.cpp"
>
</File>
<File
RelativePath=".\Src\ControllerEmu.h"
RelativePath=".\Src\DirectInputBase.cpp"
>
</File>
<File
RelativePath=".\Src\InputConfig.cpp"
RelativePath=".\Src\DirectInputBase.h"
>
</File>
<File
RelativePath=".\Src\InputConfig.h"
RelativePath=".\Src\Event.hpp"
>
</File>
<File
RelativePath=".\Src\SConscript"
RelativePath=".\Src\EventHandler.cpp"
>
</File>
<File
RelativePath=".\Src\EventHandler.h"
>
</File>
<File
RelativePath=".\Src\InputCommon.cpp"
>
</File>
<File
RelativePath=".\Src\InputCommon.h"
>
</File>
<File
RelativePath=".\Src\SDL_Util.cpp"
>
</File>
<File
RelativePath=".\Src\SDL_Util.h"
>
</File>
<File
RelativePath=".\Src\WXInputBase.cpp"
>
</File>
<File
RelativePath=".\Src\WXInputBase.h"
>
</File>
<File
RelativePath=".\Src\XInput_Util.cpp"
>
</File>
<File
RelativePath=".\Src\XInput_Util.h"
>
</File>
</Files>

View File

@ -18,10 +18,13 @@
#include <iostream> // System
#include <vector>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cmath>
#include "Common.h" // Common
#if defined HAVE_WX && HAVE_WX
#include <wx/wx.h>
#endif
#ifdef _WIN32
#define NOMINMAX
#include <Windows.h>

View File

@ -2,7 +2,6 @@
#ifdef CIFACE_USE_DIRECTINPUT_KBM
#include <Timer.h>
#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] )

View File

@ -9,6 +9,8 @@
#include <Windows.h>
#include <dinput.h>
#include <wx/stopwatch.h>
#include <wx/utils.h>
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

View File

@ -4,8 +4,6 @@
#include "XInput.h"
#pragma comment(lib, "xinput.lib")
namespace ciface
{
namespace XInput

View File

@ -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);
}

View File

@ -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 <windows.h> // System
#include <stdio.h>
#define DIRECTINPUT_VERSION 0x0800 // DirectInput
#include <dinput.h>
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

View File

@ -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

View File

@ -0,0 +1,318 @@
#include "EventHandler.h"
#include <stdio.h>
#include <ctype.h>
#if defined HAVE_WX && HAVE_WX
#include <wx/wx.h>
#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;

View File

@ -0,0 +1,64 @@
#ifndef EVENTHANDER_H
#define EVENTHANDER_H 1
#include "Common.h"
#include <queue>
#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<sf::Event> 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

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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'

View File

@ -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 <wx/stattext.h>
#include "WXInputBase.h"
//#include <string.h>
//#include <stdio.h>
//#include <ctype.h>
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 <wx/stattext.h>
#include "WXInputBase.h"
//#include <string.h>
//#include <stdio.h>
//#include <ctype.h>
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;
}
}
}

View File

@ -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 <wx/wx.h>
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 <wx/wx.h>
namespace InputCommon
{
const wxChar *WXKeyToString(int keycode);
const wxChar *WXKeymodToString(int modifier);
}
#endif

View File

@ -20,7 +20,7 @@
#include <X11/X.h>
#include <X11/keysym.h>
#include "InputConfig.h"
#include "Config.h"
#if defined(HAVE_WX) && HAVE_WX
#include <wx/wx.h>
#endif

View File

@ -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);
}

View File

@ -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

View File

@ -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 = "<group>"; };
292ABD9C11838FD400B8790B /* CDUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDUtils.cpp; sourceTree = "<group>"; };
292ABD9D11838FD400B8790B /* CDUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDUtils.h; sourceTree = "<group>"; };
292ABD9E11838FD400B8790B /* ChunkFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChunkFile.cpp; sourceTree = "<group>"; };
292ABD9F11838FD400B8790B /* ChunkFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChunkFile.h; sourceTree = "<group>"; };
292ABDA011838FD400B8790B /* ColorUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorUtil.cpp; sourceTree = "<group>"; };
292ABDA111838FD400B8790B /* ColorUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorUtil.h; sourceTree = "<group>"; };
@ -1319,6 +1323,7 @@
292ABDB311838FD400B8790B /* DebugInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugInterface.h; sourceTree = "<group>"; };
292ABDB411838FD400B8790B /* DynamicLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLibrary.cpp; sourceTree = "<group>"; };
292ABDB511838FD400B8790B /* DynamicLibrary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLibrary.h; sourceTree = "<group>"; };
292ABDB611838FD400B8790B /* ExtendedTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendedTrace.cpp; sourceTree = "<group>"; };
292ABDB711838FD400B8790B /* ExtendedTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedTrace.h; sourceTree = "<group>"; };
292ABDB811838FD400B8790B /* FileSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSearch.cpp; sourceTree = "<group>"; };
292ABDB911838FD400B8790B /* FileSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSearch.h; sourceTree = "<group>"; };
@ -1817,6 +1822,7 @@
292ABFCA11838FD600B8790B /* DSPAccelerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPAccelerator.h; sourceTree = "<group>"; };
292ABFCB11838FD600B8790B /* DSPAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPAnalyzer.cpp; sourceTree = "<group>"; };
292ABFCC11838FD600B8790B /* DSPAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPAnalyzer.h; sourceTree = "<group>"; };
292ABFCD11838FD600B8790B /* DSPBreakpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPBreakpoints.cpp; sourceTree = "<group>"; };
292ABFCE11838FD600B8790B /* DSPBreakpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPBreakpoints.h; sourceTree = "<group>"; };
292ABFCF11838FD600B8790B /* DSPCodeUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DSPCodeUtil.cpp; sourceTree = "<group>"; };
292ABFD011838FD600B8790B /* DSPCodeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSPCodeUtil.h; sourceTree = "<group>"; };
@ -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 */,

View File

@ -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

View File

@ -2,7 +2,7 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="InputUICommon"
Name="InputPluginCommon"
ProjectGUID="{660BB3F7-ED8F-4027-A460-8E4EDA8189BE}"
RootNamespace="VideoCommon"
Keyword="Win32Proj"
@ -408,18 +408,14 @@
<References>
</References>
<Files>
<Filter
Name="old"
<File
RelativePath=".\Src\Config.cpp"
>
<File
RelativePath=".\Src\WXInputBase.cpp"
>
</File>
<File
RelativePath=".\Src\WXInputBase.h"
>
</File>
</Filter>
</File>
<File
RelativePath=".\Src\Config.h"
>
</File>
<File
RelativePath=".\Src\ConfigDiag.cpp"
>
@ -433,7 +429,19 @@
>
</File>
<File
RelativePath=".\Src\SConscript"
RelativePath=".\Src\ControllerEmu.cpp"
>
</File>
<File
RelativePath=".\Src\ControllerEmu.h"
>
</File>
<File
RelativePath=".\Src\IniFile.cpp"
>
</File>
<File
RelativePath=".\Src\IniFile.h"
>
</File>
</Files>

View File

@ -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<ControllerEmu*>::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<ControllerEmu*>::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();
}

View File

@ -1,33 +1,36 @@
#pragma once
#include "ControllerInterface/ControllerInterface.h"
#include "Thread.h"
#include "FileUtil.h"
#include "IniFile.h"
#include "ControllerEmu.h"
#include <string>
#include <vector>
#include <map>
#include <sstream>
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 <ControllerInterface/ControllerInterface.h>
#include "Thread.h"
#include "FileUtil.h"
#include "IniFile.h"
#include "ControllerEmu.h"
#include <string>
#include <vector>
#include <map>
#include <sstream>
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

View File

@ -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();
}

View File

@ -22,7 +22,7 @@
#include <vector>
#include <ControllerInterface/ControllerInterface.h>
#include <InputConfig.h>
#include "Config.h"
#include "FileSearch.h"
class PadSetting

View File

@ -1,350 +1,344 @@
#include "ControllerEmu.h"
#if defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h>
#endif
ControllerEmu::~ControllerEmu()
{
// control groups
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
delete *i;
}
ControllerEmu::ControlGroup::~ControlGroup()
{
// controls
std::vector<Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
delete *ci;
// settings
std::vector<Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
delete *si;
}
ControllerEmu::Extension::~Extension()
{
// attachments
std::vector<ControllerEmu*>::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<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
{
std::vector<ControlGroup::Control*>::const_iterator
ci = (*i)->controls.begin(),
ce = (*i)->controls.end();
for ( ; ci!=ce; ++ci )
devi.UpdateReference( (*ci)->control_ref );
// extension
if ( GROUP_TYPE_EXTENSION == (*i)->type )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->UpdateReferences( devi );
}
}
}
void ControllerEmu::UpdateDefaultDevice()
{
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
{
std::vector<ControlGroup::Control*>::const_iterator
ci = (*i)->controls.begin(),
ce = (*i)->controls.end();
for ( ; ci!=ce; ++ci )
(*ci)->control_ref->device_qualifier = default_device;
// extension
if ( GROUP_TYPE_EXTENSION == (*i)->type )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
{
(*ai)->default_device = default_device;
(*ai)->UpdateDefaultDevice();
}
}
}
}
void ControllerEmu::ControlGroup::LoadConfig( Section& sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
#include "ControllerEmu.h"
#if defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h>
#endif
ControllerEmu::~ControllerEmu()
{
// control groups
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
delete *i;
}
ControllerEmu::ControlGroup::~ControlGroup()
{
// controls
std::vector<Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
delete *ci;
// settings
std::vector<Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
delete *si;
}
ControllerEmu::Extension::~Extension()
{
// attachments
std::vector<ControllerEmu*>::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<ControlGroup*>::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<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
{
// control and dev qualifier
(*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name];
std::string tmpdevstr;
sec.Get( group+(*ci)->name+"/Device", &tmpdevstr, defdev );
(*ci)->control_ref->device_qualifier.FromString(tmpdevstr);
std::vector<ControlGroup::Control*>::const_iterator
ci = (*i)->controls.begin(),
ce = (*i)->controls.end();
for ( ; ci!=ce; ++ci )
devi.UpdateReference( (*ci)->control_ref );
// extension
if ( GROUP_TYPE_EXTENSION == (*i)->type )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->UpdateReferences( devi );
}
}
}
void ControllerEmu::UpdateDefaultDevice()
{
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
{
std::vector<ControlGroup::Control*>::const_iterator
ci = (*i)->controls.begin(),
ce = (*i)->controls.end();
for ( ; ci!=ce; ++ci )
(*ci)->control_ref->device_qualifier = default_device;
// extension
if ( GROUP_TYPE_EXTENSION == (*i)->type )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
{
(*ai)->default_device = default_device;
(*ai)->UpdateDefaultDevice();
}
}
}
}
void ControllerEmu::ControlGroup::LoadConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
(*si)->value = sec.Get(group+(*si)->name, (*si)->default_value*100) / 100;
// controls
std::vector<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
{
// control and dev qualifier
(*ci)->control_ref->control_qualifier.name = sec[group + (*ci)->name];
(*ci)->control_ref->device_qualifier.FromString( sec.Get( group+(*ci)->name+"/Device", defdev ) );
// range
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<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai,++n )
{
(*ai)->default_device.FromString( defdev );
(*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" );
if ( (*ai)->GetName() == extname )
ex->switch_extension = n;
}
}
}
void ControllerEmu::LoadConfig( Section& sec, const std::string& base )
{
std::string defdev = default_device.ToString();
if ( base.empty() )
{
defdev = sec[ base + "Device" ];
default_device.FromString( defdev );
}
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->LoadConfig( sec, defdev, base );
}
void ControllerEmu::ControlGroup::SaveConfig( Section& sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 );
// controls
std::vector<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
{
// control and dev qualifier
sec.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<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" );
}
}
void ControllerEmu::SaveConfig( 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<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->SaveConfig( sec, defdev, base );
}
ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK )
{
for ( unsigned int i = 0; i < 4; ++i )
controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 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<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai,++n )
{
(*ai)->default_device.FromString( defdev );
(*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" );
if ( (*ai)->GetName() == extname )
ex->switch_extension = n;
}
}
}
void ControllerEmu::LoadConfig( IniFile::Section& sec, const std::string& base )
{
std::string defdev = default_device.ToString();
if ( base.empty() )
{
defdev = sec[ base + "Device" ];
default_device.FromString( defdev );
}
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->LoadConfig( sec, defdev, base );
}
void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section& sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
sec.Set( group+(*si)->name, (*si)->value*100, (*si)->default_value*100 );
// controls
std::vector<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
{
// control and dev qualifier
sec.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<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" );
}
}
void ControllerEmu::SaveConfig( IniFile::Section& sec, const std::string& base )
{
const std::string defdev = default_device.ToString();
if ( base.empty() )
sec.Set( std::string(" ") + base + "Device", defdev );
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->SaveConfig( sec, defdev, base );
}
ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK )
{
for ( unsigned int i = 0; i < 4; ++i )
controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 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
}

View File

@ -1,392 +1,398 @@
#pragma once
// windows crap
#define NOMINMAX
#include "../../../PluginSpecs/pluginspecs_wiimote.h"
#include <math.h>
#include "ControllerInterface/ControllerInterface.h"
#include "IniFile.h"
#include <vector>
#include <string>
#include <algorithm>
#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 <typename C>
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 <typename C>
void GetState( C* const buttons, const C* bitmasks )
{
std::vector<Control*>::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 <typename C, typename S>
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; i<trig_count; ++i,++bitmasks,++analog )
{
if ( controls[i]->control_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 <typename S>
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; i<trig_count; ++i,++analog )
*analog = S( std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range );
}
Triggers( const char* const _name );
};
class Force : public ControlGroup
{
public:
Force( const char* const _name );
template <typename C, typename R>
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 <typename C, typename R>
void GetState( C* const x, C* const y, const unsigned int base, const R range )
{
// this is all a mess
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState deadzone = settings[0]->value;
ControlState circle = settings[1]->value;
ControlState m = controls[4]->control_ref->State();
// modifier code
if ( m )
{
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
}
// deadzone / circle stick code
if ( deadzone || circle )
{
// this section might be all wrong, but its working good enough, i think
ControlState ang = atan2( yy, xx );
ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang);
// the amt a full square stick would have at current angle
ControlState square_full = std::min( 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 <typename C>
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<ControllerEmu*> 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 <CommonTypes.h>
#include <math.h>
#include <ControllerInterface/ControllerInterface.h>
#include "IniFile.h"
#include <vector>
#include <string>
#include <algorithm>
#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 <typename C>
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 <typename C>
void GetState( C* const buttons, const C* bitmasks )
{
std::vector<Control*>::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 <typename C, typename S>
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; i<trig_count; ++i,++bitmasks,++analog )
{
if ( controls[i]->control_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 <typename S>
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; i<trig_count; ++i,++analog )
*analog = S( std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range );
}
Triggers( const char* const _name );
};
class Force : public ControlGroup
{
public:
Force( const char* const _name );
template <typename C, typename R>
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 <typename C, typename R>
void GetState( C* const x, C* const y, const unsigned int base, const R range )
{
// this is all a mess
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState deadzone = settings[0]->value;
ControlState circle = settings[1]->value;
ControlState m = controls[4]->control_ref->State();
// modifier code
if ( m )
{
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
}
// deadzone / circle stick code
if ( deadzone || circle )
{
// this section might be all wrong, but its working good enough, i think
ControlState ang = atan2( yy, xx );
ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang);
// the amt a full square stick would have at current angle
ControlState square_full = std::min( 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 <typename C>
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<ControllerEmu*> 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

View File

@ -0,0 +1,156 @@
#include "IniFile.h"
//
// TrimChars
//
// trim whitespace, or any, chars from both ends
//
template <typename S>
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;
}
}

View File

@ -0,0 +1,61 @@
#ifndef _INIFILE_H_
#define _INIFILE_H_
#include <fstream>
#include <map>
#include <string>
#include <sstream>
//
// 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 <typename V, typename D>
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 <typename V>
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

View File

@ -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)

View File

@ -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)

View File

@ -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());

View File

@ -0,0 +1,559 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="Plugin_GCPad"
ProjectGUID="{9FF603F8-B3BB-4144-9688-B2B802FA0F16}"
RootNamespace="Plugin_nJoy_SDL"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib rpcrt4.lib xinput.lib winmm.lib wxbase28ud.lib wxmsw28ud_core.lib"
OutputFile="..\..\..\Binary\Win32\Plugins\$(ProjectName)D.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib xinput.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib"
OutputFile="..\..\..\Binary\Win32\Plugins\$(ProjectName).dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;DEBUGFAST;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib rpcrt4.lib xinput.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib"
OutputFile="..\..\..\Binary\Win32\Plugins\$(ProjectName)DF.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib rpcrt4.lib xinput.lib winmm.lib wxbase28ud.lib wxmsw28ud_core.lib"
OutputFile="..\..\..\Binary\x64\Plugins\$(ProjectName)D.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib xinput.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib"
OutputFile="..\..\..\Binary\x64\Plugins\$(ProjectName).dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugFast|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\PluginSpecs;..\..\..\Externals\SDL\Include;..\..\Core\Common\Src;..\..\..\Externals\wxWidgets\Include;..\..\..\Externals\wxWidgets\Include\msvc"
PreprocessorDefinitions="WIN32;NDEBUG;DEBUGFAST;_WINDOWS;_USRDLL;PLUGIN_NJOY_SDL_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SDL.lib comctl32.lib rpcrt4.lib xinput.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib"
OutputFile="..\..\..\Binary\x64\Plugins\$(ProjectName)DF.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(PlatformName)\$(ConfigurationName)\$(TargetName).lib"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Config"
>
<File
RelativePath=".\Src\Config.cpp"
>
</File>
<File
RelativePath=".\Src\Config.h"
>
</File>
<File
RelativePath=".\Src\ConfigBox.cpp"
>
</File>
<File
RelativePath=".\Src\ConfigBox.h"
>
</File>
<File
RelativePath=".\Src\ConfigJoypad.cpp"
>
</File>
</Filter>
<File
RelativePath=".\Src\GCPad.cpp"
>
</File>
<File
RelativePath=".\Src\GCPad.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_pad.h"
>
</File>
<File
RelativePath=".\Src\ReRecording.cpp"
>
</File>
<File
RelativePath=".\Src\Rumble.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -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 <iostream>
#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]);
}
}

View File

@ -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

View File

@ -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 <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#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("<Press Key>"));
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("<Move Axis>"));
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("<No Gamepad Detected>"));
}
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;
}

View File

@ -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 <wx/wx.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/stattext.h>
#include <wx/combobox.h>
#include <wx/checkbox.h>
#include <wx/notebook.h>
#include <wx/panel.h>
#include <wx/gbsizer.h>
#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__

View File

@ -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));
}

View File

@ -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<InputCommon::CONTROLLER_INFO> 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<InputCommon::CONTROLLER_INFO> &_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();
}

View File

@ -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 <vector> // System
#include <cstdio>
#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 <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#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<InputCommon::CONTROLLER_INFO> 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<InputCommon::CONTROLLER_INFO> &_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

View File

@ -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

View File

@ -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 <dinput.h>
#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

View File

@ -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)

Some files were not shown because too many files have changed in this diff Show More