physfs_platform_sdl3.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * SDL3 support routines for PhysicsFS.
  3. *
  4. * Please see the file LICENSE.txt in the source's root directory.
  5. *
  6. * This file written by Rob Loach (@RobLoach).
  7. */
  8. #define __PHYSICSFS_INTERNAL__
  9. #include "physfs_internal.h"
  10. #ifdef PHYSFS_PLATFORM_SDL3
  11. #include <SDL3/SDL.h>
  12. /**
  13. * Context for enumeration.
  14. *
  15. * @see __PHYSFS_platformEnumerate()
  16. */
  17. typedef struct platformEnumerateContext
  18. {
  19. PHYSFS_EnumerateCallback callback;
  20. const char *origdir;
  21. void *callbackdata;
  22. PHYSFS_EnumerateCallbackResult result;
  23. } platformEnumerateContext;
  24. int __PHYSFS_platformInit(const char *argv0)
  25. {
  26. (void)argv0;
  27. return 1; /* always succeed. */
  28. } /* __PHYSFS_platformInit */
  29. void __PHYSFS_platformDeinit(void)
  30. {
  31. /* no-op */
  32. } /* __PHYSFS_platformDeinit */
  33. void *__PHYSFS_platformGetThreadID(void)
  34. {
  35. return (void *)(size_t)SDL_GetCurrentThreadID();
  36. } /* __PHYSFS_platformGetThreadID */
  37. void *__PHYSFS_platformCreateMutex(void)
  38. {
  39. return (void *)SDL_CreateMutex();
  40. } /* __PHYSFS_platformCreateMutex */
  41. void __PHYSFS_platformDestroyMutex(void *mutex)
  42. {
  43. SDL_DestroyMutex((SDL_Mutex *)mutex);
  44. } /* __PHYSFS_platformDestroyMutex */
  45. int __PHYSFS_platformGrabMutex(void *mutex)
  46. {
  47. SDL_LockMutex((SDL_Mutex *)mutex);
  48. return 1;
  49. } /* __PHYSFS_platformGrabMutex */
  50. void __PHYSFS_platformReleaseMutex(void *mutex)
  51. {
  52. SDL_UnlockMutex((SDL_Mutex *)mutex);
  53. } /* __PHYSFS_platformReleaseMutex */
  54. /**
  55. * Not supported by SDL3.
  56. */
  57. void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
  58. {
  59. (void)cb;
  60. (void)data;
  61. } /* __PHYSFS_platformDetectAvailableCDs */
  62. char *__PHYSFS_platformCalcBaseDir(const char *argv0)
  63. {
  64. const char *base = SDL_GetBasePath();
  65. (void)argv0;
  66. BAIL_IF(base == NULL, PHYSFS_ERR_OS_ERROR, NULL);
  67. return __PHYSFS_strdup(base);
  68. } /* __PHYSFS_platformCalcBaseDir */
  69. char *__PHYSFS_platformCalcUserDir(void)
  70. {
  71. const char *home = SDL_GetUserFolder(SDL_FOLDER_HOME);
  72. BAIL_IF(home == NULL, PHYSFS_ERR_OS_ERROR, NULL);
  73. return __PHYSFS_strdup(home);
  74. } /* __PHYSFS_platformCalcUserDir */
  75. char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
  76. {
  77. char *out = SDL_GetPrefPath(org, app);
  78. BAIL_IF(out == NULL, PHYSFS_ERR_OS_ERROR, NULL);
  79. /* Unlike SDL_GetBasePath() or SDL_GetUserFolder(), SDL_GetPrefPath() allocates the string for us. */
  80. return out;
  81. } /* __PHYSFS_platformCalcPrefDir */
  82. static SDL_EnumerationResult SDLCALL platformEnumerateCallback(void *userdata,
  83. const char *dirname,
  84. const char *fname)
  85. {
  86. platformEnumerateContext *ctx = (platformEnumerateContext *)userdata;
  87. (void)dirname;
  88. ctx->result = ctx->callback(ctx->callbackdata, ctx->origdir, fname);
  89. switch (ctx->result) {
  90. case PHYSFS_ENUM_OK: return SDL_ENUM_CONTINUE;
  91. case PHYSFS_ENUM_STOP: return SDL_ENUM_SUCCESS;
  92. case PHYSFS_ENUM_ERROR: return SDL_ENUM_FAILURE;
  93. }
  94. return SDL_ENUM_FAILURE;
  95. } /* platformEnumerateCallback */
  96. PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
  97. PHYSFS_EnumerateCallback callback,
  98. const char *origdir,
  99. void *callbackdata)
  100. {
  101. platformEnumerateContext ctx;
  102. ctx.callback = callback;
  103. ctx.origdir = origdir;
  104. ctx.callbackdata = callbackdata;
  105. ctx.result = PHYSFS_ENUM_OK;
  106. BAIL_IF(!SDL_EnumerateDirectory(dirname, platformEnumerateCallback, &ctx),
  107. /* Determine the correct PhysFS error to report. */
  108. ctx.result == PHYSFS_ENUM_ERROR ? PHYSFS_ERR_APP_CALLBACK : PHYSFS_ERR_OS_ERROR,
  109. PHYSFS_ENUM_ERROR);
  110. return ctx.result;
  111. } /* __PHYSFS_platformEnumerate */
  112. int __PHYSFS_platformMkDir(const char *path)
  113. {
  114. BAIL_IF(!SDL_CreateDirectory(path), PHYSFS_ERR_OS_ERROR, 0);
  115. return 1;
  116. } /* __PHYSFS_platformMkDir */
  117. int __PHYSFS_platformDelete(const char *path)
  118. {
  119. BAIL_IF(!SDL_RemovePath(path), PHYSFS_ERR_OS_ERROR, 0);
  120. return 1;
  121. } /* __PHYSFS_platformDelete */
  122. int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow)
  123. {
  124. SDL_PathInfo info;
  125. (void)follow;
  126. BAIL_IF(!SDL_GetPathInfo(fn, &info), PHYSFS_ERR_NOT_FOUND, 0);
  127. switch (info.type) {
  128. case SDL_PATHTYPE_FILE:
  129. stat->filetype = PHYSFS_FILETYPE_REGULAR;
  130. stat->filesize = (PHYSFS_sint64)info.size;
  131. break;
  132. case SDL_PATHTYPE_DIRECTORY:
  133. stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
  134. stat->filesize = 0;
  135. break;
  136. case SDL_PATHTYPE_OTHER:
  137. stat->filetype = PHYSFS_FILETYPE_OTHER;
  138. stat->filesize = -1;
  139. break;
  140. case SDL_PATHTYPE_NONE:
  141. default:
  142. BAIL(PHYSFS_ERR_NOT_FOUND, 0);
  143. }
  144. stat->accesstime = (PHYSFS_sint64)(info.access_time / SDL_NS_PER_SECOND);
  145. stat->createtime = (PHYSFS_sint64)(info.create_time / SDL_NS_PER_SECOND);
  146. stat->modtime = (PHYSFS_sint64)(info.modify_time / SDL_NS_PER_SECOND);
  147. stat->readonly = 0;
  148. return 1;
  149. } /* __PHYSFS_platformStat */
  150. static void *doOpen(const char *filename, const char* mode)
  151. {
  152. SDL_IOStream *io = SDL_IOFromFile(filename, mode);
  153. BAIL_IF(io == NULL, PHYSFS_ERR_OS_ERROR, NULL);
  154. return io;
  155. } /* doOpen */
  156. void *__PHYSFS_platformOpenRead(const char *filename)
  157. {
  158. return doOpen(filename, "rb");
  159. } /* __PHYSFS_platformOpenRead */
  160. void *__PHYSFS_platformOpenWrite(const char *filename)
  161. {
  162. return doOpen(filename, "wb");
  163. } /* __PHYSFS_platformOpenWrite */
  164. void *__PHYSFS_platformOpenAppend(const char *filename)
  165. {
  166. return doOpen(filename, "ab");
  167. } /* __PHYSFS_platformOpenAppend */
  168. PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
  169. {
  170. SDL_IOStream *io = (SDL_IOStream *)opaque;
  171. size_t size = (size_t)len;
  172. size_t rc = SDL_ReadIO(io, buf, size);
  173. BAIL_IF(rc < size && SDL_GetIOStatus(io) == SDL_IO_STATUS_ERROR, PHYSFS_ERR_IO, -1);
  174. return (PHYSFS_sint64)rc;
  175. } /* __PHYSFS_platformRead */
  176. PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buf, PHYSFS_uint64 len)
  177. {
  178. SDL_IOStream *io = (SDL_IOStream *)opaque;
  179. size_t size = (size_t)len;
  180. size_t rc = SDL_WriteIO(io, buf, size);
  181. BAIL_IF(rc < size && SDL_GetIOStatus(io) == SDL_IO_STATUS_ERROR, PHYSFS_ERR_IO, -1);
  182. return (PHYSFS_sint64)rc;
  183. } /* __PHYSFS_platformWrite */
  184. int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
  185. {
  186. BAIL_IF(SDL_SeekIO((SDL_IOStream *)opaque, (Sint64)pos, SDL_IO_SEEK_SET) < 0, PHYSFS_ERR_IO, 0);
  187. return 1;
  188. } /* __PHYSFS_platformSeek */
  189. PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
  190. {
  191. Sint64 pos = SDL_TellIO((SDL_IOStream *)opaque);
  192. BAIL_IF(pos < 0, PHYSFS_ERR_IO, -1);
  193. return (PHYSFS_sint64)pos;
  194. } /* __PHYSFS_platformTell */
  195. PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
  196. {
  197. Sint64 size = SDL_GetIOSize((SDL_IOStream *)opaque);
  198. BAIL_IF(size < 0, PHYSFS_ERR_IO, -1);
  199. return (PHYSFS_sint64)size;
  200. } /* __PHYSFS_platformFileLength */
  201. int __PHYSFS_platformFlush(void *opaque)
  202. {
  203. BAIL_IF(!SDL_FlushIO((SDL_IOStream *)opaque), PHYSFS_ERR_IO, 0);
  204. return 1;
  205. } /* __PHYSFS_platformFlush */
  206. void __PHYSFS_platformClose(void *opaque)
  207. {
  208. if (!SDL_CloseIO((SDL_IOStream *)opaque)) {
  209. SDL_ClearError();
  210. }
  211. } /* __PHYSFS_platformClose */
  212. #endif