mirror of https://github.com/PCSX2/pcsx2.git
Fully implement hash-based database lookup. Fix some bugs that caused startup crashes in previous revisions of mine.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3273 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
f3ae10f5c3
commit
24ae022a74
|
@ -208,7 +208,7 @@ public:
|
||||||
|
|
||||||
hash_key_t operator()( const wxString& src ) const
|
hash_key_t operator()( const wxString& src ) const
|
||||||
{
|
{
|
||||||
return Hash( (const char *)src.data(), src.length() * sizeof( wchar_t ) );
|
return Hash( (const char *)src.data(), src.length() * sizeof( wxChar ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a hashcode for a character.
|
// Returns a hashcode for a character.
|
||||||
|
@ -555,12 +555,12 @@ public:
|
||||||
/// matter, don't use this class at all! Use the string-specialized classes <see cref="Dictionary" /> and
|
/// matter, don't use this class at all! Use the string-specialized classes <see cref="Dictionary" /> and
|
||||||
/// <see cref="UnicodeDictionary" />.
|
/// <see cref="UnicodeDictionary" />.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
template< class Key, class T >
|
template< class Key, class T, class HashFunctor=CommonHashClass >
|
||||||
class HashMap : public google::dense_hash_map<Key, T, CommonHashClass>
|
class HashMap : public google::dense_hash_map<Key, T, HashFunctor>
|
||||||
{
|
{
|
||||||
DeclareNoncopyableObject( HashMap );
|
DeclareNoncopyableObject( HashMap );
|
||||||
|
|
||||||
typedef typename google::dense_hash_map<Key, T, CommonHashClass> _parent;
|
typedef typename google::dense_hash_map<Key, T, HashFunctor> _parent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using _parent::operator[];
|
using _parent::operator[];
|
||||||
|
@ -577,7 +577,7 @@ public:
|
||||||
/// are *not* used as actual values in the set.
|
/// are *not* used as actual values in the set.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
HashMap( const Key& emptyKey, const Key& deletedKey, int initialCapacity=33 ) :
|
HashMap( const Key& emptyKey, const Key& deletedKey, int initialCapacity=33 ) :
|
||||||
google::dense_hash_map<Key, T, CommonHashClass>( initialCapacity )
|
google::dense_hash_map<Key, T, HashFunctor>( initialCapacity )
|
||||||
{
|
{
|
||||||
set_empty_key( emptyKey );
|
set_empty_key( emptyKey );
|
||||||
set_deleted_key( deletedKey );
|
set_deleted_key( deletedKey );
|
||||||
|
@ -653,14 +653,14 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class T >
|
template< class T, class HashFunctor=HashTools::CommonHashClass >
|
||||||
class pxDictionary : public HashTools::HashMap<wxString, T>
|
class pxDictionary : public HashTools::HashMap<wxString, T, HashFunctor>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~pxDictionary() {}
|
virtual ~pxDictionary() {}
|
||||||
|
|
||||||
pxDictionary( int initialCapacity=33, const wxString& emptyKey = L"@@-EMPTY-@@", const wxString& deletedKey = L"@@-DELETED-@@" )
|
pxDictionary( int initialCapacity=33, const wxString& emptyKey = L"@@-EMPTY-@@", const wxString& deletedKey = L"@@-DELETED-@@" )
|
||||||
: HashTools::HashMap<wxString, T>( emptyKey, deletedKey, initialCapacity)
|
: HashTools::HashMap<wxString, T, HashFunctor>( emptyKey, deletedKey, initialCapacity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,11 @@
|
||||||
#include "ps2/BiosTools.h"
|
#include "ps2/BiosTools.h"
|
||||||
#include "GameDatabase.h"
|
#include "GameDatabase.h"
|
||||||
|
|
||||||
wxString DiscID;
|
// This typically reflects the Sony-assigned serial code for the Disc, if one exists.
|
||||||
|
// (examples: SLUS-2113, etc).
|
||||||
|
// If the disc is homebrew then it probably won't have a valid serial; in which case
|
||||||
|
// this string will be empty.
|
||||||
|
wxString DiscSerial;
|
||||||
|
|
||||||
static cdvdStruct cdvd;
|
static cdvdStruct cdvd;
|
||||||
|
|
||||||
|
@ -340,9 +344,9 @@ static __forceinline void _reloadElfInfo(wxString elfpath)
|
||||||
if (!fname)
|
if (!fname)
|
||||||
fname = elfpath.AfterLast(':');
|
fname = elfpath.AfterLast(':');
|
||||||
if (fname.Matches(L"????_???.??*"))
|
if (fname.Matches(L"????_???.??*"))
|
||||||
DiscID = fname(0,4) + L"-" + fname(5,3) + fname(9,2);
|
DiscSerial = fname(0,4) + L"-" + fname(5,3) + fname(9,2);
|
||||||
|
|
||||||
Console.WriteLn("Disc ID = %s", DiscID.ToUTF8().data());
|
Console.WriteLn("Disc ID = %s", DiscSerial.ToUTF8().data());
|
||||||
elfptr = loadElf(elfpath);
|
elfptr = loadElf(elfpath);
|
||||||
|
|
||||||
ElfCRC = elfptr->getCRC();
|
ElfCRC = elfptr->getCRC();
|
||||||
|
@ -355,18 +359,13 @@ static __forceinline void _reloadElfInfo(wxString elfpath)
|
||||||
|
|
||||||
// Set the Game DataBase to the correct game based on Game Serial Code...
|
// Set the Game DataBase to the correct game based on Game Serial Code...
|
||||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase()) {
|
if (IGameDatabase* GameDB = AppHost_GetGameDatabase()) {
|
||||||
wxString gameSerial = DiscID;
|
wxString gameSerial( SysGetDiscID() );
|
||||||
if (gameSerial.IsEmpty()) { // Search for crc if no Serial Code
|
|
||||||
gameSerial = wxsFormat( L"%8.8x", ElfCRC );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString serialMsg;
|
wxString serialMsg;
|
||||||
if(!DiscID.IsEmpty())
|
if(!DiscSerial.IsEmpty())
|
||||||
serialMsg = L"serial=" + DiscID + L" ";
|
serialMsg = L"serial=" + DiscSerial + L" ";
|
||||||
|
|
||||||
//Game_Data CurrentGame;
|
Game_Data game;
|
||||||
//if (GameDB->getGame(CurrentGame, gameSerial))
|
if (GameDB->findGame(game, gameSerial))
|
||||||
if (GameDB->setGame(gameSerial))
|
|
||||||
{
|
{
|
||||||
Console.WriteLn(L"(GameDB) Found Game! %s [CRC=%8.8x]", serialMsg.c_str(), ElfCRC );
|
Console.WriteLn(L"(GameDB) Found Game! %s [CRC=%8.8x]", serialMsg.c_str(), ElfCRC );
|
||||||
// [TODO] Display lots of other info from the database here!
|
// [TODO] Display lots of other info from the database here!
|
||||||
|
@ -416,14 +415,14 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key)
|
||||||
cdvdReloadElfInfo();
|
cdvdReloadElfInfo();
|
||||||
|
|
||||||
// convert the number characters to a real 32 bit number
|
// convert the number characters to a real 32 bit number
|
||||||
numbers = StrToS32(DiscID(5,5));
|
numbers = StrToS32(DiscSerial(5,5));
|
||||||
|
|
||||||
// combine the lower 7 bits of each char
|
// combine the lower 7 bits of each char
|
||||||
// to make the 4 letters fit into a single u32
|
// to make the 4 letters fit into a single u32
|
||||||
letters = (s32)((DiscID[3]&0x7F)<< 0) |
|
letters = (s32)((DiscSerial[3]&0x7F)<< 0) |
|
||||||
(s32)((DiscID[2]&0x7F)<< 7) |
|
(s32)((DiscSerial[2]&0x7F)<< 7) |
|
||||||
(s32)((DiscID[1]&0x7F)<<14) |
|
(s32)((DiscSerial[1]&0x7F)<<14) |
|
||||||
(s32)((DiscID[0]&0x7F)<<21);
|
(s32)((DiscSerial[0]&0x7F)<<21);
|
||||||
|
|
||||||
// calculate magic numbers
|
// calculate magic numbers
|
||||||
key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80
|
key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80
|
||||||
|
|
|
@ -145,4 +145,4 @@ extern void cdvdWrite(u8 key, u8 rt);
|
||||||
|
|
||||||
extern void cdvdReloadElfInfo(wxString elfoverride = wxEmptyString);
|
extern void cdvdReloadElfInfo(wxString elfoverride = wxEmptyString);
|
||||||
|
|
||||||
extern wxString DiscID;
|
extern wxString DiscSerial;
|
||||||
|
|
|
@ -18,89 +18,88 @@
|
||||||
|
|
||||||
// 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 BaseGameDatabaseVector::setGame(const wxString& id) {
|
bool BaseGameDatabaseImpl::findGame(Game_Data& dest, const wxString& id) {
|
||||||
|
|
||||||
GameDataHash::const_iterator iter( gHash.find(id) );
|
GameDataHash::const_iterator iter( gHash.find(id) );
|
||||||
if( iter == gHash.end() ) {
|
if( iter == gHash.end() ) {
|
||||||
curGame = NULL;
|
dest.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
curGame = &gList[iter->second];
|
dest = gList[iter->second];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game_Data* BaseGameDatabaseVector::createNewGame(const wxString& id) {
|
void BaseGameDatabaseImpl::addNewGame(const Game_Data& game)
|
||||||
gList.push_back(Game_Data(id));
|
{
|
||||||
gHash[id] = gList.size()-1;
|
gList.push_back(game);
|
||||||
curGame = &(gList.end()-1)[0];
|
gHash[game.id] = gList.size()-1;
|
||||||
return curGame;
|
}
|
||||||
|
|
||||||
|
void BaseGameDatabaseImpl::updateGame(const Game_Data& game)
|
||||||
|
{
|
||||||
|
GameDataHash::const_iterator iter( gHash.find(game.id) );
|
||||||
|
|
||||||
|
if( iter == gHash.end() ) {
|
||||||
|
gList.push_back(game);
|
||||||
|
gHash[game.id] = gList.size()-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Re-assign existing vector/array entry!
|
||||||
|
gList[gHash[game.id]] = 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 BaseGameDatabaseVector::keyExists(const wxChar* key) {
|
bool Game_Data::keyExists(const wxChar* key) {
|
||||||
if (curGame) {
|
KeyPairArray::iterator it( kList.begin() );
|
||||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
for ( ; it != kList.end(); ++it) {
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
if (it[0].CompareKey(key)) {
|
||||||
if (it[0].CompareKey(key)) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("(GameDB) Game not set!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Totally Deletes the specified key/pair value from the current game's data
|
// Totally Deletes the specified key/pair value from the current game's data
|
||||||
void BaseGameDatabaseVector::deleteKey(const wxChar* key) {
|
void Game_Data::deleteKey(const wxChar* key) {
|
||||||
if (curGame) {
|
KeyPairArray::iterator it( kList.begin() );
|
||||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
for ( ; it != kList.end(); ++it) {
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
if (it[0].CompareKey(key)) {
|
||||||
if (it[0].CompareKey(key)) {
|
kList.erase(it);
|
||||||
curGame->kList.erase(it);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("(GameDB) Game not set!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a string representation of the 'value' for the given key
|
// Gets a string representation of the 'value' for the given key
|
||||||
wxString BaseGameDatabaseVector::getString(const wxChar* key) {
|
wxString Game_Data::getString(const wxChar* key) {
|
||||||
if (curGame) {
|
KeyPairArray::iterator it( kList.begin() );
|
||||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
for ( ; it != kList.end(); ++it) {
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
if (it[0].CompareKey(key)) {
|
||||||
if (it[0].CompareKey(key)) {
|
return it[0].value;
|
||||||
return it[0].value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("(GameDB) Game not set!");
|
|
||||||
return wxString();
|
return wxString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseGameDatabaseVector::writeString(const wxString& key, const wxString& value) {
|
void Game_Data::writeString(const wxString& key, const wxString& value) {
|
||||||
if (key.CmpNoCase(m_baseKey) == 0)
|
KeyPairArray::iterator it( kList.begin() );
|
||||||
curGame = createNewGame(value);
|
for ( ; it != kList.end(); ++it) {
|
||||||
|
if (it[0].CompareKey(key)) {
|
||||||
if (curGame) {
|
if( value.IsEmpty() )
|
||||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
kList.erase(it);
|
||||||
for ( ; it != curGame->kList.end(); ++it) {
|
else
|
||||||
if (it[0].CompareKey(key)) {
|
it[0].value = value;
|
||||||
if( value.IsEmpty() )
|
return;
|
||||||
curGame->kList.erase(it);
|
|
||||||
else
|
|
||||||
it[0].value = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( !value.IsEmpty() ) {
|
|
||||||
curGame->kList.push_back(key_pair(key, value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Console.Error("(GameDB) Game not set!");
|
if( !value.IsEmpty() ) {
|
||||||
|
kList.push_back(key_pair(key, value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a bool value to the specified key
|
// Write a bool value to the specified key
|
||||||
void BaseGameDatabaseVector::writeBool(const wxString& key, bool value) {
|
void Game_Data::writeBool(const wxString& key, bool value) {
|
||||||
writeString(key, value ? L"1" : L"0");
|
writeString(key, value ? L"1" : L"0");
|
||||||
}
|
}
|
|
@ -15,14 +15,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
//#include "Common.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "Utilities/HashMap.h"
|
#include "Utilities/HashMap.h"
|
||||||
|
|
||||||
#include <wx/wfstream.h>
|
#include <wx/wfstream.h>
|
||||||
|
|
||||||
struct key_pair;
|
struct key_pair;
|
||||||
class Game_Data;
|
struct Game_Data;
|
||||||
|
|
||||||
typedef std::vector<key_pair> KeyPairArray;
|
typedef std::vector<key_pair> KeyPairArray;
|
||||||
|
|
||||||
|
@ -70,48 +70,41 @@ struct key_pair {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Game_Data {
|
// --------------------------------------------------------------------------------------
|
||||||
public:
|
// Game_Data
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// This container is more or less required to be a simple struct (POD classification) --
|
||||||
|
// no virtuals and no inheritance. This is because it is used in a std::vector, so POD
|
||||||
|
// makes things... smoother.
|
||||||
|
struct Game_Data
|
||||||
|
{
|
||||||
wxString id; // Serial Identification Code
|
wxString id; // Serial Identification Code
|
||||||
KeyPairArray kList; // List of all (key, value) pairs for game data
|
KeyPairArray kList; // List of all (key, value) pairs for game data
|
||||||
|
|
||||||
public:
|
|
||||||
Game_Data(const wxString& _id = wxEmptyString)
|
Game_Data(const wxString& _id = wxEmptyString)
|
||||||
: id(_id) {}
|
: id(_id) {}
|
||||||
|
|
||||||
void NewSerial( const wxString& _id ) {
|
// Performs a case-insensitive compare of two IDs, returns TRUE if the IDs match
|
||||||
id = _id;
|
// or FALSE if the ids differ in a case-insensitive way.
|
||||||
|
bool CompareId( const wxString& _id ) const {
|
||||||
|
return id.CmpNoCase(_id) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
id.clear();
|
||||||
kList.clear();
|
kList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool keyExists(const wxChar* key);
|
||||||
|
void deleteKey(const wxChar* key);
|
||||||
|
wxString getString(const wxChar* key);
|
||||||
|
void writeString(const wxString& key, const wxString& value);
|
||||||
|
void writeBool(const wxString& key, bool value);
|
||||||
|
|
||||||
bool IsOk() const {
|
bool IsOk() const {
|
||||||
return !id.IsEmpty();
|
return !id.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a case-insensitive compare of two IDs, returns TRUE if the IDs match
|
|
||||||
// or FALSE if the ids differ in a case-insensitive way.
|
|
||||||
bool CompareId( const wxString& _id ) const
|
|
||||||
{
|
|
||||||
return id.CmpNoCase(_id) == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// IGameDatabase
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class IGameDatabase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IGameDatabase() throw() {}
|
|
||||||
|
|
||||||
virtual wxString getBaseKey() const=0;
|
|
||||||
virtual bool gameLoaded()=0;
|
|
||||||
virtual bool setGame(const wxString& id)=0;
|
|
||||||
virtual Game_Data* createNewGame(const wxString& id=wxEmptyString)=0;
|
|
||||||
virtual bool keyExists(const wxChar* key)=0;
|
|
||||||
virtual void deleteKey(const wxChar* key)=0;
|
|
||||||
virtual wxString getString(const wxChar* key)=0;
|
|
||||||
|
|
||||||
bool sectionExists(const wxChar* key, const wxString& value) {
|
bool sectionExists(const wxChar* key, const wxString& value) {
|
||||||
return keyExists(wxsFormat(L"[%s%s%s]", key, value.IsEmpty() ? L"" : L" = ", value.c_str()));
|
return keyExists(wxsFormat(L"[%s%s%s]", key, value.IsEmpty() ? L"" : L" = ", value.c_str()));
|
||||||
}
|
}
|
||||||
|
@ -154,57 +147,62 @@ public:
|
||||||
bool getBool(const char* key) {
|
bool getBool(const char* key) {
|
||||||
return getBool(fromUTF8(key));
|
return getBool(fromUTF8(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes a string of data associated with the specified key to the current
|
|
||||||
// game database. If the key being written is the baseKey, then a new slot is
|
|
||||||
// created to account for it, or the existing slot is set as the current game.
|
|
||||||
//
|
|
||||||
virtual void writeString(const wxString& key, const wxString& value)=0;
|
|
||||||
virtual void writeBool(const wxString& key, bool value)=0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Game_Data> GameDataArray;
|
// --------------------------------------------------------------------------------------
|
||||||
typedef pxDictionary<int> GameDataHash;
|
// IGameDatabase
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class IGameDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IGameDatabase() throw() {}
|
||||||
|
|
||||||
|
virtual wxString getBaseKey() const=0;
|
||||||
|
virtual bool findGame(Game_Data& dest, const wxString& id)=0;
|
||||||
|
virtual void addNewGame(const Game_Data& game)=0;
|
||||||
|
virtual void updateGame(const Game_Data& game)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringHashNoCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StringHashNoCase() {}
|
||||||
|
|
||||||
|
HashTools::hash_key_t operator()( const wxString& src ) const
|
||||||
|
{
|
||||||
|
return HashTools::Hash( (const char *)src.Lower().data(), src.length() * sizeof( wxChar ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<Game_Data> GameDataArray;
|
||||||
|
typedef pxDictionary<int,StringHashNoCase> GameDataHash;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// BaseGameDatabaseVector
|
// BaseGameDatabaseImpl
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// [TODO] Create a version of this that uses google hashsets; should be several magnitudes
|
// [TODO] Create a version of this that uses google hashsets; should be several magnitudes
|
||||||
// faster that way.
|
// faster that way.
|
||||||
class BaseGameDatabaseVector : public IGameDatabase
|
class BaseGameDatabaseImpl : public IGameDatabase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GameDataArray gList; // List of all game data
|
GameDataArray gList; // List of all game data
|
||||||
GameDataHash gHash; // hash table of game serials matched to their gList indexes!
|
GameDataHash gHash; // hash table of game serials matched to their gList indexes!
|
||||||
Game_Data* curGame; // Current game data (index into gList)
|
|
||||||
wxString m_baseKey;
|
wxString m_baseKey;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseGameDatabaseVector()
|
BaseGameDatabaseImpl()
|
||||||
{
|
{
|
||||||
curGame = NULL;
|
|
||||||
m_baseKey = L"Serial";
|
m_baseKey = L"Serial";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BaseGameDatabaseVector() throw() {}
|
virtual ~BaseGameDatabaseImpl() throw() {}
|
||||||
|
|
||||||
wxString getBaseKey() const { return m_baseKey; }
|
wxString getBaseKey() const { return m_baseKey; }
|
||||||
void setBaseKey( const wxString& key ) { m_baseKey = key; }
|
void setBaseKey( const wxString& key ) { m_baseKey = key; }
|
||||||
|
|
||||||
// Returns true if a game is currently loaded into the database
|
bool findGame(Game_Data& dest, const wxString& id);
|
||||||
// Returns false if otherwise (this means you need to call setGame()
|
void addNewGame(const Game_Data& game);
|
||||||
// or it could mean the game was not found in the database at all...)
|
void updateGame(const Game_Data& game);
|
||||||
bool gameLoaded() {
|
|
||||||
return curGame != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setGame(const wxString& id);
|
|
||||||
Game_Data* createNewGame(const wxString& id=wxEmptyString);
|
|
||||||
bool keyExists(const wxChar* key);
|
|
||||||
void deleteKey(const wxChar* key);
|
|
||||||
wxString getString(const wxChar* key);
|
|
||||||
void writeString(const wxString& key, const wxString& value);
|
|
||||||
void writeBool(const wxString& key, bool value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IGameDatabase* AppHost_GetGameDatabase();
|
extern IGameDatabase* AppHost_GetGameDatabase();
|
|
@ -139,13 +139,14 @@ int InitPatches(const wxString& name)
|
||||||
|
|
||||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
|
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
|
||||||
{
|
{
|
||||||
if(GameDB->gameLoaded()) {
|
Game_Data game;
|
||||||
if (GameDB->sectionExists(L"patches", name)) {
|
if (GameDB->findGame(game,name)) {
|
||||||
patch = GameDB->getSection(L"patches", name);
|
if (game.sectionExists(L"patches", name)) {
|
||||||
|
patch = game.getSection(L"patches", name);
|
||||||
patchFound = true;
|
patchFound = true;
|
||||||
}
|
}
|
||||||
else if (GameDB->keyExists(L"[patches]")) {
|
else if (game.keyExists(L"[patches]")) {
|
||||||
patch = GameDB->getString(L"[patches]");
|
patch = game.getString(L"[patches]");
|
||||||
patchFound = true;
|
patchFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ void cpuReset()
|
||||||
g_SkipBiosHack = EmuConfig.UseBOOT2Injection;
|
g_SkipBiosHack = EmuConfig.UseBOOT2Injection;
|
||||||
|
|
||||||
ElfCRC = 0;
|
ElfCRC = 0;
|
||||||
DiscID = L"";
|
DiscSerial = L"";
|
||||||
ElfEntry = -1;
|
ElfEntry = -1;
|
||||||
LastELF = L"";
|
LastELF = L"";
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
// cleaning up these things.
|
// cleaning up these things.
|
||||||
#include "sVU_zerorec.h"
|
#include "sVU_zerorec.h"
|
||||||
#include "GameDatabase.h"
|
#include "GameDatabase.h"
|
||||||
|
#include "Elfheader.h"
|
||||||
|
|
||||||
extern void closeNewVif(int idx);
|
extern void closeNewVif(int idx);
|
||||||
extern void resetNewVif(int idx);
|
extern void resetNewVif(int idx);
|
||||||
|
@ -406,9 +407,9 @@ void SysClearExecutionCache()
|
||||||
// allocation is below a certain memory address (specified in "bounds" parameter).
|
// allocation is below a certain memory address (specified in "bounds" parameter).
|
||||||
// The allocated block has code execution privileges.
|
// The allocated block has code execution privileges.
|
||||||
// Returns NULL on allocation failure.
|
// Returns NULL on allocation failure.
|
||||||
u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
|
u8* SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
|
||||||
{
|
{
|
||||||
u8 *Mem = (u8*)HostSys::Mmap( base, size );
|
u8* Mem = (u8*)HostSys::Mmap( base, size );
|
||||||
|
|
||||||
if( (Mem == NULL) || (bounds != 0 && (((uptr)Mem + size) > bounds)) )
|
if( (Mem == NULL) || (bounds != 0 && (((uptr)Mem + size) > bounds)) )
|
||||||
{
|
{
|
||||||
|
@ -434,3 +435,20 @@ u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
|
||||||
}
|
}
|
||||||
return Mem;
|
return Mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function always returns a valid DiscID -- using the Sony serial when possible, and
|
||||||
|
// falling back on the CRC checksum of the ELF binary if the PS2 software being run is
|
||||||
|
// homebrew or some other serial-less item.
|
||||||
|
wxString SysGetDiscID()
|
||||||
|
{
|
||||||
|
if( !DiscSerial.IsEmpty() ) return DiscSerial;
|
||||||
|
|
||||||
|
if( !ElfCRC )
|
||||||
|
{
|
||||||
|
// FIXME: If the system is currently running the BIOS, it should return a serial based on
|
||||||
|
// the BIOS being run (either a checksum of the BIOS roms, and/or a string based on BIOS
|
||||||
|
// region and revision).
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxsFormat( L"%8.8x", ElfCRC );
|
||||||
|
}
|
||||||
|
|
|
@ -67,11 +67,12 @@ extern SysCoreAllocations& GetSysCoreAlloc();
|
||||||
extern void SysLogMachineCaps(); // Detects cpu type and fills cpuInfo structs.
|
extern void SysLogMachineCaps(); // Detects cpu type and fills cpuInfo structs.
|
||||||
extern void SysClearExecutionCache(); // clears recompiled execution caches!
|
extern void SysClearExecutionCache(); // clears recompiled execution caches!
|
||||||
|
|
||||||
|
|
||||||
extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed");
|
extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed");
|
||||||
extern void vSyncDebugStuff( uint frame );
|
extern void vSyncDebugStuff( uint frame );
|
||||||
extern void NTFS_CompressFile( const wxString& file, bool compressStatus=true );
|
extern void NTFS_CompressFile( const wxString& file, bool compressStatus=true );
|
||||||
|
|
||||||
|
extern wxString SysGetDiscID();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// PCSX2_SEH - Defines existence of "built in" Structured Exception Handling support.
|
// PCSX2_SEH - Defines existence of "built in" Structured Exception Handling support.
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -176,13 +176,14 @@ void AppCoreThread::OnResumeReady()
|
||||||
static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
||||||
if (!gameDB) gameDB = wxGetApp().GetGameDatabase();
|
if (!gameDB) gameDB = wxGetApp().GetGameDatabase();
|
||||||
|
|
||||||
if (!gameDB->gameLoaded()) return 0;
|
Game_Data game;
|
||||||
|
if (!gameDB->findGame(game, SysGetDiscID())) return 0;
|
||||||
|
|
||||||
int gf = 0;
|
int gf = 0;
|
||||||
|
|
||||||
if (gameDB->keyExists("eeRoundMode"))
|
if (game.keyExists("eeRoundMode"))
|
||||||
{
|
{
|
||||||
SSE_RoundMode eeRM = (SSE_RoundMode)gameDB->getInt("eeRoundMode");
|
SSE_RoundMode eeRM = (SSE_RoundMode)game.getInt("eeRoundMode");
|
||||||
if (EnumIsValid(eeRM))
|
if (EnumIsValid(eeRM))
|
||||||
{
|
{
|
||||||
Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM));
|
Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM));
|
||||||
|
@ -191,9 +192,9 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameDB->keyExists("vuRoundMode"))
|
if (game.keyExists("vuRoundMode"))
|
||||||
{
|
{
|
||||||
SSE_RoundMode vuRM = (SSE_RoundMode)gameDB->getInt("vuRoundMode");
|
SSE_RoundMode vuRM = (SSE_RoundMode)game.getInt("vuRoundMode");
|
||||||
if (EnumIsValid(vuRM))
|
if (EnumIsValid(vuRM))
|
||||||
{
|
{
|
||||||
Console.WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM));
|
Console.WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM));
|
||||||
|
@ -202,8 +203,8 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameDB->keyExists("eeClampMode")) {
|
if (game.keyExists("eeClampMode")) {
|
||||||
int clampMode = gameDB->getInt("eeClampMode");
|
int clampMode = game.getInt("eeClampMode");
|
||||||
Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode);
|
Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode);
|
||||||
dest.Recompiler.fpuOverflow = (clampMode >= 1);
|
dest.Recompiler.fpuOverflow = (clampMode >= 1);
|
||||||
dest.Recompiler.fpuExtraOverflow = (clampMode >= 2);
|
dest.Recompiler.fpuExtraOverflow = (clampMode >= 2);
|
||||||
|
@ -211,8 +212,8 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
||||||
gf++;
|
gf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameDB->keyExists("vuClampMode")) {
|
if (game.keyExists("vuClampMode")) {
|
||||||
int clampMode = gameDB->getInt("vuClampMode");
|
int clampMode = game.getInt("vuClampMode");
|
||||||
Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
|
Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
|
||||||
dest.Recompiler.vuOverflow = (clampMode >= 1);
|
dest.Recompiler.vuOverflow = (clampMode >= 1);
|
||||||
dest.Recompiler.vuExtraOverflow = (clampMode >= 2);
|
dest.Recompiler.vuExtraOverflow = (clampMode >= 2);
|
||||||
|
@ -225,9 +226,9 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
||||||
wxString key( EnumToString(id) );
|
wxString key( EnumToString(id) );
|
||||||
key += L"Hack";
|
key += L"Hack";
|
||||||
|
|
||||||
if (gameDB->keyExists(key))
|
if (game.keyExists(key))
|
||||||
{
|
{
|
||||||
bool enableIt = gameDB->getBool(key);
|
bool enableIt = game.getBool(key);
|
||||||
dest.Gamefixes.Set(id, enableIt );
|
dest.Gamefixes.Set(id, enableIt );
|
||||||
Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
||||||
gf++;
|
gf++;
|
||||||
|
@ -252,14 +253,15 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
|
||||||
wxString gameCompat;
|
wxString gameCompat;
|
||||||
|
|
||||||
if (ElfCRC) gameCRC.Printf( L"%8.8x", ElfCRC );
|
if (ElfCRC) gameCRC.Printf( L"%8.8x", ElfCRC );
|
||||||
if (!DiscID.IsEmpty()) gameSerial = L" [" + DiscID + L"]";
|
if (!DiscSerial.IsEmpty()) gameSerial = L" [" + DiscSerial + L"]";
|
||||||
|
|
||||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
|
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
|
||||||
{
|
{
|
||||||
if (GameDB->gameLoaded()) {
|
Game_Data game;
|
||||||
int compat = GameDB->getInt("Compat");
|
if (GameDB->findGame(game, SysGetDiscID())) {
|
||||||
gameName = GameDB->getString("Name");
|
int compat = game.getInt("Compat");
|
||||||
gameName += L" (" + GameDB->getString("Region") + L")";
|
gameName = game.getString("Name");
|
||||||
|
gameName += L" (" + game.getString("Region") + L")";
|
||||||
gameCompat = L" [Status = "+compatToStringWX(compat)+L"]";
|
gameCompat = L" [Status = "+compatToStringWX(compat)+L"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,10 +118,14 @@ wxString DBLoaderHelper::ReadHeader()
|
||||||
|
|
||||||
void DBLoaderHelper::ReadGames()
|
void DBLoaderHelper::ReadGames()
|
||||||
{
|
{
|
||||||
Game_Data* game = m_gamedb.createNewGame();
|
Game_Data game;
|
||||||
|
|
||||||
if (m_keyPair.IsOk())
|
if (m_keyPair.IsOk())
|
||||||
m_gamedb.writeString( m_keyPair.key, m_keyPair.value );
|
{
|
||||||
|
game.writeString(m_keyPair.key, m_keyPair.value);
|
||||||
|
if( m_keyPair.CompareKey(m_gamedb.getBaseKey()) )
|
||||||
|
game.id = m_keyPair.value;
|
||||||
|
}
|
||||||
|
|
||||||
while(!m_reader.Eof()) { // Fill game data, find new game, repeat...
|
while(!m_reader.Eof()) { // Fill game data, find new game, repeat...
|
||||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||||
|
@ -132,7 +136,13 @@ void DBLoaderHelper::ReadGames()
|
||||||
if (!extractMultiLine()) extract();
|
if (!extractMultiLine()) extract();
|
||||||
|
|
||||||
if (!m_keyPair.IsOk()) continue;
|
if (!m_keyPair.IsOk()) continue;
|
||||||
m_gamedb.writeString( m_keyPair.key, m_keyPair.value );
|
if( m_keyPair.CompareKey(m_gamedb.getBaseKey()) )
|
||||||
|
{
|
||||||
|
m_gamedb.addNewGame(game);
|
||||||
|
game.clear();
|
||||||
|
game.id = m_keyPair.value;
|
||||||
|
}
|
||||||
|
game.writeString( m_keyPair.key, m_keyPair.value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +171,6 @@ AppGameDatabase& AppGameDatabase::LoadFromFile(const wxString& file, const wxStr
|
||||||
header = loader.ReadHeader();
|
header = loader.ReadHeader();
|
||||||
loader.ReadGames();
|
loader.ReadGames();
|
||||||
|
|
||||||
curGame = NULL;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
// GameDatabase class's methods to get the other key's values.
|
// GameDatabase 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 AppGameDatabase : public BaseGameDatabaseVector
|
class AppGameDatabase : public BaseGameDatabaseImpl
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
wxString header; // Header of the database
|
wxString header; // Header of the database
|
||||||
|
|
|
@ -30,6 +30,8 @@ void GSPanel::InitDefaultAccelerators()
|
||||||
|
|
||||||
typedef KeyAcceleratorCode AAC;
|
typedef KeyAcceleratorCode AAC;
|
||||||
|
|
||||||
|
if( !m_Accels ) m_Accels = new AcceleratorDictionary;
|
||||||
|
|
||||||
m_Accels->Map( AAC( WXK_F1 ), "States_FreezeCurrentSlot" );
|
m_Accels->Map( AAC( WXK_F1 ), "States_FreezeCurrentSlot" );
|
||||||
m_Accels->Map( AAC( WXK_F3 ), "States_DefrostCurrentSlot");
|
m_Accels->Map( AAC( WXK_F3 ), "States_DefrostCurrentSlot");
|
||||||
m_Accels->Map( AAC( WXK_F2 ), "States_CycleSlotForward" );
|
m_Accels->Map( AAC( WXK_F2 ), "States_CycleSlotForward" );
|
||||||
|
|
|
@ -366,7 +366,7 @@ namespace Panels
|
||||||
void AppStatusEvent_OnSettingsApplied();
|
void AppStatusEvent_OnSettingsApplied();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PopulateFields();
|
void PopulateFields( const wxString& serial=wxEmptyString );
|
||||||
bool WriteFieldsToDB();
|
bool WriteFieldsToDB();
|
||||||
void Search_Click( wxCommandEvent& evt );
|
void Search_Click( wxCommandEvent& evt );
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "AppGameDatabase.h"
|
#include "AppGameDatabase.h"
|
||||||
#include "ConfigurationPanels.h"
|
#include "ConfigurationPanels.h"
|
||||||
|
|
||||||
extern wxString DiscID;
|
extern wxString DiscSerial;
|
||||||
using namespace pxSizerFlags;
|
using namespace pxSizerFlags;
|
||||||
|
|
||||||
#define blankLine() { \
|
#define blankLine() { \
|
||||||
|
@ -43,7 +43,6 @@ wxTextCtrl* CreateMultiLineTextCtrl( wxWindow* parent, int digits, long flags =
|
||||||
Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
||||||
: BaseApplicableConfigPanel( parent )
|
: BaseApplicableConfigPanel( parent )
|
||||||
{
|
{
|
||||||
//if (!GameDB) GameDB = new GameDatabase();
|
|
||||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||||
pxAssume( GameDB != NULL );
|
pxAssume( GameDB != NULL );
|
||||||
|
|
||||||
|
@ -96,33 +95,36 @@ Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
||||||
PopulateFields();
|
PopulateFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::PopulateFields() {
|
void Panels::GameDatabasePanel::PopulateFields( const wxString& id ) {
|
||||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||||
|
if (!pxAssert(GameDB)) return;
|
||||||
|
|
||||||
if (GameDB->gameLoaded()) {
|
Game_Data game;
|
||||||
serialBox ->SetLabel(GameDB->getString("Serial"));
|
if (GameDB->findGame(game, id.IsEmpty() ? SysGetDiscID() : id))
|
||||||
nameBox ->SetLabel(GameDB->getString("Name"));
|
{
|
||||||
regionBox ->SetLabel(GameDB->getString("Region"));
|
serialBox ->SetLabel(game.getString("Serial"));
|
||||||
compatBox ->SetLabel(GameDB->getString("Compat"));
|
nameBox ->SetLabel(game.getString("Name"));
|
||||||
commentBox->SetLabel(GameDB->getString("[comments]"));
|
regionBox ->SetLabel(game.getString("Region"));
|
||||||
patchesBox->SetLabel(GameDB->getString("[patches]"));
|
compatBox ->SetLabel(game.getString("Compat"));
|
||||||
|
commentBox->SetLabel(game.getString("[comments]"));
|
||||||
|
patchesBox->SetLabel(game.getString("[patches]"));
|
||||||
|
|
||||||
for (GamefixId i=GamefixId_FIRST; i < pxEnumEnd; ++i)
|
for (GamefixId i=GamefixId_FIRST; i < pxEnumEnd; ++i)
|
||||||
{
|
{
|
||||||
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
||||||
if( GameDB->keyExists(keyName) )
|
if( game.keyExists(keyName) )
|
||||||
gameFixes[i]->SetValue(GameDB->getBool(keyName));
|
gameFixes[i]->SetValue(game.getBool(keyName));
|
||||||
else
|
else
|
||||||
gameFixes[i]->SetIndeterminate();
|
gameFixes[i]->SetIndeterminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serialBox ->SetLabel(L"");
|
serialBox ->SetLabel(wxEmptyString);
|
||||||
nameBox ->SetLabel(L"");
|
nameBox ->SetLabel(wxEmptyString);
|
||||||
regionBox ->SetLabel(L"");
|
regionBox ->SetLabel(wxEmptyString);
|
||||||
compatBox ->SetLabel(L"");
|
compatBox ->SetLabel(wxEmptyString);
|
||||||
commentBox->SetLabel(L"");
|
commentBox->SetLabel(wxEmptyString);
|
||||||
patchesBox->SetLabel(L"");
|
patchesBox->SetLabel(wxEmptyString);
|
||||||
for (int i = 0; i < GamefixId_COUNT; i++) {
|
for (int i = 0; i < GamefixId_COUNT; i++) {
|
||||||
gameFixes[i]->SetValue(0);
|
gameFixes[i]->SetValue(0);
|
||||||
}
|
}
|
||||||
|
@ -137,40 +139,39 @@ void Panels::GameDatabasePanel::PopulateFields() {
|
||||||
// returns True if the database is modified, or FALSE if no changes to save.
|
// returns True if the database is modified, or FALSE if no changes to save.
|
||||||
bool Panels::GameDatabasePanel::WriteFieldsToDB() {
|
bool Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||||
|
if (!GameDB) return false;
|
||||||
|
|
||||||
if (serialBox->GetValue().IsEmpty()) return false;
|
if (serialBox->GetValue().IsEmpty()) return false;
|
||||||
|
|
||||||
// Only write the serial if its been changed
|
Game_Data game;
|
||||||
if( !GameDB->setGame(serialBox->GetValue()) )
|
GameDB->findGame(game, serialBox->GetValue());
|
||||||
GameDB->writeString(L"Serial", serialBox->GetValue());
|
|
||||||
|
|
||||||
GameDB->writeString(L"Name", nameBox->GetValue());
|
game.id = serialBox->GetValue();
|
||||||
GameDB->writeString(L"Region", regionBox->GetValue());
|
|
||||||
GameDB->writeString(L"Compat", compatBox->GetValue());
|
game.writeString(L"Serial", serialBox->GetValue());
|
||||||
GameDB->writeString(L"[comments]", commentBox->GetValue());
|
game.writeString(L"Name", nameBox->GetValue());
|
||||||
GameDB->writeString(L"[patches]", patchesBox->GetValue());
|
game.writeString(L"Region", regionBox->GetValue());
|
||||||
|
game.writeString(L"Compat", compatBox->GetValue());
|
||||||
|
game.writeString(L"[comments]", commentBox->GetValue());
|
||||||
|
game.writeString(L"[patches]", patchesBox->GetValue());
|
||||||
|
|
||||||
for (GamefixId i=GamefixId_FIRST; i < pxEnumEnd; ++i) {
|
for (GamefixId i=GamefixId_FIRST; i < pxEnumEnd; ++i) {
|
||||||
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
||||||
|
|
||||||
if (gameFixes[i]->IsIndeterminate())
|
if (gameFixes[i]->IsIndeterminate())
|
||||||
GameDB->deleteKey(keyName);
|
game.deleteKey(keyName);
|
||||||
else
|
else
|
||||||
GameDB->writeBool(keyName, gameFixes[i]->GetValue());
|
game.writeBool(keyName, gameFixes[i]->GetValue());
|
||||||
}
|
}
|
||||||
|
GameDB->updateGame(game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
||||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||||
wxString wxStr = serialBox->GetValue();
|
if( !GameDB ) return;
|
||||||
|
|
||||||
if( wxStr.IsEmpty() ) wxStr = DiscID;
|
PopulateFields( serialBox->GetValue() );
|
||||||
|
|
||||||
bool bySerial = 1;//searchType->GetSelection()==0;
|
|
||||||
if (bySerial) GameDB->setGame(wxStr);
|
|
||||||
|
|
||||||
PopulateFields();
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,6 @@ typedef signed long long int64;
|
||||||
|
|
||||||
// directx
|
// directx
|
||||||
|
|
||||||
//#include <ddraw.h>
|
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
|
Loading…
Reference in New Issue