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:
Darío 2024-12-18 14:54:46 -03:00 committed by GitHub
parent 279390f1fe
commit bbbcdf1566
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 148 additions and 23 deletions

View file

@ -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)
@ -259,6 +263,10 @@ endif()
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)
find_package(directx12-agility CONFIG REQUIRED)

View file

@ -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);

View file

@ -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;
}

View file

@ -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();

View file

@ -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);
};

View file

@ -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)
{

View file

@ -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
View 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
```

View 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.

View 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"
]
}
}
]
}

View 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>