- 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:
Younes 2024-03-08 05:38:19 -07:00 committed by GitHub
parent 12a8cf5ee9
commit 8ba6d7add0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 9 deletions

View File

@ -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;
}
}

View File

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

View File

@ -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);