SDL
240 строк · 7.3 Кб
1/*
2Simple DirectMedia Layer
3Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
4
5This software is provided 'as-is', without any express or implied
6warranty. In no event will the authors be held liable for any damages
7arising from the use of this software.
8
9Permission is granted to anyone to use this software for any purpose,
10including commercial applications, and to alter it and redistribute it
11freely, subject to the following restrictions:
12
131. The origin of this software must not be misrepresented; you must not
14claim that you wrote the original software. If you use this software
15in a product, an acknowledgment in the product documentation would be
16appreciated but is not required.
172. Altered source versions must be plainly marked as such, and must not be
18misrepresented as being the original software.
193. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_FILESYSTEM_COCOA
24
25/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26// System dependent filesystem routines
27
28#include "../SDL_sysfilesystem.h"
29
30#include <Foundation/Foundation.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33
34char *SDL_SYS_GetBasePath(void)
35{
36@autoreleasepool {
37NSBundle *bundle = [NSBundle mainBundle];
38const char *baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
39const char *base = NULL;
40char *result = NULL;
41
42if (baseType == NULL) {
43baseType = "resource";
44}
45if (SDL_strcasecmp(baseType, "bundle") == 0) {
46base = [[bundle bundlePath] fileSystemRepresentation];
47} else if (SDL_strcasecmp(baseType, "parent") == 0) {
48base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation];
49} else {
50// this returns the exedir for non-bundled and the resourceDir for bundled apps
51base = [[bundle resourcePath] fileSystemRepresentation];
52}
53
54if (base) {
55const size_t len = SDL_strlen(base) + 2;
56result = (char *)SDL_malloc(len);
57if (result != NULL) {
58SDL_snprintf(result, len, "%s/", base);
59}
60}
61
62return result;
63}
64}
65
66char *SDL_SYS_GetPrefPath(const char *org, const char *app)
67{
68@autoreleasepool {
69char *result = NULL;
70NSArray *array;
71
72if (!app) {
73SDL_InvalidParamError("app");
74return NULL;
75}
76if (!org) {
77org = "";
78}
79
80#ifndef SDL_PLATFORM_TVOS
81array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
82#else
83/* tvOS does not have persistent local storage!
84* The only place on-device where we can store data is
85* a cache directory that the OS can empty at any time.
86*
87* It's therefore very likely that save data will be erased
88* between sessions. If you want your app's save data to
89* actually stick around, you'll need to use iCloud storage.
90*/
91{
92static bool shown = false;
93if (!shown) {
94shown = true;
95SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "tvOS does not have persistent local storage! Use iCloud storage if you want your data to persist between sessions.\n");
96}
97}
98
99array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
100#endif // !SDL_PLATFORM_TVOS
101
102if ([array count] > 0) { // we only want the first item in the list.
103NSString *str = [array objectAtIndex:0];
104const char *base = [str fileSystemRepresentation];
105if (base) {
106const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
107result = (char *)SDL_malloc(len);
108if (result != NULL) {
109char *ptr;
110if (*org) {
111SDL_snprintf(result, len, "%s/%s/%s/", base, org, app);
112} else {
113SDL_snprintf(result, len, "%s/%s/", base, app);
114}
115for (ptr = result + 1; *ptr; ptr++) {
116if (*ptr == '/') {
117*ptr = '\0';
118mkdir(result, 0700);
119*ptr = '/';
120}
121}
122mkdir(result, 0700);
123}
124}
125}
126
127return result;
128}
129}
130
131char *SDL_SYS_GetUserFolder(SDL_Folder folder)
132{
133@autoreleasepool {
134#ifdef SDL_PLATFORM_TVOS
135SDL_SetError("tvOS does not have persistent storage");
136return NULL;
137#else
138char *result = NULL;
139const char* base;
140NSArray *array;
141NSSearchPathDirectory dir;
142NSString *str;
143char *ptr;
144
145switch (folder) {
146case SDL_FOLDER_HOME:
147base = SDL_getenv("HOME");
148
149if (!base) {
150SDL_SetError("No $HOME environment variable available");
151return NULL;
152}
153
154goto append_slash;
155
156case SDL_FOLDER_DESKTOP:
157dir = NSDesktopDirectory;
158break;
159
160case SDL_FOLDER_DOCUMENTS:
161dir = NSDocumentDirectory;
162break;
163
164case SDL_FOLDER_DOWNLOADS:
165dir = NSDownloadsDirectory;
166break;
167
168case SDL_FOLDER_MUSIC:
169dir = NSMusicDirectory;
170break;
171
172case SDL_FOLDER_PICTURES:
173dir = NSPicturesDirectory;
174break;
175
176case SDL_FOLDER_PUBLICSHARE:
177dir = NSSharedPublicDirectory;
178break;
179
180case SDL_FOLDER_SAVEDGAMES:
181SDL_SetError("Saved games folder not supported on Cocoa");
182return NULL;
183
184case SDL_FOLDER_SCREENSHOTS:
185SDL_SetError("Screenshots folder not supported on Cocoa");
186return NULL;
187
188case SDL_FOLDER_TEMPLATES:
189SDL_SetError("Templates folder not supported on Cocoa");
190return NULL;
191
192case SDL_FOLDER_VIDEOS:
193dir = NSMoviesDirectory;
194break;
195
196default:
197SDL_SetError("Invalid SDL_Folder: %d", (int) folder);
198return NULL;
199};
200
201array = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES);
202
203if ([array count] <= 0) {
204SDL_SetError("Directory not found");
205return NULL;
206}
207
208str = [array objectAtIndex:0];
209base = [str fileSystemRepresentation];
210if (!base) {
211SDL_SetError("Couldn't get folder path");
212return NULL;
213}
214
215append_slash:
216result = SDL_malloc(SDL_strlen(base) + 2);
217if (result == NULL) {
218return NULL;
219}
220
221if (SDL_snprintf(result, SDL_strlen(base) + 2, "%s/", base) < 0) {
222SDL_SetError("Couldn't snprintf folder path for Cocoa: %s", base);
223SDL_free(result);
224return NULL;
225}
226
227for (ptr = result + 1; *ptr; ptr++) {
228if (*ptr == '/') {
229*ptr = '\0';
230mkdir(result, 0700);
231*ptr = '/';
232}
233}
234
235return result;
236#endif // SDL_PLATFORM_TVOS
237}
238}
239
240#endif // SDL_FILESYSTEM_COCOA
241