dev-python/agate: Bump to 1.13.0
[gentoo/gentoo.git] / games-arcade / jazz2 / files / jazz2-system-source.patch
blob35cbb3a9d9c3fba86c6f8fed9c65a16174fe5818
1 diff --git a/README.md b/README.md
2 index fe466e50..e91dd4ed 100644
3 --- a/README.md
4 +++ b/README.md
5 @@ -46,7 +46,7 @@ Jazz² Resurrection is reimplementation of the game **Jazz Jackrabbit 2** releas
6 * Install dependencies: `sudo apt install libglew2.2 libglfw3 libsdl2-2.0-0 libopenal1 libvorbisfile3 libopenmpt0`
7 * Alternatively, install provided `.deb` or `.rpm` package and dependencies should be installed automatically
8 * Copy contents of original *Jazz Jackrabbit 2* directory to `‹Game›/Source/`
9 - * If packages are used, the files must be copied to `~/.local/share/Jazz² Resurrection/Source/` instead
10 + * 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
11 * Run `‹Game›/jazz2` or `‹Game›/jazz2_sdl2` application
12 * If packages are used, the game should be visible in application list
14 diff --git a/Sources/Common.h b/Sources/Common.h
15 index 865d42bb..cf6f112c 100644
16 --- a/Sources/Common.h
17 +++ b/Sources/Common.h
18 @@ -33,6 +33,10 @@
20 #include <stdlib.h>
22 +#if !defined(NCINE_INSTALL_PREFIX) && defined(DEATH_TARGET_UNIX)
23 +# define NCINE_INSTALL_PREFIX "/usr/local"
24 +#endif
26 // Check platform-specific capabilities
27 #if defined(WITH_SDL) || defined(DEATH_TARGET_WINDOWS_RT)
28 # define NCINE_HAS_GAMEPAD_RUMBLE
29 diff --git a/Sources/Jazz2/ContentResolver.cpp b/Sources/Jazz2/ContentResolver.cpp
30 index 737582db..a7c5d460 100644
31 --- a/Sources/Jazz2/ContentResolver.cpp
32 +++ b/Sources/Jazz2/ContentResolver.cpp
33 @@ -207,7 +207,7 @@ namespace Jazz2
34 # elif defined(NCINE_OVERRIDE_CONTENT_PATH)
35 _contentPath = NCINE_OVERRIDE_CONTENT_PATH;
36 # else
37 - _contentPath = "/usr/share/" NCINE_LINUX_PACKAGE "/Content/";
38 + _contentPath = NCINE_INSTALL_PREFIX "/share/" NCINE_LINUX_PACKAGE "/Content/";
39 # endif
40 # if defined(NCINE_PACKAGED_CONTENT_PATH)
41 // If Content is packaged with binaries, always use standard XDG paths for everything else
42 @@ -226,18 +226,25 @@ namespace Jazz2
43 auto localStorage = fs::GetLocalStorage();
44 if (!localStorage.empty()) {
45 // Use "$XDG_DATA_HOME/Jazz² Resurrection/" if exists (for backward compatibility), otherwise "$XDG_DATA_HOME/{NCINE_LINUX_PACKAGE}/"
46 - _sourcePath = fs::CombinePath(localStorage, "Jazz² Resurrection/Source/"_s);
47 - if (fs::DirectoryExists(_sourcePath)) {
48 - _cachePath = fs::CombinePath(localStorage, "Jazz² Resurrection/Cache/"_s);
49 - } else {
50 + _cachePath = fs::CombinePath(localStorage, "Jazz² Resurrection/Cache/"_s);
51 + if (!fs::DirectoryExists(_cachePath)) {
52 auto appData = fs::CombinePath(localStorage, NCINE_LINUX_PACKAGE);
53 - _sourcePath = fs::CombinePath(appData, "Source/"_s);
54 _cachePath = fs::CombinePath(appData, "Cache/"_s);
56 } else {
57 - _sourcePath = "Source/"_s;
58 _cachePath = "Cache/"_s;
61 + // Prefer system-wide Source only if it exists and local one doesn't exist
62 + _sourcePath = fs::CombinePath(fs::GetDirectoryName(_cachePath), "Source/"_s);
63 + if (!fs::FindPathCaseInsensitive(fs::CombinePath(_sourcePath, "Anims.j2a"_s)) &&
64 + !fs::FindPathCaseInsensitive(fs::CombinePath(_sourcePath, "AnimsSw.j2a"_s))) {
65 + auto systemWideSource = NCINE_INSTALL_PREFIX "/share/" NCINE_LINUX_PACKAGE "/Source/";
66 + if (fs::FindPathCaseInsensitive(fs::CombinePath(systemWideSource, "Anims.j2a"_s)) ||
67 + fs::FindPathCaseInsensitive(fs::CombinePath(systemWideSource, "AnimsSw.j2a"_s))) {
68 + _sourcePath = systemWideSource;
69 + }
70 + }
71 } else {
72 // Fallback to relative paths
73 _contentPath = "Content/"_s;
74 diff --git a/Sources/Shared/IO/FileSystem.cpp b/Sources/Shared/IO/FileSystem.cpp
75 index 5b5199b0..0d4850bd 100644
76 --- a/Sources/Shared/IO/FileSystem.cpp
77 +++ b/Sources/Shared/IO/FileSystem.cpp
78 @@ -701,73 +701,91 @@ namespace Death { namespace IO {
79 #if !defined(DEATH_TARGET_WINDOWS) && !defined(DEATH_TARGET_SWITCH)
80 String FileSystem::FindPathCaseInsensitive(const StringView path)
82 - if (Exists(path)) {
83 + if (path.empty() || Exists(path)) {
84 return path;
87 - std::size_t l = path.size();
88 - char* p = (char*)alloca(l + 1);
89 - strncpy(p, path.data(), l);
90 - p[l] = '\0';
91 - std::size_t rl = 0;
92 - bool isAbsolute = (p[0] == '/' || p[0] == '\\');
93 + DIR* d = nullptr;
94 + String result = path;
95 + MutableStringView partialResult = result;
96 + char* nextPartBegin;
98 - String result(NoInit, path.size() + (isAbsolute ? 0 : 2));
99 + while (MutableStringView separator = partialResult.findLast('/')) {
100 + if DEATH_UNLIKELY(separator.begin() == result.begin()) {
101 + // Nothing left, only first slash of absolute path
102 + break;
105 - DIR* d;
106 - if (isAbsolute) {
107 - d = ::opendir("/");
108 - p = p + 1;
109 - } else {
110 - d = ::opendir(".");
111 - result[0] = '.';
112 - result[1] = '\0';
113 - rl = 1;
114 + partialResult = partialResult.prefix(separator.begin());
115 + separator[0] = '\0';
116 + d = ::opendir(result.data());
117 + separator[0] = '/';
118 + if (d != nullptr) {
119 + nextPartBegin = separator.end();
120 + break;
124 - bool last = false;
125 - char* c = strsep(&p, "/");
126 - while (c) {
127 - if (d == nullptr) {
128 - return {};
129 + if (d == nullptr) {
130 + if (result[0] == '/' || result[0] == '\\') {
131 + d = ::opendir("/");
132 + nextPartBegin = result.begin() + 1;
133 + } else {
134 + d = ::opendir(".");
135 + nextPartBegin = result.begin();
138 - if (last) {
139 - ::closedir(d);
140 + if DEATH_UNLIKELY(d == nullptr) {
141 return {};
145 + while (true) {
146 + partialResult = result.suffix(nextPartBegin);
147 + MutableStringView nextSeparator = partialResult.findOr('/', result.end());
148 + if DEATH_UNLIKELY(nextSeparator.begin() == nextPartBegin) {
149 + // Skip empty parts
150 + nextPartBegin = nextSeparator.end();
151 + continue;
154 - result[rl] = '/';
155 - rl += 1;
156 - result[rl] = '\0';
157 + bool hasNextSeparator = (nextSeparator.begin() != result.end());
158 + if DEATH_LIKELY(hasNextSeparator) {
159 + nextSeparator[0] = '\0';
162 struct dirent* entry = ::readdir(d);
163 while (entry != nullptr) {
164 - if (::strcasecmp(c, entry->d_name) == 0) {
165 - strcpy(&result[rl], entry->d_name);
166 - rl += strlen(entry->d_name);
168 + if (::strcasecmp(partialResult.begin(), entry->d_name) == 0) {
169 + std::size_t fileNameLength = std::strlen(entry->d_name);
170 + DEATH_DEBUG_ASSERT(partialResult.begin() + fileNameLength == nextSeparator.begin());
171 + std::memcpy(partialResult.begin(), entry->d_name, fileNameLength);
172 ::closedir(d);
174 + nextPartBegin = nextSeparator.end();
175 + if (!hasNextSeparator || nextPartBegin == result.end()) {
176 + if (hasNextSeparator) {
177 + nextSeparator[0] = '/';
179 + return result;
182 d = ::opendir(result.data());
183 + if DEATH_UNLIKELY(d == nullptr) {
184 + return {};
186 + nextSeparator[0] = '/';
187 break;
190 entry = ::readdir(d);
193 - if (entry == nullptr) {
194 - strcpy(&result[rl], c);
195 - rl += strlen(c);
196 - last = true;
197 + if DEATH_UNLIKELY(entry == nullptr) {
198 + ::closedir(d);
199 + return {};
202 - c = strsep(&p, "/");
205 - if (d != nullptr) {
206 - ::closedir(d);
208 - return result;
210 #endif
212 diff --git a/cmake/ncine_compiler_options.cmake b/cmake/ncine_compiler_options.cmake
213 index 9ca461ad..6d981fdc 100644
214 --- a/cmake/ncine_compiler_options.cmake
215 +++ b/cmake/ncine_compiler_options.cmake
216 @@ -10,6 +10,10 @@ target_compile_definitions(${NCINE_APP} PUBLIC "NCINE_VERSION=\"${NCINE_VERSION}
217 string(TIMESTAMP NCINE_BUILD_YEAR "%Y")
218 target_compile_definitions(${NCINE_APP} PUBLIC "NCINE_BUILD_YEAR=\"${NCINE_BUILD_YEAR}\"")
220 +if(UNIX)
221 + target_compile_definitions(${NCINE_APP} PUBLIC "NCINE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
222 +endif()
224 if(NCINE_OVERRIDE_CONTENT_PATH)
225 message(STATUS "Using overriden `Content` path: ${NCINE_OVERRIDE_CONTENT_PATH}")
226 target_compile_definitions(${NCINE_APP} PUBLIC "NCINE_OVERRIDE_CONTENT_PATH=\"${NCINE_OVERRIDE_CONTENT_PATH}\"")