Explorar el Código

WinRT: merged with SDL 2.0.0 codebase (aka. SDL hg rev d4ce48ff30d1)

David Ludwig hace 11 años
padre
commit
f7049b93d5
Se han modificado 66 ficheros con 10152 adiciones y 2459 borrados
  1. 403 0
      VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj
  2. 608 0
      VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters
  3. 505 0
      VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
  4. 608 0
      VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters
  5. 32 0
      VisualC-WinRT/SDL_VS2012-WinRT.sln
  6. BIN
      VisualC-WinRT/tests/loopwave/Assets/Logo.png
  7. BIN
      VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png
  8. BIN
      VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png
  9. BIN
      VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png
  10. 42 0
      VisualC-WinRT/tests/loopwave/Package.appxmanifest
  11. 157 0
      VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj
  12. BIN
      VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx
  13. BIN
      VisualC-WinRT/tests/testthread/Assets/Logo.png
  14. BIN
      VisualC-WinRT/tests/testthread/Assets/SmallLogo.png
  15. BIN
      VisualC-WinRT/tests/testthread/Assets/SplashScreen.png
  16. BIN
      VisualC-WinRT/tests/testthread/Assets/StoreLogo.png
  17. 42 0
      VisualC-WinRT/tests/testthread/Package.appxmanifest
  18. 160 0
      VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj
  19. BIN
      VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx
  20. 1 0
      Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
  21. 2 0
      include/SDL_config.h
  22. 180 0
      include/SDL_config_windowsrt.h
  23. 1 1
      include/SDL_cpuinfo.h
  24. 7 0
      include/SDL_stdinc.h
  25. 65 0
      include/SDL_system.h
  26. 13 0
      include/SDL_syswm.h
  27. 2 2
      include/begin_code.h
  28. 2 0
      src/SDL_assert.c
  29. 2 2
      src/SDL_log.c
  30. 1 1
      src/atomic/SDL_spinlock.c
  31. 583 437
      src/audio/xaudio2/SDL_xaudio2.c
  32. 69 0
      src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp
  33. 40 0
      src/audio/xaudio2/SDL_xaudio2_winrthelpers.h
  34. 22 4
      src/core/windows/SDL_windows.c
  35. 5 0
      src/core/windows/SDL_windows.h
  36. 94 0
      src/core/windowsrt/SDL_winrtpaths.cpp
  37. 764 757
      src/file/SDL_rwops.c
  38. 1249 1249
      src/joystick/SDL_gamecontroller.c
  39. 1 1
      src/joystick/SDL_sysjoystick.h
  40. 435 0
      src/joystick/windowsrt/SDL_xinputjoystick.c
  41. 8 0
      src/loadso/windows/SDL_sysloadso.c
  42. 14 0
      src/main/windowsrt/SDL_winrt_main.cpp
  43. 3 0
      src/render/SDL_sysrender.h
  44. 12 0
      src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl
  45. 14 0
      src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl
  46. 41 0
      src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl
  47. 1807 0
      src/render/direct3d11/SDL_render_d3d11.cpp
  48. 84 0
      src/render/direct3d11/SDL_render_d3d11_cpp.h
  49. 2 0
      src/thread/SDL_thread_c.h
  50. 183 0
      src/thread/stdcpp/SDL_syscond.cpp
  51. 113 0
      src/thread/stdcpp/SDL_sysmutex.cpp
  52. 30 0
      src/thread/stdcpp/SDL_sysmutex_c.h
  53. 124 0
      src/thread/stdcpp/SDL_systhread.cpp
  54. 26 0
      src/thread/stdcpp/SDL_systhread_c.h
  55. 3 0
      src/video/SDL_sysvideo.h
  56. 3 0
      src/video/SDL_video.c
  57. 3 1
      src/video/uikit/SDL_uikitwindow.m
  58. 978 0
      src/video/windowsrt/SDL_WinRTApp.cpp
  59. 52 0
      src/video/windowsrt/SDL_WinRTApp.h
  60. 41 0
      src/video/windowsrt/SDL_winrtevents.cpp
  61. 27 0
      src/video/windowsrt/SDL_winrtevents_c.h
  62. 149 0
      src/video/windowsrt/SDL_winrtmouse.cpp
  63. 31 0
      src/video/windowsrt/SDL_winrtmouse.h
  64. 262 0
      src/video/windowsrt/SDL_winrtvideo.cpp
  65. 40 0
      src/video/windowsrt/SDL_winrtvideo.h
  66. 7 4
      test/loopwave.c

+ 403 - 0
VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj

@@ -0,0 +1,403 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{33048af1-031a-4ce6-b61e-fad2db832e9e}</ProjectGuid>
+    <RootNamespace>SDL</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <ProjectName>SDL-WinPhone</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>_USRDLL;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>_USRDLL;UNICODE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <ClCompile>
+      <PreprocessorDefinitions>_USRDLL;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <ClCompile>
+      <PreprocessorDefinitions>_USRDLL;UNICODE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Reference Include="Windows">
+      <IsWinMDFile>true</IsWinMDFile>
+    </Reference>
+    <Reference Include="platform.winmd">
+      <IsWinMDFile>true</IsWinMDFile>
+      <Private>false</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\include\begin_code.h" />
+    <ClInclude Include="..\..\include\close_code.h" />
+    <ClInclude Include="..\..\include\SDL.h" />
+    <ClInclude Include="..\..\include\SDL_assert.h" />
+    <ClInclude Include="..\..\include\SDL_atomic.h" />
+    <ClInclude Include="..\..\include\SDL_audio.h" />
+    <ClInclude Include="..\..\include\SDL_blendmode.h" />
+    <ClInclude Include="..\..\include\SDL_clipboard.h" />
+    <ClInclude Include="..\..\include\SDL_config.h" />
+    <ClInclude Include="..\..\include\SDL_config_minimal.h" />
+    <ClInclude Include="..\..\include\SDL_config_windowsrt.h" />
+    <ClInclude Include="..\..\include\SDL_copying.h" />
+    <ClInclude Include="..\..\include\SDL_cpuinfo.h" />
+    <ClInclude Include="..\..\include\SDL_endian.h" />
+    <ClInclude Include="..\..\include\SDL_error.h" />
+    <ClInclude Include="..\..\include\SDL_events.h" />
+    <ClInclude Include="..\..\include\SDL_haptic.h" />
+    <ClInclude Include="..\..\include\SDL_hints.h" />
+    <ClInclude Include="..\..\include\SDL_input.h" />
+    <ClInclude Include="..\..\include\SDL_joystick.h" />
+    <ClInclude Include="..\..\include\SDL_keyboard.h" />
+    <ClInclude Include="..\..\include\SDL_keycode.h" />
+    <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_log.h" />
+    <ClInclude Include="..\..\include\SDL_main.h" />
+    <ClInclude Include="..\..\include\SDL_mouse.h" />
+    <ClInclude Include="..\..\include\SDL_mutex.h" />
+    <ClInclude Include="..\..\include\SDL_name.h" />
+    <ClInclude Include="..\..\include\SDL_pixels.h" />
+    <ClInclude Include="..\..\include\SDL_platform.h" />
+    <ClInclude Include="..\..\include\SDL_power.h" />
+    <ClInclude Include="..\..\include\SDL_quit.h" />
+    <ClInclude Include="..\..\include\SDL_rect.h" />
+    <ClInclude Include="..\..\include\SDL_render.h" />
+    <ClInclude Include="..\..\include\SDL_revision.h" />
+    <ClInclude Include="..\..\include\SDL_rwops.h" />
+    <ClInclude Include="..\..\include\SDL_scancode.h" />
+    <ClInclude Include="..\..\include\SDL_shape.h" />
+    <ClInclude Include="..\..\include\SDL_stdinc.h" />
+    <ClInclude Include="..\..\include\SDL_surface.h" />
+    <ClInclude Include="..\..\include\SDL_system.h" />
+    <ClInclude Include="..\..\include\SDL_syswm.h" />
+    <ClInclude Include="..\..\include\SDL_thread.h" />
+    <ClInclude Include="..\..\include\SDL_timer.h" />
+    <ClInclude Include="..\..\include\SDL_touch.h" />
+    <ClInclude Include="..\..\include\SDL_types.h" />
+    <ClInclude Include="..\..\include\SDL_version.h" />
+    <ClInclude Include="..\..\include\SDL_video.h" />
+    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
+    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
+    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
+    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
+    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
+    <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
+    <ClInclude Include="..\..\src\events\blank_cursor.h" />
+    <ClInclude Include="..\..\src\events\default_cursor.h" />
+    <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_events_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_sysevents.h" />
+    <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
+    <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
+    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
+    <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
+    <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
+    <ClInclude Include="..\..\src\render\direct3d11\SDL_render_d3d11_cpp.h" />
+    <ClInclude Include="..\..\src\render\mmx.h" />
+    <ClInclude Include="..\..\src\render\SDL_sysrender.h" />
+    <ClInclude Include="..\..\src\render\SDL_yuv_sw_c.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendline.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_draw.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_drawline.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_drawpoint.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_render_sw_c.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_rotate.h" />
+    <ClInclude Include="..\..\src\SDL_assert_c.h" />
+    <ClInclude Include="..\..\src\SDL_error_c.h" />
+    <ClInclude Include="..\..\src\SDL_fatal.h" />
+    <ClInclude Include="..\..\src\SDL_hints_c.h" />
+    <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
+    <ClInclude Include="..\..\src\thread\SDL_thread_c.h" />
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_sysmutex_c.h" />
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_systhread_c.h" />
+    <ClInclude Include="..\..\src\timer\SDL_timer_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullevents_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullframebuffer_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullvideo.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_auto.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_copy.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_slow.h" />
+    <ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_rect_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
+    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtmouse.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtvideo.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
+    <ClCompile Include="..\..\src\atomic\SDL_spinlock.c" />
+    <ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c" />
+    <ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audio.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiocvt.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiodev.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
+    <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
+    <ClCompile Include="..\..\src\audio\SDL_wave.c" />
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windowsrt\SDL_winrtpaths.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
+    <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
+    <ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
+    <ClCompile Include="..\..\src\events\SDL_dropevents.c" />
+    <ClCompile Include="..\..\src\events\SDL_events.c" />
+    <ClCompile Include="..\..\src\events\SDL_gesture.c" />
+    <ClCompile Include="..\..\src\events\SDL_keyboard.c" />
+    <ClCompile Include="..\..\src\events\SDL_mouse.c" />
+    <ClCompile Include="..\..\src\events\SDL_quit.c" />
+    <ClCompile Include="..\..\src\events\SDL_touch.c" />
+    <ClCompile Include="..\..\src\events\SDL_windowevents.c" />
+    <ClCompile Include="..\..\src\file\SDL_rwops.c" />
+    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
+    <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
+    <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
+    <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c" />
+    <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
+    <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
+    <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_render.c" />
+    <ClCompile Include="..\..\src\render\SDL_yuv_mmx.c" />
+    <ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendfillrect.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendline.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendpoint.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_drawline.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_drawpoint.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_render_sw.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_rotate.c" />
+    <ClCompile Include="..\..\src\SDL.c" />
+    <ClCompile Include="..\..\src\SDL_assert.c" />
+    <ClCompile Include="..\..\src\SDL_error.c" />
+    <ClCompile Include="..\..\src\SDL_fatal.c" />
+    <ClCompile Include="..\..\src\SDL_hints.c" />
+    <ClCompile Include="..\..\src\SDL_log.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c" />
+    <ClCompile Include="..\..\src\thread\SDL_thread.c" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_syscond.cpp" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_sysmutex.cpp" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_systhread.cpp" />
+    <ClCompile Include="..\..\src\timer\SDL_timer.c" />
+    <ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullevents.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullframebuffer.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullvideo.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_0.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_1.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_A.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_auto.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_copy.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_N.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_slow.c" />
+    <ClCompile Include="..\..\src\video\SDL_bmp.c" />
+    <ClCompile Include="..\..\src\video\SDL_clipboard.c" />
+    <ClCompile Include="..\..\src\video\SDL_fillrect.c" />
+    <ClCompile Include="..\..\src\video\SDL_pixels.c" />
+    <ClCompile Include="..\..\src\video\SDL_rect.c" />
+    <ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
+    <ClCompile Include="..\..\src\video\SDL_shape.c" />
+    <ClCompile Include="..\..\src\video\SDL_stretch.c" />
+    <ClCompile Include="..\..\src\video\SDL_surface.c" />
+    <ClCompile Include="..\..\src\video\SDL_video.c" />
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_WinRTApp.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtevents.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtmouse.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtvideo.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_FixedColor.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_TextureColored.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_VertexShader_Default.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
+    </FxCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 608 - 0
VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters

