Fix Switch startup save path

This commit is contained in:
2026-06-09 01:13:07 +08:00
parent c87b245cea
commit 8bbb847a1b
5 changed files with 83 additions and 12 deletions
@@ -253,6 +253,11 @@ private:
bool running_ = false; bool running_ = false;
bool paused_ = false; bool paused_ = false;
bool shouldQuit_ = false; bool shouldQuit_ = false;
bool sdlInitialized_ = false;
#ifdef __SWITCH__
bool switchPlatformInitialized_ = false;
bool switchRomfsMounted_ = false;
#endif
bool textInputEnabled_ = false; bool textInputEnabled_ = false;
bool immEnabled_ = false; bool immEnabled_ = false;
int textInputRequestCount_ = 0; int textInputRequestCount_ = 0;
@@ -389,6 +389,7 @@ private:
fs::path toPath(const std::string &path) const; fs::path toPath(const std::string &path) const;
std::string fromPath(const fs::path &path) const; std::string fromPath(const fs::path &path) const;
std::string resolveFullPath(const std::string &path) const; std::string resolveFullPath(const std::string &path) const;
bool isDevicePath(const std::string &path) const;
std::string workingDirectory_; std::string workingDirectory_;
std::string assetRoot_; std::string assetRoot_;
@@ -58,6 +58,7 @@ bool Application::init(const AppConfig& config) {
{ {
ScopedStartupTrace stageTrace("switchInit"); ScopedStartupTrace stageTrace("switchInit");
switchInit(); switchInit();
switchPlatformInitialized_ = true;
} }
#endif #endif
@@ -80,7 +81,11 @@ bool Application::init(const AppConfig& config) {
} }
void Application::shutdown() { void Application::shutdown() {
if (!initialized_) if (!initialized_ && !sdlInitialized_
#ifdef __SWITCH__
&& !switchPlatformInitialized_ && !switchRomfsMounted_
#endif
)
return; return;
running_ = false; running_ = false;
@@ -115,17 +120,25 @@ void Application::shutdown() {
window_ = nullptr; window_ = nullptr;
} }
if (sdlInitialized_) {
SDL_Quit();
sdlInitialized_ = false;
}
#ifdef __SWITCH__
if (switchRomfsMounted_) {
romfsExit();
switchRomfsMounted_ = false;
}
#endif
// 平台相关清理 // 平台相关清理
#ifdef __SWITCH__ #ifdef __SWITCH__
switchShutdown(); if (switchPlatformInitialized_) {
#endif switchShutdown();
switchPlatformInitialized_ = false;
// 退出 SDL(添加重复调用保护)
static bool sdlQuitCalled = false;
if (!sdlQuitCalled) {
SDL_Quit();
sdlQuitCalled = true;
} }
#endif
ObjectRegistry::get().clear(); ObjectRegistry::get().clear();
@@ -153,7 +166,8 @@ bool Application::initCoreModules() {
SDL_Log("Asset working directory: %s", workingDir.c_str()); SDL_Log("Asset working directory: %s", workingDir.c_str());
} }
#else #else
if (R_SUCCEEDED(romfsInit())) { if (!switchRomfsMounted_ && R_SUCCEEDED(romfsInit())) {
switchRomfsMounted_ = true;
asset.setWorkingDirectory("romfs:/"); asset.setWorkingDirectory("romfs:/");
} else { } else {
asset.setWorkingDirectory("/switch/Frostbite2D/" + config_.appName); asset.setWorkingDirectory("/switch/Frostbite2D/" + config_.appName);
@@ -163,7 +177,11 @@ bool Application::initCoreModules() {
{ {
ScopedStartupTrace stageTrace("SaveSystem::init"); ScopedStartupTrace stageTrace("SaveSystem::init");
if (!SaveSystem::get().init()) { SaveSystemConfig saveConfig;
#ifdef __SWITCH__
saveConfig.saveRoot = "sdmc:/switch/NSUnknownGame/save";
#endif
if (!SaveSystem::get().init(saveConfig)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize save system"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize save system");
return false; return false;
} }
@@ -175,6 +193,7 @@ bool Application::initCoreModules() {
SDL_Log("Failed to initialize SDL: %s", SDL_GetError()); SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
return false; return false;
} }
sdlInitialized_ = true;
} }
// Disable text input by default. UI widgets should enable it explicitly. // Disable text input by default. UI widgets should enable it explicitly.
+18 -1
View File
@@ -12,6 +12,23 @@ Asset &Asset::get() {
return instance; return instance;
} }
bool Asset::isDevicePath(const std::string &path) const {
auto colon = path.find(':');
if (colon == std::string::npos || colon == 0) {
return false;
}
for (size_t i = 0; i < colon; ++i) {
unsigned char ch = static_cast<unsigned char>(path[i]);
if (!std::isalnum(ch) && ch != '_' && ch != '-') {
return false;
}
}
return colon + 1 < path.size() &&
(path[colon + 1] == '/' || path[colon + 1] == '\\');
}
fs::path Asset::toPath(const std::string &path) const { fs::path Asset::toPath(const std::string &path) const {
#ifdef _WIN32 #ifdef _WIN32
return fs::u8path(path); return fs::u8path(path);
@@ -34,7 +51,7 @@ std::string Asset::resolveFullPath(const std::string &path) const {
} }
fs::path p = toPath(path); fs::path p = toPath(path);
if (p.is_absolute()) { if (p.is_absolute() || isDevicePath(path)) {
return path; return path;
} }
+29
View File
@@ -12,6 +12,34 @@
#include <frostbite2D/core/application.h> #include <frostbite2D/core/application.h>
#include <frostbite2D/scene/scene_manager.h> #include <frostbite2D/scene/scene_manager.h>
#ifdef __SWITCH__
namespace {
void showSwitchInitFailure() {
consoleInit(nullptr);
PadState pad;
padInitializeDefault(&pad);
std::puts("NS Unknown Game");
std::puts("");
std::puts("Switch init failed.");
std::puts("Check nxlink/Ryujinx logs for the failed init stage.");
std::puts("");
std::puts("Press + to exit.");
while (appletMainLoop()) {
padUpdate(&pad);
if (padGetButtonsDown(&pad) & HidNpadButton_Plus) {
break;
}
consoleUpdate(nullptr);
}
consoleExit(nullptr);
}
} // namespace
#endif
int main(int argc, char** argv) { int main(int argc, char** argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
@@ -45,6 +73,7 @@ int main(int argc, char** argv) {
if (!app.init(config)) { if (!app.init(config)) {
#ifdef __SWITCH__ #ifdef __SWITCH__
std::puts("NS Unknown Game Switch init failed."); std::puts("NS Unknown Game Switch init failed.");
showSwitchInitFailure();
#else #else
std::puts("NS Unknown Game init failed."); std::puts("NS Unknown Game init failed.");
#endif #endif