Fix Switch startup save path
This commit is contained in:
@@ -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__
|
||||||
|
if (switchPlatformInitialized_) {
|
||||||
switchShutdown();
|
switchShutdown();
|
||||||
#endif
|
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.
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user