mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Linux flatpak. (#51)
* Add flatpak support. * Add game install directory override for flatpak. * Flatpak'ing. * Flatpak it some more. * We flat it, we pak it. * Flatpak'd. * The Marvelous Misadventures of Flatpak. * Attempt to change logic of NFD and show error. * Flattenpakken. * Use game install directory instead of current path. * Attempt to fix line endings.
This commit is contained in:
parent
279390f1fe
commit
bbbcdf1566
11 changed files with 148 additions and 23 deletions
|
|
@ -5,6 +5,10 @@ if (WIN32)
|
|||
option(SWA_D3D12 "Add D3D12 support for rendering" ON)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
option(SWA_FLATPAK "Configure the build for Flatpak compatibility." OFF)
|
||||
endif()
|
||||
|
||||
option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF)
|
||||
|
||||
function(BIN2C)
|
||||
|
|
@ -257,7 +261,11 @@ else()
|
|||
add_executable(UnleashedRecomp ${SWA_CXX_SOURCES})
|
||||
endif()
|
||||
|
||||
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME})
|
||||
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME})
|
||||
|
||||
if (SWA_FLATPAK)
|
||||
target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"")
|
||||
endif()
|
||||
|
||||
if (SWA_D3D12)
|
||||
find_package(directx-headers CONFIG REQUIRED)
|
||||
|
|
|
|||
|
|
@ -313,11 +313,11 @@ SWA_API uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName
|
|||
}
|
||||
else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
|
||||
{
|
||||
root = "./dlc";
|
||||
root = GAME_INSTALL_DIRECTORY "/dlc";
|
||||
}
|
||||
else
|
||||
{
|
||||
root = ".";
|
||||
root = GAME_INSTALL_DIRECTORY;
|
||||
}
|
||||
|
||||
XamRegisterContent(*pContentData, root);
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ void KiSystemStartup()
|
|||
{
|
||||
const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
|
||||
const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
|
||||
XamRegisterContent(gameContent, std::filesystem::exists("./game") ? "./game" : ".");
|
||||
XamRegisterContent(updateContent, "./update");
|
||||
XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
|
||||
XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update");
|
||||
|
||||
const auto savePath = GetSavePath();
|
||||
const auto saveName = "SYS-DATA";
|
||||
|
|
@ -70,7 +70,7 @@ void KiSystemStartup()
|
|||
XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
|
||||
|
||||
std::error_code ec;
|
||||
for (auto& file : std::filesystem::directory_iterator("./dlc", ec))
|
||||
for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec))
|
||||
{
|
||||
if (file.is_directory())
|
||||
{
|
||||
|
|
@ -151,13 +151,13 @@ int main(int argc, char *argv[])
|
|||
|
||||
HostStartup();
|
||||
|
||||
bool isGameInstalled = Installer::checkGameInstall(".");
|
||||
bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY);
|
||||
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
|
||||
if (runInstallerWizard)
|
||||
{
|
||||
Video::CreateHostDevice();
|
||||
|
||||
if (!InstallerWizard::Run(isGameInstalled && forceDLCInstaller))
|
||||
if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static double g_appearTime = 0.0;
|
|||
static double g_disappearTime = DBL_MAX;
|
||||
static bool g_isDisappearing = false;
|
||||
|
||||
static std::filesystem::path g_installPath = ".";
|
||||
static std::filesystem::path g_installPath;
|
||||
static std::filesystem::path g_gameSourcePath;
|
||||
static std::filesystem::path g_updateSourcePath;
|
||||
static std::array<std::filesystem::path, int(DLC::Count)> g_dlcSourcePaths;
|
||||
|
|
@ -135,6 +135,7 @@ static std::string g_currentMessagePrompt = "";
|
|||
static bool g_currentMessagePromptConfirmation = false;
|
||||
static std::list<std::filesystem::path> g_currentPickerResults;
|
||||
static std::atomic<bool> g_currentPickerResultsReady = false;
|
||||
static std::string g_currentPickerErrorMessage;
|
||||
static std::unique_ptr<std::thread> g_currentPickerThread;
|
||||
static bool g_currentPickerVisible = false;
|
||||
static bool g_currentPickerFolderMode = false;
|
||||
|
|
@ -872,15 +873,15 @@ static bool ConvertPathSet(const nfdpathset_t *pathSet, std::list<std::filesyste
|
|||
|
||||
for (nfdpathsetsize_t i = 0; i < pathSetCount; i++)
|
||||
{
|
||||
char *pathSetPath = nullptr;
|
||||
if (NFD_PathSet_GetPathU8(pathSet, i, &pathSetPath) != NFD_OKAY)
|
||||
nfdnchar_t *pathSetPath = nullptr;
|
||||
if (NFD_PathSet_GetPathN(pathSet, i, &pathSetPath) != NFD_OKAY)
|
||||
{
|
||||
filePaths.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
filePaths.emplace_back(std::filesystem::path(std::u8string_view((const char8_t *)(pathSetPath))));
|
||||
NFD_PathSet_FreePathU8(pathSetPath);
|
||||
filePaths.emplace_back(std::filesystem::path(pathSetPath));
|
||||
NFD_PathSet_FreePathN(pathSetPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -892,13 +893,11 @@ static void PickerThreadProcess()
|
|||
nfdresult_t result = NFD_ERROR;
|
||||
if (g_currentPickerFolderMode)
|
||||
{
|
||||
nfdpickfolderu8args_t openArgs = {};
|
||||
result = NFD_PickFolderMultipleU8_With(&pathSet, &openArgs);
|
||||
result = NFD_PickFolderMultipleN(&pathSet, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
nfdopendialogu8args_t openArgs = {};
|
||||
result = NFD_OpenDialogMultipleU8_With(&pathSet, &openArgs);
|
||||
result = NFD_OpenDialogMultipleN(&pathSet, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
if (result == NFD_OKAY)
|
||||
|
|
@ -906,6 +905,10 @@ static void PickerThreadProcess()
|
|||
bool pathsConverted = ConvertPathSet(pathSet, g_currentPickerResults);
|
||||
NFD_PathSet_Free(pathSet);
|
||||
}
|
||||
else if (result == NFD_ERROR)
|
||||
{
|
||||
g_currentPickerErrorMessage = NFD_GetError();
|
||||
}
|
||||
|
||||
g_currentPickerResultsReady = true;
|
||||
g_currentPickerVisible = false;
|
||||
|
|
@ -1343,6 +1346,13 @@ static void CheckPickerResults()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!g_currentPickerErrorMessage.empty())
|
||||
{
|
||||
g_currentMessagePrompt = g_currentPickerErrorMessage;
|
||||
g_currentMessagePromptConfirmation = false;
|
||||
g_currentPickerErrorMessage.clear();
|
||||
}
|
||||
|
||||
ParseSourcePaths(g_currentPickerResults);
|
||||
g_currentPickerResultsReady = false;
|
||||
g_currentPickerVisible = false;
|
||||
|
|
@ -1426,8 +1436,10 @@ void InstallerWizard::Shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
bool InstallerWizard::Run(bool skipGame)
|
||||
bool InstallerWizard::Run(std::filesystem::path installPath, bool skipGame)
|
||||
{
|
||||
g_installPath = installPath;
|
||||
|
||||
EmbeddedPlayer::Init();
|
||||
NFD_Init();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ struct InstallerWizard
|
|||
static void Init();
|
||||
static void Draw();
|
||||
static void Shutdown();
|
||||
static bool Run(bool skipGame);
|
||||
static bool Run(std::filesystem::path installPath, bool skipGame);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
|
||||
#define WINDOWPOS_CENTRED 0x2FFF0000
|
||||
|
||||
static inline std::vector<IConfigDef*> g_configDefinitions{};
|
||||
inline std::vector<IConfigDef*> g_configDefinitions;
|
||||
|
||||
CONFIG_DEFINE_ENUM_TEMPLATE(ELanguage)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@
|
|||
|
||||
#define USER_DIRECTORY "SWA"
|
||||
|
||||
#ifndef GAME_INSTALL_DIRECTORY
|
||||
#define GAME_INSTALL_DIRECTORY "."
|
||||
#endif
|
||||
|
||||
inline std::filesystem::path GetGamePath()
|
||||
{
|
||||
return std::filesystem::current_path();
|
||||
return GAME_INSTALL_DIRECTORY;
|
||||
}
|
||||
|
||||
inline std::filesystem::path GetUserPath()
|
||||
{
|
||||
if (std::filesystem::exists("portable.txt"))
|
||||
return std::filesystem::current_path();
|
||||
if (std::filesystem::exists(GAME_INSTALL_DIRECTORY "portable.txt"))
|
||||
return GAME_INSTALL_DIRECTORY;
|
||||
|
||||
std::filesystem::path userPath;
|
||||
|
||||
|
|
|
|||
10
flatpak/README.md
Normal file
10
flatpak/README.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Build
|
||||
```sh
|
||||
flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo --install builddir io.github.hedge_dev.unleashedrecomp.json
|
||||
```
|
||||
|
||||
Bundle
|
||||
```sh
|
||||
flatpak build-bundle repo io.github.hedge_dev.unleashedrecomp.flatpak io.github.hedge_dev.unleashedrecomp --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
```
|
||||
|
||||
7
flatpak/io.github.hedge_dev.unleashedrecomp.desktop
Normal file
7
flatpak/io.github.hedge_dev.unleashedrecomp.desktop
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Name=Unleashed Recompiled
|
||||
Exec=/app/bin/SWA
|
||||
Type=Application
|
||||
Icon=io.github.hedge_dev.unleashedrecomp
|
||||
Categories=Game;
|
||||
Comment=Static recompilation of Sonic Unleashed.
|
||||
58
flatpak/io.github.hedge_dev.unleashedrecomp.json
Normal file
58
flatpak/io.github.hedge_dev.unleashedrecomp.json
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"id": "io.github.hedge_dev.unleashedrecomp",
|
||||
"runtime": "org.freedesktop.Platform",
|
||||
"runtime-version": "23.08",
|
||||
"sdk": "org.freedesktop.Sdk",
|
||||
"sdk-extensions" : [ "org.freedesktop.Sdk.Extension.llvm18" ],
|
||||
"finish-args": [
|
||||
"--share=network",
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--device=all",
|
||||
"--filesystem=host",
|
||||
"--filesystem=/media",
|
||||
"--filesystem=/run/media",
|
||||
"--filesystem=/mnt"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "UnleashedRecomp",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"cmake --preset linux-release -DSWA_FLATPAK=ON",
|
||||
"cmake --build out/build/linux-release",
|
||||
"mkdir -p /app/bin",
|
||||
"cp out/build/linux-release/UnleashedRecomp/SWA /app/bin/SWA",
|
||||
"install -Dm644 UnleashedRecompResources/images/game_icon.png /app/share/icons/hicolor/128x128/apps/${FLATPAK_ID}.png",
|
||||
"install -Dm644 flatpak/io.github.hedge_dev.unleashedrecomp.metainfo.xml /app/share/metainfo/${FLATPAK_ID}.metainfo.xml",
|
||||
"install -Dm644 flatpak/io.github.hedge_dev.unleashedrecomp.desktop /app/share/applications/${FLATPAK_ID}.desktop"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"branch": "linux-flatpak",
|
||||
"disable-shallow-clone": true,
|
||||
"url": "https://github.com/hedge-dev/UnleashedRecomp.git"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"path": "default.xex",
|
||||
"dest": "UnleashedRecompLib/private"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"path": "shader.ar",
|
||||
"dest": "UnleashedRecompLib/private"
|
||||
}
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/llvm18/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm18/lib",
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
26
flatpak/io.github.hedge_dev.unleashedrecomp.metainfo.xml
Normal file
26
flatpak/io.github.hedge_dev.unleashedrecomp.metainfo.xml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>io.github.hedge_dev.unleashedrecomp</id>
|
||||
|
||||
<name>Unleashed Recompiled</name>
|
||||
<summary>Static recompilation of Sonic Unleashed.</summary>
|
||||
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
|
||||
<supports>
|
||||
<control>pointing</control>
|
||||
<control>keyboard</control>
|
||||
<control>touch</control>
|
||||
</supports>
|
||||
|
||||
<description>
|
||||
<p>
|
||||
A native PC port of Sonic Unleashed for Xbox 360 achieved through static recompilation.
|
||||
|
||||
https://github.com/hedge-dev/UnleashedRecomp
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<launchable type="desktop-id">io.github.hedge_dev.unleashedrecomp.desktop</launchable>
|
||||
</component>
|
||||
Loading…
Add table
Reference in a new issue