@@ -0,0 +1,608 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{02b21b9a-45a7-41ee-a8a6-e45d14aa28da}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{abc3a7e6-f955-4cb5-8340-fae0f653e9c1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="GPU Shaders">
+      <UniqueIdentifier>{fd67993e-5155-488b-9313-d1eb06a1b67e}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\include\begin_code.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\close_code.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_assert.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_atomic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_audio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_blendmode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_clipboard.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config_minimal.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config_windowsrt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_copying.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_cpuinfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_endian.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_error.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_events.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_haptic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_hints.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_input.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_joystick.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_keyboard.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_keycode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_loadso.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_log.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_main.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_mouse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_mutex.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_name.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_pixels.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_platform.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_power.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_quit.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_rect.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_render.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_revision.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_rwops.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_scancode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_shape.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_stdinc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_surface.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_system.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_syswm.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_thread.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_timer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_touch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_version.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_video.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_wave.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\blank_cursor.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\default_cursor.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_dropevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_events_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_keyboard_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_mouse_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_sysevents.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_touch_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_windowevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\mmx.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\SDL_sysrender.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\SDL_yuv_sw_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendline.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_draw.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_drawline.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_drawpoint.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_render_sw_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_rotate.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_assert_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_error_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_fatal.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_hints_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\SDL_systhread.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\SDL_thread_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_sysmutex_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_systhread_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\timer\SDL_timer_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullframebuffer_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_auto.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_copy.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_slow.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_pixels_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_rect_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_shape_internals.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_sysvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtmouse.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\direct3d11\SDL_render_d3d11_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\atomic\SDL_spinlock.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiocvt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiodev.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_mixer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_wave.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windowsrt\SDL_winrtpaths.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_clipboardevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_dropevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_events.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_gesture.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_keyboard.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_mouse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_quit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_touch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_windowevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\file\SDL_rwops.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\haptic\SDL_haptic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\SDL_joystick.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_render.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_yuv_mmx.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_yuv_sw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendfillrect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendline.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendpoint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_drawline.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_drawpoint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_render_sw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_rotate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_assert.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_error.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_fatal.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_hints.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_log.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_iconv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_qsort.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_string.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\SDL_thread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_syscond.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_sysmutex.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_systhread.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\timer\SDL_timer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\timer\windows\SDL_systimer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullframebuffer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullvideo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_0.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_A.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_auto.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_copy.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_N.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_slow.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_bmp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_clipboard.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_fillrect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_pixels.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_rect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_RLEaccel.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_shape.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_stretch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_surface.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_video.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_WinRTApp.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtevents.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtmouse.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtvideo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_FixedColor.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_VertexShader_Default.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_TextureColored.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+  </ItemGroup>
+</Project>

+ 505 - 0
VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj

@@ -0,0 +1,505 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
+    <ClCompile Include="..\..\src\atomic\SDL_spinlock.c" />
+    <ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c" />
+    <ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audio.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiocvt.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiodev.c" />
+    <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c" />
+    <ClCompile Include="..\..\src\audio\SDL_mixer.c" />
+    <ClCompile Include="..\..\src\audio\SDL_wave.c" />
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windowsrt\SDL_winrtpaths.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
+    <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
+    <ClCompile Include="..\..\src\events\SDL_clipboardevents.c" />
+    <ClCompile Include="..\..\src\events\SDL_dropevents.c" />
+    <ClCompile Include="..\..\src\events\SDL_events.c" />
+    <ClCompile Include="..\..\src\events\SDL_gesture.c" />
+    <ClCompile Include="..\..\src\events\SDL_keyboard.c" />
+    <ClCompile Include="..\..\src\events\SDL_mouse.c" />
+    <ClCompile Include="..\..\src\events\SDL_quit.c" />
+    <ClCompile Include="..\..\src\events\SDL_touch.c" />
+    <ClCompile Include="..\..\src\events\SDL_windowevents.c" />
+    <ClCompile Include="..\..\src\file\SDL_rwops.c" />
+    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
+    <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
+    <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c" />
+    <ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
+    <ClCompile Include="..\..\src\joystick\windowsrt\SDL_xinputjoystick.c" />
+    <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
+    <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_render.c" />
+    <ClCompile Include="..\..\src\render\SDL_yuv_mmx.c" />
+    <ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendfillrect.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendline.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_blendpoint.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_drawline.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_drawpoint.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_render_sw.c" />
+    <ClCompile Include="..\..\src\render\software\SDL_rotate.c" />
+    <ClCompile Include="..\..\src\SDL.c" />
+    <ClCompile Include="..\..\src\SDL_assert.c" />
+    <ClCompile Include="..\..\src\SDL_error.c" />
+    <ClCompile Include="..\..\src\SDL_fatal.c" />
+    <ClCompile Include="..\..\src\SDL_hints.c" />
+    <ClCompile Include="..\..\src\SDL_log.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c" />
+    <ClCompile Include="..\..\src\thread\SDL_thread.c" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_syscond.cpp" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_sysmutex.cpp" />
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_systhread.cpp" />
+    <ClCompile Include="..\..\src\timer\SDL_timer.c" />
+    <ClCompile Include="..\..\src\timer\windows\SDL_systimer.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullevents.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullframebuffer.c" />
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullvideo.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_0.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_1.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_A.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_auto.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_copy.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_N.c" />
+    <ClCompile Include="..\..\src\video\SDL_blit_slow.c" />
+    <ClCompile Include="..\..\src\video\SDL_bmp.c" />
+    <ClCompile Include="..\..\src\video\SDL_clipboard.c" />
+    <ClCompile Include="..\..\src\video\SDL_fillrect.c" />
+    <ClCompile Include="..\..\src\video\SDL_pixels.c" />
+    <ClCompile Include="..\..\src\video\SDL_rect.c" />
+    <ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
+    <ClCompile Include="..\..\src\video\SDL_shape.c" />
+    <ClCompile Include="..\..\src\video\SDL_stretch.c" />
+    <ClCompile Include="..\..\src\video\SDL_surface.c" />
+    <ClCompile Include="..\..\src\video\SDL_video.c" />
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_WinRTApp.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtevents.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtmouse.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtvideo.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\include\begin_code.h" />
+    <ClInclude Include="..\..\include\close_code.h" />
+    <ClInclude Include="..\..\include\SDL.h" />
+    <ClInclude Include="..\..\include\SDL_assert.h" />
+    <ClInclude Include="..\..\include\SDL_atomic.h" />
+    <ClInclude Include="..\..\include\SDL_audio.h" />
+    <ClInclude Include="..\..\include\SDL_blendmode.h" />
+    <ClInclude Include="..\..\include\SDL_clipboard.h" />
+    <ClInclude Include="..\..\include\SDL_config.h" />
+    <ClInclude Include="..\..\include\SDL_config_minimal.h" />
+    <ClInclude Include="..\..\include\SDL_config_windowsrt.h" />
+    <ClInclude Include="..\..\include\SDL_copying.h" />
+    <ClInclude Include="..\..\include\SDL_cpuinfo.h" />
+    <ClInclude Include="..\..\include\SDL_endian.h" />
+    <ClInclude Include="..\..\include\SDL_error.h" />
+    <ClInclude Include="..\..\include\SDL_events.h" />
+    <ClInclude Include="..\..\include\SDL_haptic.h" />
+    <ClInclude Include="..\..\include\SDL_hints.h" />
+    <ClInclude Include="..\..\include\SDL_input.h" />
+    <ClInclude Include="..\..\include\SDL_joystick.h" />
+    <ClInclude Include="..\..\include\SDL_keyboard.h" />
+    <ClInclude Include="..\..\include\SDL_keycode.h" />
+    <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_log.h" />
+    <ClInclude Include="..\..\include\SDL_main.h" />
+    <ClInclude Include="..\..\include\SDL_mouse.h" />
+    <ClInclude Include="..\..\include\SDL_mutex.h" />
+    <ClInclude Include="..\..\include\SDL_name.h" />
+    <ClInclude Include="..\..\include\SDL_pixels.h" />
+    <ClInclude Include="..\..\include\SDL_platform.h" />
+    <ClInclude Include="..\..\include\SDL_power.h" />
+    <ClInclude Include="..\..\include\SDL_quit.h" />
+    <ClInclude Include="..\..\include\SDL_rect.h" />
+    <ClInclude Include="..\..\include\SDL_render.h" />
+    <ClInclude Include="..\..\include\SDL_revision.h" />
+    <ClInclude Include="..\..\include\SDL_rwops.h" />
+    <ClInclude Include="..\..\include\SDL_scancode.h" />
+    <ClInclude Include="..\..\include\SDL_shape.h" />
+    <ClInclude Include="..\..\include\SDL_stdinc.h" />
+    <ClInclude Include="..\..\include\SDL_surface.h" />
+    <ClInclude Include="..\..\include\SDL_system.h" />
+    <ClInclude Include="..\..\include\SDL_syswm.h" />
+    <ClInclude Include="..\..\include\SDL_thread.h" />
+    <ClInclude Include="..\..\include\SDL_timer.h" />
+    <ClInclude Include="..\..\include\SDL_touch.h" />
+    <ClInclude Include="..\..\include\SDL_types.h" />
+    <ClInclude Include="..\..\include\SDL_version.h" />
+    <ClInclude Include="..\..\include\SDL_video.h" />
+    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
+    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
+    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
+    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
+    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
+    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h" />
+    <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
+    <ClInclude Include="..\..\src\events\blank_cursor.h" />
+    <ClInclude Include="..\..\src\events\default_cursor.h" />
+    <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_dropevents_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_events_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_sysevents.h" />
+    <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
+    <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
+    <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
+    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
+    <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
+    <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
+    <ClInclude Include="..\..\src\render\direct3d11\SDL_render_d3d11_cpp.h" />
+    <ClInclude Include="..\..\src\render\mmx.h" />
+    <ClInclude Include="..\..\src\render\SDL_sysrender.h" />
+    <ClInclude Include="..\..\src\render\SDL_yuv_sw_c.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendline.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_draw.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_drawline.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_drawpoint.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_render_sw_c.h" />
+    <ClInclude Include="..\..\src\render\software\SDL_rotate.h" />
+    <ClInclude Include="..\..\src\SDL_assert_c.h" />
+    <ClInclude Include="..\..\src\SDL_error_c.h" />
+    <ClInclude Include="..\..\src\SDL_fatal.h" />
+    <ClInclude Include="..\..\src\SDL_hints_c.h" />
+    <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
+    <ClInclude Include="..\..\src\thread\SDL_thread_c.h" />
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_sysmutex_c.h" />
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_systhread_c.h" />
+    <ClInclude Include="..\..\src\timer\SDL_timer_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullevents_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullframebuffer_c.h" />
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullvideo.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_auto.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_copy.h" />
+    <ClInclude Include="..\..\src\video\SDL_blit_slow.h" />
+    <ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_rect_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
+    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
+    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtmouse.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtvideo.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_FixedColor.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">4.0_level_9_1</ShaderModel>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_TextureColored.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0_level_9_1</ShaderModel>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_VertexShader_Default.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">4.0_level_9_1</ShaderModel>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">4.0_level_9_1</ShaderModel>
+    </FxCompile>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{aeaea3a2-d4e6-45b1-8ec6-53d84287fc14}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectName>SDL-WinRT</ProjectName>
+    <RootNamespace>SDL_VS2012_WinRT</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <AppContainerApplication>true</AppContainerApplication>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <GenerateManifest>false</GenerateManifest>
+    <IgnoreImportLibrary>false</IgnoreImportLibrary>
+    <TargetName>SDL</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+      <AdditionalDependencies>xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 608 - 0
VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters

@@ -0,0 +1,608 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_FixedColor.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_VertexShader_Default.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+    <FxCompile Include="..\..\src\render\direct3d11\SDL_D3D11_PixelShader_TextureColored.hlsl">
+      <Filter>GPU Shaders</Filter>
+    </FxCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\SDL.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_assert.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiocvt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiodev.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_audiotypecvt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendfillrect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendline.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_blendpoint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_0.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_A.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_auto.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_copy.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_N.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_blit_slow.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_bmp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_clipboard.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_clipboardevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\disk\SDL_diskaudio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_drawline.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_drawpoint.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_dropevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_error.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_events.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_fatal.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_fillrect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_gesture.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\haptic\SDL_haptic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_hints.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_iconv.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\SDL_joystick.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_keyboard.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\SDL_log.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_mixer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_mouse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullframebuffer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\dummy\SDL_nullvideo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_pixels.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_qsort.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_quit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_rect.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_render.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_render_sw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_RLEaccel.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\software\SDL_rotate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\file\SDL_rwops.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_shape.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\atomic\SDL_spinlock.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_stretch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_string.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_surface.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_syscond.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_sysmutex.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\stdcpp\SDL_systhread.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\timer\windows\SDL_systimer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\thread\SDL_thread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\timer\SDL_timer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_touch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\SDL_video.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\SDL_wave.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\events\SDL_windowevents.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windows\SDL_windows.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_WinRTApp.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtevents.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtmouse.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtvideo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_yuv_mmx.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\SDL_yuv_sw.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\windowsrt\SDL_winrtpaths.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\SDL_gamecontroller.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\joystick\windowsrt\SDL_xinputjoystick.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\include\begin_code.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\close_code.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_assert.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_error_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_events_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_hints_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_mouse_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_sysmutex_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_assert_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_clipboardevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_dropevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_keyboard_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullframebuffer_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_pixels_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_render_sw_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\stdcpp\SDL_systhread_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\SDL_thread_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\timer\SDL_timer_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_touch_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_windowevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtevents_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\SDL_yuv_sw_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_audio.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_atomic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_blendmode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_clipboard.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendline.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_auto.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_copy.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_blit_slow.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\mmx.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config_minimal.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_config_windowsrt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_copying.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_cpuinfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_draw.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_drawline.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_drawpoint.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_endian.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_error.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_events.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\SDL_fatal.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_main.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_haptic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_hints.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_input.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_joystick.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_keyboard.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_keycode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_loadso.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_log.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_name.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_mouse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_mutex.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\dummy\SDL_nullvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_quit.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_pixels.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_platform.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_power.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_rect_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_rect.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\software\SDL_rotate.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_shape.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_render.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_revision.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_rwops.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_scancode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_surface.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_stdinc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_video.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_syswm.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_thread.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_timer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_touch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_version.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_shape_internals.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\SDL_sysevents.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\SDL_sysrender.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\thread\SDL_systhread.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\SDL_sysvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\SDL_wave.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\core\windows\SDL_windows.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtmouse.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtvideo.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2_winrthelpers.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\blank_cursor.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\events\default_cursor.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\include\SDL_system.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\render\direct3d11\SDL_render_d3d11_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{20773b57-7034-4c24-af5a-334844585f1b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{ddf04d85-6a87-4c5a-bc52-869b38f45a61}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="GPU Shaders">
+      <UniqueIdentifier>{83ed1283-8234-4c77-99a8-ffcfd8ce7381}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>

+ 32 - 0
VisualC-WinRT/SDL_VS2012-WinRT.sln

@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL_VS2012-WinRT", "SDL\SDL_VS2012-WinRT.vcxproj", "{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|ARM = Release|ARM
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|ARM.ActiveCfg = Debug|ARM
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|ARM.Build.0 = Debug|ARM
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|Win32.Build.0 = Debug|Win32
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|x64.ActiveCfg = Debug|x64
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Debug|x64.Build.0 = Debug|x64
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|ARM.ActiveCfg = Release|ARM
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|ARM.Build.0 = Release|ARM
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|Win32.ActiveCfg = Release|Win32
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|Win32.Build.0 = Release|Win32
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|x64.ActiveCfg = Release|x64
+		{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

BIN
VisualC-WinRT/tests/loopwave/Assets/Logo.png


BIN
VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png


BIN
VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png


BIN
VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png


+ 42 - 0
VisualC-WinRT/tests/loopwave/Package.appxmanifest

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+
+  <Identity Name="1702c480-cf09-431e-a5e4-b21b283ec818"
+            Publisher="CN=David"
+            Version="1.0.0.0" />
+
+  <Properties>
+    <DisplayName>loopwave_VS2012_WinRT</DisplayName>
+    <PublisherDisplayName>David</PublisherDisplayName>
+    <Logo>Assets\StoreLogo.png</Logo>
+  </Properties>
+
+  <Prerequisites>
+    <OSMinVersion>6.2.1</OSMinVersion>
+    <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+  </Prerequisites>
+
+  <Resources>
+    <Resource Language="x-generate"/>
+  </Resources>
+
+  <Applications>
+    <Application Id="App"
+        Executable="$targetnametoken$.exe"
+        EntryPoint="loopwave_VS2012_WinRT.App">
+        <VisualElements
+            DisplayName="loopwave_VS2012_WinRT"
+            Logo="Assets\Logo.png"
+            SmallLogo="Assets\SmallLogo.png"
+            Description="loopwave_VS2012_WinRT"
+            ForegroundText="light"
+            BackgroundColor="#464646">
+            <DefaultTile ShowName="allLogos" />
+            <SplashScreen Image="Assets\SplashScreen.png" />
+        </VisualElements>
+    </Application>
+  </Applications>
+  <Capabilities>
+    <Capability Name="internetClient" />
+  </Capabilities>
+</Package>

+ 157 - 0
VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{03fcc293-9406-49c2-acf6-6e7d460c3239}</ProjectGuid>
+    <RootNamespace>loopwave_VS2012</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <AppContainerApplication>true</AppContainerApplication>
+    <ProjectName>loopwave</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <PackageCertificateKeyFile>loopwave_VS2012_TemporaryKey.pfx</PackageCertificateKeyFile>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <Link>
+      <AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <ClCompile>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+      <AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+    <ClCompile>
+      <PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+    <ClCompile>
+      <PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Image Include="Assets\Logo.png" />
+    <Image Include="Assets\SmallLogo.png" />
+    <Image Include="Assets\StoreLogo.png" />
+    <Image Include="Assets\SplashScreen.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <AppxManifest Include="Package.appxmanifest">
+      <SubType>Designer</SubType>
+    </AppxManifest>
+    <None Include="loopwave_VS2012_TemporaryKey.pfx" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\src\main\windowsrt\SDL_winrt_main.cpp" />
+    <ClCompile Include="..\..\..\test\loopwave.c">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Media Include="..\..\..\test\sample.wav" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\SDL\SDL_VS2012-WinRT.vcxproj">
+      <Project>{aeaea3a2-d4e6-45b1-8ec6-53d84287fc14}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

BIN
VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx


BIN
VisualC-WinRT/tests/testthread/Assets/Logo.png


BIN
VisualC-WinRT/tests/testthread/Assets/SmallLogo.png


BIN
VisualC-WinRT/tests/testthread/Assets/SplashScreen.png


BIN
VisualC-WinRT/tests/testthread/Assets/StoreLogo.png


+ 42 - 0
VisualC-WinRT/tests/testthread/Package.appxmanifest

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+
+  <Identity Name="ca3178f1-b2b2-43bf-97dd-28ee1b7d32c5"
+            Publisher="CN=David"
+            Version="1.0.0.0" />
+
+  <Properties>
+    <DisplayName>testthread_VS2012_WinRT</DisplayName>
+    <PublisherDisplayName>David</PublisherDisplayName>
+    <Logo>Assets\StoreLogo.png</Logo>
+  </Properties>
+
+  <Prerequisites>
+    <OSMinVersion>6.2.1</OSMinVersion>
+    <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+  </Prerequisites>
+
+  <Resources>
+    <Resource Language="x-generate"/>
+  </Resources>
+
+  <Applications>
+    <Application Id="App"
+        Executable="$targetnametoken$.exe"
+        EntryPoint="testthread_VS2012_WinRT.App">
+        <VisualElements
+            DisplayName="testthread_VS2012_WinRT"
+            Logo="Assets\Logo.png"
+            SmallLogo="Assets\SmallLogo.png"
+            Description="testthread_VS2012_WinRT"
+            ForegroundText="light"
+            BackgroundColor="#464646">
+            <DefaultTile ShowName="allLogos" />
+            <SplashScreen Image="Assets\SplashScreen.png" />
+        </VisualElements>
+    </Application>
+  </Applications>
+  <Capabilities>
+    <Capability Name="internetClient" />
+  </Capabilities>
+</Package>

+ 160 - 0
VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj

@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{a8705bee-d01d-46a4-b2ab-feedfb5fdd11}</ProjectGuid>
+    <RootNamespace>testthread_VS2012</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <AppContainerApplication>true</AppContainerApplication>
+    <ProjectName>testthread</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <PackageCertificateKeyFile>testthread_VS2012_TemporaryKey.pfx</PackageCertificateKeyFile>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <Link>
+      <AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <ClCompile>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
+      <AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4453</DisableSpecificWarnings>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+    <ClCompile>
+      <PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+    <ClCompile>
+      <PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Image Include="Assets\Logo.png" />
+    <Image Include="Assets\SmallLogo.png" />
+    <Image Include="Assets\StoreLogo.png" />
+    <Image Include="Assets\SplashScreen.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <AppxManifest Include="Package.appxmanifest">
+      <SubType>Designer</SubType>
+    </AppxManifest>
+    <None Include="testthread_VS2012_TemporaryKey.pfx" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\src\main\windowsrt\SDL_winrt_main.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
+    <ClCompile Include="..\..\..\test\testthread.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\SDL\SDL_VS2012-WinRT.vcxproj">
+      <Project>{aeaea3a2-d4e6-45b1-8ec6-53d84287fc14}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

BIN
VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx


+ 1 - 0
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj

@@ -547,6 +547,7 @@
 			);
 			name = CustomTemplate;
 			sourceTree = "<group>";
+			usesTabs = 0;
 		};
 		56EA86F813E9EBF9002E47EB /* coreaudio */ = {
 			isa = PBXGroup;

+ 2 - 0
include/SDL_config.h

@@ -31,6 +31,8 @@
 /* Add any platform that doesn't build using the configure system. */
 #if defined(__WIN32__)
 #include "SDL_config_windows.h"
+#elif defined(__WINRT__)
+#include "SDL_config_windowsrt.h"
 #elif defined(__MACOSX__)
 #include "SDL_config_macosx.h"
 #elif defined(__IPHONEOS__)

+ 180 - 0
include/SDL_config_windowsrt.h

@@ -0,0 +1,180 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef _SDL_config_windows_h
+#define _SDL_config_windows_h
+
+#include "SDL_platform.h"
+
+/* This is a set of defines to configure the SDL features */
+
+#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H)
+#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__)
+#define HAVE_STDINT_H	1
+#elif defined(_MSC_VER)
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#ifndef _UINTPTR_T_DEFINED
+#ifdef  _WIN64
+typedef unsigned __int64 uintptr_t;
+#else
+typedef unsigned int uintptr_t;
+#endif
+#define _UINTPTR_T_DEFINED
+#endif
+/* Older Visual C++ headers don't have the Win64-compatible typedefs... */
+#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR)))
+#define DWORD_PTR DWORD
+#endif
+#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR)))
+#define LONG_PTR LONG
+#endif
+#else /* !__GNUC__ && !_MSC_VER */
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef unsigned int size_t;
+#endif
+typedef unsigned int uintptr_t;
+#endif /* __GNUC__ || _MSC_VER */
+#endif /* !_STDINT_H_ && !HAVE_STDINT_H */
+
+#ifdef _WIN64
+# define SIZEOF_VOIDP 8
+#else
+# define SIZEOF_VOIDP 4
+#endif
+
+/* Useful headers */
+#define HAVE_LIBC 1
+#define HAVE_STDIO_H 1
+#define STDC_HEADERS 1
+#define HAVE_STRING_H 1
+#define HAVE_CTYPE_H 1
+#define HAVE_MATH_H 1
+#define HAVE_SIGNAL_H 1
+
+/* C library functions */
+#define HAVE_MALLOC 1
+#define HAVE_CALLOC 1
+#define HAVE_REALLOC 1
+#define HAVE_FREE 1
+#define HAVE_ALLOCA 1
+#define HAVE_QSORT 1
+#define HAVE_ABS 1
+#define HAVE_MEMSET 1
+#define HAVE_MEMCPY 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MEMCMP 1
+#define HAVE_STRLEN 1
+#define HAVE__STRREV 1
+#define HAVE__STRUPR 1
+//#define HAVE__STRLWR 1	// TODO, WinRT: consider using _strlwr_s instead
+#define HAVE_STRCHR 1
+#define HAVE_STRRCHR 1
+#define HAVE_STRSTR 1
+//#define HAVE_ITOA 1   // TODO, WinRT: consider using _itoa_s instead
+//#define HAVE__LTOA 1	// TODO, WinRT: consider using _ltoa_s instead
+//#define HAVE__ULTOA 1	// TODO, WinRT: consider using _ultoa_s instead
+#define HAVE_STRTOL 1
+#define HAVE_STRTOUL 1
+//#define HAVE_STRTOLL 1
+#define HAVE_STRTOD 1
+#define HAVE_ATOI 1
+#define HAVE_ATOF 1
+#define HAVE_STRCMP 1
+#define HAVE_STRNCMP 1
+#define HAVE__STRICMP 1
+#define HAVE__STRNICMP 1
+#define HAVE_VSNPRINTF 1
+//#define HAVE_SSCANF 1	// TODO, WinRT: consider using sscanf_s instead
+#define HAVE_M_PI 1
+#define HAVE_ATAN 1
+#define HAVE_ATAN2 1
+#define HAVE_CEIL 1
+//#define HAVE_COPYSIGN 1   // TODO, WinRT: consider using _copysign instead
+#define HAVE_COS 1
+#define HAVE_COSF 1
+#define HAVE_FABS 1
+#define HAVE_FLOOR 1
+#define HAVE_LOG 1
+#define HAVE_POW 1
+//#define HAVE_SCALBN 1
+#define HAVE_SIN 1
+#define HAVE_SINF 1
+#define HAVE_SQRT 1
+#define HAVE__FSEEKI64 1
+
+/* Enable various audio drivers */
+#define SDL_AUDIO_DRIVER_XAUDIO2	1
+#define SDL_AUDIO_DRIVER_DISK	1
+#define SDL_AUDIO_DRIVER_DUMMY	1
+
+/* Enable various input drivers */
+// TODO, WinRT: Get haptic support working
+#define SDL_HAPTIC_DISABLED	1
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+#define SDL_JOYSTICK_DISABLED 1
+#else
+#define SDL_JOYSTICK_XINPUT 1
+#endif
+
+/* Enable various shared object loading systems */
+#define SDL_LOADSO_WINDOWS	1
+
+/* Enable various threading systems */
+#define SDL_THREAD_STDCPP   1
+
+/* Enable various timer systems */
+#define SDL_TIMER_WINDOWS	1
+
+/* Enable various video drivers */
+#define SDL_VIDEO_DRIVER_WINRT	1
+#define SDL_VIDEO_DRIVER_DUMMY  1
+
+// TODO, WinRT: Get a Direct3D 11 based renderer working in SDL.
+/* Enable appropriate renderer(s) */
+#define SDL_VIDEO_RENDER_D3D11  1
+
+/* Enable system power support */
+// TODO, WinRT: investigate system power support.  The Win32-based APIs don't work on WinRT.
+#define SDL_POWER_DISABLED  1
+
+/* Enable assembly routines (Win64 doesn't have inline asm) */
+#ifndef _WIN64
+#define SDL_ASSEMBLY_ROUTINES	1
+#endif
+
+#endif /* _SDL_config_windows_h */

+ 1 - 1
include/SDL_cpuinfo.h

@@ -32,7 +32,7 @@
 
 /* Need to do this here because intrin.h has C++ code in it */
 /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
 #include <intrin.h>
 #ifndef _WIN64
 #define __MMX__

+ 7 - 0
include/SDL_stdinc.h

@@ -71,6 +71,13 @@
 # include <ctype.h>
 #endif
 #ifdef HAVE_MATH_H
+# if defined(__WINRT__)
+/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on
+   Windows RT.  See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx
+   for more information.
+*/
+#  define _USE_MATH_DEFINES
+# endif
 # include <math.h>
 #endif
 #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H)

+ 65 - 0
include/SDL_system.h

@@ -94,6 +94,71 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
 #endif /* __ANDROID__ */
 
 
+/* Platform specific functions for Windows RT */
+#if defined(__WINRT__) && __WINRT__
+
+/**
+ *  \brief Windows RT / Windows Phone path types
+ */
+typedef enum
+{
+    /** \brief The installed app's root directory.
+        Files here are likely to be read-only. */
+    SDL_WINRT_PATH_INSTALLED_LOCATION,
+
+    /** \brief The app's local data store.  Files may be written here */
+    SDL_WINRT_PATH_LOCAL_FOLDER,
+
+    /** \brief The app's roaming data store.  Unsupported on Windows Phone.
+        Files written here may be copied to other machines via a network
+        connection.
+    */
+    SDL_WINRT_PATH_ROAMING_FOLDER,
+
+    /** \brief The app's temporary data store.  Unsupported on Windows Phone.
+        Files written here may be deleted at any time. */
+    SDL_WINRT_PATH_TEMP_FOLDER
+} SDL_WinRT_Path;
+
+
+/**
+ *  \brief Retrieves a Windows RT defined path on the local file system
+ *
+ *  \note Documentation on most app-specific path types on Windows RT
+ *      can be found on MSDN, at the URL:
+ *      http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
+ *
+ *  \param pathType The type of path to retrieve.
+ *  \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL
+ *      if the path is not available for any reason.  Not all paths are
+ *      available on all versions of Windows.  This is especially true on
+ *      Windows Phone.  Check the documentation for the given
+ *      SDL_WinRT_Path for more information on which path types are
+ *      supported where.
+ */
+extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType);
+
+/**
+ *  \brief Retrieves a Windows RT defined path on the local file system
+ *
+ *  \note Documentation on most app-specific path types on Windows RT
+ *      can be found on MSDN, at the URL:
+ *      http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
+ *
+ *  \param pathType The type of path to retrieve.
+ *  \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL
+ *      if the path is not available for any reason.  Not all paths are
+ *      available on all versions of Windows.  This is especially true on
+ *      Windows Phone.  Check the documentation for the given
+ *      SDL_WinRT_Path for more information on which path types are
+ *      supported where.
+ */
+extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
+
+
+#endif /* __WINRT__ */
+
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }

+ 13 - 0
include/SDL_syswm.h

@@ -56,6 +56,10 @@ struct SDL_SysWMinfo;
 #include <windows.h>
 #endif
 
+#if defined(SDL_VIDEO_DRIVER_WINRT)
+#include <Unknwn.h>
+#endif
+
 /* This is the structure for custom window manager events */
 #if defined(SDL_VIDEO_DRIVER_X11)
 #if defined(__APPLE__) && defined(__MACH__)
@@ -90,6 +94,7 @@ typedef struct _NSWindow NSWindow;
 #include <UIKit/UIKit.h>
 #else
 typedef struct _UIWindow UIWindow;
+typedef struct _UIViewController UIViewController;
 #endif
 #endif
 
@@ -100,6 +105,7 @@ typedef enum
 {
     SDL_SYSWM_UNKNOWN,
     SDL_SYSWM_WINDOWS,
+    SDL_SYSWM_WINDOWSRT,
     SDL_SYSWM_X11,
     SDL_SYSWM_DIRECTFB,
     SDL_SYSWM_COCOA,
@@ -168,6 +174,12 @@ struct SDL_SysWMinfo
             HWND window;                /**< The window handle */
         } win;
 #endif
+#if defined(SDL_VIDEO_DRIVER_WINRT)
+        struct
+        {
+            IUnknown * window;          /**< The Windows RT CoreWindow */
+        } winrt;
+#endif
 #if defined(SDL_VIDEO_DRIVER_X11)
         struct
         {
@@ -193,6 +205,7 @@ struct SDL_SysWMinfo
         struct
         {
             UIWindow *window;           /* The UIKit window */
+            UIViewController *viewcontroller;   /* The UIKit view controller */
         } uikit;
 #endif
         /* Can't have an empty union */

+ 2 - 2
include/begin_code.h

@@ -41,7 +41,7 @@
 #  else
 #   define DECLSPEC __declspec(export)
 #  endif
-# elif defined(__WIN32__)
+# elif defined(__WIN32__) || defined(__WINRT__)
 #  ifdef __BORLANDC__
 #   ifdef BUILD_SDL
 #    define DECLSPEC
@@ -62,7 +62,7 @@
 
 /* By default SDL uses the C calling convention */
 #ifndef SDLCALL
-#if defined(__WIN32__) && !defined(__GNUC__)
+#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
 #define SDLCALL __cdecl
 #else
 #define SDLCALL

+ 2 - 0
src/SDL_assert.c

@@ -37,8 +37,10 @@
 #else  /* fprintf, _exit(), etc. */
 #include <stdio.h>
 #include <stdlib.h>
+#if ! defined(__WINRT__)
 #include <unistd.h>
 #endif
+#endif
 
 static SDL_assert_state
 SDL_PromptAssertion(const SDL_assert_data *data, void *userdata);

+ 2 - 2
src/SDL_log.c

@@ -28,7 +28,7 @@
 #include <stdio.h>
 #endif
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) || defined(__WINRT__)
 #include "core/windows/SDL_windows.h"
 #elif defined(__ANDROID__)
 #include <android/log.h>
@@ -315,7 +315,7 @@ static void
 SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
               const char *message)
 {
-#if defined(__WIN32__)
+#if defined(__WIN32__) || defined(__WINRT__)
     /* Way too many allocations here, urgh */
     /* Note: One can't call SDL_SetError here, since that function itself logs. */
     {

+ 1 - 1
src/atomic/SDL_spinlock.c

@@ -25,7 +25,7 @@
 #include "SDL_timer.h"
 
 /* Don't do the check for Visual Studio 2005, it's safe here */
-#ifdef __WIN32__
+#if defined(__WIN32__) || defined(__WINRT__)
 #include "../core/windows/SDL_windows.h"
 #endif
 

+ 583 - 437
src/audio/xaudio2/SDL_xaudio2.c

@@ -1,437 +1,583 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-#include "SDL_config.h"
-
-#if SDL_AUDIO_DRIVER_XAUDIO2
-
-#include "../../core/windows/SDL_windows.h"
-#include "SDL_audio.h"
-#include "../SDL_audio_c.h"
-#include "../SDL_sysaudio.h"
-#include "SDL_assert.h"
-
-#ifdef __GNUC__
-/* The configure script already did any necessary checking */
-#  define SDL_XAUDIO2_HAS_SDK 1
-#else
-#include <dxsdkver.h> /* XAudio2 exists as of the March 2008 DirectX SDK */
-#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
-#  pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
-#else
-#  define SDL_XAUDIO2_HAS_SDK 1
-#endif
-#endif /* __GNUC__ */
-
-#ifdef SDL_XAUDIO2_HAS_SDK
-
-#define INITGUID 1
-#include <xaudio2.h>
-
-/* Hidden "this" pointer for the audio functions */
-#define _THIS   SDL_AudioDevice *this
-
-struct SDL_PrivateAudioData
-{
-    IXAudio2 *ixa2;
-    IXAudio2SourceVoice *source;
-    IXAudio2MasteringVoice *mastering;
-    HANDLE semaphore;
-    Uint8 *mixbuf;
-    int mixlen;
-    Uint8 *nextbuf;
-};
-
-
-static __inline__ char *
-utf16_to_utf8(const WCHAR *S)
-{
-    /* !!! FIXME: this should be UTF-16, not UCS-2! */
-    return SDL_iconv_string("UTF-8", "UCS-2", (char *)(S),
-                            (SDL_wcslen(S)+1)*sizeof(WCHAR));
-}
-
-static void
-XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
-{
-    IXAudio2 *ixa2 = NULL;
-    UINT32 devcount = 0;
-    UINT32 i = 0;
-
-    if (iscapture) {
-        SDL_SetError("XAudio2: capture devices unsupported.");
-        return;
-    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
-        SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
-        return;
-    } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
-        SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
-        IXAudio2_Release(ixa2);
-        return;
-    }
-
-    for (i = 0; i < devcount; i++) {
-        XAUDIO2_DEVICE_DETAILS details;
-        if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
-            char *str = utf16_to_utf8(details.DisplayName);
-            if (str != NULL) {
-                addfn(str);
-                SDL_free(str);  /* addfn() made a copy of the string. */
-            }
-        }
-    }
-
-    IXAudio2_Release(ixa2);
-}
-
-static void STDMETHODCALLTYPE
-VoiceCBOnBufferEnd(THIS_ void *data)
-{
-    /* Just signal the SDL audio thread and get out of XAudio2's way. */
-    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
-    ReleaseSemaphore(this->hidden->semaphore, 1, NULL);
-}
-
-static void STDMETHODCALLTYPE
-VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
-{
-    /* !!! FIXME: attempt to recover, or mark device disconnected. */
-    SDL_assert(0 && "write me!");
-}
-
-/* no-op callbacks... */
-static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
-static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
-static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
-static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
-static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
-
-
-static Uint8 *
-XAUDIO2_GetDeviceBuf(_THIS)
-{
-    return this->hidden->nextbuf;
-}
-
-static void
-XAUDIO2_PlayDevice(_THIS)
-{
-    XAUDIO2_BUFFER buffer;
-    Uint8 *mixbuf = this->hidden->mixbuf;
-    Uint8 *nextbuf = this->hidden->nextbuf;
-    const int mixlen = this->hidden->mixlen;
-    IXAudio2SourceVoice *source = this->hidden->source;
-    HRESULT result = S_OK;
-
-    if (!this->enabled) { /* shutting down? */
-        return;
-    }
-
-    /* Submit the next filled buffer */
-    SDL_zero(buffer);
-    buffer.AudioBytes = mixlen;
-    buffer.pAudioData = nextbuf;
-    buffer.pContext = this;
-
-    if (nextbuf == mixbuf) {
-        nextbuf += mixlen;
-    } else {
-        nextbuf = mixbuf;
-    }
-    this->hidden->nextbuf = nextbuf;
-
-    result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
-    if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
-        /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
-    }
-
-    if (result != S_OK) {  /* uhoh, panic! */
-        IXAudio2SourceVoice_FlushSourceBuffers(source);
-        this->enabled = 0;
-    }
-}
-
-static void
-XAUDIO2_WaitDevice(_THIS)
-{
-    if (this->enabled) {
-        WaitForSingleObject(this->hidden->semaphore, INFINITE);
-    }
-}
-
-static void
-XAUDIO2_WaitDone(_THIS)
-{
-    IXAudio2SourceVoice *source = this->hidden->source;
-    XAUDIO2_VOICE_STATE state;
-    SDL_assert(!this->enabled);  /* flag that stops playing. */
-    IXAudio2SourceVoice_Discontinuity(source);
-    IXAudio2SourceVoice_GetState(source, &state);
-    while (state.BuffersQueued > 0) {
-        WaitForSingleObject(this->hidden->semaphore, INFINITE);
-        IXAudio2SourceVoice_GetState(source, &state);
-    }
-}
-
-
-static void
-XAUDIO2_CloseDevice(_THIS)
-{
-    if (this->hidden != NULL) {
-        IXAudio2 *ixa2 = this->hidden->ixa2;
-        IXAudio2SourceVoice *source = this->hidden->source;
-        IXAudio2MasteringVoice *mastering = this->hidden->mastering;
-
-        if (source != NULL) {
-            IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
-            IXAudio2SourceVoice_FlushSourceBuffers(source);
-            IXAudio2SourceVoice_DestroyVoice(source);
-        }
-        if (ixa2 != NULL) {
-            IXAudio2_StopEngine(ixa2);
-        }
-        if (mastering != NULL) {
-            IXAudio2MasteringVoice_DestroyVoice(mastering);
-        }
-        if (ixa2 != NULL) {
-            IXAudio2_Release(ixa2);
-        }
-        if (this->hidden->mixbuf != NULL) {
-            SDL_free(this->hidden->mixbuf);
-        }
-        if (this->hidden->semaphore != NULL) {
-            CloseHandle(this->hidden->semaphore);
-        }
-
-        SDL_free(this->hidden);
-        this->hidden = NULL;
-    }
-}
-
-static int
-XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
-{
-    HRESULT result = S_OK;
-    WAVEFORMATEX waveformat;
-    int valid_format = 0;
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
-    IXAudio2 *ixa2 = NULL;
-    IXAudio2SourceVoice *source = NULL;
-    UINT32 devId = 0;  /* 0 == system default device. */
-
-    static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
-        VoiceCBOnVoiceProcessPassStart,
-        VoiceCBOnVoiceProcessPassEnd,
-        VoiceCBOnStreamEnd,
-        VoiceCBOnBufferStart,
-        VoiceCBOnBufferEnd,
-        VoiceCBOnLoopEnd,
-        VoiceCBOnVoiceError
-    };
-
-    static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
-
-    if (iscapture) {
-        return SDL_SetError("XAudio2: capture devices unsupported.");
-    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
-        return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
-    }
-
-    if (devname != NULL) {
-        UINT32 devcount = 0;
-        UINT32 i = 0;
-
-        if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
-            IXAudio2_Release(ixa2);
-            return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
-        }
-        for (i = 0; i < devcount; i++) {
-            XAUDIO2_DEVICE_DETAILS details;
-            if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
-                char *str = utf16_to_utf8(details.DisplayName);
-                if (str != NULL) {
-                    const int match = (SDL_strcmp(str, devname) == 0);
-                    SDL_free(str);
-                    if (match) {
-                        devId = i;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (i == devcount) {
-            IXAudio2_Release(ixa2);
-            return SDL_SetError("XAudio2: Requested device not found.");
-        }
-    }
-
-    /* Initialize all variables that we clean on shutdown */
-    this->hidden = (struct SDL_PrivateAudioData *)
-        SDL_malloc((sizeof *this->hidden));
-    if (this->hidden == NULL) {
-        IXAudio2_Release(ixa2);
-        return SDL_OutOfMemory();
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
-    this->hidden->ixa2 = ixa2;
-    this->hidden->semaphore = CreateSemaphore(NULL, 1, 2, NULL);
-    if (this->hidden->semaphore == NULL) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: CreateSemaphore() failed!");
-    }
-
-    while ((!valid_format) && (test_format)) {
-        switch (test_format) {
-        case AUDIO_U8:
-        case AUDIO_S16:
-        case AUDIO_S32:
-        case AUDIO_F32:
-            this->spec.format = test_format;
-            valid_format = 1;
-            break;
-        }
-        test_format = SDL_NextAudioFormat();
-    }
-
-    if (!valid_format) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: Unsupported audio format");
-    }
-
-    /* Update the fragment size as size in bytes */
-    SDL_CalculateAudioSpec(&this->spec);
-
-    /* We feed a Source, it feeds the Mastering, which feeds the device. */
-    this->hidden->mixlen = this->spec.size;
-    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
-    if (this->hidden->mixbuf == NULL) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_OutOfMemory();
-    }
-    this->hidden->nextbuf = this->hidden->mixbuf;
-    SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
-
-    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
-       Xbox360, this means 5.1 output, but on Windows, it means "figure out
-       what the system has." It might be preferable to let XAudio2 blast
-       stereo output to appropriate surround sound configurations
-       instead of clamping to 2 channels, even though we'll configure the
-       Source Voice for whatever number of channels you supply. */
-    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
-                                           XAUDIO2_DEFAULT_CHANNELS,
-                                           this->spec.freq, 0, devId, NULL);
-    if (result != S_OK) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: Couldn't create mastering voice");
-    }
-
-    SDL_zero(waveformat);
-    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
-        waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
-    } else {
-        waveformat.wFormatTag = WAVE_FORMAT_PCM;
-    }
-    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
-    waveformat.nChannels = this->spec.channels;
-    waveformat.nSamplesPerSec = this->spec.freq;
-    waveformat.nBlockAlign =
-        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
-    waveformat.nAvgBytesPerSec =
-        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
-
-    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
-                                        XAUDIO2_VOICE_NOSRC |
-                                        XAUDIO2_VOICE_NOPITCH,
-                                        1.0f, &callbacks, NULL, NULL);
-    if (result != S_OK) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: Couldn't create source voice");
-    }
-    this->hidden->source = source;
-
-    /* Start everything playing! */
-    result = IXAudio2_StartEngine(ixa2);
-    if (result != S_OK) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: Couldn't start engine");
-    }
-
-    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
-    if (result != S_OK) {
-        XAUDIO2_CloseDevice(this);
-        return SDL_SetError("XAudio2: Couldn't start source voice");
-    }
-
-    return 0; /* good to go. */
-}
-
-static void
-XAUDIO2_Deinitialize(void)
-{
-    WIN_CoUninitialize();
-}
-
-#endif  /* SDL_XAUDIO2_HAS_SDK */
-
-
-static int
-XAUDIO2_Init(SDL_AudioDriverImpl * impl)
-{
-#ifndef SDL_XAUDIO2_HAS_SDK
-    SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
-    return 0;  /* no XAudio2 support, ever. Update your SDK! */
-#else
-    /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
-    IXAudio2 *ixa2 = NULL;
-    if (FAILED(WIN_CoInitialize())) {
-        SDL_SetError("XAudio2: CoInitialize() failed");
-        return 0;
-    }
-
-    if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
-        WIN_CoUninitialize();
-        SDL_SetError("XAudio2: XAudio2Create() failed at initialization");
-        return 0;  /* not available. */
-    }
-    IXAudio2_Release(ixa2);
-
-    /* Set the function pointers */
-    impl->DetectDevices = XAUDIO2_DetectDevices;
-    impl->OpenDevice = XAUDIO2_OpenDevice;
-    impl->PlayDevice = XAUDIO2_PlayDevice;
-    impl->WaitDevice = XAUDIO2_WaitDevice;
-    impl->WaitDone = XAUDIO2_WaitDone;
-    impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
-    impl->CloseDevice = XAUDIO2_CloseDevice;
-    impl->Deinitialize = XAUDIO2_Deinitialize;
-
-    return 1;   /* this audio target is available. */
-#endif
-}
-
-AudioBootStrap XAUDIO2_bootstrap = {
-    "xaudio2", "XAudio2", XAUDIO2_Init, 0
-};
-
-#endif  /* SDL_AUDIO_DRIVER_XAUDIO2 */
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* WinRT NOTICE:
+
+   A number of changes were warranted to SDL's XAudio2 backend in order to
+   get it compiling for Windows RT.
+
+   When compiling for WinRT, XAudio2.h requires that it be compiled in a C++
+   file, and not a straight C file.  Trying to compile it as C leads to lots
+   of errors, at least with MSVC 2012 and Windows SDK 8.0, as of Nov 22, 2012.
+   To address this specific issue, a few changes were made to SDL_xaudio2.c:
+   
+   1. SDL_xaudio2.c is compiled as a C++ file in WinRT builds.  Exported
+      symbols, namely XAUDIO2_bootstrap, uses 'extern "C"' to make sure the
+      rest of SDL can access it.  Non-WinRT builds continue to compile
+      SDL_xaudio2.c as a C file.
+   2. A macro redefines variables named 'this' to '_this', to prevent compiler
+      errors (C2355 in Visual C++) related to 'this' being a reserverd keyword.
+      This hack may need to be altered in the future, particularly if C++'s
+      'this' keyword needs to be used (within SDL_xaudio2.c).  At the time
+      WinRT support was initially added to SDL's XAudio2 backend, this
+      capability was not needed.
+   3. The C-style macros to invoke XAudio2's COM-based methods were
+      rewritten to be C++-friendly.  These are provided in the file,
+      SDL_xaudio2_winrthelpers.h.
+   4. IXAudio2::CreateSourceVoice, when used in C++, requires its callbacks to
+      be specified via a C++ class.  SDL's XAudio2 backend was written with
+      C-style callbacks.  A class to bridge these two interfaces,
+      SDL_XAudio2VoiceCallback, was written to make XAudio2 happy.  Its methods
+      just call SDL's existing, C-style callbacks.
+   5. Multiple checks for the __cplusplus macro were made, in appropriate
+      places.  
+
+
+   A few additional changes to SDL's XAudio2 backend were warranted by API
+   changes to Windows.  Many, but not all of these are documented by Microsoft
+   at:
+   http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
+
+   1. Windows' thread synchronization function, CreateSemaphore, was removed
+      from Windows RT.  SDL's semaphore API was substituted instead.
+   2. The method calls, IXAudio2::GetDeviceCount and IXAudio2::GetDeviceDetails
+      were removed from the XAudio2 API.  Microsoft is telling developers to
+      use APIs in Windows::Foundation instead.
+      For SDL, the missing methods were reimplemented using the APIs Microsoft
+      said to use.
+   3. CoInitialize and CoUninitialize are not available in Windows RT.
+      These calls were removed, as COM will have been initialized earlier,
+      at least by the call to the WinRT app's main function
+      (aka 'int main(Platform::Array<Platform::String^>^)).  (DLudwig:
+      This was my understanding of how WinRT: the 'main' function uses
+      a tag of [MTAThread], which should initialize COM.  My understanding
+      of COM is somewhat limited, and I may be incorrect here.)
+   4. IXAudio2::CreateMasteringVoice changed its integer-based 'DeviceIndex'
+      argument to a string-based one, 'szDeviceId'.  In Windows RT, the
+      string-based argument will be used.
+*/
+
+#include "SDL_config.h"
+
+#if SDL_AUDIO_DRIVER_XAUDIO2
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "../../core/windows/SDL_windows.h"
+#include "SDL_audio.h"
+#include "../SDL_audio_c.h"
+#include "../SDL_sysaudio.h"
+#include "SDL_assert.h"
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(__WINRT__)
+#  define SDL_XAUDIO2_HAS_SDK 1
+#endif
+#if defined(__WIN32__)
+#ifdef __GNUC__
+/* The configure script already did any necessary checking */
+#  define SDL_XAUDIO2_HAS_SDK 1
+#elif defined(__WINRT__)
+/* WinRT always has access to the .the XAudio 2 SD
+#  define SDL_XAUDIO2_HAS_SDK
+#else
+#include <dxsdkver.h> /* XAudio2 exists as of the March 2008 DirectX SDK */
+#if (!defined(_DXSDK_BUILD_MAJOR) || (_DXSDK_BUILD_MAJOR < 1284))
+#  pragma message("Your DirectX SDK is too old. Disabling XAudio2 support.")
+#else
+#  define SDL_XAUDIO2_HAS_SDK 1
+#endif
+#endif
+
+#ifdef SDL_XAUDIO2_HAS_SDK
+
+#define INITGUID 1
+#include <xaudio2.h>
+
+/* Hidden "this" pointer for the audio functions */
+#define _THIS   SDL_AudioDevice *this
+
+#ifdef __cplusplus
+#define this _this
+#include "SDL_xaudio2_winrthelpers.h"
+#endif
+
+struct SDL_PrivateAudioData
+{
+    IXAudio2 *ixa2;
+    IXAudio2SourceVoice *source;
+    IXAudio2MasteringVoice *mastering;
+    SDL_sem * semaphore;
+    Uint8 *mixbuf;
+    int mixlen;
+    Uint8 *nextbuf;
+};
+
+
+static void
+XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
+{
+    IXAudio2 *ixa2 = NULL;
+    UINT32 devcount = 0;
+    UINT32 i = 0;
+
+    if (iscapture) {
+        SDL_SetError("XAudio2: capture devices unsupported.");
+        return;
+    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
+        SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
+        return;
+    } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
+        SDL_SetError("XAudio2: IXAudio2::GetDeviceCount() failed.");
+        IXAudio2_Release(ixa2);
+        return;
+    }
+
+    for (i = 0; i < devcount; i++) {
+        XAUDIO2_DEVICE_DETAILS details;
+        if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
+            char *str = WIN_StringToUTF8(details.DisplayName);
+            if (str != NULL) {
+                addfn(str);
+                SDL_free(str);  /* addfn() made a copy of the string. */
+            }
+        }
+    }
+
+    IXAudio2_Release(ixa2);
+}
+
+static void STDMETHODCALLTYPE
+VoiceCBOnBufferEnd(THIS_ void *data)
+{
+    /* Just signal the SDL audio thread and get out of XAudio2's way. */
+    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
+    SDL_SemPost(this->hidden->semaphore);
+}
+
+static void STDMETHODCALLTYPE
+VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
+{
+    /* !!! FIXME: attempt to recover, or mark device disconnected. */
+    SDL_assert(0 && "write me!");
+}
+
+/* no-op callbacks... */
+static void STDMETHODCALLTYPE VoiceCBOnStreamEnd(THIS) {}
+static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassStart(THIS_ UINT32 b) {}
+static void STDMETHODCALLTYPE VoiceCBOnVoiceProcessPassEnd(THIS) {}
+static void STDMETHODCALLTYPE VoiceCBOnBufferStart(THIS_ void *data) {}
+static void STDMETHODCALLTYPE VoiceCBOnLoopEnd(THIS_ void *data) {}
+
+#if defined(__cplusplus)
+class SDL_XAudio2VoiceCallback : public IXAudio2VoiceCallback
+{
+public:
+    STDMETHOD_(void, OnBufferEnd)(void *pBufferContext) {
+        VoiceCBOnBufferEnd(pBufferContext);
+    }
+    STDMETHOD_(void, OnBufferStart)(void *pBufferContext) {
+        VoiceCBOnBufferStart(pBufferContext);
+    }
+    STDMETHOD_(void, OnLoopEnd)(void *pBufferContext) {
+        VoiceCBOnLoopEnd(pBufferContext);
+    }
+    STDMETHOD_(void, OnStreamEnd)() {
+        VoiceCBOnStreamEnd();
+    }
+    STDMETHOD_(void, OnVoiceError)(void *pBufferContext, HRESULT Error) {
+        VoiceCBOnVoiceError(pBufferContext, Error);
+    }
+    STDMETHOD_(void, OnVoiceProcessingPassEnd)() {
+        VoiceCBOnVoiceProcessPassEnd();
+    }
+    STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32 BytesRequired) {
+        VoiceCBOnVoiceProcessPassStart(BytesRequired);
+    }
+};
+#endif
+
+static Uint8 *
+XAUDIO2_GetDeviceBuf(_THIS)
+{
+    return this->hidden->nextbuf;
+}
+
+static void
+XAUDIO2_PlayDevice(_THIS)
+{
+    XAUDIO2_BUFFER buffer;
+    Uint8 *mixbuf = this->hidden->mixbuf;
+    Uint8 *nextbuf = this->hidden->nextbuf;
+    const int mixlen = this->hidden->mixlen;
+    IXAudio2SourceVoice *source = this->hidden->source;
+    HRESULT result = S_OK;
+
+    if (!this->enabled) { /* shutting down? */
+        return;
+    }
+
+    /* Submit the next filled buffer */
+    SDL_zero(buffer);
+    buffer.AudioBytes = mixlen;
+    buffer.pAudioData = nextbuf;
+    buffer.pContext = this;
+
+    if (nextbuf == mixbuf) {
+        nextbuf += mixlen;
+    } else {
+        nextbuf = mixbuf;
+    }
+    this->hidden->nextbuf = nextbuf;
+
+    result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
+    if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
+        /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
+    }
+
+    if (result != S_OK) {  /* uhoh, panic! */
+        IXAudio2SourceVoice_FlushSourceBuffers(source);
+        this->enabled = 0;
+    }
+}
+
+static void
+XAUDIO2_WaitDevice(_THIS)
+{
+    if (this->enabled) {
+        SDL_SemWait(this->hidden->semaphore);
+    }
+}
+
+static void
+XAUDIO2_WaitDone(_THIS)
+{
+    IXAudio2SourceVoice *source = this->hidden->source;
+    XAUDIO2_VOICE_STATE state;
+    SDL_assert(!this->enabled);  /* flag that stops playing. */
+    IXAudio2SourceVoice_Discontinuity(source);
+    IXAudio2SourceVoice_GetState(source, &state);
+    while (state.BuffersQueued > 0) {
+        SDL_SemWait(this->hidden->semaphore);
+        IXAudio2SourceVoice_GetState(source, &state);
+    }
+}
+
+
+static void
+XAUDIO2_CloseDevice(_THIS)
+{
+    if (this->hidden != NULL) {
+        IXAudio2 *ixa2 = this->hidden->ixa2;
+        IXAudio2SourceVoice *source = this->hidden->source;
+        IXAudio2MasteringVoice *mastering = this->hidden->mastering;
+
+        if (source != NULL) {
+            IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
+            IXAudio2SourceVoice_FlushSourceBuffers(source);
+            IXAudio2SourceVoice_DestroyVoice(source);
+        }
+        if (ixa2 != NULL) {
+            IXAudio2_StopEngine(ixa2);
+        }
+        if (mastering != NULL) {
+            IXAudio2MasteringVoice_DestroyVoice(mastering);
+        }
+        if (ixa2 != NULL) {
+            IXAudio2_Release(ixa2);
+        }
+        if (this->hidden->mixbuf != NULL) {
+            SDL_free(this->hidden->mixbuf);
+        }
+        if (this->hidden->semaphore != NULL) {
+            SDL_DestroySemaphore(this->hidden->semaphore);
+        }
+
+        SDL_free(this->hidden);
+        this->hidden = NULL;
+    }
+}
+
+static int
+XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
+{
+    HRESULT result = S_OK;
+    WAVEFORMATEX waveformat;
+    int valid_format = 0;
+    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
+    IXAudio2 *ixa2 = NULL;
+    IXAudio2SourceVoice *source = NULL;
+#if defined(__WINRT__)
+    WCHAR devIdBuffer[256];
+    LPCWSTR devId = 0;
+#else
+    UINT32 devId = 0;  /* 0 == system default device. */
+#endif
+
+#if defined(__cplusplus)
+    static SDL_XAudio2VoiceCallback callbacks;
+#else
+	static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
+	    VoiceCBOnVoiceProcessPassStart,
+        VoiceCBOnVoiceProcessPassEnd,
+        VoiceCBOnStreamEnd,
+        VoiceCBOnBufferStart,
+        VoiceCBOnBufferEnd,
+        VoiceCBOnLoopEnd,
+        VoiceCBOnVoiceError
+    };
+
+	static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
+#endif // ! defined(__cplusplus)
+
+#if defined(__WINRT__)
+    SDL_zero(devIdBuffer);
+#endif
+
+    if (iscapture) {
+        return SDL_SetError("XAudio2: capture devices unsupported.");
+    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
+        return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
+    }
+    /*
+    XAUDIO2_DEBUG_CONFIGURATION debugConfig;
+    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;
+    debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; //XAUDIO2_LOG_WARNINGS;
+    debugConfig.LogThreadID = TRUE;
+    debugConfig.LogFileline = TRUE;
+    debugConfig.LogFunctionName = TRUE;
+    debugConfig.LogTiming = TRUE;
+    ixa2->SetDebugConfiguration(&debugConfig);
+    */
+
+#if ! defined(__WINRT__) || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+    if (devname != NULL) {
+        UINT32 devcount = 0;
+        UINT32 i = 0;
+
+        if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
+            IXAudio2_Release(ixa2);
+            return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
+        }
+        for (i = 0; i < devcount; i++) {
+            XAUDIO2_DEVICE_DETAILS details;
+            if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
+                char *str = WIN_StringToUTF8(details.DisplayName);
+                if (str != NULL) {
+                    const int match = (SDL_strcmp(str, devname) == 0);
+                    SDL_free(str);
+                    if (match) {
+#if defined(__WINRT__)
+                        wcsncpy_s(devIdBuffer, ARRAYSIZE(devIdBuffer), details.DeviceID, _TRUNCATE);
+                        devId = (LPCWSTR) &devIdBuffer;
+#else
+                        devId = i;
+#endif
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (i == devcount) {
+            IXAudio2_Release(ixa2);
+            return SDL_SetError("XAudio2: Requested device not found.");
+        }
+    }
+#endif
+
+    /* Initialize all variables that we clean on shutdown */
+    this->hidden = (struct SDL_PrivateAudioData *)
+        SDL_malloc((sizeof *this->hidden));
+    if (this->hidden == NULL) {
+        IXAudio2_Release(ixa2);
+        return SDL_OutOfMemory();
+    }
+    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+    this->hidden->ixa2 = ixa2;
+    this->hidden->semaphore = SDL_CreateSemaphore(1);
+    if (this->hidden->semaphore == NULL) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: CreateSemaphore() failed!");
+    }
+
+    while ((!valid_format) && (test_format)) {
+        switch (test_format) {
+        case AUDIO_U8:
+        case AUDIO_S16:
+        case AUDIO_S32:
+        case AUDIO_F32:
+            this->spec.format = test_format;
+            valid_format = 1;
+            break;
+        }
+        test_format = SDL_NextAudioFormat();
+    }
+
+    if (!valid_format) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: Unsupported audio format");
+    }
+
+    /* Update the fragment size as size in bytes */
+    SDL_CalculateAudioSpec(&this->spec);
+
+    /* We feed a Source, it feeds the Mastering, which feeds the device. */
+    this->hidden->mixlen = this->spec.size;
+    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
+    if (this->hidden->mixbuf == NULL) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_OutOfMemory();
+    }
+    this->hidden->nextbuf = this->hidden->mixbuf;
+    SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
+
+    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
+       Xbox360, this means 5.1 output, but on Windows, it means "figure out
+       what the system has." It might be preferable to let XAudio2 blast
+       stereo output to appropriate surround sound configurations
+       instead of clamping to 2 channels, even though we'll configure the
+       Source Voice for whatever number of channels you supply. */
+    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
+                                           XAUDIO2_DEFAULT_CHANNELS,
+                                           this->spec.freq, 0, devId, NULL);
+    if (result != S_OK) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: Couldn't create mastering voice");
+    }
+
+    SDL_zero(waveformat);
+    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
+        waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+    } else {
+        waveformat.wFormatTag = WAVE_FORMAT_PCM;
+    }
+    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
+    waveformat.nChannels = this->spec.channels;
+    waveformat.nSamplesPerSec = this->spec.freq;
+    waveformat.nBlockAlign =
+        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
+    waveformat.nAvgBytesPerSec =
+        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
+    waveformat.cbSize = sizeof(waveformat);
+
+#ifdef __WINRT__
+    // DLudwig: for now, make XAudio2 do sample rate conversion, just to
+    // get the loopwave test to work.
+    //
+    // TODO, WinRT: consider removing WinRT-specific source-voice creation code from SDL_xaudio2.c
+    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
+                                        0,
+                                        1.0f, &callbacks, NULL, NULL);
+#else
+    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
+                                        XAUDIO2_VOICE_NOSRC |
+                                        XAUDIO2_VOICE_NOPITCH,
+                                        1.0f, &callbacks, NULL, NULL);
+
+#endif
+    if (result != S_OK) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: Couldn't create source voice");
+    }
+    this->hidden->source = source;
+
+    /* Start everything playing! */
+    result = IXAudio2_StartEngine(ixa2);
+    if (result != S_OK) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: Couldn't start engine");
+    }
+
+    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
+    if (result != S_OK) {
+        XAUDIO2_CloseDevice(this);
+        return SDL_SetError("XAudio2: Couldn't start source voice");
+    }
+
+    return 0; /* good to go. */
+}
+
+static void
+XAUDIO2_Deinitialize(void)
+{
+#if defined(__WIN32__)
+    WIN_CoUninitialize();
+#endif
+}
+
+#endif  /* SDL_XAUDIO2_HAS_SDK */
+
+
+static int
+XAUDIO2_Init(SDL_AudioDriverImpl * impl)
+{
+#ifndef SDL_XAUDIO2_HAS_SDK
+    SDL_SetError("XAudio2: SDL was built without XAudio2 support (old DirectX SDK).");
+    return 0;  /* no XAudio2 support, ever. Update your SDK! */
+#else
+    /* XAudio2Create() is a macro that uses COM; we don't load the .dll */
+    IXAudio2 *ixa2 = NULL;
+#if defined(__WIN32__)
+    // TODO, WinRT: Investigate using CoInitializeEx here
+    if (FAILED(WIN_CoInitialize())) {
+        SDL_SetError("XAudio2: CoInitialize() failed");
+        return 0;
+    }
+#endif
+
+    if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
+#if defined(__WIN32__)
+        WIN_CoUninitialize();
+#endif
+        SDL_SetError("XAudio2: XAudio2Create() failed at initialization");
+        return 0;  /* not available. */
+    }
+    IXAudio2_Release(ixa2);
+
+    /* Set the function pointers */
+    impl->DetectDevices = XAUDIO2_DetectDevices;
+    impl->OpenDevice = XAUDIO2_OpenDevice;
+    impl->PlayDevice = XAUDIO2_PlayDevice;
+    impl->WaitDevice = XAUDIO2_WaitDevice;
+    impl->WaitDone = XAUDIO2_WaitDone;
+    impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
+    impl->CloseDevice = XAUDIO2_CloseDevice;
+    impl->Deinitialize = XAUDIO2_Deinitialize;
+
+    return 1;   /* this audio target is available. */
+#endif
+}
+
+#if defined(__cplusplus)
+extern "C"
+#endif
+AudioBootStrap XAUDIO2_bootstrap = {
+    "xaudio2", "XAudio2", XAUDIO2_Init, 0
+};
+
+#endif  /* SDL_AUDIO_DRIVER_XAUDIO2 */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 69 - 0
src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp

@@ -0,0 +1,69 @@
+
+#include <xaudio2.h>
+#include "SDL_xaudio2_winrthelpers.h"
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+using Windows::Devices::Enumeration::DeviceClass;
+using Windows::Devices::Enumeration::DeviceInformation;
+using Windows::Devices::Enumeration::DeviceInformationCollection;
+#endif
+
+HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount)
+{
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    // There doesn't seem to be any audio device enumeration on Windows Phone.
+    // In lieu of this, just treat things as if there is one and only one
+    // audio device.
+    *devcount = 1;
+    return S_OK;
+#else
+    // TODO, WinRT: make xaudio2 device enumeration only happen once, and in the background
+    auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
+    while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
+    {
+    }
+ 
+    DeviceInformationCollection^ devices = operation->GetResults();
+    *devcount = devices->Size;
+    return S_OK;
+#endif
+}
+
+HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details)
+{
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    // Windows Phone doesn't seem to have the same device enumeration APIs that
+    // Windows 8/RT has, or it doesn't have them at all.  In lieu of this,
+    // just treat things as if there is one, and only one, default device.
+    if (index != 0)
+    {
+        return XAUDIO2_E_INVALID_CALL;
+    }
+
+    if (details)
+    {
+        wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), L"default", _TRUNCATE);
+        wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), L"default", _TRUNCATE);
+    }
+    return S_OK;
+#else
+    auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
+    while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
+    {
+    }
+ 
+    DeviceInformationCollection^ devices = operation->GetResults();
+    if (index >= devices->Size)
+    {
+        return XAUDIO2_E_INVALID_CALL;
+    }
+
+    DeviceInformation^ d = devices->GetAt(index);
+    if (details)
+    {
+        wcsncpy_s(details->DeviceID, ARRAYSIZE(details->DeviceID), d->Id->Data(), _TRUNCATE);
+        wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), d->Name->Data(), _TRUNCATE);
+    }
+    return S_OK;
+#endif
+}

