Fix non-portable (#532)

* Fix for non-portable builds

* submodule update Torch, [TEMP] libultraship

* submodule update libultraship

* place assets in exe's dir on post build
This commit is contained in:
AltoXorg 2025-08-10 01:25:46 +08:00 committed by GitHub
parent 334fdeafd2
commit db01cf3d6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 28 deletions

View File

@ -93,9 +93,6 @@ set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endif() endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config.yml" "${CMAKE_BINARY_DIR}/config.yml")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/yamls/" "${CMAKE_BINARY_DIR}/yamls/")
if (MSVC) if (MSVC)
set(CPP "${CMAKE_C_COMPILER}" "/EP") set(CPP "${CMAKE_C_COMPILER}" "/EP")
else() else()
@ -656,6 +653,13 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
endif() endif()
endif() endif()
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMENT "Copying asset yamls..."
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config.yml" "$<TARGET_FILE_DIR:Spaghettify>/config.yml"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/yamls/" "$<TARGET_FILE_DIR:Spaghettify>/yamls/"
)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch") if(NOT CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
include(ExternalProject) include(ExternalProject)
ExternalProject_Add(TorchExternal ExternalProject_Add(TorchExternal

@ -1 +1 @@
Subproject commit 5e33d3e7cd0396f847923cd6c471eaf324e90351 Subproject commit 09dfab5fb2a9a047a6e268dc9db2daad9b2ce5f0

View File

@ -76,6 +76,8 @@ bool CreateDirectoryRecursive(std::string const& dirName, std::error_code& err)
} }
GameEngine::GameEngine() { GameEngine::GameEngine() {
// Initialize context properties early to recognize paths properly for non-portable builds
this->context = Ship::Context::CreateUninitializedInstance("Spaghetti Kart", "spaghettify", "spaghettify.cfg.json");
const std::string main_path = Ship::Context::GetPathRelativeToAppDirectory("mk64.o2r"); const std::string main_path = Ship::Context::GetPathRelativeToAppDirectory("mk64.o2r");
const std::string assets_path = Ship::Context::LocateFileAcrossAppDirs("spaghetti.o2r"); const std::string assets_path = Ship::Context::LocateFileAcrossAppDirs("spaghetti.o2r");
@ -121,8 +123,6 @@ GameEngine::GameEngine() {
} }
} }
this->context = Ship::Context::CreateUninitializedInstance("Spaghetti Kart", "spaghettify", "spaghettify.cfg.json");
this->context->InitConfiguration(); // without this line InitConsoleVariables fails at Config::Reload() this->context->InitConfiguration(); // without this line InitConsoleVariables fails at Config::Reload()
this->context->InitConsoleVariables(); // without this line the controldeck constructor failes in this->context->InitConsoleVariables(); // without this line the controldeck constructor failes in
// ShipDeviceIndexMappingManager::UpdateControllerNamesFromConfig() // ShipDeviceIndexMappingManager::UpdateControllerNamesFromConfig()

View File

