Improved PSF loader.

Improved Game Viewer.
Implemented cellPadGetInfo.
Minor improvements.
This commit is contained in:
DH 2013-12-08 15:47:54 +02:00
parent 34f5997f82
commit eaef09df91
10 changed files with 1024 additions and 1040 deletions

View File

@ -1238,8 +1238,10 @@ private:
}
void AI(u32 rt, u32 ra, s32 i10)
{
const __u32x4 imm = {i10, i10, i10, i10};
CPU.GPR[rt]._m128i = _mm_add_epi32(CPU.GPR[ra]._m128i, imm.m128i);
CPU.GPR[rt]._i32[0] = CPU.GPR[ra]._i32[0] + i10;
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)
{

View File

@ -1058,8 +1058,6 @@ void GLGSRender::Flip()
u32 height = re(buffers[m_gcm_current_buffer].height);
u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL);
glRotated(90, 1, 0, 0);
if(Memory.IsGoodAddr(addr))
{
//TODO

View File

@ -13,6 +13,7 @@ void sys_io_init()
sys_io.AddFunc(0x8b72cda1, cellPadGetData);
sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra);
sys_io.AddFunc(0xf65544ee, cellPadSetActDirect);
sys_io.AddFunc(0x3aaad464, cellPadGetInfo);
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);

View File

@ -240,6 +240,7 @@ extern int cellPadClearBuf(u32 port_no);
extern int cellPadGetData(u32 port_no, 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 cellPadGetInfo(u32 info_addr);
extern int cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);

View File

@ -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);
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;
}
@ -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;
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)
return CELL_ENOMEM;

View File

@ -24,6 +24,16 @@ struct CellPadData
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
{
u32 max_connect;
@ -142,6 +152,35 @@ int cellPadSetActDirect(u32 port_no, u32 param_addr)
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)
{
sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);

View File

@ -8,7 +8,7 @@ GameViewer::GameViewer(wxWindow* parent) : wxListView(parent)
LoadSettings();
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));
@ -34,16 +34,13 @@ void GameViewer::LoadGames()
if(!dir.HasSubDirs()) return;
wxString buf;
if(!dir.GetFirst(&buf)) return;
if(wxDirExists(buf)) m_games.Add(buf);
for(;;)
for(bool ok = dir.GetFirst(&buf); ok; ok = dir.GetNext(&buf))
{
if(!dir.GetNext(&buf)) break;
if(wxDirExists(buf)) m_games.Add(buf);
if(wxDirExists(m_path + 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());
}
@ -52,7 +49,7 @@ void GameViewer::LoadPSF()
m_game_data.Clear();
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;
vfsLocalFile f(path);
PSFLoader psf(f);
@ -91,7 +88,7 @@ void GameViewer::DClick(wxListEvent& event)
long i = GetFirstSelected();
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))
{
ConLog.Error("Boot error: elf not found! [%s]", path.mb_str());

File diff suppressed because it is too large Load Diff

View File

@ -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)
{
if(!psf_f.IsOpened()) return false;
@ -13,17 +24,7 @@ bool PSFLoader::Load(bool show)
if(!LoadHdr()) return false;
if(!LoadKeyTable()) return false;
if(!LoadValuesTable()) 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();
}
if(!LoadDataTable()) return false;
return true;
}
@ -35,198 +36,71 @@ bool PSFLoader::Close()
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(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;
}
bool PSFLoader::LoadKeyTable()
{
psf_f.Seek(psfhdr.psf_offset_key_table);
m_table.Clear();
m_table.Add(wxEmptyString);
while(!psf_f.Eof())
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
{
char c;
psf_f.Read(&c, 1);
if(c == 0)
psf_f.Seek(psfhdr.psf_offset_key_table + m_psfindxs[i].psf_key_table_offset);
int c_pos = 0;
while(!psf_f.Eof())
{
char c;
psf_f.Read(&c, 1);
if(c == 0) break;
m_entries[i].name[c_pos++] = c;
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;
}
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;
for(uint i=0; i<size && !f.Eof(); ++i)
{
ret += ReadChar(f);
}
return ret;
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);
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);
}
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();
for(uint i=0;i<m_table.GetCount(); i++)
{
if(!m_table[i].Cmp("TITLE_ID"))
{
m_info.serial = PsfHelper::ReadString(psf_f);
m_table[i].Append(wxString::Format(": %s", m_info.serial.mb_str()));
PsfHelper::GoToNN(psf_f);
}
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(PsfEntry* entry = SearchEntry("TITLE_ID")) m_info.serial = entry->Format();
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)
{

View File

@ -6,7 +6,7 @@ struct PsfHeader
u32 psf_magic;
u32 psf_version;
u32 psf_offset_key_table;
u32 psf_offset_values_table;
u32 psf_offset_data_table;
u32 psf_entries_num;
bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; }
@ -14,13 +14,44 @@ struct PsfHeader
struct PsfDefTbl
{
u16 psf_name_tbl_offset;
u16 psf_data_type;
u32 psf_data_size;
u32 psf_data_fsize;
u16 psf_key_table_offset;
u16 psf_param_fmt;
u32 psf_param_len;
u32 psf_param_max_len;
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
{
vfsStream& psf_f;
@ -29,14 +60,19 @@ class PSFLoader
public:
PSFLoader(vfsStream& f);
wxArrayString m_table;
Array<PsfEntry> m_entries;
PsfEntry* SearchEntry(const std::string& key);
//wxArrayString m_table;
GameInfo m_info;
PsfHeader psfhdr;
Array<PsfDefTbl> m_psfindxs;
virtual bool Load(bool show = true);
virtual bool Close();
private:
bool LoadHdr();
bool LoadKeyTable();
bool LoadValuesTable();
bool LoadDataTable();
};