Simple Directmedia Layer
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add SDL_storage

authored by

Ethan Lee and committed by
Sam Lantinga
744227e6 4fc74944

+1035
+30
CMakeLists.txt
··· 494 494 "${SDL3_SOURCE_DIR}/src/render/*/*.c" 495 495 "${SDL3_SOURCE_DIR}/src/sensor/*.c" 496 496 "${SDL3_SOURCE_DIR}/src/stdlib/*.c" 497 + "${SDL3_SOURCE_DIR}/src/storage/*.c" 497 498 "${SDL3_SOURCE_DIR}/src/thread/*.c" 498 499 "${SDL3_SOURCE_DIR}/src/timer/*.c" 499 500 "${SDL3_SOURCE_DIR}/src/video/*.c" ··· 1753 1754 sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/unix/*.c") 1754 1755 set(HAVE_SDL_FILESYSTEM TRUE) 1755 1756 1757 + set(SDL_STORAGE_GENERIC 1) 1758 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c") 1759 + if(LINUX) 1760 + set(SDL_STORAGE_STEAM 1) 1761 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/steam/*.c") 1762 + endif() 1763 + set(HAVE_SDL_STORAGE 1) 1764 + 1756 1765 set(SDL_TIMER_UNIX 1) 1757 1766 sdl_glob_sources("${SDL3_SOURCE_DIR}/src/timer/unix/*.c") 1758 1767 set(HAVE_SDL_TIMERS TRUE) ··· 1972 1981 endif() 1973 1982 set(HAVE_SDL_FILESYSTEM TRUE) 1974 1983 1984 + set(SDL_STORAGE_GENERIC 1) 1985 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c") 1986 + if(NOT WINDOWS_STORE) 1987 + set(SDL_STORAGE_STEAM 1) 1988 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/steam/*.c") 1989 + endif() 1990 + set(HAVE_SDL_STORAGE 1) 1991 + 1975 1992 # Libraries for Win32 native and MinGW 1976 1993 if(NOT WINDOWS_STORE) 1977 1994 sdl_link_dependency(base LIBS kernel32 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32) ··· 2203 2220 set(SDL_FILESYSTEM_COCOA 1) 2204 2221 sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/cocoa/*.m") 2205 2222 set(HAVE_SDL_FILESYSTEM TRUE) 2223 + 2224 + # TODO: SDL_STORAGE_ICLOUD 2225 + set(SDL_STORAGE_GENERIC 1) 2226 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c") 2227 + if(DARWIN OR MACOSX) 2228 + set(SDL_STORAGE_STEAM 1) 2229 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/steam/*.c") 2230 + endif() 2231 + set(HAVE_SDL_STORAGE 1) 2206 2232 2207 2233 if(SDL_SENSOR) 2208 2234 if(IOS OR VISIONOS) ··· 2819 2845 if(NOT HAVE_SDL_FILESYSTEM) 2820 2846 set(SDL_FILESYSTEM_DUMMY 1) 2821 2847 sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/dummy/*.c") 2848 + endif() 2849 + if(NOT HAVE_SDL_STORAGE) 2850 + set(SDL_STORAGE_GENERIC 1) 2851 + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c") 2822 2852 endif() 2823 2853 if(NOT HAVE_SDL_LOCALE) 2824 2854 set(SDL_LOCALE_DUMMY 1)
+3
VisualC-GDK/SDL/SDL.vcxproj
··· 368 368 <ClInclude Include="..\..\include\SDL3\SDL_scancode.h" /> 369 369 <ClInclude Include="..\..\include\SDL3\SDL_sensor.h" /> 370 370 <ClInclude Include="..\..\include\SDL3\SDL_stdinc.h" /> 371 + <ClInclude Include="..\..\include\SDL3\SDL_storage.h" /> 371 372 <ClInclude Include="..\..\include\SDL3\SDL_surface.h" /> 372 373 <ClInclude Include="..\..\include\SDL3\SDL_system.h" /> 373 374 <ClInclude Include="..\..\include\SDL3\SDL_test.h" /> ··· 778 779 <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" /> 779 780 <ClCompile Include="..\..\src\stdlib\SDL_string.c" /> 780 781 <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" /> 782 + <ClCompile Include="..\..\src\storage\generic\SDL_genericstorage.c" /> 783 + <ClCompile Include="..\..\src\storage\SDL_storage.c" /> 781 784 <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" /> 782 785 <ClCompile Include="..\..\src\thread\generic\SDL_sysrwlock.c" /> 783 786 <ClCompile Include="..\..\src\thread\SDL_thread.c" />
+3
VisualC-WinRT/SDL-UWP.vcxproj
··· 82 82 <ClInclude Include="..\include\SDL3\SDL_scancode.h" /> 83 83 <ClInclude Include="..\include\SDL3\SDL_sensor.h" /> 84 84 <ClInclude Include="..\include\SDL3\SDL_stdinc.h" /> 85 + <ClInclude Include="..\include\SDL3\SDL_storage.h" /> 85 86 <ClInclude Include="..\include\SDL3\SDL_surface.h" /> 86 87 <ClInclude Include="..\include\SDL3\SDL_system.h" /> 87 88 <ClInclude Include="..\include\SDL3\SDL_thread.h" /> ··· 439 440 <ClCompile Include="..\src\stdlib\SDL_stdlib.c" /> 440 441 <ClCompile Include="..\src\stdlib\SDL_string.c" /> 441 442 <ClCompile Include="..\src\stdlib\SDL_strtokr.c" /> 443 + <ClCompile Include="..\src\storage\generic\SDL_genericstorage.c" /> 444 + <ClCompile Include="..\src\storage\SDL_storage.c" /> 442 445 <ClCompile Include="..\src\thread\generic\SDL_syssem.c" /> 443 446 <ClCompile Include="..\src\thread\SDL_thread.c" /> 444 447 <ClCompile Include="..\src\thread\stdcpp\SDL_syscond.cpp">
+4
VisualC/SDL/SDL.vcxproj
··· 291 291 <ClInclude Include="..\..\include\SDL3\SDL_scancode.h" /> 292 292 <ClInclude Include="..\..\include\SDL3\SDL_sensor.h" /> 293 293 <ClInclude Include="..\..\include\SDL3\SDL_stdinc.h" /> 294 + <ClInclude Include="..\..\include\SDL3\SDL_storage.h" /> 294 295 <ClInclude Include="..\..\include\SDL3\SDL_surface.h" /> 295 296 <ClInclude Include="..\..\include\SDL3\SDL_system.h" /> 296 297 <ClInclude Include="..\..\include\SDL3\SDL_test.h" /> ··· 635 636 <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" /> 636 637 <ClCompile Include="..\..\src\stdlib\SDL_string.c" /> 637 638 <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" /> 639 + <ClCompile Include="..\..\src\storage\generic\SDL_genericstorage.c" /> 640 + <ClCompile Include="..\..\src\storage\steam\SDL_steamstorage.c" /> 641 + <ClCompile Include="..\..\src\storage\SDL_storage.c" /> 638 642 <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" /> 639 643 <ClCompile Include="..\..\src\thread\generic\SDL_sysrwlock.c" /> 640 644 <ClCompile Include="..\..\src\thread\SDL_thread.c" />
+1
include/SDL3/SDL.h
··· 71 71 #include <SDL3/SDL_iostream.h> 72 72 #include <SDL3/SDL_scancode.h> 73 73 #include <SDL3/SDL_sensor.h> 74 + #include <SDL3/SDL_storage.h> 74 75 #include <SDL3/SDL_surface.h> 75 76 #include <SDL3/SDL_system.h> 76 77 #include <SDL3/SDL_thread.h>
+18
include/SDL3/SDL_hints.h
··· 1905 1905 #define SDL_HINT_SHUTDOWN_DBUS_ON_QUIT "SDL_SHUTDOWN_DBUS_ON_QUIT" 1906 1906 1907 1907 /** 1908 + * A variable that specifies a backend to use for title storage. 1909 + * 1910 + * By default, SDL will try all available storage backends in a reasonable order until it finds one that can work, but this hint allows the app or user to force a specific target, such as "pc" if, say, you are on Steam but want to avoid SteamRemoteStorage for title data. 1911 + * 1912 + * This hint should be set before SDL is initialized. 1913 + */ 1914 + #define SDL_HINT_STORAGE_TITLE_DRIVER "SDL_STORAGE_TITLE_DRIVER" 1915 + 1916 + /** 1917 + * A variable that specifies a backend to use for user storage. 1918 + * 1919 + * By default, SDL will try all available storage backends in a reasonable order until it finds one that can work, but this hint allows the app or user to force a specific target, such as "pc" if, say, you are on Steam but want to avoid SteamRemoteStorage for user data. 1920 + * 1921 + * This hint should be set before SDL is initialized. 1922 + */ 1923 + #define SDL_HINT_STORAGE_USER_DRIVER "SDL_STORAGE_USER_DRIVER" 1924 + 1925 + /** 1908 1926 * Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime. 1909 1927 * 1910 1928 * On some platforms, like Linux, a realtime priority thread may be subject to restrictions that require special handling by the application. This hint exists to let SDL know that the app is prepared to handle said restrictions.
+276
include/SDL3/SDL_storage.h
··· 1 + /* 2 + Simple DirectMedia Layer 3 + Copyright (C) 1997-2024 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 + 22 + /** 23 + * \file SDL_storage.h 24 + * 25 + * Include file for storage container SDL API functions 26 + */ 27 + 28 + #ifndef SDL_storage_h_ 29 + #define SDL_storage_h_ 30 + 31 + #include <SDL3/SDL_stdinc.h> 32 + #include <SDL3/SDL_mutex.h> 33 + #include <SDL3/SDL_properties.h> 34 + 35 + #include <SDL3/SDL_begin_code.h> 36 + 37 + /* Set up for C function definitions, even when using C++ */ 38 + #ifdef __cplusplus 39 + extern "C" { 40 + #endif 41 + 42 + /* !!! FIXME: Don't let this ship without async R/W support!!! */ 43 + 44 + typedef struct SDL_StorageInterface 45 + { 46 + int (SDLCALL *close)(void *userdata); 47 + 48 + SDL_bool (SDLCALL *ready)(void *userdata); 49 + 50 + int (SDLCALL *fileSize)(void *userdata, const char *path, Uint64 *length); 51 + 52 + int (SDLCALL *readFile)(void *userdata, const char *path, void *destination, Uint64 length); 53 + 54 + int (SDLCALL *writeFile)(void *userdata, const char *path, const void *source, Uint64 length); 55 + 56 + Uint64 (SDLCALL *spaceRemaining)(void *userdata); 57 + } SDL_StorageInterface; 58 + 59 + typedef struct SDL_Storage SDL_Storage; 60 + 61 + /** 62 + * Opens up a read-only container for the application's filesystem. 63 + * 64 + * \param override a path to override the backend's default title root 65 + * \param props a property list that may contain backend-specific information 66 + * \returns a title storage container on success or NULL on failure; call 67 + * SDL_GetError() for more information. 68 + * 69 + * \since This function is available since SDL 3.0.0. 70 + * 71 + * \sa SDL_OpenUserStorage 72 + * \sa SDL_OpenStorage 73 + * \sa SDL_TitleStorageReady 74 + * \sa SDL_CloseStorage 75 + * \sa SDL_StorageReady 76 + * \sa SDL_StorageFileSize 77 + * \sa SDL_StorageReadFile 78 + * \sa SDL_StorageWriteFile 79 + * \sa SDL_StorageSpaceRemaining 80 + */ 81 + extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenTitleStorage(const char *override, SDL_PropertiesID props); 82 + 83 + /** 84 + * Opens up a container for a user's unique read/write filesystem. 85 + * 86 + * While title storage can generally be kept open throughout runtime, user 87 + * storage should only be opened when the client is ready to read/write files. 88 + * This allows the backend to properly batch R/W operations and flush them when 89 + * the container has been closed; ensuring safe and optimal save I/O. 90 + * 91 + * \param org the name of your organization 92 + * \param app the name of your application 93 + * \param props a property list that may contain backend-specific information 94 + * \returns a user storage container on success or NULL on failure; call 95 + * SDL_GetError() for more information. 96 + * 97 + * \since This function is available since SDL 3.0.0. 98 + * 99 + * \sa SDL_OpenTitleStorage 100 + * \sa SDL_OpenStorage 101 + * \sa SDL_CloseStorage 102 + * \sa SDL_StorageReady 103 + * \sa SDL_StorageFileSize 104 + * \sa SDL_StorageReadFile 105 + * \sa SDL_StorageWriteFile 106 + * \sa SDL_StorageSpaceRemaining 107 + */ 108 + extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenUserStorage(const char *org, const char *app, SDL_PropertiesID props); 109 + 110 + /** 111 + * Opens up a container using a client-provided storage interface. 112 + * 113 + * Applications do not need to use this function unless they are providing 114 + * their own SDL_Storage implementation. If you just need an 115 + * SDL_Storage, you should use the built-in implementations in SDL, 116 + * like SDL_OpenTitleStorage() or SDL_OpenUserStorage(). 117 + * 118 + * \param iface the function table to be used by this container 119 + * \param userdata the pointer that will be passed to the store interface 120 + * \returns a storage container on success or NULL on failure; call 121 + * SDL_GetError() for more information. 122 + * 123 + * \since This function is available since SDL 3.0.0. 124 + * 125 + * \sa SDL_OpenTitleStorage 126 + * \sa SDL_OpenUserStorage 127 + * \sa SDL_CloseStorage 128 + * \sa SDL_StorageReady 129 + * \sa SDL_StorageFileSize 130 + * \sa SDL_StorageReadFile 131 + * \sa SDL_StorageWriteFile 132 + * \sa SDL_StorageSpaceRemaining 133 + */ 134 + extern DECLSPEC SDL_Storage *SDLCALL SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata); 135 + 136 + /** 137 + * Closes and frees a storage container. 138 + * 139 + * \param storage a storage container to close 140 + * \returns 0 if the container was freed with no errors, a negative value 141 + * otherwise; call SDL_GetError() for more information. Even if the 142 + * function returns an error, the container data will be freed; the 143 + * error is only for informational purposes. 144 + * 145 + * \since This function is available since SDL 3.0.0. 146 + * 147 + * \sa SDL_OpenTitleStorage 148 + * \sa SDL_OpenUserStorage 149 + * \sa SDL_OpenStorage 150 + * \sa SDL_StorageReady 151 + * \sa SDL_StorageFileSize 152 + * \sa SDL_StorageReadFile 153 + * \sa SDL_StorageWriteFile 154 + * \sa SDL_StorageSpaceRemaining 155 + */ 156 + extern DECLSPEC int SDLCALL SDL_CloseStorage(SDL_Storage *storage); 157 + 158 + /** 159 + * Checks if the storage container is ready to use. 160 + * 161 + * This function should be called in regular intervals until it returns 162 + * SDL_TRUE - however, it is not recommended to spinwait on this call, as 163 + * the backend may depend on a synchronous message loop. 164 + * 165 + * \param storage a storage container to query 166 + * \returns SDL_TRUE if the container is ready, SDL_FALSE otherwise 167 + * 168 + * \since This function is available since SDL 3.0.0. 169 + * 170 + * \sa SDL_OpenTitleStorage 171 + * \sa SDL_OpenUserStorage 172 + * \sa SDL_OpenStorage 173 + * \sa SDL_CloseStorage 174 + * \sa SDL_StorageFileSize 175 + * \sa SDL_StorageReadFile 176 + * \sa SDL_StorageWriteFile 177 + * \sa SDL_StorageSpaceRemaining 178 + */ 179 + extern DECLSPEC SDL_bool SDLCALL SDL_StorageReady(SDL_Storage *storage); 180 + 181 + /** 182 + * Query the size of a file within a storage container. 183 + * 184 + * \param storage a storage container to query 185 + * \param path the relative path of the file to query 186 + * \param length a pointer to be filled with the file's length 187 + * \returns 0 if the file could be queried, a negative value otherwise; call 188 + * SDL_GetError() for more information. 189 + * 190 + * \since This function is available since SDL 3.0.0. 191 + * 192 + * \sa SDL_OpenTitleStorage 193 + * \sa SDL_OpenUserStorage 194 + * \sa SDL_OpenStorage 195 + * \sa SDL_CloseStorage 196 + * \sa SDL_StorageReady 197 + * \sa SDL_StorageReadFile 198 + * \sa SDL_StorageWriteFile 199 + * \sa SDL_StorageSpaceRemaining 200 + */ 201 + extern DECLSPEC int SDLCALL SDL_StorageFileSize(SDL_Storage *storage, const char *path, Uint64 *length); 202 + 203 + /** 204 + * Synchronously read a file from a storage container into a client-provided buffer. 205 + * 206 + * \param storage a storage container to read from 207 + * \param path the relative path of the file to read 208 + * \param destination a client-provided buffer to read the file into 209 + * \param length the length of the destination buffer 210 + * \returns 0 if the file was read, a negative value otherwise; call 211 + * SDL_GetError() for more information. 212 + * 213 + * \since This function is available since SDL 3.0.0. 214 + * 215 + * \sa SDL_OpenTitleStorage 216 + * \sa SDL_OpenUserStorage 217 + * \sa SDL_OpenStorage 218 + * \sa SDL_CloseStorage 219 + * \sa SDL_StorageReady 220 + * \sa SDL_StorageFileSize 221 + * \sa SDL_StorageWriteFile 222 + * \sa SDL_StorageSpaceRemaining 223 + */ 224 + extern DECLSPEC int SDLCALL SDL_StorageReadFile(SDL_Storage *storage, const char *path, void *destination, Uint64 length); 225 + 226 + /** 227 + * Synchronously write a file from client memory into a storage container. 228 + * 229 + * \param storage a storage container to write to 230 + * \param path the relative path of the file to write 231 + * \param source a client-provided buffer to write from 232 + * \param length the length of the source buffer 233 + * \returns 0 if the file was written, a negative value otherwise; call 234 + * SDL_GetError() for more information. 235 + * 236 + * \since This function is available since SDL 3.0.0. 237 + * 238 + * \sa SDL_OpenTitleStorage 239 + * \sa SDL_OpenUserStorage 240 + * \sa SDL_OpenStorage 241 + * \sa SDL_CloseStorage 242 + * \sa SDL_StorageReady 243 + * \sa SDL_StorageFileSize 244 + * \sa SDL_StorageReadFile 245 + * \sa SDL_StorageSpaceRemaining 246 + */ 247 + extern DECLSPEC int SDL_StorageWriteFile(SDL_Storage *storage, const char *path, const void *source, Uint64 length); 248 + 249 + /** 250 + * Queries the remaining space in a storage container. 251 + * 252 + * \param storage a storage container to query 253 + * \returns the amount of remaining space, in bytes 254 + * 255 + * \since This function is available since SDL 3.0.0. 256 + * 257 + * \sa SDL_OpenTitleStorage 258 + * \sa SDL_OpenUserStorage 259 + * \sa SDL_OpenStorage 260 + * \sa SDL_CloseStorage 261 + * \sa SDL_StorageReady 262 + * \sa SDL_StorageFileSize 263 + * \sa SDL_StorageReadFile 264 + * \sa SDL_StorageReadFileAsync 265 + * \sa SDL_StorageWriteFile 266 + * \sa SDL_StorageWriteFileAsync 267 + */ 268 + extern DECLSPEC Uint64 SDLCALL SDL_StorageSpaceRemaining(SDL_Storage *storage); 269 + 270 + /* Ends C function definitions when using C++ */ 271 + #ifdef __cplusplus 272 + } 273 + #endif 274 + #include <SDL3/SDL_close_code.h> 275 + 276 + #endif /* SDL_storage_h_ */
+4
include/build_config/SDL_build_config.h.cmake
··· 465 465 #cmakedefine SDL_FILESYSTEM_PS2 @SDL_FILESYSTEM_PS2@ 466 466 #cmakedefine SDL_FILESYSTEM_N3DS @SDL_FILESYSTEM_N3DS@ 467 467 468 + /* Enable system storage support */ 469 + #cmakedefine SDL_STORAGE_GENERIC @SDL_STORAGE_GENERIC@ 470 + #cmakedefine SDL_STORAGE_STEAM @SDL_STORAGE_STEAM@ 471 + 468 472 /* Enable camera subsystem */ 469 473 #cmakedefine SDL_CAMERA_DRIVER_DUMMY @SDL_CAMERA_DRIVER_DUMMY@ 470 474 /* !!! FIXME: for later cmakedefine SDL_CAMERA_DRIVER_DISK @SDL_CAMERA_DRIVER_DISK@ */
+8
src/dynapi/SDL_dynapi.sym
··· 979 979 SDL_OpenIO; 980 980 SDL_CloseIO; 981 981 SDL_GetIOStatus; 982 + SDL_OpenTitleStorage; 983 + SDL_OpenUserStorage; 984 + SDL_OpenStorage; 985 + SDL_CloseStorage; 986 + SDL_StorageReady; 987 + SDL_StorageFileSize; 988 + SDL_StorageReadFile; 989 + SDL_StorageSpaceRemaining; 982 990 # extra symbols go here (don't modify this line) 983 991 local: *; 984 992 };
+8
src/dynapi/SDL_dynapi_overrides.h
··· 1004 1004 #define SDL_OpenIO SDL_OpenIO_REAL 1005 1005 #define SDL_CloseIO SDL_CloseIO_REAL 1006 1006 #define SDL_GetIOStatus SDL_GetIOStatus_REAL 1007 + #define SDL_OpenTitleStorage SDL_OpenTitleStorage_REAL 1008 + #define SDL_OpenUserStorage SDL_OpenUserStorage_REAL 1009 + #define SDL_OpenStorage SDL_OpenStorage_REAL 1010 + #define SDL_CloseStorage SDL_CloseStorage_REAL 1011 + #define SDL_StorageReady SDL_StorageReady_REAL 1012 + #define SDL_StorageFileSize SDL_StorageFileSize_REAL 1013 + #define SDL_StorageReadFile SDL_StorageReadFile_REAL 1014 + #define SDL_StorageSpaceRemaining SDL_StorageSpaceRemaining_REAL
+8
src/dynapi/SDL_dynapi_procs.h
··· 1029 1029 SDL_DYNAPI_PROC(SDL_IOStream*,SDL_OpenIO,(const SDL_IOStreamInterface *a, void *b),(a,b),return) 1030 1030 SDL_DYNAPI_PROC(int,SDL_CloseIO,(SDL_IOStream *a),(a),return) 1031 1031 SDL_DYNAPI_PROC(SDL_IOStatus,SDL_GetIOStatus,(SDL_IOStream *a),(a),return) 1032 + SDL_DYNAPI_PROC(SDL_Storage*,SDL_OpenTitleStorage,(const char *a, SDL_PropertiesID b),(a,b),return) 1033 + SDL_DYNAPI_PROC(SDL_Storage*,SDL_OpenUserStorage,(const char *a, const char *b, SDL_PropertiesID c),(a,b,c),return) 1034 + SDL_DYNAPI_PROC(SDL_Storage*,SDL_OpenStorage,(const SDL_StorageInterface *a, void *b),(a,b),return) 1035 + SDL_DYNAPI_PROC(int,SDL_CloseStorage,(SDL_Storage *a),(a),return) 1036 + SDL_DYNAPI_PROC(SDL_bool,SDL_StorageReady,(SDL_Storage *a),(a),return) 1037 + SDL_DYNAPI_PROC(int,SDL_StorageFileSize,(SDL_Storage *a, const char *b, Uint64 *c),(a,b,c),return) 1038 + SDL_DYNAPI_PROC(int,SDL_StorageReadFile,(SDL_Storage *a, const char *b, void *c, Uint64 d),(a,b,c,d),return) 1039 + SDL_DYNAPI_PROC(Uint64,SDL_StorageSpaceRemaining,(SDL_Storage *a),(a),return)
+222
src/storage/SDL_storage.c
··· 1 + /* 2 + Simple DirectMedia Layer 3 + Copyright (C) 1997-2024 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 + 22 + #include "SDL_internal.h" 23 + 24 + #include "SDL_sysstorage.h" 25 + 26 + /* Available title storage drivers */ 27 + static TitleStorageBootStrap *titlebootstrap[] = { 28 + &GENERIC_titlebootstrap, 29 + }; 30 + 31 + /* Available user storage drivers */ 32 + static UserStorageBootStrap *userbootstrap[] = { 33 + #ifdef SDL_STORAGE_STEAM 34 + &STEAM_userbootstrap, 35 + #endif 36 + &GENERIC_userbootstrap, 37 + }; 38 + 39 + struct SDL_Storage 40 + { 41 + SDL_StorageInterface iface; 42 + void *userdata; 43 + }; 44 + 45 + #define CHECK_STORAGE_MAGIC() \ 46 + if (!storage) { \ 47 + return SDL_SetError("Invalid storage container"); \ 48 + } 49 + 50 + #define CHECK_STORAGE_MAGIC_RET(retval) \ 51 + if (!storage) { \ 52 + SDL_SetError("Invalid storage container"); \ 53 + return retval; \ 54 + } 55 + 56 + SDL_Storage *SDL_OpenTitleStorage(const char *override, SDL_PropertiesID props) 57 + { 58 + SDL_Storage *storage = NULL; 59 + int i = 0; 60 + 61 + /* Select the proper storage driver */ 62 + const char *driver_name = SDL_GetHint(SDL_HINT_STORAGE_TITLE_DRIVER); 63 + if (driver_name && *driver_name != 0) { 64 + const char *driver_attempt = driver_name; 65 + while (driver_attempt && *driver_attempt != 0 && !storage) { 66 + const char *driver_attempt_end = SDL_strchr(driver_attempt, ','); 67 + size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt) 68 + : SDL_strlen(driver_attempt); 69 + 70 + for (i = 0; titlebootstrap[i]; ++i) { 71 + if ((driver_attempt_len == SDL_strlen(titlebootstrap[i]->name)) && 72 + (SDL_strncasecmp(titlebootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { 73 + storage = titlebootstrap[i]->create(override, props); 74 + break; 75 + } 76 + } 77 + 78 + driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL; 79 + } 80 + } else { 81 + for (i = 0; titlebootstrap[i]; ++i) { 82 + storage = titlebootstrap[i]->create(override, props); 83 + if (storage) { 84 + break; 85 + } 86 + } 87 + } 88 + if (!storage) { 89 + if (driver_name) { 90 + SDL_SetError("%s not available", driver_name); 91 + } else { 92 + SDL_SetError("No available title storage driver"); 93 + } 94 + } 95 + return storage; 96 + } 97 + 98 + SDL_Storage *SDL_OpenUserStorage(const char *org, const char *app, SDL_PropertiesID props) 99 + { 100 + SDL_Storage *storage = NULL; 101 + int i = 0; 102 + 103 + /* Select the proper storage driver */ 104 + const char *driver_name = SDL_GetHint(SDL_HINT_STORAGE_USER_DRIVER); 105 + if (driver_name && *driver_name != 0) { 106 + const char *driver_attempt = driver_name; 107 + while (driver_attempt && *driver_attempt != 0 && !storage) { 108 + const char *driver_attempt_end = SDL_strchr(driver_attempt, ','); 109 + size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt) 110 + : SDL_strlen(driver_attempt); 111 + 112 + for (i = 0; userbootstrap[i]; ++i) { 113 + if ((driver_attempt_len == SDL_strlen(userbootstrap[i]->name)) && 114 + (SDL_strncasecmp(userbootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { 115 + storage = userbootstrap[i]->create(org, app, props); 116 + break; 117 + } 118 + } 119 + 120 + driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL; 121 + } 122 + } else { 123 + for (i = 0; userbootstrap[i]; ++i) { 124 + storage = userbootstrap[i]->create(org, app, props); 125 + if (storage) { 126 + break; 127 + } 128 + } 129 + } 130 + if (!storage) { 131 + if (driver_name) { 132 + SDL_SetError("%s not available", driver_name); 133 + } else { 134 + SDL_SetError("No available user storage driver"); 135 + } 136 + } 137 + return storage; 138 + } 139 + 140 + SDL_Storage *SDL_OpenStorage(const SDL_StorageInterface *iface, void *userdata) 141 + { 142 + SDL_Storage *storage; 143 + 144 + if (iface->close == NULL || iface->ready == NULL || iface->fileSize == NULL) { 145 + SDL_SetError("iface is missing required callbacks"); 146 + return NULL; 147 + } 148 + 149 + if ((iface->writeFile != NULL) != (iface->spaceRemaining != NULL)) { 150 + SDL_SetError("Writeable containers must have both writeFile and spaceRemaining"); 151 + return NULL; 152 + } 153 + 154 + storage = (SDL_Storage*) SDL_malloc(sizeof(SDL_Storage)); 155 + if (storage == NULL) { 156 + SDL_OutOfMemory(); 157 + return NULL; 158 + } 159 + 160 + SDL_memcpy(&storage->iface, iface, sizeof(SDL_StorageInterface)); 161 + storage->userdata = userdata; 162 + return storage; 163 + } 164 + 165 + int SDL_CloseStorage(SDL_Storage *storage) 166 + { 167 + int retval; 168 + 169 + CHECK_STORAGE_MAGIC() 170 + 171 + retval = storage->iface.close(storage->userdata); 172 + SDL_free(storage); 173 + return retval; 174 + } 175 + 176 + SDL_bool SDL_StorageReady(SDL_Storage *storage) 177 + { 178 + CHECK_STORAGE_MAGIC_RET(SDL_FALSE) 179 + 180 + return storage->iface.ready(storage->userdata); 181 + } 182 + 183 + int SDL_StorageFileSize(SDL_Storage *storage, const char *path, Uint64 *length) 184 + { 185 + CHECK_STORAGE_MAGIC() 186 + 187 + return storage->iface.fileSize(storage->userdata, path, length); 188 + } 189 + 190 + int SDL_StorageReadFile(SDL_Storage *storage, const char *path, void *destination, Uint64 length) 191 + { 192 + CHECK_STORAGE_MAGIC() 193 + 194 + if (storage->iface.readFile == NULL) { 195 + return SDL_SetError("Storage container does not have read capability"); 196 + } 197 + 198 + return storage->iface.readFile(storage->userdata, path, destination, length); 199 + } 200 + 201 + int SDL_StorageWriteFile(SDL_Storage *storage, const char *path, const void *source, Uint64 length) 202 + { 203 + CHECK_STORAGE_MAGIC() 204 + 205 + if (storage->iface.writeFile == NULL) { 206 + return SDL_SetError("Storage container does not have write capability"); 207 + } 208 + 209 + return storage->iface.writeFile(storage->userdata, path, source, length); 210 + } 211 + 212 + Uint64 SDL_StorageSpaceRemaining(SDL_Storage *storage) 213 + { 214 + CHECK_STORAGE_MAGIC_RET(0) 215 + 216 + if (storage->iface.spaceRemaining == NULL) { 217 + SDL_SetError("Storage container does not have write capability"); 218 + return 0; 219 + } 220 + 221 + return storage->iface.spaceRemaining(storage->userdata); 222 + }
+49
src/storage/SDL_sysstorage.h
··· 1 + /* 2 + Simple DirectMedia Layer 3 + Copyright (C) 1997-2024 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 + 22 + #ifndef SDL_sysstorage_h_ 23 + #define SDL_sysstorage_h_ 24 + 25 + #include "SDL_internal.h" 26 + 27 + typedef struct TitleStorageBootStrap 28 + { 29 + const char *name; 30 + const char *desc; 31 + SDL_Storage *(*create)(const char*, SDL_PropertiesID); 32 + } TitleStorageBootStrap; 33 + 34 + typedef struct UserStorageBootStrap 35 + { 36 + const char *name; 37 + const char *desc; 38 + SDL_Storage *(*create)(const char*, const char*, SDL_PropertiesID); 39 + } UserStorageBootStrap; 40 + 41 + /* Not all of these are available in a given build. Use #ifdefs, etc. */ 42 + 43 + extern TitleStorageBootStrap GENERIC_titlebootstrap; 44 + /* Steam does not have title storage APIs */ 45 + 46 + extern UserStorageBootStrap GENERIC_userbootstrap; 47 + extern UserStorageBootStrap STEAM_userbootstrap; 48 + 49 + #endif /* SDL_sysstorage_h_ */
+188
src/storage/generic/SDL_genericstorage.c
··· 1 + /* 2 + Simple DirectMedia Layer 3 + Copyright (C) 1997-2024 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 + 22 + #include "SDL_internal.h" 23 + 24 + #include "../SDL_sysstorage.h" 25 + 26 + static char *GENERIC_INTERNAL_CreateFullPath(const char *base, const char *relative) 27 + { 28 + size_t fulllen = SDL_strlen(base) + SDL_strlen(relative) + 1; 29 + char *result = (char*) SDL_malloc(fulllen); 30 + if (result != NULL) { 31 + SDL_snprintf(result, fulllen, "%s%s", base, relative); 32 + } 33 + return result; 34 + } 35 + 36 + static int GENERIC_StorageClose(void *userdata) 37 + { 38 + SDL_free(userdata); 39 + return 0; 40 + } 41 + 42 + static SDL_bool GENERIC_StorageReady(void *userdata) 43 + { 44 + return SDL_TRUE; 45 + } 46 + 47 + static int GENERIC_StorageFileSize(void *userdata, const char *path, Uint64 *length) 48 + { 49 + SDL_IOStream *stream; 50 + Sint64 result; 51 + 52 + char *fullpath = GENERIC_INTERNAL_CreateFullPath((char*) userdata, path); 53 + if (fullpath == NULL) { 54 + return SDL_OutOfMemory(); 55 + } 56 + stream = SDL_IOFromFile(fullpath, "rb"); 57 + SDL_free(fullpath); 58 + 59 + result = SDL_SizeIO(stream); 60 + SDL_CloseIO(stream); 61 + if (result < 0) { 62 + return result; 63 + } 64 + 65 + /* FIXME: Should SDL_SizeIO use u64 now...? */ 66 + *length = (Uint64) result; 67 + return 0; 68 + } 69 + 70 + static int GENERIC_StorageReadFile(void *userdata, const char *path, void *destination, Uint64 length) 71 + { 72 + SDL_IOStream *stream; 73 + char *fullpath; 74 + int fullread; 75 + 76 + if (length > SDL_SIZE_MAX) { 77 + return SDL_SetError("Read size exceeds SDL_SIZE_MAX"); 78 + } 79 + 80 + fullpath = GENERIC_INTERNAL_CreateFullPath((char*) userdata, path); 81 + if (fullpath == NULL) { 82 + return SDL_OutOfMemory(); 83 + } 84 + stream = SDL_IOFromFile(fullpath, "rb"); 85 + SDL_free(fullpath); 86 + 87 + /* FIXME: Should SDL_ReadIO use u64 now...? */ 88 + fullread = (SDL_ReadIO(stream, destination, (size_t) length) == length); 89 + SDL_CloseIO(stream); 90 + return fullread - 1; 91 + } 92 + 93 + static int GENERIC_StorageWriteFile(void *userdata, const char *path, const void *source, Uint64 length) 94 + { 95 + /* TODO: Recursively create subdirectories with SDL_mkdir */ 96 + SDL_IOStream *stream; 97 + char *fullpath; 98 + int fullwrite; 99 + 100 + if (length > SDL_SIZE_MAX) { 101 + return SDL_SetError("Write size exceeds SDL_SIZE_MAX"); 102 + } 103 + 104 + fullpath = GENERIC_INTERNAL_CreateFullPath((char*) userdata, path); 105 + if (fullpath == NULL) { 106 + return SDL_OutOfMemory(); 107 + } 108 + stream = SDL_IOFromFile(fullpath, "wb"); 109 + SDL_free(fullpath); 110 + 111 + /* FIXME: Should SDL_WriteIO use u64 now...? */ 112 + fullwrite = (SDL_WriteIO(stream, source, (size_t) length) == length); 113 + SDL_CloseIO(stream); 114 + return fullwrite - 1; 115 + } 116 + 117 + static Uint64 GENERIC_StorageSpaceRemaining(void *userdata) 118 + { 119 + /* TODO: There's totally a way to query a folder root's quota... */ 120 + return SDL_MAX_UINT64; 121 + } 122 + 123 + static const SDL_StorageInterface GENERIC_title_iface = { 124 + GENERIC_StorageClose, 125 + GENERIC_StorageReady, 126 + GENERIC_StorageFileSize, 127 + GENERIC_StorageReadFile, 128 + NULL, 129 + NULL 130 + }; 131 + 132 + static SDL_Storage *GENERIC_Title_Create(const char *override, SDL_PropertiesID props) 133 + { 134 + SDL_Storage *result; 135 + 136 + char *basepath; 137 + if (override != NULL) { 138 + basepath = SDL_strdup(override); 139 + } else { 140 + basepath = SDL_GetBasePath(); 141 + } 142 + if (basepath == NULL) { 143 + return NULL; 144 + } 145 + 146 + result = SDL_OpenStorage(&GENERIC_title_iface, basepath); 147 + if (result == NULL) { 148 + SDL_free(basepath); 149 + } 150 + return result; 151 + } 152 + 153 + TitleStorageBootStrap GENERIC_titlebootstrap = { 154 + "generic", 155 + "SDL generic title storage driver", 156 + GENERIC_Title_Create 157 + }; 158 + 159 + static const SDL_StorageInterface GENERIC_user_iface = { 160 + GENERIC_StorageClose, 161 + GENERIC_StorageReady, 162 + GENERIC_StorageFileSize, 163 + GENERIC_StorageReadFile, 164 + GENERIC_StorageWriteFile, 165 + GENERIC_StorageSpaceRemaining 166 + }; 167 + 168 + static SDL_Storage *GENERIC_User_Create(const char *org, const char *app, SDL_PropertiesID props) 169 + { 170 + SDL_Storage *result; 171 + 172 + char *prefpath = SDL_GetPrefPath(org, app); 173 + if (prefpath == NULL) { 174 + return NULL; 175 + } 176 + 177 + result = SDL_OpenStorage(&GENERIC_user_iface, prefpath); 178 + if (result == NULL) { 179 + SDL_free(prefpath); 180 + } 181 + return result; 182 + } 183 + 184 + UserStorageBootStrap GENERIC_userbootstrap = { 185 + "generic", 186 + "SDL generic user storage driver", 187 + GENERIC_User_Create 188 + };
+199
src/storage/steam/SDL_steamstorage.c
··· 1 + /* 2 + Simple DirectMedia Layer 3 + Copyright (C) 1997-2024 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 + 22 + #include "SDL_internal.h" 23 + 24 + #include "../SDL_sysstorage.h" 25 + 26 + #include <stdbool.h> /* Needed by Steamworks */ 27 + 28 + // !!! FIXME: Async API can use SteamRemoteStorage_ReadFileAsync 29 + // !!! FIXME: Async API can use SteamRemoteStorage_WriteFileAsync 30 + 31 + #define STEAM_PROC(ret, func, parms) \ 32 + typedef ret (*steamfntype_##func) parms; 33 + #include "SDL_steamstorage_proc.h" 34 + 35 + typedef struct STEAM_RemoteStorage 36 + { 37 + void *libsteam_api; 38 + #define STEAM_PROC(ret, func, parms) \ 39 + steamfntype_##func func; 40 + #include "SDL_steamstorage_proc.h" 41 + } STEAM_RemoteStorage; 42 + 43 + static int STEAM_UserStorageClose(void *userdata) 44 + { 45 + int result = 0; 46 + STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata; 47 + void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 48 + if (steamremotestorage == NULL) { 49 + result = SDL_SetError("SteamRemoteStorage unavailable"); 50 + } else if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) { 51 + result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed"); 52 + } 53 + SDL_UnloadObject(steam->libsteam_api); 54 + SDL_free(steam); 55 + return result; 56 + } 57 + 58 + static SDL_bool STEAM_UserStorageReady(void *userdata) 59 + { 60 + return SDL_TRUE; 61 + } 62 + 63 + static int STEAM_UserStorageFileSize(void *userdata, const char *path, Uint64 *length) 64 + { 65 + STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata; 66 + void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 67 + if (steamremotestorage == NULL) { 68 + return SDL_SetError("SteamRemoteStorage unavailable"); 69 + } 70 + *length = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path); 71 + return 0; 72 + } 73 + 74 + static int STEAM_UserStorageReadFile(void *userdata, const char *path, void *destination, Uint64 length) 75 + { 76 + int retval; 77 + STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata; 78 + void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 79 + if (steamremotestorage == NULL) { 80 + return SDL_SetError("SteamRemoteStorage unavailable"); 81 + } 82 + if (length > SDL_MAX_SINT32) { 83 + return SDL_SetError("SteamRemoteStorage only supports INT32_MAX read size"); 84 + } 85 + retval = steam->SteamAPI_ISteamRemoteStorage_FileRead(steamremotestorage, path, destination, (Sint32) length) == length; 86 + return retval - 1; 87 + } 88 + 89 + static int STEAM_UserStorageWriteFile(void *userdata, const char *path, const void *source, Uint64 length) 90 + { 91 + int retval; 92 + STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata; 93 + void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 94 + if (steamremotestorage == NULL) { 95 + return SDL_SetError("SteamRemoteStorage unavailable"); 96 + } 97 + if (length > SDL_MAX_SINT32) { 98 + return SDL_SetError("SteamRemoteStorage only supports INT32_MAX write size"); 99 + } 100 + retval = steam->SteamAPI_ISteamRemoteStorage_FileWrite(steamremotestorage, path, source, (Sint32) length) == length; 101 + return retval - 1; 102 + } 103 + 104 + static Uint64 STEAM_UserStorageSpaceRemaining(void *userdata) 105 + { 106 + Uint64 total, remaining; 107 + STEAM_RemoteStorage *steam = (STEAM_RemoteStorage*) userdata; 108 + void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 109 + if (steamremotestorage == NULL) { 110 + SDL_SetError("SteamRemoteStorage unavailable"); 111 + return 0; 112 + } 113 + if (!steam->SteamAPI_ISteamRemoteStorage_GetQuota(steamremotestorage, &total, &remaining)) { 114 + SDL_SetError("SteamRemoteStorage()->GetQuota failed"); 115 + return 0; 116 + } 117 + return remaining; 118 + } 119 + 120 + static const SDL_StorageInterface STEAM_user_iface = { 121 + STEAM_UserStorageClose, 122 + STEAM_UserStorageReady, 123 + STEAM_UserStorageFileSize, 124 + STEAM_UserStorageReadFile, 125 + STEAM_UserStorageWriteFile, 126 + STEAM_UserStorageSpaceRemaining 127 + }; 128 + 129 + static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_PropertiesID props) 130 + { 131 + SDL_Storage *result; 132 + STEAM_RemoteStorage *steam; 133 + void *steamremotestorage; 134 + 135 + steam = (STEAM_RemoteStorage*) SDL_malloc(sizeof(STEAM_RemoteStorage)); 136 + if (steam == NULL) { 137 + SDL_OutOfMemory(); 138 + return NULL; 139 + } 140 + 141 + steam->libsteam_api = SDL_LoadObject( 142 + #if defined(_WIN64) 143 + "steam_api64.dll" 144 + #elif defined(_WIN32) 145 + "steam_api.dll" 146 + #elif defined(__APPLE__) 147 + "libsteam_api.dylib" 148 + #else 149 + "libsteam_api.so" 150 + #endif 151 + ); 152 + if (steam->libsteam_api == NULL) { 153 + SDL_free(steam); 154 + return NULL; 155 + } 156 + 157 + #define STEAM_PROC(ret, func, parms) \ 158 + steam->func = (steamfntype_##func) SDL_LoadFunction(steam->libsteam_api, #func); \ 159 + if (steam->func == NULL) { \ 160 + SDL_SetError("Could not load function " #func); \ 161 + goto steamfail; \ 162 + } 163 + #include "SDL_steamstorage_proc.h" 164 + 165 + steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016(); 166 + if (steamremotestorage == NULL) { 167 + SDL_SetError("SteamRemoteStorage unavailable"); 168 + goto steamfail; 169 + } 170 + if (!steam->SteamAPI_ISteamRemoteStorage_IsCloudEnabledForAccount(steamremotestorage)) { 171 + SDL_SetError("Steam cloud is disabled for this user"); 172 + goto steamfail; 173 + } 174 + if (!steam->SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp(steamremotestorage)) { 175 + SDL_SetError("Steam cloud is disabled for this application"); 176 + goto steamfail; 177 + } 178 + if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) { 179 + SDL_SetError("SteamRemoteStorage()->BeginFileWriteBatch failed"); 180 + goto steamfail; 181 + } 182 + 183 + result = SDL_OpenStorage(&STEAM_user_iface, steam); 184 + if (result == NULL) { 185 + goto steamfail; 186 + } 187 + return result; 188 + 189 + steamfail: 190 + SDL_UnloadObject(steam->libsteam_api); 191 + SDL_free(steam); 192 + return NULL; 193 + } 194 + 195 + UserStorageBootStrap STEAM_userbootstrap = { 196 + "steam", 197 + "SDL Steam user storage driver", 198 + STEAM_User_Create 199 + };
+14
src/storage/steam/SDL_steamstorage_proc.h
··· 1 + STEAM_PROC(void*, SteamAPI_SteamRemoteStorage_v016, (void)) 2 + 3 + STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_IsCloudEnabledForAccount, (void*)) 4 + STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp, (void*)) 5 + 6 + STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch, (void*)) 7 + STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_EndFileWriteBatch, (void*)) 8 + 9 + STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileSize, (void*, const char*)) 10 + STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileRead, (void*, const char*, void*, Sint32)) 11 + STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileWrite, (void*, const char*, const void*, Sint32)) 12 + STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_GetQuota, (void*, Uint64*, Uint64*)) 13 + 14 + #undef STEAM_PROC