@ -56,7 +56,10 @@ std::optional<std::string> GameExtractor::ValidateChecksum() const {
} }
bool GameExtractor::GenerateOTR() const { bool GameExtractor::GenerateOTR() const {
Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false); const std::string assets_path = Ship::Context::GetAppBundlePath();
const std::string game_path = Ship::Context::GetAppDirectoryPath();
Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false, assets_path, game_path);
try { try {
Companion::Instance->Init(ExportType::Binary); Companion::Instance->Init(ExportType::Binary);

View File

@ -1,5 +1,6 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <format>
#include <libultraship.h> #include <libultraship.h>
#include <libultraship/libultra.h> #include <libultraship/libultra.h>
@ -15,10 +16,19 @@ typedef struct ControllerPak {
FILE* file; FILE* file;
} ControllerPak; } ControllerPak;
std::string Pfs_PakFile_GetPath(u8 file_no) {
return Ship::Context::GetPathRelativeToAppDirectory(std::format("controllerPak_file_{}.sav", file_no));
}
std::string Pfs_PakHeader_GetPath() {
return Ship::Context::GetPathRelativeToAppDirectory("controllerPak_header.sav");
}
bool Pfs_PakHeader_Write(u32* file_size, u32* game_code, u16* company_code, u8* ext_name, u8* game_name, u8 fileIndex) { bool Pfs_PakHeader_Write(u32* file_size, u32* game_code, u16* company_code, u8* ext_name, u8* game_name, u8 fileIndex) {
ControllerPak pak; ControllerPak pak;
pak.header = fopen("controllerPak_header.sav", "w+b"); std::string filename = Pfs_PakHeader_GetPath();
pak.header = fopen(filename.c_str(), "w+b");
if (!pak.header) { if (!pak.header) {
return false; return false;
@ -51,7 +61,8 @@ bool Pfs_PakHeader_Read(u32* file_size, u32* game_code, u16* company_code, char*
u8 fileIndex) { u8 fileIndex) {
ControllerPak pak; ControllerPak pak;
pak.header = fopen("controllerPak_header.sav", "rb"); std::string filename = Pfs_PakHeader_GetPath();
pak.header = fopen(filename.c_str(), "rb");
if(!pak.header) { if(!pak.header) {
return false; return false;
@ -91,12 +102,13 @@ extern "C" s32 osPfsInit(OSMesgQueue* queue, OSPfs* pfs, int channel) {
pfs->status = PFS_INITIALIZED; pfs->status = PFS_INITIALIZED;
ControllerPak pak; ControllerPak pak;
std::string header_file = Pfs_PakHeader_GetPath();
pak.header = fopen("controllerPak_header.sav", "rb"); pak.header = fopen(header_file.c_str(), "rb");
// If a header file doesn't exist, create it. // If a header file doesn't exist, create it.
if(!pak.header) { if(!pak.header) {
pak.header = fopen("controllerPak_header.sav", "w+b"); pak.header = fopen(header_file.c_str(), "w+b");
if (!pak.header) { if (!pak.header) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
} }
@ -108,8 +120,9 @@ extern "C" s32 osPfsInit(OSMesgQueue* queue, OSPfs* pfs, int channel) {
extern "C" s32 osPfsFreeBlocks(OSPfs* pfs, s32* bytes_not_used) { extern "C" s32 osPfsFreeBlocks(OSPfs* pfs, s32* bytes_not_used) {
ControllerPak pak; ControllerPak pak;
std::string header_file = Pfs_PakHeader_GetPath();
pak.header = fopen("controllerPak_header.sav", "rb"); pak.header = fopen(header_file.c_str(), "rb");
if (!pak.header) { if (!pak.header) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
@ -178,9 +191,8 @@ extern "C" s32 osPfsAllocateFile(OSPfs* pfs, u16 company_code, u32 game_code, u8
} }
/* Create empty file */ /* Create empty file */
char filename[100]; std::string filename = Pfs_PakFile_GetPath(freeFileIndex);
sprintf(filename, "controllerPak_file_%d.sav", freeFileIndex); pak.file = fopen(filename.c_str(), "w+b");
pak.file = fopen(filename, "w+b");
if (!pak.file) { if (!pak.file) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
@ -214,9 +226,8 @@ extern "C" s32 osPfsFileState(OSPfs* pfs, s32 file_no, OSPfsState* state) {
// games call this function 16 times, once per file // games call this function 16 times, once per file
// fills the incoming state with the information inside the header of the pak. // fills the incoming state with the information inside the header of the pak.
char filename[100]; std::string filename = Pfs_PakFile_GetPath(file_no);
sprintf(filename, "controllerPak_file_%d.sav", file_no); FILE* file = fopen(filename.c_str(), "rb");
FILE* file = fopen(filename, "rb");
if (file) { if (file) {
fclose(file); fclose(file);
} else { } else {
@ -275,10 +286,9 @@ extern "C" s32 osPfsFindFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* ga
extern "C" s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, int offset, int size_in_bytes, u8* data_buffer) { extern "C" s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, int offset, int size_in_bytes, u8* data_buffer) {
ControllerPak pak; ControllerPak pak;
std::string filename = Pfs_PakFile_GetPath(file_no);
char filename[100]; pak.file = fopen(filename.c_str(), flag == 0 ? "r+b" : "w+b");
sprintf(filename, "controllerPak_file_%d.sav", file_no);
pak.file = fopen(filename, flag == 0 ? "r+b" : "w+b");
if (!pak.file) { if (!pak.file) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
@ -332,8 +342,8 @@ extern "C" s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8*
u32 file_size_ = 0; u32 file_size_ = 0;
u32 game_code_ = 0; u32 game_code_ = 0;
u16 company_code_ = 0; u16 company_code_ = 0;
char ext_name_[4] = { 0 }; char ext_name_[EXT_NAME_SIZE] = { 0 };
char game_name_[16] = { 0 }; char game_name_[GAME_NAME_SIZE] = { 0 };
if (!Pfs_PakHeader_Read(&file_size_, &game_code_, &company_code_, ext_name_, game_name_, i)) { if (!Pfs_PakHeader_Read(&file_size_, &game_code_, &company_code_, ext_name_, game_name_, i)) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
@ -345,7 +355,8 @@ extern "C" s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8*
if ((game_code == game_code_) && (strcmp((const char*) game_name, (const char*) game_name_) == 0) && if ((game_code == game_code_) && (strcmp((const char*) game_name, (const char*) game_name_) == 0) &&
strcmp((const char*) ext_name, (const char*) ext_name_) == 0) { strcmp((const char*) ext_name, (const char*) ext_name_) == 0) {
// File found // File found
pak.header = fopen("controllerPak_header.sav", "w+b"); std::string header_file = Pfs_PakHeader_GetPath();
pak.header = fopen(header_file.c_str(), "w+b");
if(!pak.header) { if(!pak.header) {
return PFS_ERR_INVALID; return PFS_ERR_INVALID;
@ -365,10 +376,9 @@ extern "C" s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8*
free(zero_block); free(zero_block);
fclose(pak.header); fclose(pak.header);
char filename[100];
sprintf(filename, "controllerPak_file_%d.sav", i);
remove(filename); std::string filename = Pfs_PakFile_GetPath(i);
remove(filename.c_str());
return PFS_NO_ERROR; return PFS_NO_ERROR;
} }

2
torch

@ -1 +1 @@
Subproject commit 5773373b3620e4a6bc6c92fdc4690d66741c086d Subproject commit cd92cc0f161c5e79e36f5dda0d0029edd3fc8d50