+ 40 - 0
src/audio/xaudio2/SDL_xaudio2_winrthelpers.h

@@ -0,0 +1,40 @@
+
+#pragma once
+
+//
+// Re-implementation of methods removed from XAudio2 (in Windows RT):
+//
+
+typedef struct XAUDIO2_DEVICE_DETAILS
+{
+    WCHAR DeviceID[256];
+    WCHAR DisplayName[256];
+    /* Other fields exist in the pre-Windows 8 version of this struct, however
+       they weren't used by SDL, so they weren't added.
+    */
+} XAUDIO2_DEVICE_DETAILS;
+
+HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount);
+HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details);
+
+
+//
+// C-style macros to call XAudio2's methods in C++:
+//
+
+#define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G))
+#define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H))
+#define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C))
+#define IXAudio2_Release(A) (A)->Release()
+#define IXAudio2_StartEngine(A) (A)->StartEngine()
+#define IXAudio2_StopEngine(A) (A)->StopEngine()
+
+#define IXAudio2MasteringVoice_DestroyVoice(A) (A)->DestroyVoice()
+
+#define IXAudio2SourceVoice_DestroyVoice(A) (A)->DestroyVoice()
+#define IXAudio2SourceVoice_Discontinuity(A) (A)->Discontinuity()
+#define IXAudio2SourceVoice_FlushSourceBuffers(A) (A)->FlushSourceBuffers()
+#define IXAudio2SourceVoice_GetState(A, B) (A)->GetState((B))
+#define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C))
+#define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C))
+#define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C))

+ 22 - 4
src/core/windows/SDL_windows.c

@@ -20,21 +20,21 @@
 */
 #include "SDL_config.h"
 
-#ifdef __WIN32__
+#if defined(__WIN32__) || defined(__WINRT__)
 
 #include "SDL_error.h"
 #include "SDL_windows.h"
 #include "SDL_assert.h"
 
-#include <objbase.h>  /* for CoInitialize/CoUninitialize */
+#include <objbase.h>  /* for CoInitialize/CoUninitialize (Win32 only) */
 
 /* Sets an error message based on GetLastError() */
 int
-WIN_SetError(const char *prefix)
+WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
 {
     TCHAR buffer[1024];
     char *message;
-    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0,
                   buffer, SDL_arraysize(buffer), NULL);
     message = WIN_StringToUTF8(buffer);
     SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
@@ -42,9 +42,24 @@ WIN_SetError(const char *prefix)
     return -1;
 }
 
+/* Sets an error message based on GetLastError() */
+int
+WIN_SetError(const char *prefix)
+{
+    return WIN_SetErrorFromHRESULT(prefix, GetLastError());
+}
+
 HRESULT
 WIN_CoInitialize(void)
 {
+#ifdef __WINRT__
+    /* DLudwig: On WinRT, it is assumed that COM was initialized in main().
+       CoInitializeEx is available (not CoInitialize though), however
+       on WinRT, main() is typically declared with the [MTAThread]
+       attribute, which, AFAIK, should initialize COM.
+    */
+    return S_OK;
+#else
     const HRESULT hr = CoInitialize(NULL);
 
     /* S_FALSE means success, but someone else already initialized. */
@@ -54,12 +69,15 @@ WIN_CoInitialize(void)
     }
 
     return hr;
+#endif
 }
 
 void
 WIN_CoUninitialize(void)
 {
+#ifndef __WINRT__
     CoUninitialize();
+#endif
 }
 
 #endif /* __WIN32__ */

+ 5 - 0
src/core/windows/SDL_windows.h

@@ -24,6 +24,7 @@
 #ifndef _INCLUDED_WINDOWS_H
 #define _INCLUDED_WINDOWS_H
 
+#if defined(__WIN32__)
 #define WIN32_LEAN_AND_MEAN
 #define STRICT
 #ifndef UNICODE
@@ -31,6 +32,7 @@
 #endif
 #undef _WIN32_WINNT
 #define _WIN32_WINNT  0x501   /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */
+#endif
 
 #include <windows.h>
 
@@ -43,6 +45,9 @@
 #define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)(S), SDL_strlen(S)+1)
 #endif
 
+/* Sets an error message based on a given HRESULT */
+extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
+
 /* Sets an error message based on GetLastError(). Always return -1. */
 extern int WIN_SetError(const char *prefix);
 

+ 94 - 0
src/core/windowsrt/SDL_winrtpaths.cpp

@@ -0,0 +1,94 @@
+/* TODO, WinRT: include copyright info in SDL_winrtpaths.cpp
+   TODO, WinRT: add note to SDL_winrtpaths.cpp mentioning that /ZW must be used when compiling the file
+*/
+
+#include "SDL_config.h"
+
+#ifdef __WINRT__
+
+extern "C" {
+#include "SDL_error.h"
+#include "SDL_stdinc.h"
+#include "SDL_system.h"
+#include "../windows/SDL_windows.h"
+}
+
+#include <string>
+#include <unordered_map>
+
+using namespace std;
+using namespace Windows::Storage;
+
+extern "C" const wchar_t *
+SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
+{
+    switch (pathType) {
+        case SDL_WINRT_PATH_INSTALLED_LOCATION:
+        {
+            static wstring path;
+            if (path.empty()) {
+                path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
+            }
+            return path.c_str();
+        }
+
+        case SDL_WINRT_PATH_LOCAL_FOLDER:
+        {
+            static wstring path;
+            if (path.empty()) {
+                path = ApplicationData::Current->LocalFolder->Path->Data();
+            }
+            return path.c_str();
+        }
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+        case SDL_WINRT_PATH_ROAMING_FOLDER:
+        {
+            static wstring path;
+            if (path.empty()) {
+                path = ApplicationData::Current->RoamingFolder->Path->Data();
+            }
+            return path.c_str();
+        }
+
+        case SDL_WINRT_PATH_TEMP_FOLDER:
+        {
+            static wstring path;
+            if (path.empty()) {
+                path = ApplicationData::Current->TemporaryFolder->Path->Data();
+            }
+            return path.c_str();
+        }
+#endif
+
+        default:
+            break;
+    }
+
+    SDL_Unsupported();
+    return NULL;
+}
+
+extern "C" const char *
+SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType)
+{
+    typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
+    static UTF8PathMap utf8Paths;
+
+    UTF8PathMap::iterator searchResult = utf8Paths.find(pathType);
+    if (searchResult != utf8Paths.end()) {
+        return searchResult->second.c_str();
+    }
+
+    const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType);
+    if (!ucs2Path) {
+        return NULL;
+    }
+
+    char * utf8Path = WIN_StringToUTF8(ucs2Path);
+    utf8Paths[pathType] = utf8Path;
+    SDL_free(utf8Path);
+    return utf8Paths[pathType].c_str();
+}
+
+#endif /* __WINRT__ */

+ 764 - 757
src/file/SDL_rwops.c

