chore(build): revert to sdl2

This commit is contained in:
phaneron 2024-07-21 17:06:25 -04:00
parent 20f392cd74
commit b5902f5230
2095 changed files with 244085 additions and 192940 deletions

View file

@ -0,0 +1,60 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_ANDROID
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <unistd.h>
#include "SDL_error.h"
#include "SDL_filesystem.h"
#include "SDL_system.h"
char *SDL_GetBasePath(void)
{
/* The current working directory is / on Android */
SDL_Unsupported();
return NULL;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
const char *path = SDL_AndroidGetInternalStoragePath();
if (path) {
size_t pathlen = SDL_strlen(path) + 2;
char *fullpath = (char *)SDL_malloc(pathlen);
if (!fullpath) {
SDL_OutOfMemory();
return NULL;
}
SDL_snprintf(fullpath, pathlen, "%s/", path);
return fullpath;
}
return NULL;
}
#endif /* SDL_FILESYSTEM_ANDROID */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,139 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_COCOA
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <Foundation/Foundation.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
@autoreleasepool {
NSBundle *bundle = [NSBundle mainBundle];
const char *baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
const char *base = NULL;
char *retval = NULL;
if (baseType == NULL) {
baseType = "resource";
}
if (SDL_strcasecmp(baseType, "bundle") == 0) {
base = [[bundle bundlePath] fileSystemRepresentation];
} else if (SDL_strcasecmp(baseType, "parent") == 0) {
base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation];
} else {
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */
base = [[bundle resourcePath] fileSystemRepresentation];
}
if (base) {
const size_t len = SDL_strlen(base) + 2;
retval = (char *)SDL_malloc(len);
if (retval == NULL) {
SDL_OutOfMemory();
} else {
SDL_snprintf(retval, len, "%s/", base);
}
}
return retval;
}
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
@autoreleasepool {
char *retval = NULL;
NSArray *array;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
#if !TARGET_OS_TV
array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
#else
/* tvOS does not have persistent local storage!
* The only place on-device where we can store data is
* a cache directory that the OS can empty at any time.
*
* It's therefore very likely that save data will be erased
* between sessions. If you want your app's save data to
* actually stick around, you'll need to use iCloud storage.
*/
{
static SDL_bool shown = SDL_FALSE;
if (!shown) {
shown = SDL_TRUE;
SDL_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");
}
}
array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
#endif /* !TARGET_OS_TV */
if ([array count] > 0) { /* we only want the first item in the list. */
NSString *str = [array objectAtIndex:0];
const char *base = [str fileSystemRepresentation];
if (base) {
const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *)SDL_malloc(len);
if (retval == NULL) {
SDL_OutOfMemory();
} else {
char *ptr;
if (*org) {
SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s/%s/", base, app);
}
for (ptr = retval + 1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
mkdir(retval, 0700);
*ptr = '/';
}
}
mkdir(retval, 0700);
}
}
}
return retval;
}
}
#endif /* SDL_FILESYSTEM_COCOA */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if defined(SDL_FILESYSTEM_DUMMY) || defined(SDL_FILESYSTEM_DISABLED)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "SDL_error.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
SDL_Unsupported();
return NULL;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
SDL_Unsupported();
return NULL;
}
#endif /* SDL_FILESYSTEM_DUMMY || SDL_FILESYSTEM_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,91 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_EMSCRIPTEN
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <errno.h>
#include <sys/stat.h>
#include "SDL_error.h"
#include "SDL_filesystem.h"
#include <emscripten/emscripten.h>
char *SDL_GetBasePath(void)
{
char *retval = "/";
return SDL_strdup(retval);
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
const char *append = "/libsdl/";
char *retval;
char *ptr = NULL;
size_t len = 0;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
retval = (char *)SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", append, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", append, app);
}
for (ptr = retval + 1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
goto error;
}
*ptr = '/';
}
}
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
error:
SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno));
SDL_free(retval);
return NULL;
}
return retval;
}
#endif /* SDL_FILESYSTEM_EMSCRIPTEN */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,138 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "../../core/windows/SDL_windows.h"
#include "SDL_hints.h"
#include "SDL_system.h"
#include "SDL_filesystem.h"
#include <XGameSaveFiles.h>
char *
SDL_GetBasePath(void)
{
/* NOTE: This function is a UTF8 version of the Win32 SDL_GetBasePath()!
* The GDK actually _recommends_ the 'A' functions over the 'W' functions :o
*/
DWORD buflen = 128;
CHAR *path = NULL;
DWORD len = 0;
int i;
while (SDL_TRUE) {
void *ptr = SDL_realloc(path, buflen * sizeof(CHAR));
if (!ptr) {
SDL_free(path);
SDL_OutOfMemory();
return NULL;
}
path = (CHAR *)ptr;
len = GetModuleFileNameA(NULL, path, buflen);
/* if it truncated, then len >= buflen - 1 */
/* if there was enough room (or failure), len < buflen - 1 */
if (len < buflen - 1) {
break;
}
/* buffer too small? Try again. */
buflen *= 2;
}
if (len == 0) {
SDL_free(path);
WIN_SetError("Couldn't locate our .exe");
return NULL;
}
for (i = len - 1; i > 0; i--) {
if (path[i] == '\\') {
break;
}
}
SDL_assert(i > 0); /* Should have been an absolute path. */
path[i + 1] = '\0'; /* chop off filename. */
return path;
}
char *
SDL_GetPrefPath(const char *org, const char *app)
{
XUserHandle user = NULL;
XAsyncBlock block = { 0 };
char *folderPath;
HRESULT result;
const char *csid = SDL_GetHint("SDL_GDK_SERVICE_CONFIGURATION_ID");
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
/* This should be set before calling SDL_GetPrefPath! */
if (!csid) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "Set SDL_GDK_SERVICE_CONFIGURATION_ID before calling SDL_GetPrefPath!");
return SDL_strdup("T:\\");
}
if (SDL_GDKGetDefaultUser(&user) < 0) {
/* Error already set, just return */
return NULL;
}
if (FAILED(result = XGameSaveFilesGetFolderWithUiAsync(user, csid, &block))) {
WIN_SetErrorFromHRESULT("XGameSaveFilesGetFolderWithUiAsync", result);
return NULL;
}
folderPath = (char*) SDL_malloc(MAX_PATH);
do {
result = XGameSaveFilesGetFolderWithUiResult(&block, MAX_PATH, folderPath);
} while (result == E_PENDING);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT("XGameSaveFilesGetFolderWithUiResult", result);
SDL_free(folderPath);
return NULL;
}
/* We aren't using 'app' here because the container rules are a lot more
* strict than the NTFS rules, so it will most likely be invalid :(
*/
SDL_strlcat(folderPath, "\\SDLPrefPath\\", MAX_PATH);
if (CreateDirectoryA(folderPath, NULL) == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
WIN_SetError("CreateDirectoryA");
SDL_free(folderPath);
return NULL;
}
}
return folderPath;
}
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,107 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_HAIKU
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <kernel/image.h>
#include <storage/Directory.h>
#include <storage/Entry.h>
#include <storage/Path.h>
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
image_info info;
int32 cookie = 0;
while (get_next_image_info(0, &cookie, &info) == B_OK) {
if (info.type == B_APP_IMAGE) {
break;
}
}
BEntry entry(info.name, true);
BPath path;
status_t rc = entry.GetPath(&path); /* (path) now has binary's path. */
SDL_assert(rc == B_OK);
rc = path.GetParent(&path); /* chop filename, keep directory. */
SDL_assert(rc == B_OK);
const char *str = path.Path();
SDL_assert(str != NULL);
const size_t len = SDL_strlen(str);
char *retval = (char *) SDL_malloc(len + 2);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(retval, str, len);
retval[len] = '/';
retval[len+1] = '\0';
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
// !!! FIXME: is there a better way to do this?
const char *home = SDL_getenv("HOME");
const char *append = "/config/settings/";
size_t len = SDL_strlen(home);
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!len || (home[len - 1] == '/')) {
++append; // home empty or ends with separator, skip the one from append
}
len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
char *retval = (char *) SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
} else {
if (*org) {
SDL_snprintf(retval, len, "%s%s%s/%s/", home, append, org, app);
} else {
SDL_snprintf(retval, len, "%s%s%s/", home, append, app);
}
create_directory(retval, 0700); // Haiku api: creates missing dirs
}
return retval;
}
#endif /* SDL_FILESYSTEM_HAIKU */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,89 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_N3DS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <3ds.h>
#include <dirent.h>
#include <errno.h>
#include "SDL_error.h"
#include "SDL_filesystem.h"
SDL_FORCE_INLINE char *MakePrefPath(const char *app);
SDL_FORCE_INLINE int CreatePrefPathDir(const char *pref);
char *SDL_GetBasePath(void)
{
char *base_path = SDL_strdup("romfs:/");
return base_path;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
char *pref_path = NULL;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
pref_path = MakePrefPath(app);
if (!pref_path) {
return NULL;
}
if (CreatePrefPathDir(pref_path) < 0) {
SDL_free(pref_path);
return NULL;
}
return pref_path;
}
SDL_FORCE_INLINE char *
MakePrefPath(const char *app)
{
char *pref_path;
if (SDL_asprintf(&pref_path, "sdmc:/3ds/%s/", app) < 0) {
SDL_OutOfMemory();
return NULL;
}
return pref_path;
}
SDL_FORCE_INLINE int
CreatePrefPathDir(const char *pref)
{
int result = mkdir(pref, 0666);
if (result == -1 && errno != EEXIST) {
return SDL_SetError("Failed to create '%s' (%s)", pref, strerror(errno));
}
return 0;
}
#endif /* SDL_FILESYSTEM_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,41 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_error.h"
#include "SDL_filesystem.h"
#ifdef SDL_FILESYSTEM_NACL
char *SDL_GetBasePath(void)
{
SDL_Unsupported();
return NULL;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
SDL_Unsupported();
return NULL;
}
#endif /* SDL_FILESYSTEM_NACL */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,129 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_OS2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "../../core/os2/SDL_os2.h"
#include "SDL_error.h"
#include "SDL_filesystem.h"
#define INCL_DOSFILEMGR
#define INCL_DOSPROCESS
#define INCL_DOSMODULEMGR
#define INCL_DOSERRORS
#include <os2.h>
char *SDL_GetBasePath(void)
{
PTIB tib;
PPIB pib;
ULONG ulRC = DosGetInfoBlocks(&tib, &pib);
PCHAR pcEnd;
CHAR acBuf[CCHMAXPATH];
if (ulRC != NO_ERROR) {
SDL_SetError("Can't get process information block (E%lu)", ulRC);
return NULL;
}
ulRC = DosQueryModuleName(pib->pib_hmte, sizeof(acBuf), acBuf);
if (ulRC != NO_ERROR) {
SDL_SetError("Can't query the module name (E%lu)", ulRC);
return NULL;
}
pcEnd = SDL_strrchr(acBuf, '\\');
if (pcEnd != NULL)
pcEnd[1] = '\0';
else {
if (acBuf[1] == ':') /* e.g. "C:FOO" */
acBuf[2] = '\0';
else {
SDL_SetError("No path in module name");
return NULL;
}
}
return OS2_SysToUTF8(acBuf);
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
PSZ pszPath;
CHAR acBuf[CCHMAXPATH];
int lPosApp, lPosOrg;
PSZ pszApp, pszOrg;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
pszPath = SDL_getenv("HOME");
if (!pszPath) {
pszPath = SDL_getenv("ETC");
if (!pszPath) {
SDL_SetError("HOME or ETC environment not set");
return NULL;
}
}
if (!org) {
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath);
} else {
pszOrg = OS2_UTF8ToSys(org);
if (!pszOrg) {
SDL_OutOfMemory();
return NULL;
}
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s\\%s", pszPath, pszOrg);
SDL_free(pszOrg);
}
if (lPosApp < 0)
return NULL;
DosCreateDir(acBuf, NULL);
pszApp = OS2_UTF8ToSys(app);
if (!pszApp) {
SDL_OutOfMemory();
return NULL;
}
lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp);
SDL_free(pszApp);
if (lPosOrg < 0)
return NULL;
DosCreateDir(acBuf, NULL);
*((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\';
return OS2_SysToUTF8(acBuf);
}
#endif /* SDL_FILESYSTEM_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,110 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include <sys/stat.h>
#include <unistd.h>
#if defined(SDL_FILESYSTEM_PS2)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "SDL_error.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
char *retval;
size_t len;
char cwd[FILENAME_MAX];
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 1;
retval = (char *)SDL_malloc(len);
if (retval) {
SDL_memcpy(retval, cwd, len);
}
return retval;
}
/* Do a recursive mkdir of parents folders */
static void recursive_mkdir(const char *dir)
{
char tmp[FILENAME_MAX];
char *base = SDL_GetBasePath();
char *p = NULL;
size_t len;
snprintf(tmp, sizeof(tmp), "%s", dir);
len = strlen(tmp);
if (tmp[len - 1] == '/') {
tmp[len - 1] = 0;
}
for (p = tmp + 1; *p; p++) {
if (*p == '/') {
*p = 0;
// Just creating subfolders from current path
if (strstr(tmp, base) != NULL) {
mkdir(tmp, S_IRWXU);
}
*p = '/';
}
}
free(base);
mkdir(tmp, S_IRWXU);
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *)SDL_malloc(len);
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}
free(base);
recursive_mkdir(retval);
return retval;
}
#endif /* SDL_FILESYSTEM_PS2 */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,77 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include <sys/stat.h>
#include <unistd.h>
#if defined(SDL_FILESYSTEM_PSP)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "SDL_error.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
char *retval = NULL;
size_t len;
char cwd[FILENAME_MAX];
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 2;
retval = (char *)SDL_malloc(len);
SDL_snprintf(retval, len, "%s/", cwd);
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *)SDL_malloc(len);
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}
free(base);
mkdir(retval, 0755);
return retval;
}
#endif /* SDL_FILESYSTEM_PSP */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,208 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_RISCOS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <kernel.h>
#include <swis.h>
#include <unixlib/local.h>
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
/* Wrapper around __unixify_std that uses SDL's memory allocators */
static char *SDL_unixify_std(const char *ro_path, char *buffer, size_t buf_len, int filetype)
{
const char *const in_buf = buffer; /* = NULL if we allocate the buffer. */
if (!buffer) {
/* This matches the logic in __unixify, with an additional byte for the
* extra path separator.
*/
buf_len = SDL_strlen(ro_path) + 14 + 1;
buffer = SDL_malloc(buf_len);
if (!buffer) {
SDL_OutOfMemory();
return NULL;
}
}
if (!__unixify_std(ro_path, buffer, buf_len, filetype)) {
if (!in_buf) {
SDL_free(buffer);
}
SDL_SetError("Could not convert '%s' to a Unix-style path", ro_path);
return NULL;
}
/* HACK: It's necessary to add an extra path separator here since SDL's API
* requires it, however paths with trailing separators aren't normally valid
* on RISC OS.
*/
if (__get_riscosify_control() & __RISCOSIFY_NO_PROCESS)
SDL_strlcat(buffer, ".", buf_len);
else
SDL_strlcat(buffer, "/", buf_len);
return buffer;
}
static char *canonicalisePath(const char *path, const char *pathVar)
{
_kernel_oserror *error;
_kernel_swi_regs regs;
char *buf;
regs.r[0] = 37;
regs.r[1] = (int)path;
regs.r[2] = 0;
regs.r[3] = (int)pathVar;
regs.r[4] = 0;
regs.r[5] = 0;
error = _kernel_swi(OS_FSControl, &regs, &regs);
if (error) {
SDL_SetError("Couldn't canonicalise path: %s", error->errmess);
return NULL;
}
regs.r[5] = 1 - regs.r[5];
buf = SDL_malloc(regs.r[5]);
if (!buf) {
SDL_OutOfMemory();
return NULL;
}
regs.r[2] = (int)buf;
error = _kernel_swi(OS_FSControl, &regs, &regs);
if (error) {
SDL_SetError("Couldn't canonicalise path: %s", error->errmess);
SDL_free(buf);
return NULL;
}
return buf;
}
static _kernel_oserror *createDirectoryRecursive(char *path)
{
char *ptr = NULL;
_kernel_oserror *error;
_kernel_swi_regs regs;
regs.r[0] = 8;
regs.r[1] = (int)path;
regs.r[2] = 0;
for (ptr = path + 1; *ptr; ptr++) {
if (*ptr == '.') {
*ptr = '\0';
error = _kernel_swi(OS_File, &regs, &regs);
*ptr = '.';
if (error) {
return error;
}
}
}
return _kernel_swi(OS_File, &regs, &regs);
}
char *SDL_GetBasePath(void)
{
_kernel_swi_regs regs;
_kernel_oserror *error;
char *canon, *ptr, *retval;
error = _kernel_swi(OS_GetEnv, &regs, &regs);
if (error) {
return NULL;
}
canon = canonicalisePath((const char *)regs.r[0], "Run$Path");
if (!canon) {
return NULL;
}
/* chop off filename. */
ptr = SDL_strrchr(canon, '.');
if (ptr) {
*ptr = '\0';
}
retval = SDL_unixify_std(canon, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED);
SDL_free(canon);
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
char *canon, *dir, *retval;
size_t len;
_kernel_oserror *error;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
canon = canonicalisePath("<Choices$Write>", "Run$Path");
if (!canon) {
return NULL;
}
len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4;
dir = (char *)SDL_malloc(len);
if (!dir) {
SDL_OutOfMemory();
SDL_free(canon);
return NULL;
}
if (*org) {
SDL_snprintf(dir, len, "%s.%s.%s", canon, org, app);
} else {
SDL_snprintf(dir, len, "%s.%s", canon, app);
}
SDL_free(canon);
error = createDirectoryRecursive(dir);
if (error) {
SDL_SetError("Couldn't create directory: %s", error->errmess);
SDL_free(dir);
return NULL;
}
retval = SDL_unixify_std(dir, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED);
SDL_free(dir);
return retval;
}
#endif /* SDL_FILESYSTEM_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,347 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_UNIX
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <fcntl.h>
#if defined(__FREEBSD__) || defined(__OPENBSD__)
#include <sys/sysctl.h>
#endif
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
#include "SDL_rwops.h"
/* QNX's /proc/self/exefile is a text file and not a symlink. */
#if !defined(__QNXNTO__)
static char *readSymLink(const char *path)
{
char *retval = NULL;
ssize_t len = 64;
ssize_t rc = -1;
while (1) {
char *ptr = (char *)SDL_realloc(retval, (size_t)len);
if (!ptr) {
SDL_OutOfMemory();
break;
}
retval = ptr;
rc = readlink(path, retval, len);
if (rc == -1) {
break; /* not a symlink, i/o error, etc. */
} else if (rc < len) {
retval[rc] = '\0'; /* readlink doesn't null-terminate. */
return retval; /* we're good to go. */
}
len *= 2; /* grow buffer, try again. */
}
SDL_free(retval);
return NULL;
}
#endif
#if defined(__OPENBSD__)
static char *search_path_for_binary(const char *bin)
{
char *envr = SDL_getenv("PATH");
size_t alloc_size;
char *exe = NULL;
char *start = envr;
char *ptr;
if (!envr) {
SDL_SetError("No $PATH set");
return NULL;
}
envr = SDL_strdup(envr);
if (!envr) {
SDL_OutOfMemory();
return NULL;
}
SDL_assert(bin != NULL);
alloc_size = SDL_strlen(bin) + SDL_strlen(envr) + 2;
exe = (char *)SDL_malloc(alloc_size);
do {
ptr = SDL_strchr(start, ':'); /* find next $PATH separator. */
if (ptr != start) {
if (ptr) {
*ptr = '\0';
}
/* build full binary path... */
SDL_snprintf(exe, alloc_size, "%s%s%s", start, (ptr && (ptr[-1] == '/')) ? "" : "/", bin);
if (access(exe, X_OK) == 0) { /* Exists as executable? We're done. */
SDL_free(envr);
return exe;
}
}
start = ptr + 1; /* start points to beginning of next element. */
} while (ptr);
SDL_free(envr);
SDL_free(exe);
SDL_SetError("Process not found in $PATH");
return NULL; /* doesn't exist in path. */
}
#endif
char *SDL_GetBasePath(void)
{
char *retval = NULL;
#if defined(__FREEBSD__)
char fullpath[PATH_MAX];
size_t buflen = sizeof(fullpath);
const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
if (sysctl(mib, SDL_arraysize(mib), fullpath, &buflen, NULL, 0) != -1) {
retval = SDL_strdup(fullpath);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
}
#endif
#if defined(__OPENBSD__)
/* Please note that this will fail if the process was launched with a relative path and $PWD + the cwd have changed, or argv is altered. So don't do that. Or add a new sysctl to OpenBSD. */
char **cmdline;
size_t len;
const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
if (sysctl(mib, 4, NULL, &len, NULL, 0) != -1) {
char *exe, *pwddst;
char *realpathbuf = (char *)SDL_malloc(PATH_MAX + 1);
if (!realpathbuf) {
SDL_OutOfMemory();
return NULL;
}
cmdline = SDL_malloc(len);
if (!cmdline) {
SDL_free(realpathbuf);
SDL_OutOfMemory();
return NULL;
}
sysctl(mib, 4, cmdline, &len, NULL, 0);
exe = cmdline[0];
pwddst = NULL;
if (SDL_strchr(exe, '/') == NULL) { /* not a relative or absolute path, check $PATH for it */
exe = search_path_for_binary(cmdline[0]);
} else {
if (exe && *exe == '.') {
const char *pwd = SDL_getenv("PWD");
if (pwd && *pwd) {
SDL_asprintf(&pwddst, "%s/%s", pwd, exe);
}
}
}
if (exe) {
if (!pwddst) {
if (realpath(exe, realpathbuf) != NULL) {
retval = realpathbuf;
}
} else {
if (realpath(pwddst, realpathbuf) != NULL) {
retval = realpathbuf;
}
SDL_free(pwddst);
}
if (exe != cmdline[0]) {
SDL_free(exe);
}
}
if (!retval) {
SDL_free(realpathbuf);
}
SDL_free(cmdline);
}
#endif
/* is a Linux-style /proc filesystem available? */
if (!retval && (access("/proc", F_OK) == 0)) {
/* !!! FIXME: after 2.0.6 ships, let's delete this code and just
use the /proc/%llu version. There's no reason to have
two copies of this plus all the #ifdefs. --ryan. */
#if defined(__FREEBSD__)
retval = readSymLink("/proc/curproc/file");
#elif defined(__NETBSD__)
retval = readSymLink("/proc/curproc/exe");
#elif defined(__SOLARIS__)
retval = readSymLink("/proc/self/path/a.out");
#elif defined(__QNXNTO__)
retval = SDL_LoadFile("/proc/self/exefile", NULL);
#else
retval = readSymLink("/proc/self/exe"); /* linux. */
if (!retval) {
/* older kernels don't have /proc/self ... try PID version... */
char path[64];
const int rc = SDL_snprintf(path, sizeof(path),
"/proc/%llu/exe",
(unsigned long long)getpid());
if ((rc > 0) && (rc < sizeof(path))) {
retval = readSymLink(path);
}
}
#endif
}
#if defined(__SOLARIS__) /* try this as a fallback if /proc didn't pan out */
if (!retval) {
const char *path = getexecname();
if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
retval = SDL_strdup(path);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
}
}
#endif
/* If we had access to argv[0] here, we could check it for a path,
or troll through $PATH looking for it, too. */
if (retval) { /* chop off filename. */
char *ptr = SDL_strrchr(retval, '/');
if (ptr) {
*(ptr + 1) = '\0';
} else { /* shouldn't happen, but just in case... */
SDL_free(retval);
retval = NULL;
}
}
if (retval) {
/* try to shrink buffer... */
char *ptr = (char *)SDL_realloc(retval, SDL_strlen(retval) + 1);
if (ptr) {
retval = ptr; /* oh well if it failed. */
}
}
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
/*
* We use XDG's base directory spec, even if you're not on Linux.
* This isn't strictly correct, but the results are relatively sane
* in any case.
*
* http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
*/
const char *envr = SDL_getenv("XDG_DATA_HOME");
const char *append;
char *retval = NULL;
char *ptr = NULL;
size_t len = 0;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!envr) {
/* You end up with "$HOME/.local/share/Game Name 2" */
envr = SDL_getenv("HOME");
if (!envr) {
/* we could take heroic measures with /etc/passwd, but oh well. */
SDL_SetError("neither XDG_DATA_HOME nor HOME environment is set");
return NULL;
}
append = "/.local/share/";
} else {
append = "/";
}
len = SDL_strlen(envr);
if (envr[len - 1] == '/') {
append += 1;
}
len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
retval = (char *)SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
if (*org) {
(void)SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app);
} else {
(void)SDL_snprintf(retval, len, "%s%s%s/", envr, append, app);
}
for (ptr = retval + 1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
goto error;
}
*ptr = '/';
}
}
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
error:
SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno));
SDL_free(retval);
return NULL;
}
return retval;
}
#endif /* SDL_FILESYSTEM_UNIX */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,93 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_VITA
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <psp2/io/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <fcntl.h>
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
#include "SDL_rwops.h"
char *SDL_GetBasePath(void)
{
const char *basepath = "app0:/";
char *retval = SDL_strdup(basepath);
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
const char *envr = "ux0:/data/";
char *retval = NULL;
char *ptr = NULL;
size_t len = 0;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(envr);
len += SDL_strlen(org) + SDL_strlen(app) + 3;
retval = (char *)SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", envr, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", envr, app);
}
for (ptr = retval + 1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
sceIoMkdir(retval, 0777);
*ptr = '/';
}
}
sceIoMkdir(retval, 0777);
return retval;
}
#endif /* SDL_FILESYSTEM_VITA */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,173 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_WINDOWS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include "../../core/windows/SDL_windows.h"
#include <shlobj.h>
#include "SDL_error.h"
#include "SDL_stdinc.h"
#include "SDL_filesystem.h"
char *SDL_GetBasePath(void)
{
DWORD buflen = 128;
WCHAR *path = NULL;
char *retval = NULL;
DWORD len = 0;
int i;
while (SDL_TRUE) {
void *ptr = SDL_realloc(path, buflen * sizeof(WCHAR));
if (!ptr) {
SDL_free(path);
SDL_OutOfMemory();
return NULL;
}
path = (WCHAR *)ptr;
len = GetModuleFileNameW(NULL, path, buflen);
/* if it truncated, then len >= buflen - 1 */
/* if there was enough room (or failure), len < buflen - 1 */
if (len < buflen - 1) {
break;
}
/* buffer too small? Try again. */
buflen *= 2;
}
if (len == 0) {
SDL_free(path);
WIN_SetError("Couldn't locate our .exe");
return NULL;
}
for (i = len - 1; i > 0; i--) {
if (path[i] == '\\') {
break;
}
}
SDL_assert(i > 0); /* Should have been an absolute path. */
path[i + 1] = '\0'; /* chop off filename. */
retval = WIN_StringToUTF8W(path);
SDL_free(path);
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
/*
* Vista and later has a new API for this, but SHGetFolderPath works there,
* and apparently just wraps the new API. This is the new way to do it:
*
* SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE,
* NULL, &wszPath);
*/
WCHAR path[MAX_PATH];
char *retval = NULL;
WCHAR *worg = NULL;
WCHAR *wapp = NULL;
size_t new_wpath_len = 0;
BOOL api_result = FALSE;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) {
WIN_SetError("Couldn't locate our prefpath");
return NULL;
}
worg = WIN_UTF8ToStringW(org);
if (!worg) {
SDL_OutOfMemory();
return NULL;
}
wapp = WIN_UTF8ToStringW(app);
if (!wapp) {
SDL_free(worg);
SDL_OutOfMemory();
return NULL;
}
new_wpath_len = SDL_wcslen(worg) + SDL_wcslen(wapp) + SDL_wcslen(path) + 3;
if ((new_wpath_len + 1) > MAX_PATH) {
SDL_free(worg);
SDL_free(wapp);
WIN_SetError("Path too long.");
return NULL;
}
if (*worg) {
SDL_wcslcat(path, L"\\", SDL_arraysize(path));
SDL_wcslcat(path, worg, SDL_arraysize(path));
}
SDL_free(worg);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
SDL_free(wapp);
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", SDL_arraysize(path));
SDL_wcslcat(path, wapp, SDL_arraysize(path));
SDL_free(wapp);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", SDL_arraysize(path));
retval = WIN_StringToUTF8W(path);
return retval;
}
#endif /* SDL_FILESYSTEM_WINDOWS */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -0,0 +1,242 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
/* TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all
*/
#ifdef __WINRT__
extern "C" {
#include "SDL_filesystem.h"
#include "SDL_error.h"
#include "SDL_hints.h"
#include "SDL_stdinc.h"
#include "SDL_system.h"
#include "../../core/windows/SDL_windows.h"
}
#include <string>
#include <unordered_map>
using namespace std;
using namespace Windows::Storage;
extern "C" const wchar_t *
SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
{
switch (pathType) {
case SDL_WINRT_PATH_INSTALLED_LOCATION:
{
static wstring path;
if (path.empty()) {
#if defined(NTDDI_WIN10_19H1) && (NTDDI_VERSION >= NTDDI_WIN10_19H1) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) /* Only PC supports mods */
/* Windows 1903 supports mods, via the EffectiveLocation API */
if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8, 0)) {
path = Windows::ApplicationModel::Package::Current->EffectiveLocation->Path->Data();
} else {
path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
}
#else
path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
#endif
}
return path.c_str();
}
case SDL_WINRT_PATH_LOCAL_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->LocalFolder->Path->Data();
}
return path.c_str();
}
#if !SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION > NTDDI_WIN8)
case SDL_WINRT_PATH_ROAMING_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->RoamingFolder->Path->Data();
}
return path.c_str();
}
case SDL_WINRT_PATH_TEMP_FOLDER:
{
static wstring path;
if (path.empty()) {
path = ApplicationData::Current->TemporaryFolder->Path->Data();
}
return path.c_str();
}
#endif
default:
break;
}
SDL_Unsupported();
return NULL;
}
extern "C" const char *
SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
{
typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
static UTF8PathMap utf8Paths;
UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
if (searchResult != utf8Paths.end()) {
return searchResult->second.c_str();
}
const wchar_t *ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
if (!ucs2Path) {
return NULL;
}
char *utf8Path = WIN_StringToUTF8(ucs2Path);
utf8Paths[pathType] = utf8Path;
SDL_free(utf8Path);
return utf8Paths[pathType].c_str();
}
extern "C" char *
SDL_GetBasePath(void)
{
const char *srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION);
size_t destPathLen;
char *destPath = NULL;
if (!srcPath) {
SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
return NULL;
}
destPathLen = SDL_strlen(srcPath) + 2;
destPath = (char *)SDL_malloc(destPathLen);
if (!destPath) {
SDL_OutOfMemory();
return NULL;
}
SDL_snprintf(destPath, destPathLen, "%s\\", srcPath);
return destPath;
}
extern "C" char *
SDL_GetPrefPath(const char *org, const char *app)
{
/* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and
* earlier is not available on WinRT or Windows Phone. WinRT provides
* a similar API, but SHGetFolderPath can't be called, at least not
* without violating Microsoft's app-store requirements.
*/
const WCHAR *srcPath = NULL;
WCHAR path[MAX_PATH];
char *retval = NULL;
WCHAR *worg = NULL;
WCHAR *wapp = NULL;
size_t new_wpath_len = 0;
BOOL api_result = FALSE;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
srcPath = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_LOCAL_FOLDER);
if (!srcPath) {
SDL_SetError("Unable to find a source path");
return NULL;
}
if (SDL_wcslen(srcPath) >= MAX_PATH) {
SDL_SetError("Path too long.");
return NULL;
}
SDL_wcslcpy(path, srcPath, SDL_arraysize(path));
worg = WIN_UTF8ToString(org);
if (!worg) {
SDL_OutOfMemory();
return NULL;
}
wapp = WIN_UTF8ToString(app);
if (!wapp) {
SDL_free(worg);
SDL_OutOfMemory();
return NULL;
}
new_wpath_len = SDL_wcslen(worg) + SDL_wcslen(wapp) + SDL_wcslen(path) + 3;
if ((new_wpath_len + 1) > MAX_PATH) {
SDL_free(worg);
SDL_free(wapp);
SDL_SetError("Path too long.");
return NULL;
}
if (*worg) {
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, worg, new_wpath_len + 1);
SDL_free(worg);
}
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
SDL_free(wapp);
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, wapp, new_wpath_len + 1);
SDL_free(wapp);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
retval = WIN_StringToUTF8(path);
return retval;
}
#endif /* __WINRT__ */
/* vi: set ts=4 sw=4 expandtab: */