commit:     0e973d719b511e3b8fa0ba06504fd0009efd3402
Author:     James Le Cuirot <chewi <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 19 22:23:10 2024 +0000
Commit:     James Le Cuirot <chewi <AT> gentoo <DOT> org>
CommitDate: Thu Dec 19 22:40:42 2024 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=0e973d71

games-arcade/jazz2: Backport changes to use system-wide game data

Signed-off-by: James Le Cuirot <chewi <AT> gentoo.org>

 games-arcade/jazz2/files/jazz2-system-source.patch | 226 +++++++++++++++++++++
 .../{jazz2-3.0.0.ebuild => jazz2-3.0.0-r1.ebuild}  |  33 ++-
 2 files changed, 240 insertions(+), 19 deletions(-)

diff --git a/games-arcade/jazz2/files/jazz2-system-source.patch 
b/games-arcade/jazz2/files/jazz2-system-source.patch
new file mode 100644
index 000000000000..35cbb3a9d9c3
--- /dev/null
+++ b/games-arcade/jazz2/files/jazz2-system-source.patch
@@ -0,0 +1,226 @@
+diff --git a/README.md b/README.md
+index fe466e50..e91dd4ed 100644
+--- a/README.md
++++ b/README.md
+@@ -46,7 +46,7 @@ Jazz² Resurrection is reimplementation of the game **Jazz 
Jackrabbit 2** releas
+ * Install dependencies: `sudo apt install libglew2.2 libglfw3 libsdl2-2.0-0 
libopenal1 libvorbisfile3 libopenmpt0`
+   * Alternatively, install provided `.deb` or `.rpm` package and dependencies 
should be installed automatically
+ * Copy contents of original *Jazz Jackrabbit 2* directory to `‹Game›/Source/`
+-  * If packages are used, the files must be copied to `~/.local/share/Jazz² 
Resurrection/Source/` instead
++  * If packages are used, the files must be copied to `~/.local/share/Jazz² 
Resurrection/Source/` or `/usr/local/share/Jazz² Resurrection/Source/` instead, 
please follow instructions of specific package
+ * Run `‹Game›/jazz2` or `‹Game›/jazz2_sdl2` application
+   * If packages are used, the game should be visible in application list
+ 
+diff --git a/Sources/Common.h b/Sources/Common.h
+index 865d42bb..cf6f112c 100644
+--- a/Sources/Common.h
++++ b/Sources/Common.h
+@@ -33,6 +33,10 @@
+ 
+ #include <stdlib.h>
+ 
++#if !defined(NCINE_INSTALL_PREFIX) && defined(DEATH_TARGET_UNIX)
++#     define NCINE_INSTALL_PREFIX "/usr/local"
++#endif
++
+ // Check platform-specific capabilities
+ #if defined(WITH_SDL) || defined(DEATH_TARGET_WINDOWS_RT)
+ #     define NCINE_HAS_GAMEPAD_RUMBLE
+diff --git a/Sources/Jazz2/ContentResolver.cpp 
b/Sources/Jazz2/ContentResolver.cpp
+index 737582db..a7c5d460 100644
+--- a/Sources/Jazz2/ContentResolver.cpp
++++ b/Sources/Jazz2/ContentResolver.cpp
+@@ -207,7 +207,7 @@ namespace Jazz2
+ #     elif defined(NCINE_OVERRIDE_CONTENT_PATH)
+               _contentPath = NCINE_OVERRIDE_CONTENT_PATH;
+ #     else
+-              _contentPath = "/usr/share/" NCINE_LINUX_PACKAGE "/Content/";
++              _contentPath = NCINE_INSTALL_PREFIX "/share/" 
NCINE_LINUX_PACKAGE "/Content/";
+ #     endif
+ #     if defined(NCINE_PACKAGED_CONTENT_PATH)
+               // If Content is packaged with binaries, always use standard 
XDG paths for everything else
+@@ -226,18 +226,25 @@ namespace Jazz2
+                       auto localStorage = fs::GetLocalStorage();
+                       if (!localStorage.empty()) {
+                               // Use "$XDG_DATA_HOME/Jazz² Resurrection/" if 
exists (for backward compatibility), otherwise 
"$XDG_DATA_HOME/{NCINE_LINUX_PACKAGE}/"
+-                              _sourcePath = fs::CombinePath(localStorage, 
"Jazz² Resurrection/Source/"_s);
+-                              if (fs::DirectoryExists(_sourcePath)) {
+-                                      _cachePath = 
fs::CombinePath(localStorage, "Jazz² Resurrection/Cache/"_s);
+-                              } else {
++                              _cachePath = fs::CombinePath(localStorage, 
"Jazz² Resurrection/Cache/"_s);
++                              if (!fs::DirectoryExists(_cachePath)) {
+                                       auto appData = 
fs::CombinePath(localStorage, NCINE_LINUX_PACKAGE);
+-                                      _sourcePath = fs::CombinePath(appData, 
"Source/"_s);
+                                       _cachePath = fs::CombinePath(appData, 
"Cache/"_s);
+                               }
+                       } else {
+-                              _sourcePath = "Source/"_s;
+                               _cachePath = "Cache/"_s;
+                       }
++
++                      // Prefer system-wide Source only if it exists and 
local one doesn't exist
++                      _sourcePath = 
fs::CombinePath(fs::GetDirectoryName(_cachePath), "Source/"_s);
++                      if 
(!fs::FindPathCaseInsensitive(fs::CombinePath(_sourcePath, "Anims.j2a"_s)) &&
++                              
!fs::FindPathCaseInsensitive(fs::CombinePath(_sourcePath, "AnimsSw.j2a"_s))) {
++                              auto systemWideSource = NCINE_INSTALL_PREFIX 
"/share/" NCINE_LINUX_PACKAGE "/Source/";
++                              if 
(fs::FindPathCaseInsensitive(fs::CombinePath(systemWideSource, "Anims.j2a"_s)) 
||
++                                      
fs::FindPathCaseInsensitive(fs::CombinePath(systemWideSource, 
"AnimsSw.j2a"_s))) {
++                                      _sourcePath = systemWideSource;
++                              }
++                      }
+               } else {
+                       // Fallback to relative paths
+                       _contentPath = "Content/"_s;
+diff --git a/Sources/Shared/IO/FileSystem.cpp 
b/Sources/Shared/IO/FileSystem.cpp
+index 5b5199b0..0d4850bd 100644
+--- a/Sources/Shared/IO/FileSystem.cpp
++++ b/Sources/Shared/IO/FileSystem.cpp
+@@ -701,73 +701,91 @@ namespace Death { namespace IO {
+ #if !defined(DEATH_TARGET_WINDOWS) && !defined(DEATH_TARGET_SWITCH)
+       String FileSystem::FindPathCaseInsensitive(const StringView path)
+       {
+-              if (Exists(path)) {
++              if (path.empty() || Exists(path)) {
+                       return path;
+               }
+ 
+-              std::size_t l = path.size();
+-              char* p = (char*)alloca(l + 1);
+-              strncpy(p, path.data(), l);
+-              p[l] = '\0';
+-              std::size_t rl = 0;
+-              bool isAbsolute = (p[0] == '/' || p[0] == '\\');
++              DIR* d = nullptr;
++              String result = path;
++              MutableStringView partialResult = result;
++              char* nextPartBegin;
+ 
+-              String result(NoInit, path.size() + (isAbsolute ? 0 : 2));
++              while (MutableStringView separator = 
partialResult.findLast('/')) {
++                      if DEATH_UNLIKELY(separator.begin() == result.begin()) {
++                              // Nothing left, only first slash of absolute 
path
++                              break;
++                      }
+ 
+-              DIR* d;
+-              if (isAbsolute) {
+-                      d = ::opendir("/");
+-                      p = p + 1;
+-              } else {
+-                      d = ::opendir(".");
+-                      result[0] = '.';
+-                      result[1] = '\0';
+-                      rl = 1;
++                      partialResult = partialResult.prefix(separator.begin());
++                      separator[0] = '\0';
++                      d = ::opendir(result.data());
++                      separator[0] = '/';
++                      if (d != nullptr) {
++                              nextPartBegin = separator.end();
++                              break;
++                      }
+               }
+ 
+-              bool last = false;
+-              char* c = strsep(&p, "/");
+-              while (c) {
+-                      if (d == nullptr) {
+-                              return {};
++              if (d == nullptr) {
++                      if (result[0] == '/' || result[0] == '\\') {
++                              d = ::opendir("/");
++                              nextPartBegin = result.begin() + 1;
++                      } else {
++                              d = ::opendir(".");
++                              nextPartBegin = result.begin();
+                       }
+ 
+-                      if (last) {
+-                              ::closedir(d);
++                      if DEATH_UNLIKELY(d == nullptr) {
+                               return {};
+                       }
++              }
++
++              while (true) {
++                      partialResult = result.suffix(nextPartBegin);
++                      MutableStringView nextSeparator = 
partialResult.findOr('/', result.end());
++                      if DEATH_UNLIKELY(nextSeparator.begin() == 
nextPartBegin) {
++                              // Skip empty parts
++                              nextPartBegin = nextSeparator.end();
++                              continue;
++                      }
+ 
+-                      result[rl] = '/';
+-                      rl += 1;
+-                      result[rl] = '\0';
++                      bool hasNextSeparator = (nextSeparator.begin() != 
result.end());
++                      if DEATH_LIKELY(hasNextSeparator) {
++                              nextSeparator[0] = '\0';
++                      }
+ 
+                       struct dirent* entry = ::readdir(d);
+                       while (entry != nullptr) {
+-                              if (::strcasecmp(c, entry->d_name) == 0) {
+-                                      strcpy(&result[rl], entry->d_name);
+-                                      rl += strlen(entry->d_name);
+-
++                              if (::strcasecmp(partialResult.begin(), 
entry->d_name) == 0) {
++                                      std::size_t fileNameLength = 
std::strlen(entry->d_name);
++                                      
DEATH_DEBUG_ASSERT(partialResult.begin() + fileNameLength == 
nextSeparator.begin());
++                                      std::memcpy(partialResult.begin(), 
entry->d_name, fileNameLength);
+                                       ::closedir(d);
++
++                                      nextPartBegin = nextSeparator.end();
++                                      if (!hasNextSeparator || nextPartBegin 
== result.end()) {
++                                              if (hasNextSeparator) {
++                                                      nextSeparator[0] = '/';
++                                              }
++                                              return result;
++                                      }
++
+                                       d = ::opendir(result.data());
++                                      if DEATH_UNLIKELY(d == nullptr) {
++                                              return {};
++                                      }
++                                      nextSeparator[0] = '/';
+                                       break;
+                               }
+ 
+                               entry = ::readdir(d);
+                       }
+ 
+-                      if (entry == nullptr) {
+-                              strcpy(&result[rl], c);
+-                              rl += strlen(c);
+-                              last = true;
++                      if DEATH_UNLIKELY(entry == nullptr) {
++                              ::closedir(d);
++                              return {};
+                       }
+-
+-                      c = strsep(&p, "/");
+               }
+-
+-              if (d != nullptr) {
+-                      ::closedir(d);
+-              }
+-              return result;
+       }
+ #endif
+ 
+diff --git a/cmake/ncine_compiler_options.cmake 
b/cmake/ncine_compiler_options.cmake
+index 9ca461ad..6d981fdc 100644
+--- a/cmake/ncine_compiler_options.cmake
++++ b/cmake/ncine_compiler_options.cmake
+@@ -10,6 +10,10 @@ target_compile_definitions(${NCINE_APP} PUBLIC 
"NCINE_VERSION=\"${NCINE_VERSION}
+ string(TIMESTAMP NCINE_BUILD_YEAR "%Y") 
+ target_compile_definitions(${NCINE_APP} PUBLIC 
"NCINE_BUILD_YEAR=\"${NCINE_BUILD_YEAR}\"")
+ 
++if(UNIX)
++      target_compile_definitions(${NCINE_APP} PUBLIC 
"NCINE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
++endif()
++
+ if(NCINE_OVERRIDE_CONTENT_PATH)
+       message(STATUS "Using overriden `Content` path: 
${NCINE_OVERRIDE_CONTENT_PATH}")
+       target_compile_definitions(${NCINE_APP} PUBLIC 
"NCINE_OVERRIDE_CONTENT_PATH=\"${NCINE_OVERRIDE_CONTENT_PATH}\"")

diff --git a/games-arcade/jazz2/jazz2-3.0.0.ebuild 
b/games-arcade/jazz2/jazz2-3.0.0-r1.ebuild
similarity index 70%
rename from games-arcade/jazz2/jazz2-3.0.0.ebuild
rename to games-arcade/jazz2/jazz2-3.0.0-r1.ebuild
index 4a7c0ac77fc6..ba50e47ce088 100644
--- a/games-arcade/jazz2/jazz2-3.0.0.ebuild
+++ b/games-arcade/jazz2/jazz2-3.0.0-r1.ebuild
@@ -3,17 +3,11 @@
 
 EAPI=8
 
-inherit cmake xdg-utils
+inherit cmake optfeature prefix xdg
 
 DESCRIPTION="Open source reimplementation of Jazz Jackrabbit 2"
-HOMEPAGE="
-       https://deat.tk/jazz2/
-       https://github.com/deathkiller/jazz2-native
-"
-SRC_URI="
-       
https://github.com/deathkiller/jazz2-native/archive/refs/tags/${PV}.tar.gz
-               -> ${P}.tar.gz
-"
+HOMEPAGE="https://deat.tk/jazz2/";
+SRC_URI="https://github.com/deathkiller/jazz2-native/archive/refs/tags/${PV}.tar.gz
 -> ${P}.tar.gz"
 S="${WORKDIR}/${PN}-native-${PV}"
 
 LICENSE="GPL-3"
@@ -22,8 +16,8 @@ KEYWORDS="~amd64"
 IUSE="+openal sdl"
 
 DEPEND="
-       sys-libs/zlib:=
        media-libs/libglvnd
+       sys-libs/zlib:=
        openal? (
                media-libs/libopenmpt
                media-libs/openal
@@ -33,16 +27,20 @@ DEPEND="
 "
 RDEPEND="${DEPEND}"
 
+PATCHES=(
+       "${FILESDIR}"/${PN}-system-source.patch
+)
+
 src_prepare() {
+       cmake_src_prepare
+       hprefixify Sources/Shared/Environment.cpp
+
        # We need to install README.md to a different directory, default
        # src_install will handle that.
        sed -i '/README_INSTALL_DESTINATION/d' cmake/ncine_installation.cmake 
|| die
-       cmake_src_prepare
 }
 
 src_configure() {
-       local backend=GLFW
-       use sdl && backend=SDL2
        local mycmakeargs=(
                -DNCINE_LINUX_PACKAGE="${PN}"
 
@@ -54,7 +52,7 @@ src_configure() {
 
                -DNCINE_WITH_GLEW=OFF
 
-               -DNCINE_PREFERRED_BACKEND=${backend}
+               -DNCINE_PREFERRED_BACKEND=$(usex sdl SDL2 GLFW)
 
                -DNCINE_WITH_AUDIO=$(usex openal)
        )
@@ -62,9 +60,6 @@ src_configure() {
 }
 
 pkg_postinst() {
-       xdg_icon_cache_update
-}
-
-pkg_postrm() {
-       xdg_icon_cache_update
+       xdg_pkg_postinst
+       optfeature "game data unless you want to install it manually" 
${CATEGORY}/${PN}-data
 }

Reply via email to