mirror of https://github.com/PCSX2/pcsx2.git
Patches are now part of the game database.
They can be CRC specific, or just based on the game serial. Examples: [patches] // This patch is loaded regardless of crc patch=0,EE,002aa040,word,24020001 [/patches] [patches = 84993903] // Patches go here // This is only loaded if crc = 84993903 patch=0,EE,002bc040,word,24020341 [/patches] notes: - pcsx2 only loads the first [patches] block that matches the game. - The [patches] block based on crc takes priority when pcsx2 searches for patches... - Everything in-between the patches block gets fed to pcsx2's old patch parser; so currently the patch syntax is the same as before... - A lot of patches weren't added to the database since they didn't include serial codes in their *.pnach files :/ git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3007 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
1d534c7481
commit
7abc292cb2
1088
bin/DataBase.dbf
1088
bin/DataBase.dbf
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,26 @@ struct key_pair {
|
|||
string value;
|
||||
key_pair(string _key, string _value)
|
||||
: key(_key) , value(_value) {}
|
||||
string toString() {
|
||||
string t;
|
||||
if (key[0] == '[') {
|
||||
t = key + "\n";
|
||||
t += value;
|
||||
stringstream ss(key);
|
||||
string t2;
|
||||
ss >> t2;
|
||||
t += "[/" + t2.substr(1, t2.length()-1);
|
||||
if (t2.compare(t)) t += "]";
|
||||
}
|
||||
else {
|
||||
t = key;
|
||||
for (int a = 6 - key.length(); a > 0; a--) {
|
||||
t += " "; // Padding for nice formatting on small key-names
|
||||
}
|
||||
t += " = " + value;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
class Game_Data {
|
||||
|
@ -63,7 +83,21 @@ private:
|
|||
if (doMsg) Console.Error("DataBase_Loader: Bad file data [%s]", line.c_str());
|
||||
keyPair.key = "";
|
||||
}
|
||||
void extract(string& line, key_pair& keyPair) {
|
||||
void extractMultiLine(string& line, key_pair& keyPair, File_Reader& reader, stringstream& ss) {
|
||||
string t = "";
|
||||
string endString;
|
||||
endString = "[/" + keyPair.key.substr(1, keyPair.key.length()-1);
|
||||
if (keyPair.key[keyPair.key.length()-1] != ']') {
|
||||
endString += "]";
|
||||
keyPair.key = line;
|
||||
}
|
||||
for(;;) {
|
||||
t = reader.getLine();
|
||||
if (!t.compare(endString)) break;
|
||||
keyPair.value += t + "\n";
|
||||
}
|
||||
}
|
||||
void extract(string& line, key_pair& keyPair, File_Reader& reader) {
|
||||
int eol = line.rfind("\r");
|
||||
if (eol != string::npos) line = line.substr(0, eol);
|
||||
|
||||
|
@ -76,6 +110,10 @@ private:
|
|||
doError(line, keyPair);
|
||||
return;
|
||||
}
|
||||
if (keyPair.key[0] == '[') {
|
||||
extractMultiLine(line, keyPair, reader, ss);
|
||||
return;
|
||||
}
|
||||
ss >> t;
|
||||
if (t.compare("=") != 0) {
|
||||
doError(line, keyPair, true);
|
||||
|
@ -90,8 +128,7 @@ private:
|
|||
while (!ss.eof() && !ss.fail()) {
|
||||
ss >> t;
|
||||
if (isComment(t)) break;
|
||||
keyPair.value += " ";
|
||||
keyPair.value += t;
|
||||
keyPair.value += " " + t;
|
||||
}
|
||||
if (ss.fail()) {
|
||||
doError(line, keyPair);
|
||||
|
@ -117,7 +154,7 @@ public:
|
|||
for(;;) {
|
||||
for(;;) { // Find first game
|
||||
s0 = reader.getLine();
|
||||
extract(s0, keyPair);
|
||||
extract(s0, keyPair, reader);
|
||||
if (keyPair.key.compare(key) == 0) break;
|
||||
header.write(s0);
|
||||
header.write("\n");
|
||||
|
@ -126,7 +163,7 @@ public:
|
|||
game->kList.push_back(keyPair);
|
||||
for (;;) { // Fill game data, find new game, repeat...
|
||||
s0 = reader.getLine();
|
||||
extract(s0, keyPair);
|
||||
extract(s0, keyPair, reader);
|
||||
if (keyPair.key.compare("") == 0) continue;
|
||||
if (keyPair.key.compare(key) == 0) {
|
||||
gList.push_back(game);
|
||||
|
@ -178,13 +215,7 @@ public:
|
|||
for ( ; it != gList.end(); ++it) {
|
||||
deque<key_pair>::iterator i = it[0]->kList.begin();
|
||||
for ( ; i != it[0]->kList.end(); ++i) {
|
||||
writer.write(i[0].key);
|
||||
for (int a = 6 - i[0].key.length(); a > 0; a--) {
|
||||
writer.write(" "); // Padding for nice formatting on small key-names
|
||||
}
|
||||
writer.write(" = ");
|
||||
writer.write(i[0].value);
|
||||
writer.write("\n");
|
||||
writer.write(i[0].toString() + "\n");
|
||||
}
|
||||
writer.write("---------------------------------------------\n");
|
||||
}
|
||||
|
@ -201,6 +232,20 @@ public:
|
|||
curGame = game;
|
||||
}
|
||||
|
||||
// Searches the current game's data to see if the given key exists
|
||||
bool keyExists(string key) {
|
||||
if (curGame) {
|
||||
deque<key_pair>::iterator it = curGame->kList.begin();
|
||||
for ( ; it != curGame->kList.end(); ++it) {
|
||||
if (!it[0].key.compare(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else Console.Error("DataBase_Loader: Game not set!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gets a string representation of the 'value' for the given key
|
||||
string getString(string key) {
|
||||
if (curGame) {
|
||||
|
|
|
@ -95,11 +95,16 @@ public:
|
|||
};
|
||||
|
||||
class String_Stream {
|
||||
private:
|
||||
char buff[2048];
|
||||
public:
|
||||
stringstream* ss;
|
||||
String_Stream() {
|
||||
ss = new stringstream(stringstream::in | stringstream::out);
|
||||
}
|
||||
String_Stream(string& str) {
|
||||
ss = new stringstream(str, stringstream::in | stringstream::out);
|
||||
}
|
||||
~String_Stream() {
|
||||
delete ss;
|
||||
}
|
||||
|
@ -112,6 +117,17 @@ public:
|
|||
string toString() {
|
||||
return ss->str();
|
||||
}
|
||||
string getLine() {
|
||||
ss->getline(buff, sizeof(buff));
|
||||
return string(buff);
|
||||
}
|
||||
wxString getLineWX() {
|
||||
ss->getline(buff, sizeof(buff));
|
||||
return wxString(fromAscii(buff));
|
||||
}
|
||||
bool finished() {
|
||||
return ss->eof() || ss->fail();
|
||||
}
|
||||
};
|
||||
|
||||
static bool fileExists(string file) {
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
|
||||
#include "IopCommon.h"
|
||||
#include "Patch.h"
|
||||
|
||||
#include <wx/textfile.h>
|
||||
#include "DataBase_Loader.h"
|
||||
|
||||
IniPatch Patch[ MAX_PATCH ];
|
||||
|
||||
|
@ -418,12 +417,16 @@ void inifile_command( const wxString& cmd )
|
|||
|
||||
// This routine recieves a file from inifile_read, trims it,
|
||||
// Then sends the command to be parsed.
|
||||
void inifile_process(wxTextFile &f1 )
|
||||
void inifile_process(string& s)
|
||||
{
|
||||
for (uint i = 0; i < f1.GetLineCount(); i++)
|
||||
String_Stream ss(s);
|
||||
wxString buff;
|
||||
while (!ss.finished())
|
||||
{
|
||||
inifile_trim(f1[i]);
|
||||
if (!f1[i].IsEmpty()) inifile_command(f1[i]);
|
||||
buff = ss.getLineWX();
|
||||
//Console.Error("%s", buff.ToAscii());
|
||||
inifile_trim(buff);
|
||||
if (!buff.IsEmpty()) inifile_command(buff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,28 +434,27 @@ void inifile_process(wxTextFile &f1 )
|
|||
// loads it, trims the commands, and sends them to be parsed.
|
||||
void inifile_read(const wxString& name )
|
||||
{
|
||||
wxTextFile f1;
|
||||
wxString buffer;
|
||||
|
||||
bool patchFound = false;
|
||||
string patch;
|
||||
string crc = string(name.ToAscii());
|
||||
patchnumber = 0;
|
||||
|
||||
// FIXME : We need to add a 'patches' folder to the AppConfig, and use that instead. --air
|
||||
|
||||
buffer = Path::Combine(L"patches", name + L".pnach");
|
||||
|
||||
if(!f1.Open(buffer) && wxFileName::IsCaseSensitive())
|
||||
{
|
||||
f1.Open( Path::Combine(L"patches", name.Upper() + L".pnach") );
|
||||
if (GameDB && GameDB->gameLoaded()) {
|
||||
if (GameDB->keyExists("[patches = " + crc + "]")) {
|
||||
patch = GameDB->getString("[patches = " + crc + "]");
|
||||
patchFound = true;
|
||||
}
|
||||
else if (GameDB->keyExists("[patches]")) {
|
||||
patch = GameDB->getString("[patches]");
|
||||
patchFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!f1.IsOpened())
|
||||
{
|
||||
Console.WriteLn( Color_Gray, "No patch found. Resuming execution without a patch (this is NOT an error)." );
|
||||
return;
|
||||
if (patchFound) {
|
||||
Console.WriteLn(Color_Green, "Patch found!");
|
||||
inifile_process(patch);
|
||||
}
|
||||
|
||||
Console.WriteLn( Color_Green, "Patch found!");
|
||||
inifile_process( f1 );
|
||||
else Console.WriteLn(Color_Gray, "No patch found. Resuming execution without a patch (this is NOT an error).");
|
||||
}
|
||||
|
||||
void _ApplyPatch(IniPatch *p)
|
||||
|
|
|
@ -589,7 +589,7 @@ void __fastcall eeGameStarting()
|
|||
gameCompat = L" [Status = "+compatToStringWX(compat)+L"]";
|
||||
}
|
||||
|
||||
// if patches found the following title will be overwritten
|
||||
// this title can be overwritten by patches if they set the gametitle key
|
||||
Console.SetTitle(gameName + gameSerial + gameCompat);
|
||||
|
||||
if (EmuConfig.EnablePatches) InitPatch(gameCRC);
|
||||
|
|
Loading…
Reference in New Issue