added psf file format and correct load to gamelist viewer
This commit is contained in:
parent
2c8cab1f05
commit
7101247fd5
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <immintrin.h>
|
||||
|
||||
using S08 = char;
|
||||
using S16 = short;
|
||||
|
@ -12,3 +13,34 @@ using U64 = unsigned long long;
|
|||
|
||||
using F32 = float;
|
||||
using F64 = double;
|
||||
|
||||
|
||||
template< typename T > T inline LoadBE(T* src) { return *src; };
|
||||
template< typename T > inline void StoreBE(T* dst, T src) { *dst = src; };
|
||||
|
||||
inline S16 LoadBE(S16* src) { return _loadbe_i16(src); };
|
||||
inline S32 LoadBE(S32* src) { return _loadbe_i32(src); };
|
||||
inline S64 LoadBE(S64* src) { return _loadbe_i64(src); };
|
||||
|
||||
inline U16 LoadBE(U16* src) { return _load_be_u16(src); };
|
||||
inline U32 LoadBE(U32* src) { return _load_be_u32(src); };
|
||||
inline U64 LoadBE(U64* src) { return _load_be_u64(src); };
|
||||
|
||||
inline void StoreBE(S16* dst, S16 const src) { _storebe_i16(dst, src); };
|
||||
inline void StoreBE(S32* dst, S32 const src) { _storebe_i32(dst, src); };
|
||||
inline void StoreBE(S64* dst, S64 const src) { _storebe_i64(dst, src); };
|
||||
|
||||
inline void StoreBE(U16* dst, U16 const src) { _store_be_u16(dst, src); };
|
||||
inline void StoreBE(U32* dst, U32 const src) { _store_be_u32(dst, src); };
|
||||
inline void StoreBE(U64* dst, U64 const src) { _store_be_u64(dst, src); };
|
||||
|
||||
|
||||
template< typename T > inline void ReadBE(T& val)
|
||||
{
|
||||
val = LoadBE(&val); // swap inplace
|
||||
}
|
||||
|
||||
template< typename T > inline void WriteBE(T& val)
|
||||
{
|
||||
StoreBE(&val, val); // swap inplace
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include "PSF.h"
|
||||
#include "../../Core/FsFile.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
PSF::PSF()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PSF::~PSF()
|
||||
{
|
||||
}
|
||||
bool PSF::open(const std::string& filepath) {
|
||||
FsFile file;
|
||||
if (!file.Open(filepath, fsRead))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const U64 psfSize = file.getFileSize();
|
||||
psf.resize(psfSize);
|
||||
file.Seek(0, fsSeekSet);
|
||||
file.Read(&psf[0], psfSize);
|
||||
|
||||
// Parse file contents
|
||||
const auto& header = (PSFHeader&)psf[0];
|
||||
for (U32 i = 0; i < header.indexTableEntries; i++) {
|
||||
const U32 offset = sizeof(PSFHeader) + i * sizeof(PSFEntry);
|
||||
auto& entry = (PSFEntry&)psf[offset];
|
||||
|
||||
std::string key = (char*)&psf[header.keyTableOffset + entry.keyOffset];
|
||||
ReadBE(entry.param_fmt);//param_fmt is big endian convert it (this convert the original entry maybe we should store it elsewhere?)
|
||||
if (entry.param_fmt == PSFEntry::Fmt::TEXT_RAW ||
|
||||
entry.param_fmt == PSFEntry::Fmt::TEXT_NORMAL) {
|
||||
map_strings[key] = (char*)&psf[header.dataTableOffset + entry.dataOffset];
|
||||
}
|
||||
if (entry.param_fmt == PSFEntry::Fmt::INTEGER) {
|
||||
map_integers[key] = (U32&)psf[header.dataTableOffset + entry.dataOffset];
|
||||
}
|
||||
}
|
||||
//debug code print all keys
|
||||
std::ofstream out;
|
||||
out.open("psf.txt", std::fstream::out | std::fstream::app);
|
||||
out << "---------------------------------------------" << "\n";
|
||||
for (auto stringkey : map_strings)
|
||||
{
|
||||
out << " " << stringkey.first << " : " << stringkey.second << "\n";
|
||||
}
|
||||
for (auto integerkey : map_integers)
|
||||
{
|
||||
out << " " << integerkey.first << " : " << integerkey.second << "\n";
|
||||
}
|
||||
out << "---------------------------------------------" << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
std::string PSF::get_string(const std::string& key) {
|
||||
if (map_strings.find(key) != map_strings.end()) {
|
||||
return map_strings.at(key);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
U32 PSF::get_integer(const std::string& key)
|
||||
{
|
||||
if (map_integers.find(key) != map_integers.end()) {
|
||||
return map_integers.at(key); //TODO std::invalid_argument exception if it fails?
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "../../types.h"
|
||||
|
||||
struct PSFHeader {
|
||||
U32 magic; //big endian
|
||||
U32 version;
|
||||
U32 keyTableOffset;
|
||||
U32 dataTableOffset;
|
||||
U32 indexTableEntries;
|
||||
};
|
||||
|
||||
struct PSFEntry {
|
||||
enum Fmt : U16 {
|
||||
TEXT_RAW = 0x0400, // String in UTF-8 format and not NULL terminated
|
||||
TEXT_NORMAL = 0x0402, // String in UTF-8 format and NULL terminated
|
||||
INTEGER = 0x0404, // Unsigned 32-bit integer
|
||||
};
|
||||
|
||||
U16 keyOffset;
|
||||
U16 param_fmt;//big endian
|
||||
U32 paramLen;
|
||||
U32 paramMaxLen;
|
||||
U32 dataOffset;
|
||||
};
|
||||
|
||||
class PSF
|
||||
{
|
||||
std::vector<U08> psf;
|
||||
std::unordered_map<std::string, std::string> map_strings;
|
||||
std::unordered_map<std::string, U32> map_integers;
|
||||
|
||||
public:
|
||||
PSF();
|
||||
~PSF();
|
||||
bool open(const std::string& filepath);
|
||||
|
||||
// Access data
|
||||
std::string get_string(const std::string& key);
|
||||
U32 get_integer(const std::string& key);
|
||||
};
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QDirIterator>
|
||||
#include <QLineEdit>
|
||||
#include "../emulator/fileFormat/PSF.h"
|
||||
|
||||
GameListViewer::GameListViewer(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
@ -147,20 +148,20 @@ void GameListWorker::AddEntriesToGameList(const std::string& dir_path) {
|
|||
QFileInfoList fList = parent_folder.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::DirsFirst);
|
||||
foreach(QFileInfo item, fList)
|
||||
{
|
||||
//TODO PSF psf;
|
||||
//TODO if (!psf.open(item.absoluteFilePath().toStdString() + "/PARAM.SFO"))
|
||||
//TODO continue;//if we can't open param.sfo go to the next entry
|
||||
PSF psf;
|
||||
if (!psf.open(item.absoluteFilePath().toStdString() + "/PARAM.SFO"))
|
||||
continue;//if we can't open param.sfo go to the next entry
|
||||
|
||||
//TODO std::string test = psf.get_string("TITLE_ID");
|
||||
QString iconpath(item.absoluteFilePath() + "/ICON0.PNG");
|
||||
|
||||
emit EntryReady({
|
||||
new GameIconItem(iconpath),
|
||||
new GameListItem("TODO"/*QString::fromStdString(psf.get_string("TITLE"))*/),
|
||||
new GameListItem("TODO"/*QString::fromStdString(psf.get_string("TITLE_ID"))*/),
|
||||
new GameListItem("TODO"/*QString::fromStdString(psf.get_string("SYSTEM_VER"))*/),
|
||||
new GameListItem("TODO"/*QString::fromStdString(psf.get_string("APP_VER"))*/),
|
||||
new GameListItem("TODO"/*QString::fromStdString(psf.get_string("CATEGORY"))*/),
|
||||
new GameListItem(QString::fromStdString(psf.get_string("TITLE"))),
|
||||
new GameListItem(QString::fromStdString(psf.get_string("TITLE_ID"))),
|
||||
new GameListItem(QString("%1").arg(psf.get_integer("SYSTEM_VER"), 8, 16, QLatin1Char('0'))),
|
||||
new GameListItem(QString::fromStdString(psf.get_string("APP_VER"))),
|
||||
new GameListItem(QString::fromStdString(psf.get_string("CATEGORY"))),
|
||||
new GameListItem(item.fileName())
|
||||
});
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="core\FsFile.cpp" />
|
||||
<ClCompile Include="emulator\fileFormat\PSF.cpp" />
|
||||
<ClCompile Include="gui\GameListViewer.cpp" />
|
||||
<ClCompile Include="gui\shadps4gui.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
|
@ -27,6 +28,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="core\FsFile.h" />
|
||||
<ClInclude Include="emulator\fileFormat\PSF.h" />
|
||||
<ClInclude Include="Types.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
<Filter Include="Core">
|
||||
<UniqueIdentifier>{73d07238-8864-48b5-9987-e455fa73c82f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="emulator">
|
||||
<UniqueIdentifier>{66864aec-390b-47a8-bddb-b52032630d7a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="emulator\fileFormat">
|
||||
<UniqueIdentifier>{ed31734c-f010-4590-9f01-18e0b2497ffb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
|
@ -41,6 +47,9 @@
|
|||
<ClCompile Include="core\FsFile.cpp">
|
||||
<Filter>Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="emulator\fileFormat\PSF.cpp">
|
||||
<Filter>emulator\fileFormat</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="gui\shadps4gui.ui">
|
||||
|
@ -62,5 +71,8 @@
|
|||
<ClInclude Include="core\FsFile.h">
|
||||
<Filter>Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="emulator\fileFormat\PSF.h">
|
||||
<Filter>emulator\fileFormat</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue