mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
Improved PSF loader.
Improved Game Viewer. Implemented cellPadGetInfo. Minor improvements.
This commit is contained in:
parent
34f5997f82
commit
eaef09df91
10 changed files with 1024 additions and 1040 deletions
|
@ -1238,8 +1238,10 @@ private:
|
||||||
}
|
}
|
||||||
void AI(u32 rt, u32 ra, s32 i10)
|
void AI(u32 rt, u32 ra, s32 i10)
|
||||||
{
|
{
|
||||||
const __u32x4 imm = {i10, i10, i10, i10};
|
CPU.GPR[rt]._i32[0] = CPU.GPR[ra]._i32[0] + i10;
|
||||||
CPU.GPR[rt]._m128i = _mm_add_epi32(CPU.GPR[ra]._m128i, imm.m128i);
|
CPU.GPR[rt]._i32[1] = CPU.GPR[ra]._i32[1] + i10;
|
||||||
|
CPU.GPR[rt]._i32[2] = CPU.GPR[ra]._i32[2] + i10;
|
||||||
|
CPU.GPR[rt]._i32[3] = CPU.GPR[ra]._i32[3] + i10;
|
||||||
}
|
}
|
||||||
void AHI(u32 rt, u32 ra, s32 i10)
|
void AHI(u32 rt, u32 ra, s32 i10)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1058,8 +1058,6 @@ void GLGSRender::Flip()
|
||||||
u32 height = re(buffers[m_gcm_current_buffer].height);
|
u32 height = re(buffers[m_gcm_current_buffer].height);
|
||||||
u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL);
|
u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL);
|
||||||
|
|
||||||
glRotated(90, 1, 0, 0);
|
|
||||||
|
|
||||||
if(Memory.IsGoodAddr(addr))
|
if(Memory.IsGoodAddr(addr))
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
|
|
|
@ -13,6 +13,7 @@ void sys_io_init()
|
||||||
sys_io.AddFunc(0x8b72cda1, cellPadGetData);
|
sys_io.AddFunc(0x8b72cda1, cellPadGetData);
|
||||||
sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra);
|
sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra);
|
||||||
sys_io.AddFunc(0xf65544ee, cellPadSetActDirect);
|
sys_io.AddFunc(0xf65544ee, cellPadSetActDirect);
|
||||||
|
sys_io.AddFunc(0x3aaad464, cellPadGetInfo);
|
||||||
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
|
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
|
||||||
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
|
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
|
||||||
|
|
||||||
|
|
|
@ -240,6 +240,7 @@ extern int cellPadClearBuf(u32 port_no);
|
||||||
extern int cellPadGetData(u32 port_no, u32 data_addr);
|
extern int cellPadGetData(u32 port_no, u32 data_addr);
|
||||||
extern int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr);
|
extern int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr);
|
||||||
extern int cellPadSetActDirect(u32 port_no, u32 param_addr);
|
extern int cellPadSetActDirect(u32 port_no, u32 param_addr);
|
||||||
|
extern int cellPadGetInfo(u32 info_addr);
|
||||||
extern int cellPadGetInfo2(u32 info_addr);
|
extern int cellPadGetInfo2(u32 info_addr);
|
||||||
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
|
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,28 @@ int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a
|
||||||
{
|
{
|
||||||
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
|
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
|
||||||
|
|
||||||
Memory.Write32(alloc_addr, Memory.Alloc(size, alignment));
|
if(!Memory.IsGoodAddr(alloc_addr)) return CELL_EFAULT;
|
||||||
|
|
||||||
|
if(!alignment)
|
||||||
|
alignment = 1;
|
||||||
|
|
||||||
|
u32 addr;
|
||||||
|
|
||||||
|
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_1M:
|
||||||
|
if(Memory.AlignAddr(size, alignment) & 0xfffff) return CELL_EALIGN;
|
||||||
|
addr = Memory.Alloc(size, 0x100000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_64K:
|
||||||
|
if(Memory.AlignAddr(size, alignment) & 0xffff) return CELL_EALIGN;
|
||||||
|
addr = Memory.Alloc(size, 0x10000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Memory.Write32(alloc_addr, addr);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +112,22 @@ int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr)
|
||||||
|
|
||||||
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
|
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
|
||||||
|
|
||||||
u64 addr = Memory.Alloc(size, 4);
|
u32 addr;
|
||||||
|
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
|
||||||
|
{
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_1M:
|
||||||
|
if(size & 0xfffff) return CELL_EALIGN;
|
||||||
|
addr = Memory.Alloc(size, 0x100000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_64K:
|
||||||
|
if(size & 0xffff) return CELL_EALIGN;
|
||||||
|
addr = Memory.Alloc(size, 0x10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if(!addr)
|
if(!addr)
|
||||||
return CELL_ENOMEM;
|
return CELL_ENOMEM;
|
||||||
|
|
|
@ -24,6 +24,16 @@ struct CellPadData
|
||||||
u16 button[CELL_PAD_MAX_CODES];
|
u16 button[CELL_PAD_MAX_CODES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CellPadInfo
|
||||||
|
{
|
||||||
|
u32 max_connect;
|
||||||
|
u32 now_connect;
|
||||||
|
u32 system_info;
|
||||||
|
u16 vendor_id[CELL_MAX_PADS];
|
||||||
|
u16 product_id[CELL_MAX_PADS];
|
||||||
|
u8 status[CELL_MAX_PADS];
|
||||||
|
};
|
||||||
|
|
||||||
struct CellPadInfo2
|
struct CellPadInfo2
|
||||||
{
|
{
|
||||||
u32 max_connect;
|
u32 max_connect;
|
||||||
|
@ -142,6 +152,35 @@ int cellPadSetActDirect(u32 port_no, u32 param_addr)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cellPadGetInfo(u32 info_addr)
|
||||||
|
{
|
||||||
|
sys_io.Log("cellPadGetInfo(info_addr=0x%x)", info_addr);
|
||||||
|
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
|
||||||
|
|
||||||
|
CellPadInfo info;
|
||||||
|
memset(&info, 0, sizeof(CellPadInfo));
|
||||||
|
|
||||||
|
const PadInfo& rinfo = Emu.GetPadManager().GetInfo();
|
||||||
|
info.max_connect = re(rinfo.max_connect);
|
||||||
|
info.now_connect = re(rinfo.now_connect);
|
||||||
|
info.system_info = re(rinfo.system_info);
|
||||||
|
|
||||||
|
const Array<Pad>& pads = Emu.GetPadManager().GetPads();
|
||||||
|
|
||||||
|
for(u32 i=0; i<CELL_MAX_PADS; ++i)
|
||||||
|
{
|
||||||
|
if(i >= pads.GetCount()) break;
|
||||||
|
|
||||||
|
info.status[i] = re(pads[i].m_port_status);
|
||||||
|
info.product_id[i] = 0xdead; //TODO
|
||||||
|
info.vendor_id[i] = 0xbeaf; //TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
Memory.WriteData(info_addr, info);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int cellPadGetInfo2(u32 info_addr)
|
int cellPadGetInfo2(u32 info_addr)
|
||||||
{
|
{
|
||||||
sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);
|
sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);
|
||||||
|
|
|
@ -8,7 +8,7 @@ GameViewer::GameViewer(wxWindow* parent) : wxListView(parent)
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
m_columns.Show(this);
|
m_columns.Show(this);
|
||||||
|
|
||||||
m_path = wxGetCwd(); //TODO
|
m_path = wxGetCwd() + "\\dev_hdd0\\game\\"; //TODO
|
||||||
|
|
||||||
Connect(GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(GameViewer::DClick));
|
Connect(GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(GameViewer::DClick));
|
||||||
|
|
||||||
|
@ -34,16 +34,13 @@ void GameViewer::LoadGames()
|
||||||
if(!dir.HasSubDirs()) return;
|
if(!dir.HasSubDirs()) return;
|
||||||
|
|
||||||
wxString buf;
|
wxString buf;
|
||||||
if(!dir.GetFirst(&buf)) return;
|
for(bool ok = dir.GetFirst(&buf); ok; ok = dir.GetNext(&buf))
|
||||||
if(wxDirExists(buf)) m_games.Add(buf);
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
if(!dir.GetNext(&buf)) break;
|
if(wxDirExists(m_path + buf))
|
||||||
if(wxDirExists(buf)) m_games.Add(buf);
|
m_games.Add(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ConLog.Write("path: %s", m_path);
|
//ConLog.Write("path: %s", m_path.c_str());
|
||||||
//ConLog.Write("folders count: %d", m_games.GetCount());
|
//ConLog.Write("folders count: %d", m_games.GetCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +49,7 @@ void GameViewer::LoadPSF()
|
||||||
m_game_data.Clear();
|
m_game_data.Clear();
|
||||||
for(uint i=0; i<m_games.GetCount(); ++i)
|
for(uint i=0; i<m_games.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
const wxString& path = m_games[i] + "\\" + "PARAM.SFO";
|
const wxString& path = m_path + m_games[i] + "\\PARAM.SFO";
|
||||||
if(!wxFileExists(path)) continue;
|
if(!wxFileExists(path)) continue;
|
||||||
vfsLocalFile f(path);
|
vfsLocalFile f(path);
|
||||||
PSFLoader psf(f);
|
PSFLoader psf(f);
|
||||||
|
@ -91,7 +88,7 @@ void GameViewer::DClick(wxListEvent& event)
|
||||||
long i = GetFirstSelected();
|
long i = GetFirstSelected();
|
||||||
if(i < 0) return;
|
if(i < 0) return;
|
||||||
|
|
||||||
const wxString& path = m_path + "\\" + m_game_data[i].root + "\\" + "USRDIR" + "\\" + "BOOT.BIN";
|
const wxString& path = m_path + "\\" + m_game_data[i].root + "\\USRDIR\\BOOT.BIN";
|
||||||
if(!wxFileExists(path))
|
if(!wxFileExists(path))
|
||||||
{
|
{
|
||||||
ConLog.Error("Boot error: elf not found! [%s]", path.mb_str());
|
ConLog.Error("Boot error: elf not found! [%s]", path.mb_str());
|
||||||
|
|
|
@ -522,8 +522,8 @@ void MainFrame::BootSelf(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
||||||
Emu.SetPath(fileOut);
|
Emu.SetPath(fileOut);
|
||||||
Emu.Load();
|
Emu.Load();
|
||||||
if (!wxRemoveFile(fileOut))
|
//if (!wxRemoveFile(fileOut))
|
||||||
ConLog.Warning("Could not delete the decrypted ELF file");
|
// ConLog.Warning("Could not delete the decrypted ELF file");
|
||||||
|
|
||||||
ConLog.Write("SELF: boot done.");
|
ConLog.Write("SELF: boot done.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,17 @@ PSFLoader::PSFLoader(vfsStream& f) : psf_f(f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PsfEntry* PSFLoader::SearchEntry(const std::string& key)
|
||||||
|
{
|
||||||
|
for(uint i=0; i<m_entries.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(m_entries[i].name == key)
|
||||||
|
return &m_entries[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool PSFLoader::Load(bool show)
|
bool PSFLoader::Load(bool show)
|
||||||
{
|
{
|
||||||
if(!psf_f.IsOpened()) return false;
|
if(!psf_f.IsOpened()) return false;
|
||||||
|
@ -13,17 +24,7 @@ bool PSFLoader::Load(bool show)
|
||||||
|
|
||||||
if(!LoadHdr()) return false;
|
if(!LoadHdr()) return false;
|
||||||
if(!LoadKeyTable()) return false;
|
if(!LoadKeyTable()) return false;
|
||||||
if(!LoadValuesTable()) return false;
|
if(!LoadDataTable()) return false;
|
||||||
|
|
||||||
if(show)
|
|
||||||
{
|
|
||||||
ConLog.SkipLn();
|
|
||||||
for(uint i=0; i<m_table.GetCount(); ++i)
|
|
||||||
{
|
|
||||||
ConLog.Write("%s", m_table[i].mb_str());
|
|
||||||
}
|
|
||||||
ConLog.SkipLn();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -35,198 +36,71 @@ bool PSFLoader::Close()
|
||||||
|
|
||||||
bool PSFLoader::LoadHdr()
|
bool PSFLoader::LoadHdr()
|
||||||
{
|
{
|
||||||
psf_f.Read(&psfhdr, sizeof(PsfHeader));
|
if(psf_f.Read(&psfhdr, sizeof(PsfHeader)) != sizeof(PsfHeader))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(!psfhdr.CheckMagic()) return false;
|
if(!psfhdr.CheckMagic()) return false;
|
||||||
|
|
||||||
if(m_show_log) ConLog.Write("PSF version: %x", psfhdr.psf_version);
|
if(m_show_log) ConLog.Write("PSF version: %x", psfhdr.psf_version);
|
||||||
|
|
||||||
|
m_psfindxs.Clear();
|
||||||
|
m_entries.Clear();
|
||||||
|
m_psfindxs.SetCount(psfhdr.psf_entries_num);
|
||||||
|
m_entries.SetCount(psfhdr.psf_entries_num);
|
||||||
|
|
||||||
|
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
|
||||||
|
{
|
||||||
|
if(psf_f.Read(&m_psfindxs[i], sizeof(PsfDefTbl)) != sizeof(PsfDefTbl))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_entries[i].fmt = m_psfindxs[i].psf_param_fmt;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PSFLoader::LoadKeyTable()
|
bool PSFLoader::LoadKeyTable()
|
||||||
{
|
{
|
||||||
psf_f.Seek(psfhdr.psf_offset_key_table);
|
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
|
||||||
|
{
|
||||||
|
psf_f.Seek(psfhdr.psf_offset_key_table + m_psfindxs[i].psf_key_table_offset);
|
||||||
|
|
||||||
m_table.Clear();
|
int c_pos = 0;
|
||||||
m_table.Add(wxEmptyString);
|
|
||||||
|
|
||||||
while(!psf_f.Eof())
|
while(!psf_f.Eof())
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
psf_f.Read(&c, 1);
|
psf_f.Read(&c, 1);
|
||||||
if(c == 0)
|
m_entries[i].name[c_pos++] = c;
|
||||||
{
|
|
||||||
psf_f.Read(&c, 1);
|
|
||||||
if(c == 0) break;
|
|
||||||
|
|
||||||
m_table.Add(wxEmptyString);
|
if(c_pos >= sizeof(m_entries[i].name) || c == '\0')
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
m_table[m_table.GetCount() - 1].Append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_table.GetCount() != psfhdr.psf_entries_num)
|
|
||||||
{
|
|
||||||
if(m_show_log) ConLog.Error("PSF error: Entries loaded with error! [%d - %d]", m_table.GetCount(), psfhdr.psf_entries_num);
|
|
||||||
m_table.Clear();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PsfHelper
|
bool PSFLoader::LoadDataTable()
|
||||||
{
|
{
|
||||||
static wxString ReadString(vfsStream& f, const u32 size)
|
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
|
||||||
{
|
{
|
||||||
wxString ret = wxEmptyString;
|
psf_f.Seek(psfhdr.psf_offset_data_table + m_psfindxs[i].psf_data_tbl_offset);
|
||||||
|
psf_f.Read(m_entries[i].param, m_psfindxs[i].psf_param_len);
|
||||||
for(uint i=0; i<size && !f.Eof(); ++i)
|
memset(m_entries[i].param + m_psfindxs[i].psf_param_len, 0, m_psfindxs[i].psf_param_max_len - m_psfindxs[i].psf_param_len);
|
||||||
{
|
|
||||||
ret += ReadChar(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wxString ReadString(vfsStream& f)
|
|
||||||
{
|
|
||||||
wxString ret = wxEmptyString;
|
|
||||||
|
|
||||||
while(!f.Eof())
|
|
||||||
{
|
|
||||||
const char c = ReadChar(f);
|
|
||||||
if(c == 0) break;
|
|
||||||
ret += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char ReadChar(vfsStream& f)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
f.Read(&c, 1);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char ReadCharNN(vfsStream& f)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
while(!f.Eof())
|
|
||||||
{
|
|
||||||
f.Read(&c, 1);
|
|
||||||
if(c != 0) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GoToNN(vfsStream& f)
|
|
||||||
{
|
|
||||||
while(!f.Eof())
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
f.Read(&c, 1);
|
|
||||||
if(c != 0)
|
|
||||||
{
|
|
||||||
f.Seek(f.Tell() - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static wxString FixName(const wxString& name)
|
|
||||||
{
|
|
||||||
wxString ret = wxEmptyString;
|
|
||||||
|
|
||||||
for(uint i=0; i<name.Length(); ++i)
|
|
||||||
{
|
|
||||||
switch((u8)name[i])
|
|
||||||
{
|
|
||||||
case 0xE2: case 0xA2: case 0x84: continue;
|
|
||||||
default: ret += name[i]; break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool PSFLoader::LoadValuesTable()
|
|
||||||
{
|
|
||||||
psf_f.Seek(psfhdr.psf_offset_values_table);
|
|
||||||
m_info.Reset();
|
m_info.Reset();
|
||||||
|
|
||||||
for(uint i=0;i<m_table.GetCount(); i++)
|
if(PsfEntry* entry = SearchEntry("TITLE_ID")) m_info.serial = entry->Format();
|
||||||
{
|
if(PsfEntry* entry = SearchEntry("TITLE")) m_info.name = entry->Format();
|
||||||
if(!m_table[i].Cmp("TITLE_ID"))
|
if(PsfEntry* entry = SearchEntry("APP_VER")) m_info.app_ver = entry->Format();
|
||||||
{
|
if(PsfEntry* entry = SearchEntry("CATEGORY")) m_info.category = entry->Format();
|
||||||
m_info.serial = PsfHelper::ReadString(psf_f);
|
if(PsfEntry* entry = SearchEntry("PS3_SYSTEM_VER")) m_info.fw = entry->Format();
|
||||||
m_table[i].Append(wxString::Format(": %s", m_info.serial.mb_str()));
|
if(PsfEntry* entry = SearchEntry("SOUND_FORMAT")) m_info.sound_format = entry->FormatInteger();
|
||||||
PsfHelper::GoToNN(psf_f);
|
if(PsfEntry* entry = SearchEntry("RESOLUTION")) m_info.resolution = entry->FormatInteger();
|
||||||
}
|
if(PsfEntry* entry = SearchEntry("PARENTAL_LEVEL")) m_info.parental_lvl = entry->FormatInteger();
|
||||||
else if(!m_table[i](0, 5).Cmp("TITLE"))
|
|
||||||
{
|
|
||||||
m_info.name = PsfHelper::FixName(PsfHelper::ReadString(psf_f));
|
|
||||||
m_table[i].Append(wxString::Format(": %s", m_info.name.mb_str()));
|
|
||||||
PsfHelper::GoToNN(psf_f);
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("APP_VER"))
|
|
||||||
{
|
|
||||||
m_info.app_ver = PsfHelper::ReadString(psf_f, sizeof(u64));
|
|
||||||
m_table[i].Append(wxString::Format(": %s", m_info.app_ver.mb_str()));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("ATTRIBUTE"))
|
|
||||||
{
|
|
||||||
psf_f.Read(&m_info.attr, sizeof(m_info.attr));
|
|
||||||
m_table[i].Append(wxString::Format(": 0x%x", m_info.attr));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("CATEGORY"))
|
|
||||||
{
|
|
||||||
m_info.category = PsfHelper::ReadString(psf_f, sizeof(u32));
|
|
||||||
m_table[i].Append(wxString::Format(": %s", m_info.category.mb_str()));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("BOOTABLE"))
|
|
||||||
{
|
|
||||||
psf_f.Read(&m_info.bootable, sizeof(m_info.bootable));
|
|
||||||
m_table[i].Append(wxString::Format(": %d", m_info.bootable));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("LICENSE"))
|
|
||||||
{
|
|
||||||
m_table[i].Append(wxString::Format(": %s", PsfHelper::ReadString(psf_f).mb_str()));
|
|
||||||
psf_f.Seek(psf_f.Tell() + (sizeof(u64) * 7 * 2) - 1);
|
|
||||||
}
|
|
||||||
else if(!m_table[i](0, 14).Cmp("PARENTAL_LEVEL"))
|
|
||||||
{
|
|
||||||
u32 buf;
|
|
||||||
psf_f.Read(&buf, sizeof(buf));
|
|
||||||
if(!m_table[i].Cmp("PARENTAL_LEVEL"))
|
|
||||||
{
|
|
||||||
m_info.parental_lvl = buf;
|
|
||||||
}
|
|
||||||
m_table[i].Append(wxString::Format(": %d", buf));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("PS3_SYSTEM_VER"))
|
|
||||||
{
|
|
||||||
m_info.fw = PsfHelper::ReadString(psf_f, sizeof(u64));
|
|
||||||
m_table[i].Append(wxString::Format(": %s", m_info.fw.mb_str()));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("SOUND_FORMAT"))
|
|
||||||
{
|
|
||||||
m_info.sound_format = Read32(psf_f);
|
|
||||||
m_table[i].Append(wxString::Format(": 0x%x", m_info.sound_format));
|
|
||||||
}
|
|
||||||
else if(!m_table[i].Cmp("RESOLUTION"))
|
|
||||||
{
|
|
||||||
m_info.resolution = Read32(psf_f);
|
|
||||||
m_table[i].Append(wxString::Format(": 0x%x", m_info.resolution));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_table[i].Append(wxString::Format(": %s", PsfHelper::ReadString(psf_f).mb_str()));
|
|
||||||
PsfHelper::GoToNN(psf_f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_info.serial.Length() == 9)
|
if(m_info.serial.Length() == 9)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct PsfHeader
|
||||||
u32 psf_magic;
|
u32 psf_magic;
|
||||||
u32 psf_version;
|
u32 psf_version;
|
||||||
u32 psf_offset_key_table;
|
u32 psf_offset_key_table;
|
||||||
u32 psf_offset_values_table;
|
u32 psf_offset_data_table;
|
||||||
u32 psf_entries_num;
|
u32 psf_entries_num;
|
||||||
|
|
||||||
bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; }
|
bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; }
|
||||||
|
@ -14,13 +14,44 @@ struct PsfHeader
|
||||||
|
|
||||||
struct PsfDefTbl
|
struct PsfDefTbl
|
||||||
{
|
{
|
||||||
u16 psf_name_tbl_offset;
|
u16 psf_key_table_offset;
|
||||||
u16 psf_data_type;
|
u16 psf_param_fmt;
|
||||||
u32 psf_data_size;
|
u32 psf_param_len;
|
||||||
u32 psf_data_fsize;
|
u32 psf_param_max_len;
|
||||||
u32 psf_data_tbl_offset;
|
u32 psf_data_tbl_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PsfEntry
|
||||||
|
{
|
||||||
|
char name[128];
|
||||||
|
u16 fmt;
|
||||||
|
char param[4096];
|
||||||
|
|
||||||
|
std::string Format() const
|
||||||
|
{
|
||||||
|
switch(fmt)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0x0400:
|
||||||
|
case 0x0402:
|
||||||
|
return FormatString();
|
||||||
|
|
||||||
|
case 0x0404:
|
||||||
|
return wxString::Format("0x%x", FormatInteger()).c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 FormatInteger() const
|
||||||
|
{
|
||||||
|
return *(u32*)param;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* FormatString() const
|
||||||
|
{
|
||||||
|
return (char*)param;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class PSFLoader
|
class PSFLoader
|
||||||
{
|
{
|
||||||
vfsStream& psf_f;
|
vfsStream& psf_f;
|
||||||
|
@ -29,14 +60,19 @@ class PSFLoader
|
||||||
public:
|
public:
|
||||||
PSFLoader(vfsStream& f);
|
PSFLoader(vfsStream& f);
|
||||||
|
|
||||||
wxArrayString m_table;
|
Array<PsfEntry> m_entries;
|
||||||
|
|
||||||
|
PsfEntry* SearchEntry(const std::string& key);
|
||||||
|
|
||||||
|
//wxArrayString m_table;
|
||||||
GameInfo m_info;
|
GameInfo m_info;
|
||||||
PsfHeader psfhdr;
|
PsfHeader psfhdr;
|
||||||
|
Array<PsfDefTbl> m_psfindxs;
|
||||||
virtual bool Load(bool show = true);
|
virtual bool Load(bool show = true);
|
||||||
virtual bool Close();
|
virtual bool Close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool LoadHdr();
|
bool LoadHdr();
|
||||||
bool LoadKeyTable();
|
bool LoadKeyTable();
|
||||||
bool LoadValuesTable();
|
bool LoadDataTable();
|
||||||
};
|
};
|
Loading…
Add table
Add a link
Reference in a new issue