4 Commits

Author SHA1 Message Date
ITotalJustice
4d27bf5492 bump version for new release 0.13.2 -> 0.13.3 2025-06-19 11:40:42 +01:00
ITotalJustice
6b85d2cef1 fix account save listing where the profile uid differs from the account uid.
i am unsure how this happens, as i thought the profile uid was the same as the account uid, but apparently this can differ.
on the same switch in sysmmc, the uid's match, so everything works.
again on the same switch, created in emummc, same account, the uid differs...

i performed the same test but on another 2 switches, and the uid's all match, so i am not sure what causes them to change.

in any case, using the uid from the account is the intended behaviour anyway, so this commit fixes that.
2025-06-19 11:37:08 +01:00
xHR
aae9930f5e Updated UK translation (#180)
* fixed long strings, translate untranslated

* Updated UK translation
2025-06-19 11:36:42 +01:00
ITotalJustice
eca19aa4bf fix hdd createDirWithPath, improve flashcart detection in gc menu, bump version for new release 0.13.1 -> 0.13.2 2025-06-18 23:17:58 +01:00
6 changed files with 53 additions and 18 deletions

View File

@@ -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",

View File

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

View File

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

View File

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

View File

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

View File

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