@@ -1,757 +1,764 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-/* Need this so Linux systems define fseek64o, ftell64o and off64_t */
-#define _LARGEFILE64_SOURCE
-#include "SDL_config.h"
-
-/* This file provides a general interface for SDL to read and write
-   data sources.  It can easily be extended to files, memory, etc.
-*/
-
-#include "SDL_endian.h"
-#include "SDL_rwops.h"
-
-#ifdef __APPLE__
-#include "cocoa/SDL_rwopsbundlesupport.h"
-#endif /* __APPLE__ */
-
-#ifdef ANDROID
-#include "../core/android/SDL_android.h"
-#include "SDL_system.h"
-#endif
-
-#ifdef __WIN32__
-
-/* Functions to read/write Win32 API file pointers */
-
-#include "../core/windows/SDL_windows.h"
-
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
-#endif
-
-#define READAHEAD_BUFFER_SIZE   1024
-
-static int SDLCALL
-windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
-{
-    UINT old_error_mode;
-    HANDLE h;
-    DWORD r_right, w_right;
-    DWORD must_exist, truncate;
-    int a_mode;
-
-    if (!context)
-        return -1;              /* failed (invalid call) */
-
-    context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* mark this as unusable */
-    context->hidden.windowsio.buffer.data = NULL;
-    context->hidden.windowsio.buffer.size = 0;
-    context->hidden.windowsio.buffer.left = 0;
-
-    /* "r" = reading, file must exist */
-    /* "w" = writing, truncate existing, file may not exist */
-    /* "r+"= reading or writing, file must exist            */
-    /* "a" = writing, append file may not exist             */
-    /* "a+"= append + read, file may not exist              */
-    /* "w+" = read, write, truncate. file may not exist    */
-
-    must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
-    truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
-    r_right = (SDL_strchr(mode, '+') != NULL
-               || must_exist) ? GENERIC_READ : 0;
-    a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
-    w_right = (a_mode || SDL_strchr(mode, '+')
-               || truncate) ? GENERIC_WRITE : 0;
-
-    if (!r_right && !w_right)   /* inconsistent mode */
-        return -1;              /* failed (invalid call) */
-
-    context->hidden.windowsio.buffer.data =
-        (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
-    if (!context->hidden.windowsio.buffer.data) {
-        return SDL_OutOfMemory();
-    }
-    /* Do not open a dialog box if failure */
-    old_error_mode =
-        SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
-
-    {
-        LPTSTR tstr = WIN_UTF8ToString(filename);
-        h = CreateFile(tstr, (w_right | r_right),
-                       (w_right) ? 0 : FILE_SHARE_READ, NULL,
-                       (must_exist | truncate | a_mode),
-                       FILE_ATTRIBUTE_NORMAL, NULL);
-        SDL_free(tstr);
-    }
-
-    /* restore old behavior */
-    SetErrorMode(old_error_mode);
-
-    if (h == INVALID_HANDLE_VALUE) {
-        SDL_free(context->hidden.windowsio.buffer.data);
-        context->hidden.windowsio.buffer.data = NULL;
-        SDL_SetError("Couldn't open %s", filename);
-        return -2;              /* failed (CreateFile) */
-    }
-    context->hidden.windowsio.h = h;
-    context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
-
-    return 0;                   /* ok */
-}
-
-static Sint64 SDLCALL
-windows_file_size(SDL_RWops * context)
-{
-    LARGE_INTEGER size;
-
-    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("windows_file_size: invalid context/file not opened");
-    }
-
-    if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
-        return WIN_SetError("windows_file_size");
-    }
-
-    return size.QuadPart;
-}
-
-static Sint64 SDLCALL
-windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
-{
-    DWORD windowswhence;
-    LARGE_INTEGER windowsoffset;
-
-    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
-        return SDL_SetError("windows_file_seek: invalid context/file not opened");
-    }
-
-    /* FIXME: We may be able to satisfy the seek within buffered data */
-    if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
-        offset -= (long)context->hidden.windowsio.buffer.left;
-    }
-    context->hidden.windowsio.buffer.left = 0;
-
-    switch (whence) {
-    case RW_SEEK_SET:
-        windowswhence = FILE_BEGIN;
-        break;
-    case RW_SEEK_CUR:
-        windowswhence = FILE_CURRENT;
-        break;
-    case RW_SEEK_END:
-        windowswhence = FILE_END;
-        break;
-    default:
-        return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
-    }
-
-    windowsoffset.QuadPart = offset;
-    if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
-        return WIN_SetError("windows_file_seek");
-    }
-    return windowsoffset.QuadPart;
-}
-
-static size_t SDLCALL
-windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
-{
-    size_t total_need;
-    size_t total_read = 0;
-    size_t read_ahead;
-    DWORD byte_read;
-
-    total_need = size * maxnum;
-
-    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
-        || !total_need)
-        return 0;
-
-    if (context->hidden.windowsio.buffer.left > 0) {
-        void *data = (char *) context->hidden.windowsio.buffer.data +
-            context->hidden.windowsio.buffer.size -
-            context->hidden.windowsio.buffer.left;
-        read_ahead =
-            SDL_min(total_need, context->hidden.windowsio.buffer.left);
-        SDL_memcpy(ptr, data, read_ahead);
-        context->hidden.windowsio.buffer.left -= read_ahead;
-
-        if (read_ahead == total_need) {
-            return maxnum;
-        }
-        ptr = (char *) ptr + read_ahead;
-        total_need -= read_ahead;
-        total_read += read_ahead;
-    }
-
-    if (total_need < READAHEAD_BUFFER_SIZE) {
-        if (!ReadFile
-            (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
-             READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
-            SDL_Error(SDL_EFREAD);
-            return 0;
-        }
-        read_ahead = SDL_min(total_need, (int) byte_read);
-        SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
-        context->hidden.windowsio.buffer.size = byte_read;
-        context->hidden.windowsio.buffer.left = byte_read - read_ahead;
-        total_read += read_ahead;
-    } else {
-        if (!ReadFile
-            (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
-            SDL_Error(SDL_EFREAD);
-            return 0;
-        }
-        total_read += byte_read;
-    }
-    return (total_read / size);
-}
-
-static size_t SDLCALL
-windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
-                 size_t num)
-{
-
-    size_t total_bytes;
-    DWORD byte_written;
-    size_t nwritten;
-
-    total_bytes = size * num;
-
-    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
-        || total_bytes <= 0 || !size)
-        return 0;
-
-    if (context->hidden.windowsio.buffer.left) {
-        SetFilePointer(context->hidden.windowsio.h,
-                       -(LONG)context->hidden.windowsio.buffer.left, NULL,
-                       FILE_CURRENT);
-        context->hidden.windowsio.buffer.left = 0;
-    }
-
-    /* if in append mode, we must go to the EOF before write */
-    if (context->hidden.windowsio.append) {
-        if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
-            INVALID_SET_FILE_POINTER) {
-            SDL_Error(SDL_EFWRITE);
-            return 0;
-        }
-    }
-
-    if (!WriteFile
-        (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
-        SDL_Error(SDL_EFWRITE);
-        return 0;
-    }
-
-    nwritten = byte_written / size;
-    return nwritten;
-}
-
-static int SDLCALL
-windows_file_close(SDL_RWops * context)
-{
-
-    if (context) {
-        if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
-            CloseHandle(context->hidden.windowsio.h);
-            context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* to be sure */
-        }
-        if (context->hidden.windowsio.buffer.data) {
-            SDL_free(context->hidden.windowsio.buffer.data);
-            context->hidden.windowsio.buffer.data = NULL;
-        }
-        SDL_FreeRW(context);
-    }
-    return (0);
-}
-#endif /* __WIN32__ */
-
-#ifdef HAVE_STDIO_H
-
-/* Functions to read/write stdio file pointers */
-
-static Sint64 SDLCALL
-stdio_size(SDL_RWops * context)
-{
-    Sint64 pos, size;
-
-    pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
-    if (pos < 0) {
-        return -1;
-    }
-    size = SDL_RWseek(context, 0, RW_SEEK_END);
-
-    SDL_RWseek(context, pos, RW_SEEK_SET);
-    return size;
-}
-
-static Sint64 SDLCALL
-stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
-{
-#ifdef HAVE_FSEEKO64
-    if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
-        return ftello64(context->hidden.stdio.fp);
-    }
-#elif defined(HAVE_FSEEKO)
-    if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
-        return ftello(context->hidden.stdio.fp);
-    }
-#else
-    if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
-        return (ftell(context->hidden.stdio.fp));
-    }
-#endif
-    return SDL_Error(SDL_EFSEEK);
-}
-
-static size_t SDLCALL
-stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
-{
-    size_t nread;
-
-    nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
-    if (nread == 0 && ferror(context->hidden.stdio.fp)) {
-        SDL_Error(SDL_EFREAD);
-    }
-    return (nread);
-}
-
-static size_t SDLCALL
-stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
-{
-    size_t nwrote;
-
-    nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
-    if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
-        SDL_Error(SDL_EFWRITE);
-    }
-    return (nwrote);
-}
-
-static int SDLCALL
-stdio_close(SDL_RWops * context)
-{
-    int status = 0;
-    if (context) {
-        if (context->hidden.stdio.autoclose) {
-            /* WARNING:  Check the return value here! */
-            if (fclose(context->hidden.stdio.fp) != 0) {
-                status = SDL_Error(SDL_EFWRITE);
-            }
-        }
-        SDL_FreeRW(context);
-    }
-    return status;
-}
-#endif /* !HAVE_STDIO_H */
-
-/* Functions to read/write memory pointers */
-
-static Sint64 SDLCALL
-mem_size(SDL_RWops * context)
-{
-    return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
-}
-
-static Sint64 SDLCALL
-mem_seek(SDL_RWops * context, Sint64 offset, int whence)
-{
-    Uint8 *newpos;
-
-    switch (whence) {
-    case RW_SEEK_SET:
-        newpos = context->hidden.mem.base + offset;
-        break;
-    case RW_SEEK_CUR:
-        newpos = context->hidden.mem.here + offset;
-        break;
-    case RW_SEEK_END:
-        newpos = context->hidden.mem.stop + offset;
-        break;
-    default:
-        return SDL_SetError("Unknown value for 'whence'");
-    }
-    if (newpos < context->hidden.mem.base) {
-        newpos = context->hidden.mem.base;
-    }
-    if (newpos > context->hidden.mem.stop) {
-        newpos = context->hidden.mem.stop;
-    }
-    context->hidden.mem.here = newpos;
-    return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
-}
-
-static size_t SDLCALL
-mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
-{
-    size_t total_bytes;
-    size_t mem_available;
-
-    total_bytes = (maxnum * size);
-    if ((maxnum <= 0) || (size <= 0)
-        || ((total_bytes / maxnum) != (size_t) size)) {
-        return 0;
-    }
-
-    mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
-    if (total_bytes > mem_available) {
-        total_bytes = mem_available;
-    }
-
-    SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
-    context->hidden.mem.here += total_bytes;
-
-    return (total_bytes / size);
-}
-
-static size_t SDLCALL
-mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
-{
-    if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
-        num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
-    }
-    SDL_memcpy(context->hidden.mem.here, ptr, num * size);
-    context->hidden.mem.here += num * size;
-    return (num);
-}
-
-static size_t SDLCALL
-mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
-{
-    SDL_SetError("Can't write to read-only memory");
-    return (0);
-}
-
-static int SDLCALL
-mem_close(SDL_RWops * context)
-{
-    if (context) {
-        SDL_FreeRW(context);
-    }
-    return (0);
-}
-
-
-/* Functions to create SDL_RWops structures from various data sources */
-
-SDL_RWops *
-SDL_RWFromFile(const char *file, const char *mode)
-{
-    SDL_RWops *rwops = NULL;
-    if (!file || !*file || !mode || !*mode) {
-        SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
-        return NULL;
-    }
-#if defined(ANDROID)
-#ifdef HAVE_STDIO_H
-    /* Try to open the file on the filesystem first */
-    if (*file == '/') {
-        FILE *fp = fopen(file, mode);
-        if (fp) {
-            return SDL_RWFromFP(fp, 1);
-        }
-    } else {
-        /* Try opening it from internal storage if it's a relative path */
-        char *path;
-        FILE *fp;
-
-        path = SDL_stack_alloc(char, PATH_MAX);
-        if (path) {
-            SDL_snprintf(path, PATH_MAX, "%s/%s",
-                         SDL_AndroidGetInternalStoragePath(), file);
-            fp = fopen(path, mode);
-            SDL_stack_free(path);
-            if (fp) {
-                return SDL_RWFromFP(fp, 1);
-            }
-        }
-    }
-#endif /* HAVE_STDIO_H */
-
-    /* Try to open the file from the asset system */
-    rwops = SDL_AllocRW();
-    if (!rwops)
-        return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
-    if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
-        SDL_FreeRW(rwops);
-        return NULL;
-    }
-    rwops->size = Android_JNI_FileSize;
-    rwops->seek = Android_JNI_FileSeek;
-    rwops->read = Android_JNI_FileRead;
-    rwops->write = Android_JNI_FileWrite;
-    rwops->close = Android_JNI_FileClose;
-    rwops->type = SDL_RWOPS_JNIFILE;
-
-#elif defined(__WIN32__)
-    rwops = SDL_AllocRW();
-    if (!rwops)
-        return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
-    if (windows_file_open(rwops, file, mode) < 0) {
-        SDL_FreeRW(rwops);
-        return NULL;
-    }
-    rwops->size = windows_file_size;
-    rwops->seek = windows_file_seek;
-    rwops->read = windows_file_read;
-    rwops->write = windows_file_write;
-    rwops->close = windows_file_close;
-    rwops->type = SDL_RWOPS_WINFILE;
-
-#elif HAVE_STDIO_H
-    {
-        #ifdef __APPLE__
-        FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
-        #else
-        FILE *fp = fopen(file, mode);
-        #endif
-        if (fp == NULL) {
-            SDL_SetError("Couldn't open %s", file);
-        } else {
-            rwops = SDL_RWFromFP(fp, 1);
-        }
-    }
-#else
-    SDL_SetError("SDL not compiled with stdio support");
-#endif /* !HAVE_STDIO_H */
-
-    return (rwops);
-}
-
-#ifdef HAVE_STDIO_H
-SDL_RWops *
-SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
-{
-    SDL_RWops *rwops = NULL;
-
-    rwops = SDL_AllocRW();
-    if (rwops != NULL) {
-        rwops->size = stdio_size;
-        rwops->seek = stdio_seek;
-        rwops->read = stdio_read;
-        rwops->write = stdio_write;
-        rwops->close = stdio_close;
-        rwops->hidden.stdio.fp = fp;
-        rwops->hidden.stdio.autoclose = autoclose;
-        rwops->type = SDL_RWOPS_STDFILE;
-    }
-    return (rwops);
-}
-#else
-SDL_RWops *
-SDL_RWFromFP(void * fp, SDL_bool autoclose)
-{
-    SDL_SetError("SDL not compiled with stdio support");
-    return NULL;
-}
-#endif /* HAVE_STDIO_H */
-
-SDL_RWops *
-SDL_RWFromMem(void *mem, int size)
-{
-    SDL_RWops *rwops = NULL;
-    if (!mem) {
-      SDL_InvalidParamError("mem");
-      return (rwops);
-    }
-    if (!size) {
-      SDL_InvalidParamError("size");
-      return (rwops);
-    }
-
-    rwops = SDL_AllocRW();
-    if (rwops != NULL) {
-        rwops->size = mem_size;
-        rwops->seek = mem_seek;
-        rwops->read = mem_read;
-        rwops->write = mem_write;
-        rwops->close = mem_close;
-        rwops->hidden.mem.base = (Uint8 *) mem;
-        rwops->hidden.mem.here = rwops->hidden.mem.base;
-        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
-        rwops->type = SDL_RWOPS_MEMORY;
-    }
-    return (rwops);
-}
-
-SDL_RWops *
-SDL_RWFromConstMem(const void *mem, int size)
-{
-    SDL_RWops *rwops = NULL;
-    if (!mem) {
-      SDL_InvalidParamError("mem");
-      return (rwops);
-    }
-    if (!size) {
-      SDL_InvalidParamError("size");
-      return (rwops);
-    }
-
-    rwops = SDL_AllocRW();
-    if (rwops != NULL) {
-        rwops->size = mem_size;
-        rwops->seek = mem_seek;
-        rwops->read = mem_read;
-        rwops->write = mem_writeconst;
-        rwops->close = mem_close;
-        rwops->hidden.mem.base = (Uint8 *) mem;
-        rwops->hidden.mem.here = rwops->hidden.mem.base;
-        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
-        rwops->type = SDL_RWOPS_MEMORY_RO;
-    }
-    return (rwops);
-}
-
-SDL_RWops *
-SDL_AllocRW(void)
-{
-    SDL_RWops *area;
-
-    area = (SDL_RWops *) SDL_malloc(sizeof *area);
-    if (area == NULL) {
-        SDL_OutOfMemory();
-    } else {
-        area->type = SDL_RWOPS_UNKNOWN;
-    }
-    return (area);
-}
-
-void
-SDL_FreeRW(SDL_RWops * area)
-{
-    SDL_free(area);
-}
-
-/* Functions for dynamically reading and writing endian-specific values */
-
-Uint8
-SDL_ReadU8(SDL_RWops * src)
-{
-    Uint8 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return value;
-}
-
-Uint16
-SDL_ReadLE16(SDL_RWops * src)
-{
-    Uint16 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapLE16(value));
-}
-
-Uint16
-SDL_ReadBE16(SDL_RWops * src)
-{
-    Uint16 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapBE16(value));
-}
-
-Uint32
-SDL_ReadLE32(SDL_RWops * src)
-{
-    Uint32 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapLE32(value));
-}
-
-Uint32
-SDL_ReadBE32(SDL_RWops * src)
-{
-    Uint32 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapBE32(value));
-}
-
-Uint64
-SDL_ReadLE64(SDL_RWops * src)
-{
-    Uint64 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapLE64(value));
-}
-
-Uint64
-SDL_ReadBE64(SDL_RWops * src)
-{
-    Uint64 value = 0;
-
-    SDL_RWread(src, &value, (sizeof value), 1);
-    return (SDL_SwapBE64(value));
-}
-
-size_t
-SDL_WriteU8(SDL_RWops * dst, Uint8 value)
-{
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
-{
-    value = SDL_SwapLE16(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
-{
-    value = SDL_SwapBE16(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
-{
-    value = SDL_SwapLE32(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
-{
-    value = SDL_SwapBE32(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
-{
-    value = SDL_SwapLE64(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-size_t
-SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
-{
-    value = SDL_SwapBE64(value);
-    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+/* Need this so Linux systems define fseek64o, ftell64o and off64_t */
+#define _LARGEFILE64_SOURCE
+#include "SDL_config.h"
+
+/* This file provides a general interface for SDL to read and write
+   data sources.  It can easily be extended to files, memory, etc.
+*/
+
+#include "SDL_endian.h"
+#include "SDL_rwops.h"
+
+#ifdef __APPLE__
+#include "cocoa/SDL_rwopsbundlesupport.h"
+#endif /* __APPLE__ */
+
+#ifdef ANDROID
+#include "../core/android/SDL_android.h"
+#include "SDL_system.h"
+#endif
+
+#ifdef __WIN32__
+
+/* Functions to read/write Win32 API file pointers */
+
+#include "../core/windows/SDL_windows.h"
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
+#endif
+
+#define READAHEAD_BUFFER_SIZE   1024
+
+static int SDLCALL
+windows_file_open(SDL_RWops * context, const char *filename, const char *mode)
+{
+    UINT old_error_mode;
+    HANDLE h;
+    DWORD r_right, w_right;
+    DWORD must_exist, truncate;
+    int a_mode;
+
+    if (!context)
+        return -1;              /* failed (invalid call) */
+
+    context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* mark this as unusable */
+    context->hidden.windowsio.buffer.data = NULL;
+    context->hidden.windowsio.buffer.size = 0;
+    context->hidden.windowsio.buffer.left = 0;
+
+    /* "r" = reading, file must exist */
+    /* "w" = writing, truncate existing, file may not exist */
+    /* "r+"= reading or writing, file must exist            */
+    /* "a" = writing, append file may not exist             */
+    /* "a+"= append + read, file may not exist              */
+    /* "w+" = read, write, truncate. file may not exist    */
+
+    must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
+    truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
+    r_right = (SDL_strchr(mode, '+') != NULL
+               || must_exist) ? GENERIC_READ : 0;
+    a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
+    w_right = (a_mode || SDL_strchr(mode, '+')
+               || truncate) ? GENERIC_WRITE : 0;
+
+    if (!r_right && !w_right)   /* inconsistent mode */
+        return -1;              /* failed (invalid call) */
+
+    context->hidden.windowsio.buffer.data =
+        (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
+    if (!context->hidden.windowsio.buffer.data) {
+        return SDL_OutOfMemory();
+    }
+    /* Do not open a dialog box if failure */
+    old_error_mode =
+        SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
+
+    {
+        LPTSTR tstr = WIN_UTF8ToString(filename);
+        h = CreateFile(tstr, (w_right | r_right),
+                       (w_right) ? 0 : FILE_SHARE_READ, NULL,
+                       (must_exist | truncate | a_mode),
+                       FILE_ATTRIBUTE_NORMAL, NULL);
+        SDL_free(tstr);
+    }
+
+    /* restore old behavior */
+    SetErrorMode(old_error_mode);
+
+    if (h == INVALID_HANDLE_VALUE) {
+        SDL_free(context->hidden.windowsio.buffer.data);
+        context->hidden.windowsio.buffer.data = NULL;
+        SDL_SetError("Couldn't open %s", filename);
+        return -2;              /* failed (CreateFile) */
+    }
+    context->hidden.windowsio.h = h;
+    context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE;
+
+    return 0;                   /* ok */
+}
+
+static Sint64 SDLCALL
+windows_file_size(SDL_RWops * context)
+{
+    LARGE_INTEGER size;
+
+    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
+        return SDL_SetError("windows_file_size: invalid context/file not opened");
+    }
+
+    if (!GetFileSizeEx(context->hidden.windowsio.h, &size)) {
+        return WIN_SetError("windows_file_size");
+    }
+
+    return size.QuadPart;
+}
+
+static Sint64 SDLCALL
+windows_file_seek(SDL_RWops * context, Sint64 offset, int whence)
+{
+    DWORD windowswhence;
+    LARGE_INTEGER windowsoffset;
+
+    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) {
+        return SDL_SetError("windows_file_seek: invalid context/file not opened");
+    }
+
+    /* FIXME: We may be able to satisfy the seek within buffered data */
+    if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) {
+        offset -= (long)context->hidden.windowsio.buffer.left;
+    }
+    context->hidden.windowsio.buffer.left = 0;
+
+    switch (whence) {
+    case RW_SEEK_SET:
+        windowswhence = FILE_BEGIN;
+        break;
+    case RW_SEEK_CUR:
+        windowswhence = FILE_CURRENT;
+        break;
+    case RW_SEEK_END:
+        windowswhence = FILE_END;
+        break;
+    default:
+        return SDL_SetError("windows_file_seek: Unknown value for 'whence'");
+    }
+
+    windowsoffset.QuadPart = offset;
+    if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, windowswhence)) {
+        return WIN_SetError("windows_file_seek");
+    }
+    return windowsoffset.QuadPart;
+}
+
+static size_t SDLCALL
+windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
+{
+    size_t total_need;
+    size_t total_read = 0;
+    size_t read_ahead;
+    DWORD byte_read;
+
+    total_need = size * maxnum;
+
+    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
+        || !total_need)
+        return 0;
+
+    if (context->hidden.windowsio.buffer.left > 0) {
+        void *data = (char *) context->hidden.windowsio.buffer.data +
+            context->hidden.windowsio.buffer.size -
+            context->hidden.windowsio.buffer.left;
+        read_ahead =
+            SDL_min(total_need, context->hidden.windowsio.buffer.left);
+        SDL_memcpy(ptr, data, read_ahead);
+        context->hidden.windowsio.buffer.left -= read_ahead;
+
+        if (read_ahead == total_need) {
+            return maxnum;
+        }
+        ptr = (char *) ptr + read_ahead;
+        total_need -= read_ahead;
+        total_read += read_ahead;
+    }
+
+    if (total_need < READAHEAD_BUFFER_SIZE) {
+        if (!ReadFile
+            (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data,
+             READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
+            SDL_Error(SDL_EFREAD);
+            return 0;
+        }
+        read_ahead = SDL_min(total_need, (int) byte_read);
+        SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead);
+        context->hidden.windowsio.buffer.size = byte_read;
+        context->hidden.windowsio.buffer.left = byte_read - read_ahead;
+        total_read += read_ahead;
+    } else {
+        if (!ReadFile
+            (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) {
+            SDL_Error(SDL_EFREAD);
+            return 0;
+        }
+        total_read += byte_read;
+    }
+    return (total_read / size);
+}
+
+static size_t SDLCALL
+windows_file_write(SDL_RWops * context, const void *ptr, size_t size,
+                 size_t num)
+{
+
+    size_t total_bytes;
+    DWORD byte_written;
+    size_t nwritten;
+
+    total_bytes = size * num;
+
+    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE
+        || total_bytes <= 0 || !size)
+        return 0;
+
+    if (context->hidden.windowsio.buffer.left) {
+        SetFilePointer(context->hidden.windowsio.h,
+                       -(LONG)context->hidden.windowsio.buffer.left, NULL,
+                       FILE_CURRENT);
+        context->hidden.windowsio.buffer.left = 0;
+    }
+
+    /* if in append mode, we must go to the EOF before write */
+    if (context->hidden.windowsio.append) {
+        if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
+            INVALID_SET_FILE_POINTER) {
+            SDL_Error(SDL_EFWRITE);
+            return 0;
+        }
+    }
+
+    if (!WriteFile
+        (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) {
+        SDL_Error(SDL_EFWRITE);
+        return 0;
+    }
+
+    nwritten = byte_written / size;
+    return nwritten;
+}
+
+static int SDLCALL
+windows_file_close(SDL_RWops * context)
+{
+
+    if (context) {
+        if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) {
+            CloseHandle(context->hidden.windowsio.h);
+            context->hidden.windowsio.h = INVALID_HANDLE_VALUE;   /* to be sure */
+        }
+        if (context->hidden.windowsio.buffer.data) {
+            SDL_free(context->hidden.windowsio.buffer.data);
+            context->hidden.windowsio.buffer.data = NULL;
+        }
+        SDL_FreeRW(context);
+    }
+    return (0);
+}
+#endif /* __WIN32__ */
+
+#ifdef HAVE_STDIO_H
+
+/* Functions to read/write stdio file pointers */
+
+static Sint64 SDLCALL
+stdio_size(SDL_RWops * context)
+{
+    Sint64 pos, size;
+
+    pos = SDL_RWseek(context, 0, RW_SEEK_CUR);
+    if (pos < 0) {
+        return -1;
+    }
+    size = SDL_RWseek(context, 0, RW_SEEK_END);
+
+    SDL_RWseek(context, pos, RW_SEEK_SET);
+    return size;
+}
+
+static Sint64 SDLCALL
+stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
+{
+#ifdef HAVE_FSEEKO64
+    if (fseeko64(context->hidden.stdio.fp, (off64_t)offset, whence) == 0) {
+        return ftello64(context->hidden.stdio.fp);
+    }
+#elif defined(HAVE_FSEEKO)
+    if (fseeko(context->hidden.stdio.fp, (off_t)offset, whence) == 0) {
+        return ftello(context->hidden.stdio.fp);
+    }
+#elif defined(HAVE__FSEEKI64)
+    if (_fseeki64(context->hidden.stdio.fp, offset, whence) == 0) {
+        return _ftelli64(context->hidden.stdio.fp);
+    }
+#else
+    if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
+        return (ftell(context->hidden.stdio.fp));
+    }
+#endif
+    return SDL_Error(SDL_EFSEEK);
+}
+
+static size_t SDLCALL
+stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
+{
+    size_t nread;
+
+    nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
+    if (nread == 0 && ferror(context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFREAD);
+    }
+    return (nread);
+}
+
+static size_t SDLCALL
+stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
+{
+    size_t nwrote;
+
+    nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
+    if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
+        SDL_Error(SDL_EFWRITE);
+    }
+    return (nwrote);
+}
+
+static int SDLCALL
+stdio_close(SDL_RWops * context)
+{
+    int status = 0;
+    if (context) {
+        if (context->hidden.stdio.autoclose) {
+            /* WARNING:  Check the return value here! */
+            if (fclose(context->hidden.stdio.fp) != 0) {
+                status = SDL_Error(SDL_EFWRITE);
+            }
+        }
+        SDL_FreeRW(context);
+    }
+    return status;
+}
+#endif /* !HAVE_STDIO_H */
+
+/* Functions to read/write memory pointers */
+
+static Sint64 SDLCALL
+mem_size(SDL_RWops * context)
+{
+    return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base);
+}
+
+static Sint64 SDLCALL
+mem_seek(SDL_RWops * context, Sint64 offset, int whence)
+{
+    Uint8 *newpos;
+
+    switch (whence) {
+    case RW_SEEK_SET:
+        newpos = context->hidden.mem.base + offset;
+        break;
+    case RW_SEEK_CUR:
+        newpos = context->hidden.mem.here + offset;
+        break;
+    case RW_SEEK_END:
+        newpos = context->hidden.mem.stop + offset;
+        break;
+    default:
+        return SDL_SetError("Unknown value for 'whence'");
+    }
+    if (newpos < context->hidden.mem.base) {
+        newpos = context->hidden.mem.base;
+    }
+    if (newpos > context->hidden.mem.stop) {
+        newpos = context->hidden.mem.stop;
+    }
+    context->hidden.mem.here = newpos;
+    return (Sint64)(context->hidden.mem.here - context->hidden.mem.base);
+}
+
+static size_t SDLCALL
+mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
+{
+    size_t total_bytes;
+    size_t mem_available;
+
+    total_bytes = (maxnum * size);
+    if ((maxnum <= 0) || (size <= 0)
+        || ((total_bytes / maxnum) != (size_t) size)) {
+        return 0;
+    }
+
+    mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
+    if (total_bytes > mem_available) {
+        total_bytes = mem_available;
+    }
+
+    SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
+    context->hidden.mem.here += total_bytes;
+
+    return (total_bytes / size);
+}
+
+static size_t SDLCALL
+mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
+{
+    if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
+        num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
+    }
+    SDL_memcpy(context->hidden.mem.here, ptr, num * size);
+    context->hidden.mem.here += num * size;
+    return (num);
+}
+
+static size_t SDLCALL
+mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
+{
+    SDL_SetError("Can't write to read-only memory");
+    return (0);
+}
+
+static int SDLCALL
+mem_close(SDL_RWops * context)
+{
+    if (context) {
+        SDL_FreeRW(context);
+    }
+    return (0);
+}
+
+
+/* Functions to create SDL_RWops structures from various data sources */
+
+SDL_RWops *
+SDL_RWFromFile(const char *file, const char *mode)
+{
+    SDL_RWops *rwops = NULL;
+    if (!file || !*file || !mode || !*mode) {
+        SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
+        return NULL;
+    }
+#if defined(ANDROID)
+#ifdef HAVE_STDIO_H
+    /* Try to open the file on the filesystem first */
+    if (*file == '/') {
+        FILE *fp = fopen(file, mode);
+        if (fp) {
+            return SDL_RWFromFP(fp, 1);
+        }
+    } else {
+        /* Try opening it from internal storage if it's a relative path */
+        char *path;
+        FILE *fp;
+
+        path = SDL_stack_alloc(char, PATH_MAX);
+        if (path) {
+            SDL_snprintf(path, PATH_MAX, "%s/%s",
+                         SDL_AndroidGetInternalStoragePath(), file);
+            fp = fopen(path, mode);
+            SDL_stack_free(path);
+            if (fp) {
+                return SDL_RWFromFP(fp, 1);
+            }
+        }
+    }
+#endif /* HAVE_STDIO_H */
+
+    /* Try to open the file from the asset system */
+    rwops = SDL_AllocRW();
+    if (!rwops)
+        return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
+    if (Android_JNI_FileOpen(rwops, file, mode) < 0) {
+        SDL_FreeRW(rwops);
+        return NULL;
+    }
+    rwops->size = Android_JNI_FileSize;
+    rwops->seek = Android_JNI_FileSeek;
+    rwops->read = Android_JNI_FileRead;
+    rwops->write = Android_JNI_FileWrite;
+    rwops->close = Android_JNI_FileClose;
+    rwops->type = SDL_RWOPS_JNIFILE;
+
+#elif defined(__WIN32__)
+    rwops = SDL_AllocRW();
+    if (!rwops)
+        return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
+    if (windows_file_open(rwops, file, mode) < 0) {
+        SDL_FreeRW(rwops);
+        return NULL;
+    }
+    rwops->size = windows_file_size;
+    rwops->seek = windows_file_seek;
+    rwops->read = windows_file_read;
+    rwops->write = windows_file_write;
+    rwops->close = windows_file_close;
+    rwops->type = SDL_RWOPS_WINFILE;
+
+#elif HAVE_STDIO_H
+    {
+        #ifdef __APPLE__
+        FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
+        #elif __WINRT__
+        FILE *fp = NULL;
+        fopen_s(&fp, file, mode);
+        #else
+        FILE *fp = fopen(file, mode);
+        #endif
+        if (fp == NULL) {
+            SDL_SetError("Couldn't open %s", file);
+        } else {
+            rwops = SDL_RWFromFP(fp, 1);
+        }
+    }
+#else
+    SDL_SetError("SDL not compiled with stdio support");
+#endif /* !HAVE_STDIO_H */
+
+    return (rwops);
+}
+
+#ifdef HAVE_STDIO_H
+SDL_RWops *
+SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
+{
+    SDL_RWops *rwops = NULL;
+
+    rwops = SDL_AllocRW();
+    if (rwops != NULL) {
+        rwops->size = stdio_size;
+        rwops->seek = stdio_seek;
+        rwops->read = stdio_read;
+        rwops->write = stdio_write;
+        rwops->close = stdio_close;
+        rwops->hidden.stdio.fp = fp;
+        rwops->hidden.stdio.autoclose = autoclose;
+        rwops->type = SDL_RWOPS_STDFILE;
+    }
+    return (rwops);
+}
+#else
+SDL_RWops *
+SDL_RWFromFP(void * fp, SDL_bool autoclose)
+{
+    SDL_SetError("SDL not compiled with stdio support");
+    return NULL;
+}
+#endif /* HAVE_STDIO_H */
+
+SDL_RWops *
+SDL_RWFromMem(void *mem, int size)
+{
+    SDL_RWops *rwops = NULL;
+    if (!mem) {
+      SDL_InvalidParamError("mem");
+      return (rwops);
+    }
+    if (!size) {
+      SDL_InvalidParamError("size");
+      return (rwops);
+    }
+
+    rwops = SDL_AllocRW();
+    if (rwops != NULL) {
+        rwops->size = mem_size;
+        rwops->seek = mem_seek;
+        rwops->read = mem_read;
+        rwops->write = mem_write;
+        rwops->close = mem_close;
+        rwops->hidden.mem.base = (Uint8 *) mem;
+        rwops->hidden.mem.here = rwops->hidden.mem.base;
+        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
+        rwops->type = SDL_RWOPS_MEMORY;
+    }
+    return (rwops);
+}
+
+SDL_RWops *
+SDL_RWFromConstMem(const void *mem, int size)
+{
+    SDL_RWops *rwops = NULL;
+    if (!mem) {
+      SDL_InvalidParamError("mem");
+      return (rwops);
+    }
+    if (!size) {
+      SDL_InvalidParamError("size");
+      return (rwops);
+    }
+
+    rwops = SDL_AllocRW();
+    if (rwops != NULL) {
+        rwops->size = mem_size;
+        rwops->seek = mem_seek;
+        rwops->read = mem_read;
+        rwops->write = mem_writeconst;
+        rwops->close = mem_close;
+        rwops->hidden.mem.base = (Uint8 *) mem;
+        rwops->hidden.mem.here = rwops->hidden.mem.base;
+        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
+        rwops->type = SDL_RWOPS_MEMORY_RO;
+    }
+    return (rwops);
+}
+
+SDL_RWops *
+SDL_AllocRW(void)
+{
+    SDL_RWops *area;
+
+    area = (SDL_RWops *) SDL_malloc(sizeof *area);
+    if (area == NULL) {
+        SDL_OutOfMemory();
+    } else {
+        area->type = SDL_RWOPS_UNKNOWN;
+    }
+    return (area);
+}
+
+void
+SDL_FreeRW(SDL_RWops * area)
+{
+    SDL_free(area);
+}
+
+/* Functions for dynamically reading and writing endian-specific values */
+
+Uint8
+SDL_ReadU8(SDL_RWops * src)
+{
+    Uint8 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return value;
+}
+
+Uint16
+SDL_ReadLE16(SDL_RWops * src)
+{
+    Uint16 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapLE16(value));
+}
+
+Uint16
+SDL_ReadBE16(SDL_RWops * src)
+{
+    Uint16 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapBE16(value));
+}
+
+Uint32
+SDL_ReadLE32(SDL_RWops * src)
+{
+    Uint32 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapLE32(value));
+}
+
+Uint32
+SDL_ReadBE32(SDL_RWops * src)
+{
+    Uint32 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapBE32(value));
+}
+
+Uint64
+SDL_ReadLE64(SDL_RWops * src)
+{
+    Uint64 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapLE64(value));
+}
+
+Uint64
+SDL_ReadBE64(SDL_RWops * src)
+{
+    Uint64 value = 0;
+
+    SDL_RWread(src, &value, (sizeof value), 1);
+    return (SDL_SwapBE64(value));
+}
+
+size_t
+SDL_WriteU8(SDL_RWops * dst, Uint8 value)
+{
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
+{
+    value = SDL_SwapLE16(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
+{
+    value = SDL_SwapBE16(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
+{
+    value = SDL_SwapLE32(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
+{
+    value = SDL_SwapBE32(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
+{
+    value = SDL_SwapLE64(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+size_t
+SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
+{
+    value = SDL_SwapBE64(value);
+    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 1249 - 1249
src/joystick/SDL_gamecontroller.c

@@ -1,1249 +1,1249 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-#include "SDL_config.h"
-
-/* This is the game controller API for Simple DirectMedia Layer */
-
-#include "SDL_events.h"
-#include "SDL_assert.h"
-#include "SDL_sysjoystick.h"
-#include "SDL_hints.h"
-#include "SDL_gamecontrollerdb.h"
-
-#if !SDL_EVENTS_DISABLED
-#include "../events/SDL_events_c.h"
-#endif
-#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
-
-
-/* a list of currently opened game controllers */
-static SDL_GameController *SDL_gamecontrollers = NULL;
-
-/* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
-struct _SDL_HatMapping
-{
-    int hat;
-    Uint8 mask;
-};
-
-#define k_nMaxReverseEntries 20
-
-/**
- * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
- * MAX 4 hats supported
- */
-#define k_nMaxHatEntries 0x3f + 1
-
-/* our in memory mapping db between joystick objects and controller mappings*/
-struct _SDL_ControllerMapping
-{
-    SDL_JoystickGUID guid;
-    const char *name;
-
-    /* mapping of axis/button id to controller version */
-    int axes[SDL_CONTROLLER_AXIS_MAX];
-    int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
-
-    int buttons[SDL_CONTROLLER_BUTTON_MAX];
-    int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
-    struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
-
-    /* reverse mapping, joystick indices to buttons */
-    SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
-    SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
-
-    SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
-    SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
-    SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
-
-};
-
-
-/* our hard coded list of mapping support */
-typedef struct _ControllerMapping_t
-{
-    SDL_JoystickGUID guid;
-    char *name;
-    char *mapping;
-    struct _ControllerMapping_t *next;
-} ControllerMapping_t;
-
-static ControllerMapping_t *s_pSupportedControllers = NULL;
-#ifdef SDL_JOYSTICK_DINPUT
-static ControllerMapping_t *s_pXInputMapping = NULL;
-#endif
-
-/* The SDL game controller structure */
-struct _SDL_GameController
-{
-    SDL_Joystick *joystick; /* underlying joystick device */
-    int ref_count;
-    Uint8 hatState[4]; /* the current hat state for this controller */
-    struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
-    struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
-};
-
-
-int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
-int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
-
-/*
- * Event filter to fire controller events from joystick ones
- */
-int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
-{
-    switch( event->type )
-    {
-    case SDL_JOYAXISMOTION:
-        {
-            SDL_GameController *controllerlist;
-
-            if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;
-
-            controllerlist = SDL_gamecontrollers;
-            while ( controllerlist )
-            {
-                if ( controllerlist->joystick->instance_id == event->jaxis.which )
-                {
-                    if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */
-                    {
-                        SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
-                        Sint16 value = event->jaxis.value;
-                        switch (axis)
-                        {
-                            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
-                            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
-                                /* Shift it to be 0 - 32767. */
-                                value = value / 2 + 16384;
-                            default:
-                                break;
-                        }
-                        SDL_PrivateGameControllerAxis( controllerlist, axis, value );
-                    }
-                    else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */
-                    {
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
-                    }
-                    break;
-                }
-                controllerlist = controllerlist->next;
-            }
-        }
-        break;
-    case SDL_JOYBUTTONDOWN:
-    case SDL_JOYBUTTONUP:
-        {
-            SDL_GameController *controllerlist;
-
-            if ( event->jbutton.button >= k_nMaxReverseEntries ) break;
-
-            controllerlist = SDL_gamecontrollers;
-            while ( controllerlist )
-            {
-                if ( controllerlist->joystick->instance_id == event->jbutton.which )
-                {
-                    if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */
-                    {
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
-                    }
-                    else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */
-                    {
-                        SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
-                    }
-                    break;
-                }
-                controllerlist = controllerlist->next;
-            }
-        }
-        break;
-    case SDL_JOYHATMOTION:
-        {
-            SDL_GameController *controllerlist;
-
-            if ( event->jhat.hat >= 4 ) break;
-
-            controllerlist = SDL_gamecontrollers;
-            while ( controllerlist )
-            {
-                if ( controllerlist->joystick->instance_id == event->jhat.which )
-                {
-                    Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
-                    /* Get list of removed bits (button release) */
-                    Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
-                    /* the hat idx in the high nibble */
-                    int bHighHat = event->jhat.hat << 4;
-
-                    if ( bChanged & SDL_HAT_DOWN )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
-                    if ( bChanged & SDL_HAT_UP )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
-                    if ( bChanged & SDL_HAT_LEFT )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
-                    if ( bChanged & SDL_HAT_RIGHT )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );
-
-                    /* Get list of added bits (button press) */
-                    bChanged = event->jhat.value ^ bSame;
-
-                    if ( bChanged & SDL_HAT_DOWN )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
-                    if ( bChanged & SDL_HAT_UP )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
-                    if ( bChanged & SDL_HAT_LEFT )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
-                    if ( bChanged & SDL_HAT_RIGHT )
-                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );
-
-                    /* update our state cache */
-                    controllerlist->hatState[event->jhat.hat] = event->jhat.value;
-
-                    break;
-                }
-                controllerlist = controllerlist->next;
-            }
-        }
-        break;
-    case SDL_JOYDEVICEADDED:
-        {
-            if ( SDL_IsGameController(event->jdevice.which ) )
-            {
-                SDL_Event deviceevent;
-                deviceevent.type = SDL_CONTROLLERDEVICEADDED;
-                deviceevent.cdevice.which = event->jdevice.which;
-                SDL_PushEvent(&deviceevent);
-            }
-        }
-        break;
-    case SDL_JOYDEVICEREMOVED:
-        {
-            SDL_GameController *controllerlist = SDL_gamecontrollers;
-            while ( controllerlist )
-            {
-                if ( controllerlist->joystick->instance_id == event->jdevice.which )
-                {
-                    SDL_Event deviceevent;
-                    deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
-                    deviceevent.cdevice.which = event->jdevice.which;
-                    SDL_PushEvent(&deviceevent);
-                    break;
-                }
-                controllerlist = controllerlist->next;
-            }
-        }
-        break;
-    default:
-        break;
-    }
-
-    return 1;
-}
-
-/*
- * Helper function to scan the mappings database for a controller with the specified GUID
- */
-ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
-{
-    ControllerMapping_t *pSupportedController = s_pSupportedControllers;
-    while ( pSupportedController )
-    {
-        if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
-        {
-            return pSupportedController;
-        }
-        pSupportedController = pSupportedController->next;
-    }
-    return NULL;
-}
-
-/*
- * Helper function to determine pre-calculated offset to certain joystick mappings
- */
-ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
-{
-#ifdef SDL_JOYSTICK_DINPUT
-    if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
-    {
-        return s_pXInputMapping;
-    }
-    else
-#endif
-    {
-        SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
-        return SDL_PrivateGetControllerMappingForGUID(&jGUID);
-    }
-
-    return NULL;
-}
-
-static const char* map_StringForControllerAxis[] = {
-    "leftx",
-    "lefty",
-    "rightx",
-    "righty",
-    "lefttrigger",
-    "righttrigger",
-    NULL
-};
-
-/*
- * convert a string to its enum equivalent
- */
-SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
-{
-    int entry;
-    if ( !pchString || !pchString[0] )
-        return SDL_CONTROLLER_AXIS_INVALID;
-
-    for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
-    {
-        if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
-            return entry;
-    }
-    return SDL_CONTROLLER_AXIS_INVALID;
-}
-
-/*
- * convert an enum to its string equivalent
- */
-const char* SDL_GameControllerGetStringForAxis( SDL_GameControllerAxis axis )
-{
-    if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX)
-    {
-        return map_StringForControllerAxis[axis];
-    }
-    return NULL;
-}
-
-static const char* map_StringForControllerButton[] = {
-    "a",
-    "b",
-    "x",
-    "y",
-    "back",
-    "guide",
-    "start",
-    "leftstick",
-    "rightstick",
-    "leftshoulder",
-    "rightshoulder",
-    "dpup",
-    "dpdown",
-    "dpleft",
-    "dpright",
-    NULL
-};
-
-/*
- * convert a string to its enum equivalent
- */
-SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
-{
-    int entry;
-    if ( !pchString || !pchString[0] )
-        return SDL_CONTROLLER_BUTTON_INVALID;
-
-    for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
-    {
-        if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
-        return entry;
-    }
-    return SDL_CONTROLLER_BUTTON_INVALID;
-}
-
-/*
- * convert an enum to its string equivalent
- */
-const char* SDL_GameControllerGetStringForButton( SDL_GameControllerButton axis )
-{
-    if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX)
-    {
-        return map_StringForControllerButton[axis];
-    }
-    return NULL;
-}
-
-/*
- * given a controller button name and a joystick name update our mapping structure with it
- */
-void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
-{
-    int iSDLButton = 0;
-    SDL_GameControllerButton button;
-    SDL_GameControllerAxis axis;
-    button = SDL_GameControllerGetButtonFromString( szGameButton );
-    axis = SDL_GameControllerGetAxisFromString( szGameButton );
-    iSDLButton = SDL_atoi( &szJoystickButton[1] );
-
-    if ( szJoystickButton[0] == 'a' )
-    {
-        if ( iSDLButton >= k_nMaxReverseEntries )
-        {
-            SDL_SetError("Axis index too large: %d", iSDLButton );
-            return;
-        }
-        if ( axis != SDL_CONTROLLER_AXIS_INVALID )
-        {
-            pMapping->axes[ axis ] = iSDLButton;
-            pMapping->raxes[ iSDLButton ] = axis;
-        }
-        else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
-        {
-            pMapping->axesasbutton[ button ] = iSDLButton;
-            pMapping->raxesasbutton[ iSDLButton ] = button;
-        }
-        else
-        {
-            SDL_assert( !"How did we get here?" );
-        }
-
-    }
-    else if ( szJoystickButton[0] == 'b' )
-    {
-        if ( iSDLButton >= k_nMaxReverseEntries )
-        {
-            SDL_SetError("Button index too large: %d", iSDLButton );
-            return;
-        }
-        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
-        {
-            pMapping->buttons[ button ] = iSDLButton;
-            pMapping->rbuttons[ iSDLButton ] = button;
-        }
-        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
-        {
-            pMapping->buttonasaxis[ axis ] = iSDLButton;
-            pMapping->rbuttonasaxis[ iSDLButton ] = axis;
-        }
-        else
-        {
-            SDL_assert( !"How did we get here?" );
-        }
-    }
-    else if ( szJoystickButton[0] == 'h' )
-    {
-        int hat = SDL_atoi( &szJoystickButton[1] );
-        int mask = SDL_atoi( &szJoystickButton[3] );
-        if (hat >= 4) {
-            SDL_SetError("Hat index too large: %d", iSDLButton );
-        }
-
-        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
-        {
-            int ridx;
-            pMapping->hatasbutton[ button ].hat = hat;
-            pMapping->hatasbutton[ button ].mask = mask;
-            ridx = (hat << 4) | mask;
-            pMapping->rhatasbutton[ ridx ] = button;
-        }
-        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
-        {
-            SDL_assert( !"Support hat as axis" );
-        }
-        else
-        {
-            SDL_assert( !"How did we get here?" );
-        }
-    }
-}
-
-
-/*
- * given a controller mapping string update our mapping object
- */
-static void
-SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
-{
-    char szGameButton[20];
-    char szJoystickButton[20];
-    SDL_bool bGameButton = SDL_TRUE;
-    int i = 0;
-    const char *pchPos = pchString;
-
-    SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
-    SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
-
-    while ( pchPos && *pchPos )
-    {
-        if ( *pchPos == ':' )
-        {
-            i = 0;
-            bGameButton = SDL_FALSE;
-        }
-        else if ( *pchPos == ' ' )
-        {
-
-        }
-        else if ( *pchPos == ',' )
-        {
-            i = 0;
-            bGameButton = SDL_TRUE;
-            SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
-            SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
-            SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
-
-        }
-        else if ( bGameButton )
-        {
-            if ( i >=  sizeof(szGameButton))
-            {
-                SDL_SetError( "Button name too large: %s", szGameButton );
-                return;
-            }
-            szGameButton[i] = *pchPos;
-            i++;
-        }
-        else
-        {
-            if ( i >=  sizeof(szJoystickButton))
-            {
-                SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
-                return;
-            }
-            szJoystickButton[i] = *pchPos;
-            i++;
-        }
-        pchPos++;
-    }
-
-    SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
-
-}
-
-/*
- * Make a new button mapping struct
- */
-void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
-{
-    int j;
-
-    pMapping->guid = guid;
-    pMapping->name = pchName;
-
-    /* set all the button mappings to non defaults */
-    for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
-    {
-        pMapping->axes[j] = -1;
-        pMapping->buttonasaxis[j] = -1;
-    }
-    for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
-    {
-        pMapping->buttons[j] = -1;
-        pMapping->axesasbutton[j] = -1;
-        pMapping->hatasbutton[j].hat = -1;
-    }
-
-    for ( j = 0; j < k_nMaxReverseEntries; j++ )
-    {
-        pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
-        pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
-        pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
-        pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
-    }
-
-    for (j = 0; j < k_nMaxHatEntries; j++)
-    {
-        pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
-    }
-
-    SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
-}
-
-
-/*
- * grab the guid string from a mapping string
- */
-char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
-{
-    const char *pFirstComma = SDL_strchr( pMapping, ',' );
-    if ( pFirstComma )
-    {
-        char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
-        if ( !pchGUID )
-        {
-            SDL_OutOfMemory();
-            return NULL;
-        }
-        SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
-        pchGUID[ pFirstComma - pMapping ] = 0;
-        return pchGUID;
-    }
-    return NULL;
-}
-
-
-/*
- * grab the name string from a mapping string
- */
-char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
-{
-    const char *pFirstComma, *pSecondComma;
-    char *pchName;
-
-    pFirstComma = SDL_strchr( pMapping, ',' );
-    if ( !pFirstComma )
-        return NULL;
-
-    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
-    if ( !pSecondComma )
-        return NULL;
-
-    pchName = SDL_malloc( pSecondComma - pFirstComma );
-    if ( !pchName )
-    {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-    SDL_memcpy( pchName, pFirstComma + 1, pSecondComma - pFirstComma );
-    pchName[ pSecondComma - pFirstComma - 1 ] = 0;
-    return pchName;
-}
-
-
-/*
- * grab the button mapping string from a mapping string
- */
-char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
-{
-    const char *pFirstComma, *pSecondComma;
-
-    pFirstComma = SDL_strchr( pMapping, ',' );
-    if ( !pFirstComma )
-        return NULL;
-
-    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
-    if ( !pSecondComma )
-        return NULL;
-
-    return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
-}
-
-void SDL_PrivateGameControllerRefreshMapping( ControllerMapping_t *pControllerMapping )
-{
-    SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
-    while ( gamecontrollerlist )
-    {
-        if ( !SDL_memcmp( &gamecontrollerlist->mapping.guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid) ) )
-        {
-            SDL_Event event;
-            event.type = SDL_CONTROLLERDEVICEREMAPPED;
-            event.cdevice.which = gamecontrollerlist->joystick->instance_id;
-            SDL_PushEvent(&event);
-
-            /* Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher? */
-            SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
-        }
-
-        gamecontrollerlist = gamecontrollerlist->next;
-    }
-}
-
-/*
- * Add or update an entry into the Mappings Database
- */
-int
-SDL_GameControllerAddMapping( const char *mappingString )
-{
-    char *pchGUID;
-    char *pchName;
-    char *pchMapping;
-    SDL_JoystickGUID jGUID;
-    ControllerMapping_t *pControllerMapping;
-#ifdef SDL_JOYSTICK_DINPUT
-    SDL_bool is_xinput_mapping = SDL_FALSE;
-#endif
-
-    pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( mappingString );
-    if (!pchGUID) {
-        return -1;
-    }
-#ifdef SDL_JOYSTICK_DINPUT
-    if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
-        is_xinput_mapping = SDL_TRUE;
-    }
-#endif
-    jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
-    SDL_free(pchGUID);
-
-    pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
-
-    pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
-    if (!pchName) return -1;
-
-    pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
-    if (!pchMapping) {
-        SDL_free( pchName );
-        return -1;
-    }
-
-    if (pControllerMapping) {
-        /* Update existing mapping */
-        SDL_free( pControllerMapping->name );
-        pControllerMapping->name = pchName;
-        SDL_free( pControllerMapping->mapping );
-        pControllerMapping->mapping = pchMapping;
-        /* refresh open controllers */
-        SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
-        return 0;
-    } else {
-        pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
-        if (!pControllerMapping) {
-            SDL_free( pchName );
-            SDL_free( pchMapping );
-            return SDL_OutOfMemory();
-        }
-#ifdef SDL_JOYSTICK_DINPUT
-        if ( is_xinput_mapping )
-        {
-            s_pXInputMapping = pControllerMapping;
-        }
-#endif
-        pControllerMapping->guid = jGUID;
-        pControllerMapping->name = pchName;
-        pControllerMapping->mapping = pchMapping;
-        pControllerMapping->next = s_pSupportedControllers;
-        s_pSupportedControllers = pControllerMapping;
-        return 1;
-    }
-}
-
-/*
- * Get the mapping string for this GUID
- */
-char *
-SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
-{
-    char *pMappingString = NULL;
-    ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
-    if (mapping) {
-        char pchGUID[33];
-        size_t needed;
-        SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
-        /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
-        needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
-        pMappingString = SDL_malloc( needed );
-        SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
-    }
-    return pMappingString;
-}
-
-/*
- * Get the mapping string for this device
- */
-char *
-SDL_GameControllerMapping( SDL_GameController * gamecontroller )
-{
-    return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
-}
-
-static void
-SDL_GameControllerLoadHints()
-{
-    const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
-    if ( hint && hint[0] ) {
-        int nchHints = SDL_strlen( hint );
-        char *pUserMappings = SDL_malloc( nchHints + 1 );
-        char *pTempMappings = pUserMappings;
-        SDL_memcpy( pUserMappings, hint, nchHints );
-        while ( pUserMappings ) {
-            char *pchNewLine = NULL;
-
-            pchNewLine = SDL_strchr( pUserMappings, '\n' );
-            if ( pchNewLine )
-                *pchNewLine = '\0';
-
-            SDL_GameControllerAddMapping( pUserMappings );
-
-            if ( pchNewLine )
-                pUserMappings = pchNewLine + 1;
-            else
-                pUserMappings = NULL;
-        }
-        SDL_free(pTempMappings);
-    }
-}
-
-/*
- * Initialize the game controller system, mostly load our DB of controller config mappings
- */
-int
-SDL_GameControllerInit(void)
-{
-    int i = 0;
-    const char *pMappingString = NULL;
-    s_pSupportedControllers = NULL;
-    pMappingString = s_ControllerMappings[i];
-    while ( pMappingString )
-    {
-        SDL_GameControllerAddMapping( pMappingString );
-
-        i++;
-        pMappingString = s_ControllerMappings[i];
-    }
-
-    /* load in any user supplied config */
-    SDL_GameControllerLoadHints();
-
-    /* watch for joy events and fire controller ones if needed */
-    SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );
-
-    return (0);
-}
-
-
-/*
- * Get the implementation dependent name of a controller
- */
-const char *
-SDL_GameControllerNameForIndex(int device_index)
-{
-    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
-    if ( pSupportedController )
-    {
-        return pSupportedController->name;
-    }
-    return NULL;
-}
-
-
-/*
- * Return 1 if the joystick at this device index is a supported controller
- */
-SDL_bool
-SDL_IsGameController(int device_index)
-{
-    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
-    if ( pSupportedController )
-    {
-        return SDL_TRUE;
-    }
-
-    return SDL_FALSE;
-}
-
-/*
- * Open a controller for use - the index passed as an argument refers to
- * the N'th controller on the system.  This index is the value which will
- * identify this controller in future controller events.
- *
- * This function returns a controller identifier, or NULL if an error occurred.
- */
-SDL_GameController *
-SDL_GameControllerOpen(int device_index)
-{
-    SDL_GameController *gamecontroller;
-    SDL_GameController *gamecontrollerlist;
-    ControllerMapping_t *pSupportedController = NULL;
-
-    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
-        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
-        return (NULL);
-    }
-
-    gamecontrollerlist = SDL_gamecontrollers;
-    /* If the controller is already open, return it */
-    while ( gamecontrollerlist )
-    {
-        if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
-                gamecontroller = gamecontrollerlist;
-                ++gamecontroller->ref_count;
-                return (gamecontroller);
-        }
-        gamecontrollerlist = gamecontrollerlist->next;
-    }
-
-    /* Find a controller mapping */
-    pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
-    if ( !pSupportedController ) {
-        SDL_SetError("Couldn't find mapping for device (%d)", device_index );
-        return (NULL);
-    }
-
-    /* Create and initialize the joystick */
-    gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
-    if (gamecontroller == NULL) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
-    gamecontroller->joystick = SDL_JoystickOpen(device_index);
-    if ( !gamecontroller->joystick ) {
-        SDL_free(gamecontroller);
-        return NULL;
-    }
-
-    SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );
-
-    /* Add joystick to list */
-    ++gamecontroller->ref_count;
-    /* Link the joystick in the list */
-    gamecontroller->next = SDL_gamecontrollers;
-    SDL_gamecontrollers = gamecontroller;
-
-    SDL_SYS_JoystickUpdate( gamecontroller->joystick );
-
-    return (gamecontroller);
-}
-
-/*
- * Manually pump for controller updates.
- */
-void
-SDL_GameControllerUpdate(void)
-{
-    /* Just for API completeness; the joystick API does all the work. */
-    SDL_JoystickUpdate();
-}
-
-
-/*
- * Get the current state of an axis control on a controller
- */
-Sint16
-SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
-{
-    if ( !gamecontroller )
-        return 0;
-
-    if (gamecontroller->mapping.axes[axis] >= 0 )
-    {
-        Sint16 value = ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
-        switch (axis)
-        {
-            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
-            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
-                /* Shift it to be 0 - 32767. */
-                value = value / 2 + 16384;
-            default:
-                break;
-        }
-        return value;
-    }
-    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
-    {
-        Uint8 value;
-        value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
-        if ( value > 0 )
-            return 32767;
-        return 0;
-    }
-    return 0;
-}
-
-
-/*
- * Get the current state of a button on a controller
- */
-Uint8
-SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
-{
-    if ( !gamecontroller )
-        return 0;
-
-    if ( gamecontroller->mapping.buttons[button] >= 0 )
-    {
-        return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
-    }
-    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
-    {
-        Sint16 value;
-        value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
-        if ( ABS(value) > 32768/2 )
-            return 1;
-        return 0;
-    }
-    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
-    {
-        Uint8 value;
-        value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );
-
-        if ( value & gamecontroller->mapping.hatasbutton[button].mask )
-            return 1;
-        return 0;
-    }
-
-    return 0;
-}
-
-/*
- * Return if the joystick in question is currently attached to the system,
- *  \return 0 if not plugged in, 1 if still present.
- */
-SDL_bool
-SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
-{
-    if ( !gamecontroller )
-        return SDL_FALSE;
-
-    return SDL_JoystickGetAttached(gamecontroller->joystick);
-}
-
-
-/*
- * Get the number of multi-dimensional axis controls on a joystick
- */
-const char *
-SDL_GameControllerName(SDL_GameController * gamecontroller)
-{
-    if ( !gamecontroller )
-        return NULL;
-
-    return (gamecontroller->mapping.name);
-}
-
-
-/*
- * Get the joystick for this controller
- */
-SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
-{
-    if ( !gamecontroller )
-        return NULL;
-
-    return gamecontroller->joystick;
-}
-
-/**
- * Get the SDL joystick layer binding for this controller axis mapping
- */
-SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
-{
-    SDL_GameControllerButtonBind bind;
-    SDL_memset( &bind, 0x0, sizeof(bind) );
-
-    if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
-        return bind;
-
-    if (gamecontroller->mapping.axes[axis] >= 0 )
-    {
-        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
-        bind.value.button = gamecontroller->mapping.axes[axis];
-    }
-    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
-    {
-        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
-        bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
-    }
-
-    return bind;
-}
-
-
-/**
- * Get the SDL joystick layer binding for this controller button mapping
- */
-SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
-{
-    SDL_GameControllerButtonBind bind;
-    SDL_memset( &bind, 0x0, sizeof(bind) );
-
-    if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID )
-        return bind;
-
-    if ( gamecontroller->mapping.buttons[button] >= 0 )
-    {
-        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
-        bind.value.button = gamecontroller->mapping.buttons[button];
-    }
-    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
-    {
-        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
-        bind.value.axis = gamecontroller->mapping.axesasbutton[button];
-    }
-    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
-    {
-        bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
-        bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
-        bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
-    }
-
-    return bind;
-}
-
-
-/*
- * Close a joystick previously opened with SDL_JoystickOpen()
- */
-void
-SDL_GameControllerClose(SDL_GameController * gamecontroller)
-{
-    SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
-
-    if ( !gamecontroller )
-        return;
-
-    /* First decrement ref count */
-    if (--gamecontroller->ref_count > 0) {
-        return;
-    }
-
-    SDL_JoystickClose( gamecontroller->joystick );
-
-    gamecontrollerlist = SDL_gamecontrollers;
-    gamecontrollerlistprev = NULL;
-    while ( gamecontrollerlist )
-    {
-        if (gamecontroller == gamecontrollerlist)
-        {
-            if ( gamecontrollerlistprev )
-            {
-                /* unlink this entry */
-                gamecontrollerlistprev->next = gamecontrollerlist->next;
-            }
-            else
-            {
-                SDL_gamecontrollers = gamecontroller->next;
-            }
-
-            break;
-        }
-        gamecontrollerlistprev = gamecontrollerlist;
-        gamecontrollerlist = gamecontrollerlist->next;
-    }
-
-    SDL_free(gamecontroller);
-}
-
-
-/*
- * Quit the controller subsystem
- */
-void
-SDL_GameControllerQuit(void)
-{
-    ControllerMapping_t *pControllerMap;
-    while ( SDL_gamecontrollers )
-    {
-        SDL_gamecontrollers->ref_count = 1;
-        SDL_GameControllerClose(SDL_gamecontrollers);
-    }
-
-    while ( s_pSupportedControllers )
-    {
-        pControllerMap = s_pSupportedControllers;
-        s_pSupportedControllers = s_pSupportedControllers->next;
-        SDL_free( pControllerMap->name );
-        SDL_free( pControllerMap );
-    }
-
-    SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL );
-
-}
-
-/*
- * Event filter to transform joystick events into appropriate game controller ones
- */
-int
-SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
-{
-    int posted;
-
-    /* translate the event, if desired */
-    posted = 0;
-#if !SDL_EVENTS_DISABLED
-    if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
-        SDL_Event event;
-        event.type = SDL_CONTROLLERAXISMOTION;
-        event.caxis.which = gamecontroller->joystick->instance_id;
-        event.caxis.axis = axis;
-        event.caxis.value = value;
-        posted = SDL_PushEvent(&event) == 1;
-    }
-#endif /* !SDL_EVENTS_DISABLED */
-    return (posted);
-}
-
-
-/*
- * Event filter to transform joystick events into appropriate game controller ones
- */
-int
-SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
-{
-    int posted;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-
-    if ( button == SDL_CONTROLLER_BUTTON_INVALID )
-        return (0);
-
-    switch (state) {
-    case SDL_PRESSED:
-        event.type = SDL_CONTROLLERBUTTONDOWN;
-        break;
-    case SDL_RELEASED:
-        event.type = SDL_CONTROLLERBUTTONUP;
-        break;
-    default:
-        /* Invalid state -- bail */
-        return (0);
-    }
-#endif /* !SDL_EVENTS_DISABLED */
-
-    /* translate the event, if desired */
-    posted = 0;
-#if !SDL_EVENTS_DISABLED
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.cbutton.which = gamecontroller->joystick->instance_id;
-        event.cbutton.button = button;
-        event.cbutton.state = state;
-        posted = SDL_PushEvent(&event) == 1;
-    }
-#endif /* !SDL_EVENTS_DISABLED */
-    return (posted);
-}
-
-/*
- * Turn off controller events
- */
-int
-SDL_GameControllerEventState(int state)
-{
-#if SDL_EVENTS_DISABLED
-    return SDL_IGNORE;
-#else
-    const Uint32 event_list[] = {
-        SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
-        SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
-    };
-    unsigned int i;
-
-    switch (state) {
-    case SDL_QUERY:
-        state = SDL_IGNORE;
-        for (i = 0; i < SDL_arraysize(event_list); ++i) {
-            state = SDL_EventState(event_list[i], SDL_QUERY);
-            if (state == SDL_ENABLE) {
-                break;
-            }
-        }
-        break;
-    default:
-        for (i = 0; i < SDL_arraysize(event_list); ++i) {
-            SDL_EventState(event_list[i], state);
-        }
-        break;
-    }
-    return (state);
-#endif /* SDL_EVENTS_DISABLED */
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+/* This is the game controller API for Simple DirectMedia Layer */
+
+#include "SDL_events.h"
+#include "SDL_assert.h"
+#include "SDL_sysjoystick.h"
+#include "SDL_hints.h"
+#include "SDL_gamecontrollerdb.h"
+
+#if !SDL_EVENTS_DISABLED
+#include "../events/SDL_events_c.h"
+#endif
+#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
+
+
+/* a list of currently opened game controllers */
+static SDL_GameController *SDL_gamecontrollers = NULL;
+
+/* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
+struct _SDL_HatMapping
+{
+    int hat;
+    Uint8 mask;
+};
+
+#define k_nMaxReverseEntries 20
+
+/**
+ * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
+ * MAX 4 hats supported
+ */
+#define k_nMaxHatEntries 0x3f + 1
+
+/* our in memory mapping db between joystick objects and controller mappings*/
+struct _SDL_ControllerMapping
+{
+    SDL_JoystickGUID guid;
+    const char *name;
+
+    /* mapping of axis/button id to controller version */
+    int axes[SDL_CONTROLLER_AXIS_MAX];
+    int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
+
+    int buttons[SDL_CONTROLLER_BUTTON_MAX];
+    int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
+    struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
+
+    /* reverse mapping, joystick indices to buttons */
+    SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
+    SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
+
+    SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
+    SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
+    SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
+
+};
+
+
+/* our hard coded list of mapping support */
+typedef struct _ControllerMapping_t
+{
+    SDL_JoystickGUID guid;
+    char *name;
+    char *mapping;
+    struct _ControllerMapping_t *next;
+} ControllerMapping_t;
+
+static ControllerMapping_t *s_pSupportedControllers = NULL;
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
+static ControllerMapping_t *s_pXInputMapping = NULL;
+#endif
+
+/* The SDL game controller structure */
+struct _SDL_GameController
+{
+    SDL_Joystick *joystick; /* underlying joystick device */
+    int ref_count;
+    Uint8 hatState[4]; /* the current hat state for this controller */
+    struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
+    struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
+};
+
+
+int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
+int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
+
+/*
+ * Event filter to fire controller events from joystick ones
+ */
+int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
+{
+    switch( event->type )
+    {
+    case SDL_JOYAXISMOTION:
+        {
+            SDL_GameController *controllerlist;
+
+            if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;
+
+            controllerlist = SDL_gamecontrollers;
+            while ( controllerlist )
+            {
+                if ( controllerlist->joystick->instance_id == event->jaxis.which )
+                {
+                    if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */
+                    {
+                        SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
+                        Sint16 value = event->jaxis.value;
+                        switch (axis)
+                        {
+                            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
+                            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
+                                /* Shift it to be 0 - 32767. */
+                                value = value / 2 + 16384;
+                            default:
+                                break;
+                        }
+                        SDL_PrivateGameControllerAxis( controllerlist, axis, value );
+                    }
+                    else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */
+                    {
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
+                    }
+                    break;
+                }
+                controllerlist = controllerlist->next;
+            }
+        }
+        break;
+    case SDL_JOYBUTTONDOWN:
+    case SDL_JOYBUTTONUP:
+        {
+            SDL_GameController *controllerlist;
+
+            if ( event->jbutton.button >= k_nMaxReverseEntries ) break;
+
+            controllerlist = SDL_gamecontrollers;
+            while ( controllerlist )
+            {
+                if ( controllerlist->joystick->instance_id == event->jbutton.which )
+                {
+                    if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */
+                    {
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
+                    }
+                    else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */
+                    {
+                        SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
+                    }
+                    break;
+                }
+                controllerlist = controllerlist->next;
+            }
+        }
+        break;
+    case SDL_JOYHATMOTION:
+        {
+            SDL_GameController *controllerlist;
+
+            if ( event->jhat.hat >= 4 ) break;
+
+            controllerlist = SDL_gamecontrollers;
+            while ( controllerlist )
+            {
+                if ( controllerlist->joystick->instance_id == event->jhat.which )
+                {
+                    Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
+                    /* Get list of removed bits (button release) */
+                    Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
+                    /* the hat idx in the high nibble */
+                    int bHighHat = event->jhat.hat << 4;
+
+                    if ( bChanged & SDL_HAT_DOWN )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
+                    if ( bChanged & SDL_HAT_UP )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
+                    if ( bChanged & SDL_HAT_LEFT )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
+                    if ( bChanged & SDL_HAT_RIGHT )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );
+
+                    /* Get list of added bits (button press) */
+                    bChanged = event->jhat.value ^ bSame;
+
+                    if ( bChanged & SDL_HAT_DOWN )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
+                    if ( bChanged & SDL_HAT_UP )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
+                    if ( bChanged & SDL_HAT_LEFT )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
+                    if ( bChanged & SDL_HAT_RIGHT )
+                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );
+
+                    /* update our state cache */
+                    controllerlist->hatState[event->jhat.hat] = event->jhat.value;
+
+                    break;
+                }
+                controllerlist = controllerlist->next;
+            }
+        }
+        break;
+    case SDL_JOYDEVICEADDED:
+        {
+            if ( SDL_IsGameController(event->jdevice.which ) )
+            {
+                SDL_Event deviceevent;
+                deviceevent.type = SDL_CONTROLLERDEVICEADDED;
+                deviceevent.cdevice.which = event->jdevice.which;
+                SDL_PushEvent(&deviceevent);
+            }
+        }
+        break;
+    case SDL_JOYDEVICEREMOVED:
+        {
+            SDL_GameController *controllerlist = SDL_gamecontrollers;
+            while ( controllerlist )
+            {
+                if ( controllerlist->joystick->instance_id == event->jdevice.which )
+                {
+                    SDL_Event deviceevent;
+                    deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
+                    deviceevent.cdevice.which = event->jdevice.which;
+                    SDL_PushEvent(&deviceevent);
+                    break;
+                }
+                controllerlist = controllerlist->next;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    return 1;
+}
+
+/*
+ * Helper function to scan the mappings database for a controller with the specified GUID
+ */
+ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
+{
+    ControllerMapping_t *pSupportedController = s_pSupportedControllers;
+    while ( pSupportedController )
+    {
+        if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
+        {
+            return pSupportedController;
+        }
+        pSupportedController = pSupportedController->next;
+    }
+    return NULL;
+}
+
+/*
+ * Helper function to determine pre-calculated offset to certain joystick mappings
+ */
+ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
+{
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
+    if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
+    {
+        return s_pXInputMapping;
+    }
+    else
+#endif
+    {
+        SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
+        return SDL_PrivateGetControllerMappingForGUID(&jGUID);
+    }
+
+    return NULL;
+}
+
+static const char* map_StringForControllerAxis[] = {
+    "leftx",
+    "lefty",
+    "rightx",
+    "righty",
+    "lefttrigger",
+    "righttrigger",
+    NULL
+};
+
+/*
+ * convert a string to its enum equivalent
+ */
+SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
+{
+    int entry;
+    if ( !pchString || !pchString[0] )
+        return SDL_CONTROLLER_AXIS_INVALID;
+
+    for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
+    {
+        if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
+            return entry;
+    }
+    return SDL_CONTROLLER_AXIS_INVALID;
+}
+
+/*
+ * convert an enum to its string equivalent
+ */
+const char* SDL_GameControllerGetStringForAxis( SDL_GameControllerAxis axis )
+{
+    if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX)
+    {
+        return map_StringForControllerAxis[axis];
+    }
+    return NULL;
+}
+
+static const char* map_StringForControllerButton[] = {
+    "a",
+    "b",
+    "x",
+    "y",
+    "back",
+    "guide",
+    "start",
+    "leftstick",
+    "rightstick",
+    "leftshoulder",
+    "rightshoulder",
+    "dpup",
+    "dpdown",
+    "dpleft",
+    "dpright",
+    NULL
+};
+
+/*
+ * convert a string to its enum equivalent
+ */
+SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
+{
+    int entry;
+    if ( !pchString || !pchString[0] )
+        return SDL_CONTROLLER_BUTTON_INVALID;
+
+    for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
+    {
+        if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
+        return entry;
+    }
+    return SDL_CONTROLLER_BUTTON_INVALID;
+}
+
+/*
+ * convert an enum to its string equivalent
+ */
+const char* SDL_GameControllerGetStringForButton( SDL_GameControllerButton axis )
+{
+    if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX)
+    {
+        return map_StringForControllerButton[axis];
+    }
+    return NULL;
+}
+
+/*
+ * given a controller button name and a joystick name update our mapping structure with it
+ */
+void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
+{
+    int iSDLButton = 0;
+    SDL_GameControllerButton button;
+    SDL_GameControllerAxis axis;
+    button = SDL_GameControllerGetButtonFromString( szGameButton );
+    axis = SDL_GameControllerGetAxisFromString( szGameButton );
+    iSDLButton = SDL_atoi( &szJoystickButton[1] );
+
+    if ( szJoystickButton[0] == 'a' )
+    {
+        if ( iSDLButton >= k_nMaxReverseEntries )
+        {
+            SDL_SetError("Axis index too large: %d", iSDLButton );
+            return;
+        }
+        if ( axis != SDL_CONTROLLER_AXIS_INVALID )
+        {
+            pMapping->axes[ axis ] = iSDLButton;
+            pMapping->raxes[ iSDLButton ] = axis;
+        }
+        else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
+        {
+            pMapping->axesasbutton[ button ] = iSDLButton;
+            pMapping->raxesasbutton[ iSDLButton ] = button;
+        }
+        else
+        {
+            SDL_assert( !"How did we get here?" );
+        }
+
+    }
+    else if ( szJoystickButton[0] == 'b' )
+    {
+        if ( iSDLButton >= k_nMaxReverseEntries )
+        {
+            SDL_SetError("Button index too large: %d", iSDLButton );
+            return;
+        }
+        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
+        {
+            pMapping->buttons[ button ] = iSDLButton;
+            pMapping->rbuttons[ iSDLButton ] = button;
+        }
+        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
+        {
+            pMapping->buttonasaxis[ axis ] = iSDLButton;
+            pMapping->rbuttonasaxis[ iSDLButton ] = axis;
+        }
+        else
+        {
+            SDL_assert( !"How did we get here?" );
+        }
+    }
+    else if ( szJoystickButton[0] == 'h' )
+    {
+        int hat = SDL_atoi( &szJoystickButton[1] );
+        int mask = SDL_atoi( &szJoystickButton[3] );
+        if (hat >= 4) {
+            SDL_SetError("Hat index too large: %d", iSDLButton );
+        }
+
+        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
+        {
+            int ridx;
+            pMapping->hatasbutton[ button ].hat = hat;
+            pMapping->hatasbutton[ button ].mask = mask;
+            ridx = (hat << 4) | mask;
+            pMapping->rhatasbutton[ ridx ] = button;
+        }
+        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
+        {
+            SDL_assert( !"Support hat as axis" );
+        }
+        else
+        {
+            SDL_assert( !"How did we get here?" );
+        }
+    }
+}
+
+
+/*
+ * given a controller mapping string update our mapping object
+ */
+static void
+SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
+{
+    char szGameButton[20];
+    char szJoystickButton[20];
+    SDL_bool bGameButton = SDL_TRUE;
+    int i = 0;
+    const char *pchPos = pchString;
+
+    SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
+    SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
+
+    while ( pchPos && *pchPos )
+    {
+        if ( *pchPos == ':' )
+        {
+            i = 0;
+            bGameButton = SDL_FALSE;
+        }
+        else if ( *pchPos == ' ' )
+        {
+
+        }
+        else if ( *pchPos == ',' )
+        {
+            i = 0;
+            bGameButton = SDL_TRUE;
+            SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
+            SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
+            SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );
+
+        }
+        else if ( bGameButton )
+        {
+            if ( i >=  sizeof(szGameButton))
+            {
+                SDL_SetError( "Button name too large: %s", szGameButton );
+                return;
+            }
+            szGameButton[i] = *pchPos;
+            i++;
+        }
+        else
+        {
+            if ( i >=  sizeof(szJoystickButton))
+            {
+                SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
+                return;
+            }
+            szJoystickButton[i] = *pchPos;
+            i++;
+        }
+        pchPos++;
+    }
+
+    SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
+
+}
+
+/*
+ * Make a new button mapping struct
+ */
+void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
+{
+    int j;
+
+    pMapping->guid = guid;
+    pMapping->name = pchName;
+
+    /* set all the button mappings to non defaults */
+    for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
+    {
+        pMapping->axes[j] = -1;
+        pMapping->buttonasaxis[j] = -1;
+    }
+    for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
+    {
+        pMapping->buttons[j] = -1;
+        pMapping->axesasbutton[j] = -1;
+        pMapping->hatasbutton[j].hat = -1;
+    }
+
+    for ( j = 0; j < k_nMaxReverseEntries; j++ )
+    {
+        pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
+        pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
+        pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
+        pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
+    }
+
+    for (j = 0; j < k_nMaxHatEntries; j++)
+    {
+        pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
+    }
+
+    SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
+}
+
+
+/*
+ * grab the guid string from a mapping string
+ */
+char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
+{
+    const char *pFirstComma = SDL_strchr( pMapping, ',' );
+    if ( pFirstComma )
+    {
+        char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
+        if ( !pchGUID )
+        {
+            SDL_OutOfMemory();
+            return NULL;
+        }
+        SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
+        pchGUID[ pFirstComma - pMapping ] = 0;
+        return pchGUID;
+    }
+    return NULL;
+}
+
+
+/*
+ * grab the name string from a mapping string
+ */
+char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
+{
+    const char *pFirstComma, *pSecondComma;
+    char *pchName;
+
+    pFirstComma = SDL_strchr( pMapping, ',' );
+    if ( !pFirstComma )
+        return NULL;
+
+    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
+    if ( !pSecondComma )
+        return NULL;
+
+    pchName = SDL_malloc( pSecondComma - pFirstComma );
+    if ( !pchName )
+    {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_memcpy( pchName, pFirstComma + 1, pSecondComma - pFirstComma );
+    pchName[ pSecondComma - pFirstComma - 1 ] = 0;
+    return pchName;
+}
+
+
+/*
+ * grab the button mapping string from a mapping string
+ */
+char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
+{
+    const char *pFirstComma, *pSecondComma;
+
+    pFirstComma = SDL_strchr( pMapping, ',' );
+    if ( !pFirstComma )
+        return NULL;
+
+    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
+    if ( !pSecondComma )
+        return NULL;
+
+    return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
+}
+
+void SDL_PrivateGameControllerRefreshMapping( ControllerMapping_t *pControllerMapping )
+{
+    SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
+    while ( gamecontrollerlist )
+    {
+        if ( !SDL_memcmp( &gamecontrollerlist->mapping.guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid) ) )
+        {
+            SDL_Event event;
+            event.type = SDL_CONTROLLERDEVICEREMAPPED;
+            event.cdevice.which = gamecontrollerlist->joystick->instance_id;
+            SDL_PushEvent(&event);
+
+            /* Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher? */
+            SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
+        }
+
+        gamecontrollerlist = gamecontrollerlist->next;
+    }
+}
+
+/*
+ * Add or update an entry into the Mappings Database
+ */
+int
+SDL_GameControllerAddMapping( const char *mappingString )
+{
+    char *pchGUID;
+    char *pchName;
+    char *pchMapping;
+    SDL_JoystickGUID jGUID;
+    ControllerMapping_t *pControllerMapping;
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
+    SDL_bool is_xinput_mapping = SDL_FALSE;
+#endif
+
+    pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( mappingString );
+    if (!pchGUID) {
+        return -1;
+    }
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
+    if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
+        is_xinput_mapping = SDL_TRUE;
+    }
+#endif
+    jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
+    SDL_free(pchGUID);
+
+    pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
+
+    pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
+    if (!pchName) return -1;
+
+    pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
+    if (!pchMapping) {
+        SDL_free( pchName );
+        return -1;
+    }
+
+    if (pControllerMapping) {
+        /* Update existing mapping */
+        SDL_free( pControllerMapping->name );
+        pControllerMapping->name = pchName;
+        SDL_free( pControllerMapping->mapping );
+        pControllerMapping->mapping = pchMapping;
+        /* refresh open controllers */
+        SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
+        return 0;
+    } else {
+        pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
+        if (!pControllerMapping) {
+            SDL_free( pchName );
+            SDL_free( pchMapping );
+            return SDL_OutOfMemory();
+        }
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
+        if ( is_xinput_mapping )
+        {
+            s_pXInputMapping = pControllerMapping;
+        }
+#endif
+        pControllerMapping->guid = jGUID;
+        pControllerMapping->name = pchName;
+        pControllerMapping->mapping = pchMapping;
+        pControllerMapping->next = s_pSupportedControllers;
+        s_pSupportedControllers = pControllerMapping;
+        return 1;
+    }
+}
+
+/*
+ * Get the mapping string for this GUID
+ */
+char *
+SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
+{
+    char *pMappingString = NULL;
+    ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
+    if (mapping) {
+        char pchGUID[33];
+        size_t needed;
+        SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
+        /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
+        needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
+        pMappingString = SDL_malloc( needed );
+        SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
+    }
+    return pMappingString;
+}
+
+/*
+ * Get the mapping string for this device
+ */
+char *
+SDL_GameControllerMapping( SDL_GameController * gamecontroller )
+{
+    return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
+}
+
+static void
+SDL_GameControllerLoadHints()
+{
+    const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
+    if ( hint && hint[0] ) {
+        int nchHints = SDL_strlen( hint );
+        char *pUserMappings = SDL_malloc( nchHints + 1 );
+        char *pTempMappings = pUserMappings;
+        SDL_memcpy( pUserMappings, hint, nchHints );
+        while ( pUserMappings ) {
+            char *pchNewLine = NULL;
+
+            pchNewLine = SDL_strchr( pUserMappings, '\n' );
+            if ( pchNewLine )
+                *pchNewLine = '\0';
+
+            SDL_GameControllerAddMapping( pUserMappings );
+
+            if ( pchNewLine )
+                pUserMappings = pchNewLine + 1;
+            else
+                pUserMappings = NULL;
+        }
+        SDL_free(pTempMappings);
+    }
+}
+
+/*
+ * Initialize the game controller system, mostly load our DB of controller config mappings
+ */
+int
+SDL_GameControllerInit(void)
+{
+    int i = 0;
+    const char *pMappingString = NULL;
+    s_pSupportedControllers = NULL;
+    pMappingString = s_ControllerMappings[i];
+    while ( pMappingString )
+    {
+        SDL_GameControllerAddMapping( pMappingString );
+
+        i++;
+        pMappingString = s_ControllerMappings[i];
+    }
+
+    /* load in any user supplied config */
+    SDL_GameControllerLoadHints();
+
+    /* watch for joy events and fire controller ones if needed */
+    SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );
+
+    return (0);
+}
+
+
+/*
+ * Get the implementation dependent name of a controller
+ */
+const char *
+SDL_GameControllerNameForIndex(int device_index)
+{
+    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
+    if ( pSupportedController )
+    {
+        return pSupportedController->name;
+    }
+    return NULL;
+}
+
+
+/*
+ * Return 1 if the joystick at this device index is a supported controller
+ */
+SDL_bool
+SDL_IsGameController(int device_index)
+{
+    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
+    if ( pSupportedController )
+    {
+        return SDL_TRUE;
+    }
+
+    return SDL_FALSE;
+}
+
+/*
+ * Open a controller for use - the index passed as an argument refers to
+ * the N'th controller on the system.  This index is the value which will
+ * identify this controller in future controller events.
+ *
+ * This function returns a controller identifier, or NULL if an error occurred.
+ */
+SDL_GameController *
+SDL_GameControllerOpen(int device_index)
+{
+    SDL_GameController *gamecontroller;
+    SDL_GameController *gamecontrollerlist;
+    ControllerMapping_t *pSupportedController = NULL;
+
+    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
+        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
+        return (NULL);
+    }
+
+    gamecontrollerlist = SDL_gamecontrollers;
+    /* If the controller is already open, return it */
+    while ( gamecontrollerlist )
+    {
+        if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
+                gamecontroller = gamecontrollerlist;
+                ++gamecontroller->ref_count;
+                return (gamecontroller);
+        }
+        gamecontrollerlist = gamecontrollerlist->next;
+    }
+
+    /* Find a controller mapping */
+    pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
+    if ( !pSupportedController ) {
+        SDL_SetError("Couldn't find mapping for device (%d)", device_index );
+        return (NULL);
+    }
+
+    /* Create and initialize the joystick */
+    gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
+    if (gamecontroller == NULL) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
+    gamecontroller->joystick = SDL_JoystickOpen(device_index);
+    if ( !gamecontroller->joystick ) {
+        SDL_free(gamecontroller);
+        return NULL;
+    }
+
+    SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );
+
+    /* Add joystick to list */
+    ++gamecontroller->ref_count;
+    /* Link the joystick in the list */
+    gamecontroller->next = SDL_gamecontrollers;
+    SDL_gamecontrollers = gamecontroller;
+
+    SDL_SYS_JoystickUpdate( gamecontroller->joystick );
+
+    return (gamecontroller);
+}
+
+/*
+ * Manually pump for controller updates.
+ */
+void
+SDL_GameControllerUpdate(void)
+{
+    /* Just for API completeness; the joystick API does all the work. */
+    SDL_JoystickUpdate();
+}
+
+
+/*
+ * Get the current state of an axis control on a controller
+ */
+Sint16
+SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
+{
+    if ( !gamecontroller )
+        return 0;
+
+    if (gamecontroller->mapping.axes[axis] >= 0 )
+    {
+        Sint16 value = ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
+        switch (axis)
+        {
+            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
+            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
+                /* Shift it to be 0 - 32767. */
+                value = value / 2 + 16384;
+            default:
+                break;
+        }
+        return value;
+    }
+    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
+    {
+        Uint8 value;
+        value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
+        if ( value > 0 )
+            return 32767;
+        return 0;
+    }
+    return 0;
+}
+
+
+/*
+ * Get the current state of a button on a controller
+ */
+Uint8
+SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
+{
+    if ( !gamecontroller )
+        return 0;
+
+    if ( gamecontroller->mapping.buttons[button] >= 0 )
+    {
+        return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
+    }
+    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
+    {
+        Sint16 value;
+        value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
+        if ( ABS(value) > 32768/2 )
+            return 1;
+        return 0;
+    }
+    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
+    {
+        Uint8 value;
+        value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );
+
+        if ( value & gamecontroller->mapping.hatasbutton[button].mask )
+            return 1;
+        return 0;
+    }
+
+    return 0;
+}
+
+/*
+ * Return if the joystick in question is currently attached to the system,
+ *  \return 0 if not plugged in, 1 if still present.
+ */
+SDL_bool
+SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
+{
+    if ( !gamecontroller )
+        return SDL_FALSE;
+
+    return SDL_JoystickGetAttached(gamecontroller->joystick);
+}
+
+
+/*
+ * Get the number of multi-dimensional axis controls on a joystick
+ */
+const char *
+SDL_GameControllerName(SDL_GameController * gamecontroller)
+{
+    if ( !gamecontroller )
+        return NULL;
+
+    return (gamecontroller->mapping.name);
+}
+
+
+/*
+ * Get the joystick for this controller
+ */
+SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
+{
+    if ( !gamecontroller )
+        return NULL;
+
+    return gamecontroller->joystick;
+}
+
+/**
+ * Get the SDL joystick layer binding for this controller axis mapping
+ */
+SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
+{
+    SDL_GameControllerButtonBind bind;
+    SDL_memset( &bind, 0x0, sizeof(bind) );
+
+    if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
+        return bind;
+
+    if (gamecontroller->mapping.axes[axis] >= 0 )
+    {
+        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
+        bind.value.button = gamecontroller->mapping.axes[axis];
+    }
+    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
+    {
+        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
+        bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
+    }
+
+    return bind;
+}
+
+
+/**
+ * Get the SDL joystick layer binding for this controller button mapping
+ */
+SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
+{
+    SDL_GameControllerButtonBind bind;
+    SDL_memset( &bind, 0x0, sizeof(bind) );
+
+    if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID )
+        return bind;
+
+    if ( gamecontroller->mapping.buttons[button] >= 0 )
+    {
+        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
+        bind.value.button = gamecontroller->mapping.buttons[button];
+    }
+    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
+    {
+        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
+        bind.value.axis = gamecontroller->mapping.axesasbutton[button];
+    }
+    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
+    {
+        bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
+        bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
+        bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
+    }
+
+    return bind;
+}
+
+
+/*
+ * Close a joystick previously opened with SDL_JoystickOpen()
+ */
+void
+SDL_GameControllerClose(SDL_GameController * gamecontroller)
+{
+    SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
+
+    if ( !gamecontroller )
+        return;
+
+    /* First decrement ref count */
+    if (--gamecontroller->ref_count > 0) {
+        return;
+    }
+
+    SDL_JoystickClose( gamecontroller->joystick );
+
+    gamecontrollerlist = SDL_gamecontrollers;
+    gamecontrollerlistprev = NULL;
+    while ( gamecontrollerlist )
+    {
+        if (gamecontroller == gamecontrollerlist)
+        {
+            if ( gamecontrollerlistprev )
+            {
+                /* unlink this entry */
+                gamecontrollerlistprev->next = gamecontrollerlist->next;
+            }
+            else
+            {
+                SDL_gamecontrollers = gamecontroller->next;
+            }
+
+            break;
+        }
+        gamecontrollerlistprev = gamecontrollerlist;
+        gamecontrollerlist = gamecontrollerlist->next;
+    }
+
+    SDL_free(gamecontroller);
+}
+
+
+/*
+ * Quit the controller subsystem
+ */
+void
+SDL_GameControllerQuit(void)
+{
+    ControllerMapping_t *pControllerMap;
+    while ( SDL_gamecontrollers )
+    {
+        SDL_gamecontrollers->ref_count = 1;
+        SDL_GameControllerClose(SDL_gamecontrollers);
+    }
+
+    while ( s_pSupportedControllers )
+    {
+        pControllerMap = s_pSupportedControllers;
+        s_pSupportedControllers = s_pSupportedControllers->next;
+        SDL_free( pControllerMap->name );
+        SDL_free( pControllerMap );
+    }
+
+    SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL );
+
+}
+
+/*
+ * Event filter to transform joystick events into appropriate game controller ones
+ */
+int
+SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
+{
+    int posted;
+
+    /* translate the event, if desired */
+    posted = 0;
+#if !SDL_EVENTS_DISABLED
+    if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
+        SDL_Event event;
+        event.type = SDL_CONTROLLERAXISMOTION;
+        event.caxis.which = gamecontroller->joystick->instance_id;
+        event.caxis.axis = axis;
+        event.caxis.value = value;
+        posted = SDL_PushEvent(&event) == 1;
+    }
+#endif /* !SDL_EVENTS_DISABLED */
+    return (posted);
+}
+
+
+/*
+ * Event filter to transform joystick events into appropriate game controller ones
+ */
+int
+SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
+{
+    int posted;
+#if !SDL_EVENTS_DISABLED
+    SDL_Event event;
+
+    if ( button == SDL_CONTROLLER_BUTTON_INVALID )
+        return (0);
+
+    switch (state) {
+    case SDL_PRESSED:
+        event.type = SDL_CONTROLLERBUTTONDOWN;
+        break;
+    case SDL_RELEASED:
+        event.type = SDL_CONTROLLERBUTTONUP;
+        break;
+    default:
+        /* Invalid state -- bail */
+        return (0);
+    }
+#endif /* !SDL_EVENTS_DISABLED */
+
+    /* translate the event, if desired */
+    posted = 0;
+#if !SDL_EVENTS_DISABLED
+    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+        event.cbutton.which = gamecontroller->joystick->instance_id;
+        event.cbutton.button = button;
+        event.cbutton.state = state;
+        posted = SDL_PushEvent(&event) == 1;
+    }
+#endif /* !SDL_EVENTS_DISABLED */
+    return (posted);
+}
+
+/*
+ * Turn off controller events
+ */
+int
+SDL_GameControllerEventState(int state)
+{
+#if SDL_EVENTS_DISABLED
+    return SDL_IGNORE;
+#else
+    const Uint32 event_list[] = {
+        SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
+        SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
+    };
+    unsigned int i;
+
+    switch (state) {
+    case SDL_QUERY:
+        state = SDL_IGNORE;
+        for (i = 0; i < SDL_arraysize(event_list); ++i) {
+            state = SDL_EventState(event_list[i], SDL_QUERY);
+            if (state == SDL_ENABLE) {
+                break;
+            }
+        }
+        break;
+    default:
+        for (i = 0; i < SDL_arraysize(event_list); ++i) {
+            SDL_EventState(event_list[i], state);
+        }
+        break;
+    }
+    return (state);
+#endif /* SDL_EVENTS_DISABLED */
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
src/joystick/SDL_sysjoystick.h

@@ -108,7 +108,7 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index);
 /* Function to return the stable GUID for a opened joystick */
 extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick);
 
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
 /* Function to get the current instance id of the joystick located at device_index */
 extern SDL_bool SDL_SYS_IsXInputDeviceIndex( int device_index );
 #endif

