- pkg extraction: fix a rare issue when there is extra entries with uroot and flat_path_table (this is how it should be handled anyway!) (#96)
- gui: - fix crash when switching between List and Grid modes. - fix fw display text (it was showing wrong numbers in certain cases) - made sfo viewer show numbers in hex.
This commit is contained in:
parent
12a8cf5ee9
commit
8ba6d7add0
|
@ -189,9 +189,9 @@ bool PKG::Extract(const std::string& filepath, const std::filesystem::path& extr
|
|||
u32 ndinode = 0;
|
||||
int ndinode_counter = 0;
|
||||
bool dinode_reached = false;
|
||||
bool uroot_reached = false;
|
||||
std::vector<char> compressedData;
|
||||
std::vector<char> decompressedData(0x10000);
|
||||
extractPaths[2] = extract_path.parent_path() / GetTitleID();
|
||||
|
||||
// Get iNdoes and Dirents.
|
||||
for (int i = 0; i < num_blocks; i++) {
|
||||
|
@ -226,6 +226,30 @@ bool PKG::Extract(const std::string& filepath, const std::filesystem::path& extr
|
|||
}
|
||||
}
|
||||
|
||||
// let's deal with the root/uroot enteries here.
|
||||
// Sometimes it's more than 2 enteries (Tomb Raider Remastered)
|
||||
const std::string_view flat_path_table(&decompressedData[0x10], 15);
|
||||
if (flat_path_table == "flat_path_table") {
|
||||
uroot_reached = true;
|
||||
}
|
||||
|
||||
if (uroot_reached) {
|
||||
for (int i = 0; i < 0x10000; i += ent_size) {
|
||||
Dirent dirent;
|
||||
std::memcpy(&dirent, &decompressedData[i], sizeof(dirent));
|
||||
ent_size = dirent.entsize;
|
||||
if (dirent.ino != 0) {
|
||||
ndinode_counter++;
|
||||
} else {
|
||||
// Set the the folder according to the current inode.
|
||||
// Can be 2 or more (rarely)
|
||||
extractPaths[ndinode_counter] = extract_path.parent_path() / GetTitleID();
|
||||
uroot_reached = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char dot = decompressedData[0x10];
|
||||
const std::string_view dotdot(&decompressedData[0x28], 2);
|
||||
if (dot == '.' && dotdot == "..") {
|
||||
|
@ -261,7 +285,7 @@ bool PKG::Extract(const std::string& filepath, const std::filesystem::path& extr
|
|||
std::filesystem::create_directory(extractPaths[table.inode]);
|
||||
}
|
||||
ndinode_counter++;
|
||||
if ((ndinode_counter + 3) == ndinode) // 3 for root, uroot and flat_path_table.
|
||||
if ((ndinode_counter + 1) == ndinode) // 1 for the image itself (root).
|
||||
end_reached = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,8 @@ void GameListFrame::RequestGameMenu(const QPoint& pos) {
|
|||
for (const auto& pair : psf.map_integers) {
|
||||
QTableWidgetItem* keyItem =
|
||||
new QTableWidgetItem(QString::fromStdString(pair.first));
|
||||
QTableWidgetItem* valueItem = new QTableWidgetItem(QString::number(pair.second));
|
||||
QTableWidgetItem* valueItem =
|
||||
new QTableWidgetItem(QString("0x").append(QString::number(pair.second, 16)));
|
||||
|
||||
tableWidget->setItem(row, 0, keyItem);
|
||||
tableWidget->setItem(row, 1, valueItem);
|
||||
|
@ -483,10 +484,9 @@ void GameListFrame::Refresh(const bool from_drive, const bool scroll_after) {
|
|||
game.pic_path = picpath.toStdString();
|
||||
game.name = psf.GetString("TITLE");
|
||||
game.serial = psf.GetString("TITLE_ID");
|
||||
game.fw = (QString("%1").arg(psf.GetInteger("SYSTEM_VER"), 8, 16, QLatin1Char('0')))
|
||||
.mid(1, 3)
|
||||
.insert(1, '.')
|
||||
.toStdString();
|
||||
u32 fw_int = psf.GetInteger("SYSTEM_VER");
|
||||
QString fw = QString::number(fw_int, 16).toUpper().left(3).insert(1, '.');
|
||||
game.fw = (fw_int == 0) ? "0.00" : fw.toStdString();
|
||||
game.version = psf.GetString("APP_VER");
|
||||
game.category = psf.GetString("CATEGORY");
|
||||
|
||||
|
@ -812,7 +812,7 @@ void GameListFrame::SetListMode(const bool& is_list) {
|
|||
|
||||
m_gui_settings->SetValue(gui::game_list_listMode, is_list);
|
||||
|
||||
Refresh(true);
|
||||
Refresh(false);
|
||||
|
||||
m_central_widget->setCurrentWidget(m_is_list_layout ? m_game_list : m_game_grid);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ void MainWindow::CreateConnects() {
|
|||
m_gui_settings->SetValue(gui::main_window_gamelist_visible, checked);
|
||||
});
|
||||
connect(ui->refreshGameListAct, &QAction::triggered, this,
|
||||
[this] { m_game_list_frame->Refresh(true); });
|
||||
[this] { m_game_list_frame->Refresh(false); });
|
||||
|
||||
connect(m_icon_size_act_group, &QActionGroup::triggered, this, [this](QAction* act) {
|
||||
static const int index_small = gui::get_Index(gui::game_list_icon_size_small);
|
||||
|
|
Loading…
Reference in New Issue