Atlas - SDL_sysfilesystem.c
Home / ext / SDL / src / filesystem / riscos Lines: 1 | Size: 5229 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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, ®s, ®s); 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, ®s, ®s); 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, ®s, ®s); 119 *ptr = '.'; 120 if (error) { 121 return error; 122 } 123 } 124 } 125 return _kernel_swi(OS_File, ®s, ®s); 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, ®s, ®s); 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 _kernel_oserror *error; 159 160 canon = canonicalisePath("<Choices$Write>", "Run$Path"); 161 if (!canon) { 162 return NULL; 163 } 164 165 const size_t len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4; 166 dir = (char *)SDL_malloc(len); 167 if (!dir) { 168 SDL_free(canon); 169 return NULL; 170 } 171 172 if (*org) { 173 SDL_snprintf(dir, len, "%s.%s.%s", canon, org, app); 174 } else { 175 SDL_snprintf(dir, len, "%s.%s", canon, app); 176 } 177 178 SDL_free(canon); 179 180 error = createDirectoryRecursive(dir); 181 if (error) { 182 SDL_SetError("Couldn't create directory: %s", error->errmess); 183 SDL_free(dir); 184 return NULL; 185 } 186 187 result = SDL_unixify_std(dir, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED); 188 SDL_free(dir); 189 return result; 190} 191 192// TODO 193char *SDL_SYS_GetUserFolder(SDL_Folder folder) 194{ 195 SDL_Unsupported(); 196 return NULL; 197} 198 199#endif // SDL_FILESYSTEM_RISCOS 200[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.