1.1 --- a/include/SDL_config_winrt.h Tue Mar 04 19:49:11 2014 -0500
1.2 +++ b/include/SDL_config_winrt.h Sun Mar 09 11:06:11 2014 -0700
1.3 @@ -166,9 +166,9 @@
1.4 #define SDL_VIDEO_DRIVER_WINRT 1
1.5 #define SDL_VIDEO_DRIVER_DUMMY 1
1.6
1.7 -/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */
1.8 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */
1.9 -#define SDL_VIDEO_OPENGL_ES2 1
1.10 +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */
1.11 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */
1.12 +#define SDL_VIDEO_OPENGL_ES2 1
1.13 #define SDL_VIDEO_OPENGL_EGL 1
1.14 #endif
1.15
2.1 --- a/include/SDL_egl.h Tue Mar 04 19:49:11 2014 -0500
2.2 +++ b/include/SDL_egl.h Sun Mar 09 11:06:11 2014 -0700
2.3 @@ -393,8 +393,8 @@
2.4
2.5 #if __WINRT__
2.6 #include <Unknwn.h>
2.7 -typedef IUnknown * EGLNativeWindowType;
2.8 -typedef int EGLNativeDisplayType;
2.9 +typedef IUnknown * EGLNativeWindowType;
2.10 +typedef int EGLNativeDisplayType;
2.11 typedef HBITMAP EGLNativePixmapType;
2.12 #else
2.13 typedef HDC EGLNativeDisplayType;
3.1 --- a/include/SDL_main.h Tue Mar 04 19:49:11 2014 -0500
3.2 +++ b/include/SDL_main.h Sun Mar 09 11:06:11 2014 -0700
3.3 @@ -140,7 +140,7 @@
3.4 * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more
3.5 * information on the failure.
3.6 */
3.7 -extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel);
3.8 +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel);
3.9
3.10 #endif /* __WINRT__ */
3.11
4.1 --- a/include/SDL_platform.h Tue Mar 04 19:49:11 2014 -0500
4.2 +++ b/include/SDL_platform.h Sun Mar 09 11:06:11 2014 -0700
4.3 @@ -1,168 +1,168 @@
4.4 -/*
4.5 - Simple DirectMedia Layer
4.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4.7 -
4.8 - This software is provided 'as-is', without any express or implied
4.9 - warranty. In no event will the authors be held liable for any damages
4.10 - arising from the use of this software.
4.11 -
4.12 - Permission is granted to anyone to use this software for any purpose,
4.13 - including commercial applications, and to alter it and redistribute it
4.14 - freely, subject to the following restrictions:
4.15 -
4.16 - 1. The origin of this software must not be misrepresented; you must not
4.17 - claim that you wrote the original software. If you use this software
4.18 - in a product, an acknowledgment in the product documentation would be
4.19 - appreciated but is not required.
4.20 - 2. Altered source versions must be plainly marked as such, and must not be
4.21 - misrepresented as being the original software.
4.22 - 3. This notice may not be removed or altered from any source distribution.
4.23 -*/
4.24 -
4.25 -/**
4.26 - * \file SDL_platform.h
4.27 - *
4.28 - * Try to get a standard set of platform defines.
4.29 - */
4.30 -
4.31 -#ifndef _SDL_platform_h
4.32 -#define _SDL_platform_h
4.33 -
4.34 -#if defined(_AIX)
4.35 -#undef __AIX__
4.36 -#define __AIX__ 1
4.37 -#endif
4.38 -#if defined(__HAIKU__)
4.39 -#undef __HAIKU__
4.40 -#define __HAIKU__ 1
4.41 -#endif
4.42 -#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
4.43 -#undef __BSDI__
4.44 -#define __BSDI__ 1
4.45 -#endif
4.46 -#if defined(_arch_dreamcast)
4.47 -#undef __DREAMCAST__
4.48 -#define __DREAMCAST__ 1
4.49 -#endif
4.50 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
4.51 -#undef __FREEBSD__
4.52 -#define __FREEBSD__ 1
4.53 -#endif
4.54 -#if defined(hpux) || defined(__hpux) || defined(__hpux__)
4.55 -#undef __HPUX__
4.56 -#define __HPUX__ 1
4.57 -#endif
4.58 -#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE)
4.59 -#undef __IRIX__
4.60 -#define __IRIX__ 1
4.61 -#endif
4.62 -#if defined(linux) || defined(__linux) || defined(__linux__)
4.63 -#undef __LINUX__
4.64 -#define __LINUX__ 1
4.65 -#endif
4.66 -#if defined(ANDROID)
4.67 -#undef __ANDROID__
4.68 -#undef __LINUX__ /* do we need to do this? */
4.69 -#define __ANDROID__ 1
4.70 -#endif
4.71 -
4.72 -#if defined(__APPLE__)
4.73 -/* lets us know what version of Mac OS X we're compiling on */
4.74 -#include "AvailabilityMacros.h"
4.75 -#include "TargetConditionals.h"
4.76 -#if TARGET_OS_IPHONE
4.77 -/* if compiling for iPhone */
4.78 -#undef __IPHONEOS__
4.79 -#define __IPHONEOS__ 1
4.80 -#undef __MACOSX__
4.81 -#else
4.82 -/* if not compiling for iPhone */
4.83 -#undef __MACOSX__
4.84 -#define __MACOSX__ 1
4.85 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
4.86 -# error SDL for Mac OS X only supports deploying on 10.5 and above.
4.87 -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */
4.88 -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
4.89 -# error SDL for Mac OS X must be built with a 10.6 SDK or above.
4.90 -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1060 */
4.91 -#endif /* TARGET_OS_IPHONE */
4.92 -#endif /* defined(__APPLE__) */
4.93 -
4.94 -#if defined(__NetBSD__)
4.95 -#undef __NETBSD__
4.96 -#define __NETBSD__ 1
4.97 -#endif
4.98 -#if defined(__OpenBSD__)
4.99 -#undef __OPENBSD__
4.100 -#define __OPENBSD__ 1
4.101 -#endif
4.102 -#if defined(__OS2__)
4.103 -#undef __OS2__
4.104 -#define __OS2__ 1
4.105 -#endif
4.106 -#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE)
4.107 -#undef __OSF__
4.108 -#define __OSF__ 1
4.109 -#endif
4.110 -#if defined(__QNXNTO__)
4.111 -#undef __QNXNTO__
4.112 -#define __QNXNTO__ 1
4.113 -#endif
4.114 -#if defined(riscos) || defined(__riscos) || defined(__riscos__)
4.115 -#undef __RISCOS__
4.116 -#define __RISCOS__ 1
4.117 -#endif
4.118 -#if defined(__SVR4)
4.119 -#undef __SOLARIS__
4.120 -#define __SOLARIS__ 1
4.121 -#endif
4.122 -
4.123 -#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
4.124 -/* Try to find out if we're compiling for WinRT or non-WinRT */
4.125 -#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */
4.126 -#include <winapifamily.h>
4.127 -#endif /* _MSC_VER >= 1700 */
4.128 -/* Default to classic, Win32/Win64/Desktop compilation either if:
4.129 - 1. the version of Windows is explicity set to a 'Desktop' (non-Metro) app
4.130 - 2. the version of Windows cannot be determined via winapifamily.h
4.131 - If neither is true, then see if we're compiling for WinRT.
4.132 - */
4.133 -#if ! defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
4.134 -#undef __WINDOWS__
4.135 -#define __WINDOWS__ 1
4.136 -/* See if we're compiling for WinRT: */
4.137 -#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
4.138 -#undef __WINRT__
4.139 -#define __WINRT__ 1
4.140 -#endif /* ! defined(WINAPI_FAMILY_PARTITION) */
4.141 -#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */
4.142 -
4.143 -#if defined(__WINDOWS__)
4.144 -#undef __WIN32__
4.145 -#define __WIN32__ 1
4.146 -#endif
4.147 -#if defined(__PSP__)
4.148 -#undef __PSP__
4.149 -#define __PSP__ 1
4.150 -#endif
4.151 -
4.152 -#include "begin_code.h"
4.153 -/* Set up for C function definitions, even when using C++ */
4.154 -#ifdef __cplusplus
4.155 -extern "C" {
4.156 -#endif
4.157 -
4.158 -/**
4.159 - * \brief Gets the name of the platform.
4.160 - */
4.161 -extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void);
4.162 -
4.163 -/* Ends C function definitions when using C++ */
4.164 -#ifdef __cplusplus
4.165 -}
4.166 -#endif
4.167 -#include "close_code.h"
4.168 -
4.169 -#endif /* _SDL_platform_h */
4.170 -
4.171 -/* vi: set ts=4 sw=4 expandtab: */
4.172 +/*
4.173 + Simple DirectMedia Layer
4.174 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4.175 +
4.176 + This software is provided 'as-is', without any express or implied
4.177 + warranty. In no event will the authors be held liable for any damages
4.178 + arising from the use of this software.
4.179 +
4.180 + Permission is granted to anyone to use this software for any purpose,
4.181 + including commercial applications, and to alter it and redistribute it
4.182 + freely, subject to the following restrictions:
4.183 +
4.184 + 1. The origin of this software must not be misrepresented; you must not
4.185 + claim that you wrote the original software. If you use this software
4.186 + in a product, an acknowledgment in the product documentation would be
4.187 + appreciated but is not required.
4.188 + 2. Altered source versions must be plainly marked as such, and must not be
4.189 + misrepresented as being the original software.
4.190 + 3. This notice may not be removed or altered from any source distribution.
4.191 +*/
4.192 +
4.193 +/**
4.194 + * \file SDL_platform.h
4.195 + *
4.196 + * Try to get a standard set of platform defines.
4.197 + */
4.198 +
4.199 +#ifndef _SDL_platform_h
4.200 +#define _SDL_platform_h
4.201 +
4.202 +#if defined(_AIX)
4.203 +#undef __AIX__
4.204 +#define __AIX__ 1
4.205 +#endif
4.206 +#if defined(__HAIKU__)
4.207 +#undef __HAIKU__
4.208 +#define __HAIKU__ 1
4.209 +#endif
4.210 +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
4.211 +#undef __BSDI__
4.212 +#define __BSDI__ 1
4.213 +#endif
4.214 +#if defined(_arch_dreamcast)
4.215 +#undef __DREAMCAST__
4.216 +#define __DREAMCAST__ 1
4.217 +#endif
4.218 +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
4.219 +#undef __FREEBSD__
4.220 +#define __FREEBSD__ 1
4.221 +#endif
4.222 +#if defined(hpux) || defined(__hpux) || defined(__hpux__)
4.223 +#undef __HPUX__
4.224 +#define __HPUX__ 1
4.225 +#endif
4.226 +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE)
4.227 +#undef __IRIX__
4.228 +#define __IRIX__ 1
4.229 +#endif
4.230 +#if defined(linux) || defined(__linux) || defined(__linux__)
4.231 +#undef __LINUX__
4.232 +#define __LINUX__ 1
4.233 +#endif
4.234 +#if defined(ANDROID)
4.235 +#undef __ANDROID__
4.236 +#undef __LINUX__ /* do we need to do this? */
4.237 +#define __ANDROID__ 1
4.238 +#endif
4.239 +
4.240 +#if defined(__APPLE__)
4.241 +/* lets us know what version of Mac OS X we're compiling on */
4.242 +#include "AvailabilityMacros.h"
4.243 +#include "TargetConditionals.h"
4.244 +#if TARGET_OS_IPHONE
4.245 +/* if compiling for iPhone */
4.246 +#undef __IPHONEOS__
4.247 +#define __IPHONEOS__ 1
4.248 +#undef __MACOSX__
4.249 +#else
4.250 +/* if not compiling for iPhone */
4.251 +#undef __MACOSX__
4.252 +#define __MACOSX__ 1
4.253 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
4.254 +# error SDL for Mac OS X only supports deploying on 10.5 and above.
4.255 +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */
4.256 +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
4.257 +# error SDL for Mac OS X must be built with a 10.6 SDK or above.
4.258 +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1060 */
4.259 +#endif /* TARGET_OS_IPHONE */
4.260 +#endif /* defined(__APPLE__) */
4.261 +
4.262 +#if defined(__NetBSD__)
4.263 +#undef __NETBSD__
4.264 +#define __NETBSD__ 1
4.265 +#endif
4.266 +#if defined(__OpenBSD__)
4.267 +#undef __OPENBSD__
4.268 +#define __OPENBSD__ 1
4.269 +#endif
4.270 +#if defined(__OS2__)
4.271 +#undef __OS2__
4.272 +#define __OS2__ 1
4.273 +#endif
4.274 +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE)
4.275 +#undef __OSF__
4.276 +#define __OSF__ 1
4.277 +#endif
4.278 +#if defined(__QNXNTO__)
4.279 +#undef __QNXNTO__
4.280 +#define __QNXNTO__ 1
4.281 +#endif
4.282 +#if defined(riscos) || defined(__riscos) || defined(__riscos__)
4.283 +#undef __RISCOS__
4.284 +#define __RISCOS__ 1
4.285 +#endif
4.286 +#if defined(__SVR4)
4.287 +#undef __SOLARIS__
4.288 +#define __SOLARIS__ 1
4.289 +#endif
4.290 +
4.291 +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
4.292 +/* Try to find out if we're compiling for WinRT or non-WinRT */
4.293 +#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */
4.294 +#include <winapifamily.h>
4.295 +#endif /* _MSC_VER >= 1700 */
4.296 +/* Default to classic, Win32/Win64/Desktop compilation either if:
4.297 + 1. the version of Windows is explicity set to a 'Desktop' (non-Metro) app
4.298 + 2. the version of Windows cannot be determined via winapifamily.h
4.299 + If neither is true, then see if we're compiling for WinRT.
4.300 + */
4.301 +#if ! defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
4.302 +#undef __WINDOWS__
4.303 +#define __WINDOWS__ 1
4.304 +/* See if we're compiling for WinRT: */
4.305 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
4.306 +#undef __WINRT__
4.307 +#define __WINRT__ 1
4.308 +#endif /* ! defined(WINAPI_FAMILY_PARTITION) */
4.309 +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */
4.310 +
4.311 +#if defined(__WINDOWS__)
4.312 +#undef __WIN32__
4.313 +#define __WIN32__ 1
4.314 +#endif
4.315 +#if defined(__PSP__)
4.316 +#undef __PSP__
4.317 +#define __PSP__ 1
4.318 +#endif
4.319 +
4.320 +#include "begin_code.h"
4.321 +/* Set up for C function definitions, even when using C++ */
4.322 +#ifdef __cplusplus
4.323 +extern "C" {
4.324 +#endif
4.325 +
4.326 +/**
4.327 + * \brief Gets the name of the platform.
4.328 + */
4.329 +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void);
4.330 +
4.331 +/* Ends C function definitions when using C++ */
4.332 +#ifdef __cplusplus
4.333 +}
4.334 +#endif
4.335 +#include "close_code.h"
4.336 +
4.337 +#endif /* _SDL_platform_h */
4.338 +
4.339 +/* vi: set ts=4 sw=4 expandtab: */
5.1 --- a/include/SDL_system.h Tue Mar 04 19:49:11 2014 -0500
5.2 +++ b/include/SDL_system.h Sun Mar 09 11:06:11 2014 -0700
5.3 @@ -1,185 +1,185 @@
5.4 -/*
5.5 - Simple DirectMedia Layer
5.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
5.7 -
5.8 - This software is provided 'as-is', without any express or implied
5.9 - warranty. In no event will the authors be held liable for any damages
5.10 - arising from the use of this software.
5.11 -
5.12 - Permission is granted to anyone to use this software for any purpose,
5.13 - including commercial applications, and to alter it and redistribute it
5.14 - freely, subject to the following restrictions:
5.15 -
5.16 - 1. The origin of this software must not be misrepresented; you must not
5.17 - claim that you wrote the original software. If you use this software
5.18 - in a product, an acknowledgment in the product documentation would be
5.19 - appreciated but is not required.
5.20 - 2. Altered source versions must be plainly marked as such, and must not be
5.21 - misrepresented as being the original software.
5.22 - 3. This notice may not be removed or altered from any source distribution.
5.23 -*/
5.24 -
5.25 -/**
5.26 - * \file SDL_system.h
5.27 - *
5.28 - * Include file for platform specific SDL API functions
5.29 - */
5.30 -
5.31 -#ifndef _SDL_system_h
5.32 -#define _SDL_system_h
5.33 -
5.34 -#include "SDL_stdinc.h"
5.35 -#include "SDL_keyboard.h"
5.36 -#include "SDL_render.h"
5.37 -#include "SDL_video.h"
5.38 -
5.39 -#include "begin_code.h"
5.40 -/* Set up for C function definitions, even when using C++ */
5.41 -#ifdef __cplusplus
5.42 -extern "C" {
5.43 -#endif
5.44 -
5.45 -
5.46 -/* Platform specific functions for Windows */
5.47 -#ifdef __WIN32__
5.48 -
5.49 -/* Returns the D3D9 adapter index that matches the specified display index.
5.50 - This adapter index can be passed to IDirect3D9::CreateDevice and controls
5.51 - on which monitor a full screen application will appear.
5.52 -*/
5.53 -extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
5.54 -
5.55 -/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
5.56 - Once you are done using the device, you should release it to avoid a resource leak.
5.57 - */
5.58 -typedef struct IDirect3DDevice9 IDirect3DDevice9;
5.59 -extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer);
5.60 -
5.61 -#endif /* __WIN32__ */
5.62 -
5.63 -
5.64 -/* Platform specific functions for iOS */
5.65 -#if defined(__IPHONEOS__) && __IPHONEOS__
5.66 -
5.67 -extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
5.68 -extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
5.69 -
5.70 -#endif /* __IPHONEOS__ */
5.71 -
5.72 -
5.73 -/* Platform specific functions for Android */
5.74 -#if defined(__ANDROID__) && __ANDROID__
5.75 -
5.76 -/* Get the JNI environment for the current thread
5.77 - This returns JNIEnv*, but the prototype is void* so we don't need jni.h
5.78 - */
5.79 -extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
5.80 -
5.81 -/* Get the SDL Activity object for the application
5.82 - This returns jobject, but the prototype is void* so we don't need jni.h
5.83 - The jobject returned by SDL_AndroidGetActivity is a local reference.
5.84 - It is the caller's responsibility to properly release it
5.85 - (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef)
5.86 - */
5.87 -extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity();
5.88 -
5.89 -/* See the official Android developer guide for more information:
5.90 - http://developer.android.com/guide/topics/data/data-storage.html
5.91 -*/
5.92 -#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01
5.93 -#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02
5.94 -
5.95 -/* Get the path used for internal storage for this application.
5.96 - This path is unique to your application and cannot be written to
5.97 - by other applications.
5.98 - */
5.99 -extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath();
5.100 -
5.101 -/* Get the current state of external storage, a bitmask of these values:
5.102 - SDL_ANDROID_EXTERNAL_STORAGE_READ
5.103 - SDL_ANDROID_EXTERNAL_STORAGE_WRITE
5.104 - If external storage is currently unavailable, this will return 0.
5.105 -*/
5.106 -extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState();
5.107 -
5.108 -/* Get the path used for external storage for this application.
5.109 - This path is unique to your application, but is public and can be
5.110 - written to by other applications.
5.111 - */
5.112 -extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
5.113 -
5.114 -#endif /* __ANDROID__ */
5.115 -
5.116 -/* Platform specific functions for WinRT */
5.117 -#if defined(__WINRT__) && __WINRT__
5.118 -
5.119 -/**
5.120 - * \brief WinRT / Windows Phone path types
5.121 - */
5.122 -typedef enum
5.123 -{
5.124 - /** \brief The installed app's root directory.
5.125 - Files here are likely to be read-only. */
5.126 - SDL_WINRT_PATH_INSTALLED_LOCATION,
5.127 -
5.128 - /** \brief The app's local data store. Files may be written here */
5.129 - SDL_WINRT_PATH_LOCAL_FOLDER,
5.130 -
5.131 - /** \brief The app's roaming data store. Unsupported on Windows Phone.
5.132 - Files written here may be copied to other machines via a network
5.133 - connection.
5.134 - */
5.135 - SDL_WINRT_PATH_ROAMING_FOLDER,
5.136 -
5.137 - /** \brief The app's temporary data store. Unsupported on Windows Phone.
5.138 - Files written here may be deleted at any time. */
5.139 - SDL_WINRT_PATH_TEMP_FOLDER
5.140 -} SDL_WinRT_Path;
5.141 -
5.142 -
5.143 -/**
5.144 - * \brief Retrieves a WinRT defined path on the local file system
5.145 - *
5.146 - * \note Documentation on most app-specific path types on WinRT
5.147 - * can be found on MSDN, at the URL:
5.148 - * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
5.149 - *
5.150 - * \param pathType The type of path to retrieve.
5.151 - * \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL
5.152 - * if the path is not available for any reason. Not all paths are
5.153 - * available on all versions of Windows. This is especially true on
5.154 - * Windows Phone. Check the documentation for the given
5.155 - * SDL_WinRT_Path for more information on which path types are
5.156 - * supported where.
5.157 - */
5.158 -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType);
5.159 -
5.160 -/**
5.161 - * \brief Retrieves a WinRT defined path on the local file system
5.162 - *
5.163 - * \note Documentation on most app-specific path types on WinRT
5.164 - * can be found on MSDN, at the URL:
5.165 - * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
5.166 - *
5.167 - * \param pathType The type of path to retrieve.
5.168 - * \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL
5.169 - * if the path is not available for any reason. Not all paths are
5.170 - * available on all versions of Windows. This is especially true on
5.171 - * Windows Phone. Check the documentation for the given
5.172 - * SDL_WinRT_Path for more information on which path types are
5.173 - * supported where.
5.174 - */
5.175 -extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
5.176 -
5.177 -#endif /* __WINRT__ */
5.178 -
5.179 -
5.180 -/* Ends C function definitions when using C++ */
5.181 -#ifdef __cplusplus
5.182 -}
5.183 -#endif
5.184 -#include "close_code.h"
5.185 -
5.186 -#endif /* _SDL_system_h */
5.187 -
5.188 -/* vi: set ts=4 sw=4 expandtab: */
5.189 +/*
5.190 + Simple DirectMedia Layer
5.191 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
5.192 +
5.193 + This software is provided 'as-is', without any express or implied
5.194 + warranty. In no event will the authors be held liable for any damages
5.195 + arising from the use of this software.
5.196 +
5.197 + Permission is granted to anyone to use this software for any purpose,
5.198 + including commercial applications, and to alter it and redistribute it
5.199 + freely, subject to the following restrictions:
5.200 +
5.201 + 1. The origin of this software must not be misrepresented; you must not
5.202 + claim that you wrote the original software. If you use this software
5.203 + in a product, an acknowledgment in the product documentation would be
5.204 + appreciated but is not required.
5.205 + 2. Altered source versions must be plainly marked as such, and must not be
5.206 + misrepresented as being the original software.
5.207 + 3. This notice may not be removed or altered from any source distribution.
5.208 +*/
5.209 +
5.210 +/**
5.211 + * \file SDL_system.h
5.212 + *
5.213 + * Include file for platform specific SDL API functions
5.214 + */
5.215 +
5.216 +#ifndef _SDL_system_h
5.217 +#define _SDL_system_h
5.218 +
5.219 +#include "SDL_stdinc.h"
5.220 +#include "SDL_keyboard.h"
5.221 +#include "SDL_render.h"
5.222 +#include "SDL_video.h"
5.223 +
5.224 +#include "begin_code.h"
5.225 +/* Set up for C function definitions, even when using C++ */
5.226 +#ifdef __cplusplus
5.227 +extern "C" {
5.228 +#endif
5.229 +
5.230 +
5.231 +/* Platform specific functions for Windows */
5.232 +#ifdef __WIN32__
5.233 +
5.234 +/* Returns the D3D9 adapter index that matches the specified display index.
5.235 + This adapter index can be passed to IDirect3D9::CreateDevice and controls
5.236 + on which monitor a full screen application will appear.
5.237 +*/
5.238 +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
5.239 +
5.240 +/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
5.241 + Once you are done using the device, you should release it to avoid a resource leak.
5.242 + */
5.243 +typedef struct IDirect3DDevice9 IDirect3DDevice9;
5.244 +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer);
5.245 +
5.246 +#endif /* __WIN32__ */
5.247 +
5.248 +
5.249 +/* Platform specific functions for iOS */
5.250 +#if defined(__IPHONEOS__) && __IPHONEOS__
5.251 +
5.252 +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
5.253 +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
5.254 +
5.255 +#endif /* __IPHONEOS__ */
5.256 +
5.257 +
5.258 +/* Platform specific functions for Android */
5.259 +#if defined(__ANDROID__) && __ANDROID__
5.260 +
5.261 +/* Get the JNI environment for the current thread
5.262 + This returns JNIEnv*, but the prototype is void* so we don't need jni.h
5.263 + */
5.264 +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
5.265 +
5.266 +/* Get the SDL Activity object for the application
5.267 + This returns jobject, but the prototype is void* so we don't need jni.h
5.268 + The jobject returned by SDL_AndroidGetActivity is a local reference.
5.269 + It is the caller's responsibility to properly release it
5.270 + (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef)
5.271 + */
5.272 +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity();
5.273 +
5.274 +/* See the official Android developer guide for more information:
5.275 + http://developer.android.com/guide/topics/data/data-storage.html
5.276 +*/
5.277 +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01
5.278 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02
5.279 +
5.280 +/* Get the path used for internal storage for this application.
5.281 + This path is unique to your application and cannot be written to
5.282 + by other applications.
5.283 + */
5.284 +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath();
5.285 +
5.286 +/* Get the current state of external storage, a bitmask of these values:
5.287 + SDL_ANDROID_EXTERNAL_STORAGE_READ
5.288 + SDL_ANDROID_EXTERNAL_STORAGE_WRITE
5.289 + If external storage is currently unavailable, this will return 0.
5.290 +*/
5.291 +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState();
5.292 +
5.293 +/* Get the path used for external storage for this application.
5.294 + This path is unique to your application, but is public and can be
5.295 + written to by other applications.
5.296 + */
5.297 +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
5.298 +
5.299 +#endif /* __ANDROID__ */
5.300 +
5.301 +/* Platform specific functions for WinRT */
5.302 +#if defined(__WINRT__) && __WINRT__
5.303 +
5.304 +/**
5.305 + * \brief WinRT / Windows Phone path types
5.306 + */
5.307 +typedef enum
5.308 +{
5.309 + /** \brief The installed app's root directory.
5.310 + Files here are likely to be read-only. */
5.311 + SDL_WINRT_PATH_INSTALLED_LOCATION,
5.312 +
5.313 + /** \brief The app's local data store. Files may be written here */
5.314 + SDL_WINRT_PATH_LOCAL_FOLDER,
5.315 +
5.316 + /** \brief The app's roaming data store. Unsupported on Windows Phone.
5.317 + Files written here may be copied to other machines via a network
5.318 + connection.
5.319 + */
5.320 + SDL_WINRT_PATH_ROAMING_FOLDER,
5.321 +
5.322 + /** \brief The app's temporary data store. Unsupported on Windows Phone.
5.323 + Files written here may be deleted at any time. */
5.324 + SDL_WINRT_PATH_TEMP_FOLDER
5.325 +} SDL_WinRT_Path;
5.326 +
5.327 +
5.328 +/**
5.329 + * \brief Retrieves a WinRT defined path on the local file system
5.330 + *
5.331 + * \note Documentation on most app-specific path types on WinRT
5.332 + * can be found on MSDN, at the URL:
5.333 + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
5.334 + *
5.335 + * \param pathType The type of path to retrieve.
5.336 + * \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL
5.337 + * if the path is not available for any reason. Not all paths are
5.338 + * available on all versions of Windows. This is especially true on
5.339 + * Windows Phone. Check the documentation for the given
5.340 + * SDL_WinRT_Path for more information on which path types are
5.341 + * supported where.
5.342 + */
5.343 +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType);
5.344 +
5.345 +/**
5.346 + * \brief Retrieves a WinRT defined path on the local file system
5.347 + *
5.348 + * \note Documentation on most app-specific path types on WinRT
5.349 + * can be found on MSDN, at the URL:
5.350 + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
5.351 + *
5.352 + * \param pathType The type of path to retrieve.
5.353 + * \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL
5.354 + * if the path is not available for any reason. Not all paths are
5.355 + * available on all versions of Windows. This is especially true on
5.356 + * Windows Phone. Check the documentation for the given
5.357 + * SDL_WinRT_Path for more information on which path types are
5.358 + * supported where.
5.359 + */
5.360 +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
5.361 +
5.362 +#endif /* __WINRT__ */
5.363 +
5.364 +
5.365 +/* Ends C function definitions when using C++ */
5.366 +#ifdef __cplusplus
5.367 +}
5.368 +#endif
5.369 +#include "close_code.h"
5.370 +
5.371 +#endif /* _SDL_system_h */
5.372 +
5.373 +/* vi: set ts=4 sw=4 expandtab: */
6.1 --- a/include/begin_code.h Tue Mar 04 19:49:11 2014 -0500
6.2 +++ b/include/begin_code.h Sun Mar 09 11:06:11 2014 -0700
6.3 @@ -1,140 +1,140 @@
6.4 -/*
6.5 - Simple DirectMedia Layer
6.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
6.7 -
6.8 - This software is provided 'as-is', without any express or implied
6.9 - warranty. In no event will the authors be held liable for any damages
6.10 - arising from the use of this software.
6.11 -
6.12 - Permission is granted to anyone to use this software for any purpose,
6.13 - including commercial applications, and to alter it and redistribute it
6.14 - freely, subject to the following restrictions:
6.15 -
6.16 - 1. The origin of this software must not be misrepresented; you must not
6.17 - claim that you wrote the original software. If you use this software
6.18 - in a product, an acknowledgment in the product documentation would be
6.19 - appreciated but is not required.
6.20 - 2. Altered source versions must be plainly marked as such, and must not be
6.21 - misrepresented as being the original software.
6.22 - 3. This notice may not be removed or altered from any source distribution.
6.23 -*/
6.24 -
6.25 -/**
6.26 - * \file begin_code.h
6.27 - *
6.28 - * This file sets things up for C dynamic library function definitions,
6.29 - * static inlined functions, and structures aligned at 4-byte alignment.
6.30 - * If you don't like ugly C preprocessor code, don't look at this file. :)
6.31 - */
6.32 -
6.33 -/* This shouldn't be nested -- included it around code only. */
6.34 -#ifdef _begin_code_h
6.35 -#error Nested inclusion of begin_code.h
6.36 -#endif
6.37 -#define _begin_code_h
6.38 -
6.39 -#ifndef SDL_DEPRECATED
6.40 -# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
6.41 -# define SDL_DEPRECATED __attribute__((deprecated))
6.42 -# else
6.43 -# define SDL_DEPRECATED
6.44 -# endif
6.45 -#endif
6.46 -
6.47 -/* Some compilers use a special export keyword */
6.48 -#ifndef DECLSPEC
6.49 -# if defined(__WIN32__) || defined(__WINRT__)
6.50 -# ifdef __BORLANDC__
6.51 -# ifdef BUILD_SDL
6.52 -# define DECLSPEC
6.53 -# else
6.54 -# define DECLSPEC __declspec(dllimport)
6.55 -# endif
6.56 -# else
6.57 -# define DECLSPEC __declspec(dllexport)
6.58 -# endif
6.59 -# else
6.60 -# if defined(__GNUC__) && __GNUC__ >= 4
6.61 -# define DECLSPEC __attribute__ ((visibility("default")))
6.62 -# elif defined(__GNUC__) && __GNUC__ >= 2
6.63 -# define DECLSPEC __declspec(dllexport)
6.64 -# else
6.65 -# define DECLSPEC
6.66 -# endif
6.67 -# endif
6.68 -#endif
6.69 -
6.70 -/* By default SDL uses the C calling convention */
6.71 -#ifndef SDLCALL
6.72 -#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
6.73 -#define SDLCALL __cdecl
6.74 -#else
6.75 -#define SDLCALL
6.76 -#endif
6.77 -#endif /* SDLCALL */
6.78 -
6.79 -/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
6.80 -#ifdef __SYMBIAN32__
6.81 -#undef DECLSPEC
6.82 -#define DECLSPEC
6.83 -#endif /* __SYMBIAN32__ */
6.84 -
6.85 -/* Force structure packing at 4 byte alignment.
6.86 - This is necessary if the header is included in code which has structure
6.87 - packing set to an alternate value, say for loading structures from disk.
6.88 - The packing is reset to the previous value in close_code.h
6.89 - */
6.90 -#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
6.91 -#ifdef _MSC_VER
6.92 -#pragma warning(disable: 4103)
6.93 -#endif
6.94 -#ifdef __BORLANDC__
6.95 -#pragma nopackwarning
6.96 -#endif
6.97 -#ifdef _M_X64
6.98 -/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
6.99 -#pragma pack(push,8)
6.100 -#else
6.101 -#pragma pack(push,4)
6.102 -#endif
6.103 -#endif /* Compiler needs structure packing set */
6.104 -
6.105 -#ifndef SDL_INLINE
6.106 -#if defined(__GNUC__)
6.107 -#define SDL_INLINE __inline__
6.108 -#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
6.109 - defined(__DMC__) || defined(__SC__) || \
6.110 - defined(__WATCOMC__) || defined(__LCC__) || \
6.111 - defined(__DECC)
6.112 -#define SDL_INLINE __inline
6.113 -#ifndef __inline__
6.114 -#define __inline__ __inline
6.115 -#endif
6.116 -#else
6.117 -#define SDL_INLINE inline
6.118 -#ifndef __inline__
6.119 -#define __inline__ inline
6.120 -#endif
6.121 -#endif
6.122 -#endif /* SDL_INLINE not defined */
6.123 -
6.124 -#ifndef SDL_FORCE_INLINE
6.125 -#if defined(_MSC_VER)
6.126 -#define SDL_FORCE_INLINE __forceinline
6.127 -#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
6.128 -#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
6.129 -#else
6.130 -#define SDL_FORCE_INLINE static SDL_INLINE
6.131 -#endif
6.132 -#endif /* SDL_FORCE_INLINE not defined */
6.133 -
6.134 -/* Apparently this is needed by several Windows compilers */
6.135 -#if !defined(__MACH__)
6.136 -#ifndef NULL
6.137 -#ifdef __cplusplus
6.138 -#define NULL 0
6.139 -#else
6.140 -#define NULL ((void *)0)
6.141 -#endif
6.142 -#endif /* NULL */
6.143 -#endif /* ! Mac OS X - breaks precompiled headers */
6.144 +/*
6.145 + Simple DirectMedia Layer
6.146 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
6.147 +
6.148 + This software is provided 'as-is', without any express or implied
6.149 + warranty. In no event will the authors be held liable for any damages
6.150 + arising from the use of this software.
6.151 +
6.152 + Permission is granted to anyone to use this software for any purpose,
6.153 + including commercial applications, and to alter it and redistribute it
6.154 + freely, subject to the following restrictions:
6.155 +
6.156 + 1. The origin of this software must not be misrepresented; you must not
6.157 + claim that you wrote the original software. If you use this software
6.158 + in a product, an acknowledgment in the product documentation would be
6.159 + appreciated but is not required.
6.160 + 2. Altered source versions must be plainly marked as such, and must not be
6.161 + misrepresented as being the original software.
6.162 + 3. This notice may not be removed or altered from any source distribution.
6.163 +*/
6.164 +
6.165 +/**
6.166 + * \file begin_code.h
6.167 + *
6.168 + * This file sets things up for C dynamic library function definitions,
6.169 + * static inlined functions, and structures aligned at 4-byte alignment.
6.170 + * If you don't like ugly C preprocessor code, don't look at this file. :)
6.171 + */
6.172 +
6.173 +/* This shouldn't be nested -- included it around code only. */
6.174 +#ifdef _begin_code_h
6.175 +#error Nested inclusion of begin_code.h
6.176 +#endif
6.177 +#define _begin_code_h
6.178 +
6.179 +#ifndef SDL_DEPRECATED
6.180 +# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
6.181 +# define SDL_DEPRECATED __attribute__((deprecated))
6.182 +# else
6.183 +# define SDL_DEPRECATED
6.184 +# endif
6.185 +#endif
6.186 +
6.187 +/* Some compilers use a special export keyword */
6.188 +#ifndef DECLSPEC
6.189 +# if defined(__WIN32__) || defined(__WINRT__)
6.190 +# ifdef __BORLANDC__
6.191 +# ifdef BUILD_SDL
6.192 +# define DECLSPEC
6.193 +# else
6.194 +# define DECLSPEC __declspec(dllimport)
6.195 +# endif
6.196 +# else
6.197 +# define DECLSPEC __declspec(dllexport)
6.198 +# endif
6.199 +# else
6.200 +# if defined(__GNUC__) && __GNUC__ >= 4
6.201 +# define DECLSPEC __attribute__ ((visibility("default")))
6.202 +# elif defined(__GNUC__) && __GNUC__ >= 2
6.203 +# define DECLSPEC __declspec(dllexport)
6.204 +# else
6.205 +# define DECLSPEC
6.206 +# endif
6.207 +# endif
6.208 +#endif
6.209 +
6.210 +/* By default SDL uses the C calling convention */
6.211 +#ifndef SDLCALL
6.212 +#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
6.213 +#define SDLCALL __cdecl
6.214 +#else
6.215 +#define SDLCALL
6.216 +#endif
6.217 +#endif /* SDLCALL */
6.218 +
6.219 +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
6.220 +#ifdef __SYMBIAN32__
6.221 +#undef DECLSPEC
6.222 +#define DECLSPEC
6.223 +#endif /* __SYMBIAN32__ */
6.224 +
6.225 +/* Force structure packing at 4 byte alignment.
6.226 + This is necessary if the header is included in code which has structure
6.227 + packing set to an alternate value, say for loading structures from disk.
6.228 + The packing is reset to the previous value in close_code.h
6.229 + */
6.230 +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
6.231 +#ifdef _MSC_VER
6.232 +#pragma warning(disable: 4103)
6.233 +#endif
6.234 +#ifdef __BORLANDC__
6.235 +#pragma nopackwarning
6.236 +#endif
6.237 +#ifdef _M_X64
6.238 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
6.239 +#pragma pack(push,8)
6.240 +#else
6.241 +#pragma pack(push,4)
6.242 +#endif
6.243 +#endif /* Compiler needs structure packing set */
6.244 +
6.245 +#ifndef SDL_INLINE
6.246 +#if defined(__GNUC__)
6.247 +#define SDL_INLINE __inline__
6.248 +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
6.249 + defined(__DMC__) || defined(__SC__) || \
6.250 + defined(__WATCOMC__) || defined(__LCC__) || \
6.251 + defined(__DECC)
6.252 +#define SDL_INLINE __inline
6.253 +#ifndef __inline__
6.254 +#define __inline__ __inline
6.255 +#endif
6.256 +#else
6.257 +#define SDL_INLINE inline
6.258 +#ifndef __inline__
6.259 +#define __inline__ inline
6.260 +#endif
6.261 +#endif
6.262 +#endif /* SDL_INLINE not defined */
6.263 +
6.264 +#ifndef SDL_FORCE_INLINE
6.265 +#if defined(_MSC_VER)
6.266 +#define SDL_FORCE_INLINE __forceinline
6.267 +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
6.268 +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
6.269 +#else
6.270 +#define SDL_FORCE_INLINE static SDL_INLINE
6.271 +#endif
6.272 +#endif /* SDL_FORCE_INLINE not defined */
6.273 +
6.274 +/* Apparently this is needed by several Windows compilers */
6.275 +#if !defined(__MACH__)
6.276 +#ifndef NULL
6.277 +#ifdef __cplusplus
6.278 +#define NULL 0
6.279 +#else
6.280 +#define NULL ((void *)0)
6.281 +#endif
6.282 +#endif /* NULL */
6.283 +#endif /* ! Mac OS X - breaks precompiled headers */
7.1 --- a/src/SDL_log.c Tue Mar 04 19:49:11 2014 -0500
7.2 +++ b/src/SDL_log.c Sun Mar 09 11:06:11 2014 -0700
7.3 @@ -1,439 +1,439 @@
7.4 -/*
7.5 - Simple DirectMedia Layer
7.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
7.7 -
7.8 - This software is provided 'as-is', without any express or implied
7.9 - warranty. In no event will the authors be held liable for any damages
7.10 - arising from the use of this software.
7.11 -
7.12 - Permission is granted to anyone to use this software for any purpose,
7.13 - including commercial applications, and to alter it and redistribute it
7.14 - freely, subject to the following restrictions:
7.15 -
7.16 - 1. The origin of this software must not be misrepresented; you must not
7.17 - claim that you wrote the original software. If you use this software
7.18 - in a product, an acknowledgment in the product documentation would be
7.19 - appreciated but is not required.
7.20 - 2. Altered source versions must be plainly marked as such, and must not be
7.21 - misrepresented as being the original software.
7.22 - 3. This notice may not be removed or altered from any source distribution.
7.23 -*/
7.24 -#include "SDL_config.h"
7.25 -
7.26 -#if defined(__WIN32__) || defined(__WINRT__)
7.27 -#include "core/windows/SDL_windows.h"
7.28 -#endif
7.29 -
7.30 -/* Simple log messages in SDL */
7.31 -
7.32 -#include "SDL_log.h"
7.33 -
7.34 -#if HAVE_STDIO_H
7.35 -#include <stdio.h>
7.36 -#endif
7.37 -
7.38 -#if defined(__ANDROID__)
7.39 -#include <android/log.h>
7.40 -#endif
7.41 -
7.42 -#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
7.43 -#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
7.44 -#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
7.45 -#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE
7.46 -
7.47 -/* Forward definition of error function */
7.48 -extern int SDL_SetError(const char *fmt, ...);
7.49 -
7.50 -typedef struct SDL_LogLevel
7.51 -{
7.52 - int category;
7.53 - SDL_LogPriority priority;
7.54 - struct SDL_LogLevel *next;
7.55 -} SDL_LogLevel;
7.56 -
7.57 -/* The default log output function */
7.58 -static void SDL_LogOutput(void *userdata,
7.59 - int category, SDL_LogPriority priority,
7.60 - const char *message);
7.61 -
7.62 -static SDL_LogLevel *SDL_loglevels;
7.63 -static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
7.64 -static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
7.65 -static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
7.66 -static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
7.67 -static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
7.68 -static void *SDL_log_userdata = NULL;
7.69 -
7.70 -static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
7.71 - NULL,
7.72 - "VERBOSE",
7.73 - "DEBUG",
7.74 - "INFO",
7.75 - "WARN",
7.76 - "ERROR",
7.77 - "CRITICAL"
7.78 -};
7.79 -
7.80 -#ifdef __ANDROID__
7.81 -static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = {
7.82 - "APP",
7.83 - "ERROR",
7.84 - "SYSTEM",
7.85 - "AUDIO",
7.86 - "VIDEO",
7.87 - "RENDER",
7.88 - "INPUT"
7.89 -};
7.90 -
7.91 -static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
7.92 - ANDROID_LOG_UNKNOWN,
7.93 - ANDROID_LOG_VERBOSE,
7.94 - ANDROID_LOG_DEBUG,
7.95 - ANDROID_LOG_INFO,
7.96 - ANDROID_LOG_WARN,
7.97 - ANDROID_LOG_ERROR,
7.98 - ANDROID_LOG_FATAL
7.99 -};
7.100 -#endif /* __ANDROID__ */
7.101 -
7.102 -
7.103 -void
7.104 -SDL_LogSetAllPriority(SDL_LogPriority priority)
7.105 -{
7.106 - SDL_LogLevel *entry;
7.107 -
7.108 - for (entry = SDL_loglevels; entry; entry = entry->next) {
7.109 - entry->priority = priority;
7.110 - }
7.111 - SDL_default_priority = priority;
7.112 - SDL_assert_priority = priority;
7.113 - SDL_application_priority = priority;
7.114 -}
7.115 -
7.116 -void
7.117 -SDL_LogSetPriority(int category, SDL_LogPriority priority)
7.118 -{
7.119 - SDL_LogLevel *entry;
7.120 -
7.121 - for (entry = SDL_loglevels; entry; entry = entry->next) {
7.122 - if (entry->category == category) {
7.123 - entry->priority = priority;
7.124 - return;
7.125 - }
7.126 - }
7.127 -
7.128 - /* Create a new entry */
7.129 - entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry));
7.130 - if (entry) {
7.131 - entry->category = category;
7.132 - entry->priority = priority;
7.133 - entry->next = SDL_loglevels;
7.134 - SDL_loglevels = entry;
7.135 - }
7.136 -}
7.137 -
7.138 -SDL_LogPriority
7.139 -SDL_LogGetPriority(int category)
7.140 -{
7.141 - SDL_LogLevel *entry;
7.142 -
7.143 - for (entry = SDL_loglevels; entry; entry = entry->next) {
7.144 - if (entry->category == category) {
7.145 - return entry->priority;
7.146 - }
7.147 - }
7.148 -
7.149 - if (category == SDL_LOG_CATEGORY_TEST) {
7.150 - return SDL_test_priority;
7.151 - } else if (category == SDL_LOG_CATEGORY_APPLICATION) {
7.152 - return SDL_application_priority;
7.153 - } else if (category == SDL_LOG_CATEGORY_ASSERT) {
7.154 - return SDL_assert_priority;
7.155 - } else {
7.156 - return SDL_default_priority;
7.157 - }
7.158 -}
7.159 -
7.160 -void
7.161 -SDL_LogResetPriorities(void)
7.162 -{
7.163 - SDL_LogLevel *entry;
7.164 -
7.165 - while (SDL_loglevels) {
7.166 - entry = SDL_loglevels;
7.167 - SDL_loglevels = entry->next;
7.168 - SDL_free(entry);
7.169 - }
7.170 -
7.171 - SDL_default_priority = DEFAULT_PRIORITY;
7.172 - SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
7.173 - SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
7.174 - SDL_test_priority = DEFAULT_TEST_PRIORITY;
7.175 -}
7.176 -
7.177 -void
7.178 -SDL_Log(const char *fmt, ...)
7.179 -{
7.180 - va_list ap;
7.181 -
7.182 - va_start(ap, fmt);
7.183 - SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap);
7.184 - va_end(ap);
7.185 -}
7.186 -
7.187 -void
7.188 -SDL_LogVerbose(int category, const char *fmt, ...)
7.189 -{
7.190 - va_list ap;
7.191 -
7.192 - va_start(ap, fmt);
7.193 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap);
7.194 - va_end(ap);
7.195 -}
7.196 -
7.197 -void
7.198 -SDL_LogDebug(int category, const char *fmt, ...)
7.199 -{
7.200 - va_list ap;
7.201 -
7.202 - va_start(ap, fmt);
7.203 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap);
7.204 - va_end(ap);
7.205 -}
7.206 -
7.207 -void
7.208 -SDL_LogInfo(int category, const char *fmt, ...)
7.209 -{
7.210 - va_list ap;
7.211 -
7.212 - va_start(ap, fmt);
7.213 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap);
7.214 - va_end(ap);
7.215 -}
7.216 -
7.217 -void
7.218 -SDL_LogWarn(int category, const char *fmt, ...)
7.219 -{
7.220 - va_list ap;
7.221 -
7.222 - va_start(ap, fmt);
7.223 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap);
7.224 - va_end(ap);
7.225 -}
7.226 -
7.227 -void
7.228 -SDL_LogError(int category, const char *fmt, ...)
7.229 -{
7.230 - va_list ap;
7.231 -
7.232 - va_start(ap, fmt);
7.233 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap);
7.234 - va_end(ap);
7.235 -}
7.236 -
7.237 -void
7.238 -SDL_LogCritical(int category, const char *fmt, ...)
7.239 -{
7.240 - va_list ap;
7.241 -
7.242 - va_start(ap, fmt);
7.243 - SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap);
7.244 - va_end(ap);
7.245 -}
7.246 -
7.247 -void
7.248 -SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...)
7.249 -{
7.250 - va_list ap;
7.251 -
7.252 - va_start(ap, fmt);
7.253 - SDL_LogMessageV(category, priority, fmt, ap);
7.254 - va_end(ap);
7.255 -}
7.256 -
7.257 -#ifdef __ANDROID__
7.258 -static const char *
7.259 -GetCategoryPrefix(int category)
7.260 -{
7.261 - if (category < SDL_LOG_CATEGORY_RESERVED1) {
7.262 - return SDL_category_prefixes[category];
7.263 - }
7.264 - if (category < SDL_LOG_CATEGORY_CUSTOM) {
7.265 - return "RESERVED";
7.266 - }
7.267 - return "CUSTOM";
7.268 -}
7.269 -#endif /* __ANDROID__ */
7.270 -
7.271 -void
7.272 -SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
7.273 -{
7.274 - char *message;
7.275 - size_t len;
7.276 -
7.277 - /* Nothing to do if we don't have an output function */
7.278 - if (!SDL_log_function) {
7.279 - return;
7.280 - }
7.281 -
7.282 - /* Make sure we don't exceed array bounds */
7.283 - if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) {
7.284 - return;
7.285 - }
7.286 -
7.287 - /* See if we want to do anything with this message */
7.288 - if (priority < SDL_LogGetPriority(category)) {
7.289 - return;
7.290 - }
7.291 -
7.292 - message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
7.293 - if (!message) {
7.294 - return;
7.295 - }
7.296 -
7.297 - SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
7.298 -
7.299 - /* Chop off final endline. */
7.300 - len = SDL_strlen(message);
7.301 - if ((len > 0) && (message[len-1] == '\n')) {
7.302 - message[--len] = '\0';
7.303 - if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */
7.304 - message[--len] = '\0';
7.305 - }
7.306 - }
7.307 -
7.308 - SDL_log_function(SDL_log_userdata, category, priority, message);
7.309 - SDL_stack_free(message);
7.310 -}
7.311 -
7.312 -#if defined(__WIN32__)
7.313 -/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */
7.314 -static int consoleAttached = 0;
7.315 -
7.316 -/* Handle to stderr output of console. */
7.317 -static HANDLE stderrHandle = NULL;
7.318 -#endif
7.319 -
7.320 -static void
7.321 -SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
7.322 - const char *message)
7.323 -{
7.324 -#if defined(__WIN32__) || defined(__WINRT__)
7.325 - /* Way too many allocations here, urgh */
7.326 - /* Note: One can't call SDL_SetError here, since that function itself logs. */
7.327 - {
7.328 - char *output;
7.329 - size_t length;
7.330 - LPTSTR tstr;
7.331 -
7.332 -#ifndef __WINRT__
7.333 - BOOL attachResult;
7.334 - DWORD attachError;
7.335 - unsigned long charsWritten;
7.336 -
7.337 - /* Maybe attach console and get stderr handle */
7.338 - if (consoleAttached == 0) {
7.339 - attachResult = AttachConsole(ATTACH_PARENT_PROCESS);
7.340 - if (!attachResult) {
7.341 - attachError = GetLastError();
7.342 - if (attachError == ERROR_INVALID_HANDLE) {
7.343 - OutputDebugString(TEXT("Parent process has no console\r\n"));
7.344 - consoleAttached = -1;
7.345 - } else if (attachError == ERROR_GEN_FAILURE) {
7.346 - OutputDebugString(TEXT("Could not attach to console of parent process\r\n"));
7.347 - consoleAttached = -1;
7.348 - } else if (attachError == ERROR_ACCESS_DENIED) {
7.349 - /* Already attached */
7.350 - consoleAttached = 1;
7.351 - } else {
7.352 - OutputDebugString(TEXT("Error attaching console\r\n"));
7.353 - consoleAttached = -1;
7.354 - }
7.355 - } else {
7.356 - /* Newly attached */
7.357 - consoleAttached = 1;
7.358 - }
7.359 -
7.360 - if (consoleAttached == 1) {
7.361 - stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
7.362 - }
7.363 - }
7.364 -#endif /* ifndef __WINRT__ */
7.365 -
7.366 - length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
7.367 - output = SDL_stack_alloc(char, length);
7.368 - SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message);
7.369 - tstr = WIN_UTF8ToString(output);
7.370 -
7.371 - /* Output to debugger */
7.372 - OutputDebugString(tstr);
7.373 -
7.374 -#ifndef __WINRT__
7.375 - /* Screen output to stderr, if console was attached. */
7.376 - if (consoleAttached == 1) {
7.377 - if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
7.378 - OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
7.379 - }
7.380 - if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) {
7.381 - OutputDebugString(TEXT("Insufficient heap memory to write message\r\n"));
7.382 - }
7.383 - }
7.384 -#endif /* ifndef __WINRT__ */
7.385 -
7.386 - SDL_free(tstr);
7.387 - SDL_stack_free(output);
7.388 - }
7.389 -#elif defined(__ANDROID__)
7.390 - {
7.391 - char tag[32];
7.392 -
7.393 - SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
7.394 - __android_log_write(SDL_android_priority[priority], tag, message);
7.395 - }
7.396 -#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
7.397 - /* Technically we don't need SDL_VIDEO_DRIVER_COCOA, but that's where this function is defined for now.
7.398 - */
7.399 - extern void SDL_NSLog(const char *text);
7.400 - {
7.401 - char *text;
7.402 -
7.403 - text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
7.404 - if (text) {
7.405 - SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message);
7.406 - SDL_NSLog(text);
7.407 - SDL_stack_free(text);
7.408 - return;
7.409 - }
7.410 - }
7.411 -#elif defined(__PSP__)
7.412 - {
7.413 - FILE* pFile;
7.414 - pFile = fopen ("SDL_Log.txt", "a");
7.415 - fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
7.416 - fclose (pFile);
7.417 - }
7.418 -#endif
7.419 -#if HAVE_STDIO_H
7.420 - fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
7.421 -#endif
7.422 -}
7.423 -
7.424 -void
7.425 -SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
7.426 -{
7.427 - if (callback) {
7.428 - *callback = SDL_log_function;
7.429 - }
7.430 - if (userdata) {
7.431 - *userdata = SDL_log_userdata;
7.432 - }
7.433 -}
7.434 -
7.435 -void
7.436 -SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata)
7.437 -{
7.438 - SDL_log_function = callback;
7.439 - SDL_log_userdata = userdata;
7.440 -}
7.441 -
7.442 -/* vi: set ts=4 sw=4 expandtab: */
7.443 +/*
7.444 + Simple DirectMedia Layer
7.445 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
7.446 +
7.447 + This software is provided 'as-is', without any express or implied
7.448 + warranty. In no event will the authors be held liable for any damages
7.449 + arising from the use of this software.
7.450 +
7.451 + Permission is granted to anyone to use this software for any purpose,
7.452 + including commercial applications, and to alter it and redistribute it
7.453 + freely, subject to the following restrictions:
7.454 +
7.455 + 1. The origin of this software must not be misrepresented; you must not
7.456 + claim that you wrote the original software. If you use this software
7.457 + in a product, an acknowledgment in the product documentation would be
7.458 + appreciated but is not required.
7.459 + 2. Altered source versions must be plainly marked as such, and must not be
7.460 + misrepresented as being the original software.
7.461 + 3. This notice may not be removed or altered from any source distribution.
7.462 +*/
7.463 +#include "SDL_config.h"
7.464 +
7.465 +#if defined(__WIN32__) || defined(__WINRT__)
7.466 +#include "core/windows/SDL_windows.h"
7.467 +#endif
7.468 +
7.469 +/* Simple log messages in SDL */
7.470 +
7.471 +#include "SDL_log.h"
7.472 +
7.473 +#if HAVE_STDIO_H
7.474 +#include <stdio.h>
7.475 +#endif
7.476 +
7.477 +#if defined(__ANDROID__)
7.478 +#include <android/log.h>
7.479 +#endif
7.480 +
7.481 +#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
7.482 +#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
7.483 +#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
7.484 +#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE
7.485 +
7.486 +/* Forward definition of error function */
7.487 +extern int SDL_SetError(const char *fmt, ...);
7.488 +
7.489 +typedef struct SDL_LogLevel
7.490 +{
7.491 + int category;
7.492 + SDL_LogPriority priority;
7.493 + struct SDL_LogLevel *next;
7.494 +} SDL_LogLevel;
7.495 +
7.496 +/* The default log output function */
7.497 +static void SDL_LogOutput(void *userdata,
7.498 + int category, SDL_LogPriority priority,
7.499 + const char *message);
7.500 +
7.501 +static SDL_LogLevel *SDL_loglevels;
7.502 +static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
7.503 +static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
7.504 +static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
7.505 +static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
7.506 +static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
7.507 +static void *SDL_log_userdata = NULL;
7.508 +
7.509 +static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
7.510 + NULL,
7.511 + "VERBOSE",
7.512 + "DEBUG",
7.513 + "INFO",
7.514 + "WARN",
7.515 + "ERROR",
7.516 + "CRITICAL"
7.517 +};
7.518 +
7.519 +#ifdef __ANDROID__
7.520 +static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = {
7.521 + "APP",
7.522 + "ERROR",
7.523 + "SYSTEM",
7.524 + "AUDIO",
7.525 + "VIDEO",
7.526 + "RENDER",
7.527 + "INPUT"
7.528 +};
7.529 +
7.530 +static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
7.531 + ANDROID_LOG_UNKNOWN,
7.532 + ANDROID_LOG_VERBOSE,
7.533 + ANDROID_LOG_DEBUG,
7.534 + ANDROID_LOG_INFO,
7.535 + ANDROID_LOG_WARN,
7.536 + ANDROID_LOG_ERROR,
7.537 + ANDROID_LOG_FATAL
7.538 +};
7.539 +#endif /* __ANDROID__ */
7.540 +
7.541 +
7.542 +void
7.543 +SDL_LogSetAllPriority(SDL_LogPriority priority)
7.544 +{
7.545 + SDL_LogLevel *entry;
7.546 +
7.547 + for (entry = SDL_loglevels; entry; entry = entry->next) {
7.548 + entry->priority = priority;
7.549 + }
7.550 + SDL_default_priority = priority;
7.551 + SDL_assert_priority = priority;
7.552 + SDL_application_priority = priority;
7.553 +}
7.554 +
7.555 +void
7.556 +SDL_LogSetPriority(int category, SDL_LogPriority priority)
7.557 +{
7.558 + SDL_LogLevel *entry;
7.559 +
7.560 + for (entry = SDL_loglevels; entry; entry = entry->next) {
7.561 + if (entry->category == category) {
7.562 + entry->priority = priority;
7.563 + return;
7.564 + }
7.565 + }
7.566 +
7.567 + /* Create a new entry */
7.568 + entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry));
7.569 + if (entry) {
7.570 + entry->category = category;
7.571 + entry->priority = priority;
7.572 + entry->next = SDL_loglevels;
7.573 + SDL_loglevels = entry;
7.574 + }
7.575 +}
7.576 +
7.577 +SDL_LogPriority
7.578 +SDL_LogGetPriority(int category)
7.579 +{
7.580 + SDL_LogLevel *entry;
7.581 +
7.582 + for (entry = SDL_loglevels; entry; entry = entry->next) {
7.583 + if (entry->category == category) {
7.584 + return entry->priority;
7.585 + }
7.586 + }
7.587 +
7.588 + if (category == SDL_LOG_CATEGORY_TEST) {
7.589 + return SDL_test_priority;
7.590 + } else if (category == SDL_LOG_CATEGORY_APPLICATION) {
7.591 + return SDL_application_priority;
7.592 + } else if (category == SDL_LOG_CATEGORY_ASSERT) {
7.593 + return SDL_assert_priority;
7.594 + } else {
7.595 + return SDL_default_priority;
7.596 + }
7.597 +}
7.598 +
7.599 +void
7.600 +SDL_LogResetPriorities(void)
7.601 +{
7.602 + SDL_LogLevel *entry;
7.603 +
7.604 + while (SDL_loglevels) {
7.605 + entry = SDL_loglevels;
7.606 + SDL_loglevels = entry->next;
7.607 + SDL_free(entry);
7.608 + }
7.609 +
7.610 + SDL_default_priority = DEFAULT_PRIORITY;
7.611 + SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
7.612 + SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
7.613 + SDL_test_priority = DEFAULT_TEST_PRIORITY;
7.614 +}
7.615 +
7.616 +void
7.617 +SDL_Log(const char *fmt, ...)
7.618 +{
7.619 + va_list ap;
7.620 +
7.621 + va_start(ap, fmt);
7.622 + SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap);
7.623 + va_end(ap);
7.624 +}
7.625 +
7.626 +void
7.627 +SDL_LogVerbose(int category, const char *fmt, ...)
7.628 +{
7.629 + va_list ap;
7.630 +
7.631 + va_start(ap, fmt);
7.632 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap);
7.633 + va_end(ap);
7.634 +}
7.635 +
7.636 +void
7.637 +SDL_LogDebug(int category, const char *fmt, ...)
7.638 +{
7.639 + va_list ap;
7.640 +
7.641 + va_start(ap, fmt);
7.642 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap);
7.643 + va_end(ap);
7.644 +}
7.645 +
7.646 +void
7.647 +SDL_LogInfo(int category, const char *fmt, ...)
7.648 +{
7.649 + va_list ap;
7.650 +
7.651 + va_start(ap, fmt);
7.652 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap);
7.653 + va_end(ap);
7.654 +}
7.655 +
7.656 +void
7.657 +SDL_LogWarn(int category, const char *fmt, ...)
7.658 +{
7.659 + va_list ap;
7.660 +
7.661 + va_start(ap, fmt);
7.662 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap);
7.663 + va_end(ap);
7.664 +}
7.665 +
7.666 +void
7.667 +SDL_LogError(int category, const char *fmt, ...)
7.668 +{
7.669 + va_list ap;
7.670 +
7.671 + va_start(ap, fmt);
7.672 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap);
7.673 + va_end(ap);
7.674 +}
7.675 +
7.676 +void
7.677 +SDL_LogCritical(int category, const char *fmt, ...)
7.678 +{
7.679 + va_list ap;
7.680 +
7.681 + va_start(ap, fmt);
7.682 + SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap);
7.683 + va_end(ap);
7.684 +}
7.685 +
7.686 +void
7.687 +SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...)
7.688 +{
7.689 + va_list ap;
7.690 +
7.691 + va_start(ap, fmt);
7.692 + SDL_LogMessageV(category, priority, fmt, ap);
7.693 + va_end(ap);
7.694 +}
7.695 +
7.696 +#ifdef __ANDROID__
7.697 +static const char *
7.698 +GetCategoryPrefix(int category)
7.699 +{
7.700 + if (category < SDL_LOG_CATEGORY_RESERVED1) {
7.701 + return SDL_category_prefixes[category];
7.702 + }
7.703 + if (category < SDL_LOG_CATEGORY_CUSTOM) {
7.704 + return "RESERVED";
7.705 + }
7.706 + return "CUSTOM";
7.707 +}
7.708 +#endif /* __ANDROID__ */
7.709 +
7.710 +void
7.711 +SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
7.712 +{
7.713 + char *message;
7.714 + size_t len;
7.715 +
7.716 + /* Nothing to do if we don't have an output function */
7.717 + if (!SDL_log_function) {
7.718 + return;
7.719 + }
7.720 +
7.721 + /* Make sure we don't exceed array bounds */
7.722 + if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) {
7.723 + return;
7.724 + }
7.725 +
7.726 + /* See if we want to do anything with this message */
7.727 + if (priority < SDL_LogGetPriority(category)) {
7.728 + return;
7.729 + }
7.730 +
7.731 + message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
7.732 + if (!message) {
7.733 + return;
7.734 + }
7.735 +
7.736 + SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
7.737 +
7.738 + /* Chop off final endline. */
7.739 + len = SDL_strlen(message);
7.740 + if ((len > 0) && (message[len-1] == '\n')) {
7.741 + message[--len] = '\0';
7.742 + if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */
7.743 + message[--len] = '\0';
7.744 + }
7.745 + }
7.746 +
7.747 + SDL_log_function(SDL_log_userdata, category, priority, message);
7.748 + SDL_stack_free(message);
7.749 +}
7.750 +
7.751 +#if defined(__WIN32__)
7.752 +/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */
7.753 +static int consoleAttached = 0;
7.754 +
7.755 +/* Handle to stderr output of console. */
7.756 +static HANDLE stderrHandle = NULL;
7.757 +#endif
7.758 +
7.759 +static void
7.760 +SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
7.761 + const char *message)
7.762 +{
7.763 +#if defined(__WIN32__) || defined(__WINRT__)
7.764 + /* Way too many allocations here, urgh */
7.765 + /* Note: One can't call SDL_SetError here, since that function itself logs. */
7.766 + {
7.767 + char *output;
7.768 + size_t length;
7.769 + LPTSTR tstr;
7.770 +
7.771 +#ifndef __WINRT__
7.772 + BOOL attachResult;
7.773 + DWORD attachError;
7.774 + unsigned long charsWritten;
7.775 +
7.776 + /* Maybe attach console and get stderr handle */
7.777 + if (consoleAttached == 0) {
7.778 + attachResult = AttachConsole(ATTACH_PARENT_PROCESS);
7.779 + if (!attachResult) {
7.780 + attachError = GetLastError();
7.781 + if (attachError == ERROR_INVALID_HANDLE) {
7.782 + OutputDebugString(TEXT("Parent process has no console\r\n"));
7.783 + consoleAttached = -1;
7.784 + } else if (attachError == ERROR_GEN_FAILURE) {
7.785 + OutputDebugString(TEXT("Could not attach to console of parent process\r\n"));
7.786 + consoleAttached = -1;
7.787 + } else if (attachError == ERROR_ACCESS_DENIED) {
7.788 + /* Already attached */
7.789 + consoleAttached = 1;
7.790 + } else {
7.791 + OutputDebugString(TEXT("Error attaching console\r\n"));
7.792 + consoleAttached = -1;
7.793 + }
7.794 + } else {
7.795 + /* Newly attached */
7.796 + consoleAttached = 1;
7.797 + }
7.798 +
7.799 + if (consoleAttached == 1) {
7.800 + stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
7.801 + }
7.802 + }
7.803 +#endif /* ifndef __WINRT__ */
7.804 +
7.805 + length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
7.806 + output = SDL_stack_alloc(char, length);
7.807 + SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message);
7.808 + tstr = WIN_UTF8ToString(output);
7.809 +
7.810 + /* Output to debugger */
7.811 + OutputDebugString(tstr);
7.812 +
7.813 +#ifndef __WINRT__
7.814 + /* Screen output to stderr, if console was attached. */
7.815 + if (consoleAttached == 1) {
7.816 + if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
7.817 + OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
7.818 + }
7.819 + if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) {
7.820 + OutputDebugString(TEXT("Insufficient heap memory to write message\r\n"));
7.821 + }
7.822 + }
7.823 +#endif /* ifndef __WINRT__ */
7.824 +
7.825 + SDL_free(tstr);
7.826 + SDL_stack_free(output);
7.827 + }
7.828 +#elif defined(__ANDROID__)
7.829 + {
7.830 + char tag[32];
7.831 +
7.832 + SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
7.833 + __android_log_write(SDL_android_priority[priority], tag, message);
7.834 + }
7.835 +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
7.836 + /* Technically we don't need SDL_VIDEO_DRIVER_COCOA, but that's where this function is defined for now.
7.837 + */
7.838 + extern void SDL_NSLog(const char *text);
7.839 + {
7.840 + char *text;
7.841 +
7.842 + text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
7.843 + if (text) {
7.844 + SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message);
7.845 + SDL_NSLog(text);
7.846 + SDL_stack_free(text);
7.847 + return;
7.848 + }
7.849 + }
7.850 +#elif defined(__PSP__)
7.851 + {
7.852 + FILE* pFile;
7.853 + pFile = fopen ("SDL_Log.txt", "a");
7.854 + fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
7.855 + fclose (pFile);
7.856 + }
7.857 +#endif
7.858 +#if HAVE_STDIO_H
7.859 + fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
7.860 +#endif
7.861 +}
7.862 +
7.863 +void
7.864 +SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
7.865 +{
7.866 + if (callback) {
7.867 + *callback = SDL_log_function;
7.868 + }
7.869 + if (userdata) {
7.870 + *userdata = SDL_log_userdata;
7.871 + }
7.872 +}
7.873 +
7.874 +void
7.875 +SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata)
7.876 +{
7.877 + SDL_log_function = callback;
7.878 + SDL_log_userdata = userdata;
7.879 +}
7.880 +
7.881 +/* vi: set ts=4 sw=4 expandtab: */
8.1 --- a/src/atomic/SDL_spinlock.c Tue Mar 04 19:49:11 2014 -0500
8.2 +++ b/src/atomic/SDL_spinlock.c Sun Mar 09 11:06:11 2014 -0700
8.3 @@ -1,126 +1,126 @@
8.4 -/*
8.5 - Simple DirectMedia Layer
8.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
8.7 -
8.8 - This software is provided 'as-is', without any express or implied
8.9 - warranty. In no event will the authors be held liable for any damages
8.10 - arising from the use of this software.
8.11 -
8.12 - Permission is granted to anyone to use this software for any purpose,
8.13 - including commercial applications, and to alter it and redistribute it
8.14 - freely, subject to the following restrictions:
8.15 -
8.16 - 1. The origin of this software must not be misrepresented; you must not
8.17 - claim that you wrote the original software. If you use this software
8.18 - in a product, an acknowledgment in the product documentation would be
8.19 - appreciated but is not required.
8.20 - 2. Altered source versions must be plainly marked as such, and must not be
8.21 - misrepresented as being the original software.
8.22 - 3. This notice may not be removed or altered from any source distribution.
8.23 -*/
8.24 -#include "SDL_config.h"
8.25 -
8.26 -#if defined(__WIN32__) || defined(__WINRT__)
8.27 -#include "../core/windows/SDL_windows.h"
8.28 -#endif
8.29 -
8.30 -#include "SDL_atomic.h"
8.31 -#include "SDL_mutex.h"
8.32 -#include "SDL_timer.h"
8.33 -
8.34 -
8.35 -/* This function is where all the magic happens... */
8.36 -SDL_bool
8.37 -SDL_AtomicTryLock(SDL_SpinLock *lock)
8.38 -{
8.39 -#if SDL_ATOMIC_DISABLED
8.40 - /* Terrible terrible damage */
8.41 - static SDL_mutex *_spinlock_mutex;
8.42 -
8.43 - if (!_spinlock_mutex) {
8.44 - /* Race condition on first lock... */
8.45 - _spinlock_mutex = SDL_CreateMutex();
8.46 - }
8.47 - SDL_LockMutex(_spinlock_mutex);
8.48 - if (*lock == 0) {
8.49 - *lock = 1;
8.50 - SDL_UnlockMutex(_spinlock_mutex);
8.51 - return SDL_TRUE;
8.52 - } else {
8.53 - SDL_UnlockMutex(_spinlock_mutex);
8.54 - return SDL_FALSE;
8.55 - }
8.56 -
8.57 -#elif defined(_MSC_VER)
8.58 - SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
8.59 - return (InterlockedExchange((long*)lock, 1) == 0);
8.60 -
8.61 -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
8.62 - return (__sync_lock_test_and_set(lock, 1) == 0);
8.63 -
8.64 -#elif defined(__GNUC__) && defined(__arm__) && \
8.65 - (defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
8.66 - defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \
8.67 - defined(__ARM_ARCH_5TEJ__))
8.68 - int result;
8.69 - __asm__ __volatile__ (
8.70 - "swp %0, %1, [%2]\n"
8.71 - : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
8.72 - return (result == 0);
8.73 -
8.74 -#elif defined(__GNUC__) && defined(__arm__)
8.75 - int result;
8.76 - __asm__ __volatile__ (
8.77 - "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
8.78 - : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
8.79 - return (result == 0);
8.80 -
8.81 -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
8.82 - int result;
8.83 - __asm__ __volatile__(
8.84 - "lock ; xchgl %0, (%1)\n"
8.85 - : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory");
8.86 - return (result == 0);
8.87 -
8.88 -#elif defined(__MACOSX__) || defined(__IPHONEOS__)
8.89 - /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */
8.90 - return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
8.91 -
8.92 -#elif HAVE_PTHREAD_SPINLOCK
8.93 - /* pthread instructions */
8.94 - return (pthread_spin_trylock(lock) == 0);
8.95 -
8.96 -#else
8.97 -#error Please implement for your platform.
8.98 - return SDL_FALSE;
8.99 -#endif
8.100 -}
8.101 -
8.102 -void
8.103 -SDL_AtomicLock(SDL_SpinLock *lock)
8.104 -{
8.105 - /* FIXME: Should we have an eventual timeout? */
8.106 - while (!SDL_AtomicTryLock(lock)) {
8.107 - SDL_Delay(0);
8.108 - }
8.109 -}
8.110 -
8.111 -void
8.112 -SDL_AtomicUnlock(SDL_SpinLock *lock)
8.113 -{
8.114 -#if defined(_MSC_VER)
8.115 - _ReadWriteBarrier();
8.116 - *lock = 0;
8.117 -
8.118 -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
8.119 - __sync_lock_release(lock);
8.120 -
8.121 -#elif HAVE_PTHREAD_SPINLOCK
8.122 - pthread_spin_unlock(lock);
8.123 -
8.124 -#else
8.125 - *lock = 0;
8.126 -#endif
8.127 -}
8.128 -
8.129 -/* vi: set ts=4 sw=4 expandtab: */
8.130 +/*
8.131 + Simple DirectMedia Layer
8.132 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
8.133 +
8.134 + This software is provided 'as-is', without any express or implied
8.135 + warranty. In no event will the authors be held liable for any damages
8.136 + arising from the use of this software.
8.137 +
8.138 + Permission is granted to anyone to use this software for any purpose,
8.139 + including commercial applications, and to alter it and redistribute it
8.140 + freely, subject to the following restrictions:
8.141 +
8.142 + 1. The origin of this software must not be misrepresented; you must not
8.143 + claim that you wrote the original software. If you use this software
8.144 + in a product, an acknowledgment in the product documentation would be
8.145 + appreciated but is not required.
8.146 + 2. Altered source versions must be plainly marked as such, and must not be
8.147 + misrepresented as being the original software.
8.148 + 3. This notice may not be removed or altered from any source distribution.
8.149 +*/
8.150 +#include "SDL_config.h"
8.151 +
8.152 +#if defined(__WIN32__) || defined(__WINRT__)
8.153 +#include "../core/windows/SDL_windows.h"
8.154 +#endif
8.155 +
8.156 +#include "SDL_atomic.h"
8.157 +#include "SDL_mutex.h"
8.158 +#include "SDL_timer.h"
8.159 +
8.160 +
8.161 +/* This function is where all the magic happens... */
8.162 +SDL_bool
8.163 +SDL_AtomicTryLock(SDL_SpinLock *lock)
8.164 +{
8.165 +#if SDL_ATOMIC_DISABLED
8.166 + /* Terrible terrible damage */
8.167 + static SDL_mutex *_spinlock_mutex;
8.168 +
8.169 + if (!_spinlock_mutex) {
8.170 + /* Race condition on first lock... */
8.171 + _spinlock_mutex = SDL_CreateMutex();
8.172 + }
8.173 + SDL_LockMutex(_spinlock_mutex);
8.174 + if (*lock == 0) {
8.175 + *lock = 1;
8.176 + SDL_UnlockMutex(_spinlock_mutex);
8.177 + return SDL_TRUE;
8.178 + } else {
8.179 + SDL_UnlockMutex(_spinlock_mutex);
8.180 + return SDL_FALSE;
8.181 + }
8.182 +
8.183 +#elif defined(_MSC_VER)
8.184 + SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
8.185 + return (InterlockedExchange((long*)lock, 1) == 0);
8.186 +
8.187 +#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
8.188 + return (__sync_lock_test_and_set(lock, 1) == 0);
8.189 +
8.190 +#elif defined(__GNUC__) && defined(__arm__) && \
8.191 + (defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
8.192 + defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \
8.193 + defined(__ARM_ARCH_5TEJ__))
8.194 + int result;
8.195 + __asm__ __volatile__ (
8.196 + "swp %0, %1, [%2]\n"
8.197 + : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
8.198 + return (result == 0);
8.199 +
8.200 +#elif defined(__GNUC__) && defined(__arm__)
8.201 + int result;
8.202 + __asm__ __volatile__ (
8.203 + "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
8.204 + : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
8.205 + return (result == 0);
8.206 +
8.207 +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
8.208 + int result;
8.209 + __asm__ __volatile__(
8.210 + "lock ; xchgl %0, (%1)\n"
8.211 + : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory");
8.212 + return (result == 0);
8.213 +
8.214 +#elif defined(__MACOSX__) || defined(__IPHONEOS__)
8.215 + /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */
8.216 + return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
8.217 +
8.218 +#elif HAVE_PTHREAD_SPINLOCK
8.219 + /* pthread instructions */
8.220 + return (pthread_spin_trylock(lock) == 0);
8.221 +
8.222 +#else
8.223 +#error Please implement for your platform.
8.224 + return SDL_FALSE;
8.225 +#endif
8.226 +}
8.227 +
8.228 +void
8.229 +SDL_AtomicLock(SDL_SpinLock *lock)
8.230 +{
8.231 + /* FIXME: Should we have an eventual timeout? */
8.232 + while (!SDL_AtomicTryLock(lock)) {
8.233 + SDL_Delay(0);
8.234 + }
8.235 +}
8.236 +
8.237 +void
8.238 +SDL_AtomicUnlock(SDL_SpinLock *lock)
8.239 +{
8.240 +#if defined(_MSC_VER)
8.241 + _ReadWriteBarrier();
8.242 + *lock = 0;
8.243 +
8.244 +#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
8.245 + __sync_lock_release(lock);
8.246 +
8.247 +#elif HAVE_PTHREAD_SPINLOCK
8.248 + pthread_spin_unlock(lock);
8.249 +
8.250 +#else
8.251 + *lock = 0;
8.252 +#endif
8.253 +}
8.254 +
8.255 +/* vi: set ts=4 sw=4 expandtab: */
9.1 --- a/src/audio/xaudio2/SDL_xaudio2.c Tue Mar 04 19:49:11 2014 -0500
9.2 +++ b/src/audio/xaudio2/SDL_xaudio2.c Sun Mar 09 11:06:11 2014 -0700
9.3 @@ -1,543 +1,543 @@
9.4 -/*
9.5 - Simple DirectMedia Layer
9.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
9.7 -
9.8 - This software is provided 'as-is', without any express or implied
9.9 - warranty. In no event will the authors be held liable for any damages
9.10 - arising from the use of this software.
9.11 -
9.12 - Permission is granted to anyone to use this software for any purpose,
9.13 - including commercial applications, and to alter it and redistribute it
9.14 - freely, subject to the following restrictions:
9.15 -
9.16 - 1. The origin of this software must not be misrepresented; you must not
9.17 - claim that you wrote the original software. If you use this software
9.18 - in a product, an acknowledgment in the product documentation would be
9.19 - appreciated but is not required.
9.20 - 2. Altered source versions must be plainly marked as such, and must not be
9.21 - misrepresented as being the original software.
9.22 - 3. This notice may not be removed or altered from any source distribution.
9.23 -*/
9.24 -
9.25 -/* WinRT NOTICE:
9.26 -
9.27 - A few changes to SDL's XAudio2 backend were warranted by API
9.28 - changes to Windows. Many, but not all of these are documented by Microsoft
9.29 - at:
9.30 - http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
9.31 -
9.32 - 1. Windows' thread synchronization function, CreateSemaphore, was removed
9.33 - from WinRT. SDL's semaphore API was substituted instead.
9.34 - 2. The method calls, IXAudio2::GetDeviceCount and IXAudio2::GetDeviceDetails
9.35 - were removed from the XAudio2 API. Microsoft is telling developers to
9.36 - use APIs in Windows::Foundation instead.
9.37 - For SDL, the missing methods were reimplemented using the APIs Microsoft
9.38 - said to use.
9.39 - 3. CoInitialize and CoUninitialize are not available in WinRT.
9.40 - These calls were removed, as COM will have been initialized earlier,
9.41 - at least by the call to the WinRT app's main function
9.42 - (aka 'int main(Platform::Array<Platform::String^>^)). (DLudwig:
9.43 - This was my understanding of how WinRT: the 'main' function uses
9.44 - a tag of [MTAThread], which should initialize COM. My understanding
9.45 - of COM is somewhat limited, and I may be incorrect here.)
9.46 - 4. IXAudio2::CreateMasteringVoice changed its integer-based 'DeviceIndex'
9.47 - argument to a string-based one, 'szDeviceId'. In WinRT, the
9.48 - string-based argument will be used.
9.49 -*/
9.50 -
9.51 -#include "SDL_config.h"
9.52 -
9.53 -#if SDL_AUDIO_DRIVER_XAUDIO2
9.54 -
9.55 -#include "../../core/windows/SDL_windows.h"
9.56 -#include "SDL_audio.h"
9.57 -#include "../SDL_audio_c.h"
9.58 -#include "../SDL_sysaudio.h"
9.59 -#include "SDL_assert.h"
9.60 -
9.61 -#ifdef __GNUC__
9.62 -/* The configure script already did any necessary checking */
9.63 -# define SDL_XAUDIO2_HAS_SDK 1
9.64 -#elif defined(__WINRT__)
9.65 -/* WinRT always has access to the .the XAudio 2 SDK */
9.66 -# define SDL_XAUDIO2_HAS_SDK
9.67 -#else
9.68 -/* XAudio2 exists as of the March 2008 DirectX SDK
9.69 - The XAudio2 implementation available in the Windows 8 SDK targets Windows 8 and newer.
9.70 - If you want to build SDL with XAudio2 support you should install the DirectX SDK.
9.71 - */
9.72 -#include <dxsdkver.h>
9.73 -#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
9.74 -# pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
9.75 -#else
9.76 -# define SDL_XAUDIO2_HAS_SDK 1
9.77 -#endif
9.78 -#endif
9.79 -
9.80 -#ifdef SDL_XAUDIO2_HAS_SDK
9.81 -
9.82 -/* Check to see if we're compiling for XAudio 2.8, or higher. */
9.83 -#ifdef WINVER
9.84 -#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */
9.85 -#define SDL_XAUDIO2_WIN8 1
9.86 -#endif
9.87 -#endif
9.88 -
9.89 -/* The XAudio header file, when #include'd on WinRT, will only compile in C++
9.90 - files, but not C. A few preprocessor-based hacks are defined below in order
9.91 - to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c.
9.92 - */
9.93 -#ifdef __WINRT__
9.94 -#define uuid(x)
9.95 -#define DX_BUILD
9.96 -#endif
9.97 -
9.98 -#define INITGUID 1
9.99 -#include <xaudio2.h>
9.100 -
9.101 -/* Hidden "this" pointer for the audio functions */
9.102 -#define _THIS SDL_AudioDevice *this
9.103 -
9.104 -#ifdef __WINRT__
9.105 -#include "SDL_xaudio2_winrthelpers.h"
9.106 -#endif
9.107 -
9.108 -/* Fixes bug 1210 where some versions of gcc need named parameters */
9.109 -#ifdef __GNUC__
9.110 -#ifdef THIS
9.111 -#undef THIS
9.112 -#endif
9.113 -#define THIS INTERFACE *p
9.114 -#ifdef THIS_
9.115 -#undef THIS_
9.116 -#endif
9.117 -#define THIS_ INTERFACE *p,
9.118 -#endif
9.119 -
9.120 -struct SDL_PrivateAudioData
9.121 -{
9.122 - IXAudio2 *ixa2;
9.123 - IXAudio2SourceVoice *source;
9.124 - IXAudio2MasteringVoice *mastering;
9.125 - SDL_sem * semaphore;
9.126 - Uint8 *mixbuf;
9.127 - int mixlen;
9.128 - Uint8 *nextbuf;
9.129 -};
9.130 -
9.131 -
9.132 -static void
9.133 -XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
9.134 -{
9.135 - IXAudio2 *ixa2 = NULL;
9.136 - UINT32 devcount = 0;
9.137 - UINT32 i = 0;
9.138 -
9.139 - if (iscapture) {
9.140 - SDL_SetError("XAudio2: capture devices unsupported.");
9.141 - return;
9.142 - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.143 - SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
9.144 - return;
9.145 - } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
9.146 - SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
9.147 - IXAudio2_Release(ixa2);
9.148 - return;
9.149 - }
9.150 -
9.151 - for (i = 0; i < devcount; i++) {
9.152 - XAUDIO2_DEVICE_DETAILS details;
9.153 - if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
9.154 - char *str = WIN_StringToUTF8(details.DisplayName);
9.155 - if (str != NULL) {
9.156 - addfn(str);
9.157 - SDL_free(str); /* addfn() made a copy of the string. */
9.158 - }
9.159 - }
9.160 - }
9.161 -
9.162 - IXAudio2_Release(ixa2);
9.163 -}
9.164 -
9.165 -static void STDMETHODCALLTYPE
9.166 -VoiceCBOnBufferEnd(THIS_ void *data)
9.167 -{
9.168 - /* Just signal the SDL audio thread and get out of XAudio2's way. */
9.169 - SDL_AudioDevice *this = (SDL_AudioDevice *) data;
9.170 - SDL_SemPost(this->hidden->semaphore);
9.171 -}
9.172 -
9.173 -static void STDMETHODCALLTYPE
9.174 -VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
9.175 -{
9.176 - /* !!! FIXME: attempt to recover, or mark device disconnected. */
9.177 - SDL_assert(0 && "write me!");
9.178 -}
9.179 -
9.180 -/* no-op callbacks... */
9.181 -static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
9.182 -static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
9.183 -static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
9.184 -static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
9.185 -static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
9.186 -
9.187 -
9.188 -static Uint8 *
9.189 -XAUDIO2_GetDeviceBuf(_THIS)
9.190 -{
9.191 - return this->hidden->nextbuf;
9.192 -}
9.193 -
9.194 -static void
9.195 -XAUDIO2_PlayDevice(_THIS)
9.196 -{
9.197 - XAUDIO2_BUFFER buffer;
9.198 - Uint8 *mixbuf = this->hidden->mixbuf;
9.199 - Uint8 *nextbuf = this->hidden->nextbuf;
9.200 - const int mixlen = this->hidden->mixlen;
9.201 - IXAudio2SourceVoice *source = this->hidden->source;
9.202 - HRESULT result = S_OK;
9.203 -
9.204 - if (!this->enabled) { /* shutting down? */
9.205 - return;
9.206 - }
9.207 -
9.208 - /* Submit the next filled buffer */
9.209 - SDL_zero(buffer);
9.210 - buffer.AudioBytes = mixlen;
9.211 - buffer.pAudioData = nextbuf;
9.212 - buffer.pContext = this;
9.213 -
9.214 - if (nextbuf == mixbuf) {
9.215 - nextbuf += mixlen;
9.216 - } else {
9.217 - nextbuf = mixbuf;
9.218 - }
9.219 - this->hidden->nextbuf = nextbuf;
9.220 -
9.221 - result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
9.222 - if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
9.223 - /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
9.224 - }
9.225 -
9.226 - if (result != S_OK) { /* uhoh, panic! */
9.227 - IXAudio2SourceVoice_FlushSourceBuffers(source);
9.228 - this->enabled = 0;
9.229 - }
9.230 -}
9.231 -
9.232 -static void
9.233 -XAUDIO2_WaitDevice(_THIS)
9.234 -{
9.235 - if (this->enabled) {
9.236 - SDL_SemWait(this->hidden->semaphore);
9.237 - }
9.238 -}
9.239 -
9.240 -static void
9.241 -XAUDIO2_WaitDone(_THIS)
9.242 -{
9.243 - IXAudio2SourceVoice *source = this->hidden->source;
9.244 - XAUDIO2_VOICE_STATE state;
9.245 - SDL_assert(!this->enabled); /* flag that stops playing. */
9.246 - IXAudio2SourceVoice_Discontinuity(source);
9.247 -#if SDL_XAUDIO2_WIN8
9.248 - IXAudio2SourceVoice_GetState(source, &state, 0);
9.249 -#else
9.250 - IXAudio2SourceVoice_GetState(source, &state);
9.251 -#endif
9.252 - while (state.BuffersQueued > 0) {
9.253 - SDL_SemWait(this->hidden->semaphore);
9.254 -#if SDL_XAUDIO2_WIN8
9.255 - IXAudio2SourceVoice_GetState(source, &state, 0);
9.256 -#else
9.257 - IXAudio2SourceVoice_GetState(source, &state);
9.258 -#endif
9.259 - }
9.260 -}
9.261 -
9.262 -
9.263 -static void
9.264 -XAUDIO2_CloseDevice(_THIS)
9.265 -{
9.266 - if (this->hidden != NULL) {
9.267 - IXAudio2 *ixa2 = this->hidden->ixa2;
9.268 - IXAudio2SourceVoice *source = this->hidden->source;
9.269 - IXAudio2MasteringVoice *mastering = this->hidden->mastering;
9.270 -
9.271 - if (source != NULL) {
9.272 - IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
9.273 - IXAudio2SourceVoice_FlushSourceBuffers(source);
9.274 - IXAudio2SourceVoice_DestroyVoice(source);
9.275 - }
9.276 - if (ixa2 != NULL) {
9.277 - IXAudio2_StopEngine(ixa2);
9.278 - }
9.279 - if (mastering != NULL) {
9.280 - IXAudio2MasteringVoice_DestroyVoice(mastering);
9.281 - }
9.282 - if (ixa2 != NULL) {
9.283 - IXAudio2_Release(ixa2);
9.284 - }
9.285 - SDL_free(this->hidden->mixbuf);
9.286 - if (this->hidden->semaphore != NULL) {
9.287 - SDL_DestroySemaphore(this->hidden->semaphore);
9.288 - }
9.289 -
9.290 - SDL_free(this->hidden);
9.291 - this->hidden = NULL;
9.292 - }
9.293 -}
9.294 -
9.295 -static int
9.296 -XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
9.297 -{
9.298 - HRESULT result = S_OK;
9.299 - WAVEFORMATEX waveformat;
9.300 - int valid_format = 0;
9.301 - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
9.302 - IXAudio2 *ixa2 = NULL;
9.303 - IXAudio2SourceVoice *source = NULL;
9.304 -#if defined(SDL_XAUDIO2_WIN8)
9.305 - LPCWSTR devId = NULL;
9.306 -#else
9.307 - UINT32 devId = 0; /* 0 == system default device. */
9.308 -#endif
9.309 -
9.310 - static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
9.311 - VoiceCBOnVoiceProcessPassStart,
9.312 - VoiceCBOnVoiceProcessPassEnd,
9.313 - VoiceCBOnStreamEnd,
9.314 - VoiceCBOnBufferStart,
9.315 - VoiceCBOnBufferEnd,
9.316 - VoiceCBOnLoopEnd,
9.317 - VoiceCBOnVoiceError
9.318 - };
9.319 -
9.320 - static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
9.321 -
9.322 - if (iscapture) {
9.323 - return SDL_SetError("XAudio2: capture devices unsupported.");
9.324 - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.325 - return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
9.326 - }
9.327 -
9.328 - /*
9.329 - XAUDIO2_DEBUG_CONFIGURATION debugConfig;
9.330 - debugConfig.TraceMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS | XAUDIO2_LOG_DETAIL | XAUDIO2_LOG_FUNC_CALLS | XAUDIO2_LOG_TIMING | XAUDIO2_LOG_LOCKS | XAUDIO2_LOG_MEMORY | XAUDIO2_LOG_STREAMING;
9.331 - debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS;
9.332 - debugConfig.LogThreadID = TRUE;
9.333 - debugConfig.LogFileline = TRUE;
9.334 - debugConfig.LogFunctionName = TRUE;
9.335 - debugConfig.LogTiming = TRUE;
9.336 - ixa2->SetDebugConfiguration(&debugConfig);
9.337 - */
9.338 -
9.339 -#if ! defined(__WINRT__)
9.340 - if (devname != NULL) {
9.341 - UINT32 devcount = 0;
9.342 - UINT32 i = 0;
9.343 -
9.344 - if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
9.345 - IXAudio2_Release(ixa2);
9.346 - return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
9.347 - }
9.348 - for (i = 0; i < devcount; i++) {
9.349 - XAUDIO2_DEVICE_DETAILS details;
9.350 - if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
9.351 - char *str = WIN_StringToUTF8(details.DisplayName);
9.352 - if (str != NULL) {
9.353 - const int match = (SDL_strcmp(str, devname) == 0);
9.354 - SDL_free(str);
9.355 - if (match) {
9.356 - devId = i;
9.357 - break;
9.358 - }
9.359 - }
9.360 - }
9.361 - }
9.362 -
9.363 - if (i == devcount) {
9.364 - IXAudio2_Release(ixa2);
9.365 - return SDL_SetError("XAudio2: Requested device not found.");
9.366 - }
9.367 - }
9.368 -#endif
9.369 -
9.370 - /* Initialize all variables that we clean on shutdown */
9.371 - this->hidden = (struct SDL_PrivateAudioData *)
9.372 - SDL_malloc((sizeof *this->hidden));
9.373 - if (this->hidden == NULL) {
9.374 - IXAudio2_Release(ixa2);
9.375 - return SDL_OutOfMemory();
9.376 - }
9.377 - SDL_memset(this->hidden, 0, (sizeof *this->hidden));
9.378 -
9.379 - this->hidden->ixa2 = ixa2;
9.380 - this->hidden->semaphore = SDL_CreateSemaphore(1);
9.381 - if (this->hidden->semaphore == NULL) {
9.382 - XAUDIO2_CloseDevice(this);
9.383 - return SDL_SetError("XAudio2: CreateSemaphore() failed!");
9.384 - }
9.385 -
9.386 - while ((!valid_format) && (test_format)) {
9.387 - switch (test_format) {
9.388 - case AUDIO_U8:
9.389 - case AUDIO_S16:
9.390 - case AUDIO_S32:
9.391 - case AUDIO_F32:
9.392 - this->spec.format = test_format;
9.393 - valid_format = 1;
9.394 - break;
9.395 - }
9.396 - test_format = SDL_NextAudioFormat();
9.397 - }
9.398 -
9.399 - if (!valid_format) {
9.400 - XAUDIO2_CloseDevice(this);
9.401 - return SDL_SetError("XAudio2: Unsupported audio format");
9.402 - }
9.403 -
9.404 - /* Update the fragment size as size in bytes */
9.405 - SDL_CalculateAudioSpec(&this->spec);
9.406 -
9.407 - /* We feed a Source, it feeds the Mastering, which feeds the device. */
9.408 - this->hidden->mixlen = this->spec.size;
9.409 - this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
9.410 - if (this->hidden->mixbuf == NULL) {
9.411 - XAUDIO2_CloseDevice(this);
9.412 - return SDL_OutOfMemory();
9.413 - }
9.414 - this->hidden->nextbuf = this->hidden->mixbuf;
9.415 - SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
9.416 -
9.417 - /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
9.418 - Xbox360, this means 5.1 output, but on Windows, it means "figure out
9.419 - what the system has." It might be preferable to let XAudio2 blast
9.420 - stereo output to appropriate surround sound configurations
9.421 - instead of clamping to 2 channels, even though we'll configure the
9.422 - Source Voice for whatever number of channels you supply. */
9.423 -#if SDL_XAUDIO2_WIN8
9.424 - result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
9.425 - XAUDIO2_DEFAULT_CHANNELS,
9.426 - this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects);
9.427 -#else
9.428 - result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
9.429 - XAUDIO2_DEFAULT_CHANNELS,
9.430 - this->spec.freq, 0, devId, NULL);
9.431 -#endif
9.432 - if (result != S_OK) {
9.433 - XAUDIO2_CloseDevice(this);
9.434 - return SDL_SetError("XAudio2: Couldn't create mastering voice");
9.435 - }
9.436 -
9.437 - SDL_zero(waveformat);
9.438 - if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
9.439 - waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
9.440 - } else {
9.441 - waveformat.wFormatTag = WAVE_FORMAT_PCM;
9.442 - }
9.443 - waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
9.444 - waveformat.nChannels = this->spec.channels;
9.445 - waveformat.nSamplesPerSec = this->spec.freq;
9.446 - waveformat.nBlockAlign =
9.447 - waveformat.nChannels * (waveformat.wBitsPerSample / 8);
9.448 - waveformat.nAvgBytesPerSec =
9.449 - waveformat.nSamplesPerSec * waveformat.nBlockAlign;
9.450 - waveformat.cbSize = sizeof(waveformat);
9.451 -
9.452 -#ifdef __WINRT__
9.453 - // DLudwig: for now, make XAudio2 do sample rate conversion, just to
9.454 - // get the loopwave test to work.
9.455 - //
9.456 - // TODO, WinRT: consider removing WinRT-specific source-voice creation code from SDL_xaudio2.c
9.457 - result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
9.458 - 0,
9.459 - 1.0f, &callbacks, NULL, NULL);
9.460 -#else
9.461 - result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
9.462 - XAUDIO2_VOICE_NOSRC |
9.463 - XAUDIO2_VOICE_NOPITCH,
9.464 - 1.0f, &callbacks, NULL, NULL);
9.465 -
9.466 -#endif
9.467 - if (result != S_OK) {
9.468 - XAUDIO2_CloseDevice(this);
9.469 - return SDL_SetError("XAudio2: Couldn't create source voice");
9.470 - }
9.471 - this->hidden->source = source;
9.472 -
9.473 - /* Start everything playing! */
9.474 - result = IXAudio2_StartEngine(ixa2);
9.475 - if (result != S_OK) {
9.476 - XAUDIO2_CloseDevice(this);
9.477 - return SDL_SetError("XAudio2: Couldn't start engine");
9.478 - }
9.479 -
9.480 - result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
9.481 - if (result != S_OK) {
9.482 - XAUDIO2_CloseDevice(this);
9.483 - return SDL_SetError("XAudio2: Couldn't start source voice");
9.484 - }
9.485 -
9.486 - return 0; /* good to go. */
9.487 -}
9.488 -
9.489 -static void
9.490 -XAUDIO2_Deinitialize(void)
9.491 -{
9.492 -#if defined(__WIN32__)
9.493 - WIN_CoUninitialize();
9.494 -#endif
9.495 -}
9.496 -
9.497 -#endif /* SDL_XAUDIO2_HAS_SDK */
9.498 -
9.499 -
9.500 -static int
9.501 -XAUDIO2_Init(SDL_AudioDriverImpl * impl)
9.502 -{
9.503 -#ifndef SDL_XAUDIO2_HAS_SDK
9.504 - SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
9.505 - return 0; /* no XAudio2 support, ever. Update your SDK! */
9.506 -#else
9.507 - /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
9.508 - IXAudio2 *ixa2 = NULL;
9.509 -#if defined(__WIN32__)
9.510 - // TODO, WinRT: Investigate using CoInitializeEx here
9.511 - if (FAILED(WIN_CoInitialize())) {
9.512 - SDL_SetError("XAudio2: CoInitialize() failed");
9.513 - return 0;
9.514 - }
9.515 -#endif
9.516 -
9.517 - if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.518 -#if defined(__WIN32__)
9.519 - WIN_CoUninitialize();
9.520 -#endif
9.521 - SDL_SetError("XAudio2: XAudio2Create() failed at initialization");
9.522 - return 0; /* not available. */
9.523 - }
9.524 - IXAudio2_Release(ixa2);
9.525 -
9.526 - /* Set the function pointers */
9.527 - impl->DetectDevices = XAUDIO2_DetectDevices;
9.528 - impl->OpenDevice = XAUDIO2_OpenDevice;
9.529 - impl->PlayDevice = XAUDIO2_PlayDevice;
9.530 - impl->WaitDevice = XAUDIO2_WaitDevice;
9.531 - impl->WaitDone = XAUDIO2_WaitDone;
9.532 - impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
9.533 - impl->CloseDevice = XAUDIO2_CloseDevice;
9.534 - impl->Deinitialize = XAUDIO2_Deinitialize;
9.535 -
9.536 - return 1; /* this audio target is available. */
9.537 -#endif
9.538 -}
9.539 -
9.540 -AudioBootStrap XAUDIO2_bootstrap = {
9.541 - "xaudio2", "XAudio2", XAUDIO2_Init, 0
9.542 -};
9.543 -
9.544 -#endif /* SDL_AUDIO_DRIVER_XAUDIO2 */
9.545 -
9.546 -/* vi: set ts=4 sw=4 expandtab: */
9.547 +/*
9.548 + Simple DirectMedia Layer
9.549 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
9.550 +
9.551 + This software is provided 'as-is', without any express or implied
9.552 + warranty. In no event will the authors be held liable for any damages
9.553 + arising from the use of this software.
9.554 +
9.555 + Permission is granted to anyone to use this software for any purpose,
9.556 + including commercial applications, and to alter it and redistribute it
9.557 + freely, subject to the following restrictions:
9.558 +
9.559 + 1. The origin of this software must not be misrepresented; you must not
9.560 + claim that you wrote the original software. If you use this software
9.561 + in a product, an acknowledgment in the product documentation would be
9.562 + appreciated but is not required.
9.563 + 2. Altered source versions must be plainly marked as such, and must not be
9.564 + misrepresented as being the original software.
9.565 + 3. This notice may not be removed or altered from any source distribution.
9.566 +*/
9.567 +
9.568 +/* WinRT NOTICE:
9.569 +
9.570 + A few changes to SDL's XAudio2 backend were warranted by API
9.571 + changes to Windows. Many, but not all of these are documented by Microsoft
9.572 + at:
9.573 + http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
9.574 +
9.575 + 1. Windows' thread synchronization function, CreateSemaphore, was removed
9.576 + from WinRT. SDL's semaphore API was substituted instead.
9.577 + 2. The method calls, IXAudio2::GetDeviceCount and IXAudio2::GetDeviceDetails
9.578 + were removed from the XAudio2 API. Microsoft is telling developers to
9.579 + use APIs in Windows::Foundation instead.
9.580 + For SDL, the missing methods were reimplemented using the APIs Microsoft
9.581 + said to use.
9.582 + 3. CoInitialize and CoUninitialize are not available in WinRT.
9.583 + These calls were removed, as COM will have been initialized earlier,
9.584 + at least by the call to the WinRT app's main function
9.585 + (aka 'int main(Platform::Array<Platform::String^>^)). (DLudwig:
9.586 + This was my understanding of how WinRT: the 'main' function uses
9.587 + a tag of [MTAThread], which should initialize COM. My understanding
9.588 + of COM is somewhat limited, and I may be incorrect here.)
9.589 + 4. IXAudio2::CreateMasteringVoice changed its integer-based 'DeviceIndex'
9.590 + argument to a string-based one, 'szDeviceId'. In WinRT, the
9.591 + string-based argument will be used.
9.592 +*/
9.593 +
9.594 +#include "SDL_config.h"
9.595 +
9.596 +#if SDL_AUDIO_DRIVER_XAUDIO2
9.597 +
9.598 +#include "../../core/windows/SDL_windows.h"
9.599 +#include "SDL_audio.h"
9.600 +#include "../SDL_audio_c.h"
9.601 +#include "../SDL_sysaudio.h"
9.602 +#include "SDL_assert.h"
9.603 +
9.604 +#ifdef __GNUC__
9.605 +/* The configure script already did any necessary checking */
9.606 +# define SDL_XAUDIO2_HAS_SDK 1
9.607 +#elif defined(__WINRT__)
9.608 +/* WinRT always has access to the .the XAudio 2 SDK */
9.609 +# define SDL_XAUDIO2_HAS_SDK
9.610 +#else
9.611 +/* XAudio2 exists as of the March 2008 DirectX SDK
9.612 + The XAudio2 implementation available in the Windows 8 SDK targets Windows 8 and newer.
9.613 + If you want to build SDL with XAudio2 support you should install the DirectX SDK.
9.614 + */
9.615 +#include <dxsdkver.h>
9.616 +#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
9.617 +# pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
9.618 +#else
9.619 +# define SDL_XAUDIO2_HAS_SDK 1
9.620 +#endif
9.621 +#endif
9.622 +
9.623 +#ifdef SDL_XAUDIO2_HAS_SDK
9.624 +
9.625 +/* Check to see if we're compiling for XAudio 2.8, or higher. */
9.626 +#ifdef WINVER
9.627 +#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */
9.628 +#define SDL_XAUDIO2_WIN8 1
9.629 +#endif
9.630 +#endif
9.631 +
9.632 +/* The XAudio header file, when #include'd on WinRT, will only compile in C++
9.633 + files, but not C. A few preprocessor-based hacks are defined below in order
9.634 + to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c.
9.635 + */
9.636 +#ifdef __WINRT__
9.637 +#define uuid(x)
9.638 +#define DX_BUILD
9.639 +#endif
9.640 +
9.641 +#define INITGUID 1
9.642 +#include <xaudio2.h>
9.643 +
9.644 +/* Hidden "this" pointer for the audio functions */
9.645 +#define _THIS SDL_AudioDevice *this
9.646 +
9.647 +#ifdef __WINRT__
9.648 +#include "SDL_xaudio2_winrthelpers.h"
9.649 +#endif
9.650 +
9.651 +/* Fixes bug 1210 where some versions of gcc need named parameters */
9.652 +#ifdef __GNUC__
9.653 +#ifdef THIS
9.654 +#undef THIS
9.655 +#endif
9.656 +#define THIS INTERFACE *p
9.657 +#ifdef THIS_
9.658 +#undef THIS_
9.659 +#endif
9.660 +#define THIS_ INTERFACE *p,
9.661 +#endif
9.662 +
9.663 +struct SDL_PrivateAudioData
9.664 +{
9.665 + IXAudio2 *ixa2;
9.666 + IXAudio2SourceVoice *source;
9.667 + IXAudio2MasteringVoice *mastering;
9.668 + SDL_sem * semaphore;
9.669 + Uint8 *mixbuf;
9.670 + int mixlen;
9.671 + Uint8 *nextbuf;
9.672 +};
9.673 +
9.674 +
9.675 +static void
9.676 +XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
9.677 +{
9.678 + IXAudio2 *ixa2 = NULL;
9.679 + UINT32 devcount = 0;
9.680 + UINT32 i = 0;
9.681 +
9.682 + if (iscapture) {
9.683 + SDL_SetError("XAudio2: capture devices unsupported.");
9.684 + return;
9.685 + } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.686 + SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
9.687 + return;
9.688 + } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
9.689 + SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
9.690 + IXAudio2_Release(ixa2);
9.691 + return;
9.692 + }
9.693 +
9.694 + for (i = 0; i < devcount; i++) {
9.695 + XAUDIO2_DEVICE_DETAILS details;
9.696 + if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
9.697 + char *str = WIN_StringToUTF8(details.DisplayName);
9.698 + if (str != NULL) {
9.699 + addfn(str);
9.700 + SDL_free(str); /* addfn() made a copy of the string. */
9.701 + }
9.702 + }
9.703 + }
9.704 +
9.705 + IXAudio2_Release(ixa2);
9.706 +}
9.707 +
9.708 +static void STDMETHODCALLTYPE
9.709 +VoiceCBOnBufferEnd(THIS_ void *data)
9.710 +{
9.711 + /* Just signal the SDL audio thread and get out of XAudio2's way. */
9.712 + SDL_AudioDevice *this = (SDL_AudioDevice *) data;
9.713 + SDL_SemPost(this->hidden->semaphore);
9.714 +}
9.715 +
9.716 +static void STDMETHODCALLTYPE
9.717 +VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
9.718 +{
9.719 + /* !!! FIXME: attempt to recover, or mark device disconnected. */
9.720 + SDL_assert(0 && "write me!");
9.721 +}
9.722 +
9.723 +/* no-op callbacks... */
9.724 +static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
9.725 +static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
9.726 +static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
9.727 +static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
9.728 +static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
9.729 +
9.730 +
9.731 +static Uint8 *
9.732 +XAUDIO2_GetDeviceBuf(_THIS)
9.733 +{
9.734 + return this->hidden->nextbuf;
9.735 +}
9.736 +
9.737 +static void
9.738 +XAUDIO2_PlayDevice(_THIS)
9.739 +{
9.740 + XAUDIO2_BUFFER buffer;
9.741 + Uint8 *mixbuf = this->hidden->mixbuf;
9.742 + Uint8 *nextbuf = this->hidden->nextbuf;
9.743 + const int mixlen = this->hidden->mixlen;
9.744 + IXAudio2SourceVoice *source = this->hidden->source;
9.745 + HRESULT result = S_OK;
9.746 +
9.747 + if (!this->enabled) { /* shutting down? */
9.748 + return;
9.749 + }
9.750 +
9.751 + /* Submit the next filled buffer */
9.752 + SDL_zero(buffer);
9.753 + buffer.AudioBytes = mixlen;
9.754 + buffer.pAudioData = nextbuf;
9.755 + buffer.pContext = this;
9.756 +
9.757 + if (nextbuf == mixbuf) {
9.758 + nextbuf += mixlen;
9.759 + } else {
9.760 + nextbuf = mixbuf;
9.761 + }
9.762 + this->hidden->nextbuf = nextbuf;
9.763 +
9.764 + result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
9.765 + if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
9.766 + /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
9.767 + }
9.768 +
9.769 + if (result != S_OK) { /* uhoh, panic! */
9.770 + IXAudio2SourceVoice_FlushSourceBuffers(source);
9.771 + this->enabled = 0;
9.772 + }
9.773 +}
9.774 +
9.775 +static void
9.776 +XAUDIO2_WaitDevice(_THIS)
9.777 +{
9.778 + if (this->enabled) {
9.779 + SDL_SemWait(this->hidden->semaphore);
9.780 + }
9.781 +}
9.782 +
9.783 +static void
9.784 +XAUDIO2_WaitDone(_THIS)
9.785 +{
9.786 + IXAudio2SourceVoice *source = this->hidden->source;
9.787 + XAUDIO2_VOICE_STATE state;
9.788 + SDL_assert(!this->enabled); /* flag that stops playing. */
9.789 + IXAudio2SourceVoice_Discontinuity(source);
9.790 +#if SDL_XAUDIO2_WIN8
9.791 + IXAudio2SourceVoice_GetState(source, &state, 0);
9.792 +#else
9.793 + IXAudio2SourceVoice_GetState(source, &state);
9.794 +#endif
9.795 + while (state.BuffersQueued > 0) {
9.796 + SDL_SemWait(this->hidden->semaphore);
9.797 +#if SDL_XAUDIO2_WIN8
9.798 + IXAudio2SourceVoice_GetState(source, &state, 0);
9.799 +#else
9.800 + IXAudio2SourceVoice_GetState(source, &state);
9.801 +#endif
9.802 + }
9.803 +}
9.804 +
9.805 +
9.806 +static void
9.807 +XAUDIO2_CloseDevice(_THIS)
9.808 +{
9.809 + if (this->hidden != NULL) {
9.810 + IXAudio2 *ixa2 = this->hidden->ixa2;
9.811 + IXAudio2SourceVoice *source = this->hidden->source;
9.812 + IXAudio2MasteringVoice *mastering = this->hidden->mastering;
9.813 +
9.814 + if (source != NULL) {
9.815 + IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
9.816 + IXAudio2SourceVoice_FlushSourceBuffers(source);
9.817 + IXAudio2SourceVoice_DestroyVoice(source);
9.818 + }
9.819 + if (ixa2 != NULL) {
9.820 + IXAudio2_StopEngine(ixa2);
9.821 + }
9.822 + if (mastering != NULL) {
9.823 + IXAudio2MasteringVoice_DestroyVoice(mastering);
9.824 + }
9.825 + if (ixa2 != NULL) {
9.826 + IXAudio2_Release(ixa2);
9.827 + }
9.828 + SDL_free(this->hidden->mixbuf);
9.829 + if (this->hidden->semaphore != NULL) {
9.830 + SDL_DestroySemaphore(this->hidden->semaphore);
9.831 + }
9.832 +
9.833 + SDL_free(this->hidden);
9.834 + this->hidden = NULL;
9.835 + }
9.836 +}
9.837 +
9.838 +static int
9.839 +XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
9.840 +{
9.841 + HRESULT result = S_OK;
9.842 + WAVEFORMATEX waveformat;
9.843 + int valid_format = 0;
9.844 + SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
9.845 + IXAudio2 *ixa2 = NULL;
9.846 + IXAudio2SourceVoice *source = NULL;
9.847 +#if defined(SDL_XAUDIO2_WIN8)
9.848 + LPCWSTR devId = NULL;
9.849 +#else
9.850 + UINT32 devId = 0; /* 0 == system default device. */
9.851 +#endif
9.852 +
9.853 + static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
9.854 + VoiceCBOnVoiceProcessPassStart,
9.855 + VoiceCBOnVoiceProcessPassEnd,
9.856 + VoiceCBOnStreamEnd,
9.857 + VoiceCBOnBufferStart,
9.858 + VoiceCBOnBufferEnd,
9.859 + VoiceCBOnLoopEnd,
9.860 + VoiceCBOnVoiceError
9.861 + };
9.862 +
9.863 + static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
9.864 +
9.865 + if (iscapture) {
9.866 + return SDL_SetError("XAudio2: capture devices unsupported.");
9.867 + } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.868 + return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
9.869 + }
9.870 +
9.871 + /*
9.872 + XAUDIO2_DEBUG_CONFIGURATION debugConfig;
9.873 + debugConfig.TraceMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS | XAUDIO2_LOG_DETAIL | XAUDIO2_LOG_FUNC_CALLS | XAUDIO2_LOG_TIMING | XAUDIO2_LOG_LOCKS | XAUDIO2_LOG_MEMORY | XAUDIO2_LOG_STREAMING;
9.874 + debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS;
9.875 + debugConfig.LogThreadID = TRUE;
9.876 + debugConfig.LogFileline = TRUE;
9.877 + debugConfig.LogFunctionName = TRUE;
9.878 + debugConfig.LogTiming = TRUE;
9.879 + ixa2->SetDebugConfiguration(&debugConfig);
9.880 + */
9.881 +
9.882 +#if ! defined(__WINRT__)
9.883 + if (devname != NULL) {
9.884 + UINT32 devcount = 0;
9.885 + UINT32 i = 0;
9.886 +
9.887 + if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
9.888 + IXAudio2_Release(ixa2);
9.889 + return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
9.890 + }
9.891 + for (i = 0; i < devcount; i++) {
9.892 + XAUDIO2_DEVICE_DETAILS details;
9.893 + if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
9.894 + char *str = WIN_StringToUTF8(details.DisplayName);
9.895 + if (str != NULL) {
9.896 + const int match = (SDL_strcmp(str, devname) == 0);
9.897 + SDL_free(str);
9.898 + if (match) {
9.899 + devId = i;
9.900 + break;
9.901 + }
9.902 + }
9.903 + }
9.904 + }
9.905 +
9.906 + if (i == devcount) {
9.907 + IXAudio2_Release(ixa2);
9.908 + return SDL_SetError("XAudio2: Requested device not found.");
9.909 + }
9.910 + }
9.911 +#endif
9.912 +
9.913 + /* Initialize all variables that we clean on shutdown */
9.914 + this->hidden = (struct SDL_PrivateAudioData *)
9.915 + SDL_malloc((sizeof *this->hidden));
9.916 + if (this->hidden == NULL) {
9.917 + IXAudio2_Release(ixa2);
9.918 + return SDL_OutOfMemory();
9.919 + }
9.920 + SDL_memset(this->hidden, 0, (sizeof *this->hidden));
9.921 +
9.922 + this->hidden->ixa2 = ixa2;
9.923 + this->hidden->semaphore = SDL_CreateSemaphore(1);
9.924 + if (this->hidden->semaphore == NULL) {
9.925 + XAUDIO2_CloseDevice(this);
9.926 + return SDL_SetError("XAudio2: CreateSemaphore() failed!");
9.927 + }
9.928 +
9.929 + while ((!valid_format) && (test_format)) {
9.930 + switch (test_format) {
9.931 + case AUDIO_U8:
9.932 + case AUDIO_S16:
9.933 + case AUDIO_S32:
9.934 + case AUDIO_F32:
9.935 + this->spec.format = test_format;
9.936 + valid_format = 1;
9.937 + break;
9.938 + }
9.939 + test_format = SDL_NextAudioFormat();
9.940 + }
9.941 +
9.942 + if (!valid_format) {
9.943 + XAUDIO2_CloseDevice(this);
9.944 + return SDL_SetError("XAudio2: Unsupported audio format");
9.945 + }
9.946 +
9.947 + /* Update the fragment size as size in bytes */
9.948 + SDL_CalculateAudioSpec(&this->spec);
9.949 +
9.950 + /* We feed a Source, it feeds the Mastering, which feeds the device. */
9.951 + this->hidden->mixlen = this->spec.size;
9.952 + this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
9.953 + if (this->hidden->mixbuf == NULL) {
9.954 + XAUDIO2_CloseDevice(this);
9.955 + return SDL_OutOfMemory();
9.956 + }
9.957 + this->hidden->nextbuf = this->hidden->mixbuf;
9.958 + SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
9.959 +
9.960 + /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
9.961 + Xbox360, this means 5.1 output, but on Windows, it means "figure out
9.962 + what the system has." It might be preferable to let XAudio2 blast
9.963 + stereo output to appropriate surround sound configurations
9.964 + instead of clamping to 2 channels, even though we'll configure the
9.965 + Source Voice for whatever number of channels you supply. */
9.966 +#if SDL_XAUDIO2_WIN8
9.967 + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
9.968 + XAUDIO2_DEFAULT_CHANNELS,
9.969 + this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects);
9.970 +#else
9.971 + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
9.972 + XAUDIO2_DEFAULT_CHANNELS,
9.973 + this->spec.freq, 0, devId, NULL);
9.974 +#endif
9.975 + if (result != S_OK) {
9.976 + XAUDIO2_CloseDevice(this);
9.977 + return SDL_SetError("XAudio2: Couldn't create mastering voice");
9.978 + }
9.979 +
9.980 + SDL_zero(waveformat);
9.981 + if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
9.982 + waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
9.983 + } else {
9.984 + waveformat.wFormatTag = WAVE_FORMAT_PCM;
9.985 + }
9.986 + waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
9.987 + waveformat.nChannels = this->spec.channels;
9.988 + waveformat.nSamplesPerSec = this->spec.freq;
9.989 + waveformat.nBlockAlign =
9.990 + waveformat.nChannels * (waveformat.wBitsPerSample / 8);
9.991 + waveformat.nAvgBytesPerSec =
9.992 + waveformat.nSamplesPerSec * waveformat.nBlockAlign;
9.993 + waveformat.cbSize = sizeof(waveformat);
9.994 +
9.995 +#ifdef __WINRT__
9.996 + // DLudwig: for now, make XAudio2 do sample rate conversion, just to
9.997 + // get the loopwave test to work.
9.998 + //
9.999 + // TODO, WinRT: consider removing WinRT-specific source-voice creation code from SDL_xaudio2.c
9.1000 + result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
9.1001 + 0,
9.1002 + 1.0f, &callbacks, NULL, NULL);
9.1003 +#else
9.1004 + result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
9.1005 + XAUDIO2_VOICE_NOSRC |
9.1006 + XAUDIO2_VOICE_NOPITCH,
9.1007 + 1.0f, &callbacks, NULL, NULL);
9.1008 +
9.1009 +#endif
9.1010 + if (result != S_OK) {
9.1011 + XAUDIO2_CloseDevice(this);
9.1012 + return SDL_SetError("XAudio2: Couldn't create source voice");
9.1013 + }
9.1014 + this->hidden->source = source;
9.1015 +
9.1016 + /* Start everything playing! */
9.1017 + result = IXAudio2_StartEngine(ixa2);
9.1018 + if (result != S_OK) {
9.1019 + XAUDIO2_CloseDevice(this);
9.1020 + return SDL_SetError("XAudio2: Couldn't start engine");
9.1021 + }
9.1022 +
9.1023 + result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
9.1024 + if (result != S_OK) {
9.1025 + XAUDIO2_CloseDevice(this);
9.1026 + return SDL_SetError("XAudio2: Couldn't start source voice");
9.1027 + }
9.1028 +
9.1029 + return 0; /* good to go. */
9.1030 +}
9.1031 +
9.1032 +static void
9.1033 +XAUDIO2_Deinitialize(void)
9.1034 +{
9.1035 +#if defined(__WIN32__)
9.1036 + WIN_CoUninitialize();
9.1037 +#endif
9.1038 +}
9.1039 +
9.1040 +#endif /* SDL_XAUDIO2_HAS_SDK */
9.1041 +
9.1042 +
9.1043 +static int
9.1044 +XAUDIO2_Init(SDL_AudioDriverImpl * impl)
9.1045 +{
9.1046 +#ifndef SDL_XAUDIO2_HAS_SDK
9.1047 + SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
9.1048 + return 0; /* no XAudio2 support, ever. Update your SDK! */
9.1049 +#else
9.1050 + /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
9.1051 + IXAudio2 *ixa2 = NULL;
9.1052 +#if defined(__WIN32__)
9.1053 + // TODO, WinRT: Investigate using CoInitializeEx here
9.1054 + if (FAILED(WIN_CoInitialize())) {
9.1055 + SDL_SetError("XAudio2: CoInitialize() failed");
9.1056 + return 0;
9.1057 + }
9.1058 +#endif
9.1059 +
9.1060 + if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
9.1061 +#if defined(__WIN32__)
9.1062 + WIN_CoUninitialize();
9.1063 +#endif
9.1064 + SDL_SetError("XAudio2: XAudio2Create() failed at initialization");
9.1065 + return 0; /* not available. */
9.1066 + }
9.1067 + IXAudio2_Release(ixa2);
9.1068 +
9.1069 + /* Set the function pointers */
9.1070 + impl->DetectDevices = XAUDIO2_DetectDevices;
9.1071 + impl->OpenDevice = XAUDIO2_OpenDevice;
9.1072 + impl->PlayDevice = XAUDIO2_PlayDevice;
9.1073 + impl->WaitDevice = XAUDIO2_WaitDevice;
9.1074 + impl->WaitDone = XAUDIO2_WaitDone;
9.1075 + impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
9.1076 + impl->CloseDevice = XAUDIO2_CloseDevice;
9.1077 + impl->Deinitialize = XAUDIO2_Deinitialize;
9.1078 +
9.1079 + return 1; /* this audio target is available. */
9.1080 +#endif
9.1081 +}
9.1082 +
9.1083 +AudioBootStrap XAUDIO2_bootstrap = {
9.1084 + "xaudio2", "XAudio2", XAUDIO2_Init, 0
9.1085 +};
9.1086 +
9.1087 +#endif /* SDL_AUDIO_DRIVER_XAUDIO2 */
9.1088 +
9.1089 +/* vi: set ts=4 sw=4 expandtab: */
10.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp Tue Mar 04 19:49:11 2014 -0500
10.2 +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp Sun Mar 09 11:06:11 2014 -0700
10.3 @@ -1,69 +1,69 @@
10.4 -
10.5 -#include <xaudio2.h>
10.6 -#include "SDL_xaudio2_winrthelpers.h"
10.7 -
10.8 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
10.9 -using Windows::Devices::Enumeration::DeviceClass;
10.10 -using Windows::Devices::Enumeration::DeviceInformation;
10.11 -using Windows::Devices::Enumeration::DeviceInformationCollection;
10.12 -#endif
10.13 -
10.14 -extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
10.15 -{
10.16 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
10.17 - // There doesn't seem to be any audio device enumeration on Windows Phone.
10.18 - // In lieu of this, just treat things as if there is one and only one
10.19 - // audio device.
10.20 - *devcount = 1;
10.21 - return S_OK;
10.22 -#else
10.23 - // TODO, WinRT: make xaudio2 device enumeration only happen once, and in the background
10.24 - auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
10.25 - while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
10.26 - {
10.27 - }
10.28 -
10.29 - DeviceInformationCollection^ devices = operation->GetResults();
10.30 - *devcount = devices->Size;
10.31 - return S_OK;
10.32 -#endif
10.33 -}
10.34 -
10.35 -extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
10.36 -{
10.37 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
10.38 - // Windows Phone doesn't seem to have the same device enumeration APIs that
10.39 - // Windows 8/RT has, or it doesn't have them at all. In lieu of this,
10.40 - // just treat things as if there is one, and only one, default device.
10.41 - if (index != 0)
10.42 - {
10.43 - return XAUDIO2_E_INVALID_CALL;
10.44 - }
10.45 -
10.46 - if (details)
10.47 - {
10.48 - wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), L"default", _TRUNCATE);
10.49 - wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), L"default", _TRUNCATE);
10.50 - }
10.51 - return S_OK;
10.52 -#else
10.53 - auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
10.54 - while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
10.55 - {
10.56 - }
10.57 -
10.58 - DeviceInformationCollection^ devices = operation->GetResults();
10.59 - if (index >= devices->Size)
10.60 - {
10.61 - return XAUDIO2_E_INVALID_CALL;
10.62 - }
10.63 -
10.64 - DeviceInformation^ d = devices->GetAt(index);
10.65 - if (details)
10.66 - {
10.67 - wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), d->Id->Data(), _TRUNCATE);
10.68 - wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), d->Name->Data(), _TRUNCATE);
10.69 - }
10.70 - return S_OK;
10.71 -#endif
10.72 -}
10.73 +
10.74 +#include <xaudio2.h>
10.75 +#include "SDL_xaudio2_winrthelpers.h"
10.76 +
10.77 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
10.78 +using Windows::Devices::Enumeration::DeviceClass;
10.79 +using Windows::Devices::Enumeration::DeviceInformation;
10.80 +using Windows::Devices::Enumeration::DeviceInformationCollection;
10.81 +#endif
10.82 +
10.83 +extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
10.84 +{
10.85 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
10.86 + // There doesn't seem to be any audio device enumeration on Windows Phone.
10.87 + // In lieu of this, just treat things as if there is one and only one
10.88 + // audio device.
10.89 + *devcount = 1;
10.90 + return S_OK;
10.91 +#else
10.92 + // TODO, WinRT: make xaudio2 device enumeration only happen once, and in the background
10.93 + auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
10.94 + while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
10.95 + {
10.96 + }
10.97 +
10.98 + DeviceInformationCollection^ devices = operation->GetResults();
10.99 + *devcount = devices->Size;
10.100 + return S_OK;
10.101 +#endif
10.102 +}
10.103 +
10.104 +extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
10.105 +{
10.106 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
10.107 + // Windows Phone doesn't seem to have the same device enumeration APIs that
10.108 + // Windows 8/RT has, or it doesn't have them at all. In lieu of this,
10.109 + // just treat things as if there is one, and only one, default device.
10.110 + if (index != 0)
10.111 + {
10.112 + return XAUDIO2_E_INVALID_CALL;
10.113 + }
10.114 +
10.115 + if (details)
10.116 + {
10.117 + wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), L"default", _TRUNCATE);
10.118 + wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), L"default", _TRUNCATE);
10.119 + }
10.120 + return S_OK;
10.121 +#else
10.122 + auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
10.123 + while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
10.124 + {
10.125 + }
10.126 +
10.127 + DeviceInformationCollection^ devices = operation->GetResults();
10.128 + if (index >= devices->Size)
10.129 + {
10.130 + return XAUDIO2_E_INVALID_CALL;
10.131 + }
10.132 +
10.133 + DeviceInformation^ d = devices->GetAt(index);
10.134 + if (details)
10.135 + {
10.136 + wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), d->Id->Data(), _TRUNCATE);
10.137 + wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), d->Name->Data(), _TRUNCATE);
10.138 + }
10.139 + return S_OK;
10.140 +#endif
10.141 +}
11.1 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h Tue Mar 04 19:49:11 2014 -0500
11.2 +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h Sun Mar 09 11:06:11 2014 -0700
11.3 @@ -1,52 +1,52 @@
11.4 -
11.5 -#pragma once
11.6 -
11.7 -//
11.8 -// Re-implementation of methods removed from XAudio2 (in WinRT):
11.9 -//
11.10 -
11.11 -typedef struct XAUDIO2_DEVICE_DETAILS
11.12 -{
11.13 - WCHAR DeviceID[256];
11.14 - WCHAR DisplayName[256];
11.15 - /* Other fields exist in the pre-Windows 8 version of this struct, however
11.16 - they weren't used by SDL, so they weren't added.
11.17 - */
11.18 -} XAUDIO2_DEVICE_DETAILS;
11.19 -
11.20 -
11.21 -#ifdef __cplusplus
11.22 -extern "C" {
11.23 -#endif
11.24 -
11.25 -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
11.26 -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
11.27 -
11.28 -#ifdef __cplusplus
11.29 -}
11.30 -#endif
11.31 -
11.32 -
11.33 -//
11.34 -// C-style macros to call XAudio2's methods in C++:
11.35 -//
11.36 -#ifdef __cplusplus
11.37 -/*
11.38 -#define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
11.39 -#define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
11.40 -#define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
11.41 -#define IXAudio2_Release(A) (A)->Release()
11.42 -#define IXAudio2_StartEngine(A) (A)->StartEngine()
11.43 -#define IXAudio2_StopEngine(A) (A)->StopEngine()
11.44 -
11.45 -#define IXAudio2MasteringVoice_DestroyVoice(A) (A)->DestroyVoice()
11.46 -
11.47 -#define IXAudio2SourceVoice_DestroyVoice(A) (A)->DestroyVoice()
11.48 -#define IXAudio2SourceVoice_Discontinuity(A) (A)->Discontinuity()
11.49 -#define IXAudio2SourceVoice_FlushSourceBuffers(A) (A)->FlushSourceBuffers()
11.50 -#define IXAudio2SourceVoice_GetState(A, B) (A)->GetState((B))
11.51 -#define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
11.52 -#define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
11.53 -#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
11.54 -*/
11.55 -#endif // ifdef __cplusplus
11.56 +
11.57 +#pragma once
11.58 +
11.59 +//
11.60 +// Re-implementation of methods removed from XAudio2 (in WinRT):
11.61 +//
11.62 +
11.63 +typedef struct XAUDIO2_DEVICE_DETAILS
11.64 +{
11.65 + WCHAR DeviceID[256];
11.66 + WCHAR DisplayName[256];
11.67 + /* Other fields exist in the pre-Windows 8 version of this struct, however
11.68 + they weren't used by SDL, so they weren't added.
11.69 + */
11.70 +} XAUDIO2_DEVICE_DETAILS;
11.71 +
11.72 +
11.73 +#ifdef __cplusplus
11.74 +extern "C" {
11.75 +#endif
11.76 +
11.77 +HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
11.78 +HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
11.79 +
11.80 +#ifdef __cplusplus
11.81 +}
11.82 +#endif
11.83 +
11.84 +
11.85 +//
11.86 +// C-style macros to call XAudio2's methods in C++:
11.87 +//
11.88 +#ifdef __cplusplus
11.89 +/*
11.90 +#define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
11.91 +#define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
11.92 +#define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
11.93 +#define IXAudio2_Release(A) (A)->Release()
11.94 +#define IXAudio2_StartEngine(A) (A)->StartEngine()
11.95 +#define IXAudio2_StopEngine(A) (A)->StopEngine()
11.96 +
11.97 +#define IXAudio2MasteringVoice_DestroyVoice(A) (A)->DestroyVoice()
11.98 +
11.99 +#define IXAudio2SourceVoice_DestroyVoice(A) (A)->DestroyVoice()
11.100 +#define IXAudio2SourceVoice_Discontinuity(A) (A)->Discontinuity()
11.101 +#define IXAudio2SourceVoice_FlushSourceBuffers(A) (A)->FlushSourceBuffers()
11.102 +#define IXAudio2SourceVoice_GetState(A, B) (A)->GetState((B))
11.103 +#define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
11.104 +#define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
11.105 +#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))
11.106 +*/
11.107 +#endif // ifdef __cplusplus
12.1 --- a/src/core/winrt/SDL_winrtapp_common.cpp Tue Mar 04 19:49:11 2014 -0500
12.2 +++ b/src/core/winrt/SDL_winrtapp_common.cpp Sun Mar 09 11:06:11 2014 -0700
12.3 @@ -1,16 +1,16 @@
12.4 -
12.5 -#include <SDL_system.h>
12.6 -#include "SDL_winrtapp_direct3d.h"
12.7 -#include "SDL_winrtapp_xaml.h"
12.8 -
12.9 -int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL;
12.10 -
12.11 +
12.12 +#include <SDL_system.h>
12.13 +#include "SDL_winrtapp_direct3d.h"
12.14 +#include "SDL_winrtapp_xaml.h"
12.15 +
12.16 +int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL;
12.17 +
12.18 extern "C" DECLSPEC int
12.19 -SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel)
12.20 -{
12.21 - if (xamlBackgroundPanel) {
12.22 - return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel);
12.23 - } else {
12.24 - return SDL_WinRTInitNonXAMLApp(mainFunction);
12.25 - }
12.26 -}
12.27 +SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel)
12.28 +{
12.29 + if (xamlBackgroundPanel) {
12.30 + return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel);
12.31 + } else {
12.32 + return SDL_WinRTInitNonXAMLApp(mainFunction);
12.33 + }
12.34 +}
13.1 --- a/src/core/winrt/SDL_winrtapp_common.h Tue Mar 04 19:49:11 2014 -0500
13.2 +++ b/src/core/winrt/SDL_winrtapp_common.h Sun Mar 09 11:06:11 2014 -0700
13.3 @@ -19,13 +19,13 @@
13.4 3. This notice may not be removed or altered from any source distribution.
13.5 */
13.6 #include "SDL_config.h"
13.7 -
13.8 +
13.9 #ifndef _SDL_winrtapp_common_h
13.10 -#define _SDL_winrtapp_common_h
13.11 -
13.12 -/* A pointer to the app's C-style main() function (which is a different
13.13 - function than the WinRT app's actual entry point).
13.14 - */
13.15 -extern int (*WINRT_SDLAppEntryPoint)(int, char **);
13.16 -
13.17 -#endif // ifndef _SDL_winrtapp_common_h
13.18 +#define _SDL_winrtapp_common_h
13.19 +
13.20 +/* A pointer to the app's C-style main() function (which is a different
13.21 + function than the WinRT app's actual entry point).
13.22 + */
13.23 +extern int (*WINRT_SDLAppEntryPoint)(int, char **);
13.24 +
13.25 +#endif // ifndef _SDL_winrtapp_common_h
14.1 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp Tue Mar 04 19:49:11 2014 -0500
14.2 +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp Sun Mar 09 11:06:11 2014 -0700
14.3 @@ -1,668 +1,668 @@
14.4 -
14.5 -/* Standard C++11 includes */
14.6 -#include <functional>
14.7 -#include <string>
14.8 -#include <sstream>
14.9 -using namespace std;
14.10 -
14.11 -
14.12 -/* Windows includes */
14.13 -#include "ppltasks.h"
14.14 -using namespace concurrency;
14.15 -using namespace Windows::ApplicationModel;
14.16 -using namespace Windows::ApplicationModel::Core;
14.17 -using namespace Windows::ApplicationModel::Activation;
14.18 -using namespace Windows::Devices::Input;
14.19 -using namespace Windows::Graphics::Display;
14.20 -using namespace Windows::Foundation;
14.21 -using namespace Windows::System;
14.22 -using namespace Windows::UI::Core;
14.23 -using namespace Windows::UI::Input;
14.24 -
14.25 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.26 -using namespace Windows::Phone::UI::Input;
14.27 -#endif
14.28 -
14.29 -
14.30 -/* SDL includes */
14.31 -extern "C" {
14.32 -#include "SDL_assert.h"
14.33 -#include "SDL_events.h"
14.34 -#include "SDL_hints.h"
14.35 -#include "SDL_log.h"
14.36 -#include "SDL_main.h"
14.37 -#include "SDL_stdinc.h"
14.38 -#include "SDL_render.h"
14.39 -#include "../../video/SDL_sysvideo.h"
14.40 -//#include "../../SDL_hints_c.h"
14.41 -#include "../../events/SDL_events_c.h"
14.42 -#include "../../events/SDL_keyboard_c.h"
14.43 -#include "../../events/SDL_mouse_c.h"
14.44 -#include "../../events/SDL_windowevents_c.h"
14.45 -#include "../../render/SDL_sysrender.h"
14.46 -#include "../windows/SDL_windows.h"
14.47 -}
14.48 -
14.49 -#include "../../video/winrt/SDL_winrtevents_c.h"
14.50 -#include "../../video/winrt/SDL_winrtvideo_cpp.h"
14.51 -#include "SDL_winrtapp_common.h"
14.52 -#include "SDL_winrtapp_direct3d.h"
14.53 -
14.54 -
14.55 -// Compile-time debugging options:
14.56 -// To enable, uncomment; to disable, comment them out.
14.57 -//#define LOG_POINTER_EVENTS 1
14.58 -//#define LOG_WINDOW_EVENTS 1
14.59 -//#define LOG_ORIENTATION_EVENTS 1
14.60 -
14.61 -
14.62 -// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
14.63 -// SDL/WinRT will use this throughout its code.
14.64 -//
14.65 -// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
14.66 -// non-global, such as something created inside
14.67 -// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
14.68 -// SDL_CreateWindow().
14.69 -SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
14.70 -
14.71 -ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
14.72 -{
14.73 -public:
14.74 - virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
14.75 -};
14.76 -
14.77 -IFrameworkView^ SDLApplicationSource::CreateView()
14.78 -{
14.79 - // TODO, WinRT: see if this function (CreateView) can ever get called
14.80 - // more than once. For now, just prevent it from ever assigning
14.81 - // SDL_WinRTGlobalApp more than once.
14.82 - SDL_assert(!SDL_WinRTGlobalApp);
14.83 - SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
14.84 - if (!SDL_WinRTGlobalApp)
14.85 - {
14.86 - SDL_WinRTGlobalApp = app;
14.87 - }
14.88 - return app;
14.89 -}
14.90 -
14.91 -int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
14.92 -{
14.93 - WINRT_SDLAppEntryPoint = mainFunction;
14.94 - auto direct3DApplicationSource = ref new SDLApplicationSource();
14.95 - CoreApplication::Run(direct3DApplicationSource);
14.96 - return 0;
14.97 -}
14.98 -
14.99 -static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
14.100 -{
14.101 - SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
14.102 -
14.103 - // Start with no orientation flags, then add each in as they're parsed
14.104 - // from newValue.
14.105 - unsigned int orientationFlags = 0;
14.106 - if (newValue) {
14.107 - std::istringstream tokenizer(newValue);
14.108 - while (!tokenizer.eof()) {
14.109 - std::string orientationName;
14.110 - std::getline(tokenizer, orientationName, ' ');
14.111 - if (orientationName == "LandscapeLeft") {
14.112 - orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
14.113 - } else if (orientationName == "LandscapeRight") {
14.114 - orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
14.115 - } else if (orientationName == "Portrait") {
14.116 - orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
14.117 - } else if (orientationName == "PortraitUpsideDown") {
14.118 - orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
14.119 - }
14.120 - }
14.121 - }
14.122 -
14.123 - // If no valid orientation flags were specified, use a reasonable set of defaults:
14.124 - if (!orientationFlags) {
14.125 - // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
14.126 - orientationFlags = (unsigned int) ( \
14.127 - DisplayOrientations::Landscape |
14.128 - DisplayOrientations::LandscapeFlipped |
14.129 - DisplayOrientations::Portrait |
14.130 - DisplayOrientations::PortraitFlipped);
14.131 - }
14.132 -
14.133 - // Set the orientation/rotation preferences. Please note that this does
14.134 - // not constitute a 100%-certain lock of a given set of possible
14.135 - // orientations. According to Microsoft's documentation on WinRT [1]
14.136 - // when a device is not capable of being rotated, Windows may ignore
14.137 - // the orientation preferences, and stick to what the device is capable of
14.138 - // displaying.
14.139 - //
14.140 - // [1] Documentation on the 'InitialRotationPreference' setting for a
14.141 - // Windows app's manifest file describes how some orientation/rotation
14.142 - // preferences may be ignored. See
14.143 - // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
14.144 - // for details. Microsoft's "Display orientation sample" also gives an
14.145 - // outline of how Windows treats device rotation
14.146 - // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
14.147 - DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
14.148 -}
14.149 -
14.150 -static void
14.151 -WINRT_ProcessWindowSizeChange()
14.152 -{
14.153 - // Make the new window size be the one true fullscreen mode.
14.154 - // This change was initially done, in part, to allow the Direct3D 11.1
14.155 - // renderer to receive window-resize events as a device rotates.
14.156 - // Before, rotating a device from landscape, to portrait, and then
14.157 - // back to landscape would cause the Direct3D 11.1 swap buffer to
14.158 - // not get resized appropriately. SDL would, on the rotation from
14.159 - // landscape to portrait, re-resize the SDL window to it's initial
14.160 - // size (landscape). On the subsequent rotation, SDL would drop the
14.161 - // window-resize event as it appeared the SDL window didn't change
14.162 - // size, and the Direct3D 11.1 renderer wouldn't resize its swap
14.163 - // chain.
14.164 - SDL_DisplayMode newDisplayMode;
14.165 - if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
14.166 - return;
14.167 - }
14.168 -
14.169 - // Make note of the old display mode, and it's old driverdata.
14.170 - SDL_DisplayMode oldDisplayMode;
14.171 - SDL_zero(oldDisplayMode);
14.172 - if (WINRT_GlobalSDLVideoDevice) {
14.173 - oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
14.174 - }
14.175 -
14.176 - // Setup the new display mode in the appropriate spots.
14.177 - if (WINRT_GlobalSDLVideoDevice) {
14.178 - // Make a full copy of the display mode for display_modes[0],
14.179 - // one with with a separately malloced 'driverdata' field.
14.180 - // SDL_VideoQuit(), if called, will attempt to free the driverdata
14.181 - // fields in 'desktop_mode' and each entry in the 'display_modes'
14.182 - // array.
14.183 - if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
14.184 - // Free the previous mode's memory
14.185 - SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
14.186 - WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
14.187 - }
14.188 - if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
14.189 - // Uh oh, something went wrong. A malloc call probably failed.
14.190 - SDL_free(newDisplayMode.driverdata);
14.191 - return;
14.192 - }
14.193 -
14.194 - // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
14.195 - WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
14.196 - WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
14.197 - }
14.198 -
14.199 - if (WINRT_GlobalSDLWindow) {
14.200 - // Send a window-resize event to the rest of SDL, and to apps:
14.201 - SDL_SendWindowEvent(
14.202 - WINRT_GlobalSDLWindow,
14.203 - SDL_WINDOWEVENT_RESIZED,
14.204 - newDisplayMode.w,
14.205 - newDisplayMode.h);
14.206 -
14.207 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.208 - // HACK: On Windows Phone, make sure that orientation changes from
14.209 - // Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
14.210 - // or vice-versa on either of those two, lead to the Direct3D renderer
14.211 - // getting updated.
14.212 - const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
14.213 - const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
14.214 -
14.215 - if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
14.216 - (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
14.217 - (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
14.218 - (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
14.219 - {
14.220 - // One of the reasons this event is getting sent out is because SDL
14.221 - // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
14.222 - // if and when the event size doesn't change (and the Direct3D 11.1
14.223 - // renderer doesn't get the memo).
14.224 - //
14.225 - // Make sure that the display/window size really didn't change. If
14.226 - // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
14.227 - // the Direct3D 11.1 renderer picked it up, presumably.
14.228 - if (oldDisplayMode.w == newDisplayMode.w &&
14.229 - oldDisplayMode.h == newDisplayMode.h)
14.230 - {
14.231 - SDL_SendWindowEvent(
14.232 - WINRT_GlobalSDLWindow,
14.233 - SDL_WINDOWEVENT_SIZE_CHANGED,
14.234 - newDisplayMode.w,
14.235 - newDisplayMode.h);
14.236 - }
14.237 - }
14.238 -#endif
14.239 - }
14.240 -
14.241 - // Finally, free the 'driverdata' field of the old 'desktop_mode'.
14.242 - if (oldDisplayMode.driverdata) {
14.243 - SDL_free(oldDisplayMode.driverdata);
14.244 - oldDisplayMode.driverdata = NULL;
14.245 - }
14.246 -}
14.247 -
14.248 -SDL_WinRTApp::SDL_WinRTApp() :
14.249 - m_windowClosed(false),
14.250 - m_windowVisible(true)
14.251 -{
14.252 -}
14.253 -
14.254 -void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
14.255 -{
14.256 - applicationView->Activated +=
14.257 - ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
14.258 -
14.259 - CoreApplication::Suspending +=
14.260 - ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
14.261 -
14.262 - CoreApplication::Resuming +=
14.263 - ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
14.264 -
14.265 - CoreApplication::Exiting +=
14.266 - ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
14.267 -
14.268 - DisplayProperties::OrientationChanged +=
14.269 - ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
14.270 -
14.271 - // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. This needs to be
14.272 - // done before the hint's callback is registered (as of Feb 22, 2013),
14.273 - // otherwise the hint callback won't get registered.
14.274 - //
14.275 - // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
14.276 - //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback)
14.277 - SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
14.278 -}
14.279 -
14.280 -void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
14.281 -{
14.282 -#if LOG_ORIENTATION_EVENTS==1
14.283 - CoreWindow^ window = CoreWindow::GetForCurrentThread();
14.284 - if (window) {
14.285 - SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
14.286 - __FUNCTION__,
14.287 - (int)DisplayProperties::CurrentOrientation,
14.288 - (int)DisplayProperties::NativeOrientation,
14.289 - (int)DisplayProperties::AutoRotationPreferences,
14.290 - window->Bounds.Width,
14.291 - window->Bounds.Height);
14.292 - } else {
14.293 - SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
14.294 - __FUNCTION__,
14.295 - (int)DisplayProperties::CurrentOrientation,
14.296 - (int)DisplayProperties::NativeOrientation,
14.297 - (int)DisplayProperties::AutoRotationPreferences);
14.298 - }
14.299 -#endif
14.300 -
14.301 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.302 - // On Windows Phone, treat an orientation change as a change in window size.
14.303 - // The native window's size doesn't seem to change, however SDL will simulate
14.304 - // a window size change.
14.305 - WINRT_ProcessWindowSizeChange();
14.306 -#endif
14.307 -}
14.308 -
14.309 -void SDL_WinRTApp::SetWindow(CoreWindow^ window)
14.310 -{
14.311 -#if LOG_WINDOW_EVENTS==1
14.312 - SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
14.313 - __FUNCTION__,
14.314 - (int)DisplayProperties::CurrentOrientation,
14.315 - (int)DisplayProperties::NativeOrientation,
14.316 - (int)DisplayProperties::AutoRotationPreferences,
14.317 - window->Bounds.Width,
14.318 - window->Bounds.Height);
14.319 -#endif
14.320 -
14.321 - window->SizeChanged +=
14.322 - ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
14.323 -
14.324 - window->VisibilityChanged +=
14.325 - ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
14.326 -
14.327 - window->Closed +=
14.328 - ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
14.329 -
14.330 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
14.331 - window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
14.332 -#endif
14.333 -
14.334 - window->PointerPressed +=
14.335 - ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
14.336 -
14.337 - window->PointerMoved +=
14.338 - ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
14.339 -
14.340 - window->PointerReleased +=
14.341 - ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
14.342 -
14.343 - window->PointerWheelChanged +=
14.344 - ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
14.345 -
14.346 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
14.347 - // Retrieves relative-only mouse movements:
14.348 - Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
14.349 - ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
14.350 -#endif
14.351 -
14.352 - window->KeyDown +=
14.353 - ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
14.354 -
14.355 - window->KeyUp +=
14.356 - ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
14.357 -
14.358 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.359 - HardwareButtons::BackPressed +=
14.360 - ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
14.361 -#endif
14.362 -
14.363 -#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps)
14.364 - // Make sure we know when a user has opened the app's settings pane.
14.365 - // This is needed in order to display a privacy policy, which needs
14.366 - // to be done for network-enabled apps, as per Windows Store requirements.
14.367 - using namespace Windows::UI::ApplicationSettings;
14.368 - SettingsPane::GetForCurrentView()->CommandsRequested +=
14.369 - ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
14.370 - (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
14.371 -#endif
14.372 -}
14.373 -
14.374 -void SDL_WinRTApp::Load(Platform::String^ entryPoint)
14.375 -{
14.376 -}
14.377 -
14.378 -void SDL_WinRTApp::Run()
14.379 -{
14.380 - SDL_SetMainReady();
14.381 - if (WINRT_SDLAppEntryPoint)
14.382 - {
14.383 - // TODO, WinRT: pass the C-style main() a reasonably realistic
14.384 - // representation of command line arguments.
14.385 - int argc = 0;
14.386 - char **argv = NULL;
14.387 - WINRT_SDLAppEntryPoint(argc, argv);
14.388 - }
14.389 -}
14.390 -
14.391 -void SDL_WinRTApp::PumpEvents()
14.392 -{
14.393 - if (!m_windowClosed)
14.394 - {
14.395 - if (m_windowVisible)
14.396 - {
14.397 - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
14.398 - }
14.399 - else
14.400 - {
14.401 - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
14.402 - }
14.403 - }
14.404 -}
14.405 -
14.406 -void SDL_WinRTApp::Uninitialize()
14.407 -{
14.408 -}
14.409 -
14.410 -#if WINAPI_FAMILY == WINAPI_FAMILY_APP
14.411 -void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
14.412 - Windows::UI::ApplicationSettings::SettingsPane ^p,
14.413 - Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
14.414 -{
14.415 - using namespace Platform;
14.416 - using namespace Windows::UI::ApplicationSettings;
14.417 - using namespace Windows::UI::Popups;
14.418 -
14.419 - String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy
14.420 - String ^privacyPolicyLabel = nullptr; // label/link text
14.421 - const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately
14.422 - wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion
14.423 -
14.424 - // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
14.425 - tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
14.426 - if (tmpHintValue && tmpHintValue[0] != '\0') {
14.427 - // Convert the privacy policy's URL to UCS2:
14.428 - tmpStr = WIN_UTF8ToString(tmpHintValue);
14.429 - privacyPolicyURL = ref new String(tmpStr);
14.430 - SDL_free(tmpStr);
14.431 -
14.432 - // Optionally retrieve custom label-text for the link. If this isn't
14.433 - // available, a default value will be used instead.
14.434 - tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
14.435 - if (tmpHintValue && tmpHintValue[0] != '\0') {
14.436 - tmpStr = WIN_UTF8ToString(tmpHintValue);
14.437 - privacyPolicyLabel = ref new String(tmpStr);
14.438 - SDL_free(tmpStr);
14.439 - } else {
14.440 - privacyPolicyLabel = ref new String(L"Privacy Policy");
14.441 - }
14.442 -
14.443 - // Register the link, along with a handler to be called if and when it is
14.444 - // clicked:
14.445 - auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
14.446 - ref new UICommandInvokedHandler([=](IUICommand ^) {
14.447 - Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
14.448 - }));
14.449 - args->Request->ApplicationCommands->Append(cmd);
14.450 - }
14.451 -}
14.452 -#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
14.453 -
14.454 -void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
14.455 -{
14.456 -#if LOG_WINDOW_EVENTS==1
14.457 - SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
14.458 - __FUNCTION__,
14.459 - args->Size.Width, args->Size.Height,
14.460 - (int)DisplayProperties::CurrentOrientation,
14.461 - (int)DisplayProperties::NativeOrientation,
14.462 - (int)DisplayProperties::AutoRotationPreferences,
14.463 - (WINRT_GlobalSDLWindow ? "yes" : "no"));
14.464 -#endif
14.465 -
14.466 - WINRT_ProcessWindowSizeChange();
14.467 -}
14.468 -
14.469 -void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
14.470 -{
14.471 -#if LOG_WINDOW_EVENTS==1
14.472 - SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n",
14.473 - __FUNCTION__,
14.474 - (args->Visible ? "yes" : "no"),
14.475 - (WINRT_GlobalSDLWindow ? "yes" : "no"));
14.476 -#endif
14.477 -
14.478 - m_windowVisible = args->Visible;
14.479 - if (WINRT_GlobalSDLWindow) {
14.480 - SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
14.481 -
14.482 - if (args->Visible) {
14.483 - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
14.484 - } else {
14.485 - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
14.486 - }
14.487 -
14.488 - // HACK: Prevent SDL's window-hide handling code, which currently
14.489 - // triggers a fake window resize (possibly erronously), from
14.490 - // marking the SDL window's surface as invalid.
14.491 - //
14.492 - // A better solution to this probably involves figuring out if the
14.493 - // fake window resize can be prevented.
14.494 - WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
14.495 - }
14.496 -}
14.497 -
14.498 -void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
14.499 -{
14.500 -#if LOG_WINDOW_EVENTS==1
14.501 - SDL_Log("%s\n", __FUNCTION__);
14.502 -#endif
14.503 - m_windowClosed = true;
14.504 -}
14.505 -
14.506 -void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
14.507 -{
14.508 - CoreWindow::GetForCurrentThread()->Activate();
14.509 -}
14.510 -
14.511 -static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
14.512 -{
14.513 - if (event->type == SDL_WINDOWEVENT)
14.514 - {
14.515 - switch (event->window.event)
14.516 - {
14.517 - case SDL_WINDOWEVENT_MINIMIZED:
14.518 - case SDL_WINDOWEVENT_RESTORED:
14.519 - // Return 0 to indicate that the event should be removed from the
14.520 - // event queue:
14.521 - return 0;
14.522 - default:
14.523 - break;
14.524 - }
14.525 - }
14.526 -
14.527 - // Return 1 to indicate that the event should stay in the event queue:
14.528 - return 1;
14.529 -}
14.530 -
14.531 -void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
14.532 -{
14.533 - // Save app state asynchronously after requesting a deferral. Holding a deferral
14.534 - // indicates that the application is busy performing suspending operations. Be
14.535 - // aware that a deferral may not be held indefinitely. After about five seconds,
14.536 - // the app will be forced to exit.
14.537 - SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
14.538 - create_task([this, deferral]()
14.539 - {
14.540 - // Send a window-minimized event immediately to observers.
14.541 - // CoreDispatcher::ProcessEvents, which is the backbone on which
14.542 - // SDL_WinRTApp::PumpEvents is built, will not return to its caller
14.543 - // once it sends out a suspend event. Any events posted to SDL's
14.544 - // event queue won't get received until the WinRT app is resumed.
14.545 - // SDL_AddEventWatch() may be used to receive app-suspend events on
14.546 - // WinRT.
14.547 - //
14.548 - // In order to prevent app-suspend events from being received twice:
14.549 - // first via a callback passed to SDL_AddEventWatch, and second via
14.550 - // SDL's event queue, the event will be sent to SDL, then immediately
14.551 - // removed from the queue.
14.552 - if (WINRT_GlobalSDLWindow)
14.553 - {
14.554 - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
14.555 - SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
14.556 - }
14.557 -
14.558 - SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
14.559 - SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
14.560 -
14.561 - deferral->Complete();
14.562 - });
14.563 -}
14.564 -
14.565 -void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
14.566 -{
14.567 - SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
14.568 - SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
14.569 -
14.570 - // Restore any data or state that was unloaded on suspend. By default, data
14.571 - // and state are persisted when resuming from suspend. Note that this event
14.572 - // does not occur if the app was previously terminated.
14.573 - if (WINRT_GlobalSDLWindow)
14.574 - {
14.575 - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
14.576 -
14.577 - // Remove the app-resume event from the queue, as is done with the
14.578 - // app-suspend event.
14.579 - //
14.580 - // TODO, WinRT: consider posting this event to the queue even though
14.581 - // its counterpart, the app-suspend event, effectively has to be
14.582 - // processed immediately.
14.583 - SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
14.584 - }
14.585 -}
14.586 -
14.587 -void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
14.588 -{
14.589 - SDL_SendAppEvent(SDL_APP_TERMINATING);
14.590 -}
14.591 -
14.592 -static void
14.593 -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
14.594 -{
14.595 - Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
14.596 - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
14.597 - header,
14.598 - pt->Position.X, pt->Position.Y,
14.599 - transformedPoint.X, transformedPoint.Y,
14.600 - pt->Properties->MouseWheelDelta,
14.601 - pt->FrameId,
14.602 - pt->PointerId,
14.603 - WINRT_GetSDLButtonForPointerPoint(pt));
14.604 -}
14.605 -
14.606 -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
14.607 -{
14.608 -#if LOG_POINTER_EVENTS
14.609 - WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.610 -#endif
14.611 -
14.612 - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.613 -}
14.614 -
14.615 -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
14.616 -{
14.617 -#if LOG_POINTER_EVENTS
14.618 - WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.619 -#endif
14.620 -
14.621 - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.622 -}
14.623 -
14.624 -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
14.625 -{
14.626 -#if LOG_POINTER_EVENTS
14.627 - WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.628 -#endif
14.629 -
14.630 - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.631 -}
14.632 -
14.633 -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
14.634 -{
14.635 -#if LOG_POINTER_EVENTS
14.636 - WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.637 -#endif
14.638 -
14.639 - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.640 -}
14.641 -
14.642 -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
14.643 -{
14.644 - WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
14.645 -}
14.646 -
14.647 -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
14.648 -{
14.649 - WINRT_ProcessKeyDownEvent(args);
14.650 -}
14.651 -
14.652 -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
14.653 -{
14.654 - WINRT_ProcessKeyUpEvent(args);
14.655 -}
14.656 -
14.657 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.658 -void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
14.659 -{
14.660 - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
14.661 - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
14.662 -
14.663 +
14.664 +/* Standard C++11 includes */
14.665 +#include <functional>
14.666 +#include <string>
14.667 +#include <sstream>
14.668 +using namespace std;
14.669 +
14.670 +
14.671 +/* Windows includes */
14.672 +#include "ppltasks.h"
14.673 +using namespace concurrency;
14.674 +using namespace Windows::ApplicationModel;
14.675 +using namespace Windows::ApplicationModel::Core;
14.676 +using namespace Windows::ApplicationModel::Activation;
14.677 +using namespace Windows::Devices::Input;
14.678 +using namespace Windows::Graphics::Display;
14.679 +using namespace Windows::Foundation;
14.680 +using namespace Windows::System;
14.681 +using namespace Windows::UI::Core;
14.682 +using namespace Windows::UI::Input;
14.683 +
14.684 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.685 +using namespace Windows::Phone::UI::Input;
14.686 +#endif
14.687 +
14.688 +
14.689 +/* SDL includes */
14.690 +extern "C" {
14.691 +#include "SDL_assert.h"
14.692 +#include "SDL_events.h"
14.693 +#include "SDL_hints.h"
14.694 +#include "SDL_log.h"
14.695 +#include "SDL_main.h"
14.696 +#include "SDL_stdinc.h"
14.697 +#include "SDL_render.h"
14.698 +#include "../../video/SDL_sysvideo.h"
14.699 +//#include "../../SDL_hints_c.h"
14.700 +#include "../../events/SDL_events_c.h"
14.701 +#include "../../events/SDL_keyboard_c.h"
14.702 +#include "../../events/SDL_mouse_c.h"
14.703 +#include "../../events/SDL_windowevents_c.h"
14.704 +#include "../../render/SDL_sysrender.h"
14.705 +#include "../windows/SDL_windows.h"
14.706 +}
14.707 +
14.708 +#include "../../video/winrt/SDL_winrtevents_c.h"
14.709 +#include "../../video/winrt/SDL_winrtvideo_cpp.h"
14.710 +#include "SDL_winrtapp_common.h"
14.711 +#include "SDL_winrtapp_direct3d.h"
14.712 +
14.713 +
14.714 +// Compile-time debugging options:
14.715 +// To enable, uncomment; to disable, comment them out.
14.716 +//#define LOG_POINTER_EVENTS 1
14.717 +//#define LOG_WINDOW_EVENTS 1
14.718 +//#define LOG_ORIENTATION_EVENTS 1
14.719 +
14.720 +
14.721 +// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
14.722 +// SDL/WinRT will use this throughout its code.
14.723 +//
14.724 +// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
14.725 +// non-global, such as something created inside
14.726 +// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
14.727 +// SDL_CreateWindow().
14.728 +SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
14.729 +
14.730 +ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
14.731 +{
14.732 +public:
14.733 + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
14.734 +};
14.735 +
14.736 +IFrameworkView^ SDLApplicationSource::CreateView()
14.737 +{
14.738 + // TODO, WinRT: see if this function (CreateView) can ever get called
14.739 + // more than once. For now, just prevent it from ever assigning
14.740 + // SDL_WinRTGlobalApp more than once.
14.741 + SDL_assert(!SDL_WinRTGlobalApp);
14.742 + SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
14.743 + if (!SDL_WinRTGlobalApp)
14.744 + {
14.745 + SDL_WinRTGlobalApp = app;
14.746 + }
14.747 + return app;
14.748 +}
14.749 +
14.750 +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
14.751 +{
14.752 + WINRT_SDLAppEntryPoint = mainFunction;
14.753 + auto direct3DApplicationSource = ref new SDLApplicationSource();
14.754 + CoreApplication::Run(direct3DApplicationSource);
14.755 + return 0;
14.756 +}
14.757 +
14.758 +static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
14.759 +{
14.760 + SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
14.761 +
14.762 + // Start with no orientation flags, then add each in as they're parsed
14.763 + // from newValue.
14.764 + unsigned int orientationFlags = 0;
14.765 + if (newValue) {
14.766 + std::istringstream tokenizer(newValue);
14.767 + while (!tokenizer.eof()) {
14.768 + std::string orientationName;
14.769 + std::getline(tokenizer, orientationName, ' ');
14.770 + if (orientationName == "LandscapeLeft") {
14.771 + orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
14.772 + } else if (orientationName == "LandscapeRight") {
14.773 + orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
14.774 + } else if (orientationName == "Portrait") {
14.775 + orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
14.776 + } else if (orientationName == "PortraitUpsideDown") {
14.777 + orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
14.778 + }
14.779 + }
14.780 + }
14.781 +
14.782 + // If no valid orientation flags were specified, use a reasonable set of defaults:
14.783 + if (!orientationFlags) {
14.784 + // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
14.785 + orientationFlags = (unsigned int) ( \
14.786 + DisplayOrientations::Landscape |
14.787 + DisplayOrientations::LandscapeFlipped |
14.788 + DisplayOrientations::Portrait |
14.789 + DisplayOrientations::PortraitFlipped);
14.790 + }
14.791 +
14.792 + // Set the orientation/rotation preferences. Please note that this does
14.793 + // not constitute a 100%-certain lock of a given set of possible
14.794 + // orientations. According to Microsoft's documentation on WinRT [1]
14.795 + // when a device is not capable of being rotated, Windows may ignore
14.796 + // the orientation preferences, and stick to what the device is capable of
14.797 + // displaying.
14.798 + //
14.799 + // [1] Documentation on the 'InitialRotationPreference' setting for a
14.800 + // Windows app's manifest file describes how some orientation/rotation
14.801 + // preferences may be ignored. See
14.802 + // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
14.803 + // for details. Microsoft's "Display orientation sample" also gives an
14.804 + // outline of how Windows treats device rotation
14.805 + // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
14.806 + DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
14.807 +}
14.808 +
14.809 +static void
14.810 +WINRT_ProcessWindowSizeChange()
14.811 +{
14.812 + // Make the new window size be the one true fullscreen mode.
14.813 + // This change was initially done, in part, to allow the Direct3D 11.1
14.814 + // renderer to receive window-resize events as a device rotates.
14.815 + // Before, rotating a device from landscape, to portrait, and then
14.816 + // back to landscape would cause the Direct3D 11.1 swap buffer to
14.817 + // not get resized appropriately. SDL would, on the rotation from
14.818 + // landscape to portrait, re-resize the SDL window to it's initial
14.819 + // size (landscape). On the subsequent rotation, SDL would drop the
14.820 + // window-resize event as it appeared the SDL window didn't change
14.821 + // size, and the Direct3D 11.1 renderer wouldn't resize its swap
14.822 + // chain.
14.823 + SDL_DisplayMode newDisplayMode;
14.824 + if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) {
14.825 + return;
14.826 + }
14.827 +
14.828 + // Make note of the old display mode, and it's old driverdata.
14.829 + SDL_DisplayMode oldDisplayMode;
14.830 + SDL_zero(oldDisplayMode);
14.831 + if (WINRT_GlobalSDLVideoDevice) {
14.832 + oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
14.833 + }
14.834 +
14.835 + // Setup the new display mode in the appropriate spots.
14.836 + if (WINRT_GlobalSDLVideoDevice) {
14.837 + // Make a full copy of the display mode for display_modes[0],
14.838 + // one with with a separately malloced 'driverdata' field.
14.839 + // SDL_VideoQuit(), if called, will attempt to free the driverdata
14.840 + // fields in 'desktop_mode' and each entry in the 'display_modes'
14.841 + // array.
14.842 + if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) {
14.843 + // Free the previous mode's memory
14.844 + SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata);
14.845 + WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL;
14.846 + }
14.847 + if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) {
14.848 + // Uh oh, something went wrong. A malloc call probably failed.
14.849 + SDL_free(newDisplayMode.driverdata);
14.850 + return;
14.851 + }
14.852 +
14.853 + // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'.
14.854 + WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode;
14.855 + WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode;
14.856 + }
14.857 +
14.858 + if (WINRT_GlobalSDLWindow) {
14.859 + // Send a window-resize event to the rest of SDL, and to apps:
14.860 + SDL_SendWindowEvent(
14.861 + WINRT_GlobalSDLWindow,
14.862 + SDL_WINDOWEVENT_RESIZED,
14.863 + newDisplayMode.w,
14.864 + newDisplayMode.h);
14.865 +
14.866 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.867 + // HACK: On Windows Phone, make sure that orientation changes from
14.868 + // Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
14.869 + // or vice-versa on either of those two, lead to the Direct3D renderer
14.870 + // getting updated.
14.871 + const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation;
14.872 + const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation;
14.873 +
14.874 + if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
14.875 + (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
14.876 + (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
14.877 + (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
14.878 + {
14.879 + // One of the reasons this event is getting sent out is because SDL
14.880 + // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
14.881 + // if and when the event size doesn't change (and the Direct3D 11.1
14.882 + // renderer doesn't get the memo).
14.883 + //
14.884 + // Make sure that the display/window size really didn't change. If
14.885 + // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
14.886 + // the Direct3D 11.1 renderer picked it up, presumably.
14.887 + if (oldDisplayMode.w == newDisplayMode.w &&
14.888 + oldDisplayMode.h == newDisplayMode.h)
14.889 + {
14.890 + SDL_SendWindowEvent(
14.891 + WINRT_GlobalSDLWindow,
14.892 + SDL_WINDOWEVENT_SIZE_CHANGED,
14.893 + newDisplayMode.w,
14.894 + newDisplayMode.h);
14.895 + }
14.896 + }
14.897 +#endif
14.898 + }
14.899 +
14.900 + // Finally, free the 'driverdata' field of the old 'desktop_mode'.
14.901 + if (oldDisplayMode.driverdata) {
14.902 + SDL_free(oldDisplayMode.driverdata);
14.903 + oldDisplayMode.driverdata = NULL;
14.904 + }
14.905 +}
14.906 +
14.907 +SDL_WinRTApp::SDL_WinRTApp() :
14.908 + m_windowClosed(false),
14.909 + m_windowVisible(true)
14.910 +{
14.911 +}
14.912 +
14.913 +void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
14.914 +{
14.915 + applicationView->Activated +=
14.916 + ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
14.917 +
14.918 + CoreApplication::Suspending +=
14.919 + ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
14.920 +
14.921 + CoreApplication::Resuming +=
14.922 + ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
14.923 +
14.924 + CoreApplication::Exiting +=
14.925 + ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
14.926 +
14.927 + DisplayProperties::OrientationChanged +=
14.928 + ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
14.929 +
14.930 + // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. This needs to be
14.931 + // done before the hint's callback is registered (as of Feb 22, 2013),
14.932 + // otherwise the hint callback won't get registered.
14.933 + //
14.934 + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
14.935 + //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback)
14.936 + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
14.937 +}
14.938 +
14.939 +void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
14.940 +{
14.941 +#if LOG_ORIENTATION_EVENTS==1
14.942 + CoreWindow^ window = CoreWindow::GetForCurrentThread();
14.943 + if (window) {
14.944 + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
14.945 + __FUNCTION__,
14.946 + (int)DisplayProperties::CurrentOrientation,
14.947 + (int)DisplayProperties::NativeOrientation,
14.948 + (int)DisplayProperties::AutoRotationPreferences,
14.949 + window->Bounds.Width,
14.950 + window->Bounds.Height);
14.951 + } else {
14.952 + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
14.953 + __FUNCTION__,
14.954 + (int)DisplayProperties::CurrentOrientation,
14.955 + (int)DisplayProperties::NativeOrientation,
14.956 + (int)DisplayProperties::AutoRotationPreferences);
14.957 + }
14.958 +#endif
14.959 +
14.960 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.961 + // On Windows Phone, treat an orientation change as a change in window size.
14.962 + // The native window's size doesn't seem to change, however SDL will simulate
14.963 + // a window size change.
14.964 + WINRT_ProcessWindowSizeChange();
14.965 +#endif
14.966 +}
14.967 +
14.968 +void SDL_WinRTApp::SetWindow(CoreWindow^ window)
14.969 +{
14.970 +#if LOG_WINDOW_EVENTS==1
14.971 + SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
14.972 + __FUNCTION__,
14.973 + (int)DisplayProperties::CurrentOrientation,
14.974 + (int)DisplayProperties::NativeOrientation,
14.975 + (int)DisplayProperties::AutoRotationPreferences,
14.976 + window->Bounds.Width,
14.977 + window->Bounds.Height);
14.978 +#endif
14.979 +
14.980 + window->SizeChanged +=
14.981 + ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
14.982 +
14.983 + window->VisibilityChanged +=
14.984 + ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
14.985 +
14.986 + window->Closed +=
14.987 + ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
14.988 +
14.989 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
14.990 + window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
14.991 +#endif
14.992 +
14.993 + window->PointerPressed +=
14.994 + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
14.995 +
14.996 + window->PointerMoved +=
14.997 + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
14.998 +
14.999 + window->PointerReleased +=
14.1000 + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
14.1001 +
14.1002 + window->PointerWheelChanged +=
14.1003 + ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
14.1004 +
14.1005 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
14.1006 + // Retrieves relative-only mouse movements:
14.1007 + Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
14.1008 + ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
14.1009 +#endif
14.1010 +
14.1011 + window->KeyDown +=
14.1012 + ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
14.1013 +
14.1014 + window->KeyUp +=
14.1015 + ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
14.1016 +
14.1017 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.1018 + HardwareButtons::BackPressed +=
14.1019 + ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
14.1020 +#endif
14.1021 +
14.1022 +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps)
14.1023 + // Make sure we know when a user has opened the app's settings pane.
14.1024 + // This is needed in order to display a privacy policy, which needs
14.1025 + // to be done for network-enabled apps, as per Windows Store requirements.
14.1026 + using namespace Windows::UI::ApplicationSettings;
14.1027 + SettingsPane::GetForCurrentView()->CommandsRequested +=
14.1028 + ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
14.1029 + (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
14.1030 +#endif
14.1031 +}
14.1032 +
14.1033 +void SDL_WinRTApp::Load(Platform::String^ entryPoint)
14.1034 +{
14.1035 +}
14.1036 +
14.1037 +void SDL_WinRTApp::Run()
14.1038 +{
14.1039 + SDL_SetMainReady();
14.1040 + if (WINRT_SDLAppEntryPoint)
14.1041 + {
14.1042 + // TODO, WinRT: pass the C-style main() a reasonably realistic
14.1043 + // representation of command line arguments.
14.1044 + int argc = 0;
14.1045 + char **argv = NULL;
14.1046 + WINRT_SDLAppEntryPoint(argc, argv);
14.1047 + }
14.1048 +}
14.1049 +
14.1050 +void SDL_WinRTApp::PumpEvents()
14.1051 +{
14.1052 + if (!m_windowClosed)
14.1053 + {
14.1054 + if (m_windowVisible)
14.1055 + {
14.1056 + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
14.1057 + }
14.1058 + else
14.1059 + {
14.1060 + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
14.1061 + }
14.1062 + }
14.1063 +}
14.1064 +
14.1065 +void SDL_WinRTApp::Uninitialize()
14.1066 +{
14.1067 +}
14.1068 +
14.1069 +#if WINAPI_FAMILY == WINAPI_FAMILY_APP
14.1070 +void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
14.1071 + Windows::UI::ApplicationSettings::SettingsPane ^p,
14.1072 + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
14.1073 +{
14.1074 + using namespace Platform;
14.1075 + using namespace Windows::UI::ApplicationSettings;
14.1076 + using namespace Windows::UI::Popups;
14.1077 +
14.1078 + String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy
14.1079 + String ^privacyPolicyLabel = nullptr; // label/link text
14.1080 + const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately
14.1081 + wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion
14.1082 +
14.1083 + // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
14.1084 + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
14.1085 + if (tmpHintValue && tmpHintValue[0] != '\0') {
14.1086 + // Convert the privacy policy's URL to UCS2:
14.1087 + tmpStr = WIN_UTF8ToString(tmpHintValue);
14.1088 + privacyPolicyURL = ref new String(tmpStr);
14.1089 + SDL_free(tmpStr);
14.1090 +
14.1091 + // Optionally retrieve custom label-text for the link. If this isn't
14.1092 + // available, a default value will be used instead.
14.1093 + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
14.1094 + if (tmpHintValue && tmpHintValue[0] != '\0') {
14.1095 + tmpStr = WIN_UTF8ToString(tmpHintValue);
14.1096 + privacyPolicyLabel = ref new String(tmpStr);
14.1097 + SDL_free(tmpStr);
14.1098 + } else {
14.1099 + privacyPolicyLabel = ref new String(L"Privacy Policy");
14.1100 + }
14.1101 +
14.1102 + // Register the link, along with a handler to be called if and when it is
14.1103 + // clicked:
14.1104 + auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
14.1105 + ref new UICommandInvokedHandler([=](IUICommand ^) {
14.1106 + Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
14.1107 + }));
14.1108 + args->Request->ApplicationCommands->Append(cmd);
14.1109 + }
14.1110 +}
14.1111 +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
14.1112 +
14.1113 +void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
14.1114 +{
14.1115 +#if LOG_WINDOW_EVENTS==1
14.1116 + SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
14.1117 + __FUNCTION__,
14.1118 + args->Size.Width, args->Size.Height,
14.1119 + (int)DisplayProperties::CurrentOrientation,
14.1120 + (int)DisplayProperties::NativeOrientation,
14.1121 + (int)DisplayProperties::AutoRotationPreferences,
14.1122 + (WINRT_GlobalSDLWindow ? "yes" : "no"));
14.1123 +#endif
14.1124 +
14.1125 + WINRT_ProcessWindowSizeChange();
14.1126 +}
14.1127 +
14.1128 +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
14.1129 +{
14.1130 +#if LOG_WINDOW_EVENTS==1
14.1131 + SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n",
14.1132 + __FUNCTION__,
14.1133 + (args->Visible ? "yes" : "no"),
14.1134 + (WINRT_GlobalSDLWindow ? "yes" : "no"));
14.1135 +#endif
14.1136 +
14.1137 + m_windowVisible = args->Visible;
14.1138 + if (WINRT_GlobalSDLWindow) {
14.1139 + SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
14.1140 +
14.1141 + if (args->Visible) {
14.1142 + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
14.1143 + } else {
14.1144 + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
14.1145 + }
14.1146 +
14.1147 + // HACK: Prevent SDL's window-hide handling code, which currently
14.1148 + // triggers a fake window resize (possibly erronously), from
14.1149 + // marking the SDL window's surface as invalid.
14.1150 + //
14.1151 + // A better solution to this probably involves figuring out if the
14.1152 + // fake window resize can be prevented.
14.1153 + WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
14.1154 + }
14.1155 +}
14.1156 +
14.1157 +void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
14.1158 +{
14.1159 +#if LOG_WINDOW_EVENTS==1
14.1160 + SDL_Log("%s\n", __FUNCTION__);
14.1161 +#endif
14.1162 + m_windowClosed = true;
14.1163 +}
14.1164 +
14.1165 +void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
14.1166 +{
14.1167 + CoreWindow::GetForCurrentThread()->Activate();
14.1168 +}
14.1169 +
14.1170 +static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
14.1171 +{
14.1172 + if (event->type == SDL_WINDOWEVENT)
14.1173 + {
14.1174 + switch (event->window.event)
14.1175 + {
14.1176 + case SDL_WINDOWEVENT_MINIMIZED:
14.1177 + case SDL_WINDOWEVENT_RESTORED:
14.1178 + // Return 0 to indicate that the event should be removed from the
14.1179 + // event queue:
14.1180 + return 0;
14.1181 + default:
14.1182 + break;
14.1183 + }
14.1184 + }
14.1185 +
14.1186 + // Return 1 to indicate that the event should stay in the event queue:
14.1187 + return 1;
14.1188 +}
14.1189 +
14.1190 +void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
14.1191 +{
14.1192 + // Save app state asynchronously after requesting a deferral. Holding a deferral
14.1193 + // indicates that the application is busy performing suspending operations. Be
14.1194 + // aware that a deferral may not be held indefinitely. After about five seconds,
14.1195 + // the app will be forced to exit.
14.1196 + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
14.1197 + create_task([this, deferral]()
14.1198 + {
14.1199 + // Send a window-minimized event immediately to observers.
14.1200 + // CoreDispatcher::ProcessEvents, which is the backbone on which
14.1201 + // SDL_WinRTApp::PumpEvents is built, will not return to its caller
14.1202 + // once it sends out a suspend event. Any events posted to SDL's
14.1203 + // event queue won't get received until the WinRT app is resumed.
14.1204 + // SDL_AddEventWatch() may be used to receive app-suspend events on
14.1205 + // WinRT.
14.1206 + //
14.1207 + // In order to prevent app-suspend events from being received twice:
14.1208 + // first via a callback passed to SDL_AddEventWatch, and second via
14.1209 + // SDL's event queue, the event will be sent to SDL, then immediately
14.1210 + // removed from the queue.
14.1211 + if (WINRT_GlobalSDLWindow)
14.1212 + {
14.1213 + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
14.1214 + SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
14.1215 + }
14.1216 +
14.1217 + SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
14.1218 + SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
14.1219 +
14.1220 + deferral->Complete();
14.1221 + });
14.1222 +}
14.1223 +
14.1224 +void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
14.1225 +{
14.1226 + SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
14.1227 + SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
14.1228 +
14.1229 + // Restore any data or state that was unloaded on suspend. By default, data
14.1230 + // and state are persisted when resuming from suspend. Note that this event
14.1231 + // does not occur if the app was previously terminated.
14.1232 + if (WINRT_GlobalSDLWindow)
14.1233 + {
14.1234 + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
14.1235 +
14.1236 + // Remove the app-resume event from the queue, as is done with the
14.1237 + // app-suspend event.
14.1238 + //
14.1239 + // TODO, WinRT: consider posting this event to the queue even though
14.1240 + // its counterpart, the app-suspend event, effectively has to be
14.1241 + // processed immediately.
14.1242 + SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
14.1243 + }
14.1244 +}
14.1245 +
14.1246 +void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
14.1247 +{
14.1248 + SDL_SendAppEvent(SDL_APP_TERMINATING);
14.1249 +}
14.1250 +
14.1251 +static void
14.1252 +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
14.1253 +{
14.1254 + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
14.1255 + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
14.1256 + header,
14.1257 + pt->Position.X, pt->Position.Y,
14.1258 + transformedPoint.X, transformedPoint.Y,
14.1259 + pt->Properties->MouseWheelDelta,
14.1260 + pt->FrameId,
14.1261 + pt->PointerId,
14.1262 + WINRT_GetSDLButtonForPointerPoint(pt));
14.1263 +}
14.1264 +
14.1265 +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
14.1266 +{
14.1267 +#if LOG_POINTER_EVENTS
14.1268 + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.1269 +#endif
14.1270 +
14.1271 + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.1272 +}
14.1273 +
14.1274 +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
14.1275 +{
14.1276 +#if LOG_POINTER_EVENTS
14.1277 + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.1278 +#endif
14.1279 +
14.1280 + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.1281 +}
14.1282 +
14.1283 +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
14.1284 +{
14.1285 +#if LOG_POINTER_EVENTS
14.1286 + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.1287 +#endif
14.1288 +
14.1289 + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.1290 +}
14.1291 +
14.1292 +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
14.1293 +{
14.1294 +#if LOG_POINTER_EVENTS
14.1295 + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
14.1296 +#endif
14.1297 +
14.1298 + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
14.1299 +}
14.1300 +
14.1301 +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
14.1302 +{
14.1303 + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
14.1304 +}
14.1305 +
14.1306 +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
14.1307 +{
14.1308 + WINRT_ProcessKeyDownEvent(args);
14.1309 +}
14.1310 +
14.1311 +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
14.1312 +{
14.1313 + WINRT_ProcessKeyUpEvent(args);
14.1314 +}
14.1315 +
14.1316 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
14.1317 +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)
14.1318 +{
14.1319 + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
14.1320 + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
14.1321 +
14.1322 const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON);
14.1323 if (hint) {
14.1324 if (*hint == '1') {
14.1325 args->Handled = true;
14.1326 }
14.1327 - }
14.1328 -}
14.1329 -#endif
14.1330 -
14.1331 + }
14.1332 +}
14.1333 +#endif
14.1334 +
15.1 --- a/src/core/winrt/SDL_winrtapp_direct3d.h Tue Mar 04 19:49:11 2014 -0500
15.2 +++ b/src/core/winrt/SDL_winrtapp_direct3d.h Sun Mar 09 11:06:11 2014 -0700
15.3 @@ -1,58 +1,58 @@
15.4 -#pragma once
15.5 -
15.6 -#include <Windows.h>
15.7 -
15.8 -extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **));
15.9 -
15.10 -ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView
15.11 -{
15.12 -public:
15.13 - SDL_WinRTApp();
15.14 -
15.15 - // IFrameworkView Methods.
15.16 - virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
15.17 - virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
15.18 - virtual void Load(Platform::String^ entryPoint);
15.19 - virtual void Run();
15.20 - virtual void Uninitialize();
15.21 -
15.22 -internal:
15.23 - // SDL-specific methods
15.24 - void PumpEvents();
15.25 -
15.26 -protected:
15.27 - // Event Handlers.
15.28 -
15.29 -#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps)
15.30 - void OnSettingsPaneCommandsRequested(
15.31 - Windows::UI::ApplicationSettings::SettingsPane ^p,
15.32 - Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args);
15.33 -#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
15.34 -
15.35 - void OnOrientationChanged(Platform::Object^ sender);
15.36 - void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
15.37 - void OnLogicalDpiChanged(Platform::Object^ sender);
15.38 - void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
15.39 - void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
15.40 - void OnResuming(Platform::Object^ sender, Platform::Object^ args);
15.41 - void OnExiting(Platform::Object^ sender, Platform::Object^ args);
15.42 - void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
15.43 - void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
15.44 - void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.45 - void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.46 - void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.47 - void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.48 - void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
15.49 - void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
15.50 - void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
15.51 -
15.52 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
15.53 - void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
15.54 -#endif
15.55 -
15.56 -private:
15.57 - bool m_windowClosed;
15.58 - bool m_windowVisible;
15.59 -};
15.60 -
15.61 -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
15.62 +#pragma once
15.63 +
15.64 +#include <Windows.h>
15.65 +
15.66 +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **));
15.67 +
15.68 +ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView
15.69 +{
15.70 +public:
15.71 + SDL_WinRTApp();
15.72 +
15.73 + // IFrameworkView Methods.
15.74 + virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
15.75 + virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
15.76 + virtual void Load(Platform::String^ entryPoint);
15.77 + virtual void Run();
15.78 + virtual void Uninitialize();
15.79 +
15.80 +internal:
15.81 + // SDL-specific methods
15.82 + void PumpEvents();
15.83 +
15.84 +protected:
15.85 + // Event Handlers.
15.86 +
15.87 +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps)
15.88 + void OnSettingsPaneCommandsRequested(
15.89 + Windows::UI::ApplicationSettings::SettingsPane ^p,
15.90 + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args);
15.91 +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
15.92 +
15.93 + void OnOrientationChanged(Platform::Object^ sender);
15.94 + void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
15.95 + void OnLogicalDpiChanged(Platform::Object^ sender);
15.96 + void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
15.97 + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
15.98 + void OnResuming(Platform::Object^ sender, Platform::Object^ args);
15.99 + void OnExiting(Platform::Object^ sender, Platform::Object^ args);
15.100 + void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
15.101 + void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
15.102 + void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.103 + void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.104 + void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.105 + void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
15.106 + void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
15.107 + void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
15.108 + void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
15.109 +
15.110 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
15.111 + void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
15.112 +#endif
15.113 +
15.114 +private:
15.115 + bool m_windowClosed;
15.116 + bool m_windowVisible;
15.117 +};
15.118 +
15.119 +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
16.1 --- a/src/file/SDL_rwops.c Tue Mar 04 19:49:11 2014 -0500
16.2 +++ b/src/file/SDL_rwops.c Sun Mar 09 11:06:11 2014 -0700
16.3 @@ -1,765 +1,765 @@
16.4 -/*
16.5 - Simple DirectMedia Layer
16.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
16.7 -
16.8 - This software is provided 'as-is', without any express or implied
16.9 - warranty. In no event will the authors be held liable for any damages
16.10 - arising from the use of this software.
16.11 -
16.12 - Permission is granted to anyone to use this software for any purpose,
16.13 - including commercial applications, and to alter it and redistribute it
16.14 - freely, subject to the following restrictions:
16.15 -
16.16 - 1. The origin of this software must not be misrepresented; you must not
16.17 - claim that you wrote the original software. If you use this software
16.18 - in a product, an acknowledgment in the product documentation would be
16.19 - appreciated but is not required.
16.20 - 2. Altered source versions must be plainly marked as such, and must not be
16.21 - misrepresented as being the original software.
16.22 - 3. This notice may not be removed or altered from any source distribution.
16.23 -*/
16.24 -/* Need this so Linux systems define fseek64o, ftell64o and off64_t */
16.25 -#define _LARGEFILE64_SOURCE
16.26 -#include "SDL_config.h"
16.27 -
16.28 -#if defined(__WIN32__)
16.29 -#include "../core/windows/SDL_windows.h"
16.30 -#endif
16.31 -
16.32 -
16.33 -/* This file provides a general interface for SDL to read and write
16.34 - data sources. It can easily be extended to files, memory, etc.
16.35 -*/
16.36 -
16.37 -#include "SDL_endian.h"
16.38 -#include "SDL_rwops.h"
16.39 -
16.40 -#ifdef __APPLE__
16.41 -#include "cocoa/SDL_rwopsbundlesupport.h"
16.42 -#endif /* __APPLE__ */
16.43 -
16.44 -#ifdef ANDROID
16.45 -#include "../core/android/SDL_android.h"
16.46 -#include "SDL_system.h"
16.47 -#endif
16.48 -
16.49 -#ifdef __WIN32__
16.50 -
16.51 -/* Functions to read/write Win32 API file pointers */
16.52 -
16.53 -#ifndef INVALID_SET_FILE_POINTER
16.54 -#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
16.55 -#endif
16.56 -
16.57 -#define READAHEAD_BUFFER_SIZE 1024
16.58 -
16.59 -static int SDLCALL
16.60 -windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
16.61 -{
16.62 - UINT old_error_mode;
16.63 - HANDLE h;
16.64 - DWORD r_right, w_right;
16.65 - DWORD must_exist, truncate;
16.66 - int a_mode;
16.67 -
16.68 - if (!context)
16.69 - return -1; /* failed (invalid call) */
16.70 -
16.71 - context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */
16.72 - context->hidden.windowsio.buffer.data = NULL;
16.73 - context->hidden.windowsio.buffer.size = 0;
16.74 - context->hidden.windowsio.buffer.left = 0;
16.75 -
16.76 - /* "r" = reading, file must exist */
16.77 - /* "w" = writing, truncate existing, file may not exist */
16.78 - /* "r+"= reading or writing, file must exist */
16.79 - /* "a" = writing, append file may not exist */
16.80 - /* "a+"= append + read, file may not exist */
16.81 - /* "w+" = read, write, truncate. file may not exist */
16.82 -
16.83 - must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
16.84 - truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
16.85 - r_right = (SDL_strchr(mode, '+') != NULL
16.86 - || must_exist) ? GENERIC_READ : 0;
16.87 - a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
16.88 - w_right = (a_mode || SDL_strchr(mode, '+')
16.89 - || truncate) ? GENERIC_WRITE : 0;
16.90 -
16.91 - if (!r_right && !w_right) /* inconsistent mode */
16.92 - return -1; /* failed (invalid call) */
16.93 -
16.94 - context->hidden.windowsio.buffer.data =
16.95 - (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
16.96 - if (!context->hidden.windowsio.buffer.data) {
16.97 - return SDL_OutOfMemory();
16.98 - }
16.99 - /* Do not open a dialog box if failure */
16.100 - old_error_mode =
16.101 - SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
16.102 -
16.103 - {
16.104 - LPTSTR tstr = WIN_UTF8ToString(filename);
16.105 - h = CreateFile(tstr, (w_right | r_right),
16.106 - (w_right) ? 0 : FILE_SHARE_READ, NULL,
16.107 - (must_exist | truncate | a_mode),
16.108 - FILE_ATTRIBUTE_NORMAL, NULL);
16.109 - SDL_free(tstr);
16.110 - }
16.111 -
16.112 - /* restore old behavior */
16.113 - SetErrorMode(old_error_mode);
16.114 -
16.115 - if (h == INVALID_HANDLE_VALUE) {
16.116 - SDL_free(context->hidden.windowsio.buffer.data);
16.117 - context->hidden.windowsio.buffer.data = NULL;
16.118 - SDL_SetError("Couldn't open %s", filename);
16.119 - return -2; /* failed (CreateFile) */
16.120 - }
16.121 - context->hidden.windowsio.h = h;
16.122 - context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
16.123 -
16.124 - return 0; /* ok */
16.125 -}
16.126 -
16.127 -static Sint64 SDLCALL
16.128 -windows_file_size(SDL_RWops * context)
16.129 -{
16.130 - LARGE_INTEGER size;
16.131 -
16.132 - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
16.133 - return SDL_SetError("windows_file_size: invalid context/file not opened");
16.134 - }
16.135 -
16.136 - if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
16.137 - return WIN_SetError("windows_file_size");
16.138 - }
16.139 -
16.140 - return size.QuadPart;
16.141 -}
16.142 -
16.143 -static Sint64 SDLCALL
16.144 -windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
16.145 -{
16.146 - DWORD windowswhence;
16.147 - LARGE_INTEGER windowsoffset;
16.148 -
16.149 - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
16.150 - return SDL_SetError("windows_file_seek: invalid context/file not opened");
16.151 - }
16.152 -
16.153 - /* FIXME: We may be able to satisfy the seek within buffered data */
16.154 - if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
16.155 - offset -= (long)context->hidden.windowsio.buffer.left;
16.156 - }
16.157 - context->hidden.windowsio.buffer.left = 0;
16.158 -
16.159 - switch (whence) {
16.160 - case RW_SEEK_SET:
16.161 - windowswhence = FILE_BEGIN;
16.162 - break;
16.163 - case RW_SEEK_CUR:
16.164 - windowswhence = FILE_CURRENT;
16.165 - break;
16.166 - case RW_SEEK_END:
16.167 - windowswhence = FILE_END;
16.168 - break;
16.169 - default:
16.170 - return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
16.171 - }
16.172 -
16.173 - windowsoffset.QuadPart = offset;
16.174 - if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
16.175 - return WIN_SetError("windows_file_seek");
16.176 - }
16.177 - return windowsoffset.QuadPart;
16.178 -}
16.179 -
16.180 -static size_t SDLCALL
16.181 -windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.182 -{
16.183 - size_t total_need;
16.184 - size_t total_read = 0;
16.185 - size_t read_ahead;
16.186 - DWORD byte_read;
16.187 -
16.188 - total_need = size * maxnum;
16.189 -
16.190 - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
16.191 - || !total_need)
16.192 - return 0;
16.193 -
16.194 - if (context->hidden.windowsio.buffer.left > 0) {
16.195 - void *data = (char *) context->hidden.windowsio.buffer.data +
16.196 - context->hidden.windowsio.buffer.size -
16.197 - context->hidden.windowsio.buffer.left;
16.198 - read_ahead =
16.199 - SDL_min(total_need, context->hidden.windowsio.buffer.left);
16.200 - SDL_memcpy(ptr, data, read_ahead);
16.201 - context->hidden.windowsio.buffer.left -= read_ahead;
16.202 -
16.203 - if (read_ahead == total_need) {
16.204 - return maxnum;
16.205 - }
16.206 - ptr = (char *) ptr + read_ahead;
16.207 - total_need -= read_ahead;
16.208 - total_read += read_ahead;
16.209 - }
16.210 -
16.211 - if (total_need < READAHEAD_BUFFER_SIZE) {
16.212 - if (!ReadFile
16.213 - (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
16.214 - READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
16.215 - SDL_Error(SDL_EFREAD);
16.216 - return 0;
16.217 - }
16.218 - read_ahead = SDL_min(total_need, (int) byte_read);
16.219 - SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
16.220 - context->hidden.windowsio.buffer.size = byte_read;
16.221 - context->hidden.windowsio.buffer.left = byte_read - read_ahead;
16.222 - total_read += read_ahead;
16.223 - } else {
16.224 - if (!ReadFile
16.225 - (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
16.226 - SDL_Error(SDL_EFREAD);
16.227 - return 0;
16.228 - }
16.229 - total_read += byte_read;
16.230 - }
16.231 - return (total_read / size);
16.232 -}
16.233 -
16.234 -static size_t SDLCALL
16.235 -windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
16.236 - size_t num)
16.237 -{
16.238 -
16.239 - size_t total_bytes;
16.240 - DWORD byte_written;
16.241 - size_t nwritten;
16.242 -
16.243 - total_bytes = size * num;
16.244 -
16.245 - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
16.246 - || total_bytes <= 0 || !size)
16.247 - return 0;
16.248 -
16.249 - if (context->hidden.windowsio.buffer.left) {
16.250 - SetFilePointer(context->hidden.windowsio.h,
16.251 - -(LONG)context->hidden.windowsio.buffer.left, NULL,
16.252 - FILE_CURRENT);
16.253 - context->hidden.windowsio.buffer.left = 0;
16.254 - }
16.255 -
16.256 - /* if in append mode, we must go to the EOF before write */
16.257 - if (context->hidden.windowsio.append) {
16.258 - if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
16.259 - INVALID_SET_FILE_POINTER) {
16.260 - SDL_Error(SDL_EFWRITE);
16.261 - return 0;
16.262 - }
16.263 - }
16.264 -
16.265 - if (!WriteFile
16.266 - (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
16.267 - SDL_Error(SDL_EFWRITE);
16.268 - return 0;
16.269 - }
16.270 -
16.271 - nwritten = byte_written / size;
16.272 - return nwritten;
16.273 -}
16.274 -
16.275 -static int SDLCALL
16.276 -windows_file_close(SDL_RWops * context)
16.277 -{
16.278 -
16.279 - if (context) {
16.280 - if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
16.281 - CloseHandle(context->hidden.windowsio.h);
16.282 - context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */
16.283 - }
16.284 - SDL_free(context->hidden.windowsio.buffer.data);
16.285 - context->hidden.windowsio.buffer.data = NULL;
16.286 - SDL_FreeRW(context);
16.287 - }
16.288 - return (0);
16.289 -}
16.290 -#endif /* __WIN32__ */
16.291 -
16.292 -#ifdef HAVE_STDIO_H
16.293 -
16.294 -/* Functions to read/write stdio file pointers */
16.295 -
16.296 -static Sint64 SDLCALL
16.297 -stdio_size(SDL_RWops * context)
16.298 -{
16.299 - Sint64 pos, size;
16.300 -
16.301 - pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
16.302 - if (pos < 0) {
16.303 - return -1;
16.304 - }
16.305 - size = SDL_RWseek(context, 0, RW_SEEK_END);
16.306 -
16.307 - SDL_RWseek(context, pos, RW_SEEK_SET);
16.308 - return size;
16.309 -}
16.310 -
16.311 -static Sint64 SDLCALL
16.312 -stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
16.313 -{
16.314 -#ifdef HAVE_FSEEKO64
16.315 - if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
16.316 - return ftello64(context->hidden.stdio.fp);
16.317 - }
16.318 -#elif defined(HAVE_FSEEKO)
16.319 - if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
16.320 - return ftello(context->hidden.stdio.fp);
16.321 - }
16.322 -#elif defined(HAVE__FSEEKI64)
16.323 - if (_fseeki64(context->hidden.stdio.fp, offset, whence) == 0) {
16.324 - return _ftelli64(context->hidden.stdio.fp);
16.325 - }
16.326 -#else
16.327 - if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
16.328 - return (ftell(context->hidden.stdio.fp));
16.329 - }
16.330 -#endif
16.331 - return SDL_Error(SDL_EFSEEK);
16.332 -}
16.333 -
16.334 -static size_t SDLCALL
16.335 -stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.336 -{
16.337 - size_t nread;
16.338 -
16.339 - nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
16.340 - if (nread == 0 && ferror(context->hidden.stdio.fp)) {
16.341 - SDL_Error(SDL_EFREAD);
16.342 - }
16.343 - return (nread);
16.344 -}
16.345 -
16.346 -static size_t SDLCALL
16.347 -stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.348 -{
16.349 - size_t nwrote;
16.350 -
16.351 - nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
16.352 - if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
16.353 - SDL_Error(SDL_EFWRITE);
16.354 - }
16.355 - return (nwrote);
16.356 -}
16.357 -
16.358 -static int SDLCALL
16.359 -stdio_close(SDL_RWops * context)
16.360 -{
16.361 - int status = 0;
16.362 - if (context) {
16.363 - if (context->hidden.stdio.autoclose) {
16.364 - /* WARNING: Check the return value here! */
16.365 - if (fclose(context->hidden.stdio.fp) != 0) {
16.366 - status = SDL_Error(SDL_EFWRITE);
16.367 - }
16.368 - }
16.369 - SDL_FreeRW(context);
16.370 - }
16.371 - return status;
16.372 -}
16.373 -#endif /* !HAVE_STDIO_H */
16.374 -
16.375 -/* Functions to read/write memory pointers */
16.376 -
16.377 -static Sint64 SDLCALL
16.378 -mem_size(SDL_RWops * context)
16.379 -{
16.380 - return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
16.381 -}
16.382 -
16.383 -static Sint64 SDLCALL
16.384 -mem_seek(SDL_RWops * context, Sint64 offset, int whence)
16.385 -{
16.386 - Uint8 *newpos;
16.387 -
16.388 - switch (whence) {
16.389 - case RW_SEEK_SET:
16.390 - newpos = context->hidden.mem.base + offset;
16.391 - break;
16.392 - case RW_SEEK_CUR:
16.393 - newpos = context->hidden.mem.here + offset;
16.394 - break;
16.395 - case RW_SEEK_END:
16.396 - newpos = context->hidden.mem.stop + offset;
16.397 - break;
16.398 - default:
16.399 - return SDL_SetError("Unknown value for 'whence'");
16.400 - }
16.401 - if (newpos < context->hidden.mem.base) {
16.402 - newpos = context->hidden.mem.base;
16.403 - }
16.404 - if (newpos > context->hidden.mem.stop) {
16.405 - newpos = context->hidden.mem.stop;
16.406 - }
16.407 - context->hidden.mem.here = newpos;
16.408 - return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
16.409 -}
16.410 -
16.411 -static size_t SDLCALL
16.412 -mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.413 -{
16.414 - size_t total_bytes;
16.415 - size_t mem_available;
16.416 -
16.417 - total_bytes = (maxnum * size);
16.418 - if ((maxnum <= 0) || (size <= 0)
16.419 - || ((total_bytes / maxnum) != (size_t) size)) {
16.420 - return 0;
16.421 - }
16.422 -
16.423 - mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
16.424 - if (total_bytes > mem_available) {
16.425 - total_bytes = mem_available;
16.426 - }
16.427 -
16.428 - SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
16.429 - context->hidden.mem.here += total_bytes;
16.430 -
16.431 - return (total_bytes / size);
16.432 -}
16.433 -
16.434 -static size_t SDLCALL
16.435 -mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.436 -{
16.437 - if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
16.438 - num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
16.439 - }
16.440 - SDL_memcpy(context->hidden.mem.here, ptr, num * size);
16.441 - context->hidden.mem.here += num * size;
16.442 - return (num);
16.443 -}
16.444 -
16.445 -static size_t SDLCALL
16.446 -mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.447 -{
16.448 - SDL_SetError("Can't write to read-only memory");
16.449 - return (0);
16.450 -}
16.451 -
16.452 -static int SDLCALL
16.453 -mem_close(SDL_RWops * context)
16.454 -{
16.455 - if (context) {
16.456 - SDL_FreeRW(context);
16.457 - }
16.458 - return (0);
16.459 -}
16.460 -
16.461 -
16.462 -/* Functions to create SDL_RWops structures from various data sources */
16.463 -
16.464 -SDL_RWops *
16.465 -SDL_RWFromFile(const char *file, const char *mode)
16.466 -{
16.467 - SDL_RWops *rwops = NULL;
16.468 - if (!file || !*file || !mode || !*mode) {
16.469 - SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
16.470 - return NULL;
16.471 - }
16.472 -#if defined(ANDROID)
16.473 -#ifdef HAVE_STDIO_H
16.474 - /* Try to open the file on the filesystem first */
16.475 - if (*file == '/') {
16.476 - FILE *fp = fopen(file, mode);
16.477 - if (fp) {
16.478 - return SDL_RWFromFP(fp, 1);
16.479 - }
16.480 - } else {
16.481 - /* Try opening it from internal storage if it's a relative path */
16.482 - char *path;
16.483 - FILE *fp;
16.484 -
16.485 - path = SDL_stack_alloc(char, PATH_MAX);
16.486 - if (path) {
16.487 - SDL_snprintf(path, PATH_MAX, "%s/%s",
16.488 - SDL_AndroidGetInternalStoragePath(), file);
16.489 - fp = fopen(path, mode);
16.490 - SDL_stack_free(path);
16.491 - if (fp) {
16.492 - return SDL_RWFromFP(fp, 1);
16.493 - }
16.494 - }
16.495 - }
16.496 -#endif /* HAVE_STDIO_H */
16.497 -
16.498 - /* Try to open the file from the asset system */
16.499 - rwops = SDL_AllocRW();
16.500 - if (!rwops)
16.501 - return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
16.502 - if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
16.503 - SDL_FreeRW(rwops);
16.504 - return NULL;
16.505 - }
16.506 - rwops->size = Android_JNI_FileSize;
16.507 - rwops->seek = Android_JNI_FileSeek;
16.508 - rwops->read = Android_JNI_FileRead;
16.509 - rwops->write = Android_JNI_FileWrite;
16.510 - rwops->close = Android_JNI_FileClose;
16.511 - rwops->type = SDL_RWOPS_JNIFILE;
16.512 -
16.513 -#elif defined(__WIN32__)
16.514 - rwops = SDL_AllocRW();
16.515 - if (!rwops)
16.516 - return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
16.517 - if (windows_file_open(rwops, file, mode) < 0) {
16.518 - SDL_FreeRW(rwops);
16.519 - return NULL;
16.520 - }
16.521 - rwops->size = windows_file_size;
16.522 - rwops->seek = windows_file_seek;
16.523 - rwops->read = windows_file_read;
16.524 - rwops->write = windows_file_write;
16.525 - rwops->close = windows_file_close;
16.526 - rwops->type = SDL_RWOPS_WINFILE;
16.527 -
16.528 -#elif HAVE_STDIO_H
16.529 - {
16.530 - #ifdef __APPLE__
16.531 - FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
16.532 - #elif __WINRT__
16.533 - FILE *fp = NULL;
16.534 - fopen_s(&fp, file, mode);
16.535 - #else
16.536 - FILE *fp = fopen(file, mode);
16.537 - #endif
16.538 - if (fp == NULL) {
16.539 - SDL_SetError("Couldn't open %s", file);
16.540 - } else {
16.541 - rwops = SDL_RWFromFP(fp, 1);
16.542 - }
16.543 - }
16.544 -#else
16.545 - SDL_SetError("SDL not compiled with stdio support");
16.546 -#endif /* !HAVE_STDIO_H */
16.547 -
16.548 - return (rwops);
16.549 -}
16.550 -
16.551 -#ifdef HAVE_STDIO_H
16.552 -SDL_RWops *
16.553 -SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
16.554 -{
16.555 - SDL_RWops *rwops = NULL;
16.556 -
16.557 - rwops = SDL_AllocRW();
16.558 - if (rwops != NULL) {
16.559 - rwops->size = stdio_size;
16.560 - rwops->seek = stdio_seek;
16.561 - rwops->read = stdio_read;
16.562 - rwops->write = stdio_write;
16.563 - rwops->close = stdio_close;
16.564 - rwops->hidden.stdio.fp = fp;
16.565 - rwops->hidden.stdio.autoclose = autoclose;
16.566 - rwops->type = SDL_RWOPS_STDFILE;
16.567 - }
16.568 - return (rwops);
16.569 -}
16.570 -#else
16.571 -SDL_RWops *
16.572 -SDL_RWFromFP(void * fp, SDL_bool autoclose)
16.573 -{
16.574 - SDL_SetError("SDL not compiled with stdio support");
16.575 - return NULL;
16.576 -}
16.577 -#endif /* HAVE_STDIO_H */
16.578 -
16.579 -SDL_RWops *
16.580 -SDL_RWFromMem(void *mem, int size)
16.581 -{
16.582 - SDL_RWops *rwops = NULL;
16.583 - if (!mem) {
16.584 - SDL_InvalidParamError("mem");
16.585 - return (rwops);
16.586 - }
16.587 - if (!size) {
16.588 - SDL_InvalidParamError("size");
16.589 - return (rwops);
16.590 - }
16.591 -
16.592 - rwops = SDL_AllocRW();
16.593 - if (rwops != NULL) {
16.594 - rwops->size = mem_size;
16.595 - rwops->seek = mem_seek;
16.596 - rwops->read = mem_read;
16.597 - rwops->write = mem_write;
16.598 - rwops->close = mem_close;
16.599 - rwops->hidden.mem.base = (Uint8 *) mem;
16.600 - rwops->hidden.mem.here = rwops->hidden.mem.base;
16.601 - rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
16.602 - rwops->type = SDL_RWOPS_MEMORY;
16.603 - }
16.604 - return (rwops);
16.605 -}
16.606 -
16.607 -SDL_RWops *
16.608 -SDL_RWFromConstMem(const void *mem, int size)
16.609 -{
16.610 - SDL_RWops *rwops = NULL;
16.611 - if (!mem) {
16.612 - SDL_InvalidParamError("mem");
16.613 - return (rwops);
16.614 - }
16.615 - if (!size) {
16.616 - SDL_InvalidParamError("size");
16.617 - return (rwops);
16.618 - }
16.619 -
16.620 - rwops = SDL_AllocRW();
16.621 - if (rwops != NULL) {
16.622 - rwops->size = mem_size;
16.623 - rwops->seek = mem_seek;
16.624 - rwops->read = mem_read;
16.625 - rwops->write = mem_writeconst;
16.626 - rwops->close = mem_close;
16.627 - rwops->hidden.mem.base = (Uint8 *) mem;
16.628 - rwops->hidden.mem.here = rwops->hidden.mem.base;
16.629 - rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
16.630 - rwops->type = SDL_RWOPS_MEMORY_RO;
16.631 - }
16.632 - return (rwops);
16.633 -}
16.634 -
16.635 -SDL_RWops *
16.636 -SDL_AllocRW(void)
16.637 -{
16.638 - SDL_RWops *area;
16.639 -
16.640 - area = (SDL_RWops *) SDL_malloc(sizeof *area);
16.641 - if (area == NULL) {
16.642 - SDL_OutOfMemory();
16.643 - } else {
16.644 - area->type = SDL_RWOPS_UNKNOWN;
16.645 - }
16.646 - return (area);
16.647 -}
16.648 -
16.649 -void
16.650 -SDL_FreeRW(SDL_RWops * area)
16.651 -{
16.652 - SDL_free(area);
16.653 -}
16.654 -
16.655 -/* Functions for dynamically reading and writing endian-specific values */
16.656 -
16.657 -Uint8
16.658 -SDL_ReadU8(SDL_RWops * src)
16.659 -{
16.660 - Uint8 value = 0;
16.661 -
16.662 - SDL_RWread(src, &value, (sizeof value), 1);
16.663 - return value;
16.664 -}
16.665 -
16.666 -Uint16
16.667 -SDL_ReadLE16(SDL_RWops * src)
16.668 -{
16.669 - Uint16 value = 0;
16.670 -
16.671 - SDL_RWread(src, &value, (sizeof value), 1);
16.672 - return (SDL_SwapLE16(value));
16.673 -}
16.674 -
16.675 -Uint16
16.676 -SDL_ReadBE16(SDL_RWops * src)
16.677 -{
16.678 - Uint16 value = 0;
16.679 -
16.680 - SDL_RWread(src, &value, (sizeof value), 1);
16.681 - return (SDL_SwapBE16(value));
16.682 -}
16.683 -
16.684 -Uint32
16.685 -SDL_ReadLE32(SDL_RWops * src)
16.686 -{
16.687 - Uint32 value = 0;
16.688 -
16.689 - SDL_RWread(src, &value, (sizeof value), 1);
16.690 - return (SDL_SwapLE32(value));
16.691 -}
16.692 -
16.693 -Uint32
16.694 -SDL_ReadBE32(SDL_RWops * src)
16.695 -{
16.696 - Uint32 value = 0;
16.697 -
16.698 - SDL_RWread(src, &value, (sizeof value), 1);
16.699 - return (SDL_SwapBE32(value));
16.700 -}
16.701 -
16.702 -Uint64
16.703 -SDL_ReadLE64(SDL_RWops * src)
16.704 -{
16.705 - Uint64 value = 0;
16.706 -
16.707 - SDL_RWread(src, &value, (sizeof value), 1);
16.708 - return (SDL_SwapLE64(value));
16.709 -}
16.710 -
16.711 -Uint64
16.712 -SDL_ReadBE64(SDL_RWops * src)
16.713 -{
16.714 - Uint64 value = 0;
16.715 -
16.716 - SDL_RWread(src, &value, (sizeof value), 1);
16.717 - return (SDL_SwapBE64(value));
16.718 -}
16.719 -
16.720 -size_t
16.721 -SDL_WriteU8(SDL_RWops * dst, Uint8 value)
16.722 -{
16.723 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.724 -}
16.725 -
16.726 -size_t
16.727 -SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
16.728 -{
16.729 - value = SDL_SwapLE16(value);
16.730 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.731 -}
16.732 -
16.733 -size_t
16.734 -SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
16.735 -{
16.736 - value = SDL_SwapBE16(value);
16.737 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.738 -}
16.739 -
16.740 -size_t
16.741 -SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
16.742 -{
16.743 - value = SDL_SwapLE32(value);
16.744 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.745 -}
16.746 -
16.747 -size_t
16.748 -SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
16.749 -{
16.750 - value = SDL_SwapBE32(value);
16.751 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.752 -}
16.753 -
16.754 -size_t
16.755 -SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
16.756 -{
16.757 - value = SDL_SwapLE64(value);
16.758 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.759 -}
16.760 -
16.761 -size_t
16.762 -SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
16.763 -{
16.764 - value = SDL_SwapBE64(value);
16.765 - return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.766 -}
16.767 -
16.768 -/* vi: set ts=4 sw=4 expandtab: */
16.769 +/*
16.770 + Simple DirectMedia Layer
16.771 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
16.772 +
16.773 + This software is provided 'as-is', without any express or implied
16.774 + warranty. In no event will the authors be held liable for any damages
16.775 + arising from the use of this software.
16.776 +
16.777 + Permission is granted to anyone to use this software for any purpose,
16.778 + including commercial applications, and to alter it and redistribute it
16.779 + freely, subject to the following restrictions:
16.780 +
16.781 + 1. The origin of this software must not be misrepresented; you must not
16.782 + claim that you wrote the original software. If you use this software
16.783 + in a product, an acknowledgment in the product documentation would be
16.784 + appreciated but is not required.
16.785 + 2. Altered source versions must be plainly marked as such, and must not be
16.786 + misrepresented as being the original software.
16.787 + 3. This notice may not be removed or altered from any source distribution.
16.788 +*/
16.789 +/* Need this so Linux systems define fseek64o, ftell64o and off64_t */
16.790 +#define _LARGEFILE64_SOURCE
16.791 +#include "SDL_config.h"
16.792 +
16.793 +#if defined(__WIN32__)
16.794 +#include "../core/windows/SDL_windows.h"
16.795 +#endif
16.796 +
16.797 +
16.798 +/* This file provides a general interface for SDL to read and write
16.799 + data sources. It can easily be extended to files, memory, etc.
16.800 +*/
16.801 +
16.802 +#include "SDL_endian.h"
16.803 +#include "SDL_rwops.h"
16.804 +
16.805 +#ifdef __APPLE__
16.806 +#include "cocoa/SDL_rwopsbundlesupport.h"
16.807 +#endif /* __APPLE__ */
16.808 +
16.809 +#ifdef ANDROID
16.810 +#include "../core/android/SDL_android.h"
16.811 +#include "SDL_system.h"
16.812 +#endif
16.813 +
16.814 +#ifdef __WIN32__
16.815 +
16.816 +/* Functions to read/write Win32 API file pointers */
16.817 +
16.818 +#ifndef INVALID_SET_FILE_POINTER
16.819 +#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
16.820 +#endif
16.821 +
16.822 +#define READAHEAD_BUFFER_SIZE 1024
16.823 +
16.824 +static int SDLCALL
16.825 +windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
16.826 +{
16.827 + UINT old_error_mode;
16.828 + HANDLE h;
16.829 + DWORD r_right, w_right;
16.830 + DWORD must_exist, truncate;
16.831 + int a_mode;
16.832 +
16.833 + if (!context)
16.834 + return -1; /* failed (invalid call) */
16.835 +
16.836 + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */
16.837 + context->hidden.windowsio.buffer.data = NULL;
16.838 + context->hidden.windowsio.buffer.size = 0;
16.839 + context->hidden.windowsio.buffer.left = 0;
16.840 +
16.841 + /* "r" = reading, file must exist */
16.842 + /* "w" = writing, truncate existing, file may not exist */
16.843 + /* "r+"= reading or writing, file must exist */
16.844 + /* "a" = writing, append file may not exist */
16.845 + /* "a+"= append + read, file may not exist */
16.846 + /* "w+" = read, write, truncate. file may not exist */
16.847 +
16.848 + must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
16.849 + truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
16.850 + r_right = (SDL_strchr(mode, '+') != NULL
16.851 + || must_exist) ? GENERIC_READ : 0;
16.852 + a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
16.853 + w_right = (a_mode || SDL_strchr(mode, '+')
16.854 + || truncate) ? GENERIC_WRITE : 0;
16.855 +
16.856 + if (!r_right && !w_right) /* inconsistent mode */
16.857 + return -1; /* failed (invalid call) */
16.858 +
16.859 + context->hidden.windowsio.buffer.data =
16.860 + (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
16.861 + if (!context->hidden.windowsio.buffer.data) {
16.862 + return SDL_OutOfMemory();
16.863 + }
16.864 + /* Do not open a dialog box if failure */
16.865 + old_error_mode =
16.866 + SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
16.867 +
16.868 + {
16.869 + LPTSTR tstr = WIN_UTF8ToString(filename);
16.870 + h = CreateFile(tstr, (w_right | r_right),
16.871 + (w_right) ? 0 : FILE_SHARE_READ, NULL,
16.872 + (must_exist | truncate | a_mode),
16.873 + FILE_ATTRIBUTE_NORMAL, NULL);
16.874 + SDL_free(tstr);
16.875 + }
16.876 +
16.877 + /* restore old behavior */
16.878 + SetErrorMode(old_error_mode);
16.879 +
16.880 + if (h == INVALID_HANDLE_VALUE) {
16.881 + SDL_free(context->hidden.windowsio.buffer.data);
16.882 + context->hidden.windowsio.buffer.data = NULL;
16.883 + SDL_SetError("Couldn't open %s", filename);
16.884 + return -2; /* failed (CreateFile) */
16.885 + }
16.886 + context->hidden.windowsio.h = h;
16.887 + context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
16.888 +
16.889 + return 0; /* ok */
16.890 +}
16.891 +
16.892 +static Sint64 SDLCALL
16.893 +windows_file_size(SDL_RWops * context)
16.894 +{
16.895 + LARGE_INTEGER size;
16.896 +
16.897 + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
16.898 + return SDL_SetError("windows_file_size: invalid context/file not opened");
16.899 + }
16.900 +
16.901 + if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
16.902 + return WIN_SetError("windows_file_size");
16.903 + }
16.904 +
16.905 + return size.QuadPart;
16.906 +}
16.907 +
16.908 +static Sint64 SDLCALL
16.909 +windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
16.910 +{
16.911 + DWORD windowswhence;
16.912 + LARGE_INTEGER windowsoffset;
16.913 +
16.914 + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
16.915 + return SDL_SetError("windows_file_seek: invalid context/file not opened");
16.916 + }
16.917 +
16.918 + /* FIXME: We may be able to satisfy the seek within buffered data */
16.919 + if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
16.920 + offset -= (long)context->hidden.windowsio.buffer.left;
16.921 + }
16.922 + context->hidden.windowsio.buffer.left = 0;
16.923 +
16.924 + switch (whence) {
16.925 + case RW_SEEK_SET:
16.926 + windowswhence = FILE_BEGIN;
16.927 + break;
16.928 + case RW_SEEK_CUR:
16.929 + windowswhence = FILE_CURRENT;
16.930 + break;
16.931 + case RW_SEEK_END:
16.932 + windowswhence = FILE_END;
16.933 + break;
16.934 + default:
16.935 + return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
16.936 + }
16.937 +
16.938 + windowsoffset.QuadPart = offset;
16.939 + if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
16.940 + return WIN_SetError("windows_file_seek");
16.941 + }
16.942 + return windowsoffset.QuadPart;
16.943 +}
16.944 +
16.945 +static size_t SDLCALL
16.946 +windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.947 +{
16.948 + size_t total_need;
16.949 + size_t total_read = 0;
16.950 + size_t read_ahead;
16.951 + DWORD byte_read;
16.952 +
16.953 + total_need = size * maxnum;
16.954 +
16.955 + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
16.956 + || !total_need)
16.957 + return 0;
16.958 +
16.959 + if (context->hidden.windowsio.buffer.left > 0) {
16.960 + void *data = (char *) context->hidden.windowsio.buffer.data +
16.961 + context->hidden.windowsio.buffer.size -
16.962 + context->hidden.windowsio.buffer.left;
16.963 + read_ahead =
16.964 + SDL_min(total_need, context->hidden.windowsio.buffer.left);
16.965 + SDL_memcpy(ptr, data, read_ahead);
16.966 + context->hidden.windowsio.buffer.left -= read_ahead;
16.967 +
16.968 + if (read_ahead == total_need) {
16.969 + return maxnum;
16.970 + }
16.971 + ptr = (char *) ptr + read_ahead;
16.972 + total_need -= read_ahead;
16.973 + total_read += read_ahead;
16.974 + }
16.975 +
16.976 + if (total_need < READAHEAD_BUFFER_SIZE) {
16.977 + if (!ReadFile
16.978 + (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
16.979 + READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
16.980 + SDL_Error(SDL_EFREAD);
16.981 + return 0;
16.982 + }
16.983 + read_ahead = SDL_min(total_need, (int) byte_read);
16.984 + SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
16.985 + context->hidden.windowsio.buffer.size = byte_read;
16.986 + context->hidden.windowsio.buffer.left = byte_read - read_ahead;
16.987 + total_read += read_ahead;
16.988 + } else {
16.989 + if (!ReadFile
16.990 + (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
16.991 + SDL_Error(SDL_EFREAD);
16.992 + return 0;
16.993 + }
16.994 + total_read += byte_read;
16.995 + }
16.996 + return (total_read / size);
16.997 +}
16.998 +
16.999 +static size_t SDLCALL
16.1000 +windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
16.1001 + size_t num)
16.1002 +{
16.1003 +
16.1004 + size_t total_bytes;
16.1005 + DWORD byte_written;
16.1006 + size_t nwritten;
16.1007 +
16.1008 + total_bytes = size * num;
16.1009 +
16.1010 + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
16.1011 + || total_bytes <= 0 || !size)
16.1012 + return 0;
16.1013 +
16.1014 + if (context->hidden.windowsio.buffer.left) {
16.1015 + SetFilePointer(context->hidden.windowsio.h,
16.1016 + -(LONG)context->hidden.windowsio.buffer.left, NULL,
16.1017 + FILE_CURRENT);
16.1018 + context->hidden.windowsio.buffer.left = 0;
16.1019 + }
16.1020 +
16.1021 + /* if in append mode, we must go to the EOF before write */
16.1022 + if (context->hidden.windowsio.append) {
16.1023 + if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
16.1024 + INVALID_SET_FILE_POINTER) {
16.1025 + SDL_Error(SDL_EFWRITE);
16.1026 + return 0;
16.1027 + }
16.1028 + }
16.1029 +
16.1030 + if (!WriteFile
16.1031 + (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
16.1032 + SDL_Error(SDL_EFWRITE);
16.1033 + return 0;
16.1034 + }
16.1035 +
16.1036 + nwritten = byte_written / size;
16.1037 + return nwritten;
16.1038 +}
16.1039 +
16.1040 +static int SDLCALL
16.1041 +windows_file_close(SDL_RWops * context)
16.1042 +{
16.1043 +
16.1044 + if (context) {
16.1045 + if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
16.1046 + CloseHandle(context->hidden.windowsio.h);
16.1047 + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */
16.1048 + }
16.1049 + SDL_free(context->hidden.windowsio.buffer.data);
16.1050 + context->hidden.windowsio.buffer.data = NULL;
16.1051 + SDL_FreeRW(context);
16.1052 + }
16.1053 + return (0);
16.1054 +}
16.1055 +#endif /* __WIN32__ */
16.1056 +
16.1057 +#ifdef HAVE_STDIO_H
16.1058 +
16.1059 +/* Functions to read/write stdio file pointers */
16.1060 +
16.1061 +static Sint64 SDLCALL
16.1062 +stdio_size(SDL_RWops * context)
16.1063 +{
16.1064 + Sint64 pos, size;
16.1065 +
16.1066 + pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
16.1067 + if (pos < 0) {
16.1068 + return -1;
16.1069 + }
16.1070 + size = SDL_RWseek(context, 0, RW_SEEK_END);
16.1071 +
16.1072 + SDL_RWseek(context, pos, RW_SEEK_SET);
16.1073 + return size;
16.1074 +}
16.1075 +
16.1076 +static Sint64 SDLCALL
16.1077 +stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
16.1078 +{
16.1079 +#ifdef HAVE_FSEEKO64
16.1080 + if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
16.1081 + return ftello64(context->hidden.stdio.fp);
16.1082 + }
16.1083 +#elif defined(HAVE_FSEEKO)
16.1084 + if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
16.1085 + return ftello(context->hidden.stdio.fp);
16.1086 + }
16.1087 +#elif defined(HAVE__FSEEKI64)
16.1088 + if (_fseeki64(context->hidden.stdio.fp, offset, whence) == 0) {
16.1089 + return _ftelli64(context->hidden.stdio.fp);
16.1090 + }
16.1091 +#else
16.1092 + if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
16.1093 + return (ftell(context->hidden.stdio.fp));
16.1094 + }
16.1095 +#endif
16.1096 + return SDL_Error(SDL_EFSEEK);
16.1097 +}
16.1098 +
16.1099 +static size_t SDLCALL
16.1100 +stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.1101 +{
16.1102 + size_t nread;
16.1103 +
16.1104 + nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
16.1105 + if (nread == 0 && ferror(context->hidden.stdio.fp)) {
16.1106 + SDL_Error(SDL_EFREAD);
16.1107 + }
16.1108 + return (nread);
16.1109 +}
16.1110 +
16.1111 +static size_t SDLCALL
16.1112 +stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.1113 +{
16.1114 + size_t nwrote;
16.1115 +
16.1116 + nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
16.1117 + if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
16.1118 + SDL_Error(SDL_EFWRITE);
16.1119 + }
16.1120 + return (nwrote);
16.1121 +}
16.1122 +
16.1123 +static int SDLCALL
16.1124 +stdio_close(SDL_RWops * context)
16.1125 +{
16.1126 + int status = 0;
16.1127 + if (context) {
16.1128 + if (context->hidden.stdio.autoclose) {
16.1129 + /* WARNING: Check the return value here! */
16.1130 + if (fclose(context->hidden.stdio.fp) != 0) {
16.1131 + status = SDL_Error(SDL_EFWRITE);
16.1132 + }
16.1133 + }
16.1134 + SDL_FreeRW(context);
16.1135 + }
16.1136 + return status;
16.1137 +}
16.1138 +#endif /* !HAVE_STDIO_H */
16.1139 +
16.1140 +/* Functions to read/write memory pointers */
16.1141 +
16.1142 +static Sint64 SDLCALL
16.1143 +mem_size(SDL_RWops * context)
16.1144 +{
16.1145 + return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
16.1146 +}
16.1147 +
16.1148 +static Sint64 SDLCALL
16.1149 +mem_seek(SDL_RWops * context, Sint64 offset, int whence)
16.1150 +{
16.1151 + Uint8 *newpos;
16.1152 +
16.1153 + switch (whence) {
16.1154 + case RW_SEEK_SET:
16.1155 + newpos = context->hidden.mem.base + offset;
16.1156 + break;
16.1157 + case RW_SEEK_CUR:
16.1158 + newpos = context->hidden.mem.here + offset;
16.1159 + break;
16.1160 + case RW_SEEK_END:
16.1161 + newpos = context->hidden.mem.stop + offset;
16.1162 + break;
16.1163 + default:
16.1164 + return SDL_SetError("Unknown value for 'whence'");
16.1165 + }
16.1166 + if (newpos < context->hidden.mem.base) {
16.1167 + newpos = context->hidden.mem.base;
16.1168 + }
16.1169 + if (newpos > context->hidden.mem.stop) {
16.1170 + newpos = context->hidden.mem.stop;
16.1171 + }
16.1172 + context->hidden.mem.here = newpos;
16.1173 + return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
16.1174 +}
16.1175 +
16.1176 +static size_t SDLCALL
16.1177 +mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
16.1178 +{
16.1179 + size_t total_bytes;
16.1180 + size_t mem_available;
16.1181 +
16.1182 + total_bytes = (maxnum * size);
16.1183 + if ((maxnum <= 0) || (size <= 0)
16.1184 + || ((total_bytes / maxnum) != (size_t) size)) {
16.1185 + return 0;
16.1186 + }
16.1187 +
16.1188 + mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
16.1189 + if (total_bytes > mem_available) {
16.1190 + total_bytes = mem_available;
16.1191 + }
16.1192 +
16.1193 + SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
16.1194 + context->hidden.mem.here += total_bytes;
16.1195 +
16.1196 + return (total_bytes / size);
16.1197 +}
16.1198 +
16.1199 +static size_t SDLCALL
16.1200 +mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.1201 +{
16.1202 + if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
16.1203 + num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
16.1204 + }
16.1205 + SDL_memcpy(context->hidden.mem.here, ptr, num * size);
16.1206 + context->hidden.mem.here += num * size;
16.1207 + return (num);
16.1208 +}
16.1209 +
16.1210 +static size_t SDLCALL
16.1211 +mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
16.1212 +{
16.1213 + SDL_SetError("Can't write to read-only memory");
16.1214 + return (0);
16.1215 +}
16.1216 +
16.1217 +static int SDLCALL
16.1218 +mem_close(SDL_RWops * context)
16.1219 +{
16.1220 + if (context) {
16.1221 + SDL_FreeRW(context);
16.1222 + }
16.1223 + return (0);
16.1224 +}
16.1225 +
16.1226 +
16.1227 +/* Functions to create SDL_RWops structures from various data sources */
16.1228 +
16.1229 +SDL_RWops *
16.1230 +SDL_RWFromFile(const char *file, const char *mode)
16.1231 +{
16.1232 + SDL_RWops *rwops = NULL;
16.1233 + if (!file || !*file || !mode || !*mode) {
16.1234 + SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
16.1235 + return NULL;
16.1236 + }
16.1237 +#if defined(ANDROID)
16.1238 +#ifdef HAVE_STDIO_H
16.1239 + /* Try to open the file on the filesystem first */
16.1240 + if (*file == '/') {
16.1241 + FILE *fp = fopen(file, mode);
16.1242 + if (fp) {
16.1243 + return SDL_RWFromFP(fp, 1);
16.1244 + }
16.1245 + } else {
16.1246 + /* Try opening it from internal storage if it's a relative path */
16.1247 + char *path;
16.1248 + FILE *fp;
16.1249 +
16.1250 + path = SDL_stack_alloc(char, PATH_MAX);
16.1251 + if (path) {
16.1252 + SDL_snprintf(path, PATH_MAX, "%s/%s",
16.1253 + SDL_AndroidGetInternalStoragePath(), file);
16.1254 + fp = fopen(path, mode);
16.1255 + SDL_stack_free(path);
16.1256 + if (fp) {
16.1257 + return SDL_RWFromFP(fp, 1);
16.1258 + }
16.1259 + }
16.1260 + }
16.1261 +#endif /* HAVE_STDIO_H */
16.1262 +
16.1263 + /* Try to open the file from the asset system */
16.1264 + rwops = SDL_AllocRW();
16.1265 + if (!rwops)
16.1266 + return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
16.1267 + if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
16.1268 + SDL_FreeRW(rwops);
16.1269 + return NULL;
16.1270 + }
16.1271 + rwops->size = Android_JNI_FileSize;
16.1272 + rwops->seek = Android_JNI_FileSeek;
16.1273 + rwops->read = Android_JNI_FileRead;
16.1274 + rwops->write = Android_JNI_FileWrite;
16.1275 + rwops->close = Android_JNI_FileClose;
16.1276 + rwops->type = SDL_RWOPS_JNIFILE;
16.1277 +
16.1278 +#elif defined(__WIN32__)
16.1279 + rwops = SDL_AllocRW();
16.1280 + if (!rwops)
16.1281 + return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
16.1282 + if (windows_file_open(rwops, file, mode) < 0) {
16.1283 + SDL_FreeRW(rwops);
16.1284 + return NULL;
16.1285 + }
16.1286 + rwops->size = windows_file_size;
16.1287 + rwops->seek = windows_file_seek;
16.1288 + rwops->read = windows_file_read;
16.1289 + rwops->write = windows_file_write;
16.1290 + rwops->close = windows_file_close;
16.1291 + rwops->type = SDL_RWOPS_WINFILE;
16.1292 +
16.1293 +#elif HAVE_STDIO_H
16.1294 + {
16.1295 + #ifdef __APPLE__
16.1296 + FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
16.1297 + #elif __WINRT__
16.1298 + FILE *fp = NULL;
16.1299 + fopen_s(&fp, file, mode);
16.1300 + #else
16.1301 + FILE *fp = fopen(file, mode);
16.1302 + #endif
16.1303 + if (fp == NULL) {
16.1304 + SDL_SetError("Couldn't open %s", file);
16.1305 + } else {
16.1306 + rwops = SDL_RWFromFP(fp, 1);
16.1307 + }
16.1308 + }
16.1309 +#else
16.1310 + SDL_SetError("SDL not compiled with stdio support");
16.1311 +#endif /* !HAVE_STDIO_H */
16.1312 +
16.1313 + return (rwops);
16.1314 +}
16.1315 +
16.1316 +#ifdef HAVE_STDIO_H
16.1317 +SDL_RWops *
16.1318 +SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
16.1319 +{
16.1320 + SDL_RWops *rwops = NULL;
16.1321 +
16.1322 + rwops = SDL_AllocRW();
16.1323 + if (rwops != NULL) {
16.1324 + rwops->size = stdio_size;
16.1325 + rwops->seek = stdio_seek;
16.1326 + rwops->read = stdio_read;
16.1327 + rwops->write = stdio_write;
16.1328 + rwops->close = stdio_close;
16.1329 + rwops->hidden.stdio.fp = fp;
16.1330 + rwops->hidden.stdio.autoclose = autoclose;
16.1331 + rwops->type = SDL_RWOPS_STDFILE;
16.1332 + }
16.1333 + return (rwops);
16.1334 +}
16.1335 +#else
16.1336 +SDL_RWops *
16.1337 +SDL_RWFromFP(void * fp, SDL_bool autoclose)
16.1338 +{
16.1339 + SDL_SetError("SDL not compiled with stdio support");
16.1340 + return NULL;
16.1341 +}
16.1342 +#endif /* HAVE_STDIO_H */
16.1343 +
16.1344 +SDL_RWops *
16.1345 +SDL_RWFromMem(void *mem, int size)
16.1346 +{
16.1347 + SDL_RWops *rwops = NULL;
16.1348 + if (!mem) {
16.1349 + SDL_InvalidParamError("mem");
16.1350 + return (rwops);
16.1351 + }
16.1352 + if (!size) {
16.1353 + SDL_InvalidParamError("size");
16.1354 + return (rwops);
16.1355 + }
16.1356 +
16.1357 + rwops = SDL_AllocRW();
16.1358 + if (rwops != NULL) {
16.1359 + rwops->size = mem_size;
16.1360 + rwops->seek = mem_seek;
16.1361 + rwops->read = mem_read;
16.1362 + rwops->write = mem_write;
16.1363 + rwops->close = mem_close;
16.1364 + rwops->hidden.mem.base = (Uint8 *) mem;
16.1365 + rwops->hidden.mem.here = rwops->hidden.mem.base;
16.1366 + rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
16.1367 + rwops->type = SDL_RWOPS_MEMORY;
16.1368 + }
16.1369 + return (rwops);
16.1370 +}
16.1371 +
16.1372 +SDL_RWops *
16.1373 +SDL_RWFromConstMem(const void *mem, int size)
16.1374 +{
16.1375 + SDL_RWops *rwops = NULL;
16.1376 + if (!mem) {
16.1377 + SDL_InvalidParamError("mem");
16.1378 + return (rwops);
16.1379 + }
16.1380 + if (!size) {
16.1381 + SDL_InvalidParamError("size");
16.1382 + return (rwops);
16.1383 + }
16.1384 +
16.1385 + rwops = SDL_AllocRW();
16.1386 + if (rwops != NULL) {
16.1387 + rwops->size = mem_size;
16.1388 + rwops->seek = mem_seek;
16.1389 + rwops->read = mem_read;
16.1390 + rwops->write = mem_writeconst;
16.1391 + rwops->close = mem_close;
16.1392 + rwops->hidden.mem.base = (Uint8 *) mem;
16.1393 + rwops->hidden.mem.here = rwops->hidden.mem.base;
16.1394 + rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
16.1395 + rwops->type = SDL_RWOPS_MEMORY_RO;
16.1396 + }
16.1397 + return (rwops);
16.1398 +}
16.1399 +
16.1400 +SDL_RWops *
16.1401 +SDL_AllocRW(void)
16.1402 +{
16.1403 + SDL_RWops *area;
16.1404 +
16.1405 + area = (SDL_RWops *) SDL_malloc(sizeof *area);
16.1406 + if (area == NULL) {
16.1407 + SDL_OutOfMemory();
16.1408 + } else {
16.1409 + area->type = SDL_RWOPS_UNKNOWN;
16.1410 + }
16.1411 + return (area);
16.1412 +}
16.1413 +
16.1414 +void
16.1415 +SDL_FreeRW(SDL_RWops * area)
16.1416 +{
16.1417 + SDL_free(area);
16.1418 +}
16.1419 +
16.1420 +/* Functions for dynamically reading and writing endian-specific values */
16.1421 +
16.1422 +Uint8
16.1423 +SDL_ReadU8(SDL_RWops * src)
16.1424 +{
16.1425 + Uint8 value = 0;
16.1426 +
16.1427 + SDL_RWread(src, &value, (sizeof value), 1);
16.1428 + return value;
16.1429 +}
16.1430 +
16.1431 +Uint16
16.1432 +SDL_ReadLE16(SDL_RWops * src)
16.1433 +{
16.1434 + Uint16 value = 0;
16.1435 +
16.1436 + SDL_RWread(src, &value, (sizeof value), 1);
16.1437 + return (SDL_SwapLE16(value));
16.1438 +}
16.1439 +
16.1440 +Uint16
16.1441 +SDL_ReadBE16(SDL_RWops * src)
16.1442 +{
16.1443 + Uint16 value = 0;
16.1444 +
16.1445 + SDL_RWread(src, &value, (sizeof value), 1);
16.1446 + return (SDL_SwapBE16(value));
16.1447 +}
16.1448 +
16.1449 +Uint32
16.1450 +SDL_ReadLE32(SDL_RWops * src)
16.1451 +{
16.1452 + Uint32 value = 0;
16.1453 +
16.1454 + SDL_RWread(src, &value, (sizeof value), 1);
16.1455 + return (SDL_SwapLE32(value));
16.1456 +}
16.1457 +
16.1458 +Uint32
16.1459 +SDL_ReadBE32(SDL_RWops * src)
16.1460 +{
16.1461 + Uint32 value = 0;
16.1462 +
16.1463 + SDL_RWread(src, &value, (sizeof value), 1);
16.1464 + return (SDL_SwapBE32(value));
16.1465 +}
16.1466 +
16.1467 +Uint64
16.1468 +SDL_ReadLE64(SDL_RWops * src)
16.1469 +{
16.1470 + Uint64 value = 0;
16.1471 +
16.1472 + SDL_RWread(src, &value, (sizeof value), 1);
16.1473 + return (SDL_SwapLE64(value));
16.1474 +}
16.1475 +
16.1476 +Uint64
16.1477 +SDL_ReadBE64(SDL_RWops * src)
16.1478 +{
16.1479 + Uint64 value = 0;
16.1480 +
16.1481 + SDL_RWread(src, &value, (sizeof value), 1);
16.1482 + return (SDL_SwapBE64(value));
16.1483 +}
16.1484 +
16.1485 +size_t
16.1486 +SDL_WriteU8(SDL_RWops * dst, Uint8 value)
16.1487 +{
16.1488 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1489 +}
16.1490 +
16.1491 +size_t
16.1492 +SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
16.1493 +{
16.1494 + value = SDL_SwapLE16(value);
16.1495 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1496 +}
16.1497 +
16.1498 +size_t
16.1499 +SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
16.1500 +{
16.1501 + value = SDL_SwapBE16(value);
16.1502 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1503 +}
16.1504 +
16.1505 +size_t
16.1506 +SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
16.1507 +{
16.1508 + value = SDL_SwapLE32(value);
16.1509 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1510 +}
16.1511 +
16.1512 +size_t
16.1513 +SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
16.1514 +{
16.1515 + value = SDL_SwapBE32(value);
16.1516 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1517 +}
16.1518 +
16.1519 +size_t
16.1520 +SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
16.1521 +{
16.1522 + value = SDL_SwapLE64(value);
16.1523 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1524 +}
16.1525 +
16.1526 +size_t
16.1527 +SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
16.1528 +{
16.1529 + value = SDL_SwapBE64(value);
16.1530 + return (SDL_RWwrite(dst, &value, (sizeof value), 1));
16.1531 +}
16.1532 +
16.1533 +/* vi: set ts=4 sw=4 expandtab: */
17.1 --- a/src/filesystem/winrt/SDL_sysfilesystem.cpp Tue Mar 04 19:49:11 2014 -0500
17.2 +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp Sun Mar 09 11:06:11 2014 -0700
17.3 @@ -1,154 +1,154 @@
17.4 -/* TODO, WinRT: include copyright info in SDL_winrtpaths.cpp
17.5 - TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all
17.6 -*/
17.7 -
17.8 -#include "SDL_config.h"
17.9 -
17.10 -#ifdef __WINRT__
17.11 -
17.12 -extern "C" {
17.13 -#include "SDL_filesystem.h"
17.14 -#include "SDL_error.h"
17.15 -#include "SDL_stdinc.h"
17.16 -#include "SDL_system.h"
17.17 -#include "../../core/windows/SDL_windows.h"
17.18 -}
17.19 -
17.20 -#include <string>
17.21 -#include <unordered_map>
17.22 -
17.23 -using namespace std;
17.24 -using namespace Windows::Storage;
17.25 -
17.26 -extern "C" const wchar_t *
17.27 -SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
17.28 -{
17.29 - switch (pathType) {
17.30 - case SDL_WINRT_PATH_INSTALLED_LOCATION:
17.31 - {
17.32 - static wstring path;
17.33 - if (path.empty()) {
17.34 - path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
17.35 - }
17.36 - return path.c_str();
17.37 - }
17.38 -
17.39 - case SDL_WINRT_PATH_LOCAL_FOLDER:
17.40 - {
17.41 - static wstring path;
17.42 - if (path.empty()) {
17.43 - path = ApplicationData::Current->LocalFolder->Path->Data();
17.44 - }
17.45 - return path.c_str();
17.46 - }
17.47 -
17.48 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
17.49 - case SDL_WINRT_PATH_ROAMING_FOLDER:
17.50 - {
17.51 - static wstring path;
17.52 - if (path.empty()) {
17.53 - path = ApplicationData::Current->RoamingFolder->Path->Data();
17.54 - }
17.55 - return path.c_str();
17.56 - }
17.57 -
17.58 - case SDL_WINRT_PATH_TEMP_FOLDER:
17.59 - {
17.60 - static wstring path;
17.61 - if (path.empty()) {
17.62 - path = ApplicationData::Current->TemporaryFolder->Path->Data();
17.63 - }
17.64 - return path.c_str();
17.65 - }
17.66 -#endif
17.67 -
17.68 - default:
17.69 - break;
17.70 - }
17.71 -
17.72 - SDL_Unsupported();
17.73 - return NULL;
17.74 -}
17.75 -
17.76 -extern "C" const char *
17.77 -SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
17.78 -{
17.79 - typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
17.80 - static UTF8PathMap utf8Paths;
17.81 -
17.82 - UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
17.83 - if (searchResult != utf8Paths.end()) {
17.84 - return searchResult->second.c_str();
17.85 - }
17.86 -
17.87 - const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
17.88 - if (!ucs2Path) {
17.89 - return NULL;
17.90 - }
17.91 -
17.92 - char * utf8Path = WIN_StringToUTF8(ucs2Path);
17.93 - utf8Paths[pathType] = utf8Path;
17.94 - SDL_free(utf8Path);
17.95 - return utf8Paths[pathType].c_str();
17.96 -}
17.97 -
17.98 -extern "C" char *
17.99 -SDL_GetBasePath(void)
17.100 -{
17.101 - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION);
17.102 - size_t destPathLen;
17.103 - char * destPath = NULL;
17.104 -
17.105 - if (!srcPath) {
17.106 - SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
17.107 - return NULL;
17.108 - }
17.109 -
17.110 - destPathLen = SDL_strlen(srcPath) + 2;
17.111 - destPath = (char *) SDL_malloc(destPathLen);
17.112 - if (!destPath) {
17.113 - SDL_OutOfMemory();
17.114 - return NULL;
17.115 - }
17.116 -
17.117 - SDL_snprintf(destPath, destPathLen, "%s\\", srcPath);
17.118 - return destPath;
17.119 -}
17.120 -
17.121 -extern "C" char *
17.122 -SDL_GetPrefPath(const char *org, const char *app)
17.123 -{
17.124 - /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and
17.125 - * earlier is not available on WinRT or Windows Phone. WinRT provides
17.126 - * a similar API, but SHGetFolderPath can't be called, at least not
17.127 - * without violating Microsoft's app-store requirements.
17.128 - */
17.129 -
17.130 -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
17.131 - /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */
17.132 - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER);
17.133 -#else
17.134 - /* A 'Roaming' folder is available on Windows 8 and 8.1. Use that. */
17.135 - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_ROAMING_FOLDER);
17.136 -#endif
17.137 -
17.138 - size_t destPathLen;
17.139 - char * destPath = NULL;
17.140 -
17.141 - if (!srcPath) {
17.142 - SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
17.143 - return NULL;
17.144 - }
17.145 -
17.146 - destPathLen = SDL_strlen(srcPath) + SDL_strlen(org) + SDL_strlen(app) + 4;
17.147 - destPath = (char *) SDL_malloc(destPathLen);
17.148 - if (!destPath) {
17.149 - SDL_OutOfMemory();
17.150 - return NULL;
17.151 - }
17.152 -
17.153 - SDL_snprintf(destPath, destPathLen, "%s\\%s\\%s\\", srcPath, org, app);
17.154 - return destPath;
17.155 -}
17.156 -
17.157 -#endif /* __WINRT__ */
17.158 +/* TODO, WinRT: include copyright info in SDL_winrtpaths.cpp
17.159 + TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all
17.160 +*/
17.161 +
17.162 +#include "SDL_config.h"
17.163 +
17.164 +#ifdef __WINRT__
17.165 +
17.166 +extern "C" {
17.167 +#include "SDL_filesystem.h"
17.168 +#include "SDL_error.h"
17.169 +#include "SDL_stdinc.h"
17.170 +#include "SDL_system.h"
17.171 +#include "../../core/windows/SDL_windows.h"
17.172 +}
17.173 +
17.174 +#include <string>
17.175 +#include <unordered_map>
17.176 +
17.177 +using namespace std;
17.178 +using namespace Windows::Storage;
17.179 +
17.180 +extern "C" const wchar_t *
17.181 +SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
17.182 +{
17.183 + switch (pathType) {
17.184 + case SDL_WINRT_PATH_INSTALLED_LOCATION:
17.185 + {
17.186 + static wstring path;
17.187 + if (path.empty()) {
17.188 + path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
17.189 + }
17.190 + return path.c_str();
17.191 + }
17.192 +
17.193 + case SDL_WINRT_PATH_LOCAL_FOLDER:
17.194 + {
17.195 + static wstring path;
17.196 + if (path.empty()) {
17.197 + path = ApplicationData::Current->LocalFolder->Path->Data();
17.198 + }
17.199 + return path.c_str();
17.200 + }
17.201 +
17.202 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
17.203 + case SDL_WINRT_PATH_ROAMING_FOLDER:
17.204 + {
17.205 + static wstring path;
17.206 + if (path.empty()) {
17.207 + path = ApplicationData::Current->RoamingFolder->Path->Data();
17.208 + }
17.209 + return path.c_str();
17.210 + }
17.211 +
17.212 + case SDL_WINRT_PATH_TEMP_FOLDER:
17.213 + {
17.214 + static wstring path;
17.215 + if (path.empty()) {
17.216 + path = ApplicationData::Current->TemporaryFolder->Path->Data();
17.217 + }
17.218 + return path.c_str();
17.219 + }
17.220 +#endif
17.221 +
17.222 + default:
17.223 + break;
17.224 + }
17.225 +
17.226 + SDL_Unsupported();
17.227 + return NULL;
17.228 +}
17.229 +
17.230 +extern "C" const char *
17.231 +SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
17.232 +{
17.233 + typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
17.234 + static UTF8PathMap utf8Paths;
17.235 +
17.236 + UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
17.237 + if (searchResult != utf8Paths.end()) {
17.238 + return searchResult->second.c_str();
17.239 + }
17.240 +
17.241 + const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
17.242 + if (!ucs2Path) {
17.243 + return NULL;
17.244 + }
17.245 +
17.246 + char * utf8Path = WIN_StringToUTF8(ucs2Path);
17.247 + utf8Paths[pathType] = utf8Path;
17.248 + SDL_free(utf8Path);
17.249 + return utf8Paths[pathType].c_str();
17.250 +}
17.251 +
17.252 +extern "C" char *
17.253 +SDL_GetBasePath(void)
17.254 +{
17.255 + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION);
17.256 + size_t destPathLen;
17.257 + char * destPath = NULL;
17.258 +
17.259 + if (!srcPath) {
17.260 + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
17.261 + return NULL;
17.262 + }
17.263 +
17.264 + destPathLen = SDL_strlen(srcPath) + 2;
17.265 + destPath = (char *) SDL_malloc(destPathLen);
17.266 + if (!destPath) {
17.267 + SDL_OutOfMemory();
17.268 + return NULL;
17.269 + }
17.270 +
17.271 + SDL_snprintf(destPath, destPathLen, "%s\\", srcPath);
17.272 + return destPath;
17.273 +}
17.274 +
17.275 +extern "C" char *
17.276 +SDL_GetPrefPath(const char *org, const char *app)
17.277 +{
17.278 + /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and
17.279 + * earlier is not available on WinRT or Windows Phone. WinRT provides
17.280 + * a similar API, but SHGetFolderPath can't be called, at least not
17.281 + * without violating Microsoft's app-store requirements.
17.282 + */
17.283 +
17.284 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
17.285 + /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */
17.286 + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER);
17.287 +#else
17.288 + /* A 'Roaming' folder is available on Windows 8 and 8.1. Use that. */
17.289 + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_ROAMING_FOLDER);
17.290 +#endif
17.291 +
17.292 + size_t destPathLen;
17.293 + char * destPath = NULL;
17.294 +
17.295 + if (!srcPath) {
17.296 + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError());
17.297 + return NULL;
17.298 + }
17.299 +
17.300 + destPathLen = SDL_strlen(srcPath) + SDL_strlen(org) + SDL_strlen(app) + 4;
17.301 + destPath = (char *) SDL_malloc(destPathLen);
17.302 + if (!destPath) {
17.303 + SDL_OutOfMemory();
17.304 + return NULL;
17.305 + }
17.306 +
17.307 + SDL_snprintf(destPath, destPathLen, "%s\\%s\\%s\\", srcPath, org, app);
17.308 + return destPath;
17.309 +}
17.310 +
17.311 +#endif /* __WINRT__ */
18.1 --- a/src/joystick/SDL_gamecontroller.c Tue Mar 04 19:49:11 2014 -0500
18.2 +++ b/src/joystick/SDL_gamecontroller.c Sun Mar 09 11:06:11 2014 -0700
18.3 @@ -1,1247 +1,1247 @@
18.4 -/*
18.5 - Simple DirectMedia Layer
18.6 - Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
18.7 -
18.8 - This software is provided 'as-is', without any express or implied
18.9 - warranty. In no event will the authors be held liable for any damages
18.10 - arising from the use of this software.
18.11 -
18.12 - Permission is granted to anyone to use this software for any purpose,
18.13 - including commercial applications, and to alter it and redistribute it
18.14 - freely, subject to the following restrictions:
18.15 -
18.16 - 1. The origin of this software must not be misrepresented; you must not
18.17 - claim that you wrote the original software. If you use this software
18.18 - in a product, an acknowledgment in the product documentation would be
18.19 - appreciated but is not required.
18.20 - 2. Altered source versions must be plainly marked as such, and must not be
18.21 - misrepresented as being the original software.
18.22 - 3. This notice may not be removed or altered from any source distribution.
18.23 -*/
18.24 -#include "SDL_config.h"
18.25 -
18.26 -/* This is the game controller API for Simple DirectMedia Layer */
18.27 -
18.28 -#include "SDL_events.h"
18.29 -#include "SDL_assert.h"
18.30 -#include "SDL_sysjoystick.h"
18.31 -#include "SDL_hints.h"
18.32 -#include "SDL_gamecontrollerdb.h"
18.33 -
18.34 -#if !SDL_EVENTS_DISABLED
18.35 -#include "../events/SDL_events_c.h"
18.36 -#endif
18.37 -#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
18.38 -
18.39 -
18.40 -/* a list of currently opened game controllers */
18.41 -static SDL_GameController *SDL_gamecontrollers = NULL;
18.42 -
18.43 -/* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
18.44 -struct _SDL_HatMapping
18.45 -{
18.46 - int hat;
18.47 - Uint8 mask;
18.48 -};
18.49 -
18.50 -#define k_nMaxReverseEntries 20
18.51 -
18.52 -/**
18.53 - * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
18.54 - * MAX 4 hats supported
18.55 - */
18.56 -#define k_nMaxHatEntries 0x3f + 1
18.57 -
18.58 -/* our in memory mapping db between joystick objects and controller mappings */
18.59 -struct _SDL_ControllerMapping
18.60 -{
18.61 - SDL_JoystickGUID guid;
18.62 - const char *name;
18.63 -
18.64 - /* mapping of axis/button id to controller version */
18.65 - int axes[SDL_CONTROLLER_AXIS_MAX];
18.66 - int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
18.67 -
18.68 - int buttons[SDL_CONTROLLER_BUTTON_MAX];
18.69 - int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
18.70 - struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
18.71 -
18.72 - /* reverse mapping, joystick indices to buttons */
18.73 - SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
18.74 - SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
18.75 -
18.76 - SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
18.77 - SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
18.78 - SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
18.79 -
18.80 -};
18.81 -
18.82 -
18.83 -/* our hard coded list of mapping support */
18.84 -typedef struct _ControllerMapping_t
18.85 -{
18.86 - SDL_JoystickGUID guid;
18.87 - char *name;
18.88 - char *mapping;
18.89 - struct _ControllerMapping_t *next;
18.90 -} ControllerMapping_t;
18.91 -
18.92 -static ControllerMapping_t *s_pSupportedControllers = NULL;
18.93 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
18.94 -static ControllerMapping_t *s_pXInputMapping = NULL;
18.95 -#endif
18.96 -
18.97 -/* The SDL game controller structure */
18.98 -struct _SDL_GameController
18.99 -{
18.100 - SDL_Joystick *joystick; /* underlying joystick device */
18.101 - int ref_count;
18.102 - Uint8 hatState[4]; /* the current hat state for this controller */
18.103 - struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
18.104 - struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
18.105 -};
18.106 -
18.107 -
18.108 -int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
18.109 -int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
18.110 -
18.111 -/*
18.112 - * Event filter to fire controller events from joystick ones
18.113 - */
18.114 -int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
18.115 -{
18.116 - switch( event->type )
18.117 - {
18.118 - case SDL_JOYAXISMOTION:
18.119 - {
18.120 - SDL_GameController *controllerlist;
18.121 -
18.122 - if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;
18.123 -
18.124 - controllerlist = SDL_gamecontrollers;
18.125 - while ( controllerlist )
18.126 - {
18.127 - if ( controllerlist->joystick->instance_id == event->jaxis.which )
18.128 - {
18.129 - if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */
18.130 - {
18.131 - SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
18.132 - Sint16 value = event->jaxis.value;
18.133 - switch (axis)
18.134 - {
18.135 - case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
18.136 - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
18.137 - /* Shift it to be 0 - 32767. */
18.138 - value = value / 2 + 16384;
18.139 - default:
18.140 - break;
18.141 - }
18.142 - SDL_PrivateGameControllerAxis( controllerlist, axis, value );
18.143 - }
18.144 - else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */
18.145 - {
18.146 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
18.147 - }
18.148 - break;
18.149 - }
18.150 - controllerlist = controllerlist->next;
18.151 - }
18.152 - }
18.153 - break;
18.154 - case SDL_JOYBUTTONDOWN:
18.155 - case SDL_JOYBUTTONUP:
18.156 - {
18.157 - SDL_GameController *controllerlist;
18.158 -
18.159 - if ( event->jbutton.button >= k_nMaxReverseEntries ) break;
18.160 -
18.161 - controllerlist = SDL_gamecontrollers;
18.162 - while ( controllerlist )
18.163 - {
18.164 - if ( controllerlist->joystick->instance_id == event->jbutton.which )
18.165 - {
18.166 - if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */
18.167 - {
18.168 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
18.169 - }
18.170 - else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */
18.171 - {
18.172 - SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
18.173 - }
18.174 - break;
18.175 - }
18.176 - controllerlist = controllerlist->next;
18.177 - }
18.178 - }
18.179 - break;
18.180 - case SDL_JOYHATMOTION:
18.181 - {
18.182 - SDL_GameController *controllerlist;
18.183 -
18.184 - if ( event->jhat.hat >= 4 ) break;
18.185 -
18.186 - controllerlist = SDL_gamecontrollers;
18.187 - while ( controllerlist )
18.188 - {
18.189 - if ( controllerlist->joystick->instance_id == event->jhat.which )
18.190 - {
18.191 - Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
18.192 - /* Get list of removed bits (button release) */
18.193 - Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
18.194 - /* the hat idx in the high nibble */
18.195 - int bHighHat = event->jhat.hat << 4;
18.196 -
18.197 - if ( bChanged & SDL_HAT_DOWN )
18.198 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
18.199 - if ( bChanged & SDL_HAT_UP )
18.200 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
18.201 - if ( bChanged & SDL_HAT_LEFT )
18.202 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
18.203 - if ( bChanged & SDL_HAT_RIGHT )
18.204 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );
18.205 -
18.206 - /* Get list of added bits (button press) */
18.207 - bChanged = event->jhat.value ^ bSame;
18.208 -
18.209 - if ( bChanged & SDL_HAT_DOWN )
18.210 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
18.211 - if ( bChanged & SDL_HAT_UP )
18.212 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
18.213 - if ( bChanged & SDL_HAT_LEFT )
18.214 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
18.215 - if ( bChanged & SDL_HAT_RIGHT )
18.216 - SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );
18.217 -
18.218 - /* update our state cache */
18.219 - controllerlist->hatState[event->jhat.hat] = event->jhat.value;
18.220 -
18.221 - break;
18.222 - }
18.223 - controllerlist = controllerlist->next;
18.224 - }
18.225 - }
18.226 - break;
18.227 - case SDL_JOYDEVICEADDED:
18.228 - {
18.229 - if ( SDL_IsGameController(event->jdevice.which ) )
18.230 - {
18.231 - SDL_Event deviceevent;
18.232 - deviceevent.type = SDL_CONTROLLERDEVICEADDED;
18.233 - deviceevent.cdevice.which = event->jdevice.which;
18.234 - SDL_PushEvent(&deviceevent);
18.235 - }
18.236 - }
18.237 - break;
18.238 - case SDL_JOYDEVICEREMOVED:
18.239 - {
18.240 - SDL_GameController *controllerlist = SDL_gamecontrollers;
18.241 - while ( controllerlist )
18.242 - {
18.243 - if ( controllerlist->joystick->instance_id == event->jdevice.which )
18.244 - {
18.245 - SDL_Event deviceevent;
18.246 - deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
18.247 - deviceevent.cdevice.which = event->jdevice.which;
18.248 - SDL_PushEvent(&deviceevent);
18.249 - break;
18.250 - }
18.251 - controllerlist = controllerlist->next;
18.252 - }
18.253 - }
18.254 - break;
18.255 - default:
18.256 - break;
18.257 - }
18.258 -
18.259 - return 1;
18.260 -}
18.261 -
18.262 -/*
18.263 - * Helper function to scan the mappings database for a controller with the specified GUID
18.264 - */
18.265 -ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
18.266 -{
18.267 - ControllerMapping_t *pSupportedController = s_pSupportedControllers;
18.268 - while ( pSupportedController )
18.269 - {
18.270 - if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
18.271 - {
18.272 - return pSupportedController;
18.273 - }
18.274 - pSupportedController = pSupportedController->next;
18.275 - }
18.276 - return NULL;
18.277 -}
18.278 -
18.279 -/*
18.280 - * Helper function to determine pre-calculated offset to certain joystick mappings
18.281 - */
18.282 -ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
18.283 -{
18.284 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
18.285 - if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
18.286 - {
18.287 - return s_pXInputMapping;
18.288 - }
18.289 - else
18.290 -#endif
18.291 - {
18.292 - SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
18.293 - return SDL_PrivateGetControllerMappingForGUID(&jGUID);
18.294 - }
18.295 -}
18.296 -
18.297 -static const char* map_StringForControllerAxis[] = {
18.298 - "leftx",
18.299 - "lefty",
18.300 - "rightx",
18.301 - "righty",
18.302 - "lefttrigger",
18.303 - "righttrigger",
18.304 - NULL
18.305 -};
18.306 -
18.307 -/*
18.308 - * convert a string to its enum equivalent
18.309 - */
18.310 -SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
18.311 -{
18.312 - int entry;
18.313 - if ( !pchString || !pchString[0] )
18.314 - return SDL_CONTROLLER_AXIS_INVALID;
18.315 -
18.316 - for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
18.317 - {
18.318 - if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
18.319 - return entry;
18.320 - }
18.321 - return SDL_CONTROLLER_AXIS_INVALID;
18.322 -}
18.323 -
18.324 -/*
18.325 - * convert an enum to its string equivalent
18.326 - */
18.327 -const char* SDL_GameControllerGetStringForAxis( SDL_GameControllerAxis axis )
18.328 -{
18.329 - if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX)
18.330 - {
18.331 - return map_StringForControllerAxis[axis];
18.332 - }
18.333 - return NULL;
18.334 -}
18.335 -
18.336 -static const char* map_StringForControllerButton[] = {
18.337 - "a",
18.338 - "b",
18.339 - "x",
18.340 - "y",
18.341 - "back",
18.342 - "guide",
18.343 - "start",
18.344 - "leftstick",
18.345 - "rightstick",
18.346 - "leftshoulder",
18.347 - "rightshoulder",
18.348 - "dpup",
18.349 - "dpdown",
18.350 - "dpleft",
18.351 - "dpright",
18.352 - NULL
18.353 -};
18.354 -
18.355 -/*
18.356 - * convert a string to its enum equivalent
18.357 - */
18.358 -SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
18.359 -{
18.360 - int entry;
18.361 - if ( !pchString || !pchString[0] )
18.362 - return SDL_CONTROLLER_BUTTON_INVALID;
18.363 -
18.364 - for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
18.365 - {
18.366 - if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
18.367 - return entry;
18.368 - }
18.369 - return SDL_CONTROLLER_BUTTON_INVALID;
18.370 -}
18.371 -
18.372 -/*
18.373 - * convert an enum to its string equivalent
18.374 - */
18.375 -const char* SDL_GameControllerGetStringForButton( SDL_GameControllerButton axis )
18.376 -{
18.377 - if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX)
18.378 - {
18.379 - return map_StringForControllerButton[axis];
18.380 - }
18.381 - return NULL;
18.382 -}
18.383 -
18.384 -/*
18.385 - * given a controller button name and a joystick name update our mapping structure with it
18.386 - */
18.387 -void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
18.388 -{
18.389 - int iSDLButton = 0;
18.390 - SDL_GameControllerButton button;
18.391 - SDL_GameControllerAxis axis;
18.392 - button = SDL_GameControllerGetButtonFromString( szGameButton );
18.393 - axis = SDL_GameControllerGetAxisFromString( szGameButton );
18.394 - iSDLButton = SDL_atoi( &szJoystickButton[1] );
18.395 -
18.396 - if ( szJoystickButton[0] == 'a' )
18.397 - {
18.398 - if ( iSDLButton >= k_nMaxReverseEntries )
18.399 - {
18.400 - SDL_SetError("Axis index too large: %d", iSDLButton );
18.401 - return;
18.402 - }
18.403 - if ( axis != SDL_CONTROLLER_AXIS_INVALID )
18.404 - {
18.405 - pMapping->axes[ axis ] = iSDLButton;
18.406 - pMapping->raxes[ iSDLButton ] = axis;
18.407 - }
18.408 - else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
18.409 - {
18.410 - pMapping->axesasbutton[ button ] = iSDLButton;
18.411 - pMapping->raxesasbutton[ iSDLButton ] = button;
18.412 - }
18.413 - else
18.414 - {
18.415 - SDL_assert( !"How did we get here?" );
18.416 - }
18.417 -
18.418 - }
18.419 - else if ( szJoystickButton[0] == 'b' )
18.420 - {
18.421 - if ( iSDLButton >= k_nMaxReverseEntries )
18.422 - {
18.423 - SDL_SetError("Button index too large: %d", iSDLButton );
18.424 - return;
18.425 - }
18.426 - if ( button != SDL_CONTROLLER_BUTTON_INVALID )
18.427 - {
18.428 - pMapping->buttons[ button ] = iSDLButton;
18.429 - pMapping->rbuttons[ iSDLButton ] = button;
18.430 - }
18.431 - else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
18.432 - {
18.433 - pMapping->buttonasaxis[ axis ] = iSDLButton;
18.434 - pMapping->rbuttonasaxis[ iSDLButton ] = axis;
18.435 - }
18.436 - else
18.437 - {
18.438 - SDL_assert( !"How did we get here?" );
18.439 - }
18.440 - }
18.441 - else if ( szJoystickButton[0] == 'h' )
18.442 - {
18.443 - int hat = SDL_atoi( &szJoystickButton[1] );
18.444 - int mask = SDL_atoi( &szJoystickButton[3] );
18.445 - if (hat >= 4) {
18.446 - SDL_SetError("Hat index too large: %d", iSDLButton );
18.447 - }
18.448 -
18.449 - if ( button != SDL_CONTROLLER_BUTTON_INVALID )
18.450 - {
18.451 - int ridx;
18.452 - pMapping->hatasbutton[ button ].hat = hat;
18.453 - pMapping->hatasbutton[ button ].mask = mask;
18.454 - ridx = (hat << 4) | mask;
18.455 - pMapping->rhatasbutton[ ridx ] = button;
18.456 - }
18.457 - else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
18.458 - {
18.459 - SDL_assert( !"Support hat as axis" );
18.460 - }
18.461 - else
18.462 - {
18.463 - SDL_assert( !"How did we get here?" );
18.464 - }
18.465 - }
18.466 -}
18.467 -
18.468 -
18.469 -/*
18.470 - * given a controller mapping string update our mapping object
18.471 - */
18.472 -static void
18.473 -SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
18.474 -{
18.475 - char szGameButton[20];
18.476 - char szJoystickButton[20];
18.477 - SDL_bool bGameButton = SDL_TRUE;
18.478 - int i = 0;
18.479 - const char *pchPos = pchString;
18.480 -
18.481 - SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
18.482 - SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
18.483 -
18.484 - while ( pchPos && *pchPos )
18.485 - {
18.486 - if ( *pchPos == ':' )
18.487 - {
18.488 - i = 0;
18.489 - bGameButton = SDL_FALSE;
18.490 - }
18.491 - else if ( *pchPos == ' ' )
18.492 - {
18.493 -
18.494 - }
18.495 - else if ( *pchPos == ',' )
18.496 - {
18.497 - i = 0;
18.498 - bGameButton = SDL_TRUE;
18.499 - SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
18.500 - SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
18.501 - SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
18.502 -
18.503 - }
18.504 - else if ( bGameButton )
18.505 - {
18.506 - if ( i >= sizeof(szGameButton))
18.507 - {
18.508 - SDL_SetError( "Button name too large: %s", szGameButton );
18.509 - return;
18.510 - }
18.511 - szGameButton[i] = *pchPos;
18.512 - i++;
18.513 - }
18.514 - else
18.515 - {
18.516 - if ( i >= sizeof(szJoystickButton))
18.517 - {
18.518 - SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
18.519 - return;
18.520 - }
18.521 - szJoystickButton[i] = *pchPos;
18.522 - i++;
18.523 - }
18.524 - pchPos++;
18.525 - }
18.526 -
18.527 - SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
18.528 -
18.529 -}
18.530 -
18.531 -/*
18.532 - * Make a new button mapping struct
18.533 - */
18.534 -void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
18.535 -{
18.536 - int j;
18.537 -
18.538 - pMapping->guid = guid;
18.539 - pMapping->name = pchName;
18.540 -
18.541 - /* set all the button mappings to non defaults */
18.542 - for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
18.543 - {
18.544 - pMapping->axes[j] = -1;
18.545 - pMapping->buttonasaxis[j] = -1;
18.546 - }
18.547 - for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
18.548 - {
18.549 - pMapping->buttons[j] = -1;
18.550 - pMapping->axesasbutton[j] = -1;
18.551 - pMapping->hatasbutton[j].hat = -1;
18.552 - }
18.553 -
18.554 - for ( j = 0; j < k_nMaxReverseEntries; j++ )
18.555 - {
18.556 - pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
18.557 - pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
18.558 - pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
18.559 - pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
18.560 - }
18.561 -
18.562 - for (j = 0; j < k_nMaxHatEntries; j++)
18.563 - {
18.564 - pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
18.565 - }
18.566 -
18.567 - SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
18.568 -}
18.569 -
18.570 -
18.571 -/*
18.572 - * grab the guid string from a mapping string
18.573 - */
18.574 -char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
18.575 -{
18.576 - const char *pFirstComma = SDL_strchr( pMapping, ',' );
18.577 - if ( pFirstComma )
18.578 - {
18.579 - char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
18.580 - if ( !pchGUID )
18.581 - {
18.582 - SDL_OutOfMemory();
18.583 - return NULL;
18.584 - }
18.585 - SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
18.586 - pchGUID[ pFirstComma - pMapping ] = 0;
18.587 - return pchGUID;
18.588 - }
18.589 - return NULL;
18.590 -}
18.591 -
18.592 -
18.593 -/*
18.594 - * grab the name string from a mapping string
18.595 - */
18.596 -char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
18.597 -{
18.598 - const char *pFirstComma, *pSecondComma;
18.599 - char *pchName;
18.600 -
18.601 - pFirstComma = SDL_strchr( pMapping, ',' );
18.602 - if ( !pFirstComma )
18.603 - return NULL;
18.604 -
18.605 - pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
18.606 - if ( !pSecondComma )
18.607 - return NULL;
18.608 -
18.609 - pchName = SDL_malloc( pSecondComma - pFirstComma );
18.610 - if ( !pchName )
18.611 - {
18.612 - SDL_OutOfMemory();
18.613 - return NULL;
18.614 - }
18.615 - SDL_memcpy( pchName, pFirstComma + 1, pSecondComma - pFirstComma );
18.616 - pchName[ pSecondComma - pFirstComma - 1 ] = 0;
18.617 - return pchName;
18.618 -}
18.619 -
18.620 -
18.621 -/*
18.622 - * grab the button mapping string from a mapping string
18.623 - */
18.624 -char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
18.625 -{
18.626 - const char *pFirstComma, *pSecondComma;
18.627 -
18.628 - pFirstComma = SDL_strchr( pMapping, ',' );
18.629 - if ( !pFirstComma )
18.630 - return NULL;
18.631 -
18.632 - pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
18.633 - if ( !pSecondComma )
18.634 - return NULL;
18.635 -
18.636 - return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
18.637 -}
18.638 -
18.639 -void SDL_PrivateGameControllerRefreshMapping( ControllerMapping_t *pControllerMapping )
18.640 -{
18.641 - SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
18.642 - while ( gamecontrollerlist )
18.643 - {
18.644 - if ( !SDL_memcmp( &gamecontrollerlist->mapping.guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid) ) )
18.645 - {
18.646 - SDL_Event event;
18.647 - event.type = SDL_CONTROLLERDEVICEREMAPPED;
18.648 - event.cdevice.which = gamecontrollerlist->joystick->instance_id;
18.649 - SDL_PushEvent(&event);
18.650 -
18.651 - /* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
18.652 - SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
18.653 - }
18.654 -
18.655 - gamecontrollerlist = gamecontrollerlist->next;
18.656 - }
18.657 -}
18.658 -
18.659 -/*
18.660 - * Add or update an entry into the Mappings Database
18.661 - */
18.662 -int
18.663 -SDL_GameControllerAddMapping( const char *mappingString )
18.664 -{
18.665 - char *pchGUID;
18.666 - char *pchName;
18.667 - char *pchMapping;
18.668 - SDL_JoystickGUID jGUID;
18.669 - ControllerMapping_t *pControllerMapping;
18.670 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
18.671 - SDL_bool is_xinput_mapping = SDL_FALSE;
18.672 -#endif
18.673 -
18.674 - pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( mappingString );
18.675 - if (!pchGUID) {
18.676 - return -1;
18.677 - }
18.678 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
18.679 - if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
18.680 - is_xinput_mapping = SDL_TRUE;
18.681 - }
18.682 -#endif
18.683 - jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
18.684 - SDL_free(pchGUID);
18.685 -
18.686 - pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
18.687 -
18.688 - pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
18.689 - if (!pchName) return -1;
18.690 -
18.691 - pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
18.692 - if (!pchMapping) {
18.693 - SDL_free( pchName );
18.694 - return -1;
18.695 - }
18.696 -
18.697 - if (pControllerMapping) {
18.698 - /* Update existing mapping */
18.699 - SDL_free( pControllerMapping->name );
18.700 - pControllerMapping->name = pchName;
18.701 - SDL_free( pControllerMapping->mapping );
18.702 - pControllerMapping->mapping = pchMapping;
18.703 - /* refresh open controllers */
18.704 - SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
18.705 - return 0;
18.706 - } else {
18.707 - pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
18.708 - if (!pControllerMapping) {
18.709 - SDL_free( pchName );
18.710 - SDL_free( pchMapping );
18.711 - return SDL_OutOfMemory();
18.712 - }
18.713 -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
18.714 - if ( is_xinput_mapping )
18.715 - {
18.716 - s_pXInputMapping = pControllerMapping;
18.717 - }
18.718 -#endif
18.719 - pControllerMapping->guid = jGUID;
18.720 - pControllerMapping->name = pchName;
18.721 - pControllerMapping->mapping = pchMapping;
18.722 - pControllerMapping->next = s_pSupportedControllers;
18.723 - s_pSupportedControllers = pControllerMapping;
18.724 - return 1;
18.725 - }
18.726 -}
18.727 -
18.728 -/*
18.729 - * Get the mapping string for this GUID
18.730 - */
18.731 -char *
18.732 -SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
18.733 -{
18.734 - char *pMappingString = NULL;
18.735 - ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
18.736 - if (mapping) {
18.737 - char pchGUID[33];
18.738 - size_t needed;
18.739 - SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
18.740 - /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
18.741 - needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
18.742 - pMappingString = SDL_malloc( needed );
18.743 - SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
18.744 - }
18.745 - return pMappingString;
18.746 -}
18.747 -
18.748 -/*
18.749 - * Get the mapping string for this device
18.750 - */
18.751 -char *
18.752 -SDL_GameControllerMapping( SDL_GameController * gamecontroller )
18.753 -{
18.754 - return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
18.755 -}
18.756 -
18.757 -static void
18.758 -SDL_GameControllerLoadHints()
18.759 -{
18.760 - const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
18.761 - if ( hint && hint[0] ) {
18.762 - size_t nchHints = SDL_strlen( hint );
18.763 - char *pUserMappings = SDL_malloc( nchHints + 1 );
18.764 - char *pTempMappings = pUserMappings;
18.765 - SDL_memcpy( pUserMappings, hint, nchHints );
18.766 - while ( pUserMappings ) {
18.767 - char *pchNewLine = NULL;
18.768 -
18.769 - pchNewLine = SDL_strchr( pUserMappings, '\n' );
18.770 - if ( pchNewLine )
18.771 - *pchNewLine = '\0';
18.772 -
18.773 - SDL_GameControllerAddMapping( pUserMappings );
18.774 -
18.775 - if ( pchNewLine )
18.776 - pUserMappings = pchNewLine + 1;
18.777 - else
18.778 - pUserMappings = NULL;
18.779 - }
18.780 - SDL_free(pTempMappings);
18.781 - }
18.782 -}
18.783 -
18.784 -/*
18.785 - * Initialize the game controller system, mostly load our DB of controller config mappings
18.786 - */
18.787 -int
18.788 -SDL_GameControllerInit(void)
18.789 -{
18.790 - int i = 0;
18.791 - const char *pMappingString = NULL;
18.792 - s_pSupportedControllers = NULL;
18.793 - pMappingString = s_ControllerMappings[i];
18.794 - while ( pMappingString )
18.795 - {
18.796 - SDL_GameControllerAddMapping( pMappingString );
18.797 -
18.798 - i++;
18.799 - pMappingString = s_ControllerMappings[i];
18.800 - }
18.801 -
18.802 - /* load in any user supplied config */
18.803 - SDL_GameControllerLoadHints();
18.804 -
18.805 - /* watch for joy events and fire controller ones if needed */
18.806 - SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );
18.807 -
18.808 - return (0);
18.809 -}
18.810 -
18.811 -
18.812 -/*
18.813 - * Get the implementation dependent name of a controller
18.814 - */
18.815 -const char *
18.816 -SDL_GameControllerNameForIndex(int device_index)
18.817 -{
18.818 - ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
18.819 - if ( pSupportedController )
18.820 - {
18.821 - return pSupportedController->name;
18.822 - }
18.823 - return NULL;
18.824 -}
18.825 -
18.826 -
18.827 -/*
18.828 - * Return 1 if the joystick at this device index is a supported controller
18.829 - */
18.830 -SDL_bool
18.831 -SDL_IsGameController(int device_index)
18.832 -{
18.833 - ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
18.834 - if ( pSupportedController )
18.835 - {
18.836 - return SDL_TRUE;
18.837 - }
18.838 -
18.839 - return SDL_FALSE;
18.840 -}
18.841 -
18.842 -/*
18.843 - * Open a controller for use - the index passed as an argument refers to
18.844 - * the N'th controller on the system. This index is the value which will
18.845 - * identify this controller in future controller events.
18.846 - *
18.847 - * This function returns a controller identifier, or NULL if an error occurred.
18.848 - */
18.849 -SDL_GameController *
18.850 -SDL_GameControllerOpen(int device_index)
18.851 -{
18.852 - SDL_GameController *gamecontroller;
18.853 - SDL_GameController *gamecontrollerlist;
18.854 - ControllerMapping_t *pSupportedController = NULL;
18.855 -
18.856 - if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
18.857 - SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
18.858 - return (NULL);
18.859 - }
18.860 -
18.861 - gamecontrollerlist = SDL_gamecontrollers;
18.862 - /* If the controller is already open, return it */
18.863 - while ( gamecontrollerlist )
18.864 - {
18.865 - if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
18.866 - gamecontroller = gamecontrollerlist;
18.867 - ++gamecontroller->ref_count;
18.868 - return (gamecontroller);
18.869 - }
18.870 - gamecontrollerlist = gamecontrollerlist->next;
18.871 - }
18.872 -
18.873 - /* Find a controller mapping */
18.874 - pSupportedController = SDL_PrivateGetControllerMapping(device_index);
18.875 - if ( !pSupportedController ) {
18.876 - SDL_SetError("Couldn't find mapping for device (%d)", device_index );
18.877 - return (NULL);
18.878 - }
18.879 -
18.880 - /* Create and initialize the joystick */
18.881 - gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
18.882 - if (gamecontroller == NULL) {
18.883 - SDL_OutOfMemory();
18.884 - return NULL;
18.885 - }
18.886 -
18.887 - SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
18.888 - gamecontroller->joystick = SDL_JoystickOpen(device_index);
18.889 - if ( !gamecontroller->joystick ) {
18.890 - SDL_free(gamecontroller);
18.891 - return NULL;
18.892 - }
18.893 -
18.894 - SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );
18.895 -
18.896 - /* Add joystick to list */
18.897 - ++gamecontroller->ref_count;
18.898 - /* Link the joystick in the list */
18.899 - gamecontroller->next = SDL_gamecontrollers;
18.900 - SDL_gamecontrollers = gamecontroller;
18.901 -
18.902 - SDL_SYS_JoystickUpdate( gamecontroller->joystick );
18.903 -
18.904 - return (gamecontroller);
18.905 -}
18.906 -
18.907 -/*
18.908 - * Manually pump for controller updates.
18.909 - */
18.910 -void
18.911 -SDL_GameControllerUpdate(void)
18.912 -{
18.913 - /* Just for API completeness; the joystick API does all the work. */
18.914 - SDL_JoystickUpdate();
18.915 -}
18.916 -
18.917 -
18.918 -/*
18.919 - * Get the current state of an axis control on a controller
18.920 - */
18.921 -Sint16
18.922 -SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
18.923 -{
18.924 - if ( !gamecontroller )
18.925 - return 0;
18.926 -
18.927 - if (gamecontroller->mapping.axes[axis] >= 0 )
18.928 - {
18.929 - Sint16 value = ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
18.930 - switch (axis)
18.931 - {
18.932 - case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
18.933 - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
18.934 - /* Shift it to be 0 - 32767. */
18.935 - value = value / 2 + 16384;
18.936 - default:
18.937 - break;
18.938 - }
18.939 - return value;
18.940 - }
18.941 - else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
18.942 - {
18.943 - Uint8 value;
18.944 - value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
18.945 - if ( value > 0 )
18.946 - return 32767;
18.947 - return 0;
18.948 - }
18.949 - return 0;
18.950 -}
18.951 -
18.952 -
18.953 -/*
18.954 - * Get the current state of a button on a controller
18.955 - */
18.956 -Uint8
18.957 -SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
18.958 -{
18.959 - if ( !gamecontroller )
18.960 - return 0;
18.961 -
18.962 - if ( gamecontroller->mapping.buttons[button] >= 0 )
18.963 - {
18.964 - return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
18.965 - }
18.966 - else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
18.967 - {
18.968 - Sint16 value;
18.969 - value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
18.970 - if ( ABS(value) > 32768/2 )
18.971 - return 1;
18.972 - return 0;
18.973 - }
18.974 - else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
18.975 - {
18.976 - Uint8 value;
18.977 - value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );
18.978 -
18.979 - if ( value & gamecontroller->mapping.hatasbutton[button].mask )
18.980 - return 1;
18.981 - return 0;
18.982 - }
18.983 -
18.984 - return 0;
18.985 -}
18.986 -
18.987 -/*
18.988 - * Return if the joystick in question is currently attached to the system,
18.989 - * \return 0 if not plugged in, 1 if still present.
18.990 - */
18.991 -SDL_bool
18.992 -SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
18.993 -{
18.994 - if ( !gamecontroller )
18.995 - return SDL_FALSE;
18.996 -
18.997 - return SDL_JoystickGetAttached(gamecontroller->joystick);
18.998 -}
18.999 -
18.1000 -
18.1001 -/*
18.1002 - * Get the number of multi-dimensional axis controls on a joystick
18.1003 - */
18.1004 -const char *
18.1005 -SDL_GameControllerName(SDL_GameController * gamecontroller)
18.1006 -{
18.1007 - if ( !gamecontroller )
18.1008 - return NULL;
18.1009 -
18.1010 - return (gamecontroller->mapping.name);
18.1011 -}
18.1012 -
18.1013 -
18.1014 -/*
18.1015 - * Get the joystick for this controller
18.1016 - */
18.1017 -SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
18.1018 -{
18.1019 - if ( !gamecontroller )
18.1020 - return NULL;
18.1021 -
18.1022 - return gamecontroller->joystick;
18.1023 -}
18.1024 -
18.1025 -/**
18.1026 - * Get the SDL joystick layer binding for this controller axis mapping
18.1027 - */
18.1028 -SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
18.1029 -{
18.1030 - SDL_GameControllerButtonBind bind;
18.1031 - SDL_memset( &bind, 0x0, sizeof(bind) );
18.1032 -
18.1033 - if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
18.1034 - return bind;
18.1035 -
18.1036 - if (gamecontroller->mapping.axes[axis] >= 0 )
18.1037 - {
18.1038 - bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
18.1039 - bind.value.button = gamecontroller->mapping.axes[axis];
18.1040 - }
18.1041 - else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
18.1042 - {
18.1043 - bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
18.1044 - bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
18.1045 - }
18.1046 -
18.1047 - return bind;
18.1048 -}
18.1049 -
18.1050 -
18.1051 -/**
18.1052 - * Get the SDL joystick layer binding for this controller button mapping
18.1053 - */
18.1054 -SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
18.1055 -{
18.1056 -