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
|
||||
{
|
||||
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.
|
||||
|
@ -555,12 +555,12 @@ public:
|
|||
/// matter, don't use this class at all! Use the string-specialized classes <see cref="Dictionary" /> and
|
||||
/// <see cref="UnicodeDictionary" />.
|
||||
/// </remarks>
|
||||
template< class Key, class T >
|
||||
class HashMap : public google::dense_hash_map<Key, T, CommonHashClass>
|
||||
template< class Key, class T, class HashFunctor=CommonHashClass >
|
||||
class HashMap : public google::dense_hash_map<Key, T, HashFunctor>
|
||||
{
|
||||
DeclareNoncopyableObject( HashMap );
|
||||
|
||||
typedef typename google::dense_hash_map<Key, T, CommonHashClass> _parent;
|
||||
typedef typename google::dense_hash_map<Key, T, HashFunctor> _parent;
|
||||
|
||||
public:
|
||||
using _parent::operator[];
|
||||
|
@ -577,7 +577,7 @@ public:
|
|||
/// are *not* used as actual values in the set.
|
||||
/// </remarks>
|
||||
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_deleted_key( deletedKey );
|
||||
|
@ -653,14 +653,14 @@ public:
|
|||
|
||||
}
|
||||
|
||||
template< class T >
|
||||
class pxDictionary : public HashTools::HashMap<wxString, T>
|
||||
template< class T, class HashFunctor=HashTools::CommonHashClass >
|
||||
class pxDictionary : public HashTools::HashMap<wxString, T, HashFunctor>
|
||||
{
|
||||
public:
|
||||
virtual ~pxDictionary() {}
|
||||
|
||||
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 "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;
|
||||
|
||||
|
@ -340,9 +344,9 @@ static __forceinline void _reloadElfInfo(wxString elfpath)
|
|||
if (!fname)
|
||||
fname = elfpath.AfterLast(':');
|
||||
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);
|
||||
|
||||
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...
|
||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase()) {
|
||||
wxString gameSerial = DiscID;
|
||||
if (gameSerial.IsEmpty()) { // Search for crc if no Serial Code
|
||||
gameSerial = wxsFormat( L"%8.8x", ElfCRC );
|
||||
}
|
||||
|
||||
wxString gameSerial( SysGetDiscID() );
|
||||
wxString serialMsg;
|
||||
if(!DiscID.IsEmpty())
|
||||
serialMsg = L"serial=" + DiscID + L" ";
|
||||
if(!DiscSerial.IsEmpty())
|
||||
serialMsg = L"serial=" + DiscSerial + L" ";
|
||||
|
||||
//Game_Data CurrentGame;
|
||||
//if (GameDB->getGame(CurrentGame, gameSerial))
|
||||
if (GameDB->setGame(gameSerial))
|
||||
Game_Data game;
|
||||
if (GameDB->findGame(game, gameSerial))
|
||||
{
|
||||
Console.WriteLn(L"(GameDB) Found Game! %s [CRC=%8.8x]", serialMsg.c_str(), ElfCRC );
|
||||
// [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();
|
||||
|
||||
// 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
|
||||
// to make the 4 letters fit into a single u32
|
||||
letters = (s32)((DiscID[3]&0x7F)<< 0) |
|
||||
(s32)((DiscID[2]&0x7F)<< 7) |
|
||||
(s32)((DiscID[1]&0x7F)<<14) |
|
||||
(s32)((DiscID[0]&0x7F)<<21);
|
||||
letters = (s32)((DiscSerial[3]&0x7F)<< 0) |
|
||||
(s32)((DiscSerial[2]&0x7F)<< 7) |
|
||||
(s32)((DiscSerial[1]&0x7F)<<14) |
|
||||
(s32)((DiscSerial[0]&0x7F)<<21);
|
||||
|
||||
// calculate magic numbers
|
||||
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 wxString DiscID;
|
||||
extern wxString DiscSerial;
|
||||
|
|
|
@ -18,89 +18,88 @@
|
|||
|
||||
// Sets the current game to the one matching the serial id given
|
||||
// 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) );
|
||||
if( iter == gHash.end() ) {
|
||||
curGame = NULL;
|
||||
dest.clear();
|
||||
return false;
|
||||
}
|
||||
curGame = &gList[iter->second];
|
||||
dest = gList[iter->second];
|
||||
return true;
|
||||
}
|
||||
|
||||
Game_Data* BaseGameDatabaseVector::createNewGame(const wxString& id) {
|
||||
gList.push_back(Game_Data(id));
|
||||
gHash[id] = gList.size()-1;
|
||||
curGame = &(gList.end()-1)[0];
|
||||
return curGame;
|
||||
void BaseGameDatabaseImpl::addNewGame(const Game_Data& game)
|
||||
{
|
||||
gList.push_back(game);
|
||||
gHash[game.id] = gList.size()-1;
|
||||
}
|
||||
|
||||
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
|
||||
bool BaseGameDatabaseVector::keyExists(const wxChar* key) {
|
||||
if (curGame) {
|
||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
||||
for ( ; it != curGame->kList.end(); ++it) {
|
||||
bool Game_Data::keyExists(const wxChar* key) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it[0].CompareKey(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else Console.Error("(GameDB) Game not set!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Totally Deletes the specified key/pair value from the current game's data
|
||||
void BaseGameDatabaseVector::deleteKey(const wxChar* key) {
|
||||
if (curGame) {
|
||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
||||
for ( ; it != curGame->kList.end(); ++it) {
|
||||
void Game_Data::deleteKey(const wxChar* key) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it[0].CompareKey(key)) {
|
||||
curGame->kList.erase(it);
|
||||
kList.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else Console.Error("(GameDB) Game not set!");
|
||||
}
|
||||
|
||||
// Gets a string representation of the 'value' for the given key
|
||||
wxString BaseGameDatabaseVector::getString(const wxChar* key) {
|
||||
if (curGame) {
|
||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
||||
for ( ; it != curGame->kList.end(); ++it) {
|
||||
wxString Game_Data::getString(const wxChar* key) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it[0].CompareKey(key)) {
|
||||
return it[0].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else Console.Error("(GameDB) Game not set!");
|
||||
return wxString();
|
||||
}
|
||||
|
||||
void BaseGameDatabaseVector::writeString(const wxString& key, const wxString& value) {
|
||||
if (key.CmpNoCase(m_baseKey) == 0)
|
||||
curGame = createNewGame(value);
|
||||
|
||||
if (curGame) {
|
||||
KeyPairArray::iterator it( curGame->kList.begin() );
|
||||
for ( ; it != curGame->kList.end(); ++it) {
|
||||
void Game_Data::writeString(const wxString& key, const wxString& value) {
|
||||
KeyPairArray::iterator it( kList.begin() );
|
||||
for ( ; it != kList.end(); ++it) {
|
||||
if (it[0].CompareKey(key)) {
|
||||
if( value.IsEmpty() )
|
||||
curGame->kList.erase(it);
|
||||
kList.erase(it);
|
||||
else
|
||||
it[0].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( !value.IsEmpty() ) {
|
||||
curGame->kList.push_back(key_pair(key, value));
|
||||
kList.push_back(key_pair(key, value));
|
||||
}
|
||||
}
|
||||
else Console.Error("(GameDB) Game not set!");
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
|
@ -15,14 +15,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
//#include "Common.h"
|
||||
#include "AppConfig.h"
|
||||
#include "Utilities/HashMap.h"
|
||||
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
struct key_pair;
|
||||
class Game_Data;
|
||||
struct Game_Data;
|
||||
|
||||
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
|
||||
KeyPairArray kList; // List of all (key, value) pairs for game data
|
||||
|
||||
public:
|
||||
Game_Data(const wxString& _id = wxEmptyString)
|
||||
: id(_id) {}
|
||||
|
||||
void NewSerial( const wxString& _id ) {
|
||||
id = _id;
|
||||
// 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;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
id.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 {
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
// --------------------------------------------------------------------------------------
|
||||
// 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> GameDataHash;
|
||||
typedef pxDictionary<int,StringHashNoCase> GameDataHash;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseGameDatabaseVector
|
||||
// BaseGameDatabaseImpl
|
||||
// --------------------------------------------------------------------------------------
|
||||
// [TODO] Create a version of this that uses google hashsets; should be several magnitudes
|
||||
// faster that way.
|
||||
class BaseGameDatabaseVector : public IGameDatabase
|
||||
class BaseGameDatabaseImpl : public IGameDatabase
|
||||
{
|
||||
public:
|
||||
GameDataArray gList; // List of all game data
|
||||
GameDataHash gHash; // hash table of game serials matched to their gList indexes!
|
||||
Game_Data* curGame; // Current game data (index into gList)
|
||||
wxString m_baseKey;
|
||||
|
||||
public:
|
||||
BaseGameDatabaseVector()
|
||||
BaseGameDatabaseImpl()
|
||||
{
|
||||
curGame = NULL;
|
||||
m_baseKey = L"Serial";
|
||||
}
|
||||
|
||||
virtual ~BaseGameDatabaseVector() throw() {}
|
||||
virtual ~BaseGameDatabaseImpl() throw() {}
|
||||
|
||||
wxString getBaseKey() const { return m_baseKey; }
|
||||
void setBaseKey( const wxString& key ) { m_baseKey = key; }
|
||||
|
||||
// Returns true if a game is currently loaded into the database
|
||||
// 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...)
|
||||
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);
|
||||
bool findGame(Game_Data& dest, const wxString& id);
|
||||
void addNewGame(const Game_Data& game);
|
||||
void updateGame(const Game_Data& game);
|
||||
};
|
||||
|
||||
extern IGameDatabase* AppHost_GetGameDatabase();
|
|
@ -139,13 +139,14 @@ int InitPatches(const wxString& name)
|
|||
|
||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase() )
|
||||
{
|
||||
if(GameDB->gameLoaded()) {
|
||||
if (GameDB->sectionExists(L"patches", name)) {
|
||||
patch = GameDB->getSection(L"patches", name);
|
||||
Game_Data game;
|
||||
if (GameDB->findGame(game,name)) {
|
||||
if (game.sectionExists(L"patches", name)) {
|
||||
patch = game.getSection(L"patches", name);
|
||||
patchFound = true;
|
||||
}
|
||||
else if (GameDB->keyExists(L"[patches]")) {
|
||||
patch = GameDB->getString(L"[patches]");
|
||||
else if (game.keyExists(L"[patches]")) {
|
||||
patch = game.getString(L"[patches]");
|
||||
patchFound = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ void cpuReset()
|
|||
g_SkipBiosHack = EmuConfig.UseBOOT2Injection;
|
||||
|
||||
ElfCRC = 0;
|
||||
DiscID = L"";
|
||||
DiscSerial = L"";
|
||||
ElfEntry = -1;
|
||||
LastELF = L"";
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
// cleaning up these things.
|
||||
#include "sVU_zerorec.h"
|
||||
#include "GameDatabase.h"
|
||||
#include "Elfheader.h"
|
||||
|
||||
extern void closeNewVif(int idx);
|
||||
extern void resetNewVif(int idx);
|
||||
|
@ -406,9 +407,9 @@ void SysClearExecutionCache()
|
|||
// allocation is below a certain memory address (specified in "bounds" parameter).
|
||||
// The allocated block has code execution privileges.
|
||||
// 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)) )
|
||||
{
|
||||
|
@ -434,3 +435,20 @@ u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
|
|||
}
|
||||
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 SysClearExecutionCache(); // clears recompiled execution caches!
|
||||
|
||||
|
||||
extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed");
|
||||
extern void vSyncDebugStuff( uint frame );
|
||||
extern void NTFS_CompressFile( const wxString& file, bool compressStatus=true );
|
||||
|
||||
extern wxString SysGetDiscID();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// 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) {
|
||||
if (!gameDB) gameDB = wxGetApp().GetGameDatabase();
|
||||
|
||||
if (!gameDB->gameLoaded()) return 0;
|
||||
Game_Data game;
|
||||
if (!gameDB->findGame(game, SysGetDiscID())) return 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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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")) {
|
||||
int clampMode = gameDB->getInt("eeClampMode");
|
||||
if (game.keyExists("eeClampMode")) {
|
||||
int clampMode = game.getInt("eeClampMode");
|
||||
Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode);
|
||||
dest.Recompiler.fpuOverflow = (clampMode >= 1);
|
||||
dest.Recompiler.fpuExtraOverflow = (clampMode >= 2);
|
||||
|
@ -211,8 +212,8 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
|||
gf++;
|
||||
}
|
||||
|
||||
if (gameDB->keyExists("vuClampMode")) {
|
||||
int clampMode = gameDB->getInt("vuClampMode");
|
||||
if (game.keyExists("vuClampMode")) {
|
||||
int clampMode = game.getInt("vuClampMode");
|
||||
Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode);
|
||||
dest.Recompiler.vuOverflow = (clampMode >= 1);
|
||||
dest.Recompiler.vuExtraOverflow = (clampMode >= 2);
|
||||
|
@ -225,9 +226,9 @@ static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) {
|
|||
wxString key( EnumToString(id) );
|
||||
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 );
|
||||
Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
||||
gf++;
|
||||
|
@ -252,14 +253,15 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
|
|||
wxString gameCompat;
|
||||
|
||||
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 (GameDB->gameLoaded()) {
|
||||
int compat = GameDB->getInt("Compat");
|
||||
gameName = GameDB->getString("Name");
|
||||
gameName += L" (" + GameDB->getString("Region") + L")";
|
||||
Game_Data game;
|
||||
if (GameDB->findGame(game, SysGetDiscID())) {
|
||||
int compat = game.getInt("Compat");
|
||||
gameName = game.getString("Name");
|
||||
gameName += L" (" + game.getString("Region") + L")";
|
||||
gameCompat = L" [Status = "+compatToStringWX(compat)+L"]";
|
||||
}
|
||||
|
||||
|
|
|
@ -118,10 +118,14 @@ wxString DBLoaderHelper::ReadHeader()
|
|||
|
||||
void DBLoaderHelper::ReadGames()
|
||||
{
|
||||
Game_Data* game = m_gamedb.createNewGame();
|
||||
Game_Data game;
|
||||
|
||||
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...
|
||||
pxReadLine(m_reader, m_dest, m_intermediate);
|
||||
|
@ -132,7 +136,13 @@ void DBLoaderHelper::ReadGames()
|
|||
if (!extractMultiLine()) extract();
|
||||
|
||||
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();
|
||||
loader.ReadGames();
|
||||
|
||||
curGame = NULL;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
// GameDatabase class's methods to get the other key's values.
|
||||
// Such as dbLoader.getString("Region") returns "NTSC-U"
|
||||
|
||||
class AppGameDatabase : public BaseGameDatabaseVector
|
||||
class AppGameDatabase : public BaseGameDatabaseImpl
|
||||
{
|
||||
protected:
|
||||
wxString header; // Header of the database
|
||||
|
|
|
@ -30,6 +30,8 @@ void GSPanel::InitDefaultAccelerators()
|
|||
|
||||
typedef KeyAcceleratorCode AAC;
|
||||
|
||||
if( !m_Accels ) m_Accels = new AcceleratorDictionary;
|
||||
|
||||
m_Accels->Map( AAC( WXK_F1 ), "States_FreezeCurrentSlot" );
|
||||
m_Accels->Map( AAC( WXK_F3 ), "States_DefrostCurrentSlot");
|
||||
m_Accels->Map( AAC( WXK_F2 ), "States_CycleSlotForward" );
|
||||
|
|
|
@ -366,7 +366,7 @@ namespace Panels
|
|||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
||||
protected:
|
||||
void PopulateFields();
|
||||
void PopulateFields( const wxString& serial=wxEmptyString );
|
||||
bool WriteFieldsToDB();
|
||||
void Search_Click( wxCommandEvent& evt );
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "AppGameDatabase.h"
|
||||
#include "ConfigurationPanels.h"
|
||||
|
||||
extern wxString DiscID;
|
||||
extern wxString DiscSerial;
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
#define blankLine() { \
|
||||
|
@ -43,7 +43,6 @@ wxTextCtrl* CreateMultiLineTextCtrl( wxWindow* parent, int digits, long flags =
|
|||
Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
||||
: BaseApplicableConfigPanel( parent )
|
||||
{
|
||||
//if (!GameDB) GameDB = new GameDatabase();
|
||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||
pxAssume( GameDB != NULL );
|
||||
|
||||
|
@ -96,33 +95,36 @@ Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
|||
PopulateFields();
|
||||
}
|
||||
|
||||
void Panels::GameDatabasePanel::PopulateFields() {
|
||||
void Panels::GameDatabasePanel::PopulateFields( const wxString& id ) {
|
||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||
if (!pxAssert(GameDB)) return;
|
||||
|
||||
if (GameDB->gameLoaded()) {
|
||||
serialBox ->SetLabel(GameDB->getString("Serial"));
|
||||
nameBox ->SetLabel(GameDB->getString("Name"));
|
||||
regionBox ->SetLabel(GameDB->getString("Region"));
|
||||
compatBox ->SetLabel(GameDB->getString("Compat"));
|
||||
commentBox->SetLabel(GameDB->getString("[comments]"));
|
||||
patchesBox->SetLabel(GameDB->getString("[patches]"));
|
||||
Game_Data game;
|
||||
if (GameDB->findGame(game, id.IsEmpty() ? SysGetDiscID() : id))
|
||||
{
|
||||
serialBox ->SetLabel(game.getString("Serial"));
|
||||
nameBox ->SetLabel(game.getString("Name"));
|
||||
regionBox ->SetLabel(game.getString("Region"));
|
||||
compatBox ->SetLabel(game.getString("Compat"));
|
||||
commentBox->SetLabel(game.getString("[comments]"));
|
||||
patchesBox->SetLabel(game.getString("[patches]"));
|
||||
|
||||
for (GamefixId i=GamefixId_FIRST; i < pxEnumEnd; ++i)
|
||||
{
|
||||
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
||||
if( GameDB->keyExists(keyName) )
|
||||
gameFixes[i]->SetValue(GameDB->getBool(keyName));
|
||||
if( game.keyExists(keyName) )
|
||||
gameFixes[i]->SetValue(game.getBool(keyName));
|
||||
else
|
||||
gameFixes[i]->SetIndeterminate();
|
||||
}
|
||||
}
|
||||
else {
|
||||
serialBox ->SetLabel(L"");
|
||||
nameBox ->SetLabel(L"");
|
||||
regionBox ->SetLabel(L"");
|
||||
compatBox ->SetLabel(L"");
|
||||
commentBox->SetLabel(L"");
|
||||
patchesBox->SetLabel(L"");
|
||||
serialBox ->SetLabel(wxEmptyString);
|
||||
nameBox ->SetLabel(wxEmptyString);
|
||||
regionBox ->SetLabel(wxEmptyString);
|
||||
compatBox ->SetLabel(wxEmptyString);
|
||||
commentBox->SetLabel(wxEmptyString);
|
||||
patchesBox->SetLabel(wxEmptyString);
|
||||
for (int i = 0; i < GamefixId_COUNT; i++) {
|
||||
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.
|
||||
bool Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||
if (!GameDB) return false;
|
||||
|
||||
if (serialBox->GetValue().IsEmpty()) return false;
|
||||
|
||||
// Only write the serial if its been changed
|
||||
if( !GameDB->setGame(serialBox->GetValue()) )
|
||||
GameDB->writeString(L"Serial", serialBox->GetValue());
|
||||
Game_Data game;
|
||||
GameDB->findGame(game, serialBox->GetValue());
|
||||
|
||||
GameDB->writeString(L"Name", nameBox->GetValue());
|
||||
GameDB->writeString(L"Region", regionBox->GetValue());
|
||||
GameDB->writeString(L"Compat", compatBox->GetValue());
|
||||
GameDB->writeString(L"[comments]", commentBox->GetValue());
|
||||
GameDB->writeString(L"[patches]", patchesBox->GetValue());
|
||||
game.id = serialBox->GetValue();
|
||||
|
||||
game.writeString(L"Serial", serialBox->GetValue());
|
||||
game.writeString(L"Name", nameBox->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) {
|
||||
wxString keyName (EnumToString(i)); keyName += L"Hack";
|
||||
|
||||
if (gameFixes[i]->IsIndeterminate())
|
||||
GameDB->deleteKey(keyName);
|
||||
game.deleteKey(keyName);
|
||||
else
|
||||
GameDB->writeBool(keyName, gameFixes[i]->GetValue());
|
||||
game.writeBool(keyName, gameFixes[i]->GetValue());
|
||||
}
|
||||
GameDB->updateGame(game);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||
wxString wxStr = serialBox->GetValue();
|
||||
if( !GameDB ) return;
|
||||
|
||||
if( wxStr.IsEmpty() ) wxStr = DiscID;
|
||||
|
||||
bool bySerial = 1;//searchType->GetSelection()==0;
|
||||
if (bySerial) GameDB->setGame(wxStr);
|
||||
|
||||
PopulateFields();
|
||||
PopulateFields( serialBox->GetValue() );
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,6 @@ typedef signed long long int64;
|
|||
|
||||
// directx
|
||||
|
||||
//#include <ddraw.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3d9.h>
|
||||
|
|
Loading…
Reference in New Issue