summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/filesystem/riscos
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/filesystem/riscos')
-rw-r--r--contrib/SDL-3.2.8/src/filesystem/riscos/SDL_sysfilesystem.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/filesystem/riscos/SDL_sysfilesystem.c b/contrib/SDL-3.2.8/src/filesystem/riscos/SDL_sysfilesystem.c
new file mode 100644
index 0000000..95ed80f
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/filesystem/riscos/SDL_sysfilesystem.c
@@ -0,0 +1,208 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_FILESYSTEM_RISCOS
24
25/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26// System dependent filesystem routines
27
28#include "../SDL_sysfilesystem.h"
29
30#include <kernel.h>
31#include <swis.h>
32#include <unixlib/local.h>
33
34// Wrapper around __unixify_std that uses SDL's memory allocators
35static char *SDL_unixify_std(const char *ro_path, char *buffer, size_t buf_len, int filetype)
36{
37 const char *const in_buf = buffer; // = NULL if we allocate the buffer.
38
39 if (!buffer) {
40 /* This matches the logic in __unixify, with an additional byte for the
41 * extra path separator.
42 */
43 buf_len = SDL_strlen(ro_path) + 14 + 1;
44 buffer = SDL_malloc(buf_len);
45
46 if (!buffer) {
47 return NULL;
48 }
49 }
50
51 if (!__unixify_std(ro_path, buffer, buf_len, filetype)) {
52 if (!in_buf) {
53 SDL_free(buffer);
54 }
55
56 SDL_SetError("Could not convert '%s' to a Unix-style path", ro_path);
57 return NULL;
58 }
59
60 /* HACK: It's necessary to add an extra path separator here since SDL's API
61 * requires it, however paths with trailing separators aren't normally valid
62 * on RISC OS.
63 */
64 if (__get_riscosify_control() & __RISCOSIFY_NO_PROCESS)
65 SDL_strlcat(buffer, ".", buf_len);
66 else
67 SDL_strlcat(buffer, "/", buf_len);
68
69 return buffer;
70}
71
72static char *canonicalisePath(const char *path, const char *pathVar)
73{
74 _kernel_oserror *error;
75 _kernel_swi_regs regs;
76 char *buf;
77
78 regs.r[0] = 37;
79 regs.r[1] = (int)path;
80 regs.r[2] = 0;
81 regs.r[3] = (int)pathVar;
82 regs.r[4] = 0;
83 regs.r[5] = 0;
84 error = _kernel_swi(OS_FSControl, &regs, &regs);
85 if (error) {
86 SDL_SetError("Couldn't canonicalise path: %s", error->errmess);
87 return NULL;
88 }
89
90 regs.r[5] = 1 - regs.r[5];
91 buf = SDL_malloc(regs.r[5]);
92 if (!buf) {
93 return NULL;
94 }
95 regs.r[2] = (int)buf;
96 error = _kernel_swi(OS_FSControl, &regs, &regs);
97 if (error) {
98 SDL_SetError("Couldn't canonicalise path: %s", error->errmess);
99 SDL_free(buf);
100 return NULL;
101 }
102
103 return buf;
104}
105
106static _kernel_oserror *createDirectoryRecursive(char *path)
107{
108 char *ptr = NULL;
109 _kernel_oserror *error;
110 _kernel_swi_regs regs;
111 regs.r[0] = 8;
112 regs.r[1] = (int)path;
113 regs.r[2] = 0;
114
115 for (ptr = path + 1; *ptr; ptr++) {
116 if (*ptr == '.') {
117 *ptr = '\0';
118 error = _kernel_swi(OS_File, &regs, &regs);
119 *ptr = '.';
120 if (error) {
121 return error;
122 }
123 }
124 }
125 return _kernel_swi(OS_File, &regs, &regs);
126}
127
128char *SDL_SYS_GetBasePath(void)
129{
130 _kernel_swi_regs regs;
131 _kernel_oserror *error;
132 char *canon, *ptr, *result;
133
134 error = _kernel_swi(OS_GetEnv, &regs, &regs);
135 if (error) {
136 return NULL;
137 }
138
139 canon = canonicalisePath((const char *)regs.r[0], "Run$Path");
140 if (!canon) {
141 return NULL;
142 }
143
144 // chop off filename.
145 ptr = SDL_strrchr(canon, '.');
146 if (ptr) {
147 *ptr = '\0';
148 }
149
150 result = SDL_unixify_std(canon, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED);
151 SDL_free(canon);
152 return result;
153}
154
155char *SDL_SYS_GetPrefPath(const char *org, const char *app)
156{
157 char *canon, *dir, *result;
158 size_t len;
159 _kernel_oserror *error;
160
161 if (!app) {
162 SDL_InvalidParamError("app");
163 return NULL;
164 }
165 if (!org) {
166 org = "";
167 }
168
169 canon = canonicalisePath("<Choices$Write>", "Run$Path");
170 if (!canon) {
171 return NULL;
172 }
173
174 len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4;
175 dir = (char *)SDL_malloc(len);
176 if (!dir) {
177 SDL_free(canon);
178 return NULL;
179 }
180
181 if (*org) {
182 SDL_snprintf(dir, len, "%s.%s.%s", canon, org, app);
183 } else {
184 SDL_snprintf(dir, len, "%s.%s", canon, app);
185 }
186
187 SDL_free(canon);
188
189 error = createDirectoryRecursive(dir);
190 if (error) {
191 SDL_SetError("Couldn't create directory: %s", error->errmess);
192 SDL_free(dir);
193 return NULL;
194 }
195
196 result = SDL_unixify_std(dir, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED);
197 SDL_free(dir);
198 return result;
199}
200
201// TODO
202char *SDL_SYS_GetUserFolder(SDL_Folder folder)
203{
204 SDL_Unsupported();
205 return NULL;
206}
207
208#endif // SDL_FILESYSTEM_RISCOS