+ 435 - 0
src/joystick/windowsrt/SDL_xinputjoystick.c

@@ -0,0 +1,435 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#if SDL_JOYSTICK_XINPUT
+
+/* SDL_xinputjoystick.c implements an XInput-only joystick and game controller
+   backend that is suitable for use on WinRT.  SDL's DirectInput backend, also
+   XInput-capable, was not used as DirectInput is not available on WinRT (or,
+   at least, it isn't a public API).  Some portions of this XInput backend
+   may copy parts of the XInput-using code from the DirectInput backend.
+   Refactoring the common parts into one location may be good to-do at some
+   point.
+
+   TODO, WinRT: add hotplug support for XInput based game controllers
+*/
+
+#include "SDL_joystick.h"
+#include "../SDL_sysjoystick.h"
+#include "../SDL_joystick_c.h"
+#include "SDL_events.h"
+#include "../../events/SDL_events_c.h"
+
+#include <Windows.h>
+#include <Xinput.h>
+
+struct joystick_hwdata {
+    //Uint8 bXInputHaptic; // Supports force feedback via XInput.
+    DWORD userIndex;    // The XInput device index, in the range [0, XUSER_MAX_COUNT-1] (probably [0,3]).
+    XINPUT_STATE XInputState;   // the last-read in XInputState, kept around to compare old and new values
+    SDL_bool isDeviceConnected; // was the device connected (on the last polling, or during backend-initialization)?
+    SDL_bool isDeviceRemovalEventPending;   // was the device removed, and is the associated removal event pending?
+};
+
+/* Keep track of data on all XInput devices, regardless of whether or not
+   they've been opened (via SDL_JoystickOpen).
+ */
+static struct joystick_hwdata g_XInputData[XUSER_MAX_COUNT];
+
+/* Function to scan the system for joysticks.
+ * It should return 0, or -1 on an unrecoverable fatal error.
+ */
+int
+SDL_SYS_JoystickInit(void)
+{
+    HRESULT result = S_OK;
+    XINPUT_STATE tempXInputState;
+    int i;
+
+    SDL_zero(g_XInputData);
+
+    /* Make initial notes on whether or not devices are connected (or not).
+     */
+    for (i = 0; i < XUSER_MAX_COUNT; ++i) {
+        result = XInputGetState(i, &tempXInputState);
+        if (result == ERROR_SUCCESS) {
+            g_XInputData[i].isDeviceConnected = SDL_TRUE;
+        }
+    }
+
+    return (0);
+}
+
+int SDL_SYS_NumJoysticks()
+{
+    int joystickCount = 0;
+    DWORD i;
+
+    /* Iterate through each possible XInput device and see if something
+       was connected (at joystick init, or during the last polling).
+     */
+    for (i = 0; i < XUSER_MAX_COUNT; ++i) {
+        if (g_XInputData[i].isDeviceConnected) {
+            ++joystickCount;
+        }
+    }
+
+    return joystickCount;
+}
+
+void SDL_SYS_JoystickDetect()
+{
+    DWORD i;
+    XINPUT_STATE tempXInputState;
+    HRESULT result;
+    SDL_Event event;
+
+    /* Iterate through each possible XInput device, seeing if any devices
+       have been connected, or if they were removed.
+     */
+    for (i = 0; i < XUSER_MAX_COUNT; ++i) {
+        /* See if any new devices are connected. */
+        if (!g_XInputData[i].isDeviceConnected && !g_XInputData[i].isDeviceRemovalEventPending) {
+            result = XInputGetState(i, &tempXInputState);
+            if (result == ERROR_SUCCESS) {
+                /* Yup, a device is connected.  Mark the device as connected,
+                   then tell others about it (via an SDL_JOYDEVICEADDED event.)
+                 */
+                g_XInputData[i].isDeviceConnected = SDL_TRUE;
+
+#if !SDL_EVENTS_DISABLED
+                SDL_zero(event);
+                event.type = SDL_JOYDEVICEADDED;
+                
+                if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+                    event.jdevice.which = i;
+                    if ((SDL_EventOK == NULL)
+                        || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
+                        SDL_PushEvent(&event);
+                    }
+                }
+#endif
+            }
+        } else if (g_XInputData[i].isDeviceRemovalEventPending) {
+            /* A device was previously marked as removed (by
+               SDL_SYS_JoystickUpdate).  Tell others about the device removal.
+            */
+
+            g_XInputData[i].isDeviceRemovalEventPending = SDL_FALSE;
+
+#if !SDL_EVENTS_DISABLED
+            SDL_zero(event);
+            event.type = SDL_JOYDEVICEREMOVED;
+                
+            if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+                event.jdevice.which = i; //joystick->hwdata->userIndex;
+                if ((SDL_EventOK == NULL)
+                    || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
+                    SDL_PushEvent(&event);
+                }
+            }
+#endif
+        }
+    }
+}
+
+SDL_bool SDL_SYS_JoystickNeedsPolling()
+{
+    /* Since XInput, or WinRT, provides any events to indicate when a game
+       controller gets connected, and instead indicates device availability
+       solely through polling, we'll poll (for new devices).
+     */
+    return SDL_TRUE;
+}
+
+/* Internal function to retreive device capabilities.
+   This function will return an SDL-standard value of 0 on success
+   (a device is connected, and data on it was retrieved), or -1
+   on failure (no device was connected, or some other error
+   occurred.  SDL_SetError() will be invoked to set an appropriate
+   error message.
+ */
+static int
+SDL_XInput_GetDeviceCapabilities(int device_index, XINPUT_CAPABILITIES * pDeviceCaps)
+{
+    HRESULT dwResult;
+
+    /* Make sure that the device index is a valid one.  If not, return to the
+       caller with an error.
+     */
+    if (device_index < 0 || device_index >= XUSER_MAX_COUNT) {
+        return SDL_SetError("invalid/unavailable device index");
+    }
+
+    /* See if a device exists, and if so, what its capabilities are.  If a
+       device is not available, return to the caller with an error.
+     */
+    switch ((dwResult = XInputGetCapabilities(device_index, 0, pDeviceCaps))) {
+        case ERROR_SUCCESS:
+            /* A device is available, and its capabilities were retrieved! */
+            return 0;
+        case ERROR_DEVICE_NOT_CONNECTED:
+            return SDL_SetError("no device is connected at joystick index, %d", device_index);
+        default:
+            return SDL_SetError("an unknown error occurred when retrieving info on a device at joystick index, %d", device_index);
+    }
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char *
+SDL_SYS_JoystickNameForDeviceIndex(int device_index)
+{
+    XINPUT_CAPABILITIES deviceCaps;
+
+    if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) {
+        /* Uh oh.  Device capabilities couldn't be retrieved.  Return to the
+           caller.  SDL_SetError() has already been invoked (with relevant
+           information).
+         */
+        return NULL;
+    }
+
+    switch (deviceCaps.SubType) {
+        default:
+            if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) {
+                return "Undefined game controller";
+            } else {
+                return "Undefined controller";
+            }
+        case XINPUT_DEVSUBTYPE_UNKNOWN:
+            if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) {
+                return "Unknown game controller";
+            } else {
+                return "Unknown controller";
+            }
+        case XINPUT_DEVSUBTYPE_GAMEPAD:
+            return "Gamepad controller";
+        case XINPUT_DEVSUBTYPE_WHEEL:
+            return "Racing wheel controller";
+        case XINPUT_DEVSUBTYPE_ARCADE_STICK:
+            return "Arcade stick controller";
+        case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
+            return "Flight stick controller";
+        case XINPUT_DEVSUBTYPE_DANCE_PAD:
+            return "Dance pad controller";
+        case XINPUT_DEVSUBTYPE_GUITAR:
+            return "Guitar controller";
+        case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
+            return "Guitar controller, Alternate";
+        case XINPUT_DEVSUBTYPE_GUITAR_BASS:
+            return "Guitar controller, Bass";
+        case XINPUT_DEVSUBTYPE_DRUM_KIT:
+            return "Drum controller";
+        case XINPUT_DEVSUBTYPE_ARCADE_PAD:
+            return "Arcade pad controller";
+    }
+}
+
+/* Function to perform the mapping from device index to the instance id for this index */
+SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
+{
+    return device_index;
+}
+
+/* Function to open a joystick for use.
+   The joystick to open is specified by the index field of the joystick.
+   This should fill the nbuttons and naxes fields of the joystick structure.
+   It returns 0, or -1 if there is an error.
+ */
+int
+SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
+{
+    XINPUT_CAPABILITIES deviceCaps;
+
+    if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) {
+        /* Uh oh.  Device capabilities couldn't be retrieved.  Return to the
+           caller.  SDL_SetError() has already been invoked (with relevant
+           information).
+         */
+        return -1;
+    }
+
+    /* For now, only game pads are supported.  If the device is something other
+       than that, return an error to the caller.
+     */
+    if (deviceCaps.Type != XINPUT_DEVTYPE_GAMEPAD) {
+        return SDL_SetError("a device is connected (at joystick index, %d), but it is of an unknown device type (deviceCaps.Flags=%ul)",
+            device_index, (unsigned int)deviceCaps.Flags);
+    }
+
+    /* Create the joystick data structure */
+    joystick->instance_id = device_index;
+    joystick->hwdata = &g_XInputData[device_index];
+
+    // The XInput API has a hard coded button/axis mapping, so we just match it
+    joystick->naxes = 6;
+    joystick->nbuttons = 15;
+    joystick->nballs = 0;
+    joystick->nhats = 0;
+
+    /* We're done! */
+    return (0);
+}
+
+/* Function to determine is this joystick is attached to the system right now */
+SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
+{
+    return joystick->hwdata->isDeviceConnected;
+}
+
+/* Function to return > 0 if a bit array of buttons differs after applying a mask
+*/
+static int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask )
+{
+    return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask );
+}
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+void
+SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
+{
+    HRESULT result;
+
+    /* Before polling for new data, make note of the old data */
+    XINPUT_STATE prevXInputState = joystick->hwdata->XInputState;
+
+    /* Poll for new data */
+    result = XInputGetState(joystick->hwdata->userIndex, &joystick->hwdata->XInputState);
+    if (result == ERROR_DEVICE_NOT_CONNECTED) {
+        if (joystick->hwdata->isDeviceConnected) {
+            joystick->hwdata->isDeviceConnected = SDL_FALSE;
+            joystick->hwdata->isDeviceRemovalEventPending = SDL_TRUE;
+            /* TODO, WinRT: make sure isDeviceRemovalEventPending gets cleared as appropriate, and that quick re-plugs don't cause trouble */
+        }
+        return;
+    }
+
+    /* Make sure the device is marked as connected */
+    joystick->hwdata->isDeviceConnected = SDL_TRUE;
+
+    // only fire events if the data changed from last time
+    if ( joystick->hwdata->XInputState.dwPacketNumber != 0 
+        && joystick->hwdata->XInputState.dwPacketNumber != prevXInputState.dwPacketNumber )
+    {
+        XINPUT_STATE *pXInputState = &joystick->hwdata->XInputState;
+        XINPUT_STATE *pXInputStatePrev = &prevXInputState;
+
+        SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX );
+        SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) );
+        SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX );
+        SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) );
+        SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) );
+        SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) );
+
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) )
+            SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) )
+            SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) )
+            SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) )
+            SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) )
+            SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) )
+            SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) )
+            SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) )
+            SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) )
+            SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) )
+            SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) )
+            SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) )
+            SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) )
+            SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) )
+            SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED :	SDL_RELEASED );
+        if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons,  0x400 ) )
+            SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED :	SDL_RELEASED ); // 0x400 is the undocumented code for the guide button
+    }
+}
+
+/* Function to close a joystick after use */
+void
+SDL_SYS_JoystickClose(SDL_Joystick * joystick)
+{
+    /* Clear cached button data on the joystick */
+    SDL_zero(joystick->hwdata->XInputState);
+
+    /* There's need to free 'hwdata', as it's a pointer to a global array.
+       The field will be cleared anyways, just to indicate that it's not
+       currently needed.
+     */
+    joystick->hwdata = NULL;
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+void
+SDL_SYS_JoystickQuit(void)
+{
+    return;
+}
+
+SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
+{
+    SDL_JoystickGUID guid;
+    // the GUID is just the first 16 chars of the name for now
+    const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
+    SDL_zero( guid );
+    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
+    return guid;
+}
+
+
+SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
+{
+    SDL_JoystickGUID guid;
+    // the GUID is just the first 16 chars of the name for now
+    const char *name = joystick->name;
+    SDL_zero( guid );
+    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
+    return guid;
+}
+
+SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index)
+{
+    /* The XInput-capable DirectInput joystick backend implements the same
+       function (SDL_SYS_IsXInputDeviceIndex), however in that case, not all
+       joystick devices are XInput devices.  In this case, with the
+       WinRT-enabled XInput-only backend, all "joystick" devices are XInput
+       devices.
+     */
+    return SDL_TRUE;
+}
+
+#endif /* SDL_JOYSTICK_XINPUT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 8 - 0
src/loadso/windows/SDL_sysloadso.c

@@ -33,7 +33,15 @@ void *
 SDL_LoadObject(const char *sofile)
 {
     LPTSTR tstr = WIN_UTF8ToString(sofile);
+#ifdef __WINRT__
+    /* WinRT only publically supports LoadPackagedLibrary() for loading .dll
+       files.  LoadLibrary() is a private API, and not available for apps
+       (that can be published to MS' Windows Store.)
+    */
+    void *handle = (void *) LoadPackagedLibrary(tstr, 0);
+#else
     void *handle = (void *) LoadLibrary(tstr);
+#endif
     SDL_free(tstr);
 
     /* Generate an error message if all loads failed */

+ 14 - 0
src/main/windowsrt/SDL_winrt_main.cpp

@@ -0,0 +1,14 @@
+
+//#include "pch.h"
+
+// The app's C-style main will be passed into SDL.dll as a function
+// pointer, and called at the appropriate time.
+typedef int (*SDLmain_MainFunction)(int, char **);
+extern __declspec(dllimport) int SDL_WinRT_RunApplication(SDLmain_MainFunction mainFunction);
+extern "C" int SDL_main(int, char **);
+
+[Platform::MTAThread]
+int main(Platform::Array<Platform::String^>^)
+{
+    return SDL_WinRT_RunApplication(SDL_main);
+}

+ 3 - 0
src/render/SDL_sysrender.h

@@ -166,6 +166,9 @@ struct SDL_RenderDriver
 #if SDL_VIDEO_RENDER_D3D
 extern SDL_RenderDriver D3D_RenderDriver;
 #endif
+#if SDL_VIDEO_RENDER_D3D11
+extern SDL_RenderDriver D3D11_RenderDriver;
+#endif
 #if SDL_VIDEO_RENDER_OGL
 extern SDL_RenderDriver GL_RenderDriver;
 #endif

+ 12 - 0
src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl

@@ -0,0 +1,12 @@
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    return input.color;
+}

+ 14 - 0
src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl

@@ -0,0 +1,14 @@
+Texture2D theTexture : register(t0);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    return theTexture.Sample(theSampler, input.tex) * input.color;
+}

+ 41 - 0
src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl

@@ -0,0 +1,41 @@
+
+#pragma pack_matrix( row_major )
+
+cbuffer SDL_VertexShaderConstants : register(b0)
+{
+    matrix model;
+    matrix view;
+    matrix projection;
+};
+
+struct VertexShaderInput
+{
+    float3 pos : POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+struct VertexShaderOutput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+VertexShaderOutput main(VertexShaderInput input)
+{
+    VertexShaderOutput output;
+    float4 pos = float4(input.pos, 1.0f);
+
+    // Transform the vertex position into projected space.
+    pos = mul(pos, model);
+    pos = mul(pos, view);
+    pos = mul(pos, projection);
+    output.pos = pos;
+
+    // Pass through texture coordinates and color values without transformation
+    output.tex = input.tex;
+    output.color = input.color;
+
+    return output;
+}

+ 1807 - 0
src/render/direct3d11/SDL_render_d3d11.cpp

@@ -0,0 +1,1807 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "SDL_config.h"
+
+#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
+
+#ifdef __WINRT__
+#include <windows.ui.core.h>
+#include <windows.foundation.h>
+#endif
+
+extern "C" {
+#include "../../core/windows/SDL_windows.h"
+//#include "SDL_hints.h"
+//#include "SDL_loadso.h"
+#include "SDL_system.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysrender.h"
+#include "SDL_log.h"
+#include "../../video/SDL_sysvideo.h"
+//#include "stdio.h"
+}
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "SDL_render_d3d11_cpp.h"
+
+using namespace DirectX;
+using namespace Microsoft::WRL;
+using namespace std;
+
+#ifdef __WINRT__
+using namespace Windows::Graphics::Display;
+using namespace Windows::UI::Core;
+#endif
+
+/* Direct3D 11.1 renderer implementation */
+
+static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void D3D11_WindowEvent(SDL_Renderer * renderer,
+                            const SDL_WindowEvent *event);
+static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                             const SDL_Rect * rect, const void *srcPixels,
+                             int srcPitch);
+static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                             const SDL_Rect * rect, void **pixels, int *pitch);
+static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
+static int D3D11_UpdateViewport(SDL_Renderer * renderer);
+static int D3D11_RenderClear(SDL_Renderer * renderer);
+static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
+                                  const SDL_FPoint * points, int count);
+static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
+                                 const SDL_FPoint * points, int count);
+static int D3D11_RenderFillRects(SDL_Renderer * renderer,
+                                 const SDL_FRect * rects, int count);
+static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                            const SDL_Rect * srcrect, const SDL_FRect * dstrect);
+static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
+                              const SDL_Rect * srcrect, const SDL_FRect * dstrect,
+                              const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
+static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                                  Uint32 format, void * pixels, int pitch);
+static void D3D11_RenderPresent(SDL_Renderer * renderer);
+static void D3D11_DestroyTexture(SDL_Renderer * renderer,
+                                 SDL_Texture * texture);
+static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
+
+/* Direct3D 11.1 Internal Functions */
+HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
+HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
+HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
+HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
+
+extern "C" SDL_RenderDriver D3D11_RenderDriver = {
+    D3D11_CreateRenderer,
+    {
+        "direct3d 11.1",
+        (
+            SDL_RENDERER_ACCELERATED |
+            SDL_RENDERER_PRESENTVSYNC |
+            SDL_RENDERER_TARGETTEXTURE
+        ),                          // flags.  see SDL_RendererFlags
+        2,                          // num_texture_formats
+        {                           // texture_formats
+            SDL_PIXELFORMAT_RGB888,
+            SDL_PIXELFORMAT_ARGB8888
+        },
+        0,                          // max_texture_width: will be filled in later
+        0                           // max_texture_height: will be filled in later
+    }
+};
+
+
+static Uint32
+DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
+    switch (dxgiFormat) {
+        case DXGI_FORMAT_B8G8R8A8_UNORM:
+            return SDL_PIXELFORMAT_ARGB8888;
+        case DXGI_FORMAT_B8G8R8X8_UNORM:
+            return SDL_PIXELFORMAT_RGB888;
+        default:
+            return SDL_PIXELFORMAT_UNKNOWN;
+    }
+}
+
+static DXGI_FORMAT
+SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
+{
+    switch (sdlFormat) {
+        case SDL_PIXELFORMAT_ARGB8888:
+            return DXGI_FORMAT_B8G8R8A8_UNORM;
+        case SDL_PIXELFORMAT_RGB888:
+            return DXGI_FORMAT_B8G8R8X8_UNORM;
+        default:
+            return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+
+//typedef struct
+//{
+//    float x, y, z;
+//    DWORD color;
+//    float u, v;
+//} Vertex;
+
+SDL_Renderer *
+D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_Renderer *renderer;
+    D3D11_RenderData *data;
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_zerop(renderer);
+
+    data = new D3D11_RenderData;    // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules
+    if (!data) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    data->featureLevel = (D3D_FEATURE_LEVEL) 0;
+    data->windowSizeInDIPs = XMFLOAT2(0, 0);
+    data->renderTargetSize = XMFLOAT2(0, 0);
+
+    renderer->WindowEvent = D3D11_WindowEvent;
+    renderer->CreateTexture = D3D11_CreateTexture;
+    renderer->UpdateTexture = D3D11_UpdateTexture;
+    renderer->LockTexture = D3D11_LockTexture;
+    renderer->UnlockTexture = D3D11_UnlockTexture;
+    renderer->SetRenderTarget = D3D11_SetRenderTarget;
+    renderer->UpdateViewport = D3D11_UpdateViewport;
+    renderer->RenderClear = D3D11_RenderClear;
+    renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
+    renderer->RenderDrawLines = D3D11_RenderDrawLines;
+    renderer->RenderFillRects = D3D11_RenderFillRects;
+    renderer->RenderCopy = D3D11_RenderCopy;
+    renderer->RenderCopyEx = D3D11_RenderCopyEx;
+    renderer->RenderReadPixels = D3D11_RenderReadPixels;
+    renderer->RenderPresent = D3D11_RenderPresent;
+    renderer->DestroyTexture = D3D11_DestroyTexture;
+    renderer->DestroyRenderer = D3D11_DestroyRenderer;
+    renderer->info = D3D11_RenderDriver.info;
+    renderer->driverdata = data;
+
+    // HACK: make sure the SDL_Renderer references the SDL_Window data now, in
+    // order to give init functions access to the underlying window handle:
+    renderer->window = window;
+
+    /* Initialize Direct3D resources */
+    if (FAILED(D3D11_CreateDeviceResources(renderer))) {
+        D3D11_DestroyRenderer(renderer);
+        return NULL;
+    }
+    if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
+        D3D11_DestroyRenderer(renderer);
+        return NULL;
+    }
+
+    // TODO, WinRT: fill in renderer->info.texture_formats where appropriate
+
+    return renderer;
+}
+
+static void
+D3D11_DestroyRenderer(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    if (data) {
+        delete data;
+        data = NULL;
+    }
+}
+
+static bool
+D3D11_ReadFileContents(const wstring & fileName, vector<char> & out)
+{
+    ifstream in(fileName, ios::in | ios::binary);
+    if (!in) {
+        return false;
+    }
+
+    in.seekg(0, ios::end);
+    out.resize((size_t) in.tellg());
+    in.seekg(0, ios::beg);
+    in.read(&out[0], out.size());
+    return in.good();
+}
+
+static bool
+D3D11_ReadShaderContents(const wstring & shaderName, vector<char> & out)
+{
+    wstring fileName;
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_APP
+    fileName = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_INSTALLED_LOCATION);
+    fileName += L"\\SDL_VS2012_WinRT\\";
+#elif WINAPI_FAMILY == WINAPI_PHONE_APP
+    fileName = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_INSTALLED_LOCATION);
+    fileName += L"\\";
+#endif
+    // WinRT, TODO: test Direct3D 11.1 shader loading on Win32
+    fileName += shaderName;
+    return D3D11_ReadFileContents(fileName, out);
+}
+
+static HRESULT
+D3D11_LoadPixelShader(SDL_Renderer * renderer,
+                      const wstring & shaderName,
+                      ID3D11PixelShader ** shaderOutput)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+    vector<char> fileData;
+    
+    if (!D3D11_ReadShaderContents(shaderName, fileData)) {
+        SDL_SetError("Unable to open SDL's pixel shader file.");
+        return E_FAIL;
+    }
+
+    result = data->d3dDevice->CreatePixelShader(
+        &fileData[0],
+        fileData.size(),
+        nullptr,
+        shaderOutput
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    return S_OK;
+}
+
+static HRESULT
+D3D11_CreateBlendMode(SDL_Renderer * renderer,
+                      BOOL enableBlending,
+                      D3D11_BLEND srcBlend,
+                      D3D11_BLEND destBlend,
+                      ID3D11BlendState ** blendStateOutput)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+
+    D3D11_BLEND_DESC blendDesc;
+    memset(&blendDesc, 0, sizeof(blendDesc));
+    blendDesc.AlphaToCoverageEnable = FALSE;
+    blendDesc.IndependentBlendEnable = FALSE;
+    blendDesc.RenderTarget[0].BlendEnable = enableBlending;
+    blendDesc.RenderTarget[0].SrcBlend = srcBlend;
+    blendDesc.RenderTarget[0].DestBlend = destBlend;
+    blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+    blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
+    blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
+    blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+    blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+    result = data->d3dDevice->CreateBlendState(&blendDesc, blendStateOutput);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    return S_OK;
+}
+
+// Create resources that depend on the device.
+HRESULT
+D3D11_CreateDeviceResources(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+
+    // This flag adds support for surfaces with a different color channel ordering
+    // than the API default. It is required for compatibility with Direct2D.
+    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+#if defined(_DEBUG)
+    // If the project is in a debug build, enable debugging via SDK Layers with this flag.
+    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+    // This array defines the set of DirectX hardware feature levels this app will support.
+    // Note the ordering should be preserved.
+    // Don't forget to declare your application's minimum required feature level in its
+    // description.  All applications are assumed to support 9.1 unless otherwise stated.
+    D3D_FEATURE_LEVEL featureLevels[] = 
+    {
+        D3D_FEATURE_LEVEL_11_1,
+        D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1,
+        D3D_FEATURE_LEVEL_10_0,
+        D3D_FEATURE_LEVEL_9_3,
+        D3D_FEATURE_LEVEL_9_2,
+        D3D_FEATURE_LEVEL_9_1
+    };
+
+    // Create the Direct3D 11 API device object and a corresponding context.
+    ComPtr<ID3D11Device> device;
+    ComPtr<ID3D11DeviceContext> context;
+    HRESULT result = S_OK;
+    result = D3D11CreateDevice(
+        nullptr, // Specify nullptr to use the default adapter.
+        D3D_DRIVER_TYPE_HARDWARE,
+        nullptr,
+        creationFlags, // Set set debug and Direct2D compatibility flags.
+        featureLevels, // List of feature levels this app can support.
+        ARRAYSIZE(featureLevels),
+        D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
+        &device, // Returns the Direct3D device created.
+        &data->featureLevel, // Returns feature level of device created.
+        &context // Returns the device immediate context.
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    // Get the Direct3D 11.1 API device and context interfaces.
+    Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice1;
+    result = device.As(&(data->d3dDevice));
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    result = context.As(&data->d3dContext);
+    if (FAILED(result)) {
+        return result;
+    }
+
+    //
+    // Make note of the maximum texture size
+    // Max texture sizes are documented on MSDN, at:
+    // http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
+    //
+    switch (data->d3dDevice->GetFeatureLevel()) {
+        case D3D_FEATURE_LEVEL_11_1:
+        case D3D_FEATURE_LEVEL_11_0:
+            renderer->info.max_texture_width = renderer->info.max_texture_height = 16384;
+            break;
+
+        case D3D_FEATURE_LEVEL_10_1:
+        case D3D_FEATURE_LEVEL_10_0:
+            renderer->info.max_texture_width = renderer->info.max_texture_height = 8192;
+            break;
+
+        case D3D_FEATURE_LEVEL_9_3:
+            renderer->info.max_texture_width = renderer->info.max_texture_height = 4096;
+            break;
+
+        case D3D_FEATURE_LEVEL_9_2:
+        case D3D_FEATURE_LEVEL_9_1:
+            renderer->info.max_texture_width = renderer->info.max_texture_height = 2048;
+            break;
+    }
+
+    //
+    // Load in SDL's one and only vertex shader:
+    //
+    vector<char> fileData;
+    if (!D3D11_ReadShaderContents(L"SDL_D3D11_VertexShader_Default.cso", fileData)) {
+        SDL_SetError("Unable to open SDL's vertex shader file.");
+        return E_FAIL;
+    }
+
+    result = data->d3dDevice->CreateVertexShader(
+        &fileData[0],
+        fileData.size(),
+        nullptr,
+        &data->vertexShader
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    //
+    // Create an input layout for SDL's vertex shader:
+    //
+    const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
+    {
+        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+    };
+
+    result = data->d3dDevice->CreateInputLayout(
+        vertexDesc,
+        ARRAYSIZE(vertexDesc),
+        &fileData[0],
+        fileData.size(),
+        &data->inputLayout
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    //
+    // Load in SDL's pixel shaders
+    //
+    result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_TextureColored.cso", &data->texturePixelShader);
+    if (FAILED(result)) {
+        // D3D11_LoadPixelShader will have aleady set the SDL error
+        return result;
+    }
+
+    result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_FixedColor.cso", &data->colorPixelShader);
+    if (FAILED(result)) {
+        // D3D11_LoadPixelShader will have aleady set the SDL error
+        return result;
+    }
+
+    //
+    // Setup space to hold vertex shader constants:
+    //
+    CD3D11_BUFFER_DESC constantBufferDesc(sizeof(SDL_VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER);
+    result = data->d3dDevice->CreateBuffer(
+		&constantBufferDesc,
+		nullptr,
+        &data->vertexShaderConstants
+		);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    //
+    // Make sure that the vertex buffer, if already created, gets freed.
+    // It will be recreated later.
+    //
+    data->vertexBuffer = nullptr;
+
+    //
+    // Create a sampler to use when drawing textures:
+    //
+    D3D11_SAMPLER_DESC samplerDesc;
+    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.MipLODBias = 0.0f;
+    samplerDesc.MaxAnisotropy = 1;
+    samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+    samplerDesc.BorderColor[0] = 0.0f;
+    samplerDesc.BorderColor[1] = 0.0f;
+    samplerDesc.BorderColor[2] = 0.0f;
+    samplerDesc.BorderColor[3] = 0.0f;
+    samplerDesc.MinLOD = 0.0f;
+    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+    result = data->d3dDevice->CreateSamplerState(
+        &samplerDesc,
+        &data->mainSampler
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    //
+    // Setup the Direct3D rasterizer
+    //
+    D3D11_RASTERIZER_DESC rasterDesc;
+    memset(&rasterDesc, 0, sizeof(rasterDesc));
+	rasterDesc.AntialiasedLineEnable = false;
+	rasterDesc.CullMode = D3D11_CULL_NONE;
+	rasterDesc.DepthBias = 0;
+	rasterDesc.DepthBiasClamp = 0.0f;
+	rasterDesc.DepthClipEnable = true;
+	rasterDesc.FillMode = D3D11_FILL_SOLID;
+	rasterDesc.FrontCounterClockwise = false;
+	rasterDesc.MultisampleEnable = false;
+	rasterDesc.ScissorEnable = false;
+	rasterDesc.SlopeScaledDepthBias = 0.0f;
+	result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->mainRasterizer);
+	if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    //
+    // Create blending states:
+    //
+    result = D3D11_CreateBlendMode(
+        renderer,
+        TRUE,
+        D3D11_BLEND_SRC_ALPHA,
+        D3D11_BLEND_INV_SRC_ALPHA,
+        &data->blendModeBlend);
+    if (FAILED(result)) {
+        // D3D11_CreateBlendMode will set the SDL error, if it fails
+        return result;
+    }
+
+    result = D3D11_CreateBlendMode(
+        renderer,
+        TRUE,
+        D3D11_BLEND_SRC_ALPHA,
+        D3D11_BLEND_ONE,
+        &data->blendModeAdd);
+    if (FAILED(result)) {
+        // D3D11_CreateBlendMode will set the SDL error, if it fails
+        return result;
+    }
+
+    result = D3D11_CreateBlendMode(
+        renderer,
+        TRUE,
+        D3D11_BLEND_ZERO,
+        D3D11_BLEND_SRC_COLOR,
+        &data->blendModeMod);
+    if (FAILED(result)) {
+        // D3D11_CreateBlendMode will set the SDL error, if it fails
+        return result;
+    }
+
+    //
+    // All done!
+    //
+    return S_OK;
+}
+
+#ifdef __WINRT__
+
+static ABI::Windows::UI::Core::ICoreWindow *
+D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer)
+{
+    SDL_Window * sdlWindow = renderer->window;
+    if ( ! renderer->window ) {
+        return nullptr;
+    }
+
+    SDL_SysWMinfo sdlWindowInfo;
+    SDL_VERSION(&sdlWindowInfo.version);
+    if ( ! SDL_GetWindowWMInfo(sdlWindow, &sdlWindowInfo) ) {
+        return nullptr;
+    }
+
+    if (sdlWindowInfo.subsystem != SDL_SYSWM_WINDOWSRT) {
+        return nullptr;
+    }
+
+    if ( ! sdlWindowInfo.info.winrt.window ) {
+        return nullptr;
+    }
+
+    ABI::Windows::UI::Core::ICoreWindow * coreWindow = nullptr;
+    if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) {
+        return nullptr;
+    }
+
+    return coreWindow;
+}
+
+// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+static float
+D3D11_ConvertDipsToPixels(float dips)
+{
+    static const float dipsPerInch = 96.0f;
+    return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
+}
+#endif
+
+// Initialize all resources that change when the window's size changes.
+// WinRT, TODO: get D3D11_CreateWindowSizeDependentResources working on Win32
+HRESULT
+D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+    ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
+
+    // Store the window bounds so the next time we get a SizeChanged event we can
+    // avoid rebuilding everything if the size is identical.
+    ABI::Windows::Foundation::Rect coreWindowBounds;
+    result = coreWindow->get_Bounds(&coreWindowBounds);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result);
+        return result;
+    }
+
+    data->windowSizeInDIPs.x = coreWindowBounds.Width;
+    data->windowSizeInDIPs.y = coreWindowBounds.Height;
+
+    // Calculate the necessary swap chain and render target size in pixels.
+    float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x);
+    float windowHeight = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.y);
+
+    // The width and height of the swap chain must be based on the window's
+    // landscape-oriented width and height. If the window is in a portrait
+    // orientation, the dimensions must be reversed.
+    data->orientation = DisplayProperties::CurrentOrientation;
+    const bool swapDimensions =
+        data->orientation == DisplayOrientations::Portrait ||
+        data->orientation == DisplayOrientations::PortraitFlipped;
+    data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth;
+    data->renderTargetSize.y = swapDimensions ? windowWidth : windowHeight;
+
+    if(data->swapChain != nullptr)
+    {
+        // If the swap chain already exists, resize it.
+        result = data->swapChain->ResizeBuffers(
+            2, // Double-buffered swap chain.
+            static_cast<UINT>(data->renderTargetSize.x),
+            static_cast<UINT>(data->renderTargetSize.y),
+            DXGI_FORMAT_B8G8R8A8_UNORM,
+            0
+            );
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+    }
+    else
+    {
+        // Otherwise, create a new one using the same adapter as the existing Direct3D device.
+        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+        swapChainDesc.Width = static_cast<UINT>(data->renderTargetSize.x); // Match the size of the window.
+        swapChainDesc.Height = static_cast<UINT>(data->renderTargetSize.y);
+        swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
+        swapChainDesc.Stereo = false;
+        swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
+        swapChainDesc.SampleDesc.Quality = 0;
+        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+        swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+        swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
+        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
+#else
+        swapChainDesc.Scaling = DXGI_SCALING_NONE;
+        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
+#endif
+        swapChainDesc.Flags = 0;
+
+        ComPtr<IDXGIDevice1>  dxgiDevice;
+        result = data->d3dDevice.As(&dxgiDevice);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+
+        ComPtr<IDXGIAdapter> dxgiAdapter;
+        result = dxgiDevice->GetAdapter(&dxgiAdapter);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+
+        ComPtr<IDXGIFactory2> dxgiFactory;
+        result = dxgiAdapter->GetParent(
+            __uuidof(IDXGIFactory2), 
+            &dxgiFactory
+            );
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+
+        IUnknown * coreWindowAsIUnknown = nullptr;
+        result = coreWindow->QueryInterface(&coreWindowAsIUnknown);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__ ", CoreWindow to IUnknown", result);
+            return result;
+        }
+
+        result = dxgiFactory->CreateSwapChainForCoreWindow(
+            data->d3dDevice.Get(),
+            coreWindowAsIUnknown,
+            &swapChainDesc,
+            nullptr, // Allow on all displays.
+            &data->swapChain
+            );
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+            
+        // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
+        // ensures that the application will only render after each VSync, minimizing power consumption.
+        result = dxgiDevice->SetMaximumFrameLatency(1);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+    }
+    
+    // Set the proper orientation for the swap chain, and generate the
+    // 3D matrix transformation for rendering to the rotated swap chain.
+    DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
+    switch (data->orientation)
+    {
+        case DisplayOrientations::Landscape:
+            rotation = DXGI_MODE_ROTATION_IDENTITY;
+            break;
+
+        case DisplayOrientations::Portrait:
+            rotation = DXGI_MODE_ROTATION_ROTATE270;
+            break;
+
+        case DisplayOrientations::LandscapeFlipped:
+            rotation = DXGI_MODE_ROTATION_ROTATE180;
+            break;
+
+        case DisplayOrientations::PortraitFlipped:
+            rotation = DXGI_MODE_ROTATION_ROTATE90;
+            break;
+
+        default:
+            throw ref new Platform::FailureException();
+    }
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+    // TODO, WinRT: Windows Phone does not have the IDXGISwapChain1::SetRotation method.  Check if an alternative is available, or needed.
+    result = data->swapChain->SetRotation(rotation);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+#endif
+
+    // Create a render target view of the swap chain back buffer.
+    ComPtr<ID3D11Texture2D> backBuffer;
+    result = data->swapChain->GetBuffer(
+        0,
+        __uuidof(ID3D11Texture2D),
+        &backBuffer
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    result = data->d3dDevice->CreateRenderTargetView(
+        backBuffer.Get(),
+        nullptr,
+        &data->mainRenderTargetView
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    if (D3D11_UpdateViewport(renderer) != 0) {
+        // D3D11_UpdateViewport will set the SDL error if it fails.
+        return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+// This method is called when the window's size changes.
+HRESULT
+D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+    ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
+    ABI::Windows::Foundation::Rect coreWindowBounds;
+
+    result = coreWindow->get_Bounds(&coreWindowBounds);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Get Window Bounds", result);
+        return result;
+    }
+
+    if (coreWindowBounds.Width  != data->windowSizeInDIPs.x ||
+        coreWindowBounds.Height != data->windowSizeInDIPs.y ||
+        data->orientation != DisplayProperties::CurrentOrientation)
+    {
+        ID3D11RenderTargetView* nullViews[] = {nullptr};
+        data->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
+        data->mainRenderTargetView = nullptr;
+        data->d3dContext->Flush();
+        result = D3D11_CreateWindowSizeDependentResources(renderer);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return result;
+        }
+    }
+
+    return S_OK;
+}
+
+HRESULT
+D3D11_HandleDeviceLost(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+
+    // Reset these member variables to ensure that D3D11_UpdateForWindowSizeChange recreates all resources.
+    data->windowSizeInDIPs.x = 0;
+    data->windowSizeInDIPs.y = 0;
+    data->swapChain = nullptr;
+
+    result = D3D11_CreateDeviceResources(renderer);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    result = D3D11_UpdateForWindowSizeChange(renderer);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return result;
+    }
+
+    return S_OK;
+}
+
+static void
+D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    //D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+
+    if (event->event == SDL_WINDOWEVENT_RESIZED) {
+        D3D11_UpdateForWindowSizeChange(renderer);
+    }
+}
+
+static int
+D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData;
+    HRESULT result;
+    DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
+    if (textureFormat == SDL_PIXELFORMAT_UNKNOWN) {
+        SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
+            __FUNCTION__, texture->format);
+        return -1;
+    }
+
+    textureData = new D3D11_TextureData;
+    if (!textureData) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+    textureData->pixelFormat = SDL_AllocFormat(texture->format);
+    textureData->lockedTexturePosition = XMINT2(0, 0);
+
+    texture->driverdata = textureData;
+
+    D3D11_TEXTURE2D_DESC textureDesc = {0};
+    textureDesc.Width = texture->w;
+    textureDesc.Height = texture->h;
+    textureDesc.MipLevels = 1;
+    textureDesc.ArraySize = 1;
+    textureDesc.Format = textureFormat;
+    textureDesc.SampleDesc.Count = 1;
+    textureDesc.SampleDesc.Quality = 0;
+    textureDesc.MiscFlags = 0;
+
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        textureDesc.Usage = D3D11_USAGE_DYNAMIC;
+        textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    } else {
+        textureDesc.Usage = D3D11_USAGE_DEFAULT;
+        textureDesc.CPUAccessFlags = 0;
+    }
+
+    if (texture->access == SDL_TEXTUREACCESS_TARGET) {
+        textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+    } else {
+        textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+    }
+
+#if 0
+    // Fill the texture with a non-black color, for debugging purposes:
+    const int numPixels = textureDesc.Width * textureDesc.Height;
+    const int pixelSizeInBytes = textureData->pixelFormat->BytesPerPixel;
+    std::vector<uint8> initialTexturePixels(numPixels * pixelSizeInBytes, 0x00);
+    for (int i = 0; i < (numPixels * pixelSizeInBytes); i += pixelSizeInBytes) {
+        initialTexturePixels[i+0] = 0xff;
+        initialTexturePixels[i+1] = 0xff;
+        initialTexturePixels[i+2] = 0x00;
+        initialTexturePixels[i+3] = 0xff;
+    }
+    D3D11_SUBRESOURCE_DATA initialTextureData = {0};
+    initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
+    initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes;
+    initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes;
+#endif
+
+    result = rendererData->d3dDevice->CreateTexture2D(
+        &textureDesc,
+        NULL,   // &initialTextureData,
+        &textureData->mainTexture
+        );
+    if (FAILED(result)) {
+        D3D11_DestroyTexture(renderer, texture);
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return -1;
+    }
+
+    if (texture->access & SDL_TEXTUREACCESS_TARGET) {
+        D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
+        renderTargetViewDesc.Format = textureDesc.Format;
+        renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+        renderTargetViewDesc.Texture2D.MipSlice = 0;
+
+        result = rendererData->d3dDevice->CreateRenderTargetView(
+            textureData->mainTexture.Get(),
+            &renderTargetViewDesc,
+            &textureData->mainTextureRenderTargetView);
+        if (FAILED(result)) {
+            D3D11_DestroyTexture(renderer, texture);
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return -1;
+        }
+    }
+
+    D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
+    resourceViewDesc.Format = textureDesc.Format;
+    resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+    resourceViewDesc.Texture2D.MostDetailedMip = 0;
+    resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
+    result = rendererData->d3dDevice->CreateShaderResourceView(
+        textureData->mainTexture.Get(),
+        &resourceViewDesc,
+        &textureData->mainTextureResourceView
+        );
+    if (FAILED(result)) {
+        D3D11_DestroyTexture(renderer, texture);
+        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void
+D3D11_DestroyTexture(SDL_Renderer * renderer,
+                     SDL_Texture * texture)
+{
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    if (textureData) {
+        if (textureData->pixelFormat) {
+            SDL_FreeFormat(textureData->pixelFormat);
+            textureData->pixelFormat = NULL;
+        }
+
+        delete textureData;
+        texture->driverdata = NULL;
+    }
+}
+
+static int
+D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                    const SDL_Rect * rect, const void * srcPixels,
+                    int srcPitch)
+{
+    // Lock the texture, retrieving a buffer to write pixel data to:
+    void * destPixels = NULL;
+    int destPitch = 0;
+    if (D3D11_LockTexture(renderer, texture, rect, &destPixels, &destPitch) != 0) {
+        // An error is already set.  Attach some info to it, then return to
+        // the caller.
+        std::string errorMessage = string(__FUNCTION__ ", Lock Texture Failed: ") + SDL_GetError();
+        SDL_SetError(errorMessage.c_str());
+        return -1;
+    }
+
+    // Copy pixel data to the locked texture's memory:
+    for (int y = 0; y < rect->h; ++y) {
+        memcpy(
+            ((Uint8 *)destPixels) + (destPitch * y),
+            ((Uint8 *)srcPixels) + (srcPitch * y),
+            srcPitch
+            );
+    }
+
+    // Commit the texture's memory back to Direct3D:
+    D3D11_UnlockTexture(renderer, texture);
+
+    // Return to the caller:
+    return 0;
+}
+
+static int
+D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                  const SDL_Rect * rect, void **pixels, int *pitch)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+    HRESULT result = S_OK;
+
+    if (textureData->stagingTexture) {
+        SDL_SetError("texture is already locked");
+        return -1;
+    }
+    
+    // Create a 'staging' texture, which will be used to write to a portion
+    // of the main texture.  This is necessary, as Direct3D 11.1 does not
+    // have the ability to write a CPU-bound pixel buffer to a rectangular
+    // subrect of a texture.  Direct3D 11.1 can, however, write a pixel
+    // buffer to an entire texture, hence the use of a staging texture.
+    D3D11_TEXTURE2D_DESC stagingTextureDesc;
+    textureData->mainTexture->GetDesc(&stagingTextureDesc);
+    stagingTextureDesc.Width = rect->w;
+    stagingTextureDesc.Height = rect->h;
+    stagingTextureDesc.BindFlags = 0;
+    stagingTextureDesc.MiscFlags = 0;
+    stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
+    result = rendererData->d3dDevice->CreateTexture2D(
+        &stagingTextureDesc,
+        NULL,
+        &textureData->stagingTexture);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Create Staging Texture", result);
+        return -1;
+    }
+
+    // Get a write-only pointer to data in the staging texture:
+    D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
+    result = rendererData->d3dContext->Map(
+        textureData->stagingTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        D3D11_MAP_WRITE,
+        0,
+        &textureMemory
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Map Staging Texture", result);
+        textureData->stagingTexture = nullptr;
+        return -1;
+    }
+
+    // Make note of where the staging texture will be written to (on a
+    // call to SDL_UnlockTexture):
+    textureData->lockedTexturePosition = XMINT2(rect->x, rect->y);
+
+    // Make sure the caller has information on the texture's pixel buffer,
+    // then return:
+    *pixels = textureMemory.pData;
+    *pitch = textureMemory.RowPitch;
+    return 0;
+}
+
+static void
+D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    // Commit the pixel buffer's changes back to the staging texture:
+    rendererData->d3dContext->Unmap(
+        textureData->stagingTexture.Get(),
+        0);
+
+    // Copy the staging texture's contents back to the main texture:
+    rendererData->d3dContext->CopySubresourceRegion(
+        textureData->mainTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        textureData->lockedTexturePosition.x,
+        textureData->lockedTexturePosition.y,
+        0,
+        textureData->stagingTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        NULL);
+
+    // Clean up and return:
+    textureData->stagingTexture = nullptr;
+    textureData->lockedTexturePosition = XMINT2(0, 0);
+}
+
+static int
+D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+
+    if (texture == NULL) {
+        rendererData->currentOffscreenRenderTargetView = nullptr;
+        return 0;
+    }
+
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    if (!textureData->mainTextureRenderTargetView) {
+        std::string errorMessage = string(__FUNCTION__) + ": specified texture is not a render target";
+        SDL_SetError(errorMessage.c_str());
+        return -1;
+    }
+
+    rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
+
+    return 0;
+}
+
+static int
+D3D11_UpdateViewport(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+
+    if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
+        // If the viewport is empty, assume that it is because
+        // SDL_CreateRenderer is calling it, and will call it again later
+        // with a non-empty viewport.
+        return 0;
+    }
+
+    switch (data->orientation)
+    {
+        case DisplayOrientations::Landscape:
+            data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 0-degree Z-rotation
+                1.0f, 0.0f, 0.0f, 0.0f,
+                0.0f, 1.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f,
+                0.0f, 0.0f, 0.0f, 1.0f
+                );
+            break;
+
+        case DisplayOrientations::Portrait:
+            data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 90-degree Z-rotation
+                0.0f, 1.0f, 0.0f, 0.0f,
+                -1.0f, 0.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f,
+                0.0f, 0.0f, 0.0f, 1.0f
+                );
+            break;
+
+        case DisplayOrientations::LandscapeFlipped:
+            data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 180-degree Z-rotation
+                -1.0f, 0.0f, 0.0f, 0.0f,
+                0.0f, -1.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f,
+                0.0f, 0.0f, 0.0f, 1.0f
+                );
+            break;
+
+        case DisplayOrientations::PortraitFlipped:
+            data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 270-degree Z-rotation
+                0.0f, -1.0f, 0.0f, 0.0f,
+                1.0f, 0.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f,
+                0.0f, 0.0f, 0.0f, 1.0f
+                );
+            break;
+
+        default:
+            SDL_SetError("An unknown DisplayOrientation is being used");
+            return -1;
+    }
+
+    //
+    // Update the view matrix
+    //
+    float viewportWidth = (float) renderer->viewport.w;
+    float viewportHeight = (float) renderer->viewport.h;
+    XMStoreFloat4x4(&data->vertexShaderConstantsData.view,
+        XMMatrixMultiply(
+            XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f),
+            XMMatrixMultiply(
+                XMMatrixTranslation(-1, -1, 0),
+                XMMatrixRotationX(XM_PI)
+                )));
+#if 0
+    data->vertexShaderConstantsData.view = XMMatrixIdentity();
+#endif
+
+    //
+    // Reset the model matrix
+    //
+    XMStoreFloat4x4(&data->vertexShaderConstantsData.model, XMMatrixIdentity());
+
+    //
+    // Update the Direct3D viewport, which seems to be aligned to the
+    // swap buffer's coordinate space, which is always in landscape:
+    //
+    SDL_FRect orientationAlignedViewport;
+    const bool swapDimensions =
+        data->orientation == DisplayOrientations::Portrait ||
+        data->orientation == DisplayOrientations::PortraitFlipped;
+    if (swapDimensions) {
+        orientationAlignedViewport.x = (float) renderer->viewport.y;
+        orientationAlignedViewport.y = (float) renderer->viewport.x;
+        orientationAlignedViewport.w = (float) renderer->viewport.h;
+        orientationAlignedViewport.h = (float) renderer->viewport.w;
+    } else {
+        orientationAlignedViewport.x = (float) renderer->viewport.x;
+        orientationAlignedViewport.y = (float) renderer->viewport.y;
+        orientationAlignedViewport.w = (float) renderer->viewport.w;
+        orientationAlignedViewport.h = (float) renderer->viewport.h;
+    }
+    // WinRT, TODO: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped)
+
+    D3D11_VIEWPORT viewport;
+    memset(&viewport, 0, sizeof(viewport));
+    viewport.TopLeftX = orientationAlignedViewport.x;
+    viewport.TopLeftY = orientationAlignedViewport.y;
+    viewport.Width = orientationAlignedViewport.w;
+    viewport.Height = orientationAlignedViewport.h;
+    viewport.MinDepth = 0.0f;
+    viewport.MaxDepth = 1.0f;
+    data->d3dContext->RSSetViewports(1, &viewport);
+
+#if 0
+    SDL_Log("%s, oav={%.0f,%.0f,%.0f,%.0f}, rend={%.0f,%.0f}\n",
+        __FUNCTION__,
+        orientationAlignedViewport.x,
+        orientationAlignedViewport.y,
+        orientationAlignedViewport.w,
+        orientationAlignedViewport.h,
+        data->renderTargetSize.x,
+        data->renderTargetSize.y);
+#endif
+
+    return 0;
+}
+
+static ComPtr<ID3D11RenderTargetView> &
+D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    if (data->currentOffscreenRenderTargetView) {
+        return data->currentOffscreenRenderTargetView;
+    } else {
+        return data->mainRenderTargetView;
+    }
+}
+
+static int
+D3D11_RenderClear(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+    const float colorRGBA[] = {
+        (renderer->r / 255.0f),
+        (renderer->g / 255.0f),
+        (renderer->b / 255.0f),
+        (renderer->a / 255.0f)
+    };
+    data->d3dContext->ClearRenderTargetView(
+        D3D11_GetCurrentRenderTargetView(renderer).Get(),
+        colorRGBA
+        );
+    return 0;
+}
+
+static int
+D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
+                         const void * vertexData, unsigned int dataSizeInBytes)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+    D3D11_BUFFER_DESC vertexBufferDesc;
+
+    if (rendererData->vertexBuffer) {
+        rendererData->vertexBuffer->GetDesc(&vertexBufferDesc);
+    } else {
+        memset(&vertexBufferDesc, 0, sizeof(vertexBufferDesc));
+    }
+
+    if (vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
+        rendererData->d3dContext->UpdateSubresource(rendererData->vertexBuffer.Get(), 0, NULL, vertexData, dataSizeInBytes, 0);
+    } else {
+        vertexBufferDesc.ByteWidth = dataSizeInBytes;
+        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+
+        D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
+        vertexBufferData.pSysMem = vertexData;
+        vertexBufferData.SysMemPitch = 0;
+        vertexBufferData.SysMemSlicePitch = 0;
+
+        result = rendererData->d3dDevice->CreateBuffer(
+            &vertexBufferDesc,
+            &vertexBufferData,
+            &rendererData->vertexBuffer
+            );
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, result);
+            return -1;
+        }
+    }
+
+    UINT stride = sizeof(VertexPositionColor);
+    UINT offset = 0;
+    rendererData->d3dContext->IASetVertexBuffers(
+        0,
+        1,
+        rendererData->vertexBuffer.GetAddressOf(),
+        &stride,
+        &offset
+        );
+
+    return 0;
+}
+
+static void
+D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+
+    rendererData->d3dContext->OMSetRenderTargets(
+        1,
+        D3D11_GetCurrentRenderTargetView(renderer).GetAddressOf(),
+        nullptr
+        );
+}
+
+static void
+D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    switch (blendMode) {
+        case SDL_BLENDMODE_BLEND:
+            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeBlend.Get(), 0, 0xFFFFFFFF);
+            break;
+        case SDL_BLENDMODE_ADD:
+            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeAdd.Get(), 0, 0xFFFFFFFF);
+            break;
+        case SDL_BLENDMODE_MOD:
+            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeMod.Get(), 0, 0xFFFFFFFF);
+            break;
+        case SDL_BLENDMODE_NONE:
+            rendererData->d3dContext->OMSetBlendState(NULL, 0, 0xFFFFFFFF);
+            break;
+    }
+}
+
+static void
+D3D11_SetPixelShader(SDL_Renderer * renderer,
+                     ID3D11PixelShader * shader,
+                     ID3D11ShaderResourceView * shaderResource,
+                     ID3D11SamplerState * sampler)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    rendererData->d3dContext->PSSetShader(shader, nullptr, 0);
+    rendererData->d3dContext->PSSetShaderResources(0, 1, &shaderResource);
+    rendererData->d3dContext->PSSetSamplers(0, 1, &sampler);
+}
+
+static void
+D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
+                         D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
+                         UINT vertexCount)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+
+    rendererData->d3dContext->UpdateSubresource(
+        rendererData->vertexShaderConstants.Get(),
+        0,
+        NULL,
+        &rendererData->vertexShaderConstantsData,
+        0,
+        0
+        );
+
+    rendererData->d3dContext->IASetPrimitiveTopology(primitiveTopology);
+    rendererData->d3dContext->IASetInputLayout(rendererData->inputLayout.Get());
+    rendererData->d3dContext->VSSetShader(rendererData->vertexShader.Get(), nullptr, 0);
+    rendererData->d3dContext->VSSetConstantBuffers(0, 1, rendererData->vertexShaderConstants.GetAddressOf());
+    rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get());
+    rendererData->d3dContext->Draw(vertexCount, 0);
+}
+
+static int
+D3D11_RenderDrawPoints(SDL_Renderer * renderer,
+                       const SDL_FPoint * points, int count)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    float r, g, b, a;
+
+    r = (float)(renderer->r / 255.0f);
+    g = (float)(renderer->g / 255.0f);
+    b = (float)(renderer->b / 255.0f);
+    a = (float)(renderer->a / 255.0f);
+
+    vector<VertexPositionColor> vertices;
+    vertices.reserve(count);
+    for (int i = 0; i < count; ++i) {
+        VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f),  XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)};
+        vertices.push_back(v);
+    }
+
+    D3D11_RenderStartDrawOp(renderer);
+    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
+    if (D3D11_UpdateVertexBuffer(renderer, &vertices[0], vertices.size() * sizeof(VertexPositionColor)) != 0) {
+        return -1;
+    }
+
+    D3D11_SetPixelShader(
+        renderer,
+        rendererData->colorPixelShader.Get(),
+        nullptr,
+        nullptr);
+
+    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, vertices.size());
+
+    return 0;
+}
+
+static int
+D3D11_RenderDrawLines(SDL_Renderer * renderer,
+                      const SDL_FPoint * points, int count)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    float r, g, b, a;
+
+    r = (float)(renderer->r / 255.0f);
+    g = (float)(renderer->g / 255.0f);
+    b = (float)(renderer->b / 255.0f);
+    a = (float)(renderer->a / 255.0f);
+
+    vector<VertexPositionColor> vertices;
+    vertices.reserve(count);
+    for (int i = 0; i < count; ++i) {
+        VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f),  XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)};
+        vertices.push_back(v);
+    }
+
+    D3D11_RenderStartDrawOp(renderer);
+    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
+    if (D3D11_UpdateVertexBuffer(renderer, &vertices[0], vertices.size() * sizeof(VertexPositionColor)) != 0) {
+        return -1;
+    }
+
+    D3D11_SetPixelShader(
+        renderer,
+        rendererData->colorPixelShader.Get(),
+        nullptr,
+        nullptr);
+
+    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, vertices.size());
+
+    return 0;
+}
+
+static int
+D3D11_RenderFillRects(SDL_Renderer * renderer,
+                      const SDL_FRect * rects, int count)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    float r, g, b, a;
+
+    r = (float)(renderer->r / 255.0f);
+    g = (float)(renderer->g / 255.0f);
+    b = (float)(renderer->b / 255.0f);
+    a = (float)(renderer->a / 255.0f);
+
+#if 0
+    // Set up a test pattern:
+    SDL_FRect _rects[] = {
+        {-1.1f, 1.1f, 1.1f, -1.1f},
+        {-1.0f, 1.0f, 1.0f, -1.0f},     // red
+        {0.0f, 1.0f, 1.0f, -1.0f},      // green
+        {-1.0f, 0.0f, 1.0f, -1.0f},     // blue
+        {0.0f, 0.0f, 1.0f, -1.0f}       // white
+    };
+    count = sizeof(_rects) / sizeof(SDL_FRect);
+#define rects _rects
+#endif
+
+    for (int i = 0; i < count; ++i) {
+        D3D11_RenderStartDrawOp(renderer);
+        D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
+
+#if 0
+        // Set colors for the test pattern:
+        a = 1.0f;
+        switch (i) {
+            case 0: r = 1.0f; g = 1.0f; b = 0.0f; break;
+            case 1: r = 1.0f; g = 0.0f; b = 0.0f; break;
+            case 2: r = 0.0f; g = 1.0f; b = 0.0f; break;
+            case 3: r = 0.0f; g = 0.0f; b = 1.0f; break;
+            case 4: r = 1.0f; g = 1.0f; b = 1.0f; break;
+        }
+#endif
+
+        VertexPositionColor vertices[] = {
+            {XMFLOAT3(rects[i].x, rects[i].y, 0.0f),                           XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
+            {XMFLOAT3(rects[i].x, rects[i].y + rects[i].h, 0.0f),              XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
+            {XMFLOAT3(rects[i].x + rects[i].w, rects[i].y, 0.0f),              XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
+            {XMFLOAT3(rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
+        };
+        if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
+            return -1;
+        }
+
+        D3D11_SetPixelShader(
+            renderer,
+            rendererData->colorPixelShader.Get(),
+            nullptr,
+            nullptr);
+
+        D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
+    }
+
+    return 0;
+}
+
+static int
+D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                 const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    D3D11_RenderStartDrawOp(renderer);
+    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
+
+    float minu = (float) srcrect->x / texture->w;
+    float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
+    float minv = (float) srcrect->y / texture->h;
+    float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
+
+    float r = 1.0f;
+    float g = 1.0f;
+    float b = 1.0f;
+    float a = 1.0f;
+    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
+        r = (float)(texture->r / 255.0f);
+        g = (float)(texture->g / 255.0f);
+        b = (float)(texture->b / 255.0f);
+    }
+    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
+        a = (float)(texture->a / 255.0f);
+    }
+
+    VertexPositionColor vertices[] = {
+        {XMFLOAT3(dstrect->x, dstrect->y, 0.0f),                           XMFLOAT2(minu, minv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f),              XMFLOAT2(minu, maxv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f),              XMFLOAT2(maxu, minv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(r, g, b, a)},
+    };
+    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
+        return -1;
+    }
+
+    D3D11_SetPixelShader(
+        renderer,
+        rendererData->texturePixelShader.Get(),
+        textureData->mainTextureResourceView.Get(),
+        rendererData->mainSampler.Get());
+
+    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
+
+    return 0;
+}
+
+static int
+D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
+                   const SDL_Rect * srcrect, const SDL_FRect * dstrect,
+                   const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
+{
+    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
+    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
+
+    D3D11_RenderStartDrawOp(renderer);
+    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
+
+    float minu = (float) srcrect->x / texture->w;
+    float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
+    float minv = (float) srcrect->y / texture->h;
+    float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
+
+    float r = 1.0f;
+    float g = 1.0f;
+    float b = 1.0f;
+    float a = 1.0f;
+    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
+        r = (float)(texture->r / 255.0f);
+        g = (float)(texture->g / 255.0f);
+        b = (float)(texture->b / 255.0f);
+    }
+    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
+        a = (float)(texture->a / 255.0f);
+    }
+
+    if (flip & SDL_FLIP_HORIZONTAL) {
+        float tmp = maxu;
+        maxu = minu;
+        minu = tmp;
+    }
+    if (flip & SDL_FLIP_VERTICAL) {
+        float tmp = maxv;
+        maxv = minv;
+        minv = tmp;
+    }
+
+    XMFLOAT4X4 oldModelMatrix = rendererData->vertexShaderConstantsData.model;
+    XMStoreFloat4x4(
+        &rendererData->vertexShaderConstantsData.model,
+        XMMatrixMultiply(
+            XMMatrixRotationZ((float)(XM_PI * (float) angle / 180.0f)),
+            XMMatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
+            ));
+
+    const float minx = -center->x;
+    const float maxx = dstrect->w - center->x;
+    const float miny = -center->y;
+    const float maxy = dstrect->h - center->y;
+
+    VertexPositionColor vertices[] = {
+        {XMFLOAT3(minx, miny, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(minx, maxy, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(maxx, miny, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(r, g, b, a)},
+        {XMFLOAT3(maxx, maxy, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(r, g, b, a)},
+    };
+    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
+        return -1;
+    }
+
+    D3D11_SetPixelShader(
+        renderer,
+        rendererData->texturePixelShader.Get(),
+        textureData->mainTextureResourceView.Get(),
+        rendererData->mainSampler.Get());
+
+    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
+
+    rendererData->vertexShaderConstantsData.model = oldModelMatrix;
+
+    return 0;
+}
+
+static int
+D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                       Uint32 format, void * pixels, int pitch)
+{
+    D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
+    HRESULT result = S_OK;
+
+    // Retrieve a pointer to the back buffer:
+    ComPtr<ID3D11Texture2D> backBuffer;
+    result = data->swapChain->GetBuffer(
+        0,
+        __uuidof(ID3D11Texture2D),
+        &backBuffer
+        );
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Get Back Buffer", result);
+        return -1;
+    }
+
+    // Create a staging texture to copy the screen's data to:
+    ComPtr<ID3D11Texture2D> stagingTexture;
+    D3D11_TEXTURE2D_DESC stagingTextureDesc;
+    backBuffer->GetDesc(&stagingTextureDesc);
+    stagingTextureDesc.Width = rect->w;
+    stagingTextureDesc.Height = rect->h;
+    stagingTextureDesc.BindFlags = 0;
+    stagingTextureDesc.MiscFlags = 0;
+    stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+    stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
+    result = data->d3dDevice->CreateTexture2D(
+        &stagingTextureDesc,
+        NULL,
+        &stagingTexture);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Create Staging Texture", result);
+        return -1;
+    }
+
+    // Copy the desired portion of the back buffer to the staging texture:
+    D3D11_BOX srcBox;
+    srcBox.left = rect->x;
+    srcBox.right = rect->x + rect->w;
+    srcBox.top = rect->y;
+    srcBox.bottom = rect->y + rect->h;
+    srcBox.front = 0;
+    srcBox.back = 1;
+    data->d3dContext->CopySubresourceRegion(
+        stagingTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        0, 0, 0,
+        backBuffer.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        &srcBox);
+
+    // Map the staging texture's data to CPU-accessible memory:
+    D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
+    result = data->d3dContext->Map(
+        stagingTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0),
+        D3D11_MAP_READ,
+        0,
+        &textureMemory);
+    if (FAILED(result)) {
+        WIN_SetErrorFromHRESULT(__FUNCTION__ ", Map Staging Texture to CPU Memory", result);
+        return -1;
+    }
+
+    // Copy the data into the desired buffer, converting pixels to the
+    // desired format at the same time:
+    if (SDL_ConvertPixels(
+        rect->w, rect->h,
+        DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
+        textureMemory.pData,
+        textureMemory.RowPitch,
+        format,
+        pixels,
+        pitch) != 0)
+    {
+        // When SDL_ConvertPixels fails, it'll have already set the format.
+        // Get the error message, and attach some extra data to it.
+        std::string errorMessage = string(__FUNCTION__ ", Convert Pixels failed: ") + SDL_GetError();
+        SDL_SetError(errorMessage.c_str());
+        return -1;
+    }
+
+    // Unmap the texture:
+    data->d3dContext->Unmap(
+        stagingTexture.Get(),
+        D3D11CalcSubresource(0, 0, 0));
+
+    // All done.  The staging texture will be cleaned up in it's container
+    // ComPtr<>'s destructor.
+    return 0;
+}
+
+static void
+D3D11_RenderPresent(SDL_Renderer * renderer)
+{
+    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+    // The first argument instructs DXGI to block until VSync, putting the application
+    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
+    // frames that will never be displayed to the screen.
+    HRESULT hr = data->swapChain->Present(1, 0);
+#else
+    // The application may optionally specify "dirty" or "scroll"
+    // rects to improve efficiency in certain scenarios.
+    // This option is not available on Windows Phone 8, to note.
+    DXGI_PRESENT_PARAMETERS parameters = {0};
+    parameters.DirtyRectsCount = 0;
+    parameters.pDirtyRects = nullptr;
+    parameters.pScrollRect = nullptr;
+    parameters.pScrollOffset = nullptr;
+    
+    // The first argument instructs DXGI to block until VSync, putting the application
+    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
+    // frames that will never be displayed to the screen.
+    HRESULT hr = data->swapChain->Present1(1, 0, &parameters);
+#endif
+
+    // Discard the contents of the render target.
+    // This is a valid operation only when the existing contents will be entirely
+    // overwritten. If dirty or scroll rects are used, this call should be removed.
+    data->d3dContext->DiscardView(data->mainRenderTargetView.Get());
+
+    // If the device was removed either by a disconnect or a driver upgrade, we 
+    // must recreate all device resources.
+    //
+    // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines
+    if (hr == DXGI_ERROR_DEVICE_REMOVED)
+    {
+        hr = D3D11_HandleDeviceLost(renderer);
+        if (FAILED(hr)) {
+            WIN_SetErrorFromHRESULT(__FUNCTION__, hr);
+        }
+    }
+    else
+    {
+        WIN_SetErrorFromHRESULT(__FUNCTION__, hr);
+    }
+}
+
+#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 84 - 0
src/render/direct3d11/SDL_render_d3d11_cpp.h

@@ -0,0 +1,84 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#include <D3D11_1.h>
+#include <DirectXMath.h>
+#include <wrl/client.h>
+#include <vector>
+
+struct SDL_VertexShaderConstants
+{
+    DirectX::XMFLOAT4X4 model;
+    DirectX::XMFLOAT4X4 view;
+    DirectX::XMFLOAT4X4 projection;
+};
+
+typedef struct
+{
+    Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice;
+    Microsoft::WRL::ComPtr<ID3D11DeviceContext1> d3dContext;
+    Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain;
+    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> mainRenderTargetView;
+    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> currentOffscreenRenderTargetView;
+    Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout;
+    Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBuffer;
+    Microsoft::WRL::ComPtr<ID3D11VertexShader> vertexShader;
+    Microsoft::WRL::ComPtr<ID3D11PixelShader> texturePixelShader;
+    Microsoft::WRL::ComPtr<ID3D11PixelShader> colorPixelShader;
+    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeBlend;
+    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeAdd;
+    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeMod;
+    Microsoft::WRL::ComPtr<ID3D11SamplerState> mainSampler;
+    Microsoft::WRL::ComPtr<ID3D11RasterizerState> mainRasterizer;
+    D3D_FEATURE_LEVEL featureLevel;
+
+    // Vertex buffer constants:
+    SDL_VertexShaderConstants vertexShaderConstantsData;
+    Microsoft::WRL::ComPtr<ID3D11Buffer> vertexShaderConstants;
+
+    // Cached renderer properties.
+    DirectX::XMFLOAT2 windowSizeInDIPs;
+    DirectX::XMFLOAT2 renderTargetSize;
+    Windows::Graphics::Display::DisplayOrientations orientation;
+
+    // Transform used for display orientation.
+    DirectX::XMFLOAT4X4 orientationTransform3D;
+} D3D11_RenderData;
+
+typedef struct
+{
+    Microsoft::WRL::ComPtr<ID3D11Texture2D> mainTexture;
+    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> mainTextureResourceView;
+    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> mainTextureRenderTargetView;
+    SDL_PixelFormat * pixelFormat;
+    Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
+    DirectX::XMINT2 lockedTexturePosition;
+} D3D11_TextureData;
+
+struct VertexPositionColor
+{
+    DirectX::XMFLOAT3 pos;
+    DirectX::XMFLOAT2 tex;
+    DirectX::XMFLOAT4 color;
+};
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 2 - 0
src/thread/SDL_thread_c.h

@@ -36,6 +36,8 @@
 #include "windows/SDL_systhread_c.h"
 #elif SDL_THREAD_PSP
 #include "psp/SDL_systhread_c.h"
+#elif SDL_THREAD_STDCPP
+#include "stdcpp/SDL_systhread_c.h"
 #else
 #error Need thread implementation for this platform
 #include "generic/SDL_systhread_c.h"

+ 183 - 0
src/thread/stdcpp/SDL_syscond.cpp

@@ -0,0 +1,183 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+extern "C" {
+#include "SDL_thread.h"
+}
+
+#include <chrono>
+#include <condition_variable>
+#include <exception>
+#include <ratio>
+
+#include "SDL_sysmutex_c.h"
+
+struct SDL_cond
+{
+    std::condition_variable_any cpp_cond;
+};
+
+/* Create a condition variable */
+extern "C"
+SDL_cond *
+SDL_CreateCond(void)
+{
+    /* Allocate and initialize the condition variable */
+    try {
+        SDL_cond * cond = new SDL_cond;
+        return cond;
+    } catch (std::exception & ex) {
+        SDL_SetError("unable to create C++ condition variable: %s", ex.what());
+        return NULL;
+    } catch (...) {
+        SDL_SetError("unable to create C++ condition variable due to an unknown exception");
+        return NULL;
+    }
+}
+
+/* Destroy a condition variable */
+extern "C"
+void
+SDL_DestroyCond(SDL_cond * cond)
+{
+    if (cond) {
+        try {
+            delete cond;
+        } catch (...) {
+            // catch any and all exceptions, just in case something happens
+        }
+    }
+}
+
+/* Restart one of the threads that are waiting on the condition variable */
+extern "C"
+int
+SDL_CondSignal(SDL_cond * cond)
+{
+    if (!cond) {
+        SDL_SetError("Passed a NULL condition variable");
+        return -1;
+    }
+
+    try {
+        cond->cpp_cond.notify_one();
+        return 0;
+    } catch (...) {
+        // catch any and all exceptions, just in case something happens
+        SDL_SetError("unable to signal C++ condition variable due to an unknown exception");
+        return -1;
+    }
+}
+
+/* Restart all threads that are waiting on the condition variable */
+extern "C"
+int
+SDL_CondBroadcast(SDL_cond * cond)
+{
+    if (!cond) {
+        SDL_SetError("Passed a NULL condition variable");
+        return -1;
+    }
+
+    try {
+        cond->cpp_cond.notify_all();
+        return 0;
+    } catch (...) {
+        // catch any and all exceptions, just in case something happens
+        SDL_SetError("unable to broadcast C++ condition variable due to an unknown exception");
+        return -1;
+    }
+}
+
+/* Wait on the condition variable for at most 'ms' milliseconds.
+   The mutex must be locked before entering this function!
+   The mutex is unlocked during the wait, and locked again after the wait.
+
+Typical use:
+
+Thread A:
+    SDL_LockMutex(lock);
+    while ( ! condition ) {
+        SDL_CondWait(cond, lock);
+    }
+    SDL_UnlockMutex(lock);
+
+Thread B:
+    SDL_LockMutex(lock);
+    ...
+    condition = true;
+    ...
+    SDL_CondSignal(cond);
+    SDL_UnlockMutex(lock);
+ */
+extern "C"
+int
+SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
+{
+    if (!cond) {
+        SDL_SetError("Passed a NULL condition variable");
+        return -1;
+    }
+
+    if (!mutex) {
+        SDL_SetError("Passed a NULL mutex variable");
+        return -1;
+    }
+
+    try {
+        std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::defer_lock_t());
+        if (ms == SDL_MUTEX_MAXWAIT) {
+            cond->cpp_cond.wait(
+                cpp_lock
+                );
+            cpp_lock.release();
+            return 0;
+        } else {
+            auto wait_result = cond->cpp_cond.wait_for(
+                cpp_lock,
+                std::chrono::duration<Uint32, std::milli>(ms)
+                );
+            cpp_lock.release();
+            if (wait_result == std::cv_status::timeout) {
+                return SDL_MUTEX_TIMEDOUT;
+            } else {
+                return 0;
+            }
+        }
+    } catch (std::exception & ex) {
+        SDL_SetError("unable to wait on C++ condition variable: %s", ex.what());
+        return -1;
+    } catch (...) {
+        SDL_SetError("unable to lock wait on C++ condition variable due to an unknown exception");
+        return -1;
+    }
+}
+
+/* Wait on the condition variable forever */
+extern "C"
+int
+SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
+{
+    return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 113 - 0
src/thread/stdcpp/SDL_sysmutex.cpp

@@ -0,0 +1,113 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+extern "C" {
+#include "SDL_thread.h"
+#include "SDL_systhread_c.h"
+#include "SDL_log.h"
+}
+
+#include <exception>
+
+#include "SDL_sysmutex_c.h"
+#include <Windows.h>
+
+
+/* Create a mutex */
+extern "C"
+SDL_mutex *
+SDL_CreateMutex(void)
+{
+    /* Allocate and initialize the mutex */
+    try {
+        SDL_mutex * mutex = new SDL_mutex;
+        return mutex;
+    } catch (std::exception & ex) {
+        SDL_SetError("unable to create C++ mutex: %s", ex.what());
+        return NULL;
+    } catch (...) {
+        SDL_SetError("unable to create C++ mutex due to an unknown exception");
+        return NULL;
+    }
+}
+
+/* Free the mutex */
+extern "C"
+void
+SDL_DestroyMutex(SDL_mutex * mutex)
+{
+    if (mutex) {
+        try {
+            delete mutex;
+        } catch (...) {
+            // catch any and all exceptions, just in case something happens
+        }
+    }
+}
+
+/* Lock the semaphore */
+extern "C"
+int
+SDL_mutexP(SDL_mutex * mutex)
+{
+    SDL_threadID threadID = SDL_ThreadID();
+    DWORD realThreadID = GetCurrentThreadId();
+    if (mutex == NULL) {
+        SDL_SetError("Passed a NULL mutex");
+        return -1;
+    }
+
+    try {
+        mutex->cpp_mutex.lock();
+        return 0;
+    } catch (std::exception & ex) {
+        SDL_SetError("unable to lock C++ mutex: %s", ex.what());
+        return -1;
+    } catch (...) {
+        SDL_SetError("unable to lock C++ mutex due to an unknown exception");
+        return -1;
+    }
+}
+
+/* Unlock the mutex */
+extern "C"
+int
+SDL_mutexV(SDL_mutex * mutex)
+{
+    SDL_threadID threadID = SDL_ThreadID();
+    DWORD realThreadID = GetCurrentThreadId();
+    if (mutex == NULL) {
+        SDL_SetError("Passed a NULL mutex");
+        return -1;
+    }
+
+    try {
+        mutex->cpp_mutex.unlock();
+        return 0;
+    } catch (...) {
+        // catch any and all exceptions, just in case something happens.
+        SDL_SetError("unable to unlock C++ mutex due to an unknown exception");
+        return -1;
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 30 - 0
src/thread/stdcpp/SDL_sysmutex_c.h

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

+ 124 - 0
src/thread/stdcpp/SDL_systhread.cpp

@@ -0,0 +1,124 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+/* Thread management routines for SDL */
+
+extern "C" {
+#include "SDL_thread.h"
+#include "../SDL_systhread.h"
+#include "../SDL_thread_c.h"
+#include "SDL_log.h"
+}
+
+#include <mutex>
+#include <thread>
+
+// HACK: Mimic C++11's thread_local keyword on Visual C++ 2012 (aka. VC++ 11)
+// TODO: make sure this hack doesn't get used if and when Visual C++ supports
+// the official, 'thread_local' keyword.
+#ifdef _MSC_VER
+#define thread_local __declspec(thread)
+// Documentation for __declspec(thread) can be found online at:
+// http://msdn.microsoft.com/en-us/library/2s9wt68x.aspx
+#endif
+
+static void
+RunThread(void *args)
+{
+    SDL_RunThread(args);
+}
+
+extern "C"
+int
+SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
+{
+    try {
+        std::thread cpp_thread(RunThread, args);
+        thread->handle = (void *) new std::thread(std::move(cpp_thread));
+        return 0;
+    } catch (std::exception & ex) {
+        SDL_SetError("unable to create a C++ thread: %s", ex.what());
+        return -1;
+    } catch (...) {
+        SDL_SetError("unable to create a C++ thread due to an unknown exception");
+        return -1;
+    }
+}
+
+extern "C"
+void
+SDL_SYS_SetupThread(const char *name)
+{
+    // Make sure a thread ID gets assigned ASAP, for debugging purposes:
+    SDL_ThreadID();
+    return;
+}
+
+extern "C"
+SDL_threadID
+SDL_ThreadID(void)
+{
+    static thread_local SDL_threadID current_thread_id = 0;
+    static SDL_threadID next_thread_id = 1;
+    static std::mutex next_thread_id_mutex;
+
+    if (current_thread_id == 0) {
+        std::lock_guard<std::mutex> lock(next_thread_id_mutex);
+        current_thread_id = next_thread_id;
+        ++next_thread_id;
+    }
+
+    return current_thread_id;
+}
+
+extern "C"
+int
+SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
+{
+    // Thread priorities do not look to be settable via C++11's thread
+    // interface, at least as of this writing (Nov 2012).  std::thread does
+    // provide access to the OS' native handle, however, and some form of
+    // priority-setting could, in theory, be done through this interface.
+    return (0);
+}
+
+extern "C"
+void
+SDL_SYS_WaitThread(SDL_Thread * thread)
+{
+    if ( ! thread) {
+        return;
+    }
+
+    try {
+        std::thread * cpp_thread = (std::thread *) thread->handle;
+        if (cpp_thread->joinable()) {
+            cpp_thread->join();
+        }
+    } catch (...) {
+        // Catch any exceptions, just in case.
+        // Report nothing, as SDL_WaitThread does not seem to offer a means
+        // to report errors to its callers.
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 26 - 0
src/thread/stdcpp/SDL_systhread_c.h

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

+ 3 - 0
src/video/SDL_sysvideo.h

@@ -343,6 +343,9 @@ extern VideoBootStrap DirectFB_bootstrap;
 #if SDL_VIDEO_DRIVER_WINDOWS
 extern VideoBootStrap WINDOWS_bootstrap;
 #endif
+#if SDL_VIDEO_DRIVER_WINRT
+extern VideoBootStrap WINRT_bootstrap;
+#endif
 #if SDL_VIDEO_DRIVER_BWINDOW
 extern VideoBootStrap BWINDOW_bootstrap;
 #endif

+ 3 - 0
src/video/SDL_video.c

@@ -64,6 +64,9 @@ static VideoBootStrap *bootstrap[] = {
 #if SDL_VIDEO_DRIVER_WINDOWS
     &WINDOWS_bootstrap,
 #endif
+#if SDL_VIDEO_DRIVER_WINRT
+    &WINRT_bootstrap,
+#endif
 #if SDL_VIDEO_DRIVER_BWINDOW
     &BWINDOW_bootstrap,
 #endif

+ 3 - 1
src/video/uikit/SDL_uikitwindow.m

@@ -202,7 +202,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
     if (external) {
         [uiwindow setScreen:data->uiscreen];
     }
-
+    
     if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
         [uiwindow release];
         return -1;
@@ -301,10 +301,12 @@ SDL_bool
 UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
 {
     UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+    UIViewController *uiviewcontroller = ((SDL_WindowData *) window->driverdata)->viewcontroller;
 
     if (info->version.major <= SDL_MAJOR_VERSION) {
         info->subsystem = SDL_SYSWM_UIKIT;
         info->info.uikit.window = uiwindow;
+        info->info.uikit.viewcontroller = uiviewcontroller;
         return SDL_TRUE;
     } else {
         SDL_SetError("Application not compiled with SDL %d.%d\n",

+ 978 - 0
src/video/windowsrt/SDL_WinRTApp.cpp

@@ -0,0 +1,978 @@
+
+#include <string>
+#include <unordered_map>
+#include <sstream>
+
+#include "ppltasks.h"
+
+extern "C" {
+#include "SDL_assert.h"
+#include "SDL_events.h"
+#include "SDL_hints.h"
+#include "SDL_log.h"
+#include "SDL_stdinc.h"
+#include "SDL_render.h"
+#include "../SDL_sysvideo.h"
+#include "../../SDL_hints_c.h"
+#include "../../events/scancodes_windows.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_windowevents_c.h"
+#include "../../render/SDL_sysrender.h"
+}
+
+#include "SDL_winrtvideo.h"
+#include "SDL_WinRTApp.h"
+
+using namespace concurrency;
+using namespace std;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::Devices::Input;
+using namespace Windows::Graphics::Display;
+using namespace Windows::Foundation;
+using namespace Windows::System;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+
+// Compile-time debugging options:
+// To enable, uncomment; to disable, comment them out.
+//#define LOG_POINTER_EVENTS 1
+//#define LOG_WINDOW_EVENTS 1
+//#define LOG_ORIENTATION_EVENTS 1
+
+
+// HACK, DLudwig: The C-style main() will get loaded via the app's
+// WinRT-styled main(), which is part of SDLmain_for_WinRT.cpp.
+// This seems wrong on some level, but does seem to work.
+typedef int (*SDL_WinRT_MainFunction)(int, char **);
+static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr;
+
+// HACK, DLudwig: record a reference to the global, Windows RT 'app'/view.
+// SDL/WinRT will use this throughout its code.
+//
+// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
+// non-global, such as something created inside
+// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
+// SDL_CreateWindow().
+SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
+
+ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
+};
+
+IFrameworkView^ SDLApplicationSource::CreateView()
+{
+    // TODO, WinRT: see if this function (CreateView) can ever get called
+    // more than once.  For now, just prevent it from ever assigning
+    // SDL_WinRTGlobalApp more than once.
+    SDL_assert(!SDL_WinRTGlobalApp);
+    SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
+    if (!SDL_WinRTGlobalApp)
+    {
+        SDL_WinRTGlobalApp = app;
+    }
+    return app;
+}
+
+__declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction)
+{
+    SDL_WinRT_main = mainFunction;
+    auto direct3DApplicationSource = ref new SDLApplicationSource();
+    CoreApplication::Run(direct3DApplicationSource);
+    return 0;
+}
+
+static void WINRT_SetDisplayOrientationsPreference(const char *name, const char *oldValue, const char *newValue)
+{
+    SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
+
+    // Start with no orientation flags, then add each in as they're parsed
+    // from newValue.
+    unsigned int orientationFlags = 0;
+    std::istringstream tokenizer(newValue);
+    while (!tokenizer.eof()) {
+        std::string orientationName;
+        std::getline(tokenizer, orientationName, ' ');
+        if (orientationName == "LandscapeLeft") {
+            orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
+        } else if (orientationName == "LandscapeRight") {
+            orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
+        } else if (orientationName == "Portrait") {
+            orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
+        } else if (orientationName == "PortraitUpsideDown") {
+            orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
+        }
+    }
+
+    // If no valid orientation flags were specified, use a reasonable set of defaults:
+    if (!orientationFlags) {
+        // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
+        orientationFlags = (unsigned int) ( \
+            DisplayOrientations::Landscape |
+            DisplayOrientations::LandscapeFlipped |
+            DisplayOrientations::Portrait |
+            DisplayOrientations::PortraitFlipped);
+    }
+
+    // Set the orientation/rotation preferences.  Please note that this does
+    // not constitute a 100%-certain lock of a given set of possible
+    // orientations.  According to Microsoft's documentation on Windows RT [1]
+    // when a device is not capable of being rotated, Windows may ignore
+    // the orientation preferences, and stick to what the device is capable of
+    // displaying.
+    //
+    // [1] Documentation on the 'InitialRotationPreference' setting for a
+    // Windows app's manifest file describes how some orientation/rotation
+    // preferences may be ignored.  See
+    // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
+    // for details.  Microsoft's "Display orientation sample" also gives an
+    // outline of how Windows treats device rotation
+    // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
+    DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
+}
+
+SDL_WinRTApp::SDL_WinRTApp() :
+    m_windowClosed(false),
+    m_windowVisible(true),
+    m_sdlWindowData(NULL),
+    m_sdlVideoDevice(NULL),
+    m_useRelativeMouseMode(false)
+{
+}
+
+void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
+{
+    applicationView->Activated +=
+        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnActivated);
+
+    CoreApplication::Suspending +=
+        ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);
+
+    CoreApplication::Resuming +=
+        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);
+
+    DisplayProperties::OrientationChanged +=
+        ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
+
+    // Register the hint, SDL_HINT_ORIENTATIONS, with SDL.  This needs to be
+    // done before the hint's callback is registered (as of Feb 22, 2013),
+    // otherwise the hint callback won't get registered.
+    //
+    // WinRT, TODO: 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.
+    SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown");
+    SDL_RegisterHintChangedCb(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference);
+}
+
+void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
+{
+#if LOG_ORIENTATION_EVENTS==1
+    CoreWindow^ window = CoreWindow::GetForCurrentThread();
+    if (window) {
+        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Size={%f,%f}\n",
+            __FUNCTION__,
+            (int)DisplayProperties::CurrentOrientation,
+            (int)DisplayProperties::NativeOrientation,
+            (int)DisplayProperties::AutoRotationPreferences,
+            window->Bounds.Width,
+            window->Bounds.Height);
+    } else {
+        SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
+            __FUNCTION__,
+            (int)DisplayProperties::CurrentOrientation,
+            (int)DisplayProperties::NativeOrientation,
+            (int)DisplayProperties::AutoRotationPreferences);
+    }
+#endif
+}
+
+void SDL_WinRTApp::SetWindow(CoreWindow^ window)
+{
+#if LOG_WINDOW_EVENTS==1
+    SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window Size={%f,%f}\n",
+        __FUNCTION__,
+        (int)DisplayProperties::CurrentOrientation,
+        (int)DisplayProperties::NativeOrientation,
+        (int)DisplayProperties::AutoRotationPreferences,
+        window->Bounds.Width,
+        window->Bounds.Height);
+#endif
+
+    window->SizeChanged += 
+        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);
+
+    window->VisibilityChanged +=
+        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);
+
+    window->Closed += 
+        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
+#endif
+
+    window->PointerPressed +=
+        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);
+
+    window->PointerReleased +=
+        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);
+
+    window->PointerWheelChanged +=
+        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);
+
+    window->PointerMoved +=
+        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+    // Retrieves relative-only mouse movements:
+    Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
+        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
+#endif
+
+    window->KeyDown +=
+        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
+
+    window->KeyUp +=
+        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
+}
+
+void SDL_WinRTApp::Load(Platform::String^ entryPoint)
+{
+}
+
+void SDL_WinRTApp::Run()
+{
+    if (SDL_WinRT_main)
+    {
+        // TODO, WinRT: pass the C-style main() a reasonably realistic
+        // representation of command line arguments.
+        int argc = 0;
+        char **argv = NULL;
+        SDL_WinRT_main(argc, argv);
+    }
+}
+
+void SDL_WinRTApp::PumpEvents()
+{
+    if (!m_windowClosed)
+    {
+        if (m_windowVisible)
+        {
+            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+        }
+        else
+        {
+            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+        }
+    }
+}
+
+void SDL_WinRTApp::Uninitialize()
+{
+}
+
+void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+#if LOG_WINDOW_EVENTS==1
+    SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, m_sdlWindowData?=%s\n",
+        __FUNCTION__,
+        args->Size.Width, args->Size.Height,
+        (int)DisplayProperties::CurrentOrientation,
+        (int)DisplayProperties::NativeOrientation,
+        (int)DisplayProperties::AutoRotationPreferences,
+        (m_sdlWindowData ? "yes" : "no"));
+#endif
+
+    if (m_sdlWindowData) {
+        // Make the new window size be the one true fullscreen mode.
+        // This change was done, in part, to allow the Direct3D 11.1 renderer
+        // to receive window-resize events as a device rotates.
+        // Before, rotating a device from landscape, to portrait, and then
+        // back to landscape would cause the Direct3D 11.1 swap buffer to
+        // not get resized appropriately.  SDL would, on the rotation from
+        // landscape to portrait, re-resize the SDL window to it's initial
+        // size (landscape).  On the subsequent rotation, SDL would drop the
+        // window-resize event as it appeared the SDL window didn't change
+        // size, and the Direct3D 11.1 renderer wouldn't resize its swap
+        // chain.
+        //
+        // TODO, WinRT: consider dropping old display modes after the fullscreen window changes size (from rotations, etc.)
+        m_sdlWindowData->sdlWindow->fullscreen_mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
+        SDL_AddDisplayMode(&m_sdlVideoDevice->displays[0], &m_sdlWindowData->sdlWindow->fullscreen_mode);
+
+        // HACK, Feb 19, 2013: SDL_WINDOWEVENT_RESIZED events, when sent,
+        // will attempt to fix the values of the main window's renderer's
+        // viewport.  While this can be good, it does appear to be buggy,
+        // and can cause a fullscreen viewport to become corrupted.  This
+        // behavior was noticed on a Surface RT while rotating the device
+        // from landscape to portrait.  Oddly enough, this did not occur
+        // in the Windows Simulator.
+        //
+        // Backing up, then restoring, the main renderer's 'resized' flag
+        // seems to fix fullscreen viewport problems when rotating a
+        // Windows device.
+        //
+        // Commencing hack in 3... 2... 1...
+        SDL_Renderer * rendererForMainWindow = SDL_GetRenderer(m_sdlWindowData->sdlWindow);
+        // For now, limit the hack to when the Direct3D 11.1 is getting used:
+        const bool usingD3D11Renderer = \
+            (rendererForMainWindow != NULL) &&
+            (SDL_strcmp(rendererForMainWindow->info.name, "direct3d 11.1") == 0);
+        SDL_bool wasD3D11RendererResized = SDL_FALSE;
+        if (usingD3D11Renderer) {
+            wasD3D11RendererResized = rendererForMainWindow->resized;
+        }
+
+        // Send the window-resize event to the rest of SDL, and to apps:
+        const int windowWidth = (int) ceil(args->Size.Width);
+        const int windowHeight = (int) ceil(args->Size.Height);
+        SDL_SendWindowEvent(
+            m_sdlWindowData->sdlWindow,
+            SDL_WINDOWEVENT_RESIZED,
+            windowWidth,
+            windowHeight);
+
+        // Viewport hack, part two:
+        if (usingD3D11Renderer) {
+            rendererForMainWindow->resized = wasD3D11RendererResized;
+        }
+    }
+}
+
+void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+#if LOG_WINDOW_EVENTS==1
+    SDL_Log("%s, visible?=%s, m_sdlWindowData?=%s\n",
+        __FUNCTION__,
+        (args->Visible ? "yes" : "no"),
+        (m_sdlWindowData ? "yes" : "no"));
+#endif
+
+    m_windowVisible = args->Visible;
+    if (m_sdlWindowData) {
+        SDL_bool wasSDLWindowSurfaceValid = m_sdlWindowData->sdlWindow->surface_valid;
+
+        if (args->Visible) {
+            SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
+        } else {
+            SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+        }
+
+        // HACK: Prevent SDL's window-hide handling code, which currently
+        // triggers a fake window resize (possibly erronously), from
+        // marking the SDL window's surface as invalid.
+        //
+        // A better solution to this probably involves figuring out if the
+        // fake window resize can be prevented.
+        m_sdlWindowData->sdlWindow->surface_valid = wasSDLWindowSurfaceValid;
+    }
+}
+
+void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+#if LOG_WINDOW_EVENTS==1
+    SDL_Log("%s\n", __FUNCTION__);
+#endif
+    m_windowClosed = true;
+}
+
+static Uint8
+WINRT_GetSDLButtonForPointerPoint(PointerPoint ^ pt)
+{
+    switch (pt->Properties->PointerUpdateKind)
+    {
+        case PointerUpdateKind::LeftButtonPressed:
+        case PointerUpdateKind::LeftButtonReleased:
+            return SDL_BUTTON_LEFT;
+
+        case PointerUpdateKind::RightButtonPressed:
+        case PointerUpdateKind::RightButtonReleased:
+            return SDL_BUTTON_RIGHT;
+
+        case PointerUpdateKind::MiddleButtonPressed:
+        case PointerUpdateKind::MiddleButtonReleased:
+            return SDL_BUTTON_MIDDLE;
+
+        case PointerUpdateKind::XButton1Pressed:
+        case PointerUpdateKind::XButton1Released:
+            return SDL_BUTTON_X1;
+
+        case PointerUpdateKind::XButton2Pressed:
+        case PointerUpdateKind::XButton2Released:
+            return SDL_BUTTON_X2;
+
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static const char *
+WINRT_ConvertPointerUpdateKindToString(PointerUpdateKind kind)
+{
+    switch (kind)
+    {
+        case PointerUpdateKind::Other:
+            return "Other";
+        case PointerUpdateKind::LeftButtonPressed:
+            return "LeftButtonPressed";
+        case PointerUpdateKind::LeftButtonReleased:
+            return "LeftButtonReleased";
+        case PointerUpdateKind::RightButtonPressed:
+            return "RightButtonPressed";
+        case PointerUpdateKind::RightButtonReleased:
+            return "RightButtonReleased";
+        case PointerUpdateKind::MiddleButtonPressed:
+            return "MiddleButtonPressed";
+        case PointerUpdateKind::MiddleButtonReleased:
+            return "MiddleButtonReleased";
+        case PointerUpdateKind::XButton1Pressed:
+            return "XButton1Pressed";
+        case PointerUpdateKind::XButton1Released:
+            return "XButton1Released";
+        case PointerUpdateKind::XButton2Pressed:
+            return "XButton2Pressed";
+        case PointerUpdateKind::XButton2Released:
+            return "XButton2Released";
+    }
+
+    return "";
+}
+
+static void
+WINRT_LogPointerEvent(const string & header, PointerEventArgs ^ args, Point transformedPoint)
+{
+    PointerPoint ^ pt = args->CurrentPoint;
+    SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n",
+        header.c_str(),
+        pt->Position.X, pt->Position.Y,
+        transformedPoint.X, transformedPoint.Y,
+        pt->Properties->MouseWheelDelta,
+        pt->FrameId,
+        pt->PointerId,
+        WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind));
+}
+
+void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
+{
+#if LOG_POINTER_EVENTS
+    WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position));
+#endif
+
+    if (m_sdlWindowData) {
+        Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint);
+        if (button) {
+            SDL_SendMouseButton(m_sdlWindowData->sdlWindow, 0, SDL_PRESSED, button);
+        }
+    }
+}
+
+void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
+{
+#if LOG_POINTER_EVENTS
+    WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position));
+#endif
+
+    if (m_sdlWindowData) {
+        Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint);
+        if (button) {
+            SDL_SendMouseButton(m_sdlWindowData->sdlWindow, 0, SDL_RELEASED, button);
+        }
+    }
+}
+
+void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
+{
+#if LOG_POINTER_EVENTS
+    WINRT_LogPointerEvent("wheel changed", args, TransformCursor(args->CurrentPoint->Position));
+#endif
+
+    if (m_sdlWindowData) {
+        // FIXME: This may need to accumulate deltas up to WHEEL_DELTA
+        short motion = args->CurrentPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
+        SDL_SendMouseWheel(m_sdlWindowData->sdlWindow, 0, 0, motion);
+    }
+}
+
+static inline int _lround(float arg) {
+    if (arg >= 0.0f) {
+        return (int)floor(arg + 0.5f);
+    } else {
+        return (int)ceil(arg - 0.5f);
+    }
+}
+
+void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
+{
+    if (m_sdlWindowData && m_useRelativeMouseMode) {
+        // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
+        // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
+        // MouseDelta field often reports very large values.  More information
+        // on this can be found at the following pages on MSDN:
+        //  - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
+        //  - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
+        //
+        // The values do not appear to be as large when running on some systems,
+        // most notably a Surface RT.  Furthermore, the values returned by
+        // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
+        // method, do not ever appear to be large, even when MouseEventArgs'
+        // MouseDelta is reporting to the contrary.
+        //
+        // On systems with the large-values behavior, it appears that the values
+        // get reported as if the screen's size is 65536 units in both the X and Y
+        // dimensions.  This can be viewed by using Windows' now-private, "Raw Input"
+        // APIs.  (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
+        //
+        // MSDN's documentation on MouseEventArgs' MouseDelta field (at
+        // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
+        // does not seem to indicate (to me) that its values should be so large.  It
+        // says that its values should be a "change in screen location".  I could
+        // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see: 
+        // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
+        // indicates that these values are in DIPs, which is the same unit used
+        // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
+        // property.  See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
+        // for details.)
+        //
+        // To note, PointerMoved events are sent a 'RawPosition' value (via the
+        // CurrentPoint property in MouseEventArgs), however these do not seem
+        // to exhibit the same large-value behavior.
+        //
+        // The values passed via PointerMoved events can't always be used for relative
+        // mouse motion, unfortunately.  Its values are bound to the cursor's position,
+        // which stops when it hits one of the screen's edges.  This can be a problem in
+        // first person shooters, whereby it is normal for mouse motion to travel far
+        // along any one axis for a period of time.  MouseMoved events do not have the
+        // screen-bounding limitation, and can be used regardless of where the system's
+        // cursor is.
+        //
+        // One possible workaround would be to programmatically set the cursor's
+        // position to the screen's center (when SDL's relative mouse mode is enabled),
+        // however Windows RT does not yet seem to have the ability to set the cursor's
+        // position via a public API.  Win32 did this via an API call, SetCursorPos,
+        // however WinRT makes this function be private.  Apps that use it won't get
+        // approved for distribution in the Windows Store.  I've yet to be able to find
+        // a suitable, store-friendly counterpart for WinRT.
+        //
+        // There may be some room for a workaround whereby OnPointerMoved's values
+        // are compared to the values from OnMouseMoved in order to detect
+        // when this bug is active.  A suitable transformation could then be made to
+        // OnMouseMoved's values.  For now, however, the system-reported values are sent
+        // to SDL with minimal transformation: from native screen coordinates (in DIPs)
+        // to SDL window coordinates.
+        //
+        const Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
+        const Point mouseDeltaInSDLWindowCoords = TransformCursor(mouseDeltaInDIPs);
+        SDL_SendMouseMotion(
+            m_sdlWindowData->sdlWindow,
+            0,
+            1,
+            _lround(mouseDeltaInSDLWindowCoords.X),
+            _lround(mouseDeltaInSDLWindowCoords.Y));
+    }
+}
+
+// Applies necessary geometric transformations to raw cursor positions:
+Point SDL_WinRTApp::TransformCursor(Point rawPosition)
+{
+    if ( ! m_sdlWindowData || ! m_sdlWindowData->sdlWindow ) {
+        return rawPosition;
+    }
+    CoreWindow ^ nativeWindow = CoreWindow::GetForCurrentThread();
+    Point outputPosition;
+    outputPosition.X = rawPosition.X * (((float32)m_sdlWindowData->sdlWindow->w) / nativeWindow->Bounds.Width);
+    outputPosition.Y = rawPosition.Y * (((float32)m_sdlWindowData->sdlWindow->h) / nativeWindow->Bounds.Height);
+    return outputPosition;
+}
+
+void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
+{
+#if LOG_POINTER_EVENTS
+    WINRT_LogPointerEvent("pointer moved", args, TransformCursor(args->CurrentPoint->Position));
+#endif
+
+    if (m_sdlWindowData && ! m_useRelativeMouseMode)
+    {
+        Point transformedPoint = TransformCursor(args->CurrentPoint->Position);
+        SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
+    }
+}
+
+static SDL_Scancode WinRT_Official_Keycodes[] = {
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.None -- 0
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftButton -- 1
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.RightButton -- 2
+    SDL_SCANCODE_CANCEL, // VirtualKey.Cancel -- 3
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.MiddleButton -- 4
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton1 -- 5
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton2 -- 6
+    SDL_SCANCODE_UNKNOWN, // -- 7
+    SDL_SCANCODE_BACKSPACE, // VirtualKey.Back -- 8
+    SDL_SCANCODE_TAB, // VirtualKey.Tab -- 9
+    SDL_SCANCODE_UNKNOWN, // -- 10
+    SDL_SCANCODE_UNKNOWN, // -- 11
+    SDL_SCANCODE_CLEAR, // VirtualKey.Clear -- 12
+    SDL_SCANCODE_RETURN, // VirtualKey.Enter -- 13
+    SDL_SCANCODE_UNKNOWN, // -- 14
+    SDL_SCANCODE_UNKNOWN, // -- 15
+    SDL_SCANCODE_LSHIFT, // VirtualKey.Shift -- 16
+    SDL_SCANCODE_LCTRL, // VirtualKey.Control -- 17
+    SDL_SCANCODE_MENU, // VirtualKey.Menu -- 18
+    SDL_SCANCODE_PAUSE, // VirtualKey.Pause -- 19
+    SDL_SCANCODE_CAPSLOCK, // VirtualKey.CapitalLock -- 20
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Kana or VirtualKey.Hangul -- 21
+    SDL_SCANCODE_UNKNOWN, // -- 22
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Junja -- 23
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Final -- 24
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Hanja or VirtualKey.Kanji -- 25
+    SDL_SCANCODE_UNKNOWN, // -- 26
+    SDL_SCANCODE_ESCAPE, // VirtualKey.Escape -- 27
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Convert -- 28
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.NonConvert -- 29
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Accept -- 30
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.ModeChange -- 31  (maybe SDL_SCANCODE_MODE ?)
+    SDL_SCANCODE_SPACE, // VirtualKey.Space -- 32
+    SDL_SCANCODE_PAGEUP, // VirtualKey.PageUp -- 33
+    SDL_SCANCODE_PAGEDOWN, // VirtualKey.PageDown -- 34
+    SDL_SCANCODE_END, // VirtualKey.End -- 35
+    SDL_SCANCODE_HOME, // VirtualKey.Home -- 36
+    SDL_SCANCODE_LEFT, // VirtualKey.Left -- 37
+    SDL_SCANCODE_UP, // VirtualKey.Up -- 38
+    SDL_SCANCODE_RIGHT, // VirtualKey.Right -- 39
+    SDL_SCANCODE_DOWN, // VirtualKey.Down -- 40
+    SDL_SCANCODE_SELECT, // VirtualKey.Select -- 41
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Print -- 42  (maybe SDL_SCANCODE_PRINTSCREEN ?)
+    SDL_SCANCODE_EXECUTE, // VirtualKey.Execute -- 43
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Snapshot -- 44
+    SDL_SCANCODE_INSERT, // VirtualKey.Insert -- 45
+    SDL_SCANCODE_DELETE, // VirtualKey.Delete -- 46
+    SDL_SCANCODE_HELP, // VirtualKey.Help -- 47
+    SDL_SCANCODE_0, // VirtualKey.Number0 -- 48
+    SDL_SCANCODE_1, // VirtualKey.Number1 -- 49
+    SDL_SCANCODE_2, // VirtualKey.Number2 -- 50
+    SDL_SCANCODE_3, // VirtualKey.Number3 -- 51
+    SDL_SCANCODE_4, // VirtualKey.Number4 -- 52
+    SDL_SCANCODE_5, // VirtualKey.Number5 -- 53
+    SDL_SCANCODE_6, // VirtualKey.Number6 -- 54
+    SDL_SCANCODE_7, // VirtualKey.Number7 -- 55
+    SDL_SCANCODE_8, // VirtualKey.Number8 -- 56
+    SDL_SCANCODE_9, // VirtualKey.Number9 -- 57
+    SDL_SCANCODE_UNKNOWN, // -- 58
+    SDL_SCANCODE_UNKNOWN, // -- 59
+    SDL_SCANCODE_UNKNOWN, // -- 60
+    SDL_SCANCODE_UNKNOWN, // -- 61
+    SDL_SCANCODE_UNKNOWN, // -- 62
+    SDL_SCANCODE_UNKNOWN, // -- 63
+    SDL_SCANCODE_UNKNOWN, // -- 64
+    SDL_SCANCODE_A, // VirtualKey.A -- 65
+    SDL_SCANCODE_B, // VirtualKey.B -- 66
+    SDL_SCANCODE_C, // VirtualKey.C -- 67
+    SDL_SCANCODE_D, // VirtualKey.D -- 68
+    SDL_SCANCODE_E, // VirtualKey.E -- 69
+    SDL_SCANCODE_F, // VirtualKey.F -- 70
+    SDL_SCANCODE_G, // VirtualKey.G -- 71
+    SDL_SCANCODE_H, // VirtualKey.H -- 72
+    SDL_SCANCODE_I, // VirtualKey.I -- 73
+    SDL_SCANCODE_J, // VirtualKey.J -- 74
+    SDL_SCANCODE_K, // VirtualKey.K -- 75
+    SDL_SCANCODE_L, // VirtualKey.L -- 76
+    SDL_SCANCODE_M, // VirtualKey.M -- 77
+    SDL_SCANCODE_N, // VirtualKey.N -- 78
+    SDL_SCANCODE_O, // VirtualKey.O -- 79
+    SDL_SCANCODE_P, // VirtualKey.P -- 80
+    SDL_SCANCODE_Q, // VirtualKey.Q -- 81
+    SDL_SCANCODE_R, // VirtualKey.R -- 82
+    SDL_SCANCODE_S, // VirtualKey.S -- 83
+    SDL_SCANCODE_T, // VirtualKey.T -- 84
+    SDL_SCANCODE_U, // VirtualKey.U -- 85
+    SDL_SCANCODE_V, // VirtualKey.V -- 86
+    SDL_SCANCODE_W, // VirtualKey.W -- 87
+    SDL_SCANCODE_X, // VirtualKey.X -- 88
+    SDL_SCANCODE_Y, // VirtualKey.Y -- 89
+    SDL_SCANCODE_Z, // VirtualKey.Z -- 90
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftWindows -- 91  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?)
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.RightWindows -- 92  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?)
+    SDL_SCANCODE_APPLICATION, // VirtualKey.Application -- 93
+    SDL_SCANCODE_UNKNOWN, // -- 94
+    SDL_SCANCODE_SLEEP, // VirtualKey.Sleep -- 95
+    SDL_SCANCODE_KP_0, // VirtualKey.NumberPad0 -- 96
+    SDL_SCANCODE_KP_1, // VirtualKey.NumberPad1 -- 97
+    SDL_SCANCODE_KP_2, // VirtualKey.NumberPad2 -- 98
+    SDL_SCANCODE_KP_3, // VirtualKey.NumberPad3 -- 99
+    SDL_SCANCODE_KP_4, // VirtualKey.NumberPad4 -- 100
+    SDL_SCANCODE_KP_5, // VirtualKey.NumberPad5 -- 101
+    SDL_SCANCODE_KP_6, // VirtualKey.NumberPad6 -- 102
+    SDL_SCANCODE_KP_7, // VirtualKey.NumberPad7 -- 103
+    SDL_SCANCODE_KP_8, // VirtualKey.NumberPad8 -- 104
+    SDL_SCANCODE_KP_9, // VirtualKey.NumberPad9 -- 105
+    SDL_SCANCODE_KP_MULTIPLY, // VirtualKey.Multiply -- 106
+    SDL_SCANCODE_KP_PLUS, // VirtualKey.Add -- 107
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Separator -- 108
+    SDL_SCANCODE_KP_MINUS, // VirtualKey.Subtract -- 109
+    SDL_SCANCODE_UNKNOWN, // VirtualKey.Decimal -- 110  (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?)
+    SDL_SCANCODE_KP_DIVIDE, // VirtualKey.Divide -- 111
+    SDL_SCANCODE_F1, // VirtualKey.F1 -- 112
+    SDL_SCANCODE_F2, // VirtualKey.F2 -- 113
+    SDL_SCANCODE_F3, // VirtualKey.F3 -- 114
+    SDL_SCANCODE_F4, // VirtualKey.F4 -- 115
+    SDL_SCANCODE_F5, // VirtualKey.F5 -- 116
+    SDL_SCANCODE_F6, // VirtualKey.F6 -- 117
+    SDL_SCANCODE_F7, // VirtualKey.F7 -- 118
+    SDL_SCANCODE_F8, // VirtualKey.F8 -- 119
+    SDL_SCANCODE_F9, // VirtualKey.F9 -- 120
+    SDL_SCANCODE_F10, // VirtualKey.F10 -- 121
+    SDL_SCANCODE_F11, // VirtualKey.F11 -- 122
+    SDL_SCANCODE_F12, // VirtualKey.F12 -- 123
+    SDL_SCANCODE_F13, // VirtualKey.F13 -- 124
+    SDL_SCANCODE_F14, // VirtualKey.F14 -- 125
+    SDL_SCANCODE_F15, // VirtualKey.F15 -- 126
+    SDL_SCANCODE_F16, // VirtualKey.F16 -- 127
+    SDL_SCANCODE_F17, // VirtualKey.F17 -- 128
+    SDL_SCANCODE_F18, // VirtualKey.F18 -- 129
+    SDL_SCANCODE_F19, // VirtualKey.F19 -- 130
+    SDL_SCANCODE_F20, // VirtualKey.F20 -- 131
+    SDL_SCANCODE_F21, // VirtualKey.F21 -- 132
+    SDL_SCANCODE_F22, // VirtualKey.F22 -- 133
+    SDL_SCANCODE_F23, // VirtualKey.F23 -- 134
+    SDL_SCANCODE_F24, // VirtualKey.F24 -- 135
+    SDL_SCANCODE_UNKNOWN, // -- 136
+    SDL_SCANCODE_UNKNOWN, // -- 137
+    SDL_SCANCODE_UNKNOWN, // -- 138
+    SDL_SCANCODE_UNKNOWN, // -- 139
+    SDL_SCANCODE_UNKNOWN, // -- 140
+    SDL_SCANCODE_UNKNOWN, // -- 141
+    SDL_SCANCODE_UNKNOWN, // -- 142
+    SDL_SCANCODE_UNKNOWN, // -- 143
+    SDL_SCANCODE_NUMLOCKCLEAR, // VirtualKey.NumberKeyLock -- 144
+    SDL_SCANCODE_SCROLLLOCK, // VirtualKey.Scroll -- 145
+    SDL_SCANCODE_UNKNOWN, // -- 146
+    SDL_SCANCODE_UNKNOWN, // -- 147
+    SDL_SCANCODE_UNKNOWN, // -- 148
+    SDL_SCANCODE_UNKNOWN, // -- 149
+    SDL_SCANCODE_UNKNOWN, // -- 150
+    SDL_SCANCODE_UNKNOWN, // -- 151
+    SDL_SCANCODE_UNKNOWN, // -- 152
+    SDL_SCANCODE_UNKNOWN, // -- 153
+    SDL_SCANCODE_UNKNOWN, // -- 154
+    SDL_SCANCODE_UNKNOWN, // -- 155
+    SDL_SCANCODE_UNKNOWN, // -- 156
+    SDL_SCANCODE_UNKNOWN, // -- 157
+    SDL_SCANCODE_UNKNOWN, // -- 158
+    SDL_SCANCODE_UNKNOWN, // -- 159
+    SDL_SCANCODE_LSHIFT, // VirtualKey.LeftShift -- 160
+    SDL_SCANCODE_RSHIFT, // VirtualKey.RightShift -- 161
+    SDL_SCANCODE_LCTRL, // VirtualKey.LeftControl -- 162
+    SDL_SCANCODE_RCTRL, // VirtualKey.RightControl -- 163
+    SDL_SCANCODE_MENU, // VirtualKey.LeftMenu -- 164
+    SDL_SCANCODE_MENU, // VirtualKey.RightMenu -- 165
+};
+
+static std::unordered_map<int, SDL_Scancode> WinRT_Unofficial_Keycodes;
+
+static SDL_Scancode
+TranslateKeycode(int keycode)
+{
+    if (WinRT_Unofficial_Keycodes.empty()) {
+        /* Set up a table of undocumented (by Microsoft), WinRT-specific,
+           key codes: */
+        // TODO, WinRT: move content declarations of WinRT_Unofficial_Keycodes into a C++11 initializer list, when possible
+        WinRT_Unofficial_Keycodes[220] = SDL_SCANCODE_GRAVE;
+        WinRT_Unofficial_Keycodes[222] = SDL_SCANCODE_BACKSLASH;
+    }
+
+    /* Try to get a documented, WinRT, 'VirtualKey' first (as documented at
+       http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
+       If that fails, fall back to a Win32 virtual key.
+    */
+    // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints
+    //SDL_Log("WinRT TranslateKeycode, keycode=%d\n", (int)keycode);
+    SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
+    if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
+        scancode = WinRT_Official_Keycodes[keycode];
+    }
+    if (scancode == SDL_SCANCODE_UNKNOWN) {
+        if (WinRT_Unofficial_Keycodes.find(keycode) != WinRT_Unofficial_Keycodes.end()) {
+            scancode = WinRT_Unofficial_Keycodes[keycode];
+        }
+    }
+    if (scancode == SDL_SCANCODE_UNKNOWN) {
+        if (keycode < SDL_arraysize(windows_scancode_table)) {
+            scancode = windows_scancode_table[keycode];
+        }
+    }
+    if (scancode == SDL_SCANCODE_UNKNOWN) {
+        SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
+    }
+    return scancode;
+}
+
+void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
+{
+    SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey);
+#if 0
+    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
+    SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, native scan code=%d, was down?=%s, vkey=%d, sdl scan code=%d (%s), sdl key code=%d (%s)\n",
+        (args->Handled ? "1" : "0"),
+        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
+        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
+        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
+        args->KeyStatus.RepeatCount,
+        args->KeyStatus.ScanCode,
+        (args->KeyStatus.WasKeyDown ? "1" : "0"),
+        args->VirtualKey,
+        sdlScancode,
+        SDL_GetScancodeName(sdlScancode),
+        keycode,
+        SDL_GetKeyName(keycode));
+    //args->Handled = true;
+    //VirtualKey vkey = args->VirtualKey;
+#endif
+    SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
+}
+
+void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
+{
+    SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey);
+#if 0
+    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
+    SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, native scan code=%d, was down?=%s, vkey=%d, sdl scan code=%d (%s), sdl key code=%d (%s)\n",
+        (args->Handled ? "1" : "0"),
+        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
+        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
+        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
+        args->KeyStatus.RepeatCount,
+        args->KeyStatus.ScanCode,
+        (args->KeyStatus.WasKeyDown ? "1" : "0"),
+        args->VirtualKey,
+        sdlScancode,
+        SDL_GetScancodeName(sdlScancode),
+        keycode,
+        SDL_GetKeyName(keycode));
+    //args->Handled = true;
+#endif
+    SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
+}
+
+void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+    CoreWindow::GetForCurrentThread()->Activate();
+}
+
+static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event)
+{
+    if (event->type == SDL_WINDOWEVENT)
+    {
+        switch (event->window.event)
+        {
+            case SDL_WINDOWEVENT_MINIMIZED:
+            case SDL_WINDOWEVENT_RESTORED:
+                // Return 0 to indicate that the event should be removed from the
+                // event queue:
+                return 0;
+            default:
+                break;
+        }
+    }
+
+    // Return 1 to indicate that the event should stay in the event queue:
+    return 1;
+}
+
+void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
+{
+    // Save app state asynchronously after requesting a deferral. Holding a deferral
+    // indicates that the application is busy performing suspending operations. Be
+    // aware that a deferral may not be held indefinitely. After about five seconds,
+    // the app will be forced to exit.
+    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
+    create_task([this, deferral]()
+    {
+        // Send a window-minimized event immediately to observers.
+        // CoreDispatcher::ProcessEvents, which is the backbone on which
+        // SDL_WinRTApp::PumpEvents is built, will not return to its caller
+        // once it sends out a suspend event.  Any events posted to SDL's
+        // event queue won't get received until the WinRT app is resumed.
+        // SDL_AddEventWatch() may be used to receive app-suspend events on
+        // WinRT.
+        //
+        // In order to prevent app-suspend events from being received twice:
+        // first via a callback passed to SDL_AddEventWatch, and second via
+        // SDL's event queue, the event will be sent to SDL, then immediately
+        // removed from the queue.
+        if (m_sdlWindowData)
+        {
+            SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);   // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
+            SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
+        }
+        deferral->Complete();
+    });
+}
+
+void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
+{
+    // Restore any data or state that was unloaded on suspend. By default, data
+    // and state are persisted when resuming from suspend. Note that this event
+    // does not occur if the app was previously terminated.
+    if (m_sdlWindowData)
+    {
+        SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);    // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently)
+
+        // Remove the app-resume event from the queue, as is done with the
+        // app-suspend event.
+        //
+        // TODO, WinRT: consider posting this event to the queue even though
+        // its counterpart, the app-suspend event, effectively has to be
+        // processed immediately.
+        SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
+    }
+}
+
+SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode()
+{
+    // Create an empty, zeroed-out display mode:
+    SDL_DisplayMode mode;
+    SDL_zero(mode);
+
+    // Fill in most fields:
+    mode.format = SDL_PIXELFORMAT_RGB888;
+    mode.refresh_rate = 0;  // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
+    mode.driverdata = NULL;
+
+    // Calculate the display size given the window size, taking into account
+    // the current display's DPI:
+    const float currentDPI = Windows::Graphics::Display::DisplayProperties::LogicalDpi; 
+    const float dipsPerInch = 96.0f;
+    mode.w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
+    mode.h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
+
+    return mode;
+}
+
+const SDL_WindowData * SDL_WinRTApp::GetSDLWindowData() const
+{
+    return m_sdlWindowData;
+}
+
+bool SDL_WinRTApp::HasSDLWindowData() const
+{
+    return (m_sdlWindowData != NULL);
+}
+
+void SDL_WinRTApp::SetRelativeMouseMode(bool enable)
+{
+    m_useRelativeMouseMode = enable;
+}
+
+void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData * windowData)
+{
+    m_sdlWindowData = windowData;
+}
+
+void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice)
+{
+    m_sdlVideoDevice = videoDevice;
+}

+ 52 - 0
src/video/windowsrt/SDL_WinRTApp.h

@@ -0,0 +1,52 @@
+#pragma once
+
+struct SDL_WindowData;
+
+ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView
+{
+public:
+    SDL_WinRTApp();
+    
+    // IFrameworkView Methods.
+    virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+    virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+    virtual void Load(Platform::String^ entryPoint);
+    virtual void Run();
+    virtual void Uninitialize();
+
+internal:
+    // SDL-specific methods
+    SDL_DisplayMode GetMainDisplayMode();
+    void PumpEvents();
+    const SDL_WindowData * GetSDLWindowData() const;
+    bool HasSDLWindowData() const;
+    void SetRelativeMouseMode(bool enable);
+    void SetSDLWindowData(const SDL_WindowData * windowData);
+    void SetSDLVideoDevice(const SDL_VideoDevice * videoDevice);
+    Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition);
+
+protected:
+    // Event Handlers.
+    void OnOrientationChanged(Platform::Object^ sender);
+    void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+    void OnLogicalDpiChanged(Platform::Object^ sender);
+    void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+    void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
+    void OnResuming(Platform::Object^ sender, Platform::Object^ args);
+    void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+    void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+    void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+    void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+    void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+    void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+    void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
+    void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
+    void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
+
+private:
+    bool m_windowClosed;
+    bool m_windowVisible;
+    const SDL_WindowData* m_sdlWindowData;
+    const SDL_VideoDevice* m_sdlVideoDevice;
+    bool m_useRelativeMouseMode;
+};

+ 41 - 0
src/video/windowsrt/SDL_winrtevents.cpp

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

+ 27 - 0
src/video/windowsrt/SDL_winrtevents_c.h

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

+ 149 - 0
src/video/windowsrt/SDL_winrtmouse.cpp

@@ -0,0 +1,149 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "SDL_config.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern "C" {
+#include "SDL_assert.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../SDL_sysvideo.h"
+}
+
+#include "SDL_WinRTApp.h"
+#include "SDL_winrtmouse.h"
+
+using namespace Windows::UI::Core;
+using Windows::UI::Core::CoreCursor;
+
+extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
+
+
+static SDL_Cursor *
+WINRT_CreateSystemCursor(SDL_SystemCursor id)
+{
+    SDL_Cursor *cursor;
+    CoreCursorType cursorType = CoreCursorType::Arrow;
+
+    switch(id)
+    {
+    default:
+        SDL_assert(0);
+        return NULL;
+    case SDL_SYSTEM_CURSOR_ARROW:     cursorType = CoreCursorType::Arrow; break;
+    case SDL_SYSTEM_CURSOR_IBEAM:     cursorType = CoreCursorType::IBeam; break;
+    case SDL_SYSTEM_CURSOR_WAIT:      cursorType = CoreCursorType::Wait; break;
+    case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break;
+    case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break;
+    case SDL_SYSTEM_CURSOR_SIZENWSE:  cursorType = CoreCursorType::SizeNorthwestSoutheast; break;
+    case SDL_SYSTEM_CURSOR_SIZENESW:  cursorType = CoreCursorType::SizeNortheastSouthwest; break;
+    case SDL_SYSTEM_CURSOR_SIZEWE:    cursorType = CoreCursorType::SizeWestEast; break;
+    case SDL_SYSTEM_CURSOR_SIZENS:    cursorType = CoreCursorType::SizeNorthSouth; break;
+    case SDL_SYSTEM_CURSOR_SIZEALL:   cursorType = CoreCursorType::SizeAll; break;
+    case SDL_SYSTEM_CURSOR_NO:        cursorType = CoreCursorType::UniversalNo; break;
+    case SDL_SYSTEM_CURSOR_HAND:      cursorType = CoreCursorType::Hand; break;
+    }
+
+    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+    if (cursor) {
+        /* Create a pointer to a COM reference to a cursor.  The extra
+           pointer is used (on top of the COM reference) to allow the cursor
+           to be referenced by the SDL_cursor's driverdata field, which is
+           a void pointer.
+        */
+        CoreCursor ^* theCursor = new CoreCursor^(nullptr);
+        *theCursor = ref new CoreCursor(cursorType, 0);
+        cursor->driverdata = (void *) theCursor;
+    } else {
+        SDL_OutOfMemory();
+    }
+
+    return cursor;
+}
+
+static SDL_Cursor *
+WINRT_CreateDefaultCursor()
+{
+    return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
+}
+
+static void
+WINRT_FreeCursor(SDL_Cursor * cursor)
+{
+    if (cursor->driverdata) {
+        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+        *theCursor = nullptr;       // Release the COM reference to the CoreCursor
+        delete theCursor;           // Delete the pointer to the COM reference
+    }
+    SDL_free(cursor);
+}
+
+static int
+WINRT_ShowCursor(SDL_Cursor * cursor)
+{
+    if (cursor) {
+        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+        CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
+    } else {
+        CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
+    }
+    return 0;
+}
+
+static int
+WINRT_SetRelativeMouseMode(SDL_bool enabled)
+{
+    SDL_WinRTGlobalApp->SetRelativeMouseMode(enabled ? true : false);
+    return 0;
+}
+
+void
+WINRT_InitMouse(_THIS)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    /* DLudwig, Dec 3, 2012: Windows RT does not currently provide APIs for
+       the following features, AFAIK:
+        - custom cursors  (multiple system cursors are, however, available)
+        - programmatically moveable cursors
+    */
+
+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+    //mouse->CreateCursor = WINRT_CreateCursor;
+    mouse->CreateSystemCursor = WINRT_CreateSystemCursor;
+    mouse->ShowCursor = WINRT_ShowCursor;
+    mouse->FreeCursor = WINRT_FreeCursor;
+    //mouse->WarpMouse = WINRT_WarpMouse;
+    mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode;
+
+    SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
+#endif
+}
+
+void
+WINRT_QuitMouse(_THIS)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 31 - 0
src/video/windowsrt/SDL_winrtmouse.h

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

+ 262 - 0
src/video/windowsrt/SDL_winrtvideo.cpp

@@ -0,0 +1,262 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* WinRT SDL video driver implementation
+
+   Initial work on this was done by David Ludwig (dludwig@pobox.com), and
+   was based off of SDL's "dummy" video driver.
+ */
+
+extern "C" {
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "../../render/SDL_sysrender.h"
+#include "SDL_syswm.h"
+}
+
+#include "SDL_WinRTApp.h"
+#include "SDL_winrtvideo.h"
+#include "SDL_winrtevents_c.h"
+#include "SDL_winrtmouse.h"
+
+using namespace Windows::UI::Core;
+
+/* On Windows, windows.h defines CreateWindow */
+#ifdef CreateWindow
+#undef CreateWindow
+#endif
+
+extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
+
+#define WINRTVID_DRIVER_NAME "winrt"
+
+/* Initialization/Query functions */
+static int WINRT_VideoInit(_THIS);
+static int WINRT_InitModes(_THIS);
+static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void WINRT_VideoQuit(_THIS);
+
+/* Window functions */
+static int WINRT_CreateWindow(_THIS, SDL_Window * window);
+static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
+static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
+
+/* WinRT driver bootstrap functions */
+
+static int
+WINRT_Available(void)
+{
+    return (1);
+}
+
+static void
+WINRT_DeleteDevice(SDL_VideoDevice * device)
+{
+    SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
+    SDL_free(device);
+}
+
+static SDL_VideoDevice *
+WINRT_CreateDevice(int devindex)
+{
+    SDL_VideoDevice *device;
+
+    /* Initialize all variables that we clean on shutdown */
+    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+    if (!device) {
+        SDL_OutOfMemory();
+        if (device) {
+            SDL_free(device);
+        }
+        return (0);
+    }
+
+    /* Set the function pointers */
+    device->VideoInit = WINRT_VideoInit;
+    device->VideoQuit = WINRT_VideoQuit;
+    device->CreateWindow = WINRT_CreateWindow;
+    device->DestroyWindow = WINRT_DestroyWindow;
+    device->SetDisplayMode = WINRT_SetDisplayMode;
+    device->PumpEvents = WINRT_PumpEvents;
+    //device->CreateWindowFramebuffer = SDL_WINRT_CreateWindowFramebuffer;
+    //device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer;
+    //device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer;
+    device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
+    device->free = WINRT_DeleteDevice;
+
+    SDL_WinRTGlobalApp->SetSDLVideoDevice(device);
+
+    return device;
+}
+
+VideoBootStrap WINRT_bootstrap = {
+    WINRTVID_DRIVER_NAME, "SDL Windows RT video driver",
+    WINRT_Available, WINRT_CreateDevice
+};
+
+int
+WINRT_VideoInit(_THIS)
+{
+    // TODO, WinRT: consider adding a hack to wait (here) for the app's orientation to finish getting set (before the initial display mode is set up)
+
+    if (WINRT_InitModes(_this) < 0) {
+        return -1;
+    }
+    WINRT_InitMouse(_this);
+
+    return 0;
+}
+
+static int
+WINRT_InitModes(_THIS)
+{
+    SDL_DisplayMode mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
+    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+        return -1;
+    }
+
+    SDL_AddDisplayMode(&_this->displays[0], &mode);
+    return 0;
+}
+
+static int
+WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+    return 0;
+}
+
+void
+WINRT_VideoQuit(_THIS)
+{
+    WINRT_QuitMouse(_this);
+}
+
+int
+WINRT_CreateWindow(_THIS, SDL_Window * window)
+{
+    // Make sure that only one window gets created, at least until multimonitor
+    // support is added.
+    if (SDL_WinRTGlobalApp->HasSDLWindowData())
+    {
+        SDL_SetError("WinRT only supports one window");
+        return -1;
+    }
+
+    SDL_WindowData *data = new SDL_WindowData;
+    if (!data) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+    window->driverdata = data;
+    data->sdlWindow = window;
+    data->coreWindow = CoreWindow::GetForCurrentThread();
+
+    /* Make sure the window is considered to be positioned at {0,0},
+       and is considered fullscreen, shown, and the like.
+    */
+    window->x = 0;
+    window->y = 0;
+    window->flags =
+        SDL_WINDOW_FULLSCREEN |
+        SDL_WINDOW_SHOWN |
+        SDL_WINDOW_BORDERLESS |
+        SDL_WINDOW_MAXIMIZED |
+        SDL_WINDOW_INPUT_GRABBED;
+
+    /* HACK from DLudwig: The following line of code prevents
+       SDL_CreateWindow and SDL_UpdateFullscreenMode from trying to resize
+       the window after the call to WINRT_CreateWindow returns.
+       
+       This hack should allow a window to be created in virtually any size,
+       and more importantly, it allows a window's framebuffer, as created and
+       retrieved via SDL_GetWindowSurface, to be in any size.  This can be
+       utilized by apps centered around software rendering, such as ports
+       of older apps.  The app can have SDL create a framebuffer in any size
+       it chooses.  SDL will scale the framebuffer to the native
+       screen size on the GPU (via SDL_UpdateWindowSurface).
+    */
+    _this->displays[0].fullscreen_window = window;
+
+    /* Further prevent any display resizing, and make sure SDL_GetWindowDisplayMode
+       can report the correct size of windows, by creating a new display
+       mode in the requested size.  To note, if the window is being created in
+       the device's native screen size, SDL_AddDisplayMode will do nothing.
+    */
+    window->fullscreen_mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
+    window->fullscreen_mode.w = window->w;
+    window->fullscreen_mode.h = window->h;
+    SDL_AddDisplayMode(&_this->displays[0], &window->fullscreen_mode);
+
+    /* TODO: Consider removing custom display modes in WINRT_DestroyWindow. */
+ 
+    /* Make sure the WinRT app's IFramworkView can post events on
+       behalf of SDL:
+    */
+    SDL_WinRTGlobalApp->SetSDLWindowData(data);
+
+    /* All done! */
+    return 0;
+}
+
+void
+WINRT_DestroyWindow(_THIS, SDL_Window * window)
+{
+    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
+
+    if (SDL_WinRTGlobalApp->HasSDLWindowData() &&
+        SDL_WinRTGlobalApp->GetSDLWindowData()->sdlWindow == window)
+    {
+        SDL_WinRTGlobalApp->SetSDLWindowData(NULL);
+    }
+
+    if (data) {
+        // Delete the internal window data:
+        delete data;
+        data = NULL;
+    }
+}
+
+SDL_bool
+WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+    SDL_WindowData * data = (SDL_WindowData *) window->driverdata;
+
+    if (info->version.major <= SDL_MAJOR_VERSION) {
+        info->subsystem = SDL_SYSWM_WINDOWSRT;
+        info->info.winrt.window = reinterpret_cast<IUnknown *>(data->coreWindow.Get());
+        return SDL_TRUE;
+    } else {
+        SDL_SetError("Application not compiled with SDL %d.%d\n",
+                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+        return SDL_FALSE;
+    }
+    return SDL_FALSE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 40 - 0
src/video/windowsrt/SDL_winrtvideo.h

@@ -0,0 +1,40 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_winrtvideo_h
+#define _SDL_winrtvideo_h
+
+extern "C" {
+#include "../SDL_sysvideo.h"
+}
+
+#include <agile.h>
+
+struct SDL_WindowData
+{
+    SDL_Window *sdlWindow;
+    Platform::Agile<Windows::UI::Core::CoreWindow> coreWindow;
+};
+
+#endif /* _SDL_winrtvideo_h */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 7 - 4
test/loopwave.c

@@ -79,6 +79,7 @@ int
 main(int argc, char *argv[])
 {
     int i;
+    char filename[4096];
 
     /* Load the SDL library */
     if (SDL_Init(SDL_INIT_AUDIO) < 0) {
@@ -86,12 +87,14 @@ main(int argc, char *argv[])
         return (1);
     }
 
-    if (argv[1] == NULL) {
-        argv[1] = "sample.wav";
+    if (argc >= 1) {
+        SDL_strlcpy(filename, argv[1], sizeof(filename));
+    } else {
+        SDL_strlcpy(filename, "sample.wav", sizeof(filename));
     }
     /* Load the wave file into memory */
-    if (SDL_LoadWAV(argv[1], &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
-        fprintf(stderr, "Couldn't load %s: %s\n", argv[1], SDL_GetError());
+    if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
+        fprintf(stderr, "Couldn't load %s: %s\n", filename, SDL_GetError());
         quit(1);
     }