mirror of https://github.com/PCSX2/pcsx2.git
Database Loader code cleanups: added proper use of "const string&" to the class APIs (improves compiler code generation, protects against unwanted or unexpected modification of parameter contents). As a result, fixed a potential bug in toLower; it was modifying the input string.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3101 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6ec36fa37d
commit
6282570b9c
|
@ -1,423 +1,421 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
* PCSX2 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
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "File_Reader.h"
|
#include "File_Reader.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
|
|
||||||
struct key_pair {
|
struct key_pair {
|
||||||
string key;
|
string key;
|
||||||
string value;
|
string value;
|
||||||
key_pair(string _key, string _value)
|
|
||||||
: key(_key) , value(_value) {}
|
key_pair() {}
|
||||||
string toString() {
|
key_pair(const string& _key, const string& _value)
|
||||||
|
: key(_key) , value(_value) {}
|
||||||
|
string toString() {
|
||||||
string t;
|
string t;
|
||||||
|
|
||||||
if (key[0] == '[') {
|
if (key[0] == '[') {
|
||||||
t = key + "\n";
|
t = key + "\n";
|
||||||
t += value;
|
t += value;
|
||||||
|
|
||||||
stringstream ss(key);
|
stringstream ss(key);
|
||||||
string t2;
|
string t2;
|
||||||
ss >> t2;
|
ss >> t2;
|
||||||
t += "[/" + t2.substr(1, t2.length()-1);
|
t += "[/" + t2.substr(1, t2.length()-1);
|
||||||
if (t2.compare(t)) t += "]";
|
if (t2.compare(t)) t += "]";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
t = key;
|
t = key;
|
||||||
for (int a = 6 - key.length(); a > 0; a--) {
|
for (int a = 6 - key.length(); a > 0; a--) {
|
||||||
t += " "; // Padding for nice formatting on small key-names
|
t += " "; // Padding for nice formatting on small key-names
|
||||||
}
|
}
|
||||||
t += " = " + value;
|
t += " = " + value;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Game_Data {
|
class Game_Data {
|
||||||
public:
|
public:
|
||||||
string id; // Serial Identification Code
|
string id; // Serial Identification Code
|
||||||
deque<key_pair> kList; // List of all (key, value) pairs for game data
|
deque<key_pair> kList; // List of all (key, value) pairs for game data
|
||||||
Game_Data(string _id)
|
Game_Data(const string& _id)
|
||||||
: id(_id) {}
|
: id(_id) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DataBase_Loader:
|
// DataBase_Loader:
|
||||||
// Give the starting Key and Value you're looking for,
|
// Give the starting Key and Value you're looking for,
|
||||||
// and it will extract the necessary data from the database.
|
// and it will extract the necessary data from the database.
|
||||||
// Example:
|
// Example:
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
// Serial = SLUS-20486
|
// Serial = SLUS-20486
|
||||||
// Name = Marvel vs. Capcom 2
|
// Name = Marvel vs. Capcom 2
|
||||||
// Region = NTSC-U
|
// Region = NTSC-U
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
// To Load this game data, use "Serial" as the initial Key
|
// To Load this game data, use "Serial" as the initial Key
|
||||||
// then specify "SLUS-20486" as the value in the constructor.
|
// then specify "SLUS-20486" as the value in the constructor.
|
||||||
// After the constructor loads the game data, you can use the
|
// After the constructor loads the game data, you can use the
|
||||||
// DataBase_Loader class's methods to get the other key's values.
|
// DataBase_Loader class's methods to get the other key's values.
|
||||||
// Such as dbLoader.getString("Region") returns "NTSC-U"
|
// Such as dbLoader.getString("Region") returns "NTSC-U"
|
||||||
|
|
||||||
class DataBase_Loader {
|
class DataBase_Loader {
|
||||||
private:
|
private:
|
||||||
template<class T> string toString(T value) {
|
template<class T> string toString(T value) {
|
||||||
stringstream ss(ios_base::in | ios_base::out);
|
stringstream ss(ios_base::in | ios_base::out);
|
||||||
string tString;
|
string tString;
|
||||||
ss << value;
|
ss << value;
|
||||||
ss >> tString;
|
ss >> tString;
|
||||||
return tString;
|
return tString;
|
||||||
}
|
}
|
||||||
string toLower(string s) {
|
string toLower(const string& s) {
|
||||||
for (uint i = 0; i < s.length(); i++) {
|
string retval( s );
|
||||||
char& c = s[i];
|
for (uint i = 0; i < s.length(); i++) {
|
||||||
if (c >= 'A' && c <= 'Z') {
|
char& c = retval[i];
|
||||||
c += 'a' - 'A';
|
if (c >= 'A' && c <= 'Z') {
|
||||||
}
|
c += 'a' - 'A';
|
||||||
}
|
}
|
||||||
return s;
|
}
|
||||||
}
|
return retval;
|
||||||
bool strCompare(string& s1, string& s2) {
|
}
|
||||||
string t1 = toLower(s1);
|
bool strCompare(const string& s1, const string& s2) {
|
||||||
string t2 = toLower(s2);
|
const string t1( toLower(s1) );
|
||||||
return !t1.compare(t2);
|
const string t2( toLower(s2) );
|
||||||
}
|
return !t1.compare(t2);
|
||||||
bool isComment(string& s) {
|
}
|
||||||
string sub = s.substr(0, 2);
|
bool isComment(const string& s) {
|
||||||
return (sub.compare("--") == 0) || (sub.compare("//") == 0);
|
const string sub( s.substr(0, 2) );
|
||||||
}
|
return (sub.compare("--") == 0) || (sub.compare("//") == 0);
|
||||||
void doError(string& line, key_pair& keyPair, bool doMsg = false) {
|
}
|
||||||
if (doMsg) Console.Error("DataBase_Loader: Bad file data [%s]", line.c_str());
|
void doError(const string& line, key_pair& keyPair, bool doMsg = false) {
|
||||||
keyPair.key = "";
|
if (doMsg) Console.Error("DataBase_Loader: Bad file data [%s]", line.c_str());
|
||||||
}
|
keyPair.key.clear();
|
||||||
void extractMultiLine(string& line, key_pair& keyPair, File_Reader& reader, stringstream& ss) {
|
}
|
||||||
string t = "";
|
void extractMultiLine(const string& line, key_pair& keyPair, File_Reader& reader, const stringstream& ss) {
|
||||||
string endString;
|
string t;
|
||||||
endString = "[/" + keyPair.key.substr(1, keyPair.key.length()-1);
|
string endString;
|
||||||
if (keyPair.key[keyPair.key.length()-1] != ']') {
|
endString = "[/" + keyPair.key.substr(1, keyPair.key.length()-1);
|
||||||
endString += "]";
|
if (keyPair.key[keyPair.key.length()-1] != ']') {
|
||||||
keyPair.key = line;
|
endString += "]";
|
||||||
}
|
keyPair.key = line;
|
||||||
for(;;) {
|
}
|
||||||
|
for(;;) {
|
||||||
t = reader.getLine();
|
t = reader.getLine();
|
||||||
|
|
||||||
if (!t.compare(endString)) break;
|
if (!t.compare(endString)) break;
|
||||||
keyPair.value += t + "\n";
|
keyPair.value += t + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void extract(string& line, key_pair& keyPair, File_Reader& reader) {
|
void extract(const string& line, key_pair& keyPair, File_Reader& reader) {
|
||||||
stringstream ss(line);
|
stringstream ss(line);
|
||||||
string t;
|
string t;
|
||||||
keyPair.key = "";
|
keyPair.key.clear();
|
||||||
keyPair.value = "";
|
keyPair.value.clear();
|
||||||
ss >> keyPair.key;
|
ss >> keyPair.key;
|
||||||
if (!line.length() || isComment(keyPair.key)) {
|
if (!line.length() || isComment(keyPair.key)) {
|
||||||
doError(line, keyPair);
|
doError(line, keyPair);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (keyPair.key[0] == '[') {
|
if (keyPair.key[0] == '[') {
|
||||||
extractMultiLine(line, keyPair, reader, ss);
|
extractMultiLine(line, keyPair, reader, ss);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ss >> t;
|
ss >> t;
|
||||||
if (t.compare("=") != 0) {
|
if (t.compare("=") != 0) {
|
||||||
doError(line, keyPair, true);
|
doError(line, keyPair, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ss >> t;
|
ss >> t;
|
||||||
if (isComment(t)) {
|
if (isComment(t)) {
|
||||||
doError(line, keyPair, true);
|
doError(line, keyPair, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keyPair.value = t;
|
keyPair.value = t;
|
||||||
while (!ss.eof() && !ss.fail()) {
|
while (!ss.eof() && !ss.fail()) {
|
||||||
ss >> t;
|
ss >> t;
|
||||||
if (isComment(t)) break;
|
if (isComment(t)) break;
|
||||||
keyPair.value += " " + t;
|
keyPair.value += " " + t;
|
||||||
}
|
}
|
||||||
if (ss.fail()) {
|
if (ss.fail()) {
|
||||||
doError(line, keyPair);
|
doError(line, keyPair);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
deque<Game_Data*> gList; // List of all game data
|
deque<Game_Data*> gList; // List of all game data
|
||||||
Game_Data* curGame; // Current game data
|
Game_Data* curGame; // Current game data
|
||||||
String_Stream header; // Header of the database
|
String_Stream header; // Header of the database
|
||||||
string baseKey; // Key to separate games by ("Serial")
|
string baseKey; // Key to separate games by ("Serial")
|
||||||
|
|
||||||
DataBase_Loader(string file, string key = "Serial", string value = "") {
|
DataBase_Loader(const string& file, const string& key = "Serial", const string& value = "" ) {
|
||||||
curGame = NULL;
|
curGame = NULL;
|
||||||
baseKey = key;
|
baseKey = key;
|
||||||
if (!fileExists(file)) {
|
if (!fileExists(file)) {
|
||||||
Console.Error("DataBase_Loader: DataBase Not Found! [%s]", file.c_str());
|
Console.Error("DataBase_Loader: DataBase Not Found! [%s]", file.c_str());
|
||||||
}
|
}
|
||||||
File_Reader reader(file);
|
File_Reader reader(file);
|
||||||
key_pair keyPair("", "");
|
key_pair keyPair;
|
||||||
string s0;
|
string s0;
|
||||||
Game_Data* game = NULL;
|
Game_Data* game = NULL;
|
||||||
try {
|
try {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
for(;;) { // Find first game
|
for(;;) { // Find first game
|
||||||
s0 = reader.getLine();
|
s0 = reader.getLine();
|
||||||
extract(s0, keyPair, reader);
|
extract(s0, keyPair, reader);
|
||||||
if (keyPair.key.compare(key) == 0) break;
|
if (keyPair.key.compare(key) == 0) break;
|
||||||
header.write(s0);
|
header.write(s0);
|
||||||
header.write("\n");
|
header.write("\n");
|
||||||
}
|
}
|
||||||
game = new Game_Data(keyPair.value);
|
game = new Game_Data(keyPair.value);
|
||||||
game->kList.push_back(keyPair);
|
game->kList.push_back(keyPair);
|
||||||
for (;;) { // Fill game data, find new game, repeat...
|
for (;;) { // Fill game data, find new game, repeat...
|
||||||
s0 = reader.getLine();
|
s0 = reader.getLine();
|
||||||
extract(s0, keyPair, reader);
|
extract(s0, keyPair, reader);
|
||||||
if (keyPair.key.compare("") == 0) continue;
|
if (keyPair.key.compare("") == 0) continue;
|
||||||
if (keyPair.key.compare(key) == 0) {
|
if (keyPair.key.compare(key) == 0) {
|
||||||
gList.push_back(game);
|
gList.push_back(game);
|
||||||
game = new Game_Data(keyPair.value);
|
game = new Game_Data(keyPair.value);
|
||||||
}
|
}
|
||||||
game->kList.push_back(keyPair);
|
game->kList.push_back(keyPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(int& i) { // Add Last Game if EOF
|
catch(int& i) { // Add Last Game if EOF
|
||||||
if (i==1 && game) gList.push_back(game);
|
if (i==1 && game) gList.push_back(game);
|
||||||
}
|
}
|
||||||
if (!value.compare("")) return;
|
if (!value.compare("")) return;
|
||||||
if (setGame(value)) Console.WriteLn("DataBase_Loader: Found Game! [%s]", value.c_str());
|
if (setGame(value)) Console.WriteLn("DataBase_Loader: Found Game! [%s]", value.c_str());
|
||||||
else Console.Warning("DataBase_Loader: Game Not Found! [%s]", value.c_str());
|
else Console.Warning("DataBase_Loader: Game Not Found! [%s]", value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
~DataBase_Loader() {
|
virtual ~DataBase_Loader() throw() {
|
||||||
deque<Game_Data*>::iterator it = gList.begin();
|
deque<Game_Data*>::iterator it = gList.begin();
|
||||||
for ( ; it != gList.end(); ++it) {
|
for ( ; it != gList.end(); ++it) {
|
||||||
delete it[0];
|
delete *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the current game to the one matching the serial id given
|
// Sets the current game to the one matching the serial id given
|
||||||
// Returns true if game found, false if not found...
|
// Returns true if game found, false if not found...
|
||||||
bool setGame(string id) {
|
bool setGame(const string& id) {
|
||||||
deque<Game_Data*>::iterator it = gList.begin();
|
deque<Game_Data*>::iterator it = gList.begin();
|
||||||
for ( ; it != gList.end(); ++it) {
|
for ( ; it != gList.end(); ++it) {
|
||||||
if (strCompare(it[0]->id, id)) {
|
if (strCompare(it[0]->id, id)) {
|
||||||
curGame = it[0];
|
curGame = it[0];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curGame = NULL;
|
curGame = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if a game is currently loaded into the database
|
// Returns true if a game is currently loaded into the database
|
||||||
// Returns false if otherwise (this means you need to call setGame()
|
// Returns false if otherwise (this means you need to call setGame()
|
||||||
// or it could mean the game was not found in the database at all...)
|
// or it could mean the game was not found in the database at all...)
|
||||||
bool gameLoaded() {
|
bool gameLoaded() {
|
||||||
return !!curGame;
|
return !!curGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saves changes to the database
|
// Saves changes to the database
|
||||||
void saveToFile(string file = "DataBase.dbf") {
|
void saveToFile(const string& file = "DataBase.dbf") {
|
||||||
File_Writer writer(file);
|
File_Writer writer(file);
|
||||||
writer.write(header.toString());
|
writer.write(header.toString());
|
||||||
deque<Game_Data*>::iterator it = gList.begin();
|
deque<Game_Data*>::iterator it = gList.begin();
|
||||||
for ( ; it != gList.end(); ++it) {
|
for ( ; it != gList.end(); ++it) {
|
||||||
deque<key_pair>::iterator i = it[0]->kList.begin();
|
deque<key_pair>::iterator i = it[0]->kList.begin();
|
||||||
for ( ; i != it[0]->kList.end(); ++i) {
|
for ( ; i != it[0]->kList.end(); ++i) {
|
||||||
writer.write(i[0].toString() + "\n");
|
writer.write(i[0].toString() + "\n");
|
||||||
}
|
}
|
||||||
writer.write("---------------------------------------------\n");
|
writer.write("---------------------------------------------\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds new game data to the database, and sets curGame to the new game...
|
// Adds new game data to the database, and sets curGame to the new game...
|
||||||
// If searchDB is true, it searches the database to see if game already exists.
|
// If searchDB is true, it searches the database to see if game already exists.
|
||||||
void addGame(string id, bool searchDB = true) {
|
void addGame(const string& id, bool searchDB = true) {
|
||||||
if (searchDB && setGame(id)) return;
|
if (searchDB && setGame(id)) return;
|
||||||
Game_Data* game = new Game_Data(id);
|
Game_Data* game = new Game_Data(id);
|
||||||
key_pair kp(baseKey, id);
|
key_pair kp(baseKey, id);
|
||||||
game->kList.push_back(kp);
|
game->kList.push_back(kp);
|
||||||
gList.push_back(game);
|
gList.push_back(game);
|
||||||
curGame = game;
|
curGame = game;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Searches the current game's data to see if the given key exists
|
// Searches the current game's data to see if the given key exists
|
||||||
bool keyExists(string key) {
|
bool keyExists(const string& key) {
|
||||||
if (curGame) {
|
if (curGame) {
|
||||||
deque<key_pair>::iterator it = curGame->kList.begin();
|
deque<key_pair>::iterator it = curGame->kList.begin();
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
for ( ; it != curGame->kList.end(); ++it) {
|
||||||
if (strCompare(it[0].key, key)) {
|
if (strCompare(it[0].key, key)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("DataBase_Loader: Game not set!");
|
else Console.Error("DataBase_Loader: Game not set!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a string representation of the 'value' for the given key
|
// Gets a string representation of the 'value' for the given key
|
||||||
string getString(string key) {
|
string getString(const string& key) {
|
||||||
if (curGame) {
|
if (curGame) {
|
||||||
deque<key_pair>::iterator it = curGame->kList.begin();
|
deque<key_pair>::iterator it = curGame->kList.begin();
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
for ( ; it != curGame->kList.end(); ++it) {
|
||||||
if (strCompare(it[0].key, key)) {
|
if (strCompare(it[0].key, key)) {
|
||||||
return it[0].value;
|
return it[0].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("DataBase_Loader: Game not set!");
|
else Console.Error("DataBase_Loader: Game not set!");
|
||||||
return string("");
|
return string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a wxString representation of the 'value' for the given key
|
// Gets a wxString representation of the 'value' for the given key
|
||||||
wxString getStringWX(string key) {
|
wxString getStringWX(const string& key) {
|
||||||
string s = getString(key);
|
return wxString(fromUTF8(getString(key).c_str()));
|
||||||
return wxString(fromUTF8(s.c_str()));
|
}
|
||||||
}
|
|
||||||
|
// Gets a double representation of the 'value' for the given key
|
||||||
// Gets a double representation of the 'value' for the given key
|
double getDouble(const string& key) {
|
||||||
double getDouble(string key) {
|
return atof(getString(key).c_str());
|
||||||
string v = getString(key);
|
}
|
||||||
return atof(v.c_str());
|
|
||||||
}
|
// Gets a float representation of the 'value' for the given key
|
||||||
|
float getFloat(const string& key) {
|
||||||
// Gets a float representation of the 'value' for the given key
|
return (float)atof(getString(key).c_str());
|
||||||
float getFloat(string key) {
|
}
|
||||||
string v = getString(key);
|
|
||||||
return (float)atof(v.c_str());
|
// Gets an integer representation of the 'value' for the given key
|
||||||
}
|
int getInt(const string& key) {
|
||||||
|
return strtoul(getString(key).c_str(), NULL, 0);
|
||||||
// Gets an integer representation of the 'value' for the given key
|
}
|
||||||
int getInt(string key) {
|
|
||||||
string v = getString(key);
|
// Gets a u8 representation of the 'value' for the given key
|
||||||
return strtoul(v.c_str(), NULL, 0);
|
u8 getU8(const string& key) {
|
||||||
}
|
return (u8)atoi(getString(key).c_str());
|
||||||
|
}
|
||||||
// Gets a u8 representation of the 'value' for the given key
|
|
||||||
u8 getU8(string key) {
|
// Gets a bool representation of the 'value' for the given key
|
||||||
string v = getString(key);
|
bool getBool(const string& key) {
|
||||||
return (u8)atoi(v.c_str());
|
return !!atoi(getString(key).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a bool representation of the 'value' for the given key
|
// Write a string value to the specified key
|
||||||
bool getBool(string key) {
|
void writeString(const string& key, const string& value) {
|
||||||
string v = getString(key);
|
if (curGame) {
|
||||||
return !!atoi(v.c_str());
|
deque<key_pair>::iterator it = curGame->kList.begin();
|
||||||
}
|
for ( ; it != curGame->kList.end(); ++it) {
|
||||||
|
if (strCompare(it[0].key, key)) {
|
||||||
// Write a string value to the specified key
|
it[0].value = value;
|
||||||
void writeString(string key, string value) {
|
return;
|
||||||
if (curGame) {
|
}
|
||||||
deque<key_pair>::iterator it = curGame->kList.begin();
|
}
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
key_pair tKey(key, value);
|
||||||
if (strCompare(it[0].key, key)) {
|
curGame->kList.push_back(tKey);
|
||||||
it[0].value = value;
|
}
|
||||||
return;
|
else Console.Error("DataBase_Loader: Game not set!");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
key_pair tKey(key, value);
|
// Write a wxString value to the specified key
|
||||||
curGame->kList.push_back(tKey);
|
void writeStringWX(const string& key, const wxString& value) {
|
||||||
}
|
writeString(key, value.ToUTF8().data());
|
||||||
else Console.Error("DataBase_Loader: Game not set!");
|
}
|
||||||
}
|
|
||||||
|
// Write a double value to the specified key
|
||||||
// Write a wxString value to the specified key
|
void writeDouble(const string& key, double value) {
|
||||||
void writeStringWX(string key, wxString value) {
|
writeString(key, toString(value));
|
||||||
writeString(key, string(value.ToUTF8().data()));
|
}
|
||||||
}
|
|
||||||
|
// Write a float value to the specified key
|
||||||
// Write a double value to the specified key
|
void writeFloat(const string& key, float value) {
|
||||||
void writeDouble(string key, double value) {
|
writeString(key, toString(value));
|
||||||
writeString(key, toString(value));
|
}
|
||||||
}
|
|
||||||
|
// Write an integer value to the specified key
|
||||||
// Write a float value to the specified key
|
void writeInt(const string& key, int value) {
|
||||||
void writeFloat(string key, float value) {
|
writeString(key, toString(value));
|
||||||
writeString(key, toString(value));
|
}
|
||||||
}
|
|
||||||
|
// Write a u8 value to the specified key
|
||||||
// Write an integer value to the specified key
|
void writeU8(const string& key, u8 value) {
|
||||||
void writeInt(string key, int value) {
|
writeString(key, toString(value));
|
||||||
writeString(key, toString(value));
|
}
|
||||||
}
|
|
||||||
|
// Write a bool value to the specified key
|
||||||
// Write a u8 value to the specified key
|
void writeBool(const string& key, bool value) {
|
||||||
void writeU8(string key, u8 value) {
|
writeString(key, toString(value?1:0));
|
||||||
writeString(key, toString(value));
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Write a bool value to the specified key
|
static wxString compatToStringWX(int compat) {
|
||||||
void writeBool(string key, bool value) {
|
switch (compat) {
|
||||||
writeString(key, toString(value?1:0));
|
case 6: return wxString(L"Perfect");
|
||||||
}
|
case 5: return wxString(L"Playable");
|
||||||
};
|
case 4: return wxString(L"In-Game");
|
||||||
|
case 3: return wxString(L"Menu");
|
||||||
static wxString compatToStringWX(int compat) {
|
case 2: return wxString(L"Intro");
|
||||||
switch (compat) {
|
case 1: return wxString(L"Nothing");
|
||||||
case 6: return wxString(L"Perfect");
|
default: return wxString(L"Unknown");
|
||||||
case 5: return wxString(L"Playable");
|
}
|
||||||
case 4: return wxString(L"In-Game");
|
}
|
||||||
case 3: return wxString(L"Menu");
|
|
||||||
case 2: return wxString(L"Intro");
|
#define checkGamefix(gFix) { \
|
||||||
case 1: return wxString(L"Nothing");
|
if (gameDB->keyExists(#gFix)) { \
|
||||||
default: return wxString(L"Unknown");
|
SetGameFixConfig().gFix = gameDB->getBool(#gFix); \
|
||||||
}
|
Console.WriteLn("Loading Gamefix: " #gFix); \
|
||||||
}
|
} \
|
||||||
|
}
|
||||||
#define checkGamefix(gFix) { \
|
|
||||||
if (gameDB->keyExists(#gFix)) { \
|
// Load Game Settings found in database
|
||||||
SetGameFixConfig().gFix = gameDB->getBool(#gFix); \
|
// (game fixes, round modes, clamp modes, etc...)
|
||||||
Console.WriteLn("Loading Gamefix: " #gFix); \
|
static void loadGameSettings(DataBase_Loader* gameDB) {
|
||||||
} \
|
if (gameDB && gameDB->gameLoaded()) {
|
||||||
}
|
SSE_MXCSR eeMX = EmuConfig.Cpu.sseMXCSR;
|
||||||
|
SSE_MXCSR vuMX = EmuConfig.Cpu.sseVUMXCSR;
|
||||||
// Load Game Settings found in database
|
int eeRM = eeMX.GetRoundMode();
|
||||||
// (game fixes, round modes, clamp modes, etc...)
|
int vuRM = vuMX.GetRoundMode();
|
||||||
static void loadGameSettings(DataBase_Loader* gameDB) {
|
bool rm = 0;
|
||||||
if (gameDB && gameDB->gameLoaded()) {
|
if (gameDB->keyExists("eeRoundMode")) { eeRM = gameDB->getInt("eeRoundMode"); rm=1; }
|
||||||
SSE_MXCSR eeMX = EmuConfig.Cpu.sseMXCSR;
|
if (gameDB->keyExists("vuRoundMode")) { vuRM = gameDB->getInt("vuRoundMode"); rm=1; }
|
||||||
SSE_MXCSR vuMX = EmuConfig.Cpu.sseVUMXCSR;
|
if (rm && eeRM<4 && vuRM<4) {
|
||||||
int eeRM = eeMX.GetRoundMode();
|
Console.WriteLn("Game DataBase: Changing roundmodes! [ee=%d] [vu=%d]", eeRM, vuRM);
|
||||||
int vuRM = vuMX.GetRoundMode();
|
SetCPUState(eeMX.SetRoundMode((SSE_RoundMode)eeRM), vuMX.SetRoundMode((SSE_RoundMode)vuRM));
|
||||||
bool rm = 0;
|
}
|
||||||
if (gameDB->keyExists("eeRoundMode")) { eeRM = gameDB->getInt("eeRoundMode"); rm=1; }
|
if (gameDB->keyExists("eeClampMode")) {
|
||||||
if (gameDB->keyExists("vuRoundMode")) { vuRM = gameDB->getInt("vuRoundMode"); rm=1; }
|
int clampMode = gameDB->getInt("eeClampMode");
|
||||||
if (rm && eeRM<4 && vuRM<4) {
|
Console.WriteLn("Game DataBase: Changing EE/FPU clamp mode [mode=%d]", clampMode);
|
||||||
Console.WriteLn("Game DataBase: Changing roundmodes! [ee=%d] [vu=%d]", eeRM, vuRM);
|
SetRecompilerConfig().fpuOverflow = clampMode >= 1;
|
||||||
SetCPUState(eeMX.SetRoundMode((SSE_RoundMode)eeRM), vuMX.SetRoundMode((SSE_RoundMode)vuRM));
|
SetRecompilerConfig().fpuExtraOverflow = clampMode >= 2;
|
||||||
}
|
SetRecompilerConfig().fpuFullMode = clampMode >= 3;
|
||||||
if (gameDB->keyExists("eeClampMode")) {
|
}
|
||||||
int clampMode = gameDB->getInt("eeClampMode");
|
if (gameDB->keyExists("vuClampMode")) {
|
||||||
Console.WriteLn("Game DataBase: Changing EE/FPU clamp mode [mode=%d]", clampMode);
|
int clampMode = gameDB->getInt("vuClampMode");
|
||||||
SetRecompilerConfig().fpuOverflow = clampMode >= 1;
|
Console.WriteLn("Game DataBase: Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
|
||||||
SetRecompilerConfig().fpuExtraOverflow = clampMode >= 2;
|
SetRecompilerConfig().vuOverflow = clampMode >= 1;
|
||||||
SetRecompilerConfig().fpuFullMode = clampMode >= 3;
|
SetRecompilerConfig().vuExtraOverflow = clampMode >= 2;
|
||||||
}
|
SetRecompilerConfig().vuSignOverflow = clampMode >= 3;
|
||||||
if (gameDB->keyExists("vuClampMode")) {
|
}
|
||||||
int clampMode = gameDB->getInt("vuClampMode");
|
checkGamefix(VuAddSubHack);
|
||||||
Console.WriteLn("Game DataBase: Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
|
checkGamefix(VuClipFlagHack);
|
||||||
SetRecompilerConfig().vuOverflow = clampMode >= 1;
|
checkGamefix(FpuCompareHack);
|
||||||
SetRecompilerConfig().vuExtraOverflow = clampMode >= 2;
|
checkGamefix(FpuMulHack);
|
||||||
SetRecompilerConfig().vuSignOverflow = clampMode >= 3;
|
checkGamefix(FpuNegDivHack);
|
||||||
}
|
checkGamefix(XgKickHack);
|
||||||
checkGamefix(VuAddSubHack);
|
checkGamefix(IPUWaitHack);
|
||||||
checkGamefix(VuClipFlagHack);
|
checkGamefix(EETimingHack);
|
||||||
checkGamefix(FpuCompareHack);
|
}
|
||||||
checkGamefix(FpuMulHack);
|
}
|
||||||
checkGamefix(FpuNegDivHack);
|
|
||||||
checkGamefix(XgKickHack);
|
extern ScopedPtr<DataBase_Loader> GameDB;
|
||||||
checkGamefix(IPUWaitHack);
|
|
||||||
checkGamefix(EETimingHack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern ScopedPtr<DataBase_Loader> GameDB;
|
|
||||||
|
|
Loading…
Reference in New Issue