Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d27bf5492 | ||
|
|
6b85d2cef1 | ||
|
|
aae9930f5e | ||
|
|
eca19aa4bf |
@@ -72,7 +72,7 @@
|
||||
"Append folder with .xci": "Додати до теки .xci",
|
||||
"Trim XCI": "Обрізати XCI",
|
||||
"Label trimmed XCI": "Позначити обрізаний XCI",
|
||||
"Multi-threaded USB transfer": "Многопоточ. передача USB",
|
||||
"Multi-threaded USB transfer": "Багатопотокова передача USB",
|
||||
"Dump All Bins": "Дамп всіх BIN-файлів",
|
||||
"Dump XCI": "Дамп XCI",
|
||||
"Dump Card ID Set": "Дамп набору ID картриджа",
|
||||
@@ -116,8 +116,8 @@
|
||||
"SSID:": "SSID:",
|
||||
"Passphrase:": "Кодова фраза:",
|
||||
"Failed to install, press B to exit...": "Не вдалося встановити через FTP, натисніть B для виходу...",
|
||||
"Install success!": "Встановлення через FTP успішно завершено.",
|
||||
"Install failed!": "Встановлення через FTP не вдалося.",
|
||||
"Install success!": "Успішно встановлено",
|
||||
"Install failed!": "Встановлення не вдалося.",
|
||||
"USB Install": "Встановлення через USB",
|
||||
"USB": "USB",
|
||||
"Connected, waiting for file list...": "Підключено, очікування списку файлів...",
|
||||
@@ -206,8 +206,8 @@
|
||||
"Slow": "Повільно",
|
||||
"Normal": "Середнє",
|
||||
"Fast": "Швидко",
|
||||
"Set left-side menu": "Ліве меню",
|
||||
"Set right-side menu": "Праве меню",
|
||||
"Set left-side menu": "Ліве меню (L)",
|
||||
"Set right-side menu": "Праве меню (R)",
|
||||
"Install options": "Опції встановлення",
|
||||
"Install Options": "Опції встановлення",
|
||||
"Enable sysmmc": "Дозволити в sysMMC",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(sphaira_VERSION 0.13.1)
|
||||
set(sphaira_VERSION 0.13.3)
|
||||
|
||||
project(sphaira
|
||||
VERSION ${sphaira_VERSION}
|
||||
|
||||
@@ -227,6 +227,10 @@ public:
|
||||
|
||||
AccountProfileBase base;
|
||||
if (R_SUCCEEDED(accountProfileGet(&profile, nullptr, &base))) {
|
||||
// sometimes the uid for the acc can differ to the base.
|
||||
base.uid = uids[i];
|
||||
log_write("[ACC] found uid: 0x%016lX%016lX\n", uids[i].uid[0], uids[i].uid[1]);
|
||||
log_write("[ACC] base uid: 0x%016lX%016lX\n", base.uid.uid[0], base.uid.uid[1]);
|
||||
out.emplace_back(base);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +185,6 @@ Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& _path,
|
||||
FsPath new_path{};
|
||||
std::snprintf(new_path, sizeof(new_path), "%.*s", (int)(last_slash - _path.s), _path.s);
|
||||
R_TRY(CreateDirectoryRecursively(fs, new_path, ignore_read_only));
|
||||
fsFsCommit(fs);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -1045,25 +1045,35 @@ Result Menu::DumpGames(u32 flags) {
|
||||
bool is_trimmed = false;
|
||||
Result trim_rc = 0;
|
||||
if ((flags & DumpFileFlag_XCI) && m_storage_trimmed_size < m_storage_total_size) {
|
||||
u8 temp{};
|
||||
if (R_FAILED(trim_rc = GcStorageRead(&temp, m_storage_trimmed_size, sizeof(temp)))) {
|
||||
log_write("[GC] WARNING! GameCard is already trimmed: 0x%X FlashError: %u\n", trim_rc, trim_rc == 0x13D002);
|
||||
const auto start_offset = std::min<s64>(0, m_storage_trimmed_size - 0x4000);
|
||||
// works on fw 1.2.0 and below.
|
||||
std::vector<u8> temp(1024*1024*1);
|
||||
if (R_FAILED(trim_rc = GcStorageRead(temp.data(), m_storage_trimmed_size, std::min<s64>(temp.size(), m_storage_total_size - start_offset)))) {
|
||||
log_write("[GC] WARNING1! GameCard is already trimmed: 0x%X FlashError: %u\n", trim_rc, trim_rc == 0x13D002);
|
||||
is_trimmed = true;
|
||||
}
|
||||
|
||||
if (!is_trimmed) {
|
||||
// works on fw 1.2.0 and below.
|
||||
if (R_FAILED(trim_rc = GcStorageRead(temp.data(), m_storage_total_size - temp.size(), temp.size()))) {
|
||||
log_write("[GC] WARNING2! GameCard is already trimmed: 0x%X FlashError: %u\n", trim_rc, trim_rc == 0x13D002);
|
||||
is_trimmed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if trimmed and the user wants to dump the full xci, error.
|
||||
if ((flags & DumpFileFlag_XCI) && is_trimmed && App::GetApp()->m_dump_trim_xci.Get()) {
|
||||
App::PushErrorBox(trim_rc, "GameCard is already trimmed!"_i18n);
|
||||
} else if ((flags & DumpFileFlag_XCI) && is_trimmed) {
|
||||
App::Push(std::make_shared<ui::OptionBox>(
|
||||
"WARNING: GameCard is already trimmed!"_i18n,
|
||||
"Back"_i18n, "Continue"_i18n, 0, [&](auto op_index){
|
||||
if (op_index && *op_index) {
|
||||
do_dump(flags);
|
||||
}
|
||||
}
|
||||
}, m_icon
|
||||
));
|
||||
} else if ((flags & DumpFileFlag_XCI) && is_trimmed) {
|
||||
App::PushErrorBox(trim_rc, "GameCard is trimmed, full dump is not possible!"_i18n);
|
||||
} else {
|
||||
do_dump(flags);
|
||||
}
|
||||
|
||||
@@ -815,6 +815,9 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} {
|
||||
|
||||
if (it != m_accounts.end()) {
|
||||
m_account_index = std::distance(m_accounts.begin(), it);
|
||||
log_write("[SAVE] found account uid at: %zu\n", m_account_index);
|
||||
} else {
|
||||
log_write("[SAVE] account uid is not found: 0x%016lX%016lX\n", uid.uid[0], uid.uid[1]);
|
||||
}
|
||||
|
||||
for (auto& e : ncm_entries) {
|
||||
@@ -936,10 +939,26 @@ void Menu::SetIndex(s64 index) {
|
||||
m_list->SetYoff(0);
|
||||
}
|
||||
|
||||
if (m_accounts.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
u64 id{};
|
||||
if (!m_entries.empty()) {
|
||||
if (m_data_type == FsSaveDataType_System || m_data_type == FsSaveDataType_SystemBcat) {
|
||||
id = m_entries[m_index].system_save_data_id;
|
||||
} else {
|
||||
id = m_entries[m_index].application_id;
|
||||
}
|
||||
|
||||
this->SetSubHeading(std::to_string(m_index + 1) + " / " + std::to_string(m_entries.size()));
|
||||
} else {
|
||||
this->SetSubHeading("0 / 0");
|
||||
}
|
||||
|
||||
char title[0x40];
|
||||
std::snprintf(title, sizeof(title), "%s | %016lX", m_accounts[m_account_index].nickname, m_entries[m_index].application_id);
|
||||
std::snprintf(title, sizeof(title), "%s | %016lX", m_accounts[m_account_index].nickname, id);
|
||||
SetTitleSubHeading(title);
|
||||
this->SetSubHeading(std::to_string(m_index + 1) + " / " + std::to_string(m_entries.size()));
|
||||
}
|
||||
|
||||
void Menu::ScanHomebrew() {
|
||||
@@ -947,7 +966,10 @@ void Menu::ScanHomebrew() {
|
||||
TimeStamp ts;
|
||||
|
||||
FreeEntries();
|
||||
ClearSelection();
|
||||
m_entries.reserve(ENTRY_CHUNK_COUNT);
|
||||
m_is_reversed = false;
|
||||
m_dirty = false;
|
||||
|
||||
if (m_accounts.empty()) {
|
||||
return;
|
||||
@@ -958,7 +980,9 @@ void Menu::ScanHomebrew() {
|
||||
GetFsSaveAttr(m_accounts[m_account_index], m_data_type, space_id, filter);
|
||||
|
||||
FsSaveDataInfoReader reader;
|
||||
fsOpenSaveDataInfoReaderWithFilter(&reader, space_id, &filter);
|
||||
if (R_FAILED(fsOpenSaveDataInfoReaderWithFilter(&reader, space_id, &filter))) {
|
||||
log_write("[SAVE] failed to open reader\n");
|
||||
}
|
||||
ON_SCOPE_EXIT(fsSaveDataInfoReaderClose(&reader));
|
||||
|
||||
std::vector<FsSaveDataInfo> info_list(ENTRY_CHUNK_COUNT);
|
||||
@@ -979,8 +1003,6 @@ void Menu::ScanHomebrew() {
|
||||
}
|
||||
}
|
||||
|
||||
m_is_reversed = false;
|
||||
m_dirty = false;
|
||||
log_write("games found: %zu time_taken: %.2f seconds %zu ms %zu ns\n", m_entries.size(), ts.GetSecondsD(), ts.GetMs(), ts.GetNs());
|
||||
this->Sort();
|
||||
SetIndex(0);
|
||||
|
||||
Reference in New Issue
Block a user