From 2c7269e3de196388d67cb44c4f302a71fc54972e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Fri, 28 Mar 2014 05:20:13 +0100 Subject: [PATCH] PSF Loader improved & issue #126 fixed * Improved PSF Loader: Now you can get the value of the PARAM.SFO entries directly with the GetString(key), GetInteger(key) methods. GameInfo related lines were removed since they have nothing to do with PSF files. * cellGame, cellSysutil, and GameViewer are modified because of the PSF Loader changes. * Removed unnecessary null pointer checks: https://github.com/DHrpcs3/rpcs3/issues/126 --- rpcs3/Emu/Audio/AudioManager.cpp | 7 +- rpcs3/Emu/Cell/PPUThread.cpp | 7 +- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 83 ++++++++++------------ rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 16 +++-- rpcs3/Gui/GameViewer.cpp | 22 ++++-- rpcs3/Gui/GameViewer.h | 7 +- rpcs3/Loader/PSF.cpp | 72 +++++++++---------- rpcs3/Loader/PSF.h | 42 +++++------ rpcs3/rpcs3qt/glviewer.cpp | 6 +- 9 files changed, 128 insertions(+), 134 deletions(-) diff --git a/rpcs3/Emu/Audio/AudioManager.cpp b/rpcs3/Emu/Audio/AudioManager.cpp index eb0e094cc2..f0cbfc0d78 100644 --- a/rpcs3/Emu/Audio/AudioManager.cpp +++ b/rpcs3/Emu/Audio/AudioManager.cpp @@ -23,11 +23,8 @@ void AudioManager::Init() void AudioManager::Close() { - if(m_audio_out) - { - delete m_audio_out; - m_audio_out = nullptr; - } + delete m_audio_out; + m_audio_out = nullptr; } u8 AudioManager::GetState() diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index bd6c6570e5..05405efc13 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -165,11 +165,8 @@ void PPUThread::DoPause() void PPUThread::DoStop() { - if(m_dec) - { - delete m_dec; - m_dec = nullptr; - } + delete m_dec; + m_dec = nullptr; } bool dump_enable = false; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 2f0539052f..fed9c0dc34 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -133,9 +133,9 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t contentInfoPath, mem_list_ptr_t buf, u32 bufsize) +int cellGameGetParamString(u32 id, u32 buf_addr, u32 bufsize) { - cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.GetAddr(), bufsize); + cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf_addr, bufsize); - if(!buf.IsGood()) + if(!Memory.IsGoodAddr(buf_addr)) return CELL_GAME_ERROR_PARAM; // TODO: Locate the PARAM.SFO. The following path may be wrong. @@ -223,46 +223,41 @@ int cellGameGetParamString(u32 id, mem_list_ptr_t buf, u32 bufsize) if(!psf.Load(false)) return CELL_GAME_ERROR_FAILURE; + std::string data; switch(id) { - // WARNING: Is there any difference between all these "CELL_GAME_PARAMID_TITLE*" IDs? - case CELL_GAME_PARAMID_TITLE: - case CELL_GAME_PARAMID_TITLE_DEFAULT: - case CELL_GAME_PARAMID_TITLE_JAPANESE: - case CELL_GAME_PARAMID_TITLE_ENGLISH: - case CELL_GAME_PARAMID_TITLE_FRENCH: - case CELL_GAME_PARAMID_TITLE_SPANISH: - case CELL_GAME_PARAMID_TITLE_GERMAN: - case CELL_GAME_PARAMID_TITLE_ITALIAN: - case CELL_GAME_PARAMID_TITLE_DUTCH: - case CELL_GAME_PARAMID_TITLE_PORTUGUESE: - case CELL_GAME_PARAMID_TITLE_RUSSIAN: - case CELL_GAME_PARAMID_TITLE_KOREAN: - case CELL_GAME_PARAMID_TITLE_CHINESE_T: - case CELL_GAME_PARAMID_TITLE_CHINESE_S: - case CELL_GAME_PARAMID_TITLE_FINNISH: - case CELL_GAME_PARAMID_TITLE_SWEDISH: - case CELL_GAME_PARAMID_TITLE_DANISH: - case CELL_GAME_PARAMID_TITLE_NORWEGIAN: - case CELL_GAME_PARAMID_TITLE_POLISH: - case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: - case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: - Memory.WriteString(buf.GetAddr(), psf.m_info.name.Left(bufsize)); - break; - case CELL_GAME_PARAMID_TITLE_ID: - Memory.WriteString(buf.GetAddr(), psf.m_info.serial.Left(bufsize)); - break; - case CELL_GAME_PARAMID_VERSION: - Memory.WriteString(buf.GetAddr(), psf.m_info.fw.Left(bufsize)); - break; - case CELL_GAME_PARAMID_APP_VER: - Memory.WriteString(buf.GetAddr(), psf.m_info.app_ver.Left(bufsize)); - break; + case CELL_GAME_PARAMID_TITLE: data = psf.GetString("TITLE"); break; // TODO: Is this value correct? + case CELL_GAME_PARAMID_TITLE_DEFAULT: data = psf.GetString("TITLE"); break; + case CELL_GAME_PARAMID_TITLE_JAPANESE: data = psf.GetString("TITLE_00"); break; + case CELL_GAME_PARAMID_TITLE_ENGLISH: data = psf.GetString("TITLE_01"); break; + case CELL_GAME_PARAMID_TITLE_FRENCH: data = psf.GetString("TITLE_02"); break; + case CELL_GAME_PARAMID_TITLE_SPANISH: data = psf.GetString("TITLE_03"); break; + case CELL_GAME_PARAMID_TITLE_GERMAN: data = psf.GetString("TITLE_04"); break; + case CELL_GAME_PARAMID_TITLE_ITALIAN: data = psf.GetString("TITLE_05"); break; + case CELL_GAME_PARAMID_TITLE_DUTCH: data = psf.GetString("TITLE_06"); break; + case CELL_GAME_PARAMID_TITLE_PORTUGUESE: data = psf.GetString("TITLE_07"); break; + case CELL_GAME_PARAMID_TITLE_RUSSIAN: data = psf.GetString("TITLE_08"); break; + case CELL_GAME_PARAMID_TITLE_KOREAN: data = psf.GetString("TITLE_09"); break; + case CELL_GAME_PARAMID_TITLE_CHINESE_T: data = psf.GetString("TITLE_10"); break; + case CELL_GAME_PARAMID_TITLE_CHINESE_S: data = psf.GetString("TITLE_11"); break; + case CELL_GAME_PARAMID_TITLE_FINNISH: data = psf.GetString("TITLE_12"); break; + case CELL_GAME_PARAMID_TITLE_SWEDISH: data = psf.GetString("TITLE_13"); break; + case CELL_GAME_PARAMID_TITLE_DANISH: data = psf.GetString("TITLE_14"); break; + case CELL_GAME_PARAMID_TITLE_NORWEGIAN: data = psf.GetString("TITLE_15"); break; + case CELL_GAME_PARAMID_TITLE_POLISH: data = psf.GetString("TITLE_16"); break; + case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: data = psf.GetString("TITLE_17"); break; + case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: data = psf.GetString("TITLE_18"); break; + + case CELL_GAME_PARAMID_TITLE_ID: data = psf.GetString("TITLE_ID"); break; + case CELL_GAME_PARAMID_VERSION: data = psf.GetString("PS3_SYSTEM_VER"); break; + case CELL_GAME_PARAMID_APP_VER: data = psf.GetString("APP_VER"); break; default: return CELL_GAME_ERROR_INVALID_ID; } + data.resize(bufsize-1); + Memory.WriteString(buf_addr, data.c_str()); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index f578345de2..d95ee607b6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -885,16 +885,18 @@ int cellHddGameCheck(u32 version, u32 dirName_addr, u32 errDialog, mem_func_ptr_ return CELL_HDDGAME_ERROR_BROKEN; } - get->getParam.parentalLevel = psf.m_info.parental_lvl; - get->getParam.attribute = psf.m_info.attr; - get->getParam.resolution = psf.m_info.resolution; - get->getParam.soundFormat = psf.m_info.sound_format; - memcpy(get->getParam.title, psf.m_info.name.mb_str(), CELL_HDDGAME_SYSP_TITLE_SIZE); - memcpy(get->getParam.dataVersion, psf.m_info.app_ver.mb_str(), CELL_HDDGAME_SYSP_VERSION_SIZE); + get->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); + get->getParam.attribute = psf.GetInteger("ATTRIBUTE"); + get->getParam.resolution = psf.GetInteger("RESOLUTION"); + get->getParam.soundFormat = psf.GetInteger("SOUND_FORMAT"); + memcpy(get->getParam.title, psf.GetString("TITLE"), CELL_HDDGAME_SYSP_TITLE_SIZE); + memcpy(get->getParam.dataVersion, psf.GetString("APP_VER"), CELL_HDDGAME_SYSP_VERSION_SIZE); memcpy(get->getParam.titleId, dirName.c_str(), CELL_HDDGAME_SYSP_TITLEID_SIZE); for (u32 i=0; igetParam.titleLang[i], psf.m_info.name.mb_str(), CELL_HDDGAME_SYSP_TITLE_SIZE); // TODO: Get real titleLang name + char key [16]; + sprintf(key, "TITLE_%02d", i); + memcpy(get->getParam.titleLang[i], psf.GetString(key), CELL_HDDGAME_SYSP_TITLE_SIZE); } } diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index dbcf783118..8450c81208 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -47,7 +47,7 @@ void GameViewer::LoadGames() void GameViewer::LoadPSF() { - m_game_data.Clear(); + m_game_data.clear(); for(uint i=0; i& game_data) + void Update(std::vector& game_data) { m_col_name->data.Clear(); m_col_serial->data.Clear(); @@ -100,9 +100,8 @@ public: if(m_columns.GetCount() == 0) return; - for(uint i=0; idata.Add(game.name); m_col_serial->data.Add(game.serial); m_col_fw->data.Add(game.fw); @@ -218,7 +217,7 @@ class GameViewer : public wxListView { wxString m_path; wxArrayString m_games; - ArrayF m_game_data; + std::vector m_game_data; ColumnsArr m_columns; public: diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index efe900fc2b..83053cc942 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -5,12 +5,12 @@ PSFLoader::PSFLoader(vfsStream& f) : psf_f(f) { } -PsfEntry* PSFLoader::SearchEntry(const std::string& key) +PSFEntry* PSFLoader::SearchEntry(const std::string& key) { - for(uint i=0; iFormat(); - if(PsfEntry* entry = SearchEntry("TITLE")) m_info.name = entry->Format(); - if(PsfEntry* entry = SearchEntry("APP_VER")) m_info.app_ver = entry->Format(); - if(PsfEntry* entry = SearchEntry("CATEGORY")) m_info.category = entry->Format(); - if(PsfEntry* entry = SearchEntry("PS3_SYSTEM_VER")) m_info.fw = entry->Format(); - if(PsfEntry* entry = SearchEntry("SOUND_FORMAT")) m_info.sound_format = entry->FormatInteger(); - if(PsfEntry* entry = SearchEntry("RESOLUTION")) m_info.resolution = entry->FormatInteger(); - if(PsfEntry* entry = SearchEntry("PARENTAL_LEVEL")) m_info.parental_lvl = entry->FormatInteger(); - - - if(m_info.serial.Length() == 9) - { - m_info.serial = m_info.serial(0, 4) + "-" + m_info.serial(4, 5); - } - return true; } + +const char* PSFLoader::GetString(const std::string& key) +{ + if(PSFEntry* entry = SearchEntry(key)) + return entry->FormatString(); + else + return ""; +} + +u32 PSFLoader::GetInteger(const std::string& key) +{ + if(PSFEntry* entry = SearchEntry(key)) + return entry->FormatInteger(); + else + return 0; +} diff --git a/rpcs3/Loader/PSF.h b/rpcs3/Loader/PSF.h index b8eca706cc..8b2cb799f3 100644 --- a/rpcs3/Loader/PSF.h +++ b/rpcs3/Loader/PSF.h @@ -1,7 +1,7 @@ #pragma once #include "Loader.h" -struct PsfHeader +struct PSFHeader { u32 psf_magic; u32 psf_version; @@ -12,7 +12,7 @@ struct PsfHeader bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; } }; -struct PsfDefTbl +struct PSFDefTbl { u16 psf_key_table_offset; u16 psf_param_fmt; @@ -21,23 +21,22 @@ struct PsfDefTbl u32 psf_data_tbl_offset; }; -struct PsfEntry +struct PSFEntry { char name[128]; u16 fmt; char param[4096]; - std::string Format() const + const char* FormatString() const { switch(fmt) { default: case 0x0400: case 0x0402: - return FormatString(); - + return (const char*)param; case 0x0404: - return wxString::Format("0x%x", FormatInteger()).ToStdString(); + return (const char*)wxString::Format("0x%x", FormatInteger()).mb_str(); } } @@ -45,34 +44,27 @@ struct PsfEntry { return *(u32*)param; } - - char* FormatString() const - { - return (char*)param; - } }; class PSFLoader { vfsStream& psf_f; + + PSFHeader m_header; + std::vector m_psfindxs; + std::vector m_entries; bool m_show_log; + bool LoadHeader(); + bool LoadKeyTable(); + bool LoadDataTable(); + public: PSFLoader(vfsStream& f); - - Array m_entries; - - PsfEntry* SearchEntry(const std::string& key); - - //wxArrayString m_table; - GameInfo m_info; - PsfHeader psfhdr; - Array m_psfindxs; virtual bool Load(bool show = true); virtual bool Close(); -private: - bool LoadHdr(); - bool LoadKeyTable(); - bool LoadDataTable(); + PSFEntry* SearchEntry(const std::string& key); + const char* GetString(const std::string& key); + u32 GetInteger(const std::string& key); }; \ No newline at end of file diff --git a/rpcs3/rpcs3qt/glviewer.cpp b/rpcs3/rpcs3qt/glviewer.cpp index 48106fbeba..22128e5c72 100644 --- a/rpcs3/rpcs3qt/glviewer.cpp +++ b/rpcs3/rpcs3qt/glviewer.cpp @@ -83,8 +83,6 @@ QSGNode* GLViewer::updatePaintNode(QSGNode* node, UpdatePaintNodeData* data) void GLViewer::cleanup() { this->killTimer(m_timerID); m_timerID = 0; - if (m_fbo) { - delete m_fbo; - m_fbo = 0; - } + delete m_fbo; + m_fbo = nullptr; }