mirror of https://github.com/PCSX2/pcsx2.git
Fix gruesome errors in database loading/saving.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3191 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d2b6171ce8
commit
e285ff4b50
|
@ -20,6 +20,47 @@
|
||||||
#include <wx/tokenzr.h>
|
#include <wx/tokenzr.h>
|
||||||
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// pxToUTF8
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// Converts a string to UTF8 and provides an interface for getting its length.
|
||||||
|
class pxToUTF8
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject( pxToUTF8 );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxCharBuffer m_result;
|
||||||
|
int m_length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit pxToUTF8(const wxString& src)
|
||||||
|
: m_result( src.ToUTF8() )
|
||||||
|
{
|
||||||
|
m_length = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Length()
|
||||||
|
{
|
||||||
|
if( -1 == m_length )
|
||||||
|
m_length = strlen( m_result );
|
||||||
|
return m_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Convert( const wxString& src )
|
||||||
|
{
|
||||||
|
m_result = src.ToUTF8();
|
||||||
|
m_length = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* data() const { return m_result; }
|
||||||
|
|
||||||
|
operator const char*() const
|
||||||
|
{
|
||||||
|
return m_result.data();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
extern void px_fputs( FILE* fp, const char* src );
|
extern void px_fputs( FILE* fp, const char* src );
|
||||||
|
|
||||||
extern wxString fromUTF8( const char* src );
|
extern wxString fromUTF8( const char* src );
|
||||||
|
|
|
@ -82,7 +82,10 @@ void pxWriteLine( wxOutputStream& output )
|
||||||
void pxWriteLine( wxOutputStream& output, const wxString& text )
|
void pxWriteLine( wxOutputStream& output, const wxString& text )
|
||||||
{
|
{
|
||||||
if( !text.IsEmpty() )
|
if( !text.IsEmpty() )
|
||||||
output.Write(text.ToUTF8(), text.Length());
|
{
|
||||||
|
pxToUTF8 utf8(text);
|
||||||
|
output.Write(utf8, utf8.Length());
|
||||||
|
}
|
||||||
pxWriteLine( output );
|
pxWriteLine( output );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +95,8 @@ void pxWriteMultiline( wxOutputStream& output, const wxString& src )
|
||||||
|
|
||||||
wxString result( src );
|
wxString result( src );
|
||||||
result.Replace( L"\r\n", L"\n" );
|
result.Replace( L"\r\n", L"\n" );
|
||||||
result.Replace( L"\r", wxEmptyString );
|
result.Replace( L"\r", L"\n" );
|
||||||
|
|
||||||
output.Write(result.ToUTF8(), result.Length());
|
pxToUTF8 utf8(result);
|
||||||
|
output.Write(utf8, utf8.Length());
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,37 +19,40 @@ void DataBase_Loader::doError(const wxString& line, key_pair& keyPair, bool doMs
|
||||||
// [/section]
|
// [/section]
|
||||||
//
|
//
|
||||||
// ... where the =value part is OPTIONAL.
|
// ... where the =value part is OPTIONAL.
|
||||||
void DataBase_Loader::extractMultiLine(key_pair& keyPair, wxInputStream& ffile) {
|
bool DataBase_Loader::extractMultiLine(const wxString& line, key_pair& keyPair, wxInputStream& ffile) {
|
||||||
|
|
||||||
if (!keyPair.key.EndsWith(L"]")) {
|
if (line[0] != L'[') return false; // All multiline sections begin with a '['!
|
||||||
doError(keyPair.key, keyPair, true);
|
|
||||||
return;
|
if (!line.EndsWith(L"]")) {
|
||||||
|
doError(line, keyPair, true);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Mid() to strip off the left and right side brackets.
|
keyPair.key = line;
|
||||||
ParsedAssignmentString set( keyPair.key.Mid(1, keyPair.key.Length()-2) );
|
|
||||||
|
|
||||||
wxString endString;
|
|
||||||
endString.Printf( L"[/%s]", set.lvalue.c_str() );
|
|
||||||
|
|
||||||
for(;;) {
|
// Use Mid() to strip off the left and right side brackets.
|
||||||
|
wxString midLine(line.Mid(1, line.Length()-2));
|
||||||
|
wxString lvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||||
|
//wxString rvalue(midLine.AfterFirst(L'=').Trim(true).Trim(false));
|
||||||
|
|
||||||
|
wxString endString;
|
||||||
|
endString.Printf( L"[/%s]", lvalue.c_str() );
|
||||||
|
|
||||||
|
while(!ffile.Eof()) {
|
||||||
pxReadLine( ffile, m_dest, m_intermediate );
|
pxReadLine( ffile, m_dest, m_intermediate );
|
||||||
if (m_dest == endString) break;
|
if (m_dest == endString) break;
|
||||||
keyPair.value += m_dest + L"\n";
|
keyPair.value += m_dest + L"\n";
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataBase_Loader::extract(const wxString& line, key_pair& keyPair, wxInputStream& reader) {
|
void DataBase_Loader::extract(const wxString& line, key_pair& keyPair, wxInputStream& reader) {
|
||||||
keyPair.key = line;
|
keyPair.key.clear();
|
||||||
keyPair.value.clear();
|
keyPair.value.clear();
|
||||||
|
|
||||||
if( line.IsEmpty() ) return;
|
if( line.IsEmpty() ) return;
|
||||||
|
|
||||||
if (keyPair.key[0] == L'[') {
|
if( extractMultiLine(line, keyPair, reader) ) return;
|
||||||
extractMultiLine(keyPair, reader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !pxParseAssignmentString( line, keyPair.key, keyPair.value ) ) return;
|
if( !pxParseAssignmentString( line, keyPair.key, keyPair.value ) ) return;
|
||||||
if( keyPair.value.IsEmpty() )
|
if( keyPair.value.IsEmpty() )
|
||||||
doError(line, keyPair, true);
|
doError(line, keyPair, true);
|
||||||
|
|
|
@ -31,8 +31,15 @@ struct key_pair {
|
||||||
wxString toString() const {
|
wxString toString() const {
|
||||||
if (key[0] == '[') {
|
if (key[0] == '[') {
|
||||||
pxAssumeDev( key.EndsWith(L"]"), "Malformed multiline key detected: missing end bracket!" );
|
pxAssumeDev( key.EndsWith(L"]"), "Malformed multiline key detected: missing end bracket!" );
|
||||||
return wxsFormat( L"%s\n%s\n[/%s\n",
|
|
||||||
key.c_str(), value.c_str(), key.Mid(1, key.length()-1).c_str()
|
// Terminating tag must be written without the "rvalue" -- in the form of:
|
||||||
|
// [/patches]
|
||||||
|
// Use Mid() to strip off the left and right side brackets.
|
||||||
|
wxString midLine(key.Mid(1, key.Length()-2));
|
||||||
|
wxString keyLvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||||
|
|
||||||
|
return wxsFormat( L"%s\n%s[/%s]\n",
|
||||||
|
key.c_str(), value.c_str(), keyLvalue.c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -70,7 +77,7 @@ class DataBase_Loader {
|
||||||
protected:
|
protected:
|
||||||
bool isComment(const wxString& s);
|
bool isComment(const wxString& s);
|
||||||
void doError(const wxString& line, key_pair& keyPair, bool doMsg = false);
|
void doError(const wxString& line, key_pair& keyPair, bool doMsg = false);
|
||||||
void extractMultiLine(key_pair& keyPair, wxInputStream& reader);
|
bool extractMultiLine(const wxString& line, key_pair& keyPair, wxInputStream& reader);
|
||||||
void extract(const wxString& line, key_pair& keyPair, wxInputStream& reader);
|
void extract(const wxString& line, key_pair& keyPair, wxInputStream& reader);
|
||||||
|
|
||||||
const wxString m_emptyString; // empty string for returning stuff .. never modify!
|
const wxString m_emptyString; // empty string for returning stuff .. never modify!
|
||||||
|
|
|
@ -1385,7 +1385,7 @@ void PluginManager::SendSettingsFolder()
|
||||||
ScopedLock lock( m_mtx_PluginStatus );
|
ScopedLock lock( m_mtx_PluginStatus );
|
||||||
if( m_SettingsFolder.IsEmpty() ) return;
|
if( m_SettingsFolder.IsEmpty() ) return;
|
||||||
|
|
||||||
wxCharBuffer utf8buffer( m_SettingsFolder.ToUTF8() );
|
pxToUTF8 utf8buffer( m_SettingsFolder );
|
||||||
|
|
||||||
const PluginInfo* pi = tbl_PluginInfo; do {
|
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||||
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetSettingsDir( utf8buffer );
|
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetSettingsDir( utf8buffer );
|
||||||
|
@ -1412,7 +1412,7 @@ void PluginManager::SendLogFolder()
|
||||||
ScopedLock lock( m_mtx_PluginStatus );
|
ScopedLock lock( m_mtx_PluginStatus );
|
||||||
if( m_LogFolder.IsEmpty() ) return;
|
if( m_LogFolder.IsEmpty() ) return;
|
||||||
|
|
||||||
wxCharBuffer utf8buffer( m_LogFolder.ToUTF8() );
|
pxToUTF8 utf8buffer( m_LogFolder );
|
||||||
|
|
||||||
const PluginInfo* pi = tbl_PluginInfo; do {
|
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||||
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetLogFolder( utf8buffer );
|
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetLogFolder( utf8buffer );
|
||||||
|
|
|
@ -111,8 +111,9 @@ void SaveStateBase::FreezeBios()
|
||||||
memzero( descin );
|
memzero( descin );
|
||||||
memzero( desccmp );
|
memzero( desccmp );
|
||||||
|
|
||||||
memcpy_fast( descin, descout.ToUTF8().data(), descout.Length() );
|
pxToUTF8 utf8(descout);
|
||||||
memcpy_fast( desccmp, descout.ToUTF8().data(), descout.Length() );
|
memcpy_fast( descin, utf8, utf8.Length() );
|
||||||
|
memcpy_fast( desccmp, utf8, utf8.Length() );
|
||||||
|
|
||||||
// ... and only freeze bios info once per state, since the user msg could
|
// ... and only freeze bios info once per state, since the user msg could
|
||||||
// become really annoying on a corrupted state or something. (have to always
|
// become really annoying on a corrupted state or something. (have to always
|
||||||
|
@ -130,7 +131,7 @@ void SaveStateBase::FreezeBios()
|
||||||
Console.Indent(2).Error(
|
Console.Indent(2).Error(
|
||||||
"Current Version: %s\n"
|
"Current Version: %s\n"
|
||||||
"Savestate Version: %s\n",
|
"Savestate Version: %s\n",
|
||||||
descout.ToUTF8().data(), descin
|
utf8.data(), descin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,14 +359,17 @@ namespace Panels
|
||||||
wxTextCtrl* commentBox;
|
wxTextCtrl* commentBox;
|
||||||
wxTextCtrl* patchesBox;
|
wxTextCtrl* patchesBox;
|
||||||
pxCheckBox* gameFixes[NUM_OF_GAME_FIXES];
|
pxCheckBox* gameFixes[NUM_OF_GAME_FIXES];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameDatabasePanel( wxWindow* parent );
|
GameDatabasePanel( wxWindow* parent );
|
||||||
virtual ~GameDatabasePanel() throw() { }
|
virtual ~GameDatabasePanel() throw() { }
|
||||||
void PopulateFields();
|
|
||||||
void WriteFieldsToDB();
|
|
||||||
void Search_Click( wxCommandEvent& evt );
|
|
||||||
void Apply();
|
void Apply();
|
||||||
void AppStatusEvent_OnSettingsApplied();
|
void AppStatusEvent_OnSettingsApplied();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void PopulateFields();
|
||||||
|
bool WriteFieldsToDB();
|
||||||
|
void Search_Click( wxCommandEvent& evt );
|
||||||
};
|
};
|
||||||
|
|
||||||
class SettingsDirPickerPanel : public DirPickerPanel
|
class SettingsDirPickerPanel : public DirPickerPanel
|
||||||
|
|
|
@ -141,11 +141,12 @@ void Panels::GameDatabasePanel::PopulateFields() {
|
||||||
else GameDB->writeBool(wxT(_key), _value); \
|
else GameDB->writeBool(wxT(_key), _value); \
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::WriteFieldsToDB() {
|
// returns True if the database is modified, or FALSE if no changes to save.
|
||||||
|
bool Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||||
wxString wxStr( serialBox->GetValue() );
|
wxString wxStr( serialBox->GetValue() );
|
||||||
|
|
||||||
if (wxStr.IsEmpty()) return;
|
if (wxStr.IsEmpty()) return false;
|
||||||
if (wxStr == GameDB->getString("Serial")) {
|
if (wxStr != GameDB->getString("Serial")) {
|
||||||
GameDB->addGame(wxStr);
|
GameDB->addGame(wxStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +164,7 @@ void Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||||
writeGameFixToDB("IPUWaitHack", gameFixes[6]->GetValue());
|
writeGameFixToDB("IPUWaitHack", gameFixes[6]->GetValue());
|
||||||
writeGameFixToDB("EETimingHack", gameFixes[7]->GetValue());
|
writeGameFixToDB("EETimingHack", gameFixes[7]->GetValue());
|
||||||
writeGameFixToDB("SkipMPEGHack", gameFixes[8]->GetValue());
|
writeGameFixToDB("SkipMPEGHack", gameFixes[8]->GetValue());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
||||||
|
@ -178,9 +180,11 @@ void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::Apply() {
|
void Panels::GameDatabasePanel::Apply() {
|
||||||
Console.WriteLn("Saving changes to Game Database...");
|
if( WriteFieldsToDB() )
|
||||||
WriteFieldsToDB();
|
{
|
||||||
GameDB->saveToFile();
|
Console.WriteLn("Saving changes to Game Database...");
|
||||||
|
GameDB->saveToFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::AppStatusEvent_OnSettingsApplied()
|
void Panels::GameDatabasePanel::AppStatusEvent_OnSettingsApplied()
|
||||||
|
|
Loading…
Reference in New Issue