Zarchive Loading (#724)

* Simplify archive loading and harden filesystem integration

* Restore directory entry name length assertion

* Keep graphics-dependent filesystem tests out of CI

---------

Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
Aspen
2026-09-28 16:06:44 -04:00
committed by GitHub
parent 8e61798bfd
commit 4b0de1b672
29 changed files with 1956 additions and 262 deletions
+15 -4
View File
@@ -1,3 +1,4 @@
#include "common/archive.h"
#include "common/common.h"
#include "common/dateTime.h"
#include "common/debug.h"
@@ -10,6 +11,7 @@
#include <charconv>
#include <cstdio>
#include <filesystem>
#include <string_view>
#include <vector>
#include <fmt/format.h>
@@ -40,9 +42,9 @@ static std::string GetBuildString() {
static void PrintUsage() {
::printf("%s\n", GetBuildString().c_str());
::printf("kyty_emulator --game <dir|elf> [options]\n\n");
::printf("kyty_emulator --game <dir|elf|zar> [options]\n\n");
::printf("Options:\n");
::printf(" --game <dir|elf> Game directory or ELF to load.\n");
::printf(" --game <dir|elf|zar> Game directory, ELF, or ZArchive to load.\n");
::printf(" --game-patch <json> ETAHen cheat file.\n");
::printf(" --screen-width <num> Window width. Default: 1280.\n");
::printf(" --screen-height <num> Window height. Default: 720.\n");
@@ -234,12 +236,20 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
return false;
}
value = Common::FixFilenameSlash(value);
value = Common::FixFilenameSlash(value);
const auto path = Common::PathFromUtf8(value);
if (Common::File::IsDirectoryExisting(path)) {
options.app0_dir = path;
options.elf = "/app0/eboot.bin";
} else if (Common::IsSupportedArchive(path) && Common::File::IsFileExisting(path)) {
const auto root = Common::MakeArchivePath(path);
if (!Common::File::IsFileExisting(root / "eboot.bin")) {
::printf("Archive does not contain eboot.bin: %s\n", value.c_str());
return false;
}
options.app0_dir = root;
options.elf = "/app0/eboot.bin";
} else if (Common::File::IsFileExisting(path)) {
options.app0_dir = path.parent_path();
@@ -249,7 +259,8 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
options.elf = std::filesystem::path("/app0") / path.filename();
} else {
::printf("--game must point to an existing directory or ELF: %s\n", value.c_str());
::printf("--game must point to an existing directory, ELF, or archive: %s\n",
value.c_str());
return false;
}
} else if (arg == "--game-patch") {