From 850da41f50bce9ad666e887562b320104d5830d2 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Jul 2012 17:44:08 -0400 Subject: [PATCH 001/264] Updated README.iOS to have up-to-date instructions for creating an app from scratch (not from SDL's Xcode templates). --- README.iOS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.iOS b/README.iOS index cf5eb677a..e6c7b9479 100644 --- a/README.iOS +++ b/README.iOS @@ -51,8 +51,9 @@ Here is a more manual method: 1. Create a new iPhone view based application. 2. Build the SDL static libraries (libSDL.a and libSDLSimulator.a) for iPhone and include them in your project. XCode will ignore the library that is not currently of the correct architecture, hence your app will work both on iPhone and in the iPhone Simulator. 3. Include the SDL header files in your project. -4. Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iPhone provides its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iPhone produces its user interface programmatically. -5. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell XCode not to use the project prefix file, as it includes Objective-C code. +4. Remove the AppDelegate.h and AppDelegate.m files -- SDL for iPhone provides its own UIApplicationDelegate. Remove ViewController.h, ViewController.m, and ViewController.xib -- SDL for iPhone produces its user interface programmatically. +5. Make sure your project links to the following, iOS-provided frameworks: OpenGLES.framework, AudioToolbox.framework, and QuartzCore.framework +6. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell XCode not to use the project prefix file, as it includes Objective-C code. ============================================================================== Notes -- Accelerometer as Joystick From fb4a889ee9f1bd42e1410f9edf8f0f2478846bab Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 18 Jul 2012 22:26:47 -0400 Subject: [PATCH 002/264] added UIViewController pointer to SDL_SysWMinfo for iOS --- include/SDL_syswm.h | 2 ++ src/video/uikit/SDL_uikitwindow.m | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 9d5a45e37..a96f42e2d 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -92,6 +92,7 @@ typedef struct _NSWindow NSWindow; #include #else typedef struct _UIWindow UIWindow; +typedef struct _UIViewController UIViewController; #endif #endif @@ -195,6 +196,7 @@ struct SDL_SysWMinfo struct { UIWindow *window; /* The UIKit window */ + UIViewController *viewcontroller; /* The UIKit view controller */ } uikit; #endif /* Can't have an empty union */ diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 632494a79..4b5a4b996 100755 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -267,10 +267,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", From 8215cfb34140b00ec54498c2a8943cdadf183371 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 21 Jul 2012 13:52:20 -0400 Subject: [PATCH 003/264] made Game Center's welcome banner show by having SDL display its inner UIWindow once on SDL window initialization, rather than on every frame --- src/video/uikit/SDL_uikitopengles.m | 3 --- src/video/uikit/SDL_uikitwindow.m | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/uikit/SDL_uikitopengles.m b/src/video/uikit/SDL_uikitopengles.m index f377b2b3c..fddd74d97 100755 --- a/src/video/uikit/SDL_uikitopengles.m +++ b/src/video/uikit/SDL_uikitopengles.m @@ -90,9 +90,6 @@ void UIKit_GL_SwapWindow(_THIS, SDL_Window * window) return; } [data->view swapBuffers]; - /* since now we've got something to draw - make the window visible */ - [data->uiwindow makeKeyAndVisible]; /* we need to let the event cycle run, or the OS won't update the OpenGL view! */ SDL_PumpEvents(); diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 4b5a4b996..e02ce9437 100755 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -200,6 +200,9 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) if (external) { [uiwindow setScreen:data->uiscreen]; } + + // Make sure the native window gets displayed. + [uiwindow makeKeyAndVisible]; if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) { [uiwindow release]; From 8221035d67437f29ea33d33d4235277d841e78bf Mon Sep 17 00:00:00 2001 From: DavidLudwig Date: Mon, 23 Jul 2012 00:10:19 -0400 Subject: [PATCH 004/264] Fix for UIScrollView instances not scrolling properly in iOS apps that don't use SDL_iPhoneSetAnimationCallback --- src/video/uikit/SDL_uikitevents.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index ddd6b3d02..ff08e1533 100755 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -61,6 +61,11 @@ UIKit_PumpEvents(_THIS) do { result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE); } while (result == kCFRunLoopRunHandledSource); + + /* Make sure UIScrollView objects scroll properly. */ + do { + result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, 0, TRUE); + } while(result == kCFRunLoopRunHandledSource); } } From 9e52c42ef37f311c26c34d2d4a3c6f21342af7fe Mon Sep 17 00:00:00 2001 From: DavidLudwig Date: Mon, 23 Jul 2012 00:14:07 -0400 Subject: [PATCH 005/264] Fix for Game Center leaderboard screens not always responding to touch input in iOS apps that don't use SDL_iPhoneSetAnimationCallback --- src/video/uikit/SDL_uikitevents.m | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index ff08e1533..e7f0dcc63 100755 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -57,14 +57,24 @@ UIKit_PumpEvents(_THIS) */ if (setjmp(*jump_env()) == 0) { /* if we're setting the jump, rather than jumping back */ + + /* Let the run loop run for a short amount of time: long enough for + touch events to get processed (which is important to get certain + elements of Game Center's GKLeaderboardViewController to respond + to touch input), but not long enough to introduce a significant + delay in the rest of the app. + */ + const CFTimeInterval seconds = 0.000002; + + /* Pump most event types. */ SInt32 result; do { - result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE); + result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE); } while (result == kCFRunLoopRunHandledSource); /* Make sure UIScrollView objects scroll properly. */ do { - result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, 0, TRUE); + result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE); } while(result == kCFRunLoopRunHandledSource); } } From 09edff54cdc56999584352b4ea768f8a47829032 Mon Sep 17 00:00:00 2001 From: DavidLudwig Date: Wed, 25 Jul 2012 20:56:42 -0400 Subject: [PATCH 006/264] Fix for iOS touch input coordinates being halved on Retina displays --- src/video/uikit/SDL_uikitview.m | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index b6c4cf867..02e394ae5 100755 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -94,6 +94,12 @@ if (touch) { CGPoint locationInView = [touch locationInView: self]; + + /* Make sure UIView points are converted to screen pixels: */ + if ([self respondsToSelector:@selector(contentScaleFactor)]) { + locationInView.x *= self.contentScaleFactor; + locationInView.y *= self.contentScaleFactor; + } /* send moved event */ SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); @@ -184,6 +190,12 @@ if (touch) { CGPoint locationInView = [touch locationInView: self]; + + /* Make sure UIView points are converted to screen pixels: */ + if ([self respondsToSelector:@selector(contentScaleFactor)]) { + locationInView.x *= self.contentScaleFactor; + locationInView.y *= self.contentScaleFactor; + } /* send moved event */ SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y); From 29652a3e3d30d89313bd44aa91cf053fafbc4958 Mon Sep 17 00:00:00 2001 From: DavidLudwig Date: Sat, 1 Sep 2012 07:26:55 -0400 Subject: [PATCH 007/264] Xcode project for iOS uses spaces for tabs, as per most (all?) SDL source files --- Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj index d9fc8eeb1..d6d7f7f75 100755 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj @@ -761,6 +761,7 @@ ); name = CustomTemplate; sourceTree = ""; + usesTabs = 0; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; From 03f451e902b7867cf5ded14b3e9e53192e311b34 Mon Sep 17 00:00:00 2001 From: DavidLudwig Date: Sat, 1 Sep 2012 09:17:34 -0400 Subject: [PATCH 008/264] Removed custom code that fixed Game Center notifications non-display, in favor of an official fix (done via UIKit_ShowWindow). --- src/video/uikit/SDL_uikitwindow.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index ef5a9eb84..42366900c 100755 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -200,9 +200,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) [uiwindow setScreen:data->uiscreen]; } - // Make sure the native window gets displayed. - [uiwindow makeKeyAndVisible]; - if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) { [uiwindow release]; return -1; From 95fc405a612ad380cfb30ac5b6b72cd4c7879786 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 15 Oct 2012 22:25:08 -0400 Subject: [PATCH 009/264] added Visual Studio 2012 projects for SDL and SDLmain (but not tests) --- VisualC/SDL/SDL_VS2012.vcxproj | 453 +++++++++++++++++++++++++ VisualC/SDL_VS2012.sln | 179 ++++++++++ VisualC/SDLmain/SDLmain_VS2012.vcxproj | 163 +++++++++ 3 files changed, 795 insertions(+) create mode 100644 VisualC/SDL/SDL_VS2012.vcxproj create mode 100644 VisualC/SDL_VS2012.sln create mode 100644 VisualC/SDLmain/SDLmain_VS2012.vcxproj diff --git a/VisualC/SDL/SDL_VS2012.vcxproj b/VisualC/SDL/SDL_VS2012.vcxproj new file mode 100644 index 000000000..6e64be02b --- /dev/null +++ b/VisualC/SDL/SDL_VS2012.vcxproj @@ -0,0 +1,453 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + SDL + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + SDL + + + + DynamicLibrary + false + v110 + + + DynamicLibrary + false + v110 + + + DynamicLibrary + false + v110 + + + DynamicLibrary + false + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories);"$(DXSDK_DIR)\Include"; + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + false + + + Level3 + true + EditAndContinue + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies) + true + true + Windows + false + $(DXSDK_DIR)\lib\x86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories);"$(DXSDK_DIR)\Include"; + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + false + + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies) + true + true + Windows + false + $(DXSDK_DIR)\lib\x64 + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + + + OnlyExplicitInline + false + ..\..\include;%(AdditionalIncludeDirectories);"$(DXSDK_DIR)\Include"; + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + + + Level3 + true + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies) + true + Windows + $(DXSDK_DIR)\lib\x86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + + + OnlyExplicitInline + false + ..\..\include;%(AdditionalIncludeDirectories);"$(DXSDK_DIR)\Include"; + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies) + true + Windows + $(DXSDK_DIR)\lib\x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC/SDL_VS2012.sln b/VisualC/SDL_VS2012.sln new file mode 100644 index 000000000..573e1a4d8 --- /dev/null +++ b/VisualC/SDL_VS2012.sln @@ -0,0 +1,179 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows 8 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CE748C1F-3C21-4825-AA6A-F895A023F7E7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "automated", "tests\automated\automated_VS2010.vcxproj", "{DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loopwave", "tests\loopwave\loopwave_VS2010.vcxproj", "{AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplatform", "tests\testplatform\testplatform_VS2010.vcxproj", "{26932B24-EFC6-4E3A-B277-ED653DA37968}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "tests\testfile\testfile_VS2010.vcxproj", "{CAE4F1D0-314F-4B10-805B-0EFD670133A0}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgl2", "tests\testgl2\testgl2_VS2010.vcxproj", "{8B5CFB38-CCBA-40A8-AD7A-89C57B070884}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checkkeys", "tests\checkkeys\checkkeys_VS2010.vcxproj", "{26828762-C95D-4637-9CB1-7F0979523813}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsprite2", "tests\testsprite2\testsprite2_VS2010.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C96635682}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testshape", "tests\testshape\testshape_VS2010.vcxproj", "{EDEA9D00-AF64-45DE-8F60-5957048F2F0F}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdraw2", "tests\testdraw2\testdraw2_VS2010.vcxproj", "{8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testpower", "tests\testpower\testpower_VS2010.vcxproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}" + ProjectSection(ProjectDependencies) = postProject + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "SDL\SDL_VS2012.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDLmain", "SDLmain\SDLmain_VS2012.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|Win32.ActiveCfg = Debug|Win32 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|Win32.Build.0 = Debug|Win32 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|x64.ActiveCfg = Debug|x64 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|x64.Build.0 = Debug|x64 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|Win32.ActiveCfg = Release|Win32 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|Win32.Build.0 = Release|Win32 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|x64.ActiveCfg = Release|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.ActiveCfg = Debug|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.Build.0 = Debug|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.ActiveCfg = Debug|x64 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.Build.0 = Debug|x64 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.ActiveCfg = Release|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.Build.0 = Release|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|x64.ActiveCfg = Release|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.ActiveCfg = Debug|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.Build.0 = Debug|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.ActiveCfg = Debug|x64 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.Build.0 = Debug|x64 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.ActiveCfg = Release|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.Build.0 = Release|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|x64.ActiveCfg = Release|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.ActiveCfg = Debug|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.Build.0 = Debug|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.ActiveCfg = Debug|x64 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.Build.0 = Debug|x64 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.ActiveCfg = Release|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.Build.0 = Release|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|x64.ActiveCfg = Release|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.ActiveCfg = Debug|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.Build.0 = Debug|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.ActiveCfg = Debug|x64 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.Build.0 = Debug|x64 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.ActiveCfg = Release|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.Build.0 = Release|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|x64.ActiveCfg = Release|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.ActiveCfg = Debug|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.Build.0 = Debug|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.ActiveCfg = Debug|x64 + {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.Build.0 = Debug|x64 + {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.ActiveCfg = Release|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.Build.0 = Release|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Release|x64.ActiveCfg = Release|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.ActiveCfg = Debug|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.Build.0 = Debug|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.ActiveCfg = Debug|x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.Build.0 = Debug|x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.ActiveCfg = Release|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.Build.0 = Release|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|x64.ActiveCfg = Release|Win32 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|Win32.ActiveCfg = Debug|Win32 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|Win32.Build.0 = Debug|Win32 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|x64.ActiveCfg = Debug|x64 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|x64.Build.0 = Debug|x64 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Release|Win32.ActiveCfg = Release|Win32 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Release|x64.ActiveCfg = Release|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.ActiveCfg = Debug|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.Build.0 = Debug|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.ActiveCfg = Debug|x64 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.Build.0 = Debug|x64 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.ActiveCfg = Release|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.Build.0 = Release|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|x64.ActiveCfg = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.ActiveCfg = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.Build.0 = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.ActiveCfg = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.Build.0 = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.ActiveCfg = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.Build.0 = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|x64.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.Build.0 = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.ActiveCfg = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.Build.0 = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {26932B24-EFC6-4E3A-B277-ED653DA37968} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {CAE4F1D0-314F-4B10-805B-0EFD670133A0} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {26828762-C95D-4637-9CB1-7F0979523813} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {40FB7794-D3C3-4CFE-BCF4-A80C96635682} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3} = {CE748C1F-3C21-4825-AA6A-F895A023F7E7} + EndGlobalSection +EndGlobal diff --git a/VisualC/SDLmain/SDLmain_VS2012.vcxproj b/VisualC/SDLmain/SDLmain_VS2012.vcxproj new file mode 100644 index 000000000..5a86801c0 --- /dev/null +++ b/VisualC/SDLmain/SDLmain_VS2012.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + SDLmain + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + + + + StaticLibrary + false + v110 + + + StaticLibrary + false + v110 + + + StaticLibrary + false + MultiByte + v110 + + + StaticLibrary + false + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + + + OnlyExplicitInline + ..\..\include;..\..\include\SDL;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + + + Level3 + true + Default + + + true + + + + + X64 + + + OnlyExplicitInline + ..\..\include;..\..\include\SDL;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + + + Level3 + true + Default + + + true + + + + + + Disabled + ..\..\include;..\..\include\SDL;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level3 + true + OldStyle + Default + + + true + + + + + X64 + + + Disabled + ..\..\include;..\..\include\SDL;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + .\Debug/SDLmain.pch + Level3 + true + OldStyle + Default + + + true + + + + + + + + + \ No newline at end of file From 54b4201aa0bb795ac0dc54bc5b37af0d8d52109a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 17 Oct 2012 21:43:20 -0400 Subject: [PATCH 010/264] Got a bare-bones version of SDL compiling for Windows RT. Dummy drivers are used in some places. Very little Windows-specific code (from the Win32 version of SDL) is used. --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 383 +++++++++++++++++++++++++++ VisualC/SDL_VS2012.sln | 94 +++---- include/SDL_config.h | 2 + include/SDL_config_windowsrt.h | 182 +++++++++++++ include/SDL_platform.h | 2 + include/SDL_stdinc.h | 7 + src/SDL_assert.c | 25 +- src/atomic/SDL_spinlock.c | 2 +- src/file/SDL_rwops.c | 5 +- 9 files changed, 637 insertions(+), 65 deletions(-) create mode 100644 VisualC/SDL/SDL_VS2012_WinRT.vcxproj create mode 100644 include/SDL_config_windowsrt.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj new file mode 100644 index 000000000..7d1e46b52 --- /dev/null +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -0,0 +1,383 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + Win32Proj + SDL_VS2012_WinRT + SDL_VS2012_WinRT + en-US + 11.0 + true + + + + DynamicLibrary + true + v110 + + + DynamicLibrary + true + v110 + + + DynamicLibrary + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + + + + + + + + + + + + + + + + + + + + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + + + Console + false + false + + + + + + \ No newline at end of file diff --git a/VisualC/SDL_VS2012.sln b/VisualC/SDL_VS2012.sln index 573e1a4d8..83e357b29 100644 --- a/VisualC/SDL_VS2012.sln +++ b/VisualC/SDL_VS2012.sln @@ -4,162 +4,138 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CE748C1F-3C21-4825-AA6A-F895A023F7E7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "automated", "tests\automated\automated_VS2010.vcxproj", "{DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loopwave", "tests\loopwave\loopwave_VS2010.vcxproj", "{AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplatform", "tests\testplatform\testplatform_VS2010.vcxproj", "{26932B24-EFC6-4E3A-B277-ED653DA37968}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "tests\testfile\testfile_VS2010.vcxproj", "{CAE4F1D0-314F-4B10-805B-0EFD670133A0}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgl2", "tests\testgl2\testgl2_VS2010.vcxproj", "{8B5CFB38-CCBA-40A8-AD7A-89C57B070884}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checkkeys", "tests\checkkeys\checkkeys_VS2010.vcxproj", "{26828762-C95D-4637-9CB1-7F0979523813}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsprite2", "tests\testsprite2\testsprite2_VS2010.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C96635682}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testshape", "tests\testshape\testshape_VS2010.vcxproj", "{EDEA9D00-AF64-45DE-8F60-5957048F2F0F}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdraw2", "tests\testdraw2\testdraw2_VS2010.vcxproj", "{8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testpower", "tests\testpower\testpower_VS2010.vcxproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}" - ProjectSection(ProjectDependencies) = postProject - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} - EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "SDL\SDL_VS2012.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDLmain", "SDLmain\SDLmain_VS2012.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" +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 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|ARM.ActiveCfg = Debug|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|Win32.ActiveCfg = Debug|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|Win32.Build.0 = Debug|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|x64.ActiveCfg = Debug|x64 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Debug|x64.Build.0 = Debug|x64 + {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|ARM.ActiveCfg = Release|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|Win32.ActiveCfg = Release|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|Win32.Build.0 = Release|Win32 {DDD710DB-EC7B-4CCB-BD75-535D401A2FE0}.Release|x64.ActiveCfg = Release|Win32 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|ARM.ActiveCfg = Debug|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.ActiveCfg = Debug|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.Build.0 = Debug|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.ActiveCfg = Debug|x64 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.Build.0 = Debug|x64 + {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|ARM.ActiveCfg = Release|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.ActiveCfg = Release|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.Build.0 = Release|Win32 {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|x64.ActiveCfg = Release|Win32 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|ARM.ActiveCfg = Debug|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.ActiveCfg = Debug|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.Build.0 = Debug|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.ActiveCfg = Debug|x64 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.Build.0 = Debug|x64 + {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|ARM.ActiveCfg = Release|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.ActiveCfg = Release|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.Build.0 = Release|Win32 {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|x64.ActiveCfg = Release|Win32 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|ARM.ActiveCfg = Debug|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.ActiveCfg = Debug|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.Build.0 = Debug|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.ActiveCfg = Debug|x64 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.Build.0 = Debug|x64 + {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|ARM.ActiveCfg = Release|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.ActiveCfg = Release|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.Build.0 = Release|Win32 {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|x64.ActiveCfg = Release|Win32 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|ARM.ActiveCfg = Debug|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.ActiveCfg = Debug|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.Build.0 = Debug|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.ActiveCfg = Debug|x64 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.Build.0 = Debug|x64 + {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|ARM.ActiveCfg = Release|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.ActiveCfg = Release|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.Build.0 = Release|Win32 {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|x64.ActiveCfg = Release|Win32 + {26828762-C95D-4637-9CB1-7F0979523813}.Debug|ARM.ActiveCfg = Debug|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.ActiveCfg = Debug|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.Build.0 = Debug|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.ActiveCfg = Debug|x64 {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.Build.0 = Debug|x64 + {26828762-C95D-4637-9CB1-7F0979523813}.Release|ARM.ActiveCfg = Release|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.ActiveCfg = Release|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.Build.0 = Release|Win32 {26828762-C95D-4637-9CB1-7F0979523813}.Release|x64.ActiveCfg = Release|Win32 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|ARM.ActiveCfg = Debug|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.ActiveCfg = Debug|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.Build.0 = Debug|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.ActiveCfg = Debug|x64 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.Build.0 = Debug|x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|ARM.ActiveCfg = Release|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.ActiveCfg = Release|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.Build.0 = Release|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|x64.ActiveCfg = Release|Win32 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|ARM.ActiveCfg = Debug|Win32 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|Win32.ActiveCfg = Debug|Win32 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|Win32.Build.0 = Debug|Win32 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|x64.ActiveCfg = Debug|x64 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Debug|x64.Build.0 = Debug|x64 + {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Release|ARM.ActiveCfg = Release|Win32 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Release|Win32.ActiveCfg = Release|Win32 {EDEA9D00-AF64-45DE-8F60-5957048F2F0F}.Release|x64.ActiveCfg = Release|Win32 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|ARM.ActiveCfg = Debug|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.ActiveCfg = Debug|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.Build.0 = Debug|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.ActiveCfg = Debug|x64 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.Build.0 = Debug|x64 + {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|ARM.ActiveCfg = Release|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.ActiveCfg = Release|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.Build.0 = Release|Win32 {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|x64.ActiveCfg = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|ARM.ActiveCfg = Debug|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.ActiveCfg = Debug|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.Build.0 = Debug|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.ActiveCfg = Debug|x64 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.Build.0 = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|ARM.ActiveCfg = Release|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.ActiveCfg = Release|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.Build.0 = Release|Win32 {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|x64.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 + {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 diff --git a/include/SDL_config.h b/include/SDL_config.h index 03ff56f54..db38b9a12 100644 --- a/include/SDL_config.h +++ b/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__) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h new file mode 100644 index 000000000..76f8a6d93 --- /dev/null +++ b/include/SDL_config_windowsrt.h @@ -0,0 +1,182 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +/* Enabled for SDL 1.2 (binary compatibility) */ +#define HAVE_LIBC 1 +#ifdef HAVE_LIBC +/* Useful headers */ +#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: use _strlwr_s instead +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +//#define HAVE__LTOA 1 // TODO, WinRT: use _ltoa_s instead +//#define HAVE__ULTOA 1 // TODO, WinRT: use _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_SSCANF 1 // TODO, WinRT: use sscanf_s instead +#define HAVE_M_PI 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#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 +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +//#define HAVE_STDLIB_H 1 +//#define HAVE_MALLOC 1 +//#define HAVE_FREE 1 +#endif + +/* Enable various audio drivers */ +//#define SDL_AUDIO_DRIVER_XAUDIO2 1 // TODO, WinRT: see if SDL's XAudio2 driver can compile +#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 +// TODO, WinRT: Get joystick support working +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +// TODO, WinRT: look into getting SDL's pre-WinRT timers working. +// Some functions there are supported in WinRT, others are not. +//#define SDL_TIMER_WINDOWS 1 +#define SDL_TIMERS_DISABLED 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +// TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* _SDL_config_windows_h */ diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 736d1bfec..569215c6d 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -115,9 +115,11 @@ #define __SOLARIS__ 1 #endif #if defined(WIN32) || defined(_WIN32) +#if ! defined(__WINRT__) #undef __WIN32__ #define __WIN32__ 1 #endif +#endif #if defined(__NDS__) #undef __NINTENDODS__ diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index aaef5020b..b6e6992a4 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -72,6 +72,13 @@ # include #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 #endif #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) diff --git a/src/SDL_assert.c b/src/SDL_assert.c index 7eebfe1c6..4760e0397 100644 --- a/src/SDL_assert.c +++ b/src/SDL_assert.c @@ -26,7 +26,7 @@ #include "SDL_assert_c.h" #include "video/SDL_sysvideo.h" -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINRT__) #include "core/windows/SDL_windows.h" #ifndef WS_OVERLAPPEDWINDOW @@ -59,7 +59,7 @@ debug_print(const char *fmt, ...) __attribute__((format (printf, 1, 2))); static void debug_print(const char *fmt, ...) { -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINRT__) /* Format into a buffer for OutputDebugStringA(). */ char buf[1024]; char *startptr; @@ -213,6 +213,18 @@ SDL_PromptAssertion_windows(const SDL_assert_data *data) #endif +#ifdef __WINRT__ + +static SDL_assert_state +SDL_PromptAssertion_windowsrt(const SDL_assert_data *data) +{ + /* TODO, WinRT: implement SDL_PromptAssertion_windowsrt */ + return SDL_ASSERTION_ABORT; +} + +#endif + + static void SDL_AddAssertionToReport(SDL_assert_data *data) { /* (data) is always a static struct defined with the assert macros, so @@ -254,8 +266,10 @@ static void SDL_GenerateAssertionReport(void) static void SDL_ExitProcess(int exitcode) { -#ifdef __WIN32__ +#if defined(__WIN32__) ExitProcess(exitcode); +#elif defined(__WINRT__) + exit(exitcode); #else _exit(exitcode); #endif @@ -317,9 +331,12 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) /* platform-specific UI... */ -#ifdef __WIN32__ +#if defined(__WIN32__) state = SDL_PromptAssertion_windows(data); +#elif defined(__WINRT__) + state = SDL_PromptAssertion_windowsrt(data); + #elif defined __MACOSX__ && defined SDL_VIDEO_DRIVER_COCOA /* This has to be done in an Objective-C (*.m) file, so we call out. */ extern SDL_assert_state SDL_PromptAssertion_cocoa(const SDL_assert_data *); diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index ab3c5cb31..478335c33 100644 --- a/src/atomic/SDL_spinlock.c +++ b/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 diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 83f692eaa..b42b574d7 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -456,13 +456,16 @@ SDL_RWFromFile(const char *file, const char *mode) { #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); + rwops = SDL_RWFromFP(fp, SDL_TRUE); } } #else From 8eb16c7d58a4ea8b43700ba260f280148b63df19 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 17 Oct 2012 21:50:49 -0400 Subject: [PATCH 011/264] reverted a minor, unnecessary change in SDL_rwops.c that was done with regards to WinRT compilation --- src/file/SDL_rwops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index b42b574d7..7a87c9d2a 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -465,7 +465,7 @@ SDL_RWFromFile(const char *file, const char *mode) if (fp == NULL) { SDL_SetError("Couldn't open %s", file); } else { - rwops = SDL_RWFromFP(fp, SDL_TRUE); + rwops = SDL_RWFromFP(fp, 1); } } #else From 60cb5a5229b118e0149b16a755fe3e151a6e31aa Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 18 Oct 2012 10:03:07 -0400 Subject: [PATCH 012/264] added missing Visual Studio 2012 .sln file for WinRT --- VisualC/SDL_VS2012_WinRT.sln | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 VisualC/SDL_VS2012_WinRT.sln diff --git a/VisualC/SDL_VS2012_WinRT.sln b/VisualC/SDL_VS2012_WinRT.sln new file mode 100644 index 000000000..e61a8593d --- /dev/null +++ b/VisualC/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 From 020c3bed8cb4b5412c3a0b4109176b175dd55401 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 18:21:31 -0400 Subject: [PATCH 013/264] WinRT: used Win32-style DECLSPEC and SDLCALL macros (for building a .dll) --- include/begin_code.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/begin_code.h b/include/begin_code.h index b45af55ea..381007a61 100644 --- a/include/begin_code.h +++ b/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 From b513e6f8f0eeaca537ba873532b6ee980c1101be Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 18:39:09 -0400 Subject: [PATCH 014/264] WinRT: made SDL.dll compile for ARM (and not just x86 or x64) --- include/SDL_cpuinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h index 22d04a7ca..624e9bfff 100644 --- a/include/SDL_cpuinfo.h +++ b/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 #ifndef _WIN64 #define __MMX__ From 0821c8bc81d3d4d011b975bb3e71708b690ba37b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 20:12:31 -0400 Subject: [PATCH 015/264] WinRT: created SDLmain library using most of VC++ 2012's template for Direct3D 11 apps. Most of this will be moved into SDL itself. --- VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj | 199 +++++++++++ src/main/windowsrt/BasicTimer.h | 76 ++++ src/main/windowsrt/CubeRenderer.cpp | 256 ++++++++++++++ src/main/windowsrt/CubeRenderer.h | 44 +++ src/main/windowsrt/Direct3DBase.cpp | 344 +++++++++++++++++++ src/main/windowsrt/Direct3DBase.h | 38 ++ src/main/windowsrt/DirectXHelper.h | 36 ++ src/main/windowsrt/SDL_WinRTApp.cpp | 148 ++++++++ src/main/windowsrt/SDL_WinRTApp.h | 40 +++ src/main/windowsrt/SDLmain_WinRT_common.h | 7 + src/main/windowsrt/SimplePixelShader.hlsl | 10 + src/main/windowsrt/SimpleVertexShader.hlsl | 35 ++ 12 files changed, 1233 insertions(+) create mode 100644 VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj create mode 100644 src/main/windowsrt/BasicTimer.h create mode 100644 src/main/windowsrt/CubeRenderer.cpp create mode 100644 src/main/windowsrt/CubeRenderer.h create mode 100644 src/main/windowsrt/Direct3DBase.cpp create mode 100644 src/main/windowsrt/Direct3DBase.h create mode 100644 src/main/windowsrt/DirectXHelper.h create mode 100644 src/main/windowsrt/SDL_WinRTApp.cpp create mode 100644 src/main/windowsrt/SDL_WinRTApp.h create mode 100644 src/main/windowsrt/SDLmain_WinRT_common.h create mode 100644 src/main/windowsrt/SimplePixelShader.hlsl create mode 100644 src/main/windowsrt/SimpleVertexShader.hlsl diff --git a/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj b/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj new file mode 100644 index 000000000..200bbd478 --- /dev/null +++ b/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj @@ -0,0 +1,199 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + {48666378-b527-43f5-8968-f867a6f8d2a3} + Win32Proj + SDLmain_VS2012_WinRT + SDLmain_VS2012_WinRT + en-US + 11.0 + true + + + + StaticLibrary + true + v110 + + + StaticLibrary + true + v110 + + + StaticLibrary + true + v110 + + + StaticLibrary + false + true + v110 + + + StaticLibrary + false + true + v110 + + + StaticLibrary + false + true + v110 + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + + NotUsing + true + true + + + Console + false + false + + + + + NotUsing + true + true + + + Console + false + false + + + + + Use + false + true + + + Console + false + false + + + + + Use + false + true + + + Console + false + false + + + + + Use + false + true + + + Console + false + false + + + + + Use + false + true + + + Console + false + false + + + + + + \ No newline at end of file diff --git a/src/main/windowsrt/BasicTimer.h b/src/main/windowsrt/BasicTimer.h new file mode 100644 index 000000000..4f097d4eb --- /dev/null +++ b/src/main/windowsrt/BasicTimer.h @@ -0,0 +1,76 @@ +#pragma once + +#include + +// Helper class for basic timing. +ref class BasicTimer sealed +{ +public: + // Initializes internal timer values. + BasicTimer() + { + if (!QueryPerformanceFrequency(&m_frequency)) + { + throw ref new Platform::FailureException(); + } + Reset(); + } + + // Reset the timer to initial values. + void Reset() + { + Update(); + m_startTime = m_currentTime; + m_total = 0.0f; + m_delta = 1.0f / 60.0f; + } + + // Update the timer's internal values. + void Update() + { + if (!QueryPerformanceCounter(&m_currentTime)) + { + throw ref new Platform::FailureException(); + } + + m_total = static_cast( + static_cast(m_currentTime.QuadPart - m_startTime.QuadPart) / + static_cast(m_frequency.QuadPart) + ); + + if (m_lastTime.QuadPart == m_startTime.QuadPart) + { + // If the timer was just reset, report a time delta equivalent to 60Hz frame time. + m_delta = 1.0f / 60.0f; + } + else + { + m_delta = static_cast( + static_cast(m_currentTime.QuadPart - m_lastTime.QuadPart) / + static_cast(m_frequency.QuadPart) + ); + } + + m_lastTime = m_currentTime; + } + + // Duration in seconds between the last call to Reset() and the last call to Update(). + property float Total + { + float get() { return m_total; } + } + + // Duration in seconds between the previous two calls to Update(). + property float Delta + { + float get() { return m_delta; } + } + +private: + LARGE_INTEGER m_frequency; + LARGE_INTEGER m_currentTime; + LARGE_INTEGER m_startTime; + LARGE_INTEGER m_lastTime; + float m_total; + float m_delta; +}; diff --git a/src/main/windowsrt/CubeRenderer.cpp b/src/main/windowsrt/CubeRenderer.cpp new file mode 100644 index 000000000..52e858607 --- /dev/null +++ b/src/main/windowsrt/CubeRenderer.cpp @@ -0,0 +1,256 @@ +#include "SDLmain_WinRT_common.h" +#include "CubeRenderer.h" + +using namespace DirectX; +using namespace Microsoft::WRL; +using namespace Windows::Foundation; +using namespace Windows::UI::Core; + +CubeRenderer::CubeRenderer() : + m_loadingComplete(false), + m_indexCount(0) +{ +} + +void CubeRenderer::CreateDeviceResources() +{ + Direct3DBase::CreateDeviceResources(); + + auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso"); + auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso"); + + auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { + DX::ThrowIfFailed( + m_d3dDevice->CreateVertexShader( + fileData->Data, + fileData->Length, + nullptr, + &m_vertexShader + ) + ); + + const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + DX::ThrowIfFailed( + m_d3dDevice->CreateInputLayout( + vertexDesc, + ARRAYSIZE(vertexDesc), + fileData->Data, + fileData->Length, + &m_inputLayout + ) + ); + }); + + auto createPSTask = loadPSTask.then([this](Platform::Array^ fileData) { + DX::ThrowIfFailed( + m_d3dDevice->CreatePixelShader( + fileData->Data, + fileData->Length, + nullptr, + &m_pixelShader + ) + ); + + CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER); + DX::ThrowIfFailed( + m_d3dDevice->CreateBuffer( + &constantBufferDesc, + nullptr, + &m_constantBuffer + ) + ); + }); + + auto createCubeTask = (createPSTask && createVSTask).then([this] () { + VertexPositionColor cubeVertices[] = + { + {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f)}, + {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f)}, + {XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f)}, + {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f)}, + {XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f)}, + {XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f)}, + {XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f)}, + {XMFLOAT3( 0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f)}, + }; + + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; + vertexBufferData.pSysMem = cubeVertices; + vertexBufferData.SysMemPitch = 0; + vertexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER); + DX::ThrowIfFailed( + m_d3dDevice->CreateBuffer( + &vertexBufferDesc, + &vertexBufferData, + &m_vertexBuffer + ) + ); + + unsigned short cubeIndices[] = + { + 0,2,1, // -x + 1,2,3, + + 4,5,6, // +x + 5,7,6, + + 0,1,5, // -y + 0,5,4, + + 2,6,7, // +y + 2,7,3, + + 0,4,6, // -z + 0,6,2, + + 1,3,7, // +z + 1,7,5, + }; + + m_indexCount = ARRAYSIZE(cubeIndices); + + D3D11_SUBRESOURCE_DATA indexBufferData = {0}; + indexBufferData.pSysMem = cubeIndices; + indexBufferData.SysMemPitch = 0; + indexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER); + DX::ThrowIfFailed( + m_d3dDevice->CreateBuffer( + &indexBufferDesc, + &indexBufferData, + &m_indexBuffer + ) + ); + }); + + createCubeTask.then([this] () { + m_loadingComplete = true; + }); +} + +void CubeRenderer::CreateWindowSizeDependentResources() +{ + Direct3DBase::CreateWindowSizeDependentResources(); + + float aspectRatio = m_windowBounds.Width / m_windowBounds.Height; + float fovAngleY = 70.0f * XM_PI / 180.0f; + + // Note that the m_orientationTransform3D matrix is post-multiplied here + // in order to correctly orient the scene to match the display orientation. + // This post-multiplication step is required for any draw calls that are + // made to the swap chain render target. For draw calls to other targets, + // this transform should not be applied. + XMStoreFloat4x4( + &m_constantBufferData.projection, + XMMatrixTranspose( + XMMatrixMultiply( + XMMatrixPerspectiveFovRH( + fovAngleY, + aspectRatio, + 0.01f, + 100.0f + ), + XMLoadFloat4x4(&m_orientationTransform3D) + ) + ) + ); +} + +void CubeRenderer::Update(float timeTotal, float timeDelta) +{ + (void) timeDelta; // Unused parameter. + + XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f); + XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f); + XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); + + XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up))); + XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4))); +} + +void CubeRenderer::Render() +{ + const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f }; + m_d3dContext->ClearRenderTargetView( + m_renderTargetView.Get(), + midnightBlue + ); + + m_d3dContext->ClearDepthStencilView( + m_depthStencilView.Get(), + D3D11_CLEAR_DEPTH, + 1.0f, + 0 + ); + + // Only draw the cube once it is loaded (loading is asynchronous). + if (!m_loadingComplete) + { + return; + } + + m_d3dContext->OMSetRenderTargets( + 1, + m_renderTargetView.GetAddressOf(), + m_depthStencilView.Get() + ); + + m_d3dContext->UpdateSubresource( + m_constantBuffer.Get(), + 0, + NULL, + &m_constantBufferData, + 0, + 0 + ); + + UINT stride = sizeof(VertexPositionColor); + UINT offset = 0; + m_d3dContext->IASetVertexBuffers( + 0, + 1, + m_vertexBuffer.GetAddressOf(), + &stride, + &offset + ); + + m_d3dContext->IASetIndexBuffer( + m_indexBuffer.Get(), + DXGI_FORMAT_R16_UINT, + 0 + ); + + m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + m_d3dContext->IASetInputLayout(m_inputLayout.Get()); + + m_d3dContext->VSSetShader( + m_vertexShader.Get(), + nullptr, + 0 + ); + + m_d3dContext->VSSetConstantBuffers( + 0, + 1, + m_constantBuffer.GetAddressOf() + ); + + m_d3dContext->PSSetShader( + m_pixelShader.Get(), + nullptr, + 0 + ); + + m_d3dContext->DrawIndexed( + m_indexCount, + 0, + 0 + ); +} diff --git a/src/main/windowsrt/CubeRenderer.h b/src/main/windowsrt/CubeRenderer.h new file mode 100644 index 000000000..b3ce23001 --- /dev/null +++ b/src/main/windowsrt/CubeRenderer.h @@ -0,0 +1,44 @@ +#pragma once + +#include "Direct3DBase.h" + +struct ModelViewProjectionConstantBuffer +{ + DirectX::XMFLOAT4X4 model; + DirectX::XMFLOAT4X4 view; + DirectX::XMFLOAT4X4 projection; +}; + +struct VertexPositionColor +{ + DirectX::XMFLOAT3 pos; + DirectX::XMFLOAT3 color; +}; + +// This class renders a simple spinning cube. +ref class CubeRenderer sealed : public Direct3DBase +{ +public: + CubeRenderer(); + + // Direct3DBase methods. + virtual void CreateDeviceResources() override; + virtual void CreateWindowSizeDependentResources() override; + virtual void Render() override; + + // Method for updating time-dependent objects. + void Update(float timeTotal, float timeDelta); + +private: + bool m_loadingComplete; + + Microsoft::WRL::ComPtr m_inputLayout; + Microsoft::WRL::ComPtr m_vertexBuffer; + Microsoft::WRL::ComPtr m_indexBuffer; + Microsoft::WRL::ComPtr m_vertexShader; + Microsoft::WRL::ComPtr m_pixelShader; + Microsoft::WRL::ComPtr m_constantBuffer; + + uint32 m_indexCount; + ModelViewProjectionConstantBuffer m_constantBufferData; +}; diff --git a/src/main/windowsrt/Direct3DBase.cpp b/src/main/windowsrt/Direct3DBase.cpp new file mode 100644 index 000000000..bb0ea593d --- /dev/null +++ b/src/main/windowsrt/Direct3DBase.cpp @@ -0,0 +1,344 @@ +#include "SDLmain_WinRT_common.h" +#include "Direct3DBase.h" + +using namespace DirectX; +using namespace Microsoft::WRL; +using namespace Windows::UI::Core; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; + +// Constructor. +Direct3DBase::Direct3DBase() +{ +} + +// Initialize the Direct3D resources required to run. +void Direct3DBase::Initialize(CoreWindow^ window) +{ + m_window = window; + + CreateDeviceResources(); + CreateWindowSizeDependentResources(); +} + +// Recreate all device resources and set them back to the current state. +void Direct3DBase::HandleDeviceLost() +{ + // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. + m_windowBounds.Width = 0; + m_windowBounds.Height = 0; + m_swapChain = nullptr; + + CreateDeviceResources(); + UpdateForWindowSizeChange(); +} + +// These are the resources that depend on the device. +void Direct3DBase::CreateDeviceResources() +{ + // 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 device; + ComPtr context; + DX::ThrowIfFailed( + 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. + &m_featureLevel, // Returns feature level of device created. + &context // Returns the device immediate context. + ) + ); + + // Get the Direct3D 11.1 API device and context interfaces. + DX::ThrowIfFailed( + device.As(&m_d3dDevice) + ); + + DX::ThrowIfFailed( + context.As(&m_d3dContext) + ); +} + +// Allocate all memory resources that change on a window SizeChanged event. +void Direct3DBase::CreateWindowSizeDependentResources() +{ + // Store the window bounds so the next time we get a SizeChanged event we can + // avoid rebuilding everything if the size is identical. + m_windowBounds = m_window->Bounds; + + // Calculate the necessary swap chain and render target size in pixels. + float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); + float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); + + // 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. + m_orientation = DisplayProperties::CurrentOrientation; + bool swapDimensions = + m_orientation == DisplayOrientations::Portrait || + m_orientation == DisplayOrientations::PortraitFlipped; + m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; + m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; + + if(m_swapChain != nullptr) + { + // If the swap chain already exists, resize it. + DX::ThrowIfFailed( + m_swapChain->ResizeBuffers( + 2, // Double-buffered swap chain. + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + DXGI_FORMAT_B8G8R8A8_UNORM, + 0 + ) + ); + } + 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(m_renderTargetSize.Width); // Match the size of the window. + swapChainDesc.Height = static_cast(m_renderTargetSize.Height); + 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. + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. + swapChainDesc.Flags = 0; + + ComPtr dxgiDevice; + DX::ThrowIfFailed( + m_d3dDevice.As(&dxgiDevice) + ); + + ComPtr dxgiAdapter; + DX::ThrowIfFailed( + dxgiDevice->GetAdapter(&dxgiAdapter) + ); + + ComPtr dxgiFactory; + DX::ThrowIfFailed( + dxgiAdapter->GetParent( + __uuidof(IDXGIFactory2), + &dxgiFactory + ) + ); + + Windows::UI::Core::CoreWindow^ window = m_window.Get(); + DX::ThrowIfFailed( + dxgiFactory->CreateSwapChainForCoreWindow( + m_d3dDevice.Get(), + reinterpret_cast(window), + &swapChainDesc, + nullptr, // Allow on all displays. + &m_swapChain + ) + ); + + // 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. + DX::ThrowIfFailed( + dxgiDevice->SetMaximumFrameLatency(1) + ); + } + + // 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 (m_orientation) + { + case DisplayOrientations::Landscape: + rotation = DXGI_MODE_ROTATION_IDENTITY; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE270; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE180; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE90; + m_orientationTransform3D = 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: + throw ref new Platform::FailureException(); + } + + DX::ThrowIfFailed( + m_swapChain->SetRotation(rotation) + ); + + // Create a render target view of the swap chain back buffer. + ComPtr backBuffer; + DX::ThrowIfFailed( + m_swapChain->GetBuffer( + 0, + __uuidof(ID3D11Texture2D), + &backBuffer + ) + ); + + DX::ThrowIfFailed( + m_d3dDevice->CreateRenderTargetView( + backBuffer.Get(), + nullptr, + &m_renderTargetView + ) + ); + + // Create a depth stencil view. + CD3D11_TEXTURE2D_DESC depthStencilDesc( + DXGI_FORMAT_D24_UNORM_S8_UINT, + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + 1, + 1, + D3D11_BIND_DEPTH_STENCIL + ); + + ComPtr depthStencil; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &depthStencilDesc, + nullptr, + &depthStencil + ) + ); + + CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); + DX::ThrowIfFailed( + m_d3dDevice->CreateDepthStencilView( + depthStencil.Get(), + &depthStencilViewDesc, + &m_depthStencilView + ) + ); + + // Set the rendering viewport to target the entire window. + CD3D11_VIEWPORT viewport( + 0.0f, + 0.0f, + m_renderTargetSize.Width, + m_renderTargetSize.Height + ); + + m_d3dContext->RSSetViewports(1, &viewport); +} + +// This method is called in the event handler for the SizeChanged event. +void Direct3DBase::UpdateForWindowSizeChange() +{ + if (m_window->Bounds.Width != m_windowBounds.Width || + m_window->Bounds.Height != m_windowBounds.Height || + m_orientation != DisplayProperties::CurrentOrientation) + { + ID3D11RenderTargetView* nullViews[] = {nullptr}; + m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + m_renderTargetView = nullptr; + m_depthStencilView = nullptr; + m_d3dContext->Flush(); + CreateWindowSizeDependentResources(); + } +} + +// Method to deliver the final image to the display. +void Direct3DBase::Present() +{ + // The application may optionally specify "dirty" or "scroll" + // rects to improve efficiency in certain scenarios. + 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 = m_swapChain->Present1(1, 0, ¶meters); + + // 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. + m_d3dContext->DiscardView(m_renderTargetView.Get()); + + // Discard the contents of the depth stencil. + m_d3dContext->DiscardView(m_depthStencilView.Get()); + + // If the device was removed either by a disconnect or a driver upgrade, we + // must recreate all device resources. + if (hr == DXGI_ERROR_DEVICE_REMOVED) + { + HandleDeviceLost(); + } + else + { + DX::ThrowIfFailed(hr); + } +} + +// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. +float Direct3DBase::ConvertDipsToPixels(float dips) +{ + static const float dipsPerInch = 96.0f; + return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. +} diff --git a/src/main/windowsrt/Direct3DBase.h b/src/main/windowsrt/Direct3DBase.h new file mode 100644 index 000000000..9a095dc87 --- /dev/null +++ b/src/main/windowsrt/Direct3DBase.h @@ -0,0 +1,38 @@ +#pragma once + +#include "DirectXHelper.h" + +// Helper class that initializes DirectX APIs for 3D rendering. +ref class Direct3DBase abstract +{ +internal: + Direct3DBase(); + +public: + virtual void Initialize(Windows::UI::Core::CoreWindow^ window); + virtual void HandleDeviceLost(); + virtual void CreateDeviceResources(); + virtual void CreateWindowSizeDependentResources(); + virtual void UpdateForWindowSizeChange(); + virtual void Render() = 0; + virtual void Present(); + virtual float ConvertDipsToPixels(float dips); + +protected private: + // Direct3D Objects. + Microsoft::WRL::ComPtr m_d3dDevice; + Microsoft::WRL::ComPtr m_d3dContext; + Microsoft::WRL::ComPtr m_swapChain; + Microsoft::WRL::ComPtr m_renderTargetView; + Microsoft::WRL::ComPtr m_depthStencilView; + + // Cached renderer properties. + D3D_FEATURE_LEVEL m_featureLevel; + Windows::Foundation::Size m_renderTargetSize; + Windows::Foundation::Rect m_windowBounds; + Platform::Agile m_window; + Windows::Graphics::Display::DisplayOrientations m_orientation; + + // Transform used for display orientation. + DirectX::XMFLOAT4X4 m_orientationTransform3D; +}; diff --git a/src/main/windowsrt/DirectXHelper.h b/src/main/windowsrt/DirectXHelper.h new file mode 100644 index 000000000..3d3e59b88 --- /dev/null +++ b/src/main/windowsrt/DirectXHelper.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +namespace DX +{ + inline void ThrowIfFailed(HRESULT hr) + { + if (FAILED(hr)) + { + // Set a breakpoint on this line to catch Win32 API errors. + throw Platform::Exception::CreateException(hr); + } + } + + // Function that reads from a binary file asynchronously. + inline Concurrency::task^> ReadDataAsync(Platform::String^ filename) + { + using namespace Windows::Storage; + using namespace Concurrency; + + auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation; + + return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file) + { + return FileIO::ReadBufferAsync(file); + }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array^ + { + auto fileData = ref new Platform::Array(fileBuffer->Length); + Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(fileData); + return fileData; + }); + } +} diff --git a/src/main/windowsrt/SDL_WinRTApp.cpp b/src/main/windowsrt/SDL_WinRTApp.cpp new file mode 100644 index 000000000..970fac2ef --- /dev/null +++ b/src/main/windowsrt/SDL_WinRTApp.cpp @@ -0,0 +1,148 @@ +#include "SDLmain_WinRT_common.h" +#include "SDL_WinRTApp.h" +#include "BasicTimer.h" + +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::UI::Core; +using namespace Windows::System; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; +using namespace concurrency; + +SDL_WinRTApp::SDL_WinRTApp() : + m_windowClosed(false), + m_windowVisible(true) +{ +} + +void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) +{ + applicationView->Activated += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnActivated); + + CoreApplication::Suspending += + ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler(this, &SDL_WinRTApp::OnResuming); + + m_renderer = ref new CubeRenderer(); +} + +void SDL_WinRTApp::SetWindow(CoreWindow^ window) +{ + window->SizeChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowSizeChanged); + + window->VisibilityChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); + + window->Closed += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowClosed); + + window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); + + window->PointerPressed += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + + window->PointerMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + + m_renderer->Initialize(CoreWindow::GetForCurrentThread()); +} + +void SDL_WinRTApp::Load(Platform::String^ entryPoint) +{ +} + +void SDL_WinRTApp::Run() +{ + BasicTimer^ timer = ref new BasicTimer(); + + while (!m_windowClosed) + { + if (m_windowVisible) + { + timer->Update(); + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + m_renderer->Update(timer->Total, timer->Delta); + m_renderer->Render(); + m_renderer->Present(); // This call is synchronized to the display frame rate. + } + else + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + } + } +} + +void SDL_WinRTApp::Uninitialize() +{ +} + +void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +{ + m_renderer->UpdateForWindowSizeChange(); +} + +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +{ + m_windowVisible = args->Visible; +} + +void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) +{ + m_windowClosed = true; +} + +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +{ + // Insert your code here. +} + +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ + // Insert your code here. +} + +void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +{ + CoreWindow::GetForCurrentThread()->Activate(); +} + +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]() + { + // Insert your code here. + + 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. +} + +IFrameworkView^ Direct3DApplicationSource::CreateView() +{ + return ref new SDL_WinRTApp(); +} + +int SDL_WinRT_RunApplication(/*Platform::Array^*/) +{ + auto direct3DApplicationSource = ref new Direct3DApplicationSource(); + CoreApplication::Run(direct3DApplicationSource); + return 0; +} diff --git a/src/main/windowsrt/SDL_WinRTApp.h b/src/main/windowsrt/SDL_WinRTApp.h new file mode 100644 index 000000000..cf6e88957 --- /dev/null +++ b/src/main/windowsrt/SDL_WinRTApp.h @@ -0,0 +1,40 @@ +#pragma once + +#include "SDLmain_WinRT_common.h" +#include "CubeRenderer.h" + +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(); + +protected: + // Event Handlers. + 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 OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + +private: + CubeRenderer^ m_renderer; + bool m_windowClosed; + bool m_windowVisible; +}; + +ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource +{ +public: + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); +}; diff --git a/src/main/windowsrt/SDLmain_WinRT_common.h b/src/main/windowsrt/SDLmain_WinRT_common.h new file mode 100644 index 000000000..a07dd0cdd --- /dev/null +++ b/src/main/windowsrt/SDLmain_WinRT_common.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/src/main/windowsrt/SimplePixelShader.hlsl b/src/main/windowsrt/SimplePixelShader.hlsl new file mode 100644 index 000000000..a9142692e --- /dev/null +++ b/src/main/windowsrt/SimplePixelShader.hlsl @@ -0,0 +1,10 @@ +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float3 color : COLOR0; +}; + +float4 main(PixelShaderInput input) : SV_TARGET +{ + return float4(input.color,1.0f); +} diff --git a/src/main/windowsrt/SimpleVertexShader.hlsl b/src/main/windowsrt/SimpleVertexShader.hlsl new file mode 100644 index 000000000..f4ef86899 --- /dev/null +++ b/src/main/windowsrt/SimpleVertexShader.hlsl @@ -0,0 +1,35 @@ +cbuffer ModelViewProjectionConstantBuffer : register(b0) +{ + matrix model; + matrix view; + matrix projection; +}; + +struct VertexShaderInput +{ + float3 pos : POSITION; + float3 color : COLOR0; +}; + +struct VertexShaderOutput +{ + float4 pos : SV_POSITION; + float3 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 the color without modification. + output.color = input.color; + + return output; +} From dc1da2a251771e82aabf8097aefcd27e5410a5e5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 21:20:00 -0400 Subject: [PATCH 016/264] WinRT: moved contents of platform-specific SDLmain into SDL.dll, where it should probably have been in the first place --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 36 ++++ VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj | 199 ------------------ src/{main => video}/windowsrt/BasicTimer.h | 0 .../windowsrt/CubeRenderer.cpp | 0 src/{main => video}/windowsrt/CubeRenderer.h | 0 .../windowsrt/Direct3DBase.cpp | 0 src/{main => video}/windowsrt/Direct3DBase.h | 0 src/{main => video}/windowsrt/DirectXHelper.h | 0 .../windowsrt/SDL_WinRTApp.cpp | 6 +- src/{main => video}/windowsrt/SDL_WinRTApp.h | 0 .../windowsrt/SDLmain_WinRT_common.h | 0 .../windowsrt/SimplePixelShader.hlsl | 0 .../windowsrt/SimpleVertexShader.hlsl | 0 13 files changed, 41 insertions(+), 200 deletions(-) delete mode 100644 VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj rename src/{main => video}/windowsrt/BasicTimer.h (100%) rename src/{main => video}/windowsrt/CubeRenderer.cpp (100%) rename src/{main => video}/windowsrt/CubeRenderer.h (100%) rename src/{main => video}/windowsrt/Direct3DBase.cpp (100%) rename src/{main => video}/windowsrt/Direct3DBase.h (100%) rename src/{main => video}/windowsrt/DirectXHelper.h (100%) rename src/{main => video}/windowsrt/SDL_WinRTApp.cpp (93%) rename src/{main => video}/windowsrt/SDL_WinRTApp.h (100%) rename src/{main => video}/windowsrt/SDLmain_WinRT_common.h (100%) rename src/{main => video}/windowsrt/SimplePixelShader.hlsl (100%) rename src/{main => video}/windowsrt/SimpleVertexShader.hlsl (100%) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 7d1e46b52..687b462ea 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -101,6 +101,30 @@ + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + @@ -204,6 +228,12 @@ + + + + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} @@ -310,6 +340,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) @@ -323,6 +354,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) @@ -336,6 +368,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) @@ -349,6 +382,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) @@ -362,6 +396,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) @@ -375,6 +410,7 @@ Console false false + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) diff --git a/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj b/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj deleted file mode 100644 index 200bbd478..000000000 --- a/VisualC/SDLmain/SDLmain_VS2012_WinRT.vcxproj +++ /dev/null @@ -1,199 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - {48666378-b527-43f5-8968-f867a6f8d2a3} - Win32Proj - SDLmain_VS2012_WinRT - SDLmain_VS2012_WinRT - en-US - 11.0 - true - - - - StaticLibrary - true - v110 - - - StaticLibrary - true - v110 - - - StaticLibrary - true - v110 - - - StaticLibrary - false - true - v110 - - - StaticLibrary - false - true - v110 - - - StaticLibrary - false - true - v110 - - - - - - - - - - - - - - - - - - - - - - - - false - - - false - - - false - - - false - - - false - - - false - - - - NotUsing - true - true - - - Console - false - false - - - - - NotUsing - true - true - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - Use - false - true - - - Console - false - false - - - - - - \ No newline at end of file diff --git a/src/main/windowsrt/BasicTimer.h b/src/video/windowsrt/BasicTimer.h similarity index 100% rename from src/main/windowsrt/BasicTimer.h rename to src/video/windowsrt/BasicTimer.h diff --git a/src/main/windowsrt/CubeRenderer.cpp b/src/video/windowsrt/CubeRenderer.cpp similarity index 100% rename from src/main/windowsrt/CubeRenderer.cpp rename to src/video/windowsrt/CubeRenderer.cpp diff --git a/src/main/windowsrt/CubeRenderer.h b/src/video/windowsrt/CubeRenderer.h similarity index 100% rename from src/main/windowsrt/CubeRenderer.h rename to src/video/windowsrt/CubeRenderer.h diff --git a/src/main/windowsrt/Direct3DBase.cpp b/src/video/windowsrt/Direct3DBase.cpp similarity index 100% rename from src/main/windowsrt/Direct3DBase.cpp rename to src/video/windowsrt/Direct3DBase.cpp diff --git a/src/main/windowsrt/Direct3DBase.h b/src/video/windowsrt/Direct3DBase.h similarity index 100% rename from src/main/windowsrt/Direct3DBase.h rename to src/video/windowsrt/Direct3DBase.h diff --git a/src/main/windowsrt/DirectXHelper.h b/src/video/windowsrt/DirectXHelper.h similarity index 100% rename from src/main/windowsrt/DirectXHelper.h rename to src/video/windowsrt/DirectXHelper.h diff --git a/src/main/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp similarity index 93% rename from src/main/windowsrt/SDL_WinRTApp.cpp rename to src/video/windowsrt/SDL_WinRTApp.cpp index 970fac2ef..842c591ad 100644 --- a/src/main/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -57,8 +57,12 @@ void SDL_WinRTApp::Load(Platform::String^ entryPoint) { } +#include "SDL.h" + void SDL_WinRTApp::Run() { + SDL_Init(0); + BasicTimer^ timer = ref new BasicTimer(); while (!m_windowClosed) @@ -140,7 +144,7 @@ IFrameworkView^ Direct3DApplicationSource::CreateView() return ref new SDL_WinRTApp(); } -int SDL_WinRT_RunApplication(/*Platform::Array^*/) +__declspec(dllexport) int SDL_WinRT_RunApplication(/*Platform::Array^*/) { auto direct3DApplicationSource = ref new Direct3DApplicationSource(); CoreApplication::Run(direct3DApplicationSource); diff --git a/src/main/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h similarity index 100% rename from src/main/windowsrt/SDL_WinRTApp.h rename to src/video/windowsrt/SDL_WinRTApp.h diff --git a/src/main/windowsrt/SDLmain_WinRT_common.h b/src/video/windowsrt/SDLmain_WinRT_common.h similarity index 100% rename from src/main/windowsrt/SDLmain_WinRT_common.h rename to src/video/windowsrt/SDLmain_WinRT_common.h diff --git a/src/main/windowsrt/SimplePixelShader.hlsl b/src/video/windowsrt/SimplePixelShader.hlsl similarity index 100% rename from src/main/windowsrt/SimplePixelShader.hlsl rename to src/video/windowsrt/SimplePixelShader.hlsl diff --git a/src/main/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl similarity index 100% rename from src/main/windowsrt/SimpleVertexShader.hlsl rename to src/video/windowsrt/SimpleVertexShader.hlsl From acf28c200469f4607b6f7d615efa0a34ebdd347c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 21:26:01 -0400 Subject: [PATCH 017/264] WinRT: removed some debugging code I added in earlier --- src/video/windowsrt/SDL_WinRTApp.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 842c591ad..ace8883e4 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -57,12 +57,8 @@ void SDL_WinRTApp::Load(Platform::String^ entryPoint) { } -#include "SDL.h" - void SDL_WinRTApp::Run() { - SDL_Init(0); - BasicTimer^ timer = ref new BasicTimer(); while (!m_windowClosed) From dafab5003be5bc5e2297e2dbaf9c32e20116bc2e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 22:03:31 -0400 Subject: [PATCH 018/264] WinRT: got a C-style main(int,char**) function to be called on app init --- src/video/windowsrt/SDL_WinRTApp.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index ace8883e4..f02192242 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -2,6 +2,13 @@ #include "SDL_WinRTApp.h" #include "BasicTimer.h" +// 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; + + using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; @@ -59,6 +66,15 @@ 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); + } + BasicTimer^ timer = ref new BasicTimer(); while (!m_windowClosed) @@ -140,9 +156,10 @@ IFrameworkView^ Direct3DApplicationSource::CreateView() return ref new SDL_WinRTApp(); } -__declspec(dllexport) int SDL_WinRT_RunApplication(/*Platform::Array^*/) +__declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction) { - auto direct3DApplicationSource = ref new Direct3DApplicationSource(); + SDL_WinRT_main = mainFunction; + auto direct3DApplicationSource = ref new Direct3DApplicationSource(); CoreApplication::Run(direct3DApplicationSource); return 0; } From a7a2a0130ad416b75473e9d5aee27194f6285d11 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 22:15:54 -0400 Subject: [PATCH 019/264] WinRT: made SDL_Log output to Visual C++'s debug console (via existing Win32 code in SDL) --- src/SDL_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL_log.c b/src/SDL_log.c index d38be9f93..d7f99180d 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -28,7 +28,7 @@ #include #endif -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__WINRT__) #include "core/windows/SDL_windows.h" #elif defined(__ANDROID__) #include @@ -280,7 +280,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 */ { char *output; From 231705e6b9964513505009c9f22f27a73e87ae0f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 22:27:51 -0400 Subject: [PATCH 020/264] WinRT: disabled threads to prevent SDL_Init(SDL_INIT_VIDEO) from crashing --- include/SDL_config_windowsrt.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 76f8a6d93..f8c2df300 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -158,7 +158,9 @@ typedef unsigned int uintptr_t; #define SDL_LOADSO_WINDOWS 1 /* Enable various threading systems */ -#define SDL_THREAD_WINDOWS 1 +// TODO, WinRT: get threads working on WinRT +#define SDL_THREADS_DISABLED 1 +//#define SDL_THREAD_WINDOWS 1 /* Enable various timer systems */ // TODO, WinRT: look into getting SDL's pre-WinRT timers working. From 431ac0d7f5c1d4e92fb1465674894656759b0da2 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 22:48:04 -0400 Subject: [PATCH 021/264] WinRT: created a skeleton for a video driver, using a copy of the dummy driver for a base --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 6 + include/SDL_config_windowsrt.h | 3 +- src/video/SDL_sysvideo.h | 3 + src/video/SDL_video.c | 3 + src/video/windowsrt/SDL_winrtevents.c | 41 ++++++ src/video/windowsrt/SDL_winrtevents_c.h | 27 ++++ src/video/windowsrt/SDL_winrtframebuffer.c | 94 +++++++++++++ src/video/windowsrt/SDL_winrtframebuffer_c.h | 27 ++++ src/video/windowsrt/SDL_winrtvideo.c | 137 +++++++++++++++++++ src/video/windowsrt/SDL_winrtvideo.h | 30 ++++ 10 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 src/video/windowsrt/SDL_winrtevents.c create mode 100644 src/video/windowsrt/SDL_winrtevents_c.h create mode 100644 src/video/windowsrt/SDL_winrtframebuffer.c create mode 100644 src/video/windowsrt/SDL_winrtframebuffer_c.h create mode 100644 src/video/windowsrt/SDL_winrtvideo.c create mode 100644 src/video/windowsrt/SDL_winrtvideo.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 687b462ea..e8cb1f0c8 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -125,6 +125,9 @@ true true + + + @@ -234,6 +237,9 @@ + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index f8c2df300..3f12a130c 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -169,7 +169,8 @@ typedef unsigned int uintptr_t; #define SDL_TIMERS_DISABLED 1 /* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINRT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 // TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index ae260c91b..056173cd5 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -327,6 +327,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 diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 24c72dcde..6198a0cdb 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -63,6 +63,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 diff --git a/src/video/windowsrt/SDL_winrtevents.c b/src/video/windowsrt/SDL_winrtevents.c new file mode 100644 index 000000000..d774f05b1 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtevents.c @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_events_c.h" + +#include "SDL_winrtvideo.h" +#include "SDL_winrtevents_c.h" + +void +WINRT_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtevents_c.h b/src/video/windowsrt/SDL_winrtevents_c.h new file mode 100644 index 000000000..afbd6862c --- /dev/null +++ b/src/video/windowsrt/SDL_winrtevents_c.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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: */ diff --git a/src/video/windowsrt/SDL_winrtframebuffer.c b/src/video/windowsrt/SDL_winrtframebuffer.c new file mode 100644 index 000000000..2426eac0f --- /dev/null +++ b/src/video/windowsrt/SDL_winrtframebuffer.c @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 "../SDL_sysvideo.h" +#include "SDL_winrtframebuffer_c.h" + + +#define WINRT_SURFACE "_SDL_WinRTSurface" + +int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_Surface *surface; + const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; + int w, h; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + /* Free the old framebuffer surface */ + surface = (SDL_Surface *) SDL_GetWindowData(window, WINRT_SURFACE); + if (surface) { + SDL_FreeSurface(surface); + } + + /* Create a new one */ + SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + SDL_GetWindowSize(window, &w, &h); + surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + if (!surface) { + return -1; + } + + /* Save the info and return! */ + SDL_SetWindowData(window, WINRT_SURFACE, surface); + *format = surface_format; + *pixels = surface->pixels; + *pitch = surface->pitch; + return 0; +} + +int SDL_WINRT_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects) +{ + static int frame_number; + SDL_Surface *surface; + + surface = (SDL_Surface *) SDL_GetWindowData(window, WINRT_SURFACE); + if (!surface) { + SDL_SetError("Couldn't find WinRT surface for window"); + return -1; + } + + /* Send the data to the display */ + if (SDL_getenv("SDL_VIDEO_WINRT_SAVE_FRAMES")) { + char file[128]; + SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", + SDL_GetWindowID(window), ++frame_number); + SDL_SaveBMP(surface, file); + } + return 0; +} + +void SDL_WINRT_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_Surface *surface; + + surface = (SDL_Surface *) SDL_SetWindowData(window, WINRT_SURFACE, NULL); + if (surface) { + SDL_FreeSurface(surface); + } +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtframebuffer_c.h b/src/video/windowsrt/SDL_winrtframebuffer_c.h new file mode 100644 index 000000000..d6531cfd0 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtframebuffer_c.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int SDL_WINRT_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects); +extern void SDL_WINRT_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtvideo.c b/src/video/windowsrt/SDL_winrtvideo.c new file mode 100644 index 000000000..c6b84a300 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtvideo.c @@ -0,0 +1,137 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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. + */ + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_winrtvideo.h" +#include "SDL_winrtevents_c.h" +#include "SDL_winrtframebuffer_c.h" + +#define WINRTVID_DRIVER_NAME "dummy" + +/* Initialization/Query functions */ +static int WINRT_VideoInit(_THIS); +static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static void WINRT_VideoQuit(_THIS); + +/* WinRT driver bootstrap functions */ + +static int +WINRT_Available(void) +{ + const char *envr = SDL_getenv("SDL_VIDEODRIVER"); + if ((envr) && (SDL_strcmp(envr, WINRTVID_DRIVER_NAME) == 0)) { + return (1); + } + + return (0); +} + +static void +WINRT_DeleteDevice(SDL_VideoDevice * device) +{ + 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->SetDisplayMode = WINRT_SetDisplayMode; + device->PumpEvents = WINRT_PumpEvents; + device->CreateWindowFramebuffer = SDL_WINRT_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer; + + device->free = WINRT_DeleteDevice; + + return device; +} + +VideoBootStrap WINRT_bootstrap = { + WINRTVID_DRIVER_NAME, "SDL Windows RT video driver", + WINRT_Available, WINRT_CreateDevice +}; + + +int +WINRT_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + + /* Use a fake 32-bpp desktop mode */ + mode.format = SDL_PIXELFORMAT_RGB888; + mode.w = 1024; + mode.h = 768; + mode.refresh_rate = 0; + mode.driverdata = NULL; + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_zero(mode); + SDL_AddDisplayMode(&_this->displays[0], &mode); + + /* We're done! */ + return 0; +} + +static int +WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +void +WINRT_VideoQuit(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h new file mode 100644 index 000000000..6490b31e0 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +#include "../SDL_sysvideo.h" + +#endif /* _SDL_winrtvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ From 4c0105454cbba0d43fa2c03e8198fb815d78ca80 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 27 Oct 2012 22:57:07 -0400 Subject: [PATCH 022/264] WinRT: made the WinRT video driver always be initialize-able --- src/video/windowsrt/SDL_winrtvideo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtvideo.c b/src/video/windowsrt/SDL_winrtvideo.c index c6b84a300..7fdcb64f7 100644 --- a/src/video/windowsrt/SDL_winrtvideo.c +++ b/src/video/windowsrt/SDL_winrtvideo.c @@ -50,12 +50,7 @@ static void WINRT_VideoQuit(_THIS); static int WINRT_Available(void) { - const char *envr = SDL_getenv("SDL_VIDEODRIVER"); - if ((envr) && (SDL_strcmp(envr, WINRTVID_DRIVER_NAME) == 0)) { - return (1); - } - - return (0); + return (1); } static void From 75ffd250093f94e124aebc48fddbbd70322260fa Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 18:45:33 -0400 Subject: [PATCH 023/264] WinRT: made the device's screen size be retrieve-able via SDL_GetDisplayMode() --HG-- rename : src/video/windowsrt/SDL_winrtevents.c => src/video/windowsrt/SDL_winrtevents.cpp rename : src/video/windowsrt/SDL_winrtframebuffer.c => src/video/windowsrt/SDL_winrtframebuffer.cpp rename : src/video/windowsrt/SDL_winrtvideo.c => src/video/windowsrt/SDL_winrtvideo.cpp --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 13 +++++-- src/video/windowsrt/SDL_WinRTApp.cpp | 38 ++++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 7 ++++ ...{SDL_winrtevents.c => SDL_winrtevents.cpp} | 0 ...framebuffer.c => SDL_winrtframebuffer.cpp} | 0 .../{SDL_winrtvideo.c => SDL_winrtvideo.cpp} | 28 ++++++-------- src/video/windowsrt/SDL_winrtvideo.h | 8 ++++ src/video/windowsrt/SDLmain_WinRT_common.h | 7 +++- 8 files changed, 80 insertions(+), 21 deletions(-) rename src/video/windowsrt/{SDL_winrtevents.c => SDL_winrtevents.cpp} (100%) rename src/video/windowsrt/{SDL_winrtframebuffer.c => SDL_winrtframebuffer.cpp} (100%) rename src/video/windowsrt/{SDL_winrtvideo.c => SDL_winrtvideo.cpp} (93%) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index e8cb1f0c8..350b25fc6 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -125,9 +125,16 @@ true true - - - + + + + true + true + true + true + true + true + diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index f02192242..343273611 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -2,12 +2,27 @@ #include "SDL_WinRTApp.h" #include "BasicTimer.h" +extern "C" { +#include "SDL_assert.h" +#include "SDL_stdinc.h" +#include "../SDL_sysvideo.h" +} + // 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; + using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; @@ -151,9 +166,30 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) // does not occur if the app was previously terminated. } +SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode() +{ + SDL_DisplayMode mode; + SDL_zero(mode); + mode.format = SDL_PIXELFORMAT_RGB888; + mode.w = (int) CoreWindow::GetForCurrentThread()->Bounds.Width; + mode.h = (int) CoreWindow::GetForCurrentThread()->Bounds.Height; + mode.refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps) + mode.driverdata = NULL; + return mode; +} + IFrameworkView^ Direct3DApplicationSource::CreateView() { - return ref new SDL_WinRTApp(); + // 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) diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index cf6e88957..866da4be6 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -2,6 +2,9 @@ #include "SDLmain_WinRT_common.h" #include "CubeRenderer.h" +#include + +using namespace Windows::UI::Core; ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { @@ -15,6 +18,10 @@ public: virtual void Run(); virtual void Uninitialize(); +internal: + // SDL-specific methods + SDL_DisplayMode GetMainDisplayMode(); + protected: // Event Handlers. void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); diff --git a/src/video/windowsrt/SDL_winrtevents.c b/src/video/windowsrt/SDL_winrtevents.cpp similarity index 100% rename from src/video/windowsrt/SDL_winrtevents.c rename to src/video/windowsrt/SDL_winrtevents.cpp diff --git a/src/video/windowsrt/SDL_winrtframebuffer.c b/src/video/windowsrt/SDL_winrtframebuffer.cpp similarity index 100% rename from src/video/windowsrt/SDL_winrtframebuffer.c rename to src/video/windowsrt/SDL_winrtframebuffer.cpp diff --git a/src/video/windowsrt/SDL_winrtvideo.c b/src/video/windowsrt/SDL_winrtvideo.cpp similarity index 93% rename from src/video/windowsrt/SDL_winrtvideo.c rename to src/video/windowsrt/SDL_winrtvideo.cpp index 7fdcb64f7..f084cbfd5 100644 --- a/src/video/windowsrt/SDL_winrtvideo.c +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -28,12 +28,15 @@ 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 "SDL_WinRTApp.h" #include "SDL_winrtvideo.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtframebuffer_c.h" @@ -93,26 +96,19 @@ VideoBootStrap WINRT_bootstrap = { WINRT_Available, WINRT_CreateDevice }; +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; int WINRT_VideoInit(_THIS) { - SDL_DisplayMode mode; - - /* Use a fake 32-bpp desktop mode */ - mode.format = SDL_PIXELFORMAT_RGB888; - mode.w = 1024; - mode.h = 768; - mode.refresh_rate = 0; - mode.driverdata = NULL; - if (SDL_AddBasicVideoDisplay(&mode) < 0) { - return -1; - } - - SDL_zero(mode); - SDL_AddDisplayMode(&_this->displays[0], &mode); - - /* We're done! */ + SDL_DisplayMode mode = SDL_WinRTGlobalApp->GetMainDisplayMode(); + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_AddDisplayMode(&_this->displays[0], &mode); + + /* We're done! */ return 0; } diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h index 6490b31e0..add24c234 100644 --- a/src/video/windowsrt/SDL_winrtvideo.h +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -23,8 +23,16 @@ #ifndef _SDL_winrtvideo_h #define _SDL_winrtvideo_h +#ifdef __cplusplus +extern "C" { +#endif + #include "../SDL_sysvideo.h" +#ifdef __cplusplus +} +#endif + #endif /* _SDL_winrtvideo_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDLmain_WinRT_common.h b/src/video/windowsrt/SDLmain_WinRT_common.h index a07dd0cdd..5e50662ab 100644 --- a/src/video/windowsrt/SDLmain_WinRT_common.h +++ b/src/video/windowsrt/SDLmain_WinRT_common.h @@ -4,4 +4,9 @@ #include #include #include -#include \ No newline at end of file +#include +#include + +extern "C" { +#include "../SDL_sysvideo.h" +} From b95133f5b5e2209aaef0ba74149b7699a6fc5429 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 19:47:33 -0400 Subject: [PATCH 024/264] WinRT: removed an unneeded class created by MSVC 11's Direct3D template app --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 1 - src/video/windowsrt/BasicTimer.h | 76 ---------------------------- src/video/windowsrt/SDL_WinRTApp.cpp | 6 +-- 3 files changed, 1 insertion(+), 82 deletions(-) delete mode 100644 src/video/windowsrt/BasicTimer.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 350b25fc6..18123fa86 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -238,7 +238,6 @@ - diff --git a/src/video/windowsrt/BasicTimer.h b/src/video/windowsrt/BasicTimer.h deleted file mode 100644 index 4f097d4eb..000000000 --- a/src/video/windowsrt/BasicTimer.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include - -// Helper class for basic timing. -ref class BasicTimer sealed -{ -public: - // Initializes internal timer values. - BasicTimer() - { - if (!QueryPerformanceFrequency(&m_frequency)) - { - throw ref new Platform::FailureException(); - } - Reset(); - } - - // Reset the timer to initial values. - void Reset() - { - Update(); - m_startTime = m_currentTime; - m_total = 0.0f; - m_delta = 1.0f / 60.0f; - } - - // Update the timer's internal values. - void Update() - { - if (!QueryPerformanceCounter(&m_currentTime)) - { - throw ref new Platform::FailureException(); - } - - m_total = static_cast( - static_cast(m_currentTime.QuadPart - m_startTime.QuadPart) / - static_cast(m_frequency.QuadPart) - ); - - if (m_lastTime.QuadPart == m_startTime.QuadPart) - { - // If the timer was just reset, report a time delta equivalent to 60Hz frame time. - m_delta = 1.0f / 60.0f; - } - else - { - m_delta = static_cast( - static_cast(m_currentTime.QuadPart - m_lastTime.QuadPart) / - static_cast(m_frequency.QuadPart) - ); - } - - m_lastTime = m_currentTime; - } - - // Duration in seconds between the last call to Reset() and the last call to Update(). - property float Total - { - float get() { return m_total; } - } - - // Duration in seconds between the previous two calls to Update(). - property float Delta - { - float get() { return m_delta; } - } - -private: - LARGE_INTEGER m_frequency; - LARGE_INTEGER m_currentTime; - LARGE_INTEGER m_startTime; - LARGE_INTEGER m_lastTime; - float m_total; - float m_delta; -}; diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 343273611..12593b425 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -1,6 +1,5 @@ #include "SDLmain_WinRT_common.h" #include "SDL_WinRTApp.h" -#include "BasicTimer.h" extern "C" { #include "SDL_assert.h" @@ -90,15 +89,12 @@ void SDL_WinRTApp::Run() SDL_WinRT_main(argc, argv); } - BasicTimer^ timer = ref new BasicTimer(); - while (!m_windowClosed) { if (m_windowVisible) { - timer->Update(); CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); - m_renderer->Update(timer->Total, timer->Delta); + m_renderer->Update(0.0f, 0.0f); m_renderer->Render(); m_renderer->Present(); // This call is synchronized to the display frame rate. } From c5a3281bc76157b574587a8ef2332a0bc7a78313 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 20:04:26 -0400 Subject: [PATCH 025/264] WinRT: made SDL_PumpEvents() work, in theory --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 9 ++++++++- src/video/windowsrt/SDL_WinRTApp.cpp | 5 ++++- src/video/windowsrt/SDL_WinRTApp.h | 1 + src/video/windowsrt/SDL_winrtevents.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 18123fa86..fd95bea51 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -125,7 +125,14 @@ true true - + + true + true + true + true + true + true + true diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 12593b425..662d72281 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -88,8 +88,11 @@ void SDL_WinRTApp::Run() char **argv = NULL; SDL_WinRT_main(argc, argv); } +} - while (!m_windowClosed) +void SDL_WinRTApp::PumpEvents() +{ + if (!m_windowClosed) { if (m_windowVisible) { diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 866da4be6..a6358822e 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -21,6 +21,7 @@ public: internal: // SDL-specific methods SDL_DisplayMode GetMainDisplayMode(); + void PumpEvents(); protected: // Event Handlers. diff --git a/src/video/windowsrt/SDL_winrtevents.cpp b/src/video/windowsrt/SDL_winrtevents.cpp index d774f05b1..f445b8b65 100644 --- a/src/video/windowsrt/SDL_winrtevents.cpp +++ b/src/video/windowsrt/SDL_winrtevents.cpp @@ -22,18 +22,18 @@ #if SDL_VIDEO_DRIVER_WINRT -/* Being a null driver, there's no event stream. We just define stubs for - most of the API. */ - #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) { - /* do nothing. */ + SDL_WinRTGlobalApp->PumpEvents(); } #endif /* SDL_VIDEO_DRIVER_WINRT */ From 9dfe3da5aad6f6d071539e1f0477834fb6ab06f9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 20:47:33 -0400 Subject: [PATCH 026/264] WinRT: added mouse button event support --- src/video/windowsrt/SDL_WinRTApp.cpp | 14 +++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 1 + src/video/windowsrt/SDL_winrtvideo.cpp | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 662d72281..789bfd0f3 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -5,6 +5,8 @@ extern "C" { #include "SDL_assert.h" #include "SDL_stdinc.h" #include "../SDL_sysvideo.h" +#include "../../events/SDL_mouse_c.h" +#include "SDL_events.h" } // HACK, DLudwig: The C-style main() will get loaded via the app's @@ -68,6 +70,9 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerPressed += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + window->PointerReleased += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); + window->PointerMoved += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); @@ -129,7 +134,14 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - // Insert your code here. + // TODO, WinRT: consider attaching the SDL_Window to the mouse down button event + SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT); +} + +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +{ + // TODO, WinRT: consider attaching the SDL_Window to the mouse up button event + SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT); } void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index a6358822e..d10f0e856 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -33,6 +33,7 @@ protected: 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 OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); private: diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index f084cbfd5..92aacadb6 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -41,6 +41,8 @@ extern "C" { #include "SDL_winrtevents_c.h" #include "SDL_winrtframebuffer_c.h" +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; + #define WINRTVID_DRIVER_NAME "dummy" /* Initialization/Query functions */ @@ -96,8 +98,6 @@ VideoBootStrap WINRT_bootstrap = { WINRT_Available, WINRT_CreateDevice }; -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; - int WINRT_VideoInit(_THIS) { From 06dee49efa976ac5f6b5e990196c3dc574099733 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 23:01:31 -0400 Subject: [PATCH 027/264] WinRT: SDL_GetWindowSize and SDL_MOUSEMOTION works, and cursor position data is now attached to mouse button events --- src/video/windowsrt/SDL_WinRTApp.cpp | 26 ++++++++++--- src/video/windowsrt/SDL_WinRTApp.h | 3 ++ src/video/windowsrt/SDL_winrtvideo.cpp | 44 ++++++++++++++++++++++ src/video/windowsrt/SDL_winrtvideo.h | 5 +++ src/video/windowsrt/SDLmain_WinRT_common.h | 3 ++ 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 789bfd0f3..e53e0fca5 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -7,6 +7,7 @@ extern "C" { #include "../SDL_sysvideo.h" #include "../../events/SDL_mouse_c.h" #include "SDL_events.h" +#include "SDL_log.h" } // HACK, DLudwig: The C-style main() will get loaded via the app's @@ -36,7 +37,8 @@ using namespace concurrency; SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), - m_windowVisible(true) + m_windowVisible(true), + m_sdlWindowData(NULL) { } @@ -134,19 +136,26 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - // TODO, WinRT: consider attaching the SDL_Window to the mouse down button event - SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT); + if (m_sdlWindowData) + { + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT); + } } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { - // TODO, WinRT: consider attaching the SDL_Window to the mouse up button event - SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT); + if (m_sdlWindowData) + { + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT); + } } void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { - // Insert your code here. + if (m_sdlWindowData) + { + SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, (int)args->CurrentPoint->Position.X, (int)args->CurrentPoint->Position.Y); + } } void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) @@ -189,6 +198,11 @@ SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode() return mode; } +void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData) +{ + m_sdlWindowData = windowData; +} + IFrameworkView^ Direct3DApplicationSource::CreateView() { // TODO, WinRT: see if this function (CreateView) can ever get called diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index d10f0e856..f7fc29b40 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -1,6 +1,7 @@ #pragma once #include "SDLmain_WinRT_common.h" +#include "SDL_winrtvideo.h" #include "CubeRenderer.h" #include @@ -22,6 +23,7 @@ internal: // SDL-specific methods SDL_DisplayMode GetMainDisplayMode(); void PumpEvents(); + void SetSDLWindowData(const SDL_WindowData* windowData); protected: // Event Handlers. @@ -40,6 +42,7 @@ private: CubeRenderer^ m_renderer; bool m_windowClosed; bool m_windowVisible; + const SDL_WindowData* m_sdlWindowData; }; ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 92aacadb6..e69826383 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -41,6 +41,11 @@ extern "C" { #include "SDL_winrtevents_c.h" #include "SDL_winrtframebuffer_c.h" +/* On Windows, windows.h defines CreateWindow */ +#ifdef CreateWindow +#undef CreateWindow +#endif + extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; #define WINRTVID_DRIVER_NAME "dummy" @@ -50,6 +55,10 @@ static int WINRT_VideoInit(_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); + /* WinRT driver bootstrap functions */ static int @@ -82,6 +91,8 @@ WINRT_CreateDevice(int devindex) /* 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; @@ -123,6 +134,39 @@ WINRT_VideoQuit(_THIS) { } +int +WINRT_CreateWindow(_THIS, SDL_Window * window) +{ + // TODO, WinRT: modify WINRT_Createwindow to ensure that, for now, only one window gets created + // (until multimonitor support is added to the WinRT port). + + SDL_WindowData *data; + data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + SDL_zerop(data); + data->sdlWindow = window; + + /* Adjust the window data to match the screen */ + window->x = 0; + window->y = 0; + window->w = _this->displays->desktop_mode.w; + window->h = _this->displays->desktop_mode.h; + + SDL_WinRTGlobalApp->SetSDLWindowData(data); + + return 0; +} + +void +WINRT_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WinRTGlobalApp->SetSDLWindowData(NULL); +} + + #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h index add24c234..fe8063f53 100644 --- a/src/video/windowsrt/SDL_winrtvideo.h +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -33,6 +33,11 @@ extern "C" { } #endif +struct SDL_WindowData +{ + SDL_Window *sdlWindow; +}; + #endif /* _SDL_winrtvideo_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDLmain_WinRT_common.h b/src/video/windowsrt/SDLmain_WinRT_common.h index 5e50662ab..4867b7a94 100644 --- a/src/video/windowsrt/SDLmain_WinRT_common.h +++ b/src/video/windowsrt/SDLmain_WinRT_common.h @@ -10,3 +10,6 @@ extern "C" { #include "../SDL_sysvideo.h" } + +#include "SDL_winrtvideo.h" + From c80b755392027c7a92b083666ffd065e90942666 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 28 Oct 2012 23:20:18 -0400 Subject: [PATCH 028/264] WinRT: explicitly allowed only one window at a time, pending multimonitor support (in SDL/WinRT) --- src/video/windowsrt/SDL_WinRTApp.cpp | 5 +++++ src/video/windowsrt/SDL_WinRTApp.h | 1 + src/video/windowsrt/SDL_winrtvideo.cpp | 14 +++++++++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index e53e0fca5..45b1ba30b 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -198,6 +198,11 @@ SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode() return mode; } +bool SDL_WinRTApp::HasSDLWindowData() const +{ + return (m_sdlWindowData != NULL); +} + void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData) { m_sdlWindowData = windowData; diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index f7fc29b40..68daeb3b8 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -23,6 +23,7 @@ internal: // SDL-specific methods SDL_DisplayMode GetMainDisplayMode(); void PumpEvents(); + bool HasSDLWindowData() const; void SetSDLWindowData(const SDL_WindowData* windowData); protected: diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index e69826383..ec67c9570 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -137,8 +137,13 @@ WINRT_VideoQuit(_THIS) int WINRT_CreateWindow(_THIS, SDL_Window * window) { - // TODO, WinRT: modify WINRT_Createwindow to ensure that, for now, only one window gets created - // (until multimonitor support is added to the WinRT port). + // 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; data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); @@ -163,7 +168,10 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) void WINRT_DestroyWindow(_THIS, SDL_Window * window) { - SDL_WinRTGlobalApp->SetSDLWindowData(NULL); + if (SDL_WinRTGlobalApp->HasSDLWindowData()) + { + SDL_WinRTGlobalApp->SetSDLWindowData(NULL); + } } From 5558c97e6ab8a9250753c28cec544af5abdee878 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 29 Oct 2012 23:32:13 -0400 Subject: [PATCH 029/264] WinRT: fixed bug whereby attempting to create a 2nd window (which intentionall fails, for now) would cause mouse input to stop working --- src/video/windowsrt/SDL_WinRTApp.cpp | 5 +++++ src/video/windowsrt/SDL_WinRTApp.h | 3 ++- src/video/windowsrt/SDL_winrtvideo.cpp | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 45b1ba30b..480eda734 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -198,6 +198,11 @@ SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode() return mode; } +const SDL_WindowData * SDL_WinRTApp::GetSDLWindowData() const +{ + return m_sdlWindowData; +} + bool SDL_WinRTApp::HasSDLWindowData() const { return (m_sdlWindowData != NULL); diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 68daeb3b8..af9d0bd22 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -23,8 +23,9 @@ internal: // SDL-specific methods SDL_DisplayMode GetMainDisplayMode(); void PumpEvents(); + const SDL_WindowData * GetSDLWindowData() const; bool HasSDLWindowData() const; - void SetSDLWindowData(const SDL_WindowData* windowData); + void SetSDLWindowData(const SDL_WindowData * windowData); protected: // Event Handlers. diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index ec67c9570..16a0474b9 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -168,7 +168,8 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) void WINRT_DestroyWindow(_THIS, SDL_Window * window) { - if (SDL_WinRTGlobalApp->HasSDLWindowData()) + if (SDL_WinRTGlobalApp->HasSDLWindowData() && + SDL_WinRTGlobalApp->GetSDLWindowData()->sdlWindow == window) { SDL_WinRTGlobalApp->SetSDLWindowData(NULL); } From eb890561fbc0fdd614f8ed8161e676c775d9bd8e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 4 Nov 2012 09:02:58 -0500 Subject: [PATCH 030/264] WinRT: added key event support for most WinRT/VirtualKey-based keys --- src/video/windowsrt/SDL_WinRTApp.cpp | 225 +++++++++++++++++++++++++++ src/video/windowsrt/SDL_WinRTApp.h | 2 + 2 files changed, 227 insertions(+) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 480eda734..38304436c 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -6,6 +6,7 @@ extern "C" { #include "SDL_stdinc.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" #include "SDL_events.h" #include "SDL_log.h" } @@ -78,6 +79,13 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerMoved += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + window->KeyDown += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); + + window->KeyUp += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); + + m_renderer->Initialize(CoreWindow::GetForCurrentThread()); } @@ -158,6 +166,223 @@ void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) } } +static SDL_Scancode WinRT_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_UNKNOWN, // VirtualKey.Back -- 8 (maybe SDL_SCANCODE_AC_BACK ?) + 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 SDL_Scancode +TranslateKeycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + if (keycode < SDL_arraysize(WinRT_Keycodes)) { + scancode = WinRT_Keycodes[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) +{ +#if 0 + SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\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); + //args->Handled = true; + //VirtualKey vkey = args->VirtualKey; +#endif + SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode((int)args->VirtualKey)); +} + +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ +#if 0 + SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\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); + //args->Handled = true; +#endif + SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode((int)args->VirtualKey)); +} + void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { CoreWindow::GetForCurrentThread()->Activate(); diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index af9d0bd22..09cf520c5 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -39,6 +39,8 @@ protected: 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 OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ 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: CubeRenderer^ m_renderer; From 1350bd023bd10dbd0f559dd1489fd4957368625b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 4 Nov 2012 13:17:18 -0500 Subject: [PATCH 031/264] WinRT: fixed SDL_main-related linker error when __WINRT__ is defined in an app --- include/SDL_main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_main.h b/include/SDL_main.h index b9d252b26..9f46012a8 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -30,7 +30,7 @@ * Redefine main() on some platforms so that it is called by SDL. */ -#if defined(__WIN32__) || defined(__IPHONEOS__) || defined(__ANDROID__) +#if defined(__WIN32__) || defined(__WINRT__) || defined(__IPHONEOS__) || defined(__ANDROID__) #ifndef SDL_MAIN_HANDLED #define SDL_MAIN_NEEDED #endif From 77dbd7ef65143f6a4c319d794e1b91173649b2fa Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 4 Nov 2012 13:26:53 -0500 Subject: [PATCH 032/264] WinRT: build fix for SDL_assert.c --- src/SDL_assert.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL_assert.c b/src/SDL_assert.c index 1d0fd0539..abeb4e65d 100644 --- a/src/SDL_assert.c +++ b/src/SDL_assert.c @@ -37,8 +37,10 @@ #else /* fprintf, _exit(), etc. */ #include #include +#if ! defined(__WINRT__) #include #endif +#endif static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); From aea759fc68184fe839df2c0d59416f3027bdad0f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 18 Nov 2012 23:29:52 -0500 Subject: [PATCH 033/264] WinRT: started work on renderer by getting Direct3D 11.1 to display a single, fullscreen rectangle --HG-- rename : src/video/windowsrt/CubeRenderer.cpp => src/video/windowsrt/SDL_winrtrenderer.cpp rename : src/video/windowsrt/CubeRenderer.h => src/video/windowsrt/SDL_winrtrenderer.h --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 27 +++-- src/video/windowsrt/SDL_WinRTApp.cpp | 18 ++- src/video/windowsrt/SDL_WinRTApp.h | 5 +- src/video/windowsrt/SDL_winrtframebuffer.cpp | 6 + ...CubeRenderer.cpp => SDL_winrtrenderer.cpp} | 110 +++--------------- .../{CubeRenderer.h => SDL_winrtrenderer.h} | 9 +- 6 files changed, 62 insertions(+), 113 deletions(-) rename src/video/windowsrt/{CubeRenderer.cpp => SDL_winrtrenderer.cpp} (54%) rename src/video/windowsrt/{CubeRenderer.h => SDL_winrtrenderer.h} (78%) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index fd95bea51..479d3c71b 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -101,14 +101,6 @@ - - true - true - true - true - true - true - true true @@ -133,7 +125,22 @@ true true - + + true + true + true + true + true + true + + + true + true + true + true + true + true + true true @@ -245,13 +252,13 @@ - + diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 38304436c..dcf0b2472 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -11,6 +11,9 @@ extern "C" { #include "SDL_log.h" } +// TODO, WinRT: Remove reference(s) to BasicTimer.h +#include "BasicTimer.h" + // 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. @@ -54,7 +57,7 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Resuming += ref new EventHandler(this, &SDL_WinRTApp::OnResuming); - m_renderer = ref new CubeRenderer(); + m_renderer = ref new SDL_winrtrenderer(); } void SDL_WinRTApp::SetWindow(CoreWindow^ window) @@ -112,9 +115,6 @@ void SDL_WinRTApp::PumpEvents() if (m_windowVisible) { CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); - m_renderer->Update(0.0f, 0.0f); - m_renderer->Render(); - m_renderer->Present(); // This call is synchronized to the display frame rate. } else { @@ -123,6 +123,16 @@ void SDL_WinRTApp::PumpEvents() } } +void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects) +{ + if (!m_windowClosed && m_windowVisible) + { + m_renderer->Update(0.0f, 0.0f); + m_renderer->Render(); + m_renderer->Present(); // This call is synchronized to the display frame rate. + } +} + void SDL_WinRTApp::Uninitialize() { } diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 09cf520c5..333f734ba 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -2,7 +2,7 @@ #include "SDLmain_WinRT_common.h" #include "SDL_winrtvideo.h" -#include "CubeRenderer.h" +#include "SDL_winrtrenderer.h" #include using namespace Windows::UI::Core; @@ -26,6 +26,7 @@ internal: const SDL_WindowData * GetSDLWindowData() const; bool HasSDLWindowData() const; void SetSDLWindowData(const SDL_WindowData * windowData); + void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects); protected: // Event Handlers. @@ -43,7 +44,7 @@ protected: void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); private: - CubeRenderer^ m_renderer; + SDL_winrtrenderer^ m_renderer; bool m_windowClosed; bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; diff --git a/src/video/windowsrt/SDL_winrtframebuffer.cpp b/src/video/windowsrt/SDL_winrtframebuffer.cpp index 2426eac0f..555a195d9 100644 --- a/src/video/windowsrt/SDL_winrtframebuffer.cpp +++ b/src/video/windowsrt/SDL_winrtframebuffer.cpp @@ -24,6 +24,9 @@ #include "../SDL_sysvideo.h" #include "SDL_winrtframebuffer_c.h" +#include "SDL_WinRTApp.h" + +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; #define WINRT_SURFACE "_SDL_WinRTSurface" @@ -76,6 +79,9 @@ int SDL_WINRT_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rec SDL_GetWindowID(window), ++frame_number); SDL_SaveBMP(surface, file); } + + SDL_WinRTGlobalApp->UpdateWindowFramebuffer(surface, rects, numrects); + return 0; } diff --git a/src/video/windowsrt/CubeRenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp similarity index 54% rename from src/video/windowsrt/CubeRenderer.cpp rename to src/video/windowsrt/SDL_winrtrenderer.cpp index 52e858607..fae779ce4 100644 --- a/src/video/windowsrt/CubeRenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -1,18 +1,18 @@ #include "SDLmain_WinRT_common.h" -#include "CubeRenderer.h" +#include "SDL_winrtrenderer.h" using namespace DirectX; using namespace Microsoft::WRL; using namespace Windows::Foundation; using namespace Windows::UI::Core; -CubeRenderer::CubeRenderer() : +SDL_winrtrenderer::SDL_winrtrenderer() : m_loadingComplete(false), - m_indexCount(0) + m_vertexCount(0) { } -void CubeRenderer::CreateDeviceResources() +void SDL_winrtrenderer::CreateDeviceResources() { Direct3DBase::CreateDeviceResources(); @@ -69,16 +69,14 @@ void CubeRenderer::CreateDeviceResources() auto createCubeTask = (createPSTask && createVSTask).then([this] () { VertexPositionColor cubeVertices[] = { - {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f)}, - {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f)}, - {XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f)}, - {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f)}, - {XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f)}, - {XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f)}, - {XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f)}, - {XMFLOAT3( 0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f)}, }; + m_vertexCount = ARRAYSIZE(cubeVertices); + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; vertexBufferData.pSysMem = cubeVertices; vertexBufferData.SysMemPitch = 0; @@ -91,42 +89,6 @@ void CubeRenderer::CreateDeviceResources() &m_vertexBuffer ) ); - - unsigned short cubeIndices[] = - { - 0,2,1, // -x - 1,2,3, - - 4,5,6, // +x - 5,7,6, - - 0,1,5, // -y - 0,5,4, - - 2,6,7, // +y - 2,7,3, - - 0,4,6, // -z - 0,6,2, - - 1,3,7, // +z - 1,7,5, - }; - - m_indexCount = ARRAYSIZE(cubeIndices); - - D3D11_SUBRESOURCE_DATA indexBufferData = {0}; - indexBufferData.pSysMem = cubeIndices; - indexBufferData.SysMemPitch = 0; - indexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER); - DX::ThrowIfFailed( - m_d3dDevice->CreateBuffer( - &indexBufferDesc, - &indexBufferData, - &m_indexBuffer - ) - ); }); createCubeTask.then([this] () { @@ -134,35 +96,7 @@ void CubeRenderer::CreateDeviceResources() }); } -void CubeRenderer::CreateWindowSizeDependentResources() -{ - Direct3DBase::CreateWindowSizeDependentResources(); - - float aspectRatio = m_windowBounds.Width / m_windowBounds.Height; - float fovAngleY = 70.0f * XM_PI / 180.0f; - - // Note that the m_orientationTransform3D matrix is post-multiplied here - // in order to correctly orient the scene to match the display orientation. - // This post-multiplication step is required for any draw calls that are - // made to the swap chain render target. For draw calls to other targets, - // this transform should not be applied. - XMStoreFloat4x4( - &m_constantBufferData.projection, - XMMatrixTranspose( - XMMatrixMultiply( - XMMatrixPerspectiveFovRH( - fovAngleY, - aspectRatio, - 0.01f, - 100.0f - ), - XMLoadFloat4x4(&m_orientationTransform3D) - ) - ) - ); -} - -void CubeRenderer::Update(float timeTotal, float timeDelta) +void SDL_winrtrenderer::Update(float timeTotal, float timeDelta) { (void) timeDelta; // Unused parameter. @@ -170,11 +104,11 @@ void CubeRenderer::Update(float timeTotal, float timeDelta) XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f); XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); - XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up))); - XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4))); + XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixIdentity()); + XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixIdentity()); } -void CubeRenderer::Render() +void SDL_winrtrenderer::Render() { const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f }; m_d3dContext->ClearRenderTargetView( @@ -195,6 +129,8 @@ void CubeRenderer::Render() return; } + m_d3dContext->RSSetState(m_rasterState.Get()); + m_d3dContext->OMSetRenderTargets( 1, m_renderTargetView.GetAddressOf(), @@ -220,13 +156,7 @@ void CubeRenderer::Render() &offset ); - m_d3dContext->IASetIndexBuffer( - m_indexBuffer.Get(), - DXGI_FORMAT_R16_UINT, - 0 - ); - - m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); m_d3dContext->IASetInputLayout(m_inputLayout.Get()); @@ -248,9 +178,5 @@ void CubeRenderer::Render() 0 ); - m_d3dContext->DrawIndexed( - m_indexCount, - 0, - 0 - ); + m_d3dContext->Draw(4, 0); } diff --git a/src/video/windowsrt/CubeRenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h similarity index 78% rename from src/video/windowsrt/CubeRenderer.h rename to src/video/windowsrt/SDL_winrtrenderer.h index b3ce23001..3a51d0a94 100644 --- a/src/video/windowsrt/CubeRenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,14 +16,13 @@ struct VertexPositionColor }; // This class renders a simple spinning cube. -ref class CubeRenderer sealed : public Direct3DBase +ref class SDL_winrtrenderer sealed : public Direct3DBase { public: - CubeRenderer(); + SDL_winrtrenderer(); // Direct3DBase methods. virtual void CreateDeviceResources() override; - virtual void CreateWindowSizeDependentResources() override; virtual void Render() override; // Method for updating time-dependent objects. @@ -34,11 +33,11 @@ private: Microsoft::WRL::ComPtr m_inputLayout; Microsoft::WRL::ComPtr m_vertexBuffer; - Microsoft::WRL::ComPtr m_indexBuffer; Microsoft::WRL::ComPtr m_vertexShader; Microsoft::WRL::ComPtr m_pixelShader; Microsoft::WRL::ComPtr m_constantBuffer; + Microsoft::WRL::ComPtr m_rasterState; - uint32 m_indexCount; + uint32 m_vertexCount; ModelViewProjectionConstantBuffer m_constantBufferData; }; From 02e3f1827748906f3e38dd2d78fe93fb989b1ff1 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 19 Nov 2012 22:30:00 -0500 Subject: [PATCH 034/264] WinRT: removed unused 4x4 matrix code from SDL_winrtrenderer --- src/video/windowsrt/SDL_WinRTApp.cpp | 1 - src/video/windowsrt/SDL_winrtrenderer.cpp | 36 ----------------------- src/video/windowsrt/SDL_winrtrenderer.h | 11 ------- 3 files changed, 48 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index dcf0b2472..5c67c5fcc 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -127,7 +127,6 @@ void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rec { if (!m_windowClosed && m_windowVisible) { - m_renderer->Update(0.0f, 0.0f); m_renderer->Render(); m_renderer->Present(); // This call is synchronized to the display frame rate. } diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index fae779ce4..a9d81111f 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -55,15 +55,6 @@ void SDL_winrtrenderer::CreateDeviceResources() &m_pixelShader ) ); - - CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER); - DX::ThrowIfFailed( - m_d3dDevice->CreateBuffer( - &constantBufferDesc, - nullptr, - &m_constantBuffer - ) - ); }); auto createCubeTask = (createPSTask && createVSTask).then([this] () { @@ -96,18 +87,6 @@ void SDL_winrtrenderer::CreateDeviceResources() }); } -void SDL_winrtrenderer::Update(float timeTotal, float timeDelta) -{ - (void) timeDelta; // Unused parameter. - - XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f); - XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f); - XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); - - XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixIdentity()); - XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixIdentity()); -} - void SDL_winrtrenderer::Render() { const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f }; @@ -137,15 +116,6 @@ void SDL_winrtrenderer::Render() m_depthStencilView.Get() ); - m_d3dContext->UpdateSubresource( - m_constantBuffer.Get(), - 0, - NULL, - &m_constantBufferData, - 0, - 0 - ); - UINT stride = sizeof(VertexPositionColor); UINT offset = 0; m_d3dContext->IASetVertexBuffers( @@ -166,12 +136,6 @@ void SDL_winrtrenderer::Render() 0 ); - m_d3dContext->VSSetConstantBuffers( - 0, - 1, - m_constantBuffer.GetAddressOf() - ); - m_d3dContext->PSSetShader( m_pixelShader.Get(), nullptr, diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 3a51d0a94..e7ad7c36e 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -2,13 +2,6 @@ #include "Direct3DBase.h" -struct ModelViewProjectionConstantBuffer -{ - DirectX::XMFLOAT4X4 model; - DirectX::XMFLOAT4X4 view; - DirectX::XMFLOAT4X4 projection; -}; - struct VertexPositionColor { DirectX::XMFLOAT3 pos; @@ -24,9 +17,6 @@ public: // Direct3DBase methods. virtual void CreateDeviceResources() override; virtual void Render() override; - - // Method for updating time-dependent objects. - void Update(float timeTotal, float timeDelta); private: bool m_loadingComplete; @@ -39,5 +29,4 @@ private: Microsoft::WRL::ComPtr m_rasterState; uint32 m_vertexCount; - ModelViewProjectionConstantBuffer m_constantBufferData; }; From 48df03fc3a38ecc20729a2bf258eb76e189ca890 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Nov 2012 08:12:12 -0500 Subject: [PATCH 035/264] WinRT: minor code cleanups --- src/video/windowsrt/SDL_winrtrenderer.cpp | 2 -- src/video/windowsrt/SDL_winrtrenderer.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index a9d81111f..9f9c77e0c 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -108,8 +108,6 @@ void SDL_winrtrenderer::Render() return; } - m_d3dContext->RSSetState(m_rasterState.Get()); - m_d3dContext->OMSetRenderTargets( 1, m_renderTargetView.GetAddressOf(), diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index e7ad7c36e..9b848f2fb 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -25,8 +25,6 @@ private: Microsoft::WRL::ComPtr m_vertexBuffer; Microsoft::WRL::ComPtr m_vertexShader; Microsoft::WRL::ComPtr m_pixelShader; - Microsoft::WRL::ComPtr m_constantBuffer; - Microsoft::WRL::ComPtr m_rasterState; uint32 m_vertexCount; }; From 295d3e1ab2637799901b4e9a16a4670c89fa0fb5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Nov 2012 08:46:10 -0500 Subject: [PATCH 036/264] WinRT: included shaders in SDL library (moved from SDLWinRTTestApp) --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 18 ++++++++++++++++++ src/video/windowsrt/SDL_winrtrenderer.cpp | 4 ++-- src/video/windowsrt/SimpleVertexShader.hlsl | 19 +++---------------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 479d3c71b..aedcb381f 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -261,6 +261,24 @@ + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + + + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} Win32Proj diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 9f9c77e0c..800ae9fe2 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -16,8 +16,8 @@ void SDL_winrtrenderer::CreateDeviceResources() { Direct3DBase::CreateDeviceResources(); - auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso"); - auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso"); + auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); + auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { DX::ThrowIfFailed( diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index f4ef86899..a0ea29fbb 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -1,9 +1,5 @@ -cbuffer ModelViewProjectionConstantBuffer : register(b0) -{ - matrix model; - matrix view; - matrix projection; -}; + +//#pragma pack_matrix( row_major ) struct VertexShaderInput { @@ -20,16 +16,7 @@ struct VertexShaderOutput 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 the color without modification. + output.pos = float4(input.pos, 1.0f); output.color = input.color; - return output; } From e7cfa06cb731d2ba91cef6fa2d0c4ac11976d940 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 21 Nov 2012 17:07:48 -0500 Subject: [PATCH 037/264] WinRT: made the fullscreen display be backed by a texture --- src/video/windowsrt/SDL_winrtrenderer.cpp | 85 +++++++++++++++++++-- src/video/windowsrt/SDL_winrtrenderer.h | 4 + src/video/windowsrt/SimplePixelShader.hlsl | 7 +- src/video/windowsrt/SimpleVertexShader.hlsl | 3 + 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 800ae9fe2..24a3ba60a 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -33,6 +33,7 @@ void SDL_winrtrenderer::CreateDeviceResources() { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; DX::ThrowIfFailed( @@ -60,10 +61,10 @@ void SDL_winrtrenderer::CreateDeviceResources() auto createCubeTask = (createPSTask && createVSTask).then([this] () { VertexPositionColor cubeVertices[] = { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f)}, }; m_vertexCount = ARRAYSIZE(cubeVertices); @@ -82,7 +83,77 @@ void SDL_winrtrenderer::CreateDeviceResources() ); }); - createCubeTask.then([this] () { + auto createMainTextureTask = createCubeTask.then([this] () { + D3D11_TEXTURE2D_DESC textureDesc = {0}; + textureDesc.Width = (int)m_windowBounds.Width; + textureDesc.Height = (int)m_windowBounds.Height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DYNAMIC; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + textureDesc.MiscFlags = 0; + + int numPixels = (int)m_windowBounds.Width * (int)m_windowBounds.Height; + std::vector initialTexturePixels(numPixels * 4); + for (int i = 0; i < (numPixels * 4); i += 4) { + initialTexturePixels[i+0] = 0xFF; + initialTexturePixels[i+1] = 0x00; + initialTexturePixels[i+2] = 0x00; + initialTexturePixels[i+3] = 0xFF; + } + D3D11_SUBRESOURCE_DATA initialTextureData = {0}; + initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); + initialTextureData.SysMemPitch = (int)m_windowBounds.Width * 4; + initialTextureData.SysMemSlicePitch = numPixels * 4; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &textureDesc, + &initialTextureData, + &m_mainTexture + ) + ); + + 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; + DX::ThrowIfFailed( + m_d3dDevice->CreateShaderResourceView( + m_mainTexture.Get(), + &resourceViewDesc, + &m_mainTextureResourceView) + ); + }); + + auto createMainSamplerTask = createMainTextureTask.then([this] () { + 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; + DX::ThrowIfFailed( + m_d3dDevice->CreateSamplerState( + &samplerDesc, + &m_mainSampler + ) + ); + }); + + createMainSamplerTask.then([this] () { m_loadingComplete = true; }); } @@ -140,5 +211,9 @@ void SDL_winrtrenderer::Render() 0 ); + m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf()); + + m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf()); + m_d3dContext->Draw(4, 0); } diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 9b848f2fb..92a0c9b2f 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -6,6 +6,7 @@ struct VertexPositionColor { DirectX::XMFLOAT3 pos; DirectX::XMFLOAT3 color; + DirectX::XMFLOAT2 tex; }; // This class renders a simple spinning cube. @@ -25,6 +26,9 @@ private: Microsoft::WRL::ComPtr m_vertexBuffer; Microsoft::WRL::ComPtr m_vertexShader; Microsoft::WRL::ComPtr m_pixelShader; + Microsoft::WRL::ComPtr m_mainTexture; + Microsoft::WRL::ComPtr m_mainTextureResourceView; + Microsoft::WRL::ComPtr m_mainSampler; uint32 m_vertexCount; }; diff --git a/src/video/windowsrt/SimplePixelShader.hlsl b/src/video/windowsrt/SimplePixelShader.hlsl index a9142692e..2bf42bd71 100644 --- a/src/video/windowsrt/SimplePixelShader.hlsl +++ b/src/video/windowsrt/SimplePixelShader.hlsl @@ -1,10 +1,15 @@ +Texture2D theTexture : register(t0); +SamplerState theSampler : register(s0); + struct PixelShaderInput { float4 pos : SV_POSITION; float3 color : COLOR0; + float2 tex : TEXCOORD0; }; float4 main(PixelShaderInput input) : SV_TARGET { - return float4(input.color,1.0f); + //return float4(input.color,1.0f); + return theTexture.Sample(theSampler, input.tex); } diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index a0ea29fbb..b92b79010 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -5,12 +5,14 @@ struct VertexShaderInput { float3 pos : POSITION; float3 color : COLOR0; + float2 tex : TEXCOORD0; }; struct VertexShaderOutput { float4 pos : SV_POSITION; float3 color : COLOR0; + float2 tex : TEXCOORD0; }; VertexShaderOutput main(VertexShaderInput input) @@ -18,5 +20,6 @@ VertexShaderOutput main(VertexShaderInput input) VertexShaderOutput output; output.pos = float4(input.pos, 1.0f); output.color = input.color; + output.tex = input.tex; return output; } From e5b56efc86e1dfa2ca7c4043a114fdf4dcbd92b5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 21 Nov 2012 17:19:16 -0500 Subject: [PATCH 038/264] WinRT: removed now-unused 'color' parameter from shaders --- src/video/windowsrt/SDL_winrtrenderer.cpp | 11 +++++------ src/video/windowsrt/SDL_winrtrenderer.h | 1 - src/video/windowsrt/SimplePixelShader.hlsl | 2 +- src/video/windowsrt/SimpleVertexShader.hlsl | 3 --- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 24a3ba60a..d87589c11 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -32,8 +32,7 @@ void SDL_winrtrenderer::CreateDeviceResources() const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; DX::ThrowIfFailed( @@ -61,10 +60,10 @@ void SDL_winrtrenderer::CreateDeviceResources() auto createCubeTask = (createPSTask && createVSTask).then([this] () { VertexPositionColor cubeVertices[] = { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, }; m_vertexCount = ARRAYSIZE(cubeVertices); diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 92a0c9b2f..592fc7884 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -5,7 +5,6 @@ struct VertexPositionColor { DirectX::XMFLOAT3 pos; - DirectX::XMFLOAT3 color; DirectX::XMFLOAT2 tex; }; diff --git a/src/video/windowsrt/SimplePixelShader.hlsl b/src/video/windowsrt/SimplePixelShader.hlsl index 2bf42bd71..d2f6c58bb 100644 --- a/src/video/windowsrt/SimplePixelShader.hlsl +++ b/src/video/windowsrt/SimplePixelShader.hlsl @@ -4,7 +4,7 @@ SamplerState theSampler : register(s0); struct PixelShaderInput { float4 pos : SV_POSITION; - float3 color : COLOR0; + float2 tex : TEXCOORD0; }; diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index b92b79010..bde60b3a7 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -4,14 +4,12 @@ struct VertexShaderInput { float3 pos : POSITION; - float3 color : COLOR0; float2 tex : TEXCOORD0; }; struct VertexShaderOutput { float4 pos : SV_POSITION; - float3 color : COLOR0; float2 tex : TEXCOORD0; }; @@ -19,7 +17,6 @@ VertexShaderOutput main(VertexShaderInput input) { VertexShaderOutput output; output.pos = float4(input.pos, 1.0f); - output.color = input.color; output.tex = input.tex; return output; } From 4686ec5943013f83928b31c496b718effae48dca Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 21 Nov 2012 17:38:17 -0500 Subject: [PATCH 039/264] WinRT: added code to update the main texture on each frame with dummy data --- src/video/windowsrt/SDL_winrtrenderer.cpp | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index d87589c11..a7b2a1acc 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -178,6 +178,30 @@ void SDL_winrtrenderer::Render() return; } + // Update the main texture (for SDL usage): + D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; + DX::ThrowIfFailed( + m_d3dContext->Map( + m_mainTexture.Get(), + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + &textureMemory) + ); + + const int max = (int)m_windowBounds.Width * (int)m_windowBounds.Height * 4; + uint8 * buf = (uint8 *)textureMemory.pData; + for (int i = 0; i < max; i += 4) { + buf[i+0] = 0x00; + buf[i+1] = 0xFF; + buf[i+2] = 0x00; + buf[i+3] = 0xFF; + } + + m_d3dContext->Unmap( + m_mainTexture.Get(), + 0); + m_d3dContext->OMSetRenderTargets( 1, m_renderTargetView.GetAddressOf(), From 3c39c559062fb9bdb1eb5f932dc1c06cb1528884 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 21 Nov 2012 23:44:58 -0500 Subject: [PATCH 040/264] WinRT: got SDL_UpdateWindowSurface working, rudimentarily --- src/video/windowsrt/Direct3DBase.h | 5 ++- src/video/windowsrt/SDL_WinRTApp.cpp | 2 +- src/video/windowsrt/SDL_winrtframebuffer.cpp | 2 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 36 +++++++------------- src/video/windowsrt/SDL_winrtrenderer.h | 4 ++- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/video/windowsrt/Direct3DBase.h b/src/video/windowsrt/Direct3DBase.h index 9a095dc87..eab1a178e 100644 --- a/src/video/windowsrt/Direct3DBase.h +++ b/src/video/windowsrt/Direct3DBase.h @@ -1,6 +1,7 @@ #pragma once #include "DirectXHelper.h" +#include "SDL.h" // Helper class that initializes DirectX APIs for 3D rendering. ref class Direct3DBase abstract @@ -14,10 +15,12 @@ public: virtual void CreateDeviceResources(); virtual void CreateWindowSizeDependentResources(); virtual void UpdateForWindowSizeChange(); - virtual void Render() = 0; virtual void Present(); virtual float ConvertDipsToPixels(float dips); +internal: + virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) = 0; + protected private: // Direct3D Objects. Microsoft::WRL::ComPtr m_d3dDevice; diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 5c67c5fcc..dc8cac9b9 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -127,7 +127,7 @@ void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rec { if (!m_windowClosed && m_windowVisible) { - m_renderer->Render(); + m_renderer->Render(surface, rects, numrects); m_renderer->Present(); // This call is synchronized to the display frame rate. } } diff --git a/src/video/windowsrt/SDL_winrtframebuffer.cpp b/src/video/windowsrt/SDL_winrtframebuffer.cpp index 555a195d9..ae6132ac3 100644 --- a/src/video/windowsrt/SDL_winrtframebuffer.cpp +++ b/src/video/windowsrt/SDL_winrtframebuffer.cpp @@ -34,7 +34,7 @@ extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_Surface *surface; - const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; + const Uint32 surface_format = SDL_PIXELFORMAT_ARGB8888; int w, h; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index a7b2a1acc..2e2ab206c 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -60,10 +60,10 @@ void SDL_winrtrenderer::CreateDeviceResources() auto createCubeTask = (createPSTask && createVSTask).then([this] () { VertexPositionColor cubeVertices[] = { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, }; m_vertexCount = ARRAYSIZE(cubeVertices); @@ -96,14 +96,8 @@ void SDL_winrtrenderer::CreateDeviceResources() textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; textureDesc.MiscFlags = 0; - int numPixels = (int)m_windowBounds.Width * (int)m_windowBounds.Height; - std::vector initialTexturePixels(numPixels * 4); - for (int i = 0; i < (numPixels * 4); i += 4) { - initialTexturePixels[i+0] = 0xFF; - initialTexturePixels[i+1] = 0x00; - initialTexturePixels[i+2] = 0x00; - initialTexturePixels[i+3] = 0xFF; - } + const int numPixels = (int)m_windowBounds.Width * (int)m_windowBounds.Height; + std::vector initialTexturePixels(numPixels * 4, 0x00); D3D11_SUBRESOURCE_DATA initialTextureData = {0}; initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); initialTextureData.SysMemPitch = (int)m_windowBounds.Width * 4; @@ -157,12 +151,12 @@ void SDL_winrtrenderer::CreateDeviceResources() }); } -void SDL_winrtrenderer::Render() +void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { - const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f }; + const float blackColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; m_d3dContext->ClearRenderTargetView( m_renderTargetView.Get(), - midnightBlue + blackColor ); m_d3dContext->ClearDepthStencilView( @@ -189,14 +183,10 @@ void SDL_winrtrenderer::Render() &textureMemory) ); - const int max = (int)m_windowBounds.Width * (int)m_windowBounds.Height * 4; - uint8 * buf = (uint8 *)textureMemory.pData; - for (int i = 0; i < max; i += 4) { - buf[i+0] = 0x00; - buf[i+1] = 0xFF; - buf[i+2] = 0x00; - buf[i+3] = 0xFF; - } + // TODO, WinRT: only copy over the requested rects (via SDL_BlitSurface, perhaps?) + // TODO, WinRT: do a sanity check on the src and dest data when updating the window surface + const unsigned int numBytes = (int)m_windowBounds.Width * (int)m_windowBounds.Height * 4; + memcpy(textureMemory.pData, surface->pixels, numBytes); m_d3dContext->Unmap( m_mainTexture.Get(), diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 592fc7884..bcdce2bac 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,7 +16,9 @@ public: // Direct3DBase methods. virtual void CreateDeviceResources() override; - virtual void Render() override; + +internal: + virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) override; private: bool m_loadingComplete; From 6613556cc1b6f342d4d0b56d47dc6ce8226dead5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 12:37:31 -0500 Subject: [PATCH 041/264] WinRT: added a VC++ 2012 project to help compile the loopwave test --- VisualC/tests/loopwave/WinRT/Assets/Logo.png | Bin 0 -> 801 bytes .../tests/loopwave/WinRT/Assets/SmallLogo.png | Bin 0 -> 329 bytes .../loopwave/WinRT/Assets/SplashScreen.png | Bin 0 -> 2146 bytes .../tests/loopwave/WinRT/Assets/StoreLogo.png | Bin 0 -> 429 bytes .../tests/loopwave/WinRT/Package.appxmanifest | 42 +++++ .../WinRT/loopwave_VS2012_WinRT.vcxproj | 156 ++++++++++++++++++ .../loopwave_VS2012_WinRT_TemporaryKey.pfx | Bin 0 -> 2504 bytes 7 files changed, 198 insertions(+) create mode 100644 VisualC/tests/loopwave/WinRT/Assets/Logo.png create mode 100644 VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png create mode 100644 VisualC/tests/loopwave/WinRT/Assets/SplashScreen.png create mode 100644 VisualC/tests/loopwave/WinRT/Assets/StoreLogo.png create mode 100644 VisualC/tests/loopwave/WinRT/Package.appxmanifest create mode 100644 VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj create mode 100644 VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx diff --git a/VisualC/tests/loopwave/WinRT/Assets/Logo.png b/VisualC/tests/loopwave/WinRT/Assets/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e26771cb33a49bbef824aa333737181b0a5b09a3 GIT binary patch literal 801 zcmeAS@N?(olHy`uVBq!ia0y~yV3-EN9Bd2>3^t5~j~EyjBuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFdg=EaSW-r_2%wgUu8#$hQvKeC6ZGdoyuYz>I5fd zD=cCVTGw#;WJV*C#^Im$BqU!l<@MGW@3y}Geb1#+jk-7IRhn$x_Gh!?@sCcc?j~@s zOgkVHAr!&no#2_ksne+1sJek=8nJ>RyH5AXyMu zC7zPUKdy?gnUnO4V8$neR!%tOJt2)L8_xD-?dqVQ-9w} za}*W2CRLc~EGl+wR>9xaS6bYwE^N5gpsl^?!-i=`rb>o#MR-3r)u+X~#33yiC?y&ms@MYs>e-SYhLYGz_i**Z^eOC zeJDbl>x$kiU|P+(E_=m+tVWR3!>ZrMukP;^h)56hyH*~bQ$N4;*Hq~Z&s@JIKT?a{ zabQ)W))oGV4O^8$p3ZsAtG6L*@vZq4+Dv*I&N-JpTFbHHfR(&xOoFL1t9ZoOfP<`I z#vuibS9wHZ5^5LiTHVXF?#YHzPvji#ZgXG_4~lRP**$H=12490zmNje#;q(`JDLth z35Ax$I2(ohwhT-?X6nEy9`V0F>tcP<*_P}EF1-y_?o&ChGl<3{usTj@E4ojhO{hc-m9E3cS|J`^!QH9JN2zXQG42fN#|}{%2nKyL~^3QpM0V= c*)#DloQf}5saF0GlnEF-UHx3vIVCg!0HVrD82|tP literal 0 HcmV?d00001 diff --git a/VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png b/VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb0d9d528c42f132872e8af4dc563081b0b9aff GIT binary patch literal 329 zcmV-P0k-~$P)q$gGRCwC#*X;?zAP@%N+|i#I!$mrh zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+ zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8dx}oD(QadjT^N|8cJC5vMb z^;+Y&#s!EZnzTfuGZ>R@w4o3y#%!Y$jekOQmfA%J`hl5EP}C1BM$CJE)-y81=%=^O z@80)$pZED)?~QEkY$q#il>k6?Y;tV@s0aWU8q6jDc=4Vq(*RI2(8>>N-MM{Wuy>ai zTKaYhUZx}1yTiN1+uJwv?8n|_0JE{f)$;i6(!w`Q{ZpK^wd;|qxw&Fj;lN$_)B}4r zoqOB-dhWSz53hUY$kfIj{;Av-pMEetZv<|9bv*zT05G!vlO_;71aL`%42|>>WQu?g z!layq5Q|iZMay$w7E<0ihpuszr>Ua2&~HqhdUegj^W9|`8lz6e{Wkj2RHpxz=9g-S zug2yVukFr6jfYNG(ud|3e?LN`OlFn}G6gPah?5$CNmHE6+RQAMt}6r2@tDtD^&qDI0smd#*X{s5nM5zz*+@7xkD9o z@`85qj9T6Jkji(*ok6ADs(q@|740!){_v=(XHub|lvMbyP<*qY4c4~K)TfUQpL>7( z?CdW21r4BhGnf^f%Rv065T%Rnz5B+7)gvpZ z09>d2agqwa3c;N=gvqzKM1UnT`4gBh7_)OHlL> z_fr3+xmwH={{J6qPz`FM0-_=<`@|(hIvT+gK?NsT6rWHymozK^**s+$k+;ZGArV@u z5!&=1s&>Q#gcfX>O+CdZ+{KvlF4PB8&r&D8F%C^wM1XQNFFx+0LeIT4KPnf-b% z$)2JO3!kqKBtzBZ-KVWF-3l7XNtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q| + + + + + + loopwave_VS2012_WinRT + David + Assets\StoreLogo.png + + + + 6.2.1 + 6.2.1 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj b/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj new file mode 100644 index 000000000..852dbd32a --- /dev/null +++ b/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + + {03fcc293-9406-49c2-acf6-6e7d460c3239} + loopwave_VS2012_WinRT + en-US + 11.0 + true + + + + Application + true + v110 + + + Application + true + v110 + + + Application + true + v110 + + + Application + false + true + v110 + + + Application + false + true + v110 + + + Application + false + true + v110 + + + + + + + + + + + + + + + + + + + + + + + + + loopwave_VS2012_WinRT_TemporaryKey.pfx + + + + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + + + pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\..\include;%(AdditionalIncludeDirectories) + 4453 + + + + + NDEBUG;__WINRT__;%(PreprocessorDefinitions) + NotUsing + NotUsing + NotUsing + + + + + _DEBUG;__WINRT__;%(PreprocessorDefinitions) + NotUsing + NotUsing + NotUsing + + + + + + + + + + + Designer + + + + + + + false + false + false + false + false + false + + + + + + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + + + + + + \ No newline at end of file diff --git a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx b/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..3c07b779f56405e71431543ad8e28b5bbb995690 GIT binary patch literal 2504 zcmY+Ec{J2}AIHCA#xSz45gC+B$j@%Bgk;~#zVBmS#?m7~gCScOdt>Z{5JES*vfs#Z zvlkMI#Kg^{F3-80=ehUXe_!wS`<%}|pBF?x_0z%N5CIj3L|r865f52l46srHDg;45 z1waIp4@96p`d381jUdo(LInCXh(N!LJoUd7GZT!ilz=#f2#6y{5Xtm^41+_g2u5`C zEB2ixB@!JS!vunWm=hWOPJLK)EkQ&K+rCl|#vM{~%bxppN#|kTUp9QuE~t@97JeAv z&}uh-vV9FFxi(6>^#&>D^<0wdw?9Psm{ZHcuFbE?ns>>f!|J=`lZE%o?`h)}DAQG)gHDuIKv53C zpw^lie%FUupyMllG-be-HUA8jnN$0M`y`{W30)IC7A+G*=f&?GEROsi1Is;w$+p(Lxix!xYu_>=||Ai#ZRmYF)ek$2;OdNK4_Cd~$8lBY| zZE5k3jn*f9+C+tn#5zN`WXrnlpcLCL*(p*NHb-r&SnntC&0E=QBT8EG5G-wLYy zY3jS#*BRFJp=uqc;L^+2NOEgBxSkTMBmwQi{|my%I&iEmG7K04JqV;@AdPA*5Jbf z;>h>kF7dWPzQHEX9zV1yb?Z<678*0GedqEGi4^awdIihWNw0yx;%a@vGzr>1on2Bt zO3(1Q+c{xYb)NB;_Y>}Ew(0I9Pr3X2r@6a0kl(DY`Xm^@ZuYh39i89nE5DMgx5Ji8 zs%NzMVQ=7C(!V)llQEY0DusBEZlF2Psr=(+=keW*CZd=szf@ls-1pQJ_rkMYQo&P; zbIb2elp0B;`mAjVQ~0DKPEO`20Zr5HWlynHr`0-2cc%J~=9(8ll%MfZPE4S%I-?)^ zpx_d7abe8khTl&65d&lz>;z`BV@Zd%s$TV;)LCS5sa?v8W#*tL#c`KNPaL{eFL+>Y zsp(m3oz}vb{HC1jN5ytE`Mv0RQ}^bSt!o2w;5GK8HRe0TO%?-8U)dJT&UC$ZcDxF3 z9Z>pR&^lnqEE`MNwr4PZgzP!(l6oe`__Wb_h4p}18akD;qcr-qc-EhZ5!%A;qWvT; z5oY_xNrrZx{dmmlo=uNhw~pEu?8)VqJ_t7!TP)k;JT^Krt}R3Rz;0bvX&mC;GM~R+ zr1|ONbN5|W-Yp7_HNb>axSUT`+C>Y5Z$1sUjVg?NaP+M?xWVVcmxVsIce#2i z4l5K$bm>-_OP1Y|fNMd^?`le*WY^Lxaij5W1p zwfn41swq@d$>jOSB(yDqk;g|RO34)C(?pI`SDmnaUJXZJoDz-<85_r&heR!1?u^c6 zVKK8tdtcvPHd4PvQSK!C=aGx5S=|T|Kk$gsEbEsmeDS_QKH`8j*;>zybKfVB_o_9x zHO!at@_iFsXHsSFj6qy~>k`Eyi$ow`007APAIL3ha8?gsfeLT~3cv%%15e-vq=6z( z0?NP@NCO2R3p{`_kOruQV)U>ar3<8tKP79n zf2bX}$ZM{zf;Vp3ph^y|ZLRYun&`vhdUrOPlol#gf}aI{%8y2gW+I8h*&K%Z4<*C5 zBE3qQI=fze;WnKyVI+Gz&29Eb(bLgxxfGIGukh!}@kFFYu0Gayvmz`{10D?vHn3Be z6>(H(uG~Mo8dUk%K|8BkpmAm-oh@t_KDKo4>%&LBAGZ$$EXJ0yZ4@V)dtdeYdy)71 z4<_1cJd$irQYphWw*{9CCHQ?i;A|3hG(1|wpX6q0OY{{Qq7K5G(ce|mFAuOdvrCW% zsRQ@NBIXneg80-jwojd!+-kUEE^0nM9l5c7p(S`?^r)a_S~s*+=rS=+k`-U+6vV%Q zz_qUYhNITW3d!(%Hh?ld%h5^uWyXf^TOzNuUq_3zA@mHlHJl>%QMcrruM@GM`27uX zGU``mO~(BlES0n5QDQ}w5p*_@;pze+;`Z#^VZ8U&@AJh9TAt0spsCI)B0gobn3+lD zsJgNU?(l<>onc#+<_nb`W&Y?=o(74tnWEoqB#-YU(-I8$GT$)kb@VE!Vsuk!G^y99 z*BRvo_AfhQTF#LY%CU@ocUqbLRtp2qx-es^7*)IXvsO zIy8;()^}cBiC!jklX=os{hS1htY4hi;BJC)2^q%=&K7>dZ`swNg~8qG%mB{;+YN?< zwzQa$Lr3C==-$<8zbBpBB@!+6=e1@Y{*k^#!Ci04UA)|4KpYfr5buK7KVEUv!}qaF zxy?o0XZjQ$AHjBzuPyzuvBGlwqPIn=Z|B*e>)s(=b;K Date: Thu, 22 Nov 2012 13:11:05 -0500 Subject: [PATCH 042/264] WinRT: made SDL_platform.h auto-detect WinRT --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 12 +++---- .../WinRT/loopwave_VS2012_WinRT.vcxproj | 4 +-- include/SDL_platform.h | 34 ++++++++++++++++++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index aedcb381f..cddcbdff9 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -378,7 +378,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console @@ -392,7 +392,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console @@ -406,7 +406,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console @@ -420,7 +420,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console @@ -434,7 +434,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console @@ -448,7 +448,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;__WINRT__=1;%(PreprocessorDefinitions) + _WINDLL;%(PreprocessorDefinitions) Console diff --git a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj b/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj index 852dbd32a..bb27ceb52 100644 --- a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj +++ b/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj @@ -105,7 +105,7 @@ - NDEBUG;__WINRT__;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing @@ -113,7 +113,7 @@ - _DEBUG;__WINRT__;%(PreprocessorDefinitions) + _DEBUG;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 569215c6d..2b2192ca8 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -114,12 +114,44 @@ #undef __SOLARIS__ #define __SOLARIS__ 1 #endif + #if defined(WIN32) || defined(_WIN32) -#if ! defined(__WINRT__) +/* Try to find out what version of Windows we are compiling for */ +#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */ +#include +#endif +/* Default to classic, Win32 / Desktop compilation if the version of Windows + cannot be determined via winapifamily.h. */ +#if ! defined(WINAPI_FAMILY_PARTITION) +#undef __WIN32__ +#define __WIN32__ 1 +#else +/* Include Win32 / Desktop App APIs in SDL, if available: */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +/* Include WinRT / Windows Store APIs in SDL, if available: */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#undef __WINRT__ +#define __WINRT__ 1 +#endif +#endif +#endif + +/* +#if ! defined(WINAPI_FAMILY_PARTITION) || ! WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #undef __WIN32__ #define __WIN32__ 1 +#error win32_defined #endif #endif +#if defined(WINAPI_FAMILY_PARTITION) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#undef __WINRT__ +#define __WINRT__ 1 +#error winrt_defined +#endif +*/ #if defined(__NDS__) #undef __NINTENDODS__ From c4d055488ff63d260c94de73b34b1a1cf9ef00ae Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 22:34:50 -0500 Subject: [PATCH 043/264] WinRT: got the XAudio2 backend compiling (but not running, yet) --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 30 +++- include/SDL_config_windowsrt.h | 2 +- src/audio/xaudio2/SDL_xaudio2.c | 135 +++++++++++++++++- .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 41 ++++++ src/audio/xaudio2/SDL_xaudio2_winrthelpers.h | 40 ++++++ src/core/windows/SDL_windows.h | 2 + 6 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp create mode 100644 src/audio/xaudio2/SDL_xaudio2_winrthelpers.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index cddcbdff9..73d04e207 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -37,6 +37,22 @@ + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + true + true + true + true + true + true + @@ -206,6 +222,8 @@ + + @@ -384,7 +402,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -398,7 +416,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -412,7 +430,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -426,7 +444,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -440,7 +458,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -454,7 +472,7 @@ Console false false - d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; kernel32.lib;%(AdditionalDependencies) + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 3f12a130c..fb7fdb3b9 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -144,7 +144,7 @@ typedef unsigned int uintptr_t; #endif /* Enable various audio drivers */ -//#define SDL_AUDIO_DRIVER_XAUDIO2 1 // TODO, WinRT: see if SDL's XAudio2 driver can compile +#define SDL_AUDIO_DRIVER_XAUDIO2 1 #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index d42d89638..f2302f575 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -18,22 +18,90 @@ 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^)). (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__) #include /* 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 @@ -43,12 +111,17 @@ /* 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; - HANDLE semaphore; + SDL_sem * semaphore; Uint8 *mixbuf; int mixlen; Uint8 *nextbuf; @@ -102,7 +175,7 @@ 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); + SDL_SemPost(this->hidden->semaphore); } static void STDMETHODCALLTYPE @@ -119,6 +192,33 @@ 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) { + VoiceCBOnBufferEnd(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) @@ -168,7 +268,7 @@ static void XAUDIO2_WaitDevice(_THIS) { if (this->enabled) { - WaitForSingleObject(this->hidden->semaphore, INFINITE); + SDL_SemWait(this->hidden->semaphore); } } @@ -181,7 +281,7 @@ XAUDIO2_WaitDone(_THIS) IXAudio2SourceVoice_Discontinuity(source); IXAudio2SourceVoice_GetState(source, &state); while (state.BuffersQueued > 0) { - WaitForSingleObject(this->hidden->semaphore, INFINITE); + SDL_SemWait(this->hidden->semaphore); IXAudio2SourceVoice_GetState(source, &state); } } @@ -230,8 +330,15 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; +#if defined(__WINRT__) + WCHAR devId[256]; +#else UINT32 devId = 0; /* 0 == system default device. */ +#endif +#if defined(__cplusplus) + static SDL_XAudio2VoiceCallback callbacks; +#else static IXAudio2VoiceCallbackVtbl callbacks_vtable = { VoiceCBOnVoiceProcessPassStart, VoiceCBOnVoiceProcessPassEnd, @@ -243,6 +350,11 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) }; static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; +#endif // ! defined(__cplusplus) + +#if defined(__WINRT__) + SDL_zero(devId); +#endif if (iscapture) { SDL_SetError("XAudio2: capture devices unsupported."); @@ -269,7 +381,11 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) const int match = (SDL_strcmp(str, devname) == 0); SDL_free(str); if (match) { +#if defined(__WINRT__) + wcsncpy_s(devId, ARRAYSIZE(devId), details.DeviceID, _TRUNCATE); +#else devId = i; +#endif break; } } @@ -294,7 +410,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) SDL_memset(this->hidden, 0, (sizeof *this->hidden)); this->hidden->ixa2 = ixa2; - this->hidden->semaphore = CreateSemaphore(NULL, 1, 2, NULL); + this->hidden->semaphore = SDL_CreateSemaphore(1); if (this->hidden->semaphore == NULL) { XAUDIO2_CloseDevice(this); SDL_SetError("XAudio2: CreateSemaphore() failed!"); @@ -395,7 +511,9 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) static void XAUDIO2_Deinitialize(void) { +#if defined(__WIN32__) WIN_CoUninitialize(); +#endif } #endif /* SDL_XAUDIO2_HAS_SDK */ @@ -410,13 +528,17 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) #else /* XAudio2Create() is a macro that uses COM; we don't load the .dll */ IXAudio2 *ixa2 = NULL; +#if defined(__WIN32__) 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"); return 0; /* not available. */ } @@ -436,6 +558,9 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) #endif } +#if defined(__cplusplus) +extern "C" +#endif AudioBootStrap XAUDIO2_bootstrap = { "xaudio2", "XAudio2", XAUDIO2_Init, 0 }; diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp new file mode 100644 index 000000000..2fbf63c8b --- /dev/null +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -0,0 +1,41 @@ + +#include +#include "SDL_xaudio2_winrthelpers.h" + +using Windows::Devices::Enumeration::DeviceClass; +using Windows::Devices::Enumeration::DeviceInformation; +using Windows::Devices::Enumeration::DeviceInformationCollection; + +HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) +{ + auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender); + while (operation->Status != Windows::Foundation::AsyncStatus::Completed) + { + } + + DeviceInformationCollection^ devices = operation->GetResults(); + *devcount = devices->Size; + return S_OK; +} + +HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details) +{ + 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; +} diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h new file mode 100644 index 000000000..a72804faa --- /dev/null +++ b/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)) diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index c7c6f9576..d4a7ecff9 100644 --- a/src/core/windows/SDL_windows.h +++ b/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 From 764aeee2b7522a658e90ba0c982abd66c763b47b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 22:35:38 -0500 Subject: [PATCH 044/264] WinRT: modified the loopwave test to run if and when argv is NULL --- test/loopwave.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/loopwave.c b/test/loopwave.c index 3cb664020..f3d394efe 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -78,18 +78,22 @@ poked(int sig) int main(int argc, char *argv[]) { + char filename[4096]; + /* Load the SDL library */ if (SDL_Init(SDL_INIT_AUDIO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); 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); } From c10e89fd58ae6bb440e8cabb99b2f8c4199bc309 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 22:36:34 -0500 Subject: [PATCH 045/264] WinRT: pseudo-implemented SDLmain for WinRT. It has to be compiled directly into apps, for now. --- src/main/windowsrt/SDL_winrt_main.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/windowsrt/SDL_winrt_main.cpp diff --git a/src/main/windowsrt/SDL_winrt_main.cpp b/src/main/windowsrt/SDL_winrt_main.cpp new file mode 100644 index 000000000..9cc046de5 --- /dev/null +++ b/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^) +{ + return SDL_WinRT_RunApplication(SDL_main); +} From e4c6ec5708391d7ab9279031fe18508c4cf08da8 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 23:03:56 -0500 Subject: [PATCH 046/264] WinRT: added a skeleton SDL backend for C++11-based threads --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 10 +- .../tests/testthread/WinRT/Assets/Logo.png | Bin 0 -> 801 bytes .../testthread/WinRT/Assets/SmallLogo.png | Bin 0 -> 329 bytes .../testthread/WinRT/Assets/SplashScreen.png | Bin 0 -> 2146 bytes .../testthread/WinRT/Assets/StoreLogo.png | Bin 0 -> 429 bytes .../testthread/WinRT/Package.appxmanifest | 42 ++++ .../WinRT/testthread_VS2012_WinRT.vcxproj | 159 +++++++++++++ .../testthread_VS2012_WinRT_TemporaryKey.pfx | Bin 0 -> 2504 bytes include/SDL_config_windowsrt.h | 4 +- src/thread/SDL_thread_c.h | 2 + src/thread/stdcpp/SDL_syscond.c | 223 ++++++++++++++++++ src/thread/stdcpp/SDL_sysmutex.c | 135 +++++++++++ src/thread/stdcpp/SDL_sysmutex_c.h | 22 ++ src/thread/stdcpp/SDL_systhread.c | 59 +++++ src/thread/stdcpp/SDL_systhread_c.h | 26 ++ 15 files changed, 675 insertions(+), 7 deletions(-) create mode 100644 VisualC/tests/testthread/WinRT/Assets/Logo.png create mode 100644 VisualC/tests/testthread/WinRT/Assets/SmallLogo.png create mode 100644 VisualC/tests/testthread/WinRT/Assets/SplashScreen.png create mode 100644 VisualC/tests/testthread/WinRT/Assets/StoreLogo.png create mode 100644 VisualC/tests/testthread/WinRT/Package.appxmanifest create mode 100644 VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj create mode 100644 VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx create mode 100644 src/thread/stdcpp/SDL_syscond.c create mode 100644 src/thread/stdcpp/SDL_sysmutex.c create mode 100644 src/thread/stdcpp/SDL_sysmutex_c.h create mode 100644 src/thread/stdcpp/SDL_systhread.c create mode 100644 src/thread/stdcpp/SDL_systhread_c.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 73d04e207..3bb971a7b 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -89,11 +89,11 @@ - - - + + + @@ -253,10 +253,10 @@ - - + + diff --git a/VisualC/tests/testthread/WinRT/Assets/Logo.png b/VisualC/tests/testthread/WinRT/Assets/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e26771cb33a49bbef824aa333737181b0a5b09a3 GIT binary patch literal 801 zcmeAS@N?(olHy`uVBq!ia0y~yV3-EN9Bd2>3^t5~j~EyjBuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFdg=EaSW-r_2%wgUu8#$hQvKeC6ZGdoyuYz>I5fd zD=cCVTGw#;WJV*C#^Im$BqU!l<@MGW@3y}Geb1#+jk-7IRhn$x_Gh!?@sCcc?j~@s zOgkVHAr!&no#2_ksne+1sJek=8nJ>RyH5AXyMu zC7zPUKdy?gnUnO4V8$neR!%tOJt2)L8_xD-?dqVQ-9w} za}*W2CRLc~EGl+wR>9xaS6bYwE^N5gpsl^?!-i=`rb>o#MR-3r)u+X~#33yiC?y&ms@MYs>e-SYhLYGz_i**Z^eOC zeJDbl>x$kiU|P+(E_=m+tVWR3!>ZrMukP;^h)56hyH*~bQ$N4;*Hq~Z&s@JIKT?a{ zabQ)W))oGV4O^8$p3ZsAtG6L*@vZq4+Dv*I&N-JpTFbHHfR(&xOoFL1t9ZoOfP<`I z#vuibS9wHZ5^5LiTHVXF?#YHzPvji#ZgXG_4~lRP**$H=12490zmNje#;q(`JDLth z35Ax$I2(ohwhT-?X6nEy9`V0F>tcP<*_P}EF1-y_?o&ChGl<3{usTj@E4ojhO{hc-m9E3cS|J`^!QH9JN2zXQG42fN#|}{%2nKyL~^3QpM0V= c*)#DloQf}5saF0GlnEF-UHx3vIVCg!0HVrD82|tP literal 0 HcmV?d00001 diff --git a/VisualC/tests/testthread/WinRT/Assets/SmallLogo.png b/VisualC/tests/testthread/WinRT/Assets/SmallLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb0d9d528c42f132872e8af4dc563081b0b9aff GIT binary patch literal 329 zcmV-P0k-~$P)q$gGRCwC#*X;?zAP@%N+|i#I!$mrh zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+ zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8dx}oD(QadjT^N|8cJC5vMb z^;+Y&#s!EZnzTfuGZ>R@w4o3y#%!Y$jekOQmfA%J`hl5EP}C1BM$CJE)-y81=%=^O z@80)$pZED)?~QEkY$q#il>k6?Y;tV@s0aWU8q6jDc=4Vq(*RI2(8>>N-MM{Wuy>ai zTKaYhUZx}1yTiN1+uJwv?8n|_0JE{f)$;i6(!w`Q{ZpK^wd;|qxw&Fj;lN$_)B}4r zoqOB-dhWSz53hUY$kfIj{;Av-pMEetZv<|9bv*zT05G!vlO_;71aL`%42|>>WQu?g z!layq5Q|iZMay$w7E<0ihpuszr>Ua2&~HqhdUegj^W9|`8lz6e{Wkj2RHpxz=9g-S zug2yVukFr6jfYNG(ud|3e?LN`OlFn}G6gPah?5$CNmHE6+RQAMt}6r2@tDtD^&qDI0smd#*X{s5nM5zz*+@7xkD9o z@`85qj9T6Jkji(*ok6ADs(q@|740!){_v=(XHub|lvMbyP<*qY4c4~K)TfUQpL>7( z?CdW21r4BhGnf^f%Rv065T%Rnz5B+7)gvpZ z09>d2agqwa3c;N=gvqzKM1UnT`4gBh7_)OHlL> z_fr3+xmwH={{J6qPz`FM0-_=<`@|(hIvT+gK?NsT6rWHymozK^**s+$k+;ZGArV@u z5!&=1s&>Q#gcfX>O+CdZ+{KvlF4PB8&r&D8F%C^wM1XQNFFx+0LeIT4KPnf-b% z$)2JO3!kqKBtzBZ-KVWF-3l7XNtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q| + + + + + + testthread_VS2012_WinRT + David + Assets\StoreLogo.png + + + + 6.2.1 + 6.2.1 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj b/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj new file mode 100644 index 000000000..0f522e147 --- /dev/null +++ b/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + + {a8705bee-d01d-46a4-b2ab-feedfb5fdd11} + testthread_VS2012_WinRT + en-US + 11.0 + true + + + + Application + true + v110 + + + Application + true + v110 + + + Application + true + v110 + + + Application + false + true + v110 + + + Application + false + true + v110 + + + Application + false + true + v110 + + + + + + + + + + + + + + + + + + + + + + + + + testthread_VS2012_WinRT_TemporaryKey.pfx + + + + d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + + + pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\..\include;%(AdditionalIncludeDirectories) + 4453 + + + + + NDEBUG;%(PreprocessorDefinitions) + NotUsing + NotUsing + NotUsing + false + false + false + + + + + _DEBUG;%(PreprocessorDefinitions) + NotUsing + NotUsing + NotUsing + false + false + false + + + + + + + + + + + Designer + + + + + + true + true + true + true + true + true + + + + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + + + + + + \ No newline at end of file diff --git a/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx b/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..97fd1e190077fd22da37b95fd53038fdd2ab7917 GIT binary patch literal 2504 zcmY+EcRbbmAICpuI>$j7;goUg&DV%fSs97b$&AQ295Z_)757+?aI;rdnb{&Ut833} zw<02BW_Q)^aqr{)?tR?%pU>C(^?1Dhc|Rd4wh0bHKve8qG*&cRC;WgOMgz;HVx5pw ztUW}<+CWs)&VM4*0+NdQ2vJe95EV6v#{J!*qlLk$qdQ7;&S zXo>zW++G_*KWW$NmG^8+ibfAg`x_OnsYGYd8(*^%_38QY#?#DrS;azOqkH_j^}40; znWZwjmtV^b=y&>W75jR<9iOq)PF*?6t+v1ADrWI! z&?1@`xtwG^G1{pVy65Ps(5~wIib-G4hpBr-uEsZG_2^_H$EfM~yyg94`jb?2e$W}- z_k$YbIMjI0oICv=92z|0Mb0l}NXa3dFXq=61RZbS2JUO&E~~Vb^0Anw*{vV)*E)t( z26FVY<8Pztd>iEN#1R@<6H+#sb+LTA-$6sc-m>A_vHO#;O#KekEW&w?)qaz`E-$!k zC2CyOn0hzkN$0gtjYoNU-gfN39%WqPZ@)Zx`Zr4 za=99(QX*rDTSUE&(Pq;OKQrN?C%42dG+pwa>T+3R%jHjJ8-F&-Bch($5TcmMru9RM zT3g>?VBf#Q+>#kK4(O5@89m(|_qx89S@@J7(z!)KO-wY$rr)Yjr0chhxY&B;V;9?_ zR@G+Gwb>>vy#AZwyXB{`534$?I^&%^YI3#(>GWiy29F+}Wp-cgv%Y`&P8?|qFTinY zL_daYVwCLBn{*G8 z-<|KIdp$+r!Wz}bib|xetbA@L!1T4UnrCRgg@Jg|!ybqjClhFmUUy>`+`c^(M39eh zo3b%tXyFbuF>V$J(Jq?EV-ft(d&tHvHymsyL+f;qSVah~s(U{wL7!E2rcRDHvW0Y< zUmn`$?~UTRr-{CPcUiR5_TtT}l+H#zH6J=3Ot1VyXax}8_7pt3FR zCzg*Cwk@3hExwkiNpOtJ5NA%&-rPxgcjAKkgxHW;uB>m2{-qLEv~bZdzz=3ke~)fd zIO++Z(diri`%1}`YBly1yz#53Wl!%mUc9Gb&B>(~PrOI}cKu8L=CDb{-IaTF`B#4}kTUBbrAc-<9yrPl@vbdu zS}pqQ=(a&wS=M5`D0ZkahbR7JGn2$O#re;I(7|IsA&j5HdFgaH5`(|;k0v@VwpfPf6J0Sdq#P=F1P1rmS)WPuDI0|_7p zC_n+o0SRCOAV3DTKmynUGLQjwKo-aWX+QxoKoLj-GGvLyilJdh7*&B0CQafZ0)5~F z$iNG@18?9CD8L60fFbbti?{&?KmZ!R3j_cU-~-%&1MmVizymn`)gl1WUweMQ3D^O9 z-~~|;4*y(EgU+TRZbDRq5gY~}DnkF?1oj`*qyJRBhqbEp4o{xkpQ;b0A_&p&LZ`*{ zdsjKfRJUPDQyeG8)J#gvd1j*9Vf?L|=pz#@+ca(t1APwd4HH$RKcuvk53p?GSH>q) z1`i1$bcF-gUmn-%bBWLe98(pb(n<|!G9<b@-5U+Ml+<`NX4$NP-o_DLEi^>V*37BU1y@x9i_eypNqJ$ZP&3jp(m-O@%Axz z_wlny&KGpu9Q3|ebk~z~*tFS@+&PiXNKXD3JP4?~zUi zjP5C=^v2j{@ljngCmf5<1YS?}hJktl`^Dz4LQ_QDu9eV+QSa_dm2M`&oT$0P5}B_oS?JhoIFmvl zUl5!>Ep(~OfgUfaV>zvPU(P&U$5-^UcPn*$vOQZUn(+NgZ2L$b#%vT$G1mze^PjtR za;)86^nvy{k0nAl0Wp`hqnEfhS)lU{iKK^$re#sKY^r6roNiC(CElf>N-p<(jPwN{eB`gG(7Da z9OchhVKjHw*IqsJsa+zZ3~@s=Xp|TO0)7_B5 + + 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" + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * +SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + if (cond) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if (!cond->lock || !cond->wait_sem || !cond->wait_done) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (cond); +} + +/* Destroy a condition variable */ +void +SDL_DestroyCond(SDL_cond * cond) +{ + if (cond) { + if (cond->wait_sem) { + SDL_DestroySemaphore(cond->wait_sem); + } + if (cond->wait_done) { + SDL_DestroySemaphore(cond->wait_done); + } + if (cond->lock) { + SDL_DestroyMutex(cond->lock); + } + SDL_free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int +SDL_CondSignal(SDL_cond * cond) +{ + if (!cond) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int +SDL_CondBroadcast(SDL_cond * cond) +{ + if (!cond) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if (cond->waiting > cond->signals) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for (i = 0; i < num_waiting; ++i) { + SDL_SemPost(cond->wait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for (i = 0; i < num_waiting; ++i) { + SDL_SemWait(cond->wait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* 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); + */ +int +SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +{ + int retval; + + if (!cond) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if (ms == SDL_MUTEX_MAXWAIT) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if (cond->signals > 0) { + /* If we timed out, we need to eat a condition signal */ + if (retval > 0) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int +SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_sysmutex.c b/src/thread/stdcpp/SDL_sysmutex.c new file mode 100644 index 000000000..1a6b2715c --- /dev/null +++ b/src/thread/stdcpp/SDL_sysmutex.c @@ -0,0 +1,135 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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" + +/* An implementation of mutexes using semaphores */ + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +struct SDL_mutex +{ + int recursive; + SDL_threadID owner; + SDL_sem *sem; +}; + +/* Create a mutex */ +SDL_mutex * +SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + if (mutex) { + /* Create the mutex semaphore, with initial value 1 */ + mutex->sem = SDL_CreateSemaphore(1); + mutex->recursive = 0; + mutex->owner = 0; + if (!mutex->sem) { + SDL_free(mutex); + mutex = NULL; + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) { + if (mutex->sem) { + SDL_DestroySemaphore(mutex->sem); + } + SDL_free(mutex); + } +} + +/* Lock the semaphore */ +int +SDL_mutexP(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + SDL_threadID this_thread; + + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if (mutex->owner == this_thread) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + SDL_SemWait(mutex->sem); + mutex->owner = this_thread; + mutex->recursive = 0; + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Unlock the mutex */ +int +SDL_mutexV(SDL_mutex * mutex) +{ +#if SDL_THREADS_DISABLED + return 0; +#else + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + /* If we don't own the mutex, we can't unlock it */ + if (SDL_ThreadID() != mutex->owner) { + SDL_SetError("mutex not owned by this thread"); + return -1; + } + + if (mutex->recursive) { + --mutex->recursive; + } else { + /* The order of operations is important. + First reset the owner so another thread doesn't lock + the mutex and set the ownership before we reset it, + then release the lock semaphore. + */ + mutex->owner = 0; + SDL_SemPost(mutex->sem); + } + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_sysmutex_c.h b/src/thread/stdcpp/SDL_sysmutex_c.h new file mode 100644 index 000000000..ed546b689 --- /dev/null +++ b/src/thread/stdcpp/SDL_sysmutex_c.h @@ -0,0 +1,22 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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" +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_systhread.c b/src/thread/stdcpp/SDL_systhread.c new file mode 100644 index 000000000..ed557a461 --- /dev/null +++ b/src/thread/stdcpp/SDL_systhread.c @@ -0,0 +1,59 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 */ + +#include "SDL_thread.h" +#include "../SDL_systhread.h" + +int +SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +{ + SDL_SetError("Threads are not supported on this platform"); + return (-1); +} + +void +SDL_SYS_SetupThread(const char *name) +{ + return; +} + +SDL_threadID +SDL_ThreadID(void) +{ + return (0); +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + return (0); +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + return; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_systhread_c.h b/src/thread/stdcpp/SDL_systhread_c.h new file mode 100644 index 000000000..4a060c98a --- /dev/null +++ b/src/thread/stdcpp/SDL_systhread_c.h @@ -0,0 +1,26 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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: */ From 7a24dc071bfadcf0e582e8557f85e2d856c22464 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 22 Nov 2012 23:12:06 -0500 Subject: [PATCH 047/264] WinRT: made the skeleton C++11 thread implementation use .cpp files, not .c --HG-- rename : src/thread/stdcpp/SDL_syscond.c => src/thread/stdcpp/SDL_syscond.cpp rename : src/thread/stdcpp/SDL_sysmutex.c => src/thread/stdcpp/SDL_sysmutex.cpp rename : src/thread/stdcpp/SDL_systhread.c => src/thread/stdcpp/SDL_systhread.cpp --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 6 +++--- src/thread/stdcpp/{SDL_syscond.c => SDL_syscond.cpp} | 6 ++++++ src/thread/stdcpp/{SDL_sysmutex.c => SDL_sysmutex.cpp} | 4 ++++ src/thread/stdcpp/{SDL_systhread.c => SDL_systhread.cpp} | 7 +++++++ 4 files changed, 20 insertions(+), 3 deletions(-) rename src/thread/stdcpp/{SDL_syscond.c => SDL_syscond.cpp} (98%) rename src/thread/stdcpp/{SDL_sysmutex.c => SDL_sysmutex.cpp} (98%) rename src/thread/stdcpp/{SDL_systhread.c => SDL_systhread.cpp} (95%) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 3bb971a7b..bdf0478d6 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -91,9 +91,9 @@ - - - + + + diff --git a/src/thread/stdcpp/SDL_syscond.c b/src/thread/stdcpp/SDL_syscond.cpp similarity index 98% rename from src/thread/stdcpp/SDL_syscond.c rename to src/thread/stdcpp/SDL_syscond.cpp index 7304badc1..a603a1ba3 100644 --- a/src/thread/stdcpp/SDL_syscond.c +++ b/src/thread/stdcpp/SDL_syscond.cpp @@ -38,6 +38,7 @@ struct SDL_cond }; /* Create a condition variable */ +extern "C" SDL_cond * SDL_CreateCond(void) { @@ -60,6 +61,7 @@ SDL_CreateCond(void) } /* Destroy a condition variable */ +extern "C" void SDL_DestroyCond(SDL_cond * cond) { @@ -78,6 +80,7 @@ SDL_DestroyCond(SDL_cond * cond) } /* Restart one of the threads that are waiting on the condition variable */ +extern "C" int SDL_CondSignal(SDL_cond * cond) { @@ -103,6 +106,7 @@ SDL_CondSignal(SDL_cond * cond) } /* Restart all threads that are waiting on the condition variable */ +extern "C" int SDL_CondBroadcast(SDL_cond * cond) { @@ -158,6 +162,7 @@ Thread B: SDL_CondSignal(cond); SDL_UnlockMutex(lock); */ +extern "C" int SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) { @@ -214,6 +219,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) } /* Wait on the condition variable forever */ +extern "C" int SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) { diff --git a/src/thread/stdcpp/SDL_sysmutex.c b/src/thread/stdcpp/SDL_sysmutex.cpp similarity index 98% rename from src/thread/stdcpp/SDL_sysmutex.c rename to src/thread/stdcpp/SDL_sysmutex.cpp index 1a6b2715c..e220bc5df 100644 --- a/src/thread/stdcpp/SDL_sysmutex.c +++ b/src/thread/stdcpp/SDL_sysmutex.cpp @@ -34,6 +34,7 @@ struct SDL_mutex }; /* Create a mutex */ +extern "C" SDL_mutex * SDL_CreateMutex(void) { @@ -57,6 +58,7 @@ SDL_CreateMutex(void) } /* Free the mutex */ +extern "C" void SDL_DestroyMutex(SDL_mutex * mutex) { @@ -69,6 +71,7 @@ SDL_DestroyMutex(SDL_mutex * mutex) } /* Lock the semaphore */ +extern "C" int SDL_mutexP(SDL_mutex * mutex) { @@ -100,6 +103,7 @@ SDL_mutexP(SDL_mutex * mutex) } /* Unlock the mutex */ +extern "C" int SDL_mutexV(SDL_mutex * mutex) { diff --git a/src/thread/stdcpp/SDL_systhread.c b/src/thread/stdcpp/SDL_systhread.cpp similarity index 95% rename from src/thread/stdcpp/SDL_systhread.c rename to src/thread/stdcpp/SDL_systhread.cpp index ed557a461..e40d8f277 100644 --- a/src/thread/stdcpp/SDL_systhread.c +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -22,9 +22,12 @@ /* Thread management routines for SDL */ +extern "C" { #include "SDL_thread.h" #include "../SDL_systhread.h" +} +extern "C" int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { @@ -32,24 +35,28 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) return (-1); } +extern "C" void SDL_SYS_SetupThread(const char *name) { return; } +extern "C" SDL_threadID SDL_ThreadID(void) { return (0); } +extern "C" int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { return (0); } +extern "C" void SDL_SYS_WaitThread(SDL_Thread * thread) { From 076650c2861b7693beae28ab566342d1c2d0efd8 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 23 Nov 2012 00:02:27 -0500 Subject: [PATCH 048/264] WinRT: cleanups in SDL_platform.h --- include/SDL_platform.h | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 2b2192ca8..6939f1f15 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -136,22 +136,8 @@ #undef __WINRT__ #define __WINRT__ 1 #endif -#endif -#endif - -/* -#if ! defined(WINAPI_FAMILY_PARTITION) || ! WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#undef __WIN32__ -#define __WIN32__ 1 -#error win32_defined -#endif -#endif -#if defined(WINAPI_FAMILY_PARTITION) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -#undef __WINRT__ -#define __WINRT__ 1 -#error winrt_defined -#endif -*/ +#endif /* if ! defined(WINAPI_FAMILY_PARTITION) ; else */ +#endif /* if defined(WIN32) || defined(_WIN32) */ #if defined(__NDS__) #undef __NINTENDODS__ From bc67a6617f1db857c812ba31517132311482408c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 11:16:45 -0500 Subject: [PATCH 049/264] WinRT: made testthread to use SDL_Log, not printf or fprintf, for MSVC++ logging --- test/testthread.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/testthread.c b/test/testthread.c index 21509ff1d..3deab1613 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -32,20 +32,20 @@ quit(int rc) int SDLCALL ThreadFunc(void *data) { - printf("Started thread %s: My thread id is %lu\n", + SDL_Log("Started thread %s: My thread id is %lu\n", (char *) data, SDL_ThreadID()); while (alive) { - printf("Thread '%s' is alive!\n", (char *) data); + SDL_Log("Thread '%s' is alive!\n", (char *) data); SDL_Delay(1 * 1000); } - printf("Thread '%s' exiting!\n", (char *) data); + SDL_Log("Thread '%s' exiting!\n", (char *) data); return (0); } static void killed(int sig) { - printf("Killed with SIGTERM, waiting 5 seconds to exit\n"); + SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); SDL_Delay(5 * 1000); alive = 0; quit(0); @@ -58,18 +58,18 @@ main(int argc, char *argv[]) /* Load the SDL library */ if (SDL_Init(0) < 0) { - fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Couldn't initialize SDL: %s\n", SDL_GetError()); return (1); } alive = 1; thread = SDL_CreateThread(ThreadFunc, "One", "#1"); if (thread == NULL) { - fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Couldn't create thread: %s\n", SDL_GetError()); quit(1); } SDL_Delay(5 * 1000); - printf("Waiting for thread #1\n"); + SDL_Log("Waiting for thread #1\n"); alive = 0; SDL_WaitThread(thread, NULL); @@ -77,7 +77,7 @@ main(int argc, char *argv[]) signal(SIGTERM, killed); thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); if (thread == NULL) { - fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Couldn't create thread: %s\n", SDL_GetError()); quit(1); } raise(SIGTERM); From 2fde6ac33bcdfe7a7517c04c85596f2bc5c9e761 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 11:17:23 -0500 Subject: [PATCH 050/264] WinRT: added a functional threading backend using C++11 apis --- src/thread/stdcpp/SDL_syscond.cpp | 178 +++++++++++----------------- src/thread/stdcpp/SDL_sysmutex.cpp | 106 +++++++---------- src/thread/stdcpp/SDL_sysmutex_c.h | 8 ++ src/thread/stdcpp/SDL_systhread.cpp | 66 ++++++++++- 4 files changed, 176 insertions(+), 182 deletions(-) diff --git a/src/thread/stdcpp/SDL_syscond.cpp b/src/thread/stdcpp/SDL_syscond.cpp index a603a1ba3..4ca1d96f7 100644 --- a/src/thread/stdcpp/SDL_syscond.cpp +++ b/src/thread/stdcpp/SDL_syscond.cpp @@ -20,21 +20,20 @@ */ #include "SDL_config.h" -/* An implementation of condition variables using semaphores and mutexes */ -/* - This implementation borrows heavily from the BeOS condition variable - implementation, written by Christopher Tate and Owen Smith. Thanks! - */ - +extern "C" { #include "SDL_thread.h" +} + +#include +#include +#include +#include + +#include "SDL_sysmutex_c.h" struct SDL_cond { - SDL_mutex *lock; - int waiting; - int signals; - SDL_sem *wait_sem; - SDL_sem *wait_done; + std::condition_variable_any cpp_cond; }; /* Create a condition variable */ @@ -42,22 +41,17 @@ extern "C" SDL_cond * SDL_CreateCond(void) { - SDL_cond *cond; - - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); - if (cond) { - cond->lock = SDL_CreateMutex(); - cond->wait_sem = SDL_CreateSemaphore(0); - cond->wait_done = SDL_CreateSemaphore(0); - cond->waiting = cond->signals = 0; - if (!cond->lock || !cond->wait_sem || !cond->wait_done) { - SDL_DestroyCond(cond); - cond = NULL; - } - } else { - SDL_OutOfMemory(); + /* 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; } - return (cond); } /* Destroy a condition variable */ @@ -66,16 +60,11 @@ void SDL_DestroyCond(SDL_cond * cond) { if (cond) { - if (cond->wait_sem) { - SDL_DestroySemaphore(cond->wait_sem); + try { + delete cond; + } catch (...) { + // catch any and all exceptions, just in case something happens } - if (cond->wait_done) { - SDL_DestroySemaphore(cond->wait_done); - } - if (cond->lock) { - SDL_DestroyMutex(cond->lock); - } - SDL_free(cond); } } @@ -89,20 +78,14 @@ SDL_CondSignal(SDL_cond * cond) return -1; } - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - ++cond->signals; - SDL_SemPost(cond->wait_sem); - SDL_UnlockMutex(cond->lock); - SDL_SemWait(cond->wait_done); - } else { - SDL_UnlockMutex(cond->lock); + 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; } - - return 0; } /* Restart all threads that are waiting on the condition variable */ @@ -115,30 +98,14 @@ SDL_CondBroadcast(SDL_cond * cond) return -1; } - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - int i, num_waiting; - - num_waiting = (cond->waiting - cond->signals); - cond->signals = cond->waiting; - for (i = 0; i < num_waiting; ++i) { - SDL_SemPost(cond->wait_sem); - } - /* Now all released threads are blocked here, waiting for us. - Collect them all (and win fabulous prizes!) :-) - */ - SDL_UnlockMutex(cond->lock); - for (i = 0; i < num_waiting; ++i) { - SDL_SemWait(cond->wait_done); - } - } else { - SDL_UnlockMutex(cond->lock); + 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; } - - return 0; } /* Wait on the condition variable for at most 'ms' milliseconds. @@ -166,56 +133,43 @@ extern "C" int SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) { - int retval; - if (!cond) { SDL_SetError("Passed a NULL condition variable"); return -1; } - /* Obtain the protection mutex, and increment the number of waiters. - This allows the signal mechanism to only perform a signal if there - are waiting threads. - */ - SDL_LockMutex(cond->lock); - ++cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Unlock the mutex, as is required by condition variable semantics */ - SDL_UnlockMutex(mutex); - - /* Wait for a signal */ - if (ms == SDL_MUTEX_MAXWAIT) { - retval = SDL_SemWait(cond->wait_sem); - } else { - retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + if (!mutex) { + SDL_SetError("Passed a NULL mutex variable"); + return -1; } - /* Let the signaler know we have completed the wait, otherwise - the signaler can race ahead and get the condition semaphore - if we are stopped between the mutex unlock and semaphore wait, - giving a deadlock. See the following URL for details: - http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html - */ - SDL_LockMutex(cond->lock); - if (cond->signals > 0) { - /* If we timed out, we need to eat a condition signal */ - if (retval > 0) { - SDL_SemWait(cond->wait_sem); + try { + std::unique_lock 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(ms) + ); + cpp_lock.release(); + if (wait_result == std::cv_status::timeout) { + return SDL_MUTEX_TIMEDOUT; + } else { + return 0; + } } - /* We always notify the signal thread that we are done */ - SDL_SemPost(cond->wait_done); - - /* Signal handshake complete */ - --cond->signals; + } 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; } - --cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Lock the mutex, as is required by condition variable semantics */ - SDL_LockMutex(mutex); - - return retval; } /* Wait on the condition variable forever */ diff --git a/src/thread/stdcpp/SDL_sysmutex.cpp b/src/thread/stdcpp/SDL_sysmutex.cpp index e220bc5df..e43b255e8 100644 --- a/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/src/thread/stdcpp/SDL_sysmutex.cpp @@ -20,41 +20,34 @@ */ #include "SDL_config.h" -/* An implementation of mutexes using semaphores */ - +extern "C" { #include "SDL_thread.h" #include "SDL_systhread_c.h" +#include "SDL_log.h" +} +#include + +#include "SDL_sysmutex_c.h" +#include -struct SDL_mutex -{ - int recursive; - SDL_threadID owner; - SDL_sem *sem; -}; /* Create a mutex */ extern "C" SDL_mutex * SDL_CreateMutex(void) { - SDL_mutex *mutex; - - /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); - if (mutex) { - /* Create the mutex semaphore, with initial value 1 */ - mutex->sem = SDL_CreateSemaphore(1); - mutex->recursive = 0; - mutex->owner = 0; - if (!mutex->sem) { - SDL_free(mutex); - mutex = NULL; - } - } else { - SDL_OutOfMemory(); + /* 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; } - return mutex; } /* Free the mutex */ @@ -63,10 +56,11 @@ void SDL_DestroyMutex(SDL_mutex * mutex) { if (mutex) { - if (mutex->sem) { - SDL_DestroySemaphore(mutex->sem); + try { + delete mutex; + } catch (...) { + // catch any and all exceptions, just in case something happens } - SDL_free(mutex); } } @@ -75,31 +69,23 @@ extern "C" int SDL_mutexP(SDL_mutex * mutex) { -#if SDL_THREADS_DISABLED - return 0; -#else - SDL_threadID this_thread; - + SDL_threadID threadID = SDL_ThreadID(); + DWORD realThreadID = GetCurrentThreadId(); if (mutex == NULL) { SDL_SetError("Passed a NULL mutex"); return -1; } - this_thread = SDL_ThreadID(); - if (mutex->owner == this_thread) { - ++mutex->recursive; - } else { - /* The order of operations is important. - We set the locking thread id after we obtain the lock - so unlocks from other threads will fail. - */ - SDL_SemWait(mutex->sem); - mutex->owner = this_thread; - mutex->recursive = 0; + 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; } - - return 0; -#endif /* SDL_THREADS_DISABLED */ } /* Unlock the mutex */ @@ -107,33 +93,21 @@ extern "C" int SDL_mutexV(SDL_mutex * mutex) { -#if SDL_THREADS_DISABLED - return 0; -#else + SDL_threadID threadID = SDL_ThreadID(); + DWORD realThreadID = GetCurrentThreadId(); if (mutex == NULL) { SDL_SetError("Passed a NULL mutex"); return -1; } - /* If we don't own the mutex, we can't unlock it */ - if (SDL_ThreadID() != mutex->owner) { - SDL_SetError("mutex not owned by this thread"); + 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; } - - if (mutex->recursive) { - --mutex->recursive; - } else { - /* The order of operations is important. - First reset the owner so another thread doesn't lock - the mutex and set the ownership before we reset it, - then release the lock semaphore. - */ - mutex->owner = 0; - SDL_SemPost(mutex->sem); - } - return 0; -#endif /* SDL_THREADS_DISABLED */ } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_sysmutex_c.h b/src/thread/stdcpp/SDL_sysmutex_c.h index ed546b689..500e57d40 100644 --- a/src/thread/stdcpp/SDL_sysmutex_c.h +++ b/src/thread/stdcpp/SDL_sysmutex_c.h @@ -19,4 +19,12 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_config.h" + +#include + +struct SDL_mutex +{ + std::recursive_mutex cpp_mutex; +}; + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index e40d8f277..fd4cdafb3 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -25,20 +25,51 @@ extern "C" { #include "SDL_thread.h" #include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include "SDL_log.h" +} + +#include +#include + +// 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) { - SDL_SetError("Threads are not supported on this platform"); - return (-1); + 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; } @@ -46,13 +77,27 @@ extern "C" SDL_threadID SDL_ThreadID(void) { - return (0); + 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 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); } @@ -60,7 +105,20 @@ extern "C" void SDL_SYS_WaitThread(SDL_Thread * thread) { - return; + 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: */ From be90b123c347eaa8b6f7104c96c20a8c74cf3b69 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 11:19:06 -0500 Subject: [PATCH 051/264] WinRT: got XAudio2 sort-of working (it plays stuff poorly, then crashes) --- src/audio/xaudio2/SDL_xaudio2.c | 39 ++++++++++++------- .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 1 + 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index f2302f575..bef13f68b 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -128,14 +128,6 @@ struct SDL_PrivateAudioData }; -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) { @@ -159,7 +151,7 @@ XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) 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); + char *str = WIN_StringToUTF8(details.DisplayName); if (str != NULL) { addfn(str); SDL_free(str); /* addfn() made a copy of the string. */ @@ -313,7 +305,7 @@ XAUDIO2_CloseDevice(_THIS) SDL_free(this->hidden->mixbuf); } if (this->hidden->semaphore != NULL) { - CloseHandle(this->hidden->semaphore); + SDL_DestroySemaphore(this->hidden->semaphore); } SDL_free(this->hidden); @@ -331,7 +323,8 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; #if defined(__WINRT__) - WCHAR devId[256]; + WCHAR devIdBuffer[256]; + LPCWSTR devId = 0; #else UINT32 devId = 0; /* 0 == system default device. */ #endif @@ -353,7 +346,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) #endif // ! defined(__cplusplus) #if defined(__WINRT__) - SDL_zero(devId); + SDL_zero(devIdBuffer); #endif if (iscapture) { @@ -363,6 +356,14 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) SDL_SetError("XAudio2: XAudio2Create() failed."); return 0; } + 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 (devname != NULL) { UINT32 devcount = 0; @@ -376,13 +377,14 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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); + 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(devId, ARRAYSIZE(devId), details.DeviceID, _TRUNCATE); + wcsncpy_s(devIdBuffer, ARRAYSIZE(devIdBuffer), details.DeviceID, _TRUNCATE); + devId = (LPCWSTR) &devIdBuffer; #else devId = i; #endif @@ -478,11 +480,19 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; + waveformat.cbSize = sizeof(waveformat); +#ifdef __WINRT__ + 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); SDL_SetError("XAudio2: Couldn't create source voice"); @@ -529,6 +539,7 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) /* 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; diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp index 2fbf63c8b..7fa14ab7e 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -8,6 +8,7 @@ using Windows::Devices::Enumeration::DeviceInformationCollection; HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) { + // 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) { From d966870bc6a126a099cf2f921b3dc3f90c264dce Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 11:20:59 -0500 Subject: [PATCH 052/264] WinRT: disabled the XAudio2 backend, pending work on stability and quality --- include/SDL_config_windowsrt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 759dcb866..8790e0060 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -144,7 +144,7 @@ typedef unsigned int uintptr_t; #endif /* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_XAUDIO2 1 +//#define SDL_AUDIO_DRIVER_XAUDIO2 1 /* Disabled pending work to fix quality + stability issues */ #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 From afa31553cdf06f8e8508df7e8da4d59b7319a5f4 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 11:46:15 -0500 Subject: [PATCH 053/264] WinRT: cleaned up SDL_platform_windowsrt.h --- include/SDL_config_windowsrt.h | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 8790e0060..7634d48a6 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -76,10 +76,8 @@ typedef unsigned int uintptr_t; # define SIZEOF_VOIDP 4 #endif -/* Enabled for SDL 1.2 (binary compatibility) */ -#define HAVE_LIBC 1 -#ifdef HAVE_LIBC /* Useful headers */ +#define HAVE_LIBC 1 #define HAVE_STDIO_H 1 #define STDC_HEADERS 1 #define HAVE_STRING_H 1 @@ -102,13 +100,13 @@ typedef unsigned int uintptr_t; #define HAVE_STRLEN 1 #define HAVE__STRREV 1 #define HAVE__STRUPR 1 -//#define HAVE__STRLWR 1 // TODO, WinRT: use _strlwr_s instead +//#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 -//#define HAVE__LTOA 1 // TODO, WinRT: use _ltoa_s instead -//#define HAVE__ULTOA 1 // TODO, WinRT: use _ultoa_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 @@ -119,7 +117,7 @@ typedef unsigned int uintptr_t; #define HAVE_STRNCMP 1 #define HAVE__STRICMP 1 #define HAVE__STRNICMP 1 -//#define HAVE_SSCANF 1 // TODO, WinRT: use sscanf_s instead +//#define HAVE_SSCANF 1 // TODO, WinRT: consider using sscanf_s instead #define HAVE_M_PI 1 #define HAVE_ATAN 1 #define HAVE_ATAN2 1 @@ -135,13 +133,6 @@ typedef unsigned int uintptr_t; #define HAVE_SIN 1 #define HAVE_SINF 1 #define HAVE_SQRT 1 -#else -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 -//#define HAVE_STDLIB_H 1 -//#define HAVE_MALLOC 1 -//#define HAVE_FREE 1 -#endif /* Enable various audio drivers */ //#define SDL_AUDIO_DRIVER_XAUDIO2 1 /* Disabled pending work to fix quality + stability issues */ @@ -155,11 +146,11 @@ typedef unsigned int uintptr_t; #define SDL_JOYSTICK_DISABLED 1 /* Enable various shared object loading systems */ -#define SDL_LOADSO_WINDOWS 1 +// TODO, WinRT: adapt the Win32 shared object loading code for WinRT +#define SDL_LOADSO_DISABLED 1 +//#define SDL_LOADSO_WINDOWS 1 /* Enable various threading systems */ -//#define SDL_THREADS_DISABLED 1 -//#define SDL_THREAD_WINDOWS 1 #define SDL_THREAD_STDCPP 1 /* Enable various timer systems */ @@ -175,7 +166,8 @@ typedef unsigned int uintptr_t; // TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. /* Enable system power support */ -#define SDL_POWER_WINDOWS 1 +// 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 From a83b10fba8bb08f41a9f070ac59de1ae726c34ea Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 24 Nov 2012 12:07:35 -0500 Subject: [PATCH 054/264] WinRT: got timers working --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 2 +- include/SDL_config_windowsrt.h | 5 +---- src/timer/windows/SDL_systimer.c | 23 ++++++++++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index bdf0478d6..7d6deb876 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -94,8 +94,8 @@ - + diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 7634d48a6..8330c10be 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -154,10 +154,7 @@ typedef unsigned int uintptr_t; #define SDL_THREAD_STDCPP 1 /* Enable various timer systems */ -// TODO, WinRT: look into getting SDL's pre-WinRT timers working. -// Some functions there are supported in WinRT, others are not. -//#define SDL_TIMER_WINDOWS 1 -#define SDL_TIMERS_DISABLED 1 +#define SDL_TIMER_WINDOWS 1 /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_WINRT 1 diff --git a/src/timer/windows/SDL_systimer.c b/src/timer/windows/SDL_systimer.c index a08c9ff31..60524d93c 100644 --- a/src/timer/windows/SDL_systimer.c +++ b/src/timer/windows/SDL_systimer.c @@ -48,7 +48,7 @@ SDL_StartTicks(void) #ifdef USE_GETTICKCOUNT start = GetTickCount(); #else -#if 0 /* Apparently there are problems with QPC on Win2K */ +#ifdef __WINRT__ /* Apparently there are problems with QPC on Win2K */ if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { hires_timer_available = TRUE; QueryPerformanceCounter(&hires_start_ticks); @@ -56,8 +56,12 @@ SDL_StartTicks(void) #endif { hires_timer_available = FALSE; +#ifdef __WINRT__ + start = 0; /* the timer failed to start! */ +#else timeBeginPeriod(1); /* use 1 ms timer precision */ start = timeGetTime(); +#endif } #endif } @@ -82,7 +86,11 @@ SDL_GetTicks(void) return (DWORD) hires_now.QuadPart; } else { +#ifdef __WINRT__ + now = 0; +#else now = timeGetTime(); +#endif } #endif @@ -116,6 +124,19 @@ SDL_GetPerformanceFrequency(void) return frequency.QuadPart; } +#ifdef __WINRT__ +static void +Sleep(DWORD timeout) +{ + static HANDLE mutex = 0; + if ( ! mutex ) + { + mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); + } + WaitForSingleObjectEx(mutex, timeout, FALSE); +} +#endif + void SDL_Delay(Uint32 ms) { From 615aeebd1acc9e557d9fc2dd1294ef843b5f2f9b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 14:45:04 -0500 Subject: [PATCH 055/264] WinRT: fixed Win32 builds by prevented __WINRT__ from being defined --- include/SDL_platform.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 6939f1f15..8dcc8f0a4 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -130,9 +130,8 @@ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #undef __WIN32__ #define __WIN32__ 1 -#endif +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) /* Include WinRT / Windows Store APIs in SDL, if available: */ -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) #undef __WINRT__ #define __WINRT__ 1 #endif From 6e713b5e0fb4020828b08995e207d63df7c68b5a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 14:45:22 -0500 Subject: [PATCH 056/264] WinRT: fixed Win32 compile error in XAudio2 backend --- src/audio/xaudio2/SDL_xaudio2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index bef13f68b..bbb27d0dd 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -356,6 +356,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) SDL_SetError("XAudio2: XAudio2Create() failed."); return 0; } + /* 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; @@ -364,6 +365,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) debugConfig.LogFunctionName = TRUE; debugConfig.LogTiming = TRUE; ixa2->SetDebugConfiguration(&debugConfig); + */ if (devname != NULL) { UINT32 devcount = 0; From 0ff4b6168782c1a99960df7e3ca0194336bfbec6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 17:34:41 -0500 Subject: [PATCH 057/264] WinRT: allow windows in non-native screen sizes. Scaling is applied for such. --- src/video/windowsrt/SDL_WinRTApp.cpp | 5 ++ src/video/windowsrt/SDL_WinRTApp.h | 1 + src/video/windowsrt/SDL_winrtframebuffer.cpp | 6 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 93 +++++++++++--------- src/video/windowsrt/SDL_winrtrenderer.h | 1 + src/video/windowsrt/SDL_winrtvideo.cpp | 42 ++++++++- 6 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index dc8cac9b9..15ee94973 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -447,6 +447,11 @@ void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData) m_sdlWindowData = windowData; } +void SDL_WinRTApp::ResizeMainTexture(int w, int h) +{ + m_renderer->ResizeMainTexture(w, h); +} + IFrameworkView^ Direct3DApplicationSource::CreateView() { // TODO, WinRT: see if this function (CreateView) can ever get called diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 333f734ba..48c1b7713 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -27,6 +27,7 @@ internal: bool HasSDLWindowData() const; void SetSDLWindowData(const SDL_WindowData * windowData); void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects); + void ResizeMainTexture(int w, int h); protected: // Event Handlers. diff --git a/src/video/windowsrt/SDL_winrtframebuffer.cpp b/src/video/windowsrt/SDL_winrtframebuffer.cpp index ae6132ac3..a53945454 100644 --- a/src/video/windowsrt/SDL_winrtframebuffer.cpp +++ b/src/video/windowsrt/SDL_winrtframebuffer.cpp @@ -53,11 +53,15 @@ int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * forma return -1; } - /* Save the info and return! */ + /* Save info on the surface */ SDL_SetWindowData(window, WINRT_SURFACE, surface); *format = surface_format; *pixels = surface->pixels; *pitch = surface->pitch; + + /* Make sure a Direct3D texture exists to draw the surface onto */ + SDL_WinRTGlobalApp->ResizeMainTexture(surface->w, surface->h); + return 0; } diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 2e2ab206c..99a7824f1 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -82,48 +82,7 @@ void SDL_winrtrenderer::CreateDeviceResources() ); }); - auto createMainTextureTask = createCubeTask.then([this] () { - D3D11_TEXTURE2D_DESC textureDesc = {0}; - textureDesc.Width = (int)m_windowBounds.Width; - textureDesc.Height = (int)m_windowBounds.Height; - textureDesc.MipLevels = 1; - textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Usage = D3D11_USAGE_DYNAMIC; - textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - textureDesc.MiscFlags = 0; - - const int numPixels = (int)m_windowBounds.Width * (int)m_windowBounds.Height; - std::vector initialTexturePixels(numPixels * 4, 0x00); - D3D11_SUBRESOURCE_DATA initialTextureData = {0}; - initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); - initialTextureData.SysMemPitch = (int)m_windowBounds.Width * 4; - initialTextureData.SysMemSlicePitch = numPixels * 4; - DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( - &textureDesc, - &initialTextureData, - &m_mainTexture - ) - ); - - 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; - DX::ThrowIfFailed( - m_d3dDevice->CreateShaderResourceView( - m_mainTexture.Get(), - &resourceViewDesc, - &m_mainTextureResourceView) - ); - }); - - auto createMainSamplerTask = createMainTextureTask.then([this] () { + auto createMainSamplerTask = createCubeTask.then([this] () { D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; @@ -151,6 +110,48 @@ void SDL_winrtrenderer::CreateDeviceResources() }); } +void SDL_winrtrenderer::ResizeMainTexture(int w, int h) +{ + D3D11_TEXTURE2D_DESC textureDesc = {0}; + textureDesc.Width = w; + textureDesc.Height = h; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DYNAMIC; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + textureDesc.MiscFlags = 0; + + const int numPixels = textureDesc.Width * textureDesc.Height; + std::vector initialTexturePixels(numPixels * 4, 0x00); + D3D11_SUBRESOURCE_DATA initialTextureData = {0}; + initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); + initialTextureData.SysMemPitch = textureDesc.Width * 4; + initialTextureData.SysMemSlicePitch = numPixels * 4; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &textureDesc, + &initialTextureData, + &m_mainTexture + ) + ); + + 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; + DX::ThrowIfFailed( + m_d3dDevice->CreateShaderResourceView( + m_mainTexture.Get(), + &resourceViewDesc, + &m_mainTextureResourceView) + ); +} + void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { const float blackColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -171,6 +172,10 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr { return; } + if (!m_mainTextureResourceView) + { + return; + } // Update the main texture (for SDL usage): D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; @@ -185,7 +190,9 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr // TODO, WinRT: only copy over the requested rects (via SDL_BlitSurface, perhaps?) // TODO, WinRT: do a sanity check on the src and dest data when updating the window surface - const unsigned int numBytes = (int)m_windowBounds.Width * (int)m_windowBounds.Height * 4; + D3D11_TEXTURE2D_DESC textureDesc = {0}; + m_mainTexture->GetDesc(&textureDesc); + const unsigned int numBytes = textureDesc.Width * textureDesc.Height * 4; memcpy(textureMemory.pData, surface->pixels, numBytes); m_d3dContext->Unmap( diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index bcdce2bac..7d39a26fa 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -19,6 +19,7 @@ public: internal: virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) override; + void ResizeMainTexture(int w, int h); private: bool m_loadingComplete; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 16a0474b9..66c36357f 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -154,14 +154,50 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_zerop(data); data->sdlWindow = window; - /* Adjust the window data to match the screen */ + /* 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->w = _this->displays->desktop_mode.w; - window->h = _this->displays->desktop_mode.h; + 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; } From 59cb7e8c49bb3128e4937daa0adbb45b3fddcfa9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 17:35:41 -0500 Subject: [PATCH 058/264] WinRT: made the WinRT video driver report its name correctly --- src/video/windowsrt/SDL_winrtvideo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 66c36357f..2f7c6725b 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -48,7 +48,7 @@ extern "C" { extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; -#define WINRTVID_DRIVER_NAME "dummy" +#define WINRTVID_DRIVER_NAME "winrt" /* Initialization/Query functions */ static int WINRT_VideoInit(_THIS); From 3ae66245a74da976e5fad07296ca2466bcefd393 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 19:05:56 -0500 Subject: [PATCH 059/264] WinRT: video code cleanup: combined files Direct3DBase.* and SDL_winrtrenderer.* --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 9 - src/video/windowsrt/Direct3DBase.cpp | 344 ---------------------- src/video/windowsrt/Direct3DBase.h | 41 --- src/video/windowsrt/SDL_winrtrenderer.cpp | 336 ++++++++++++++++++++- src/video/windowsrt/SDL_winrtrenderer.h | 43 ++- 5 files changed, 365 insertions(+), 408 deletions(-) delete mode 100644 src/video/windowsrt/Direct3DBase.cpp delete mode 100644 src/video/windowsrt/Direct3DBase.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 7d6deb876..3db48e32d 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -117,14 +117,6 @@ - - true - true - true - true - true - true - true true @@ -270,7 +262,6 @@ - diff --git a/src/video/windowsrt/Direct3DBase.cpp b/src/video/windowsrt/Direct3DBase.cpp deleted file mode 100644 index bb0ea593d..000000000 --- a/src/video/windowsrt/Direct3DBase.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#include "SDLmain_WinRT_common.h" -#include "Direct3DBase.h" - -using namespace DirectX; -using namespace Microsoft::WRL; -using namespace Windows::UI::Core; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; - -// Constructor. -Direct3DBase::Direct3DBase() -{ -} - -// Initialize the Direct3D resources required to run. -void Direct3DBase::Initialize(CoreWindow^ window) -{ - m_window = window; - - CreateDeviceResources(); - CreateWindowSizeDependentResources(); -} - -// Recreate all device resources and set them back to the current state. -void Direct3DBase::HandleDeviceLost() -{ - // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. - m_windowBounds.Width = 0; - m_windowBounds.Height = 0; - m_swapChain = nullptr; - - CreateDeviceResources(); - UpdateForWindowSizeChange(); -} - -// These are the resources that depend on the device. -void Direct3DBase::CreateDeviceResources() -{ - // 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 device; - ComPtr context; - DX::ThrowIfFailed( - 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. - &m_featureLevel, // Returns feature level of device created. - &context // Returns the device immediate context. - ) - ); - - // Get the Direct3D 11.1 API device and context interfaces. - DX::ThrowIfFailed( - device.As(&m_d3dDevice) - ); - - DX::ThrowIfFailed( - context.As(&m_d3dContext) - ); -} - -// Allocate all memory resources that change on a window SizeChanged event. -void Direct3DBase::CreateWindowSizeDependentResources() -{ - // Store the window bounds so the next time we get a SizeChanged event we can - // avoid rebuilding everything if the size is identical. - m_windowBounds = m_window->Bounds; - - // Calculate the necessary swap chain and render target size in pixels. - float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); - float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); - - // 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. - m_orientation = DisplayProperties::CurrentOrientation; - bool swapDimensions = - m_orientation == DisplayOrientations::Portrait || - m_orientation == DisplayOrientations::PortraitFlipped; - m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; - m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; - - if(m_swapChain != nullptr) - { - // If the swap chain already exists, resize it. - DX::ThrowIfFailed( - m_swapChain->ResizeBuffers( - 2, // Double-buffered swap chain. - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - DXGI_FORMAT_B8G8R8A8_UNORM, - 0 - ) - ); - } - 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(m_renderTargetSize.Width); // Match the size of the window. - swapChainDesc.Height = static_cast(m_renderTargetSize.Height); - 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. - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. - swapChainDesc.Flags = 0; - - ComPtr dxgiDevice; - DX::ThrowIfFailed( - m_d3dDevice.As(&dxgiDevice) - ); - - ComPtr dxgiAdapter; - DX::ThrowIfFailed( - dxgiDevice->GetAdapter(&dxgiAdapter) - ); - - ComPtr dxgiFactory; - DX::ThrowIfFailed( - dxgiAdapter->GetParent( - __uuidof(IDXGIFactory2), - &dxgiFactory - ) - ); - - Windows::UI::Core::CoreWindow^ window = m_window.Get(); - DX::ThrowIfFailed( - dxgiFactory->CreateSwapChainForCoreWindow( - m_d3dDevice.Get(), - reinterpret_cast(window), - &swapChainDesc, - nullptr, // Allow on all displays. - &m_swapChain - ) - ); - - // 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. - DX::ThrowIfFailed( - dxgiDevice->SetMaximumFrameLatency(1) - ); - } - - // 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 (m_orientation) - { - case DisplayOrientations::Landscape: - rotation = DXGI_MODE_ROTATION_IDENTITY; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE270; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE180; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE90; - m_orientationTransform3D = 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: - throw ref new Platform::FailureException(); - } - - DX::ThrowIfFailed( - m_swapChain->SetRotation(rotation) - ); - - // Create a render target view of the swap chain back buffer. - ComPtr backBuffer; - DX::ThrowIfFailed( - m_swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ) - ); - - DX::ThrowIfFailed( - m_d3dDevice->CreateRenderTargetView( - backBuffer.Get(), - nullptr, - &m_renderTargetView - ) - ); - - // Create a depth stencil view. - CD3D11_TEXTURE2D_DESC depthStencilDesc( - DXGI_FORMAT_D24_UNORM_S8_UINT, - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - 1, - 1, - D3D11_BIND_DEPTH_STENCIL - ); - - ComPtr depthStencil; - DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( - &depthStencilDesc, - nullptr, - &depthStencil - ) - ); - - CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); - DX::ThrowIfFailed( - m_d3dDevice->CreateDepthStencilView( - depthStencil.Get(), - &depthStencilViewDesc, - &m_depthStencilView - ) - ); - - // Set the rendering viewport to target the entire window. - CD3D11_VIEWPORT viewport( - 0.0f, - 0.0f, - m_renderTargetSize.Width, - m_renderTargetSize.Height - ); - - m_d3dContext->RSSetViewports(1, &viewport); -} - -// This method is called in the event handler for the SizeChanged event. -void Direct3DBase::UpdateForWindowSizeChange() -{ - if (m_window->Bounds.Width != m_windowBounds.Width || - m_window->Bounds.Height != m_windowBounds.Height || - m_orientation != DisplayProperties::CurrentOrientation) - { - ID3D11RenderTargetView* nullViews[] = {nullptr}; - m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - m_renderTargetView = nullptr; - m_depthStencilView = nullptr; - m_d3dContext->Flush(); - CreateWindowSizeDependentResources(); - } -} - -// Method to deliver the final image to the display. -void Direct3DBase::Present() -{ - // The application may optionally specify "dirty" or "scroll" - // rects to improve efficiency in certain scenarios. - 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 = m_swapChain->Present1(1, 0, ¶meters); - - // 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. - m_d3dContext->DiscardView(m_renderTargetView.Get()); - - // Discard the contents of the depth stencil. - m_d3dContext->DiscardView(m_depthStencilView.Get()); - - // If the device was removed either by a disconnect or a driver upgrade, we - // must recreate all device resources. - if (hr == DXGI_ERROR_DEVICE_REMOVED) - { - HandleDeviceLost(); - } - else - { - DX::ThrowIfFailed(hr); - } -} - -// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. -float Direct3DBase::ConvertDipsToPixels(float dips) -{ - static const float dipsPerInch = 96.0f; - return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. -} diff --git a/src/video/windowsrt/Direct3DBase.h b/src/video/windowsrt/Direct3DBase.h deleted file mode 100644 index eab1a178e..000000000 --- a/src/video/windowsrt/Direct3DBase.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "DirectXHelper.h" -#include "SDL.h" - -// Helper class that initializes DirectX APIs for 3D rendering. -ref class Direct3DBase abstract -{ -internal: - Direct3DBase(); - -public: - virtual void Initialize(Windows::UI::Core::CoreWindow^ window); - virtual void HandleDeviceLost(); - virtual void CreateDeviceResources(); - virtual void CreateWindowSizeDependentResources(); - virtual void UpdateForWindowSizeChange(); - virtual void Present(); - virtual float ConvertDipsToPixels(float dips); - -internal: - virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) = 0; - -protected private: - // Direct3D Objects. - Microsoft::WRL::ComPtr m_d3dDevice; - Microsoft::WRL::ComPtr m_d3dContext; - Microsoft::WRL::ComPtr m_swapChain; - Microsoft::WRL::ComPtr m_renderTargetView; - Microsoft::WRL::ComPtr m_depthStencilView; - - // Cached renderer properties. - D3D_FEATURE_LEVEL m_featureLevel; - Windows::Foundation::Size m_renderTargetSize; - Windows::Foundation::Rect m_windowBounds; - Platform::Agile m_window; - Windows::Graphics::Display::DisplayOrientations m_orientation; - - // Transform used for display orientation. - DirectX::XMFLOAT4X4 m_orientationTransform3D; -}; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 99a7824f1..a64cfddae 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -3,20 +3,93 @@ using namespace DirectX; using namespace Microsoft::WRL; -using namespace Windows::Foundation; using namespace Windows::UI::Core; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; +// Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : - m_loadingComplete(false), + m_loadingComplete(false), m_vertexCount(0) { } +// Initialize the Direct3D resources required to run. +void SDL_winrtrenderer::Initialize(CoreWindow^ window) +{ + m_window = window; + + CreateDeviceResources(); + CreateWindowSizeDependentResources(); +} + +// Recreate all device resources and set them back to the current state. +void SDL_winrtrenderer::HandleDeviceLost() +{ + // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. + m_windowBounds.Width = 0; + m_windowBounds.Height = 0; + m_swapChain = nullptr; + + CreateDeviceResources(); + UpdateForWindowSizeChange(); +} + +// These are the resources that depend on the device. void SDL_winrtrenderer::CreateDeviceResources() { - Direct3DBase::CreateDeviceResources(); + // 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; - auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); +#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 device; + ComPtr context; + DX::ThrowIfFailed( + 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. + &m_featureLevel, // Returns feature level of device created. + &context // Returns the device immediate context. + ) + ); + + // Get the Direct3D 11.1 API device and context interfaces. + DX::ThrowIfFailed( + device.As(&m_d3dDevice) + ); + + DX::ThrowIfFailed( + context.As(&m_d3dContext) + ); + + auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { @@ -110,6 +183,202 @@ void SDL_winrtrenderer::CreateDeviceResources() }); } +// Allocate all memory resources that change on a window SizeChanged event. +void SDL_winrtrenderer::CreateWindowSizeDependentResources() +{ + // Store the window bounds so the next time we get a SizeChanged event we can + // avoid rebuilding everything if the size is identical. + m_windowBounds = m_window->Bounds; + + // Calculate the necessary swap chain and render target size in pixels. + float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); + float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); + + // 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. + m_orientation = DisplayProperties::CurrentOrientation; + bool swapDimensions = + m_orientation == DisplayOrientations::Portrait || + m_orientation == DisplayOrientations::PortraitFlipped; + m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; + m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; + + if(m_swapChain != nullptr) + { + // If the swap chain already exists, resize it. + DX::ThrowIfFailed( + m_swapChain->ResizeBuffers( + 2, // Double-buffered swap chain. + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + DXGI_FORMAT_B8G8R8A8_UNORM, + 0 + ) + ); + } + 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(m_renderTargetSize.Width); // Match the size of the window. + swapChainDesc.Height = static_cast(m_renderTargetSize.Height); + 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. + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. + swapChainDesc.Flags = 0; + + ComPtr dxgiDevice; + DX::ThrowIfFailed( + m_d3dDevice.As(&dxgiDevice) + ); + + ComPtr dxgiAdapter; + DX::ThrowIfFailed( + dxgiDevice->GetAdapter(&dxgiAdapter) + ); + + ComPtr dxgiFactory; + DX::ThrowIfFailed( + dxgiAdapter->GetParent( + __uuidof(IDXGIFactory2), + &dxgiFactory + ) + ); + + Windows::UI::Core::CoreWindow^ window = m_window.Get(); + DX::ThrowIfFailed( + dxgiFactory->CreateSwapChainForCoreWindow( + m_d3dDevice.Get(), + reinterpret_cast(window), + &swapChainDesc, + nullptr, // Allow on all displays. + &m_swapChain + ) + ); + + // 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. + DX::ThrowIfFailed( + dxgiDevice->SetMaximumFrameLatency(1) + ); + } + + // 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 (m_orientation) + { + case DisplayOrientations::Landscape: + rotation = DXGI_MODE_ROTATION_IDENTITY; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE270; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE180; + m_orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE90; + m_orientationTransform3D = 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: + throw ref new Platform::FailureException(); + } + + DX::ThrowIfFailed( + m_swapChain->SetRotation(rotation) + ); + + // Create a render target view of the swap chain back buffer. + ComPtr backBuffer; + DX::ThrowIfFailed( + m_swapChain->GetBuffer( + 0, + __uuidof(ID3D11Texture2D), + &backBuffer + ) + ); + + DX::ThrowIfFailed( + m_d3dDevice->CreateRenderTargetView( + backBuffer.Get(), + nullptr, + &m_renderTargetView + ) + ); + + // Create a depth stencil view. + CD3D11_TEXTURE2D_DESC depthStencilDesc( + DXGI_FORMAT_D24_UNORM_S8_UINT, + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + 1, + 1, + D3D11_BIND_DEPTH_STENCIL + ); + + ComPtr depthStencil; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &depthStencilDesc, + nullptr, + &depthStencil + ) + ); + + CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); + DX::ThrowIfFailed( + m_d3dDevice->CreateDepthStencilView( + depthStencil.Get(), + &depthStencilViewDesc, + &m_depthStencilView + ) + ); + + // Set the rendering viewport to target the entire window. + CD3D11_VIEWPORT viewport( + 0.0f, + 0.0f, + m_renderTargetSize.Width, + m_renderTargetSize.Height + ); + + m_d3dContext->RSSetViewports(1, &viewport); +} + void SDL_winrtrenderer::ResizeMainTexture(int w, int h) { D3D11_TEXTURE2D_DESC textureDesc = {0}; @@ -152,6 +421,22 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) ); } +// This method is called in the event handler for the SizeChanged event. +void SDL_winrtrenderer::UpdateForWindowSizeChange() +{ + if (m_window->Bounds.Width != m_windowBounds.Width || + m_window->Bounds.Height != m_windowBounds.Height || + m_orientation != DisplayProperties::CurrentOrientation) + { + ID3D11RenderTargetView* nullViews[] = {nullptr}; + m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + m_renderTargetView = nullptr; + m_depthStencilView = nullptr; + m_d3dContext->Flush(); + CreateWindowSizeDependentResources(); + } +} + void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { const float blackColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -237,3 +522,46 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr m_d3dContext->Draw(4, 0); } + +// Method to deliver the final image to the display. +void SDL_winrtrenderer::Present() +{ + // The application may optionally specify "dirty" or "scroll" + // rects to improve efficiency in certain scenarios. + 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 = m_swapChain->Present1(1, 0, ¶meters); + + // 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. + m_d3dContext->DiscardView(m_renderTargetView.Get()); + + // Discard the contents of the depth stencil. + m_d3dContext->DiscardView(m_depthStencilView.Get()); + + // If the device was removed either by a disconnect or a driver upgrade, we + // must recreate all device resources. + if (hr == DXGI_ERROR_DEVICE_REMOVED) + { + HandleDeviceLost(); + } + else + { + DX::ThrowIfFailed(hr); + } +} + +// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. +float SDL_winrtrenderer::ConvertDipsToPixels(float dips) +{ + static const float dipsPerInch = 96.0f; + return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. +} diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 7d39a26fa..a32697b76 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -1,6 +1,7 @@ #pragma once -#include "Direct3DBase.h" +#include "DirectXHelper.h" +#include "SDL.h" struct VertexPositionColor { @@ -8,22 +9,32 @@ struct VertexPositionColor DirectX::XMFLOAT2 tex; }; -// This class renders a simple spinning cube. -ref class SDL_winrtrenderer sealed : public Direct3DBase +// Helper class that initializes DirectX APIs for 3D rendering. +ref class SDL_winrtrenderer { -public: +internal: SDL_winrtrenderer(); - // Direct3DBase methods. - virtual void CreateDeviceResources() override; +public: + virtual void Initialize(Windows::UI::Core::CoreWindow^ window); + virtual void HandleDeviceLost(); + virtual void CreateDeviceResources(); + virtual void CreateWindowSizeDependentResources(); + virtual void UpdateForWindowSizeChange(); + virtual void Present(); + virtual float ConvertDipsToPixels(float dips); internal: - virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) override; + virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); void ResizeMainTexture(int w, int h); -private: - bool m_loadingComplete; - +protected private: + // Direct3D Objects. + Microsoft::WRL::ComPtr m_d3dDevice; + Microsoft::WRL::ComPtr m_d3dContext; + Microsoft::WRL::ComPtr m_swapChain; + Microsoft::WRL::ComPtr m_renderTargetView; + Microsoft::WRL::ComPtr m_depthStencilView; Microsoft::WRL::ComPtr m_inputLayout; Microsoft::WRL::ComPtr m_vertexBuffer; Microsoft::WRL::ComPtr m_vertexShader; @@ -32,5 +43,17 @@ private: Microsoft::WRL::ComPtr m_mainTextureResourceView; Microsoft::WRL::ComPtr m_mainSampler; + // Cached renderer properties. + D3D_FEATURE_LEVEL m_featureLevel; + Windows::Foundation::Size m_renderTargetSize; + Windows::Foundation::Rect m_windowBounds; + Platform::Agile m_window; + Windows::Graphics::Display::DisplayOrientations m_orientation; uint32 m_vertexCount; + + // Transform used for display orientation. + DirectX::XMFLOAT4X4 m_orientationTransform3D; + + // Has the renderer finished loading? + bool m_loadingComplete; }; From ba39e2a2292336ffd4ce38c4d9d0a3cd229f6912 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 19:10:02 -0500 Subject: [PATCH 060/264] WinRT: removed unneeded Direct3D stencil buffer code --- src/video/windowsrt/SDL_winrtrenderer.cpp | 22 +--------------------- src/video/windowsrt/SDL_winrtrenderer.h | 1 - 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index a64cfddae..3a17e0962 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -359,15 +359,6 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() ) ); - CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); - DX::ThrowIfFailed( - m_d3dDevice->CreateDepthStencilView( - depthStencil.Get(), - &depthStencilViewDesc, - &m_depthStencilView - ) - ); - // Set the rendering viewport to target the entire window. CD3D11_VIEWPORT viewport( 0.0f, @@ -431,7 +422,6 @@ void SDL_winrtrenderer::UpdateForWindowSizeChange() ID3D11RenderTargetView* nullViews[] = {nullptr}; m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); m_renderTargetView = nullptr; - m_depthStencilView = nullptr; m_d3dContext->Flush(); CreateWindowSizeDependentResources(); } @@ -445,13 +435,6 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr blackColor ); - m_d3dContext->ClearDepthStencilView( - m_depthStencilView.Get(), - D3D11_CLEAR_DEPTH, - 1.0f, - 0 - ); - // Only draw the cube once it is loaded (loading is asynchronous). if (!m_loadingComplete) { @@ -487,7 +470,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr m_d3dContext->OMSetRenderTargets( 1, m_renderTargetView.GetAddressOf(), - m_depthStencilView.Get() + nullptr ); UINT stride = sizeof(VertexPositionColor); @@ -544,9 +527,6 @@ void SDL_winrtrenderer::Present() // overwritten. If dirty or scroll rects are used, this call should be removed. m_d3dContext->DiscardView(m_renderTargetView.Get()); - // Discard the contents of the depth stencil. - m_d3dContext->DiscardView(m_depthStencilView.Get()); - // If the device was removed either by a disconnect or a driver upgrade, we // must recreate all device resources. if (hr == DXGI_ERROR_DEVICE_REMOVED) diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index a32697b76..9e5c8fbb1 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -34,7 +34,6 @@ protected private: Microsoft::WRL::ComPtr m_d3dContext; Microsoft::WRL::ComPtr m_swapChain; Microsoft::WRL::ComPtr m_renderTargetView; - Microsoft::WRL::ComPtr m_depthStencilView; Microsoft::WRL::ComPtr m_inputLayout; Microsoft::WRL::ComPtr m_vertexBuffer; Microsoft::WRL::ComPtr m_vertexShader; From 377091d020e74260fe8823db9bdbf34c32ca8624 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 19:13:45 -0500 Subject: [PATCH 061/264] WinRT: minor code cleanup regarding some variable names --- src/video/windowsrt/SDL_winrtrenderer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 3a17e0962..97d6d5c66 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -130,8 +130,8 @@ void SDL_winrtrenderer::CreateDeviceResources() ); }); - auto createCubeTask = (createPSTask && createVSTask).then([this] () { - VertexPositionColor cubeVertices[] = + auto createVertexBuffer = (createPSTask && createVSTask).then([this] () { + VertexPositionColor vertices[] = { {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, @@ -139,13 +139,13 @@ void SDL_winrtrenderer::CreateDeviceResources() {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, }; - m_vertexCount = ARRAYSIZE(cubeVertices); + m_vertexCount = ARRAYSIZE(vertices); D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = cubeVertices; + vertexBufferData.pSysMem = vertices; vertexBufferData.SysMemPitch = 0; vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER); + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); DX::ThrowIfFailed( m_d3dDevice->CreateBuffer( &vertexBufferDesc, @@ -155,7 +155,7 @@ void SDL_winrtrenderer::CreateDeviceResources() ); }); - auto createMainSamplerTask = createCubeTask.then([this] () { + auto createMainSamplerTask = createVertexBuffer.then([this] () { D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; @@ -435,7 +435,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr blackColor ); - // Only draw the cube once it is loaded (loading is asynchronous). + // Only draw the screen once it is loaded (some loading is asynchronous). if (!m_loadingComplete) { return; From 9c173dcc1d784efd2df2666c9f6410e62d01310d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 25 Nov 2012 23:27:12 -0500 Subject: [PATCH 062/264] WinRT: fixed incorrect cursor positions when using non-native screen resolutions --- src/video/windowsrt/SDL_WinRTApp.cpp | 16 +++++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 15ee94973..87a5f0367 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -167,11 +167,25 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) } } +// 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 (m_sdlWindowData) { - SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, (int)args->CurrentPoint->Position.X, (int)args->CurrentPoint->Position.Y); + Point transformedPoint = TransformCursor(args->CurrentPoint->Position); + SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, (int)transformedPoint.X, (int)transformedPoint.Y); } } diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 48c1b7713..f00417327 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -28,6 +28,7 @@ internal: void SetSDLWindowData(const SDL_WindowData * windowData); void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects); void ResizeMainTexture(int w, int h); + Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); protected: // Event Handlers. From 06373c36da732563586e60879ceceabcda49c5d6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 3 Dec 2012 22:36:00 -0500 Subject: [PATCH 063/264] WinRT: added cursor visibility toggling, and system cursor creation --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 9 ++ src/video/windowsrt/SDL_winrtmouse.cpp | 146 +++++++++++++++++++++++++ src/video/windowsrt/SDL_winrtmouse.h | 31 ++++++ src/video/windowsrt/SDL_winrtvideo.cpp | 23 +++- 4 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 src/video/windowsrt/SDL_winrtmouse.cpp create mode 100644 src/video/windowsrt/SDL_winrtmouse.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 3db48e32d..a9fd5460c 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -141,6 +141,14 @@ true true + + true + true + true + true + true + true + true true @@ -267,6 +275,7 @@ + diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/windowsrt/SDL_winrtmouse.cpp new file mode 100644 index 000000000..f4bbea6e8 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtmouse.cpp @@ -0,0 +1,146 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 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) +//{ +// //return -1; +// 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 + */ + + //mouse->CreateCursor = WINRT_CreateCursor; + mouse->CreateSystemCursor = WINRT_CreateSystemCursor; + mouse->ShowCursor = WINRT_ShowCursor; + mouse->FreeCursor = WINRT_FreeCursor; + //mouse->WarpMouse = WINRT_WarpMouse; + //mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; // DLudwig: 'relative mouse mode' support is pending + + SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); +} + +void +WINRT_QuitMouse(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtmouse.h b/src/video/windowsrt/SDL_winrtmouse.h new file mode 100644 index 000000000..50bdbe24d --- /dev/null +++ b/src/video/windowsrt/SDL_winrtmouse.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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: */ diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 2f7c6725b..5b72c92a1 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -40,6 +40,7 @@ extern "C" { #include "SDL_winrtvideo.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtframebuffer_c.h" +#include "SDL_winrtmouse.h" /* On Windows, windows.h defines CreateWindow */ #ifdef CreateWindow @@ -52,6 +53,7 @@ extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; /* 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); @@ -111,15 +113,25 @@ VideoBootStrap WINRT_bootstrap = { int WINRT_VideoInit(_THIS) +{ + 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); - - /* We're done! */ + } + + SDL_AddDisplayMode(&_this->displays[0], &mode); return 0; } @@ -132,6 +144,7 @@ WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) void WINRT_VideoQuit(_THIS) { + WINRT_QuitMouse(_this); } int From b96cbdd3a5a7cd42059b3aa04a7e134b3fb41ec6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 9 Dec 2012 22:43:34 -0500 Subject: [PATCH 064/264] WinRT: fixed a window-surface-updating bug (WinRT/DLudwig #25, http://bit.ly/RkawRR) --- src/video/windowsrt/SDL_winrtframebuffer.cpp | 2 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 63 ++++++++++++++++---- src/video/windowsrt/SDL_winrtrenderer.h | 4 ++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtframebuffer.cpp b/src/video/windowsrt/SDL_winrtframebuffer.cpp index a53945454..a30990e19 100644 --- a/src/video/windowsrt/SDL_winrtframebuffer.cpp +++ b/src/video/windowsrt/SDL_winrtframebuffer.cpp @@ -34,7 +34,7 @@ extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_Surface *surface; - const Uint32 surface_format = SDL_PIXELFORMAT_ARGB8888; + const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; int w, h; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 97d6d5c66..8d2124c60 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -9,11 +9,20 @@ using namespace Windows::Graphics::Display; // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : + m_mainTextureHelperSurface(NULL), m_loadingComplete(false), m_vertexCount(0) { } +SDL_winrtrenderer::~SDL_winrtrenderer() +{ + if (m_mainTextureHelperSurface) { + SDL_FreeSurface(m_mainTextureHelperSurface); + m_mainTextureHelperSurface = NULL; + } +} + // Initialize the Direct3D resources required to run. void SDL_winrtrenderer::Initialize(CoreWindow^ window) { @@ -372,12 +381,14 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() void SDL_winrtrenderer::ResizeMainTexture(int w, int h) { + const int pixelSizeInBytes = 4; + D3D11_TEXTURE2D_DESC textureDesc = {0}; textureDesc.Width = w; textureDesc.Height = h; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Usage = D3D11_USAGE_DYNAMIC; @@ -385,12 +396,21 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; textureDesc.MiscFlags = 0; - const int numPixels = textureDesc.Width * textureDesc.Height; - std::vector initialTexturePixels(numPixels * 4, 0x00); + const int numPixels = textureDesc.Width * textureDesc.Height; + std::vector initialTexturePixels(numPixels * pixelSizeInBytes, 0x00); + + // Fill the texture with a non-black color, for debugging purposes: + //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 * 4; - initialTextureData.SysMemSlicePitch = numPixels * 4; + initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes; + initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes; DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &textureDesc, @@ -399,6 +419,20 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) ) ); + if (m_mainTextureHelperSurface) { + SDL_FreeSurface(m_mainTextureHelperSurface); + m_mainTextureHelperSurface = NULL; + } + m_mainTextureHelperSurface = SDL_CreateRGBSurfaceFrom( + NULL, + textureDesc.Width, textureDesc.Height, + (pixelSizeInBytes * 8), + 0, // Use an nil pitch for now. This'll be filled in when updating the texture. + 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); // TODO, WinRT: calculate masks given the Direct3D-defined pixel format of the texture + if (m_mainTextureHelperSurface == NULL) { + DX::ThrowIfFailed(E_FAIL); // TODO, WinRT: generate a better error here, taking into account who's calling this function. + } + D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; resourceViewDesc.Format = textureDesc.Format; resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; @@ -429,7 +463,7 @@ void SDL_winrtrenderer::UpdateForWindowSizeChange() void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { - const float blackColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; m_d3dContext->ClearRenderTargetView( m_renderTargetView.Get(), blackColor @@ -445,7 +479,8 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr return; } - // Update the main texture (for SDL usage): + // Update the main texture (for SDL usage). Start by mapping the SDL + // window's main texture to CPU-accessible memory: D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; DX::ThrowIfFailed( m_d3dContext->Map( @@ -456,13 +491,15 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr &textureMemory) ); - // TODO, WinRT: only copy over the requested rects (via SDL_BlitSurface, perhaps?) - // TODO, WinRT: do a sanity check on the src and dest data when updating the window surface - D3D11_TEXTURE2D_DESC textureDesc = {0}; - m_mainTexture->GetDesc(&textureDesc); - const unsigned int numBytes = textureDesc.Width * textureDesc.Height * 4; - memcpy(textureMemory.pData, surface->pixels, numBytes); + // Copy pixel data to the locked texture's memory: + m_mainTextureHelperSurface->pixels = textureMemory.pData; + m_mainTextureHelperSurface->pitch = textureMemory.RowPitch; + SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL); + // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything + // Clean up a bit, then commit the texture's memory back to Direct3D: + m_mainTextureHelperSurface->pixels = NULL; + m_mainTextureHelperSurface->pitch = 0; m_d3dContext->Unmap( m_mainTexture.Get(), 0); diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 9e5c8fbb1..6b3f9b0f8 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,6 +16,7 @@ internal: SDL_winrtrenderer(); public: + virtual ~SDL_winrtrenderer(); virtual void Initialize(Windows::UI::Core::CoreWindow^ window); virtual void HandleDeviceLost(); virtual void CreateDeviceResources(); @@ -42,6 +43,9 @@ protected private: Microsoft::WRL::ComPtr m_mainTextureResourceView; Microsoft::WRL::ComPtr m_mainSampler; + // UpdateWindowSurface helper objects + SDL_Surface * m_mainTextureHelperSurface; + // Cached renderer properties. D3D_FEATURE_LEVEL m_featureLevel; Windows::Foundation::Size m_renderTargetSize; From 028182452b3f492fc877fbb6ecce0e985c4b8b56 Mon Sep 17 00:00:00 2001 From: "David@Birdo.localdomain" Date: Sun, 16 Dec 2012 21:39:02 -0500 Subject: [PATCH 065/264] WinRT: fixed a build error caused by a reference to a missing and unused header file --- src/video/windowsrt/SDL_WinRTApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 87a5f0367..0ab809b61 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -12,7 +12,7 @@ extern "C" { } // TODO, WinRT: Remove reference(s) to BasicTimer.h -#include "BasicTimer.h" +//#include "BasicTimer.h" // HACK, DLudwig: The C-style main() will get loaded via the app's // WinRT-styled main(), which is part of SDLmain_for_WinRT.cpp. From 69ff35e1531217ad9c0bc5d66485b30dbe572d44 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 28 Dec 2012 13:24:36 -0500 Subject: [PATCH 066/264] WinRT: added support for SDL_SetRelativeMouseMode --- src/video/windowsrt/SDL_WinRTApp.cpp | 77 +++++++++++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 3 + src/video/windowsrt/SDL_winrtmouse.cpp | 14 ++--- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 0ab809b61..a3cd3a663 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -33,6 +33,7 @@ SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Devices::Input; using namespace Windows::UI::Core; using namespace Windows::System; using namespace Windows::Foundation; @@ -42,7 +43,8 @@ using namespace concurrency; SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), - m_sdlWindowData(NULL) + m_sdlWindowData(NULL), + m_useRelativeMouseMode(false) { } @@ -82,6 +84,10 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerMoved += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + // Retrieves relative-only mouse movements: + Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); + window->KeyDown += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); @@ -167,6 +173,68 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) } } +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 + // without transformation. + // + SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 1, args->MouseDelta.X, args->MouseDelta.Y); + } +} + // Applies necessary geometric transformations to raw cursor positions: Point SDL_WinRTApp::TransformCursor(Point rawPosition) { @@ -182,7 +250,7 @@ Point SDL_WinRTApp::TransformCursor(Point rawPosition) void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { - if (m_sdlWindowData) + if (m_sdlWindowData && ! m_useRelativeMouseMode) { Point transformedPoint = TransformCursor(args->CurrentPoint->Position); SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, (int)transformedPoint.X, (int)transformedPoint.Y); @@ -456,6 +524,11 @@ 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; diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index f00417327..36575d385 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -25,6 +25,7 @@ internal: void PumpEvents(); const SDL_WindowData * GetSDLWindowData() const; bool HasSDLWindowData() const; + void SetRelativeMouseMode(bool enable); void SetSDLWindowData(const SDL_WindowData * windowData); void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects); void ResizeMainTexture(int w, int h); @@ -42,6 +43,7 @@ protected: 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 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); @@ -50,6 +52,7 @@ private: bool m_windowClosed; bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; + bool m_useRelativeMouseMode; }; ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/windowsrt/SDL_winrtmouse.cpp index f4bbea6e8..2b44400e7 100644 --- a/src/video/windowsrt/SDL_winrtmouse.cpp +++ b/src/video/windowsrt/SDL_winrtmouse.cpp @@ -108,12 +108,12 @@ WINRT_ShowCursor(SDL_Cursor * cursor) return 0; } -//static int -//WINRT_SetRelativeMouseMode(SDL_bool enabled) -//{ -// //return -1; -// return 0; -//} +static int +WINRT_SetRelativeMouseMode(SDL_bool enabled) +{ + SDL_WinRTGlobalApp->SetRelativeMouseMode(enabled ? true : false); + return 0; +} void WINRT_InitMouse(_THIS) @@ -131,7 +131,7 @@ WINRT_InitMouse(_THIS) mouse->ShowCursor = WINRT_ShowCursor; mouse->FreeCursor = WINRT_FreeCursor; //mouse->WarpMouse = WINRT_WarpMouse; - //mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; // DLudwig: 'relative mouse mode' support is pending + mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); } From 0d14e78972b36cfdf30dddf2c411b86ae44c3391 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 28 Dec 2012 16:10:44 -0500 Subject: [PATCH 067/264] WinRT: scaled relative mouse mode values from the native screen size to SDL's window size --- src/video/windowsrt/SDL_WinRTApp.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index a3cd3a663..0026f229a 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -173,6 +173,14 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) } } +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) { @@ -229,9 +237,16 @@ void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) // 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 - // without transformation. + // to SDL with minimal transformation: from native screen coordinates (in DIPs) + // to SDL window coordinates. // - SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 1, args->MouseDelta.X, args->MouseDelta.Y); + const Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Point mouseDeltaInSDLWindowCoords = TransformCursor(mouseDeltaInDIPs); + SDL_SendMouseMotion( + m_sdlWindowData->sdlWindow, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); } } From 0b7cfac19e2d9d2d3b253d1da9dd8c63ddec32fe Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 30 Dec 2012 12:57:33 -0500 Subject: [PATCH 068/264] WinRT: fixed XAudio2 crash bug + enabled XAudio2 backend --- include/SDL_config_windowsrt.h | 2 +- src/audio/xaudio2/SDL_xaudio2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 8330c10be..e0a16b22d 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -135,7 +135,7 @@ typedef unsigned int uintptr_t; #define HAVE_SQRT 1 /* Enable various audio drivers */ -//#define SDL_AUDIO_DRIVER_XAUDIO2 1 /* Disabled pending work to fix quality + stability issues */ +#define SDL_AUDIO_DRIVER_XAUDIO2 1 #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index bbb27d0dd..f51614edd 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -192,7 +192,7 @@ public: VoiceCBOnBufferEnd(pBufferContext); } STDMETHOD_(void, OnBufferStart)(void *pBufferContext) { - VoiceCBOnBufferEnd(pBufferContext); + VoiceCBOnBufferStart(pBufferContext); } STDMETHOD_(void, OnLoopEnd)(void *pBufferContext) { VoiceCBOnLoopEnd(pBufferContext); From cc456a7516d3a8600c22a3a9335b6631f0203ab7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 30 Dec 2012 13:03:45 -0500 Subject: [PATCH 069/264] WinRT: added a note to try removing some WinRT-specific code from SDL_xaudio2.c --- src/audio/xaudio2/SDL_xaudio2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index f51614edd..924699445 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -485,6 +485,10 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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); From 1ce8f1c8243223fd3796c31e0770b5bed0c1e489 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 31 Dec 2012 10:30:38 -0500 Subject: [PATCH 070/264] WinRT: added support for the SDL_loadso APIs, via LoadPackagedLibrary --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 2 ++ include/SDL_config_windowsrt.h | 4 +--- src/core/windows/SDL_windows.c | 15 +++++++++++++-- src/loadso/windows/SDL_sysloadso.c | 8 ++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index a9fd5460c..a78608bdb 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -53,6 +53,7 @@ true true + @@ -68,6 +69,7 @@ + diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index e0a16b22d..3223ca261 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -146,9 +146,7 @@ typedef unsigned int uintptr_t; #define SDL_JOYSTICK_DISABLED 1 /* Enable various shared object loading systems */ -// TODO, WinRT: adapt the Win32 shared object loading code for WinRT -#define SDL_LOADSO_DISABLED 1 -//#define SDL_LOADSO_WINDOWS 1 +#define SDL_LOADSO_WINDOWS 1 /* Enable various threading systems */ #define SDL_THREAD_STDCPP 1 diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index 4103d98d8..cd8a0d088 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -20,12 +20,12 @@ */ #include "SDL_config.h" -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINRT__) #include "SDL_error.h" #include "SDL_windows.h" -#include /* for CoInitialize/CoUninitialize */ +#include /* for CoInitialize/CoUninitialize (Win32 only) */ /* Sets an error message based on GetLastError() */ @@ -44,6 +44,14 @@ WIN_SetError(const char *prefix) 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. */ @@ -53,12 +61,15 @@ WIN_CoInitialize(void) } return hr; +#endif } void WIN_CoUninitialize(void) { +#ifndef __WINRT__ CoUninitialize(); +#endif } #endif /* __WIN32__ */ diff --git a/src/loadso/windows/SDL_sysloadso.c b/src/loadso/windows/SDL_sysloadso.c index f07752cb8..e0a459499 100644 --- a/src/loadso/windows/SDL_sysloadso.c +++ b/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 */ From 219f50d87e880879368d5a97062c297862820435 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 8 Jan 2013 22:50:29 -0500 Subject: [PATCH 071/264] WinRT: send window 'minimized' and 'restored' events for app-suspend and app-resume. Use SDL_AddEventWatch() to receive these. --- src/video/windowsrt/SDL_WinRTApp.cpp | 55 ++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 0026f229a..15d24c987 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -7,6 +7,7 @@ extern "C" { #include "../SDL_sysvideo.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_windowevents_c.h" #include "SDL_events.h" #include "SDL_log.h" } @@ -494,6 +495,26 @@ void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedE 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 @@ -501,20 +522,46 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a // 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]() { - // Insert your code here. - + // 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() From ebb98e824c3ccce3373c8ffb90e2ac1242d607f3 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 8 Jan 2013 23:11:22 -0500 Subject: [PATCH 072/264] WinRT: converted tabs to spaces in src/video/windowsrt/* --- src/video/windowsrt/DirectXHelper.h | 52 +- src/video/windowsrt/SDL_WinRTApp.cpp | 110 +-- src/video/windowsrt/SDL_WinRTApp.h | 46 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 846 ++++++++++---------- src/video/windowsrt/SDL_winrtrenderer.h | 64 +- src/video/windowsrt/SimplePixelShader.hlsl | 8 +- src/video/windowsrt/SimpleVertexShader.hlsl | 16 +- 7 files changed, 571 insertions(+), 571 deletions(-) diff --git a/src/video/windowsrt/DirectXHelper.h b/src/video/windowsrt/DirectXHelper.h index 3d3e59b88..4a74492af 100644 --- a/src/video/windowsrt/DirectXHelper.h +++ b/src/video/windowsrt/DirectXHelper.h @@ -6,31 +6,31 @@ namespace DX { - inline void ThrowIfFailed(HRESULT hr) - { - if (FAILED(hr)) - { - // Set a breakpoint on this line to catch Win32 API errors. - throw Platform::Exception::CreateException(hr); - } - } + inline void ThrowIfFailed(HRESULT hr) + { + if (FAILED(hr)) + { + // Set a breakpoint on this line to catch Win32 API errors. + throw Platform::Exception::CreateException(hr); + } + } - // Function that reads from a binary file asynchronously. - inline Concurrency::task^> ReadDataAsync(Platform::String^ filename) - { - using namespace Windows::Storage; - using namespace Concurrency; - - auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation; - - return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file) - { - return FileIO::ReadBufferAsync(file); - }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array^ - { - auto fileData = ref new Platform::Array(fileBuffer->Length); - Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(fileData); - return fileData; - }); - } + // Function that reads from a binary file asynchronously. + inline Concurrency::task^> ReadDataAsync(Platform::String^ filename) + { + using namespace Windows::Storage; + using namespace Concurrency; + + auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation; + + return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file) + { + return FileIO::ReadBufferAsync(file); + }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array^ + { + auto fileData = ref new Platform::Array(fileBuffer->Length); + Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(fileData); + return fileData; + }); + } } diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 15d24c987..0a9251bad 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -42,8 +42,8 @@ using namespace Windows::Graphics::Display; using namespace concurrency; SDL_WinRTApp::SDL_WinRTApp() : - m_windowClosed(false), - m_windowVisible(true), + m_windowClosed(false), + m_windowVisible(true), m_sdlWindowData(NULL), m_useRelativeMouseMode(false) { @@ -51,52 +51,52 @@ SDL_WinRTApp::SDL_WinRTApp() : void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) { - applicationView->Activated += + applicationView->Activated += ref new TypedEventHandler(this, &SDL_WinRTApp::OnActivated); - CoreApplication::Suspending += + CoreApplication::Suspending += ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); - CoreApplication::Resuming += + CoreApplication::Resuming += ref new EventHandler(this, &SDL_WinRTApp::OnResuming); - m_renderer = ref new SDL_winrtrenderer(); + m_renderer = ref new SDL_winrtrenderer(); } void SDL_WinRTApp::SetWindow(CoreWindow^ window) { - window->SizeChanged += + window->SizeChanged += ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowSizeChanged); - window->VisibilityChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); + window->VisibilityChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); - window->Closed += + window->Closed += ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowClosed); - window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); + window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); - window->PointerPressed += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + window->PointerPressed += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); window->PointerReleased += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); - window->PointerMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + window->PointerMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); // Retrieves relative-only mouse movements: Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); window->KeyDown += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); - window->KeyUp += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); + window->KeyUp += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); - m_renderer->Initialize(CoreWindow::GetForCurrentThread()); + m_renderer->Initialize(CoreWindow::GetForCurrentThread()); } void SDL_WinRTApp::Load(Platform::String^ entryPoint) @@ -117,26 +117,26 @@ void SDL_WinRTApp::Run() void SDL_WinRTApp::PumpEvents() { - if (!m_windowClosed) - { - if (m_windowVisible) - { - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); - } - else - { - CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); - } - } + if (!m_windowClosed) + { + if (m_windowVisible) + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + } + else + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + } + } } void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects) { if (!m_windowClosed && m_windowVisible) - { - m_renderer->Render(surface, rects, numrects); - m_renderer->Present(); // This call is synchronized to the display frame rate. - } + { + m_renderer->Render(surface, rects, numrects); + m_renderer->Present(); // This call is synchronized to the display frame rate. + } } void SDL_WinRTApp::Uninitialize() @@ -145,24 +145,24 @@ void SDL_WinRTApp::Uninitialize() void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { - m_renderer->UpdateForWindowSizeChange(); + m_renderer->UpdateForWindowSizeChange(); } void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { - m_windowVisible = args->Visible; + m_windowVisible = args->Visible; } void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) { - m_windowClosed = true; + m_windowClosed = true; } void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { if (m_sdlWindowData) { - SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT); + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT); } } @@ -170,7 +170,7 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { if (m_sdlWindowData) { - SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT); + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT); } } @@ -492,7 +492,7 @@ void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::C void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { - CoreWindow::GetForCurrentThread()->Activate(); + CoreWindow::GetForCurrentThread()->Activate(); } static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * event) @@ -517,13 +517,13 @@ static int SDLCALL RemoveAppSuspendAndResumeEvents(void * userdata, SDL_Event * 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]() - { + // 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 @@ -541,15 +541,15 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a 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(); - }); + 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. + // 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) @@ -619,6 +619,6 @@ __declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFu { SDL_WinRT_main = mainFunction; auto direct3DApplicationSource = ref new Direct3DApplicationSource(); - CoreApplication::Run(direct3DApplicationSource); - return 0; + CoreApplication::Run(direct3DApplicationSource); + return 0; } diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 36575d385..06e022536 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -10,14 +10,14 @@ using namespace Windows::UI::Core; 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(); + 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 @@ -32,25 +32,25 @@ internal: Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); protected: - // Event Handlers. - 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 OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); + // Event Handlers. + 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 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: - SDL_winrtrenderer^ m_renderer; - bool m_windowClosed; - bool m_windowVisible; + SDL_winrtrenderer^ m_renderer; + bool m_windowClosed; + bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; bool m_useRelativeMouseMode; }; @@ -58,5 +58,5 @@ private: ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource { public: - virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); }; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 8d2124c60..43564fe61 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -11,7 +11,7 @@ using namespace Windows::Graphics::Display; SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), m_loadingComplete(false), - m_vertexCount(0) + m_vertexCount(0) { } @@ -26,357 +26,357 @@ SDL_winrtrenderer::~SDL_winrtrenderer() // Initialize the Direct3D resources required to run. void SDL_winrtrenderer::Initialize(CoreWindow^ window) { - m_window = window; - - CreateDeviceResources(); - CreateWindowSizeDependentResources(); + m_window = window; + + CreateDeviceResources(); + CreateWindowSizeDependentResources(); } // Recreate all device resources and set them back to the current state. void SDL_winrtrenderer::HandleDeviceLost() { - // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. - m_windowBounds.Width = 0; - m_windowBounds.Height = 0; - m_swapChain = nullptr; + // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. + m_windowBounds.Width = 0; + m_windowBounds.Height = 0; + m_swapChain = nullptr; - CreateDeviceResources(); - UpdateForWindowSizeChange(); + CreateDeviceResources(); + UpdateForWindowSizeChange(); } // These are the resources that depend on the device. void SDL_winrtrenderer::CreateDeviceResources() { - // 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; + // 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; + // 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 - }; + // 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 device; - ComPtr context; - DX::ThrowIfFailed( - 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. - &m_featureLevel, // Returns feature level of device created. - &context // Returns the device immediate context. - ) - ); + // Create the Direct3D 11 API device object and a corresponding context. + ComPtr device; + ComPtr context; + DX::ThrowIfFailed( + 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. + &m_featureLevel, // Returns feature level of device created. + &context // Returns the device immediate context. + ) + ); - // Get the Direct3D 11.1 API device and context interfaces. - DX::ThrowIfFailed( - device.As(&m_d3dDevice) - ); + // Get the Direct3D 11.1 API device and context interfaces. + DX::ThrowIfFailed( + device.As(&m_d3dDevice) + ); - DX::ThrowIfFailed( - context.As(&m_d3dContext) - ); + DX::ThrowIfFailed( + context.As(&m_d3dContext) + ); auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); - auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); + auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); - auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { - DX::ThrowIfFailed( - m_d3dDevice->CreateVertexShader( - fileData->Data, - fileData->Length, - nullptr, - &m_vertexShader - ) - ); + auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { + DX::ThrowIfFailed( + m_d3dDevice->CreateVertexShader( + fileData->Data, + fileData->Length, + nullptr, + &m_vertexShader + ) + ); - 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 }, - }; + 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 }, + }; - DX::ThrowIfFailed( - m_d3dDevice->CreateInputLayout( - vertexDesc, - ARRAYSIZE(vertexDesc), - fileData->Data, - fileData->Length, - &m_inputLayout - ) - ); - }); + DX::ThrowIfFailed( + m_d3dDevice->CreateInputLayout( + vertexDesc, + ARRAYSIZE(vertexDesc), + fileData->Data, + fileData->Length, + &m_inputLayout + ) + ); + }); - auto createPSTask = loadPSTask.then([this](Platform::Array^ fileData) { - DX::ThrowIfFailed( - m_d3dDevice->CreatePixelShader( - fileData->Data, - fileData->Length, - nullptr, - &m_pixelShader - ) - ); - }); + auto createPSTask = loadPSTask.then([this](Platform::Array^ fileData) { + DX::ThrowIfFailed( + m_d3dDevice->CreatePixelShader( + fileData->Data, + fileData->Length, + nullptr, + &m_pixelShader + ) + ); + }); - auto createVertexBuffer = (createPSTask && createVSTask).then([this] () { - VertexPositionColor vertices[] = - { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - }; + auto createVertexBuffer = (createPSTask && createVSTask).then([this] () { + VertexPositionColor vertices[] = + { + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + }; - m_vertexCount = ARRAYSIZE(vertices); + m_vertexCount = ARRAYSIZE(vertices); - D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = vertices; - vertexBufferData.SysMemPitch = 0; - vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); - DX::ThrowIfFailed( - m_d3dDevice->CreateBuffer( - &vertexBufferDesc, - &vertexBufferData, - &m_vertexBuffer - ) - ); - }); + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; + vertexBufferData.pSysMem = vertices; + vertexBufferData.SysMemPitch = 0; + vertexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); + DX::ThrowIfFailed( + m_d3dDevice->CreateBuffer( + &vertexBufferDesc, + &vertexBufferData, + &m_vertexBuffer + ) + ); + }); auto createMainSamplerTask = createVertexBuffer.then([this] () { - 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; - DX::ThrowIfFailed( - m_d3dDevice->CreateSamplerState( - &samplerDesc, - &m_mainSampler - ) - ); - }); + 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; + DX::ThrowIfFailed( + m_d3dDevice->CreateSamplerState( + &samplerDesc, + &m_mainSampler + ) + ); + }); - createMainSamplerTask.then([this] () { - m_loadingComplete = true; - }); + createMainSamplerTask.then([this] () { + m_loadingComplete = true; + }); } // Allocate all memory resources that change on a window SizeChanged event. void SDL_winrtrenderer::CreateWindowSizeDependentResources() { - // Store the window bounds so the next time we get a SizeChanged event we can - // avoid rebuilding everything if the size is identical. - m_windowBounds = m_window->Bounds; + // Store the window bounds so the next time we get a SizeChanged event we can + // avoid rebuilding everything if the size is identical. + m_windowBounds = m_window->Bounds; - // Calculate the necessary swap chain and render target size in pixels. - float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); - float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); + // Calculate the necessary swap chain and render target size in pixels. + float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); + float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); - // 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. - m_orientation = DisplayProperties::CurrentOrientation; - bool swapDimensions = - m_orientation == DisplayOrientations::Portrait || - m_orientation == DisplayOrientations::PortraitFlipped; - m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; - m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; + // 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. + m_orientation = DisplayProperties::CurrentOrientation; + bool swapDimensions = + m_orientation == DisplayOrientations::Portrait || + m_orientation == DisplayOrientations::PortraitFlipped; + m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; + m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; - if(m_swapChain != nullptr) - { - // If the swap chain already exists, resize it. - DX::ThrowIfFailed( - m_swapChain->ResizeBuffers( - 2, // Double-buffered swap chain. - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - DXGI_FORMAT_B8G8R8A8_UNORM, - 0 - ) - ); - } - 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(m_renderTargetSize.Width); // Match the size of the window. - swapChainDesc.Height = static_cast(m_renderTargetSize.Height); - 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. - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. - swapChainDesc.Flags = 0; + if(m_swapChain != nullptr) + { + // If the swap chain already exists, resize it. + DX::ThrowIfFailed( + m_swapChain->ResizeBuffers( + 2, // Double-buffered swap chain. + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + DXGI_FORMAT_B8G8R8A8_UNORM, + 0 + ) + ); + } + 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(m_renderTargetSize.Width); // Match the size of the window. + swapChainDesc.Height = static_cast(m_renderTargetSize.Height); + 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. + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. + swapChainDesc.Flags = 0; - ComPtr dxgiDevice; - DX::ThrowIfFailed( - m_d3dDevice.As(&dxgiDevice) - ); + ComPtr dxgiDevice; + DX::ThrowIfFailed( + m_d3dDevice.As(&dxgiDevice) + ); - ComPtr dxgiAdapter; - DX::ThrowIfFailed( - dxgiDevice->GetAdapter(&dxgiAdapter) - ); + ComPtr dxgiAdapter; + DX::ThrowIfFailed( + dxgiDevice->GetAdapter(&dxgiAdapter) + ); - ComPtr dxgiFactory; - DX::ThrowIfFailed( - dxgiAdapter->GetParent( - __uuidof(IDXGIFactory2), - &dxgiFactory - ) - ); + ComPtr dxgiFactory; + DX::ThrowIfFailed( + dxgiAdapter->GetParent( + __uuidof(IDXGIFactory2), + &dxgiFactory + ) + ); - Windows::UI::Core::CoreWindow^ window = m_window.Get(); - DX::ThrowIfFailed( - dxgiFactory->CreateSwapChainForCoreWindow( - m_d3dDevice.Get(), - reinterpret_cast(window), - &swapChainDesc, - nullptr, // Allow on all displays. - &m_swapChain - ) - ); - - // 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. - DX::ThrowIfFailed( - dxgiDevice->SetMaximumFrameLatency(1) - ); - } - - // 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 (m_orientation) - { - case DisplayOrientations::Landscape: - rotation = DXGI_MODE_ROTATION_IDENTITY; - m_orientationTransform3D = 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; + Windows::UI::Core::CoreWindow^ window = m_window.Get(); + DX::ThrowIfFailed( + dxgiFactory->CreateSwapChainForCoreWindow( + m_d3dDevice.Get(), + reinterpret_cast(window), + &swapChainDesc, + nullptr, // Allow on all displays. + &m_swapChain + ) + ); + + // 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. + DX::ThrowIfFailed( + dxgiDevice->SetMaximumFrameLatency(1) + ); + } + + // 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 (m_orientation) + { + case DisplayOrientations::Landscape: + rotation = DXGI_MODE_ROTATION_IDENTITY; + m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE270; - m_orientationTransform3D = 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::Portrait: + rotation = DXGI_MODE_ROTATION_ROTATE270; + m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE180; - m_orientationTransform3D = 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::LandscapeFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE180; + m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE90; - m_orientationTransform3D = 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; + case DisplayOrientations::PortraitFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE90; + m_orientationTransform3D = 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: - throw ref new Platform::FailureException(); - } + default: + throw ref new Platform::FailureException(); + } - DX::ThrowIfFailed( - m_swapChain->SetRotation(rotation) - ); + DX::ThrowIfFailed( + m_swapChain->SetRotation(rotation) + ); - // Create a render target view of the swap chain back buffer. - ComPtr backBuffer; - DX::ThrowIfFailed( - m_swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ) - ); + // Create a render target view of the swap chain back buffer. + ComPtr backBuffer; + DX::ThrowIfFailed( + m_swapChain->GetBuffer( + 0, + __uuidof(ID3D11Texture2D), + &backBuffer + ) + ); - DX::ThrowIfFailed( - m_d3dDevice->CreateRenderTargetView( - backBuffer.Get(), - nullptr, - &m_renderTargetView - ) - ); + DX::ThrowIfFailed( + m_d3dDevice->CreateRenderTargetView( + backBuffer.Get(), + nullptr, + &m_renderTargetView + ) + ); - // Create a depth stencil view. - CD3D11_TEXTURE2D_DESC depthStencilDesc( - DXGI_FORMAT_D24_UNORM_S8_UINT, - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - 1, - 1, - D3D11_BIND_DEPTH_STENCIL - ); + // Create a depth stencil view. + CD3D11_TEXTURE2D_DESC depthStencilDesc( + DXGI_FORMAT_D24_UNORM_S8_UINT, + static_cast(m_renderTargetSize.Width), + static_cast(m_renderTargetSize.Height), + 1, + 1, + D3D11_BIND_DEPTH_STENCIL + ); - ComPtr depthStencil; - DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( - &depthStencilDesc, - nullptr, - &depthStencil - ) - ); + ComPtr depthStencil; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &depthStencilDesc, + nullptr, + &depthStencil + ) + ); - // Set the rendering viewport to target the entire window. - CD3D11_VIEWPORT viewport( - 0.0f, - 0.0f, - m_renderTargetSize.Width, - m_renderTargetSize.Height - ); + // Set the rendering viewport to target the entire window. + CD3D11_VIEWPORT viewport( + 0.0f, + 0.0f, + m_renderTargetSize.Width, + m_renderTargetSize.Height + ); - m_d3dContext->RSSetViewports(1, &viewport); + m_d3dContext->RSSetViewports(1, &viewport); } void SDL_winrtrenderer::ResizeMainTexture(int w, int h) @@ -384,17 +384,17 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) const int pixelSizeInBytes = 4; D3D11_TEXTURE2D_DESC textureDesc = {0}; - textureDesc.Width = w; - textureDesc.Height = h; - textureDesc.MipLevels = 1; - textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Usage = D3D11_USAGE_DYNAMIC; - textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - textureDesc.MiscFlags = 0; + textureDesc.Width = w; + textureDesc.Height = h; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DYNAMIC; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + textureDesc.MiscFlags = 0; const int numPixels = textureDesc.Width * textureDesc.Height; std::vector initialTexturePixels(numPixels * pixelSizeInBytes, 0x00); @@ -407,17 +407,17 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) // initialTexturePixels[i+3] = 0xff; //} - D3D11_SUBRESOURCE_DATA initialTextureData = {0}; - initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); - initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes; - initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes; - DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( - &textureDesc, - &initialTextureData, - &m_mainTexture - ) - ); + D3D11_SUBRESOURCE_DATA initialTextureData = {0}; + initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]); + initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes; + initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes; + DX::ThrowIfFailed( + m_d3dDevice->CreateTexture2D( + &textureDesc, + &initialTextureData, + &m_mainTexture + ) + ); if (m_mainTextureHelperSurface) { SDL_FreeSurface(m_mainTextureHelperSurface); @@ -433,152 +433,152 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) DX::ThrowIfFailed(E_FAIL); // TODO, WinRT: generate a better error here, taking into account who's calling this function. } - 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; - DX::ThrowIfFailed( - m_d3dDevice->CreateShaderResourceView( - m_mainTexture.Get(), - &resourceViewDesc, - &m_mainTextureResourceView) - ); + 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; + DX::ThrowIfFailed( + m_d3dDevice->CreateShaderResourceView( + m_mainTexture.Get(), + &resourceViewDesc, + &m_mainTextureResourceView) + ); } // This method is called in the event handler for the SizeChanged event. void SDL_winrtrenderer::UpdateForWindowSizeChange() { - if (m_window->Bounds.Width != m_windowBounds.Width || - m_window->Bounds.Height != m_windowBounds.Height || - m_orientation != DisplayProperties::CurrentOrientation) - { - ID3D11RenderTargetView* nullViews[] = {nullptr}; - m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - m_renderTargetView = nullptr; - m_d3dContext->Flush(); - CreateWindowSizeDependentResources(); - } + if (m_window->Bounds.Width != m_windowBounds.Width || + m_window->Bounds.Height != m_windowBounds.Height || + m_orientation != DisplayProperties::CurrentOrientation) + { + ID3D11RenderTargetView* nullViews[] = {nullptr}; + m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + m_renderTargetView = nullptr; + m_d3dContext->Flush(); + CreateWindowSizeDependentResources(); + } } void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { - const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_d3dContext->ClearRenderTargetView( - m_renderTargetView.Get(), - blackColor - ); + const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + m_d3dContext->ClearRenderTargetView( + m_renderTargetView.Get(), + blackColor + ); - // Only draw the screen once it is loaded (some loading is asynchronous). - if (!m_loadingComplete) - { - return; - } + // Only draw the screen once it is loaded (some loading is asynchronous). + if (!m_loadingComplete) + { + return; + } if (!m_mainTextureResourceView) { return; } - // Update the main texture (for SDL usage). Start by mapping the SDL + // Update the main texture (for SDL usage). Start by mapping the SDL // window's main texture to CPU-accessible memory: - D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; - DX::ThrowIfFailed( - m_d3dContext->Map( - m_mainTexture.Get(), - 0, - D3D11_MAP_WRITE_DISCARD, - 0, - &textureMemory) - ); + D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; + DX::ThrowIfFailed( + m_d3dContext->Map( + m_mainTexture.Get(), + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + &textureMemory) + ); // Copy pixel data to the locked texture's memory: m_mainTextureHelperSurface->pixels = textureMemory.pData; m_mainTextureHelperSurface->pitch = textureMemory.RowPitch; SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL); - // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything + // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything // Clean up a bit, then commit the texture's memory back to Direct3D: m_mainTextureHelperSurface->pixels = NULL; m_mainTextureHelperSurface->pitch = 0; - m_d3dContext->Unmap( - m_mainTexture.Get(), - 0); + m_d3dContext->Unmap( + m_mainTexture.Get(), + 0); - m_d3dContext->OMSetRenderTargets( - 1, - m_renderTargetView.GetAddressOf(), - nullptr - ); + m_d3dContext->OMSetRenderTargets( + 1, + m_renderTargetView.GetAddressOf(), + nullptr + ); - UINT stride = sizeof(VertexPositionColor); - UINT offset = 0; - m_d3dContext->IASetVertexBuffers( - 0, - 1, - m_vertexBuffer.GetAddressOf(), - &stride, - &offset - ); + UINT stride = sizeof(VertexPositionColor); + UINT offset = 0; + m_d3dContext->IASetVertexBuffers( + 0, + 1, + m_vertexBuffer.GetAddressOf(), + &stride, + &offset + ); - m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_d3dContext->IASetInputLayout(m_inputLayout.Get()); + m_d3dContext->IASetInputLayout(m_inputLayout.Get()); - m_d3dContext->VSSetShader( - m_vertexShader.Get(), - nullptr, - 0 - ); + m_d3dContext->VSSetShader( + m_vertexShader.Get(), + nullptr, + 0 + ); - m_d3dContext->PSSetShader( - m_pixelShader.Get(), - nullptr, - 0 - ); + m_d3dContext->PSSetShader( + m_pixelShader.Get(), + nullptr, + 0 + ); - m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf()); + m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf()); - m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf()); + m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf()); - m_d3dContext->Draw(4, 0); + m_d3dContext->Draw(4, 0); } // Method to deliver the final image to the display. void SDL_winrtrenderer::Present() { - // The application may optionally specify "dirty" or "scroll" - // rects to improve efficiency in certain scenarios. - 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 = m_swapChain->Present1(1, 0, ¶meters); + // The application may optionally specify "dirty" or "scroll" + // rects to improve efficiency in certain scenarios. + 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 = m_swapChain->Present1(1, 0, ¶meters); - // 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. - m_d3dContext->DiscardView(m_renderTargetView.Get()); + // 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. + m_d3dContext->DiscardView(m_renderTargetView.Get()); - // If the device was removed either by a disconnect or a driver upgrade, we - // must recreate all device resources. - if (hr == DXGI_ERROR_DEVICE_REMOVED) - { - HandleDeviceLost(); - } - else - { - DX::ThrowIfFailed(hr); - } + // If the device was removed either by a disconnect or a driver upgrade, we + // must recreate all device resources. + if (hr == DXGI_ERROR_DEVICE_REMOVED) + { + HandleDeviceLost(); + } + else + { + DX::ThrowIfFailed(hr); + } } // Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. float SDL_winrtrenderer::ConvertDipsToPixels(float dips) { - static const float dipsPerInch = 96.0f; - return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. + static const float dipsPerInch = 96.0f; + return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. } diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 6b3f9b0f8..62b194f3d 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -5,57 +5,57 @@ struct VertexPositionColor { - DirectX::XMFLOAT3 pos; - DirectX::XMFLOAT2 tex; + DirectX::XMFLOAT3 pos; + DirectX::XMFLOAT2 tex; }; // Helper class that initializes DirectX APIs for 3D rendering. ref class SDL_winrtrenderer { internal: - SDL_winrtrenderer(); + SDL_winrtrenderer(); public: virtual ~SDL_winrtrenderer(); - virtual void Initialize(Windows::UI::Core::CoreWindow^ window); - virtual void HandleDeviceLost(); - virtual void CreateDeviceResources(); - virtual void CreateWindowSizeDependentResources(); - virtual void UpdateForWindowSizeChange(); - virtual void Present(); - virtual float ConvertDipsToPixels(float dips); + virtual void Initialize(Windows::UI::Core::CoreWindow^ window); + virtual void HandleDeviceLost(); + virtual void CreateDeviceResources(); + virtual void CreateWindowSizeDependentResources(); + virtual void UpdateForWindowSizeChange(); + virtual void Present(); + virtual float ConvertDipsToPixels(float dips); internal: - virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); + virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); void ResizeMainTexture(int w, int h); protected private: - // Direct3D Objects. - Microsoft::WRL::ComPtr m_d3dDevice; - Microsoft::WRL::ComPtr m_d3dContext; - Microsoft::WRL::ComPtr m_swapChain; - Microsoft::WRL::ComPtr m_renderTargetView; - Microsoft::WRL::ComPtr m_inputLayout; - Microsoft::WRL::ComPtr m_vertexBuffer; - Microsoft::WRL::ComPtr m_vertexShader; - Microsoft::WRL::ComPtr m_pixelShader; - Microsoft::WRL::ComPtr m_mainTexture; - Microsoft::WRL::ComPtr m_mainTextureResourceView; - Microsoft::WRL::ComPtr m_mainSampler; + // Direct3D Objects. + Microsoft::WRL::ComPtr m_d3dDevice; + Microsoft::WRL::ComPtr m_d3dContext; + Microsoft::WRL::ComPtr m_swapChain; + Microsoft::WRL::ComPtr m_renderTargetView; + Microsoft::WRL::ComPtr m_inputLayout; + Microsoft::WRL::ComPtr m_vertexBuffer; + Microsoft::WRL::ComPtr m_vertexShader; + Microsoft::WRL::ComPtr m_pixelShader; + Microsoft::WRL::ComPtr m_mainTexture; + Microsoft::WRL::ComPtr m_mainTextureResourceView; + Microsoft::WRL::ComPtr m_mainSampler; // UpdateWindowSurface helper objects SDL_Surface * m_mainTextureHelperSurface; - // Cached renderer properties. - D3D_FEATURE_LEVEL m_featureLevel; - Windows::Foundation::Size m_renderTargetSize; - Windows::Foundation::Rect m_windowBounds; - Platform::Agile m_window; - Windows::Graphics::Display::DisplayOrientations m_orientation; - uint32 m_vertexCount; + // Cached renderer properties. + D3D_FEATURE_LEVEL m_featureLevel; + Windows::Foundation::Size m_renderTargetSize; + Windows::Foundation::Rect m_windowBounds; + Platform::Agile m_window; + Windows::Graphics::Display::DisplayOrientations m_orientation; + uint32 m_vertexCount; - // Transform used for display orientation. - DirectX::XMFLOAT4X4 m_orientationTransform3D; + // Transform used for display orientation. + DirectX::XMFLOAT4X4 m_orientationTransform3D; // Has the renderer finished loading? bool m_loadingComplete; diff --git a/src/video/windowsrt/SimplePixelShader.hlsl b/src/video/windowsrt/SimplePixelShader.hlsl index d2f6c58bb..d0a804439 100644 --- a/src/video/windowsrt/SimplePixelShader.hlsl +++ b/src/video/windowsrt/SimplePixelShader.hlsl @@ -3,13 +3,13 @@ SamplerState theSampler : register(s0); struct PixelShaderInput { - float4 pos : SV_POSITION; + float4 pos : SV_POSITION; - float2 tex : TEXCOORD0; + float2 tex : TEXCOORD0; }; float4 main(PixelShaderInput input) : SV_TARGET { - //return float4(input.color,1.0f); - return theTexture.Sample(theSampler, input.tex); + //return float4(input.color,1.0f); + return theTexture.Sample(theSampler, input.tex); } diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index bde60b3a7..adaf896e9 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -3,20 +3,20 @@ struct VertexShaderInput { - float3 pos : POSITION; - float2 tex : TEXCOORD0; + float3 pos : POSITION; + float2 tex : TEXCOORD0; }; struct VertexShaderOutput { - float4 pos : SV_POSITION; - float2 tex : TEXCOORD0; + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; }; VertexShaderOutput main(VertexShaderInput input) { - VertexShaderOutput output; - output.pos = float4(input.pos, 1.0f); - output.tex = input.tex; - return output; + VertexShaderOutput output; + output.pos = float4(input.pos, 1.0f); + output.tex = input.tex; + return output; } From 12cc058140d76554355c3d747d4c51b19c300440 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 8 Jan 2013 23:30:21 -0500 Subject: [PATCH 073/264] WinRT: emit SDL_WINDOWEVENT_SHOWN and SDL_WINDOWEVENT_HIDDEN --- src/video/windowsrt/SDL_WinRTApp.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 0a9251bad..7b9214b28 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -151,6 +151,13 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { m_windowVisible = args->Visible; + if (m_sdlWindowData) { + if (args->Visible) { + SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); + } else { + SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); + } + } } void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) From 10e7b5696f0a5245b0bb504916617df263cc0137 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 22 Jan 2013 20:40:15 -0500 Subject: [PATCH 074/264] WinRT: added a keyboard mapping for the Backspace key --- src/video/windowsrt/SDL_WinRTApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 7b9214b28..0e4326ad6 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -289,7 +289,7 @@ static SDL_Scancode WinRT_Keycodes[] = { SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton1 -- 5 SDL_SCANCODE_UNKNOWN, // VirtualKey.XButton2 -- 6 SDL_SCANCODE_UNKNOWN, // -- 7 - SDL_SCANCODE_UNKNOWN, // VirtualKey.Back -- 8 (maybe SDL_SCANCODE_AC_BACK ?) + SDL_SCANCODE_BACKSPACE, // VirtualKey.Back -- 8 SDL_SCANCODE_TAB, // VirtualKey.Tab -- 9 SDL_SCANCODE_UNKNOWN, // -- 10 SDL_SCANCODE_UNKNOWN, // -- 11 From 1fcdc8675723a70b646de8beb83b0fa716964efc Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 22 Jan 2013 21:05:48 -0500 Subject: [PATCH 075/264] WinRT: created sections/filters to organize the MSVC project a bit more --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters | 611 +++++++++++++++++++ 1 file changed, 611 insertions(+) create mode 100644 VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters new file mode 100644 index 000000000..379fe48a5 --- /dev/null +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters @@ -0,0 +1,611 @@ + + + + + GPU Shaders + + + GPU Shaders + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Header Files + + + Source Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + {20773b57-7034-4c24-af5a-334844585f1b} + + + {ddf04d85-6a87-4c5a-bc52-869b38f45a61} + + + {83ed1283-8234-4c77-99a8-ffcfd8ce7381} + + + \ No newline at end of file From 61cc1f3aa4993eab7a8094fb5a69524c39db6132 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 22 Jan 2013 21:45:59 -0500 Subject: [PATCH 076/264] WinRT: added platform-specific APIs to access common, writable folder paths --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 8 +++++ include/SDL_system.h | 39 +++++++++++++++++++++++ src/core/windowsrt/SDL_winrtpaths.cpp | 45 +++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 src/core/windowsrt/SDL_winrtpaths.cpp diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index a78608bdb..4fd72398a 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -53,6 +53,14 @@ true true + + true + true + true + true + true + true + diff --git a/include/SDL_system.h b/include/SDL_system.h index 47e557575..0c5348f4b 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -93,6 +93,45 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); #endif /* __ANDROID__ */ +/* Platform specific functions for Windows RT */ +#if defined(__WINRT__) && __WINRT__ + +/* Gets the path to the local app data store. + Files and directories that should be limited to the local device can be + created in this path. + + This function may be used safely on Windows Phone 8, as opposed to + SDL_WinRTGetRoamingFolderPath() and SDL_WinRTGetTemporaryFolderPath(), + which do not work on Windows Phone 8 (and will return NULL if called + from this platform). + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetLocalFolderPath(); + +/* Gets the path to the roaming app data store. + Files and directories that should roam to different devices can be + created in this path. Be sure to read Microsoft's documentation on + roaming files for more information on how this works, as restrictions + do apply. + + Please note that on Windows Phone 8, this function will return NULL, + as Windows Phone 8 apps do not have an accessible roaming app data + store. + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetRoamingFolderPath(); + +/* Gets the path to the temporary app data store. + Files and directories may be written here, however they may be deleted + by Windows at a future date. + + Please note that on Windows Phone 8, this function will return NULL, + as Windows Phone 8 apps do not have an accessible temporary app data + store. +*/ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetTemporaryFolderPath(); + +#endif /* __WINRT__ */ + + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp new file mode 100644 index 000000000..fc33a86ed --- /dev/null +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -0,0 +1,45 @@ +/* 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_system.h" +#include "../windows/SDL_windows.h" +} + +using namespace Windows::Storage; + +extern "C" const char * SDL_WinRTGetLocalFolderPath() +{ + static const char * path = nullptr; + if (!path) { + path = WIN_StringToUTF8(ApplicationData::Current->LocalFolder->Path->Data()); + } + return path; +} + +extern "C" const char * SDL_WinRTGetRoamingFolderPath() +{ + // TODO, WinRT: make SDL_WinRTGetRoamingFolderPath return NULL on Windows Phone 8 + static const char * path = nullptr; + if (!path) { + path = WIN_StringToUTF8(ApplicationData::Current->RoamingFolder->Path->Data()); + } + return path; +} + +extern "C" const char * SDL_WinRTGetTemporaryFolderPath() +{ + // TODO, WinRT: make SDL_WinRTGetTemporaryFolderPath return NULL on Windows Phone 8 + static const char * path = nullptr; + if (!path) { + path = WIN_StringToUTF8(ApplicationData::Current->TemporaryFolder->Path->Data()); + } + return path; +} + +#endif /* __WINRT__ */ From 8620bcfefecf4e3bd820f772bd97e1b4bd9f5f69 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 22 Jan 2013 21:46:39 -0500 Subject: [PATCH 077/264] WinRT: minor, MSVC project file cleanup --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters index 379fe48a5..0682d5f5f 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters @@ -261,6 +261,9 @@ Source Files + + Source Files + @@ -554,9 +557,6 @@ Source Files - - Source Files - Source Files @@ -596,6 +596,9 @@ Source Files + + Header Files + From 37f50a4f2506f4844331b14f4f21b83a116b26ac Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 22 Jan 2013 22:36:32 -0500 Subject: [PATCH 078/264] WinRT: hack-fixed a bug whereby SDL_UpdateWindowSurface would fail if the app was hidden, then re-shown --- src/video/windowsrt/SDL_WinRTApp.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 0e4326ad6..5cc9cadb6 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -152,11 +152,21 @@ void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEven { 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; } } From fe5d1f4c32c9138e797bf934a81ffeddb31f8922 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 23 Jan 2013 08:44:12 -0500 Subject: [PATCH 079/264] WinRT: made use of Win32 key codes if and when a documented WinRT key code can't be found --- src/video/windowsrt/SDL_WinRTApp.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 5cc9cadb6..0c74750dc 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -8,6 +8,7 @@ extern "C" { #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_windowevents_c.h" +#include "../../events/scancodes_windows.h" #include "SDL_events.h" #include "SDL_log.h" } @@ -462,10 +463,20 @@ static SDL_Scancode WinRT_Keycodes[] = { static SDL_Scancode TranslateKeycode(int keycode) { + /* 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, try to get 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_Scancode scancode = SDL_SCANCODE_UNKNOWN; if (keycode < SDL_arraysize(WinRT_Keycodes)) { scancode = WinRT_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); } From 5a354ebb69051bf0d9807b6f7be5b1a0d532f302 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 23 Jan 2013 08:45:28 -0500 Subject: [PATCH 080/264] WinRT: minor comment change to keyboard code --- src/video/windowsrt/SDL_WinRTApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 0c74750dc..98f95ab0b 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -465,7 +465,7 @@ TranslateKeycode(int keycode) { /* 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, try to get a Win32 virtual key. + 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_Scancode scancode = SDL_SCANCODE_UNKNOWN; From 82b19786d364c6bb0bb36a99f3be22e5e3af30a8 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 23 Jan 2013 09:09:23 -0500 Subject: [PATCH 081/264] WinRT: got backslash keys working, at least on Win8 in a Parallels 8 VM --- src/video/windowsrt/SDL_WinRTApp.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 98f95ab0b..f7703a700 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -13,6 +13,8 @@ extern "C" { #include "SDL_log.h" } +#include + // TODO, WinRT: Remove reference(s) to BasicTimer.h //#include "BasicTimer.h" @@ -291,7 +293,7 @@ void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) } } -static SDL_Scancode WinRT_Keycodes[] = { +static SDL_Scancode WinRT_Official_Keycodes[] = { SDL_SCANCODE_UNKNOWN, // VirtualKey.None -- 0 SDL_SCANCODE_UNKNOWN, // VirtualKey.LeftButton -- 1 SDL_SCANCODE_UNKNOWN, // VirtualKey.RightButton -- 2 @@ -460,17 +462,32 @@ static SDL_Scancode WinRT_Keycodes[] = { SDL_SCANCODE_MENU, // VirtualKey.RightMenu -- 165 }; +static std::unordered_map 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[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_Keycodes)) { - scancode = WinRT_Keycodes[keycode]; + 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)) { From 499746bea9b4e42367968cd77f390f6431dd0255 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 23 Jan 2013 09:51:04 -0500 Subject: [PATCH 082/264] WinRT: made the grave/tilde key work --- src/video/windowsrt/SDL_WinRTApp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index f7703a700..9cdf0969f 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -471,6 +471,7 @@ TranslateKeycode(int keycode) /* 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; } From 240e6d6b71979f5298a230f94547240a948ca453 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 23 Jan 2013 23:42:50 -0500 Subject: [PATCH 083/264] WinRT: separated Win32 and WinRT project files --HG-- rename : VisualC/SDL/SDL_VS2012_WinRT.vcxproj => VisualC-WinRT/SDL/SDL_VS2012.vcxproj rename : VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters => VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters rename : VisualC/SDL_VS2012_WinRT.sln => VisualC-WinRT/SDL_VS2012.sln rename : VisualC/tests/loopwave/WinRT/Assets/Logo.png => VisualC-WinRT/tests/loopwave/Assets/Logo.png rename : VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png => VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png rename : VisualC/tests/loopwave/WinRT/Assets/SplashScreen.png => VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png rename : VisualC/tests/loopwave/WinRT/Assets/StoreLogo.png => VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png rename : VisualC/tests/loopwave/WinRT/Package.appxmanifest => VisualC-WinRT/tests/loopwave/Package.appxmanifest rename : VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj => VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj rename : VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx => VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx rename : VisualC/tests/testthread/WinRT/Assets/Logo.png => VisualC-WinRT/tests/testthread/Assets/Logo.png rename : VisualC/tests/testthread/WinRT/Assets/SmallLogo.png => VisualC-WinRT/tests/testthread/Assets/SmallLogo.png rename : VisualC/tests/testthread/WinRT/Assets/SplashScreen.png => VisualC-WinRT/tests/testthread/Assets/SplashScreen.png rename : VisualC/tests/testthread/WinRT/Assets/StoreLogo.png => VisualC-WinRT/tests/testthread/Assets/StoreLogo.png rename : VisualC/tests/testthread/WinRT/Package.appxmanifest => VisualC-WinRT/tests/testthread/Package.appxmanifest rename : VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj => VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj rename : VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx => VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx --- .../SDL/SDL_VS2012.vcxproj | 2 +- .../SDL/SDL_VS2012.vcxproj.filters | 0 .../SDL_VS2012.sln | 0 .../tests/loopwave}/Assets/Logo.png | Bin .../tests/loopwave}/Assets/SmallLogo.png | Bin .../tests/loopwave}/Assets/SplashScreen.png | Bin .../tests/loopwave}/Assets/StoreLogo.png | Bin .../tests/loopwave}/Package.appxmanifest | 0 .../tests/loopwave/loopwave_VS2012.vcxproj | 21 +++++++++--------- .../loopwave/loopwave_VS2012_TemporaryKey.pfx | Bin .../tests/testthread}/Assets/Logo.png | Bin .../tests/testthread}/Assets/SmallLogo.png | Bin .../tests/testthread}/Assets/SplashScreen.png | Bin .../tests/testthread}/Assets/StoreLogo.png | Bin .../tests/testthread}/Package.appxmanifest | 0 .../testthread/testthread_VS2012.vcxproj | 15 +++++++------ .../testthread_VS2012_TemporaryKey.pfx | Bin 17 files changed, 20 insertions(+), 18 deletions(-) rename VisualC/SDL/SDL_VS2012_WinRT.vcxproj => VisualC-WinRT/SDL/SDL_VS2012.vcxproj (98%) rename VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters => VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters (100%) rename VisualC/SDL_VS2012_WinRT.sln => VisualC-WinRT/SDL_VS2012.sln (100%) rename {VisualC/tests/loopwave/WinRT => VisualC-WinRT/tests/loopwave}/Assets/Logo.png (100%) rename {VisualC/tests/loopwave/WinRT => VisualC-WinRT/tests/loopwave}/Assets/SmallLogo.png (100%) rename {VisualC/tests/loopwave/WinRT => VisualC-WinRT/tests/loopwave}/Assets/SplashScreen.png (100%) rename {VisualC/tests/loopwave/WinRT => VisualC-WinRT/tests/loopwave}/Assets/StoreLogo.png (100%) rename {VisualC/tests/loopwave/WinRT => VisualC-WinRT/tests/loopwave}/Package.appxmanifest (100%) rename VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj => VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj (91%) rename VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx => VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx (100%) rename {VisualC/tests/testthread/WinRT => VisualC-WinRT/tests/testthread}/Assets/Logo.png (100%) rename {VisualC/tests/testthread/WinRT => VisualC-WinRT/tests/testthread}/Assets/SmallLogo.png (100%) rename {VisualC/tests/testthread/WinRT => VisualC-WinRT/tests/testthread}/Assets/SplashScreen.png (100%) rename {VisualC/tests/testthread/WinRT => VisualC-WinRT/tests/testthread}/Assets/StoreLogo.png (100%) rename {VisualC/tests/testthread/WinRT => VisualC-WinRT/tests/testthread}/Package.appxmanifest (100%) rename VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj => VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj (92%) rename VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx => VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx (100%) diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012.vcxproj similarity index 98% rename from VisualC/SDL/SDL_VS2012_WinRT.vcxproj rename to VisualC-WinRT/SDL/SDL_VS2012.vcxproj index 4fd72398a..ac0162d0a 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012.vcxproj @@ -310,7 +310,7 @@ {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} Win32Proj - SDL_VS2012_WinRT + SDL SDL_VS2012_WinRT en-US 11.0 diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters similarity index 100% rename from VisualC/SDL/SDL_VS2012_WinRT.vcxproj.filters rename to VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters diff --git a/VisualC/SDL_VS2012_WinRT.sln b/VisualC-WinRT/SDL_VS2012.sln similarity index 100% rename from VisualC/SDL_VS2012_WinRT.sln rename to VisualC-WinRT/SDL_VS2012.sln diff --git a/VisualC/tests/loopwave/WinRT/Assets/Logo.png b/VisualC-WinRT/tests/loopwave/Assets/Logo.png similarity index 100% rename from VisualC/tests/loopwave/WinRT/Assets/Logo.png rename to VisualC-WinRT/tests/loopwave/Assets/Logo.png diff --git a/VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png b/VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png similarity index 100% rename from VisualC/tests/loopwave/WinRT/Assets/SmallLogo.png rename to VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png diff --git a/VisualC/tests/loopwave/WinRT/Assets/SplashScreen.png b/VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png similarity index 100% rename from VisualC/tests/loopwave/WinRT/Assets/SplashScreen.png rename to VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png diff --git a/VisualC/tests/loopwave/WinRT/Assets/StoreLogo.png b/VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png similarity index 100% rename from VisualC/tests/loopwave/WinRT/Assets/StoreLogo.png rename to VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png diff --git a/VisualC/tests/loopwave/WinRT/Package.appxmanifest b/VisualC-WinRT/tests/loopwave/Package.appxmanifest similarity index 100% rename from VisualC/tests/loopwave/WinRT/Package.appxmanifest rename to VisualC-WinRT/tests/loopwave/Package.appxmanifest diff --git a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj similarity index 91% rename from VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj rename to VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index bb27ceb52..4a87cbc85 100644 --- a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -28,10 +28,11 @@ {03fcc293-9406-49c2-acf6-6e7d460c3239} - loopwave_VS2012_WinRT + loopwave_VS2012 en-US 11.0 true + loopwave @@ -90,7 +91,7 @@ - loopwave_VS2012_WinRT_TemporaryKey.pfx + loopwave_VS2012_TemporaryKey.pfx @@ -99,7 +100,7 @@ pch.h $(IntDir)pch.pch - $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\..\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\include;%(AdditionalIncludeDirectories) 4453 @@ -129,11 +130,11 @@ Designer - + - - + + false false false @@ -143,13 +144,13 @@ - - - - + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + + + diff --git a/VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx b/VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx similarity index 100% rename from VisualC/tests/loopwave/WinRT/loopwave_VS2012_WinRT_TemporaryKey.pfx rename to VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx diff --git a/VisualC/tests/testthread/WinRT/Assets/Logo.png b/VisualC-WinRT/tests/testthread/Assets/Logo.png similarity index 100% rename from VisualC/tests/testthread/WinRT/Assets/Logo.png rename to VisualC-WinRT/tests/testthread/Assets/Logo.png diff --git a/VisualC/tests/testthread/WinRT/Assets/SmallLogo.png b/VisualC-WinRT/tests/testthread/Assets/SmallLogo.png similarity index 100% rename from VisualC/tests/testthread/WinRT/Assets/SmallLogo.png rename to VisualC-WinRT/tests/testthread/Assets/SmallLogo.png diff --git a/VisualC/tests/testthread/WinRT/Assets/SplashScreen.png b/VisualC-WinRT/tests/testthread/Assets/SplashScreen.png similarity index 100% rename from VisualC/tests/testthread/WinRT/Assets/SplashScreen.png rename to VisualC-WinRT/tests/testthread/Assets/SplashScreen.png diff --git a/VisualC/tests/testthread/WinRT/Assets/StoreLogo.png b/VisualC-WinRT/tests/testthread/Assets/StoreLogo.png similarity index 100% rename from VisualC/tests/testthread/WinRT/Assets/StoreLogo.png rename to VisualC-WinRT/tests/testthread/Assets/StoreLogo.png diff --git a/VisualC/tests/testthread/WinRT/Package.appxmanifest b/VisualC-WinRT/tests/testthread/Package.appxmanifest similarity index 100% rename from VisualC/tests/testthread/WinRT/Package.appxmanifest rename to VisualC-WinRT/tests/testthread/Package.appxmanifest diff --git a/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj similarity index 92% rename from VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj rename to VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index 0f522e147..deedbc767 100644 --- a/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -28,10 +28,11 @@ {a8705bee-d01d-46a4-b2ab-feedfb5fdd11} - testthread_VS2012_WinRT + testthread_VS2012 en-US 11.0 true + testthread @@ -90,7 +91,7 @@ - testthread_VS2012_WinRT_TemporaryKey.pfx + testthread_VS2012_TemporaryKey.pfx @@ -99,7 +100,7 @@ pch.h $(IntDir)pch.pch - $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\..\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(IntermediateOutputPath);$(ProjectDir)..\..\..\include;%(AdditionalIncludeDirectories) 4453 @@ -135,10 +136,10 @@ Designer - + - + true true true @@ -146,10 +147,10 @@ true true - + - + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} diff --git a/VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx b/VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx similarity index 100% rename from VisualC/tests/testthread/WinRT/testthread_VS2012_WinRT_TemporaryKey.pfx rename to VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx From 62303fa63a3514987e784583c17f013cbf78145c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 28 Jan 2013 22:03:12 -0500 Subject: [PATCH 084/264] WinRT: made project file name include "WinRT", in order to make it distinct from a future WinPhone project --HG-- rename : VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters => VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters rename : VisualC-WinRT/SDL_VS2012.sln => VisualC-WinRT/SDL_VS2012-WinRT.sln --- ...lters => SDL_VS2012-WinRT.vcxproj.filters} | 0 VisualC-WinRT/SDL/SDL_VS2012.vcxproj | 491 ------------------ .../{SDL_VS2012.sln => SDL_VS2012-WinRT.sln} | 2 +- .../tests/loopwave/loopwave_VS2012.vcxproj | 8 +- .../testthread/testthread_VS2012.vcxproj | 2 +- 5 files changed, 6 insertions(+), 497 deletions(-) rename VisualC-WinRT/SDL/{SDL_VS2012.vcxproj.filters => SDL_VS2012-WinRT.vcxproj.filters} (100%) delete mode 100644 VisualC-WinRT/SDL/SDL_VS2012.vcxproj rename VisualC-WinRT/{SDL_VS2012.sln => SDL_VS2012-WinRT.sln} (90%) diff --git a/VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters similarity index 100% rename from VisualC-WinRT/SDL/SDL_VS2012.vcxproj.filters rename to VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters diff --git a/VisualC-WinRT/SDL/SDL_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012.vcxproj deleted file mode 100644 index ac0162d0a..000000000 --- a/VisualC-WinRT/SDL/SDL_VS2012.vcxproj +++ /dev/null @@ -1,491 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - true - true - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pixel - Pixel - Pixel - Pixel - Pixel - Pixel - - - Vertex - Vertex - Vertex - Vertex - Vertex - Vertex - - - - {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} - Win32Proj - SDL - SDL_VS2012_WinRT - en-US - 11.0 - true - - - - DynamicLibrary - true - v110 - - - DynamicLibrary - true - v110 - - - DynamicLibrary - true - v110 - - - DynamicLibrary - false - true - v110 - - - DynamicLibrary - false - true - v110 - - - DynamicLibrary - false - true - v110 - - - - - - - - - - - - - - - - - - - - - - - - false - false - SDL - - - false - false - SDL - - - false - false - SDL - - - false - false - SDL - - - false - false - SDL - - - false - false - SDL - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - NotUsing - false - ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) - - - - - - \ No newline at end of file diff --git a/VisualC-WinRT/SDL_VS2012.sln b/VisualC-WinRT/SDL_VS2012-WinRT.sln similarity index 90% rename from VisualC-WinRT/SDL_VS2012.sln rename to VisualC-WinRT/SDL_VS2012-WinRT.sln index e61a8593d..046e6b7ba 100644 --- a/VisualC-WinRT/SDL_VS2012.sln +++ b/VisualC-WinRT/SDL_VS2012-WinRT.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL_VS2012-WinRT", "SDL\SDL_VS2012-WinRT.vcxproj", "{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index 4a87cbc85..fcaee1d24 100644 --- a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -144,12 +144,12 @@ - - {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} - + - + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + diff --git a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index deedbc767..2a515b31e 100644 --- a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -150,7 +150,7 @@ - + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} From a1ef55a6f7b7fe685ee71b56925757c4fcbda406 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 28 Jan 2013 23:13:07 -0500 Subject: [PATCH 085/264] WinRT: added Windows Phone 8 project files, and got SDL compiling under them --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 423 ++++++++++++ .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 614 ++++++++++++++++++ src/audio/xaudio2/SDL_xaudio2.c | 2 + .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 27 + src/video/windowsrt/DirectXHelper.h | 7 +- 5 files changed, 1072 insertions(+), 1 deletion(-) create mode 100644 VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj create mode 100644 VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj new file mode 100644 index 000000000..0e1b2e1ea --- /dev/null +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -0,0 +1,423 @@ + + + + + Debug + Win32 + + + Debug + ARM + + + Release + Win32 + + + Release + ARM + + + + {33048af1-031a-4ce6-b61e-fad2db832e9e} + SDL + en-US + 11.0 + SDL-WinPhone + + + + DynamicLibrary + true + v110_wp80 + false + + + DynamicLibrary + true + v110_wp80 + false + + + DynamicLibrary + false + true + v110_wp80 + false + + + DynamicLibrary + false + true + v110_wp80 + false + + + + + + + + false + + + + _USRDLL;UNICODE;%(PreprocessorDefinitions) + NotUsing + pch.h + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + ..\..\include + false + + + Console + false + false + true + d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + _USRDLL;UNICODE;NDEBUG;%(PreprocessorDefinitions) + NotUsing + pch.h + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + ..\..\include + + + Console + false + false + true + d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + _USRDLL;UNICODE;%(PreprocessorDefinitions) + NotUsing + pch.h + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + ..\..\include + false + + + Console + false + false + true + d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + _USRDLL;UNICODE;NDEBUG;%(PreprocessorDefinitions) + NotUsing + pch.h + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + ..\..\include + + + Console + false + false + true + d3d11.lib;xaudio2.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + true + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + + + Document + Pixel + Pixel + Pixel + Pixel + + + Document + Vertex + Vertex + Vertex + Vertex + + + + + + + \ No newline at end of file diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters new file mode 100644 index 000000000..1774855a2 --- /dev/null +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -0,0 +1,614 @@ + + + + + {02b21b9a-45a7-41ee-a8a6-e45d14aa28da} + + + {abc3a7e6-f955-4cb5-8340-fae0f653e9c1} + + + {fd67993e-5155-488b-9313-d1eb06a1b67e} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + GPU Shaders + + + GPU Shaders + + + \ No newline at end of file diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 924699445..1509abfca 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -367,6 +367,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) ixa2->SetDebugConfiguration(&debugConfig); */ +#if ! defined(__WINRT__) || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP if (devname != NULL) { UINT32 devcount = 0; UINT32 i = 0; @@ -402,6 +403,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) return 0; } } +#endif /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp index 7fa14ab7e..aa88fd6c1 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -2,12 +2,21 @@ #include #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) @@ -17,10 +26,27 @@ HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) 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) { @@ -39,4 +65,5 @@ HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVIC wcsncpy_s(details->DisplayName, ARRAYSIZE(details->DisplayName), d->Name->Data(), _TRUNCATE); } return S_OK; +#endif } diff --git a/src/video/windowsrt/DirectXHelper.h b/src/video/windowsrt/DirectXHelper.h index 4a74492af..cc8078b42 100644 --- a/src/video/windowsrt/DirectXHelper.h +++ b/src/video/windowsrt/DirectXHelper.h @@ -25,7 +25,12 @@ namespace DX return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file) { - return FileIO::ReadBufferAsync(file); + return file->OpenReadAsync(); + }).then([] (Streams::IRandomAccessStreamWithContentType^ stream) + { + unsigned int bufferSize = static_cast(stream->Size); + auto fileBuffer = ref new Streams::Buffer(bufferSize); + return stream->ReadAsync(fileBuffer, bufferSize, Streams::InputStreamOptions::None); }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array^ { auto fileData = ref new Platform::Array(fileBuffer->Length); From cb26260357cd70b043bd5352741d64cb2acf0b63 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 28 Jan 2013 23:19:13 -0500 Subject: [PATCH 086/264] WinRT: re-added SDL's MSVC project file, which I accidentally deleted (oops!) --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 493 +++++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj new file mode 100644 index 000000000..4088ac93a --- /dev/null +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -0,0 +1,493 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + + + Document + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + + + + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} + Win32Proj + SDL-WinRT + SDL_VS2012_WinRT + en-US + 11.0 + true + + + + DynamicLibrary + true + v110 + + + DynamicLibrary + true + v110 + + + DynamicLibrary + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + + + + + + + + + + + + + + + + + + + + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + false + false + SDL + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + NotUsing + false + ..\..\include;%(AdditionalIncludeDirectories) + _WINDLL;%(PreprocessorDefinitions) + + + Console + false + false + xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file From 53ce1e6ab7f908ff6d8796616ea2539debd023b4 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 29 Jan 2013 20:27:47 -0500 Subject: [PATCH 087/264] WinRT: Windows Phone fixes. SDL can now display images, and respond to input, on Microsoft's Windows Phone 8 emulator. --- src/video/windowsrt/SDL_WinRTApp.cpp | 5 ++++- src/video/windowsrt/SDL_winrtmouse.cpp | 2 ++ src/video/windowsrt/SDL_winrtrenderer.cpp | 23 ++++++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 9cdf0969f..d74ad087a 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -33,7 +33,6 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; - using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; @@ -77,7 +76,9 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->Closed += ref new TypedEventHandler(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(this, &SDL_WinRTApp::OnPointerPressed); @@ -88,9 +89,11 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerMoved += ref new TypedEventHandler(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(this, &SDL_WinRTApp::OnMouseMoved); +#endif window->KeyDown += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/windowsrt/SDL_winrtmouse.cpp index 2b44400e7..5d6bcc607 100644 --- a/src/video/windowsrt/SDL_winrtmouse.cpp +++ b/src/video/windowsrt/SDL_winrtmouse.cpp @@ -126,6 +126,7 @@ WINRT_InitMouse(_THIS) - programmatically moveable cursors */ +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP //mouse->CreateCursor = WINRT_CreateCursor; mouse->CreateSystemCursor = WINRT_CreateSystemCursor; mouse->ShowCursor = WINRT_ShowCursor; @@ -134,6 +135,7 @@ WINRT_InitMouse(_THIS) mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); +#endif } void diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 43564fe61..030aeacb4 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -98,8 +98,13 @@ void SDL_winrtrenderer::CreateDeviceResources() context.As(&m_d3dContext) ); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso"); + auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso"); +#else auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); +#endif auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { DX::ThrowIfFailed( @@ -194,7 +199,7 @@ void SDL_winrtrenderer::CreateDeviceResources() // Allocate all memory resources that change on a window SizeChanged event. void SDL_winrtrenderer::CreateWindowSizeDependentResources() -{ +{ // Store the window bounds so the next time we get a SizeChanged event we can // avoid rebuilding everything if the size is identical. m_windowBounds = m_window->Bounds; @@ -238,8 +243,13 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() 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 dxgiDevice; @@ -327,9 +337,12 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() 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. DX::ThrowIfFailed( m_swapChain->SetRotation(rotation) ); +#endif // Create a render target view of the swap chain back buffer. ComPtr backBuffer; @@ -546,8 +559,15 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr // Method to deliver the final image to the display. void SDL_winrtrenderer::Present() { +#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 = m_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; @@ -558,6 +578,7 @@ void SDL_winrtrenderer::Present() // 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 = m_swapChain->Present1(1, 0, ¶meters); +#endif // Discard the contents of the render target. // This is a valid operation only when the existing contents will be entirely From f7b08ae60b53ce82516bb6a55586e187c25d1f2b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 2 Feb 2013 19:32:44 -0500 Subject: [PATCH 088/264] WinRT: started refactoring Direct3D 11.1 code into a new SDL_Renderer backend --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 2 + .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 + VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 2 + .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 + include/SDL_config_windowsrt.h | 2 + src/render/SDL_render.c | 3 + src/render/SDL_sysrender.h | 3 + src/render/direct3d11/SDL_render_d3d11.cpp | 291 ++++++++++++++++++ src/render/direct3d11/SDL_render_d3d11_cpp.h | 45 +++ src/video/windowsrt/SDL_WinRTApp.cpp | 6 +- src/video/windowsrt/SDL_WinRTApp.h | 4 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 115 +++---- src/video/windowsrt/SDL_winrtrenderer.h | 18 +- src/video/windowsrt/SDL_winrtvideo.cpp | 14 + 14 files changed, 444 insertions(+), 73 deletions(-) create mode 100644 src/render/direct3d11/SDL_render_d3d11.cpp create mode 100644 src/render/direct3d11/SDL_render_d3d11_cpp.h diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 0e1b2e1ea..c7156be8f 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -211,6 +211,7 @@ + @@ -302,6 +303,7 @@ + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 1774855a2..ec1edad74 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -345,6 +345,9 @@ Source Files + + Source Files + @@ -602,6 +605,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 4088ac93a..53a3bb345 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -78,6 +78,7 @@ + @@ -248,6 +249,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 0682d5f5f..fec688350 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -264,6 +264,9 @@ Source Files + + Source Files + @@ -599,6 +602,9 @@ Header Files + + Source Files + diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 3223ca261..c9af3fda1 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -159,6 +159,8 @@ typedef unsigned int uintptr_t; #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. diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 01b4aa13b..0e5edfe36 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -49,6 +49,9 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_D3D &D3D_RenderDriver, #endif +#if SDL_VIDEO_RENDER_D3D11 + &D3D11_RenderDriver, +#endif #if SDL_VIDEO_RENDER_OGL &GL_RenderDriver, #endif diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index dff297f5e..69e83ec48 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -161,6 +161,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 diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp new file mode 100644 index 000000000..21f89fd01 --- /dev/null +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -0,0 +1,291 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +extern "C" { +#include "../../core/windows/SDL_windows.h" +//#include "SDL_hints.h" +//#include "SDL_loadso.h" +#include "SDL_syswm.h" +#include "../SDL_sysrender.h" +//#include "stdio.h" +} + +#include "SDL_render_d3d11_cpp.h" + +/* Direct3D 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 *pixels, +// int pitch); +//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); + + +extern "C" { + SDL_RenderDriver D3D11_RenderDriver = { + D3D11_CreateRenderer, + { + "direct3d", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), + 1, + {SDL_PIXELFORMAT_ARGB8888}, + 0, + 0} + }; +} + +//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; +// SDL_SysWMinfo windowinfo; + // HRESULT result; + // D3DPRESENT_PARAMETERS pparams; + // IDirect3DSwapChain9 *chain; + // D3DCAPS9 caps; + // Uint32 window_flags; + // int w, h; + // SDL_DisplayMode fullscreen_mode; + // D3DMATRIX matrix; + // int d3dxVersion; + //char d3dxDLLFile[50]; + + 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) { + delete data; + SDL_OutOfMemory(); + return NULL; + } + + // TODO: Create Direct3D Object(s) + + //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; + + renderer->info.flags = SDL_RENDERER_ACCELERATED; + + //SDL_VERSION(&windowinfo.version); + //SDL_GetWindowWMInfo(window, &windowinfo); + + //window_flags = SDL_GetWindowFlags(window); + //SDL_GetWindowSize(window, &w, &h); + //SDL_GetWindowDisplayMode(window, &fullscreen_mode); + + //SDL_zero(pparams); + //pparams.hDeviceWindow = windowinfo.info.win.window; + //pparams.BackBufferWidth = w; + //pparams.BackBufferHeight = h; + //if (window_flags & SDL_WINDOW_FULLSCREEN) { + // pparams.BackBufferFormat = + // PixelFormatToD3DFMT(fullscreen_mode.format); + //} else { + // pparams.BackBufferFormat = D3DFMT_UNKNOWN; + //} + //pparams.BackBufferCount = 1; + //pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; + + //if (window_flags & SDL_WINDOW_FULLSCREEN) { + // pparams.Windowed = FALSE; + // pparams.FullScreen_RefreshRateInHz = + // fullscreen_mode.refresh_rate; + //} else { + // pparams.Windowed = TRUE; + // pparams.FullScreen_RefreshRateInHz = 0; + //} + //if (flags & SDL_RENDERER_PRESENTVSYNC) { + // pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + //} else { + // pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + //} + + ///* FIXME: Which adapter? */ + //data->adapter = D3DADAPTER_DEFAULT; + //IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); + + //result = IDirect3D9_CreateDevice(data->d3d, data->adapter, + // D3DDEVTYPE_HAL, + // pparams.hDeviceWindow, + // D3DCREATE_FPU_PRESERVE | ((caps. + // DevCaps & + // D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? + // D3DCREATE_HARDWARE_VERTEXPROCESSING : + // D3DCREATE_SOFTWARE_VERTEXPROCESSING), + // &pparams, &data->device); + //if (FAILED(result)) { + // D3D11_DestroyRenderer(renderer); + // D3D11_SetError("CreateDevice()", result); + // return NULL; + //} + //data->beginScene = SDL_TRUE; + //data->scaleMode = D3DTEXF_FORCE_DWORD; + + ///* Get presentation parameters to fill info */ + //result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); + //if (FAILED(result)) { + // D3D11_DestroyRenderer(renderer); + // D3D11_SetError("GetSwapChain()", result); + // return NULL; + //} + //result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); + //if (FAILED(result)) { + // IDirect3DSwapChain9_Release(chain); + // D3D11_DestroyRenderer(renderer); + // D3D11_SetError("GetPresentParameters()", result); + // return NULL; + //} + //IDirect3DSwapChain9_Release(chain); + //if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { + // renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + //} + //data->pparams = pparams; + + //IDirect3DDevice9_GetDeviceCaps(data->device, &caps); + //renderer->info.max_texture_width = caps.MaxTextureWidth; + //renderer->info.max_texture_height = caps.MaxTextureHeight; + //if (caps.NumSimultaneousRTs >= 2) { + // renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE; + //} + + ///* Set up parameters for rendering */ + //IDirect3DDevice9_SetVertexShader(data->device, NULL); + //IDirect3DDevice9_SetFVF(data->device, + // D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); + //IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); + //IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, + // D3DCULL_NONE); + //IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); + ///* Enable color modulation by diffuse color */ + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, + // D3DTOP_MODULATE); + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, + // D3DTA_TEXTURE); + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, + // D3DTA_DIFFUSE); + ///* Enable alpha modulation by diffuse alpha */ + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, + // D3DTOP_MODULATE); + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, + // D3DTA_TEXTURE); + //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, + // D3DTA_DIFFUSE); + ///* Disable second texture stage, since we're done */ + //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, + // D3DTOP_DISABLE); + //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, + // D3DTOP_DISABLE); + + ///* Store the default render target */ + //IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget ); + //data->currentRenderTarget = NULL; + + ///* Set an identity world and view matrix */ + //matrix.m[0][0] = 1.0f; + //matrix.m[0][1] = 0.0f; + //matrix.m[0][2] = 0.0f; + //matrix.m[0][3] = 0.0f; + //matrix.m[1][0] = 0.0f; + //matrix.m[1][1] = 1.0f; + //matrix.m[1][2] = 0.0f; + //matrix.m[1][3] = 0.0f; + //matrix.m[2][0] = 0.0f; + //matrix.m[2][1] = 0.0f; + //matrix.m[2][2] = 1.0f; + //matrix.m[2][3] = 0.0f; + //matrix.m[3][0] = 0.0f; + //matrix.m[3][1] = 0.0f; + //matrix.m[3][2] = 0.0f; + //matrix.m[3][3] = 1.0f; + //IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix); + //IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix); + + return renderer; +} + +static int +D3D11_UpdateViewport(SDL_Renderer * renderer) +{ + return 0; +} + +#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h new file mode 100644 index 000000000..3ec4998f0 --- /dev/null +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 +#include + +typedef struct +{ + Microsoft::WRL::ComPtr d3dDevice; + Microsoft::WRL::ComPtr d3dContext; + Microsoft::WRL::ComPtr swapChain; + Microsoft::WRL::ComPtr renderTargetView; + Microsoft::WRL::ComPtr inputLayout; + Microsoft::WRL::ComPtr vertexBuffer; + Microsoft::WRL::ComPtr vertexShader; + Microsoft::WRL::ComPtr pixelShader; + Microsoft::WRL::ComPtr mainTexture; + Microsoft::WRL::ComPtr mainTextureResourceView; + Microsoft::WRL::ComPtr mainSampler; +} D3D11_RenderData; + +typedef struct +{ +} D3D11_TextureData; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index d74ad087a..493d88195 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -47,7 +47,8 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), m_sdlWindowData(NULL), - m_useRelativeMouseMode(false) + m_useRelativeMouseMode(false), + m_renderer(nullptr) { } @@ -101,8 +102,7 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->KeyUp += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); - - m_renderer->Initialize(CoreWindow::GetForCurrentThread()); + //m_renderer->Initialize(CoreWindow::GetForCurrentThread()); // DLudwig: moved this call to WINRT_CreateWindow, likely elsewhere in the future } void SDL_WinRTApp::Load(Platform::String^ entryPoint) diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 06e022536..b6dd25749 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -47,8 +47,10 @@ protected: 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: +internal: SDL_winrtrenderer^ m_renderer; + +private: bool m_windowClosed; bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 030aeacb4..d8d960cb2 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -11,7 +11,8 @@ using namespace Windows::Graphics::Display; SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), m_loadingComplete(false), - m_vertexCount(0) + m_vertexCount(0), + m_sdlRendererData(NULL) { } @@ -38,8 +39,9 @@ void SDL_winrtrenderer::HandleDeviceLost() // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. m_windowBounds.Width = 0; m_windowBounds.Height = 0; - m_swapChain = nullptr; + m_sdlRendererData->swapChain = nullptr; + // TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer CreateDeviceResources(); UpdateForWindowSizeChange(); } @@ -90,12 +92,13 @@ void SDL_winrtrenderer::CreateDeviceResources() ); // Get the Direct3D 11.1 API device and context interfaces. + Microsoft::WRL::ComPtr d3dDevice1; DX::ThrowIfFailed( - device.As(&m_d3dDevice) + device.As(&(m_sdlRendererData->d3dDevice)) ); DX::ThrowIfFailed( - context.As(&m_d3dContext) + context.As(&m_sdlRendererData->d3dContext) ); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP @@ -108,11 +111,11 @@ void SDL_winrtrenderer::CreateDeviceResources() auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { DX::ThrowIfFailed( - m_d3dDevice->CreateVertexShader( + (m_sdlRendererData->d3dDevice)->CreateVertexShader( fileData->Data, fileData->Length, nullptr, - &m_vertexShader + &m_sdlRendererData->vertexShader ) ); @@ -123,23 +126,23 @@ void SDL_winrtrenderer::CreateDeviceResources() }; DX::ThrowIfFailed( - m_d3dDevice->CreateInputLayout( + m_sdlRendererData->d3dDevice->CreateInputLayout( vertexDesc, ARRAYSIZE(vertexDesc), fileData->Data, fileData->Length, - &m_inputLayout + &m_sdlRendererData->inputLayout ) ); }); auto createPSTask = loadPSTask.then([this](Platform::Array^ fileData) { DX::ThrowIfFailed( - m_d3dDevice->CreatePixelShader( + m_sdlRendererData->d3dDevice->CreatePixelShader( fileData->Data, fileData->Length, nullptr, - &m_pixelShader + &m_sdlRendererData->pixelShader ) ); }); @@ -161,10 +164,10 @@ void SDL_winrtrenderer::CreateDeviceResources() vertexBufferData.SysMemSlicePitch = 0; CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); DX::ThrowIfFailed( - m_d3dDevice->CreateBuffer( + m_sdlRendererData->d3dDevice->CreateBuffer( &vertexBufferDesc, &vertexBufferData, - &m_vertexBuffer + &m_sdlRendererData->vertexBuffer ) ); }); @@ -185,9 +188,9 @@ void SDL_winrtrenderer::CreateDeviceResources() samplerDesc.MinLOD = 0.0f; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; DX::ThrowIfFailed( - m_d3dDevice->CreateSamplerState( + m_sdlRendererData->d3dDevice->CreateSamplerState( &samplerDesc, - &m_mainSampler + &m_sdlRendererData->mainSampler ) ); }); @@ -218,11 +221,11 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; - if(m_swapChain != nullptr) + if(m_sdlRendererData->swapChain != nullptr) { // If the swap chain already exists, resize it. DX::ThrowIfFailed( - m_swapChain->ResizeBuffers( + m_sdlRendererData->swapChain->ResizeBuffers( 2, // Double-buffered swap chain. static_cast(m_renderTargetSize.Width), static_cast(m_renderTargetSize.Height), @@ -254,7 +257,7 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() ComPtr dxgiDevice; DX::ThrowIfFailed( - m_d3dDevice.As(&dxgiDevice) + m_sdlRendererData->d3dDevice.As(&dxgiDevice) ); ComPtr dxgiAdapter; @@ -273,11 +276,11 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() Windows::UI::Core::CoreWindow^ window = m_window.Get(); DX::ThrowIfFailed( dxgiFactory->CreateSwapChainForCoreWindow( - m_d3dDevice.Get(), + m_sdlRendererData->d3dDevice.Get(), reinterpret_cast(window), &swapChainDesc, nullptr, // Allow on all displays. - &m_swapChain + &m_sdlRendererData->swapChain ) ); @@ -340,14 +343,14 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() #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. DX::ThrowIfFailed( - m_swapChain->SetRotation(rotation) + m_sdlRendererData->swapChain->SetRotation(rotation) ); #endif // Create a render target view of the swap chain back buffer. ComPtr backBuffer; DX::ThrowIfFailed( - m_swapChain->GetBuffer( + m_sdlRendererData->swapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), &backBuffer @@ -355,10 +358,10 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() ); DX::ThrowIfFailed( - m_d3dDevice->CreateRenderTargetView( + m_sdlRendererData->d3dDevice->CreateRenderTargetView( backBuffer.Get(), nullptr, - &m_renderTargetView + &m_sdlRendererData->renderTargetView ) ); @@ -374,7 +377,7 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() ComPtr depthStencil; DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( + m_sdlRendererData->d3dDevice->CreateTexture2D( &depthStencilDesc, nullptr, &depthStencil @@ -389,7 +392,7 @@ void SDL_winrtrenderer::CreateWindowSizeDependentResources() m_renderTargetSize.Height ); - m_d3dContext->RSSetViewports(1, &viewport); + m_sdlRendererData->d3dContext->RSSetViewports(1, &viewport); } void SDL_winrtrenderer::ResizeMainTexture(int w, int h) @@ -425,10 +428,10 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes; initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes; DX::ThrowIfFailed( - m_d3dDevice->CreateTexture2D( + m_sdlRendererData->d3dDevice->CreateTexture2D( &textureDesc, &initialTextureData, - &m_mainTexture + &m_sdlRendererData->mainTexture ) ); @@ -452,10 +455,10 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) resourceViewDesc.Texture2D.MostDetailedMip = 0; resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels; DX::ThrowIfFailed( - m_d3dDevice->CreateShaderResourceView( - m_mainTexture.Get(), + m_sdlRendererData->d3dDevice->CreateShaderResourceView( + m_sdlRendererData->mainTexture.Get(), &resourceViewDesc, - &m_mainTextureResourceView) + &m_sdlRendererData->mainTextureResourceView) ); } @@ -467,9 +470,9 @@ void SDL_winrtrenderer::UpdateForWindowSizeChange() m_orientation != DisplayProperties::CurrentOrientation) { ID3D11RenderTargetView* nullViews[] = {nullptr}; - m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - m_renderTargetView = nullptr; - m_d3dContext->Flush(); + m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + m_sdlRendererData->renderTargetView = nullptr; + m_sdlRendererData->d3dContext->Flush(); CreateWindowSizeDependentResources(); } } @@ -477,8 +480,8 @@ void SDL_winrtrenderer::UpdateForWindowSizeChange() void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_d3dContext->ClearRenderTargetView( - m_renderTargetView.Get(), + m_sdlRendererData->d3dContext->ClearRenderTargetView( + m_sdlRendererData->renderTargetView.Get(), blackColor ); @@ -487,7 +490,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr { return; } - if (!m_mainTextureResourceView) + if (!m_sdlRendererData->mainTextureResourceView) { return; } @@ -496,8 +499,8 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr // window's main texture to CPU-accessible memory: D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; DX::ThrowIfFailed( - m_d3dContext->Map( - m_mainTexture.Get(), + m_sdlRendererData->d3dContext->Map( + m_sdlRendererData->mainTexture.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, @@ -513,47 +516,47 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr // Clean up a bit, then commit the texture's memory back to Direct3D: m_mainTextureHelperSurface->pixels = NULL; m_mainTextureHelperSurface->pitch = 0; - m_d3dContext->Unmap( - m_mainTexture.Get(), + m_sdlRendererData->d3dContext->Unmap( + m_sdlRendererData->mainTexture.Get(), 0); - m_d3dContext->OMSetRenderTargets( + m_sdlRendererData->d3dContext->OMSetRenderTargets( 1, - m_renderTargetView.GetAddressOf(), + m_sdlRendererData->renderTargetView.GetAddressOf(), nullptr ); UINT stride = sizeof(VertexPositionColor); UINT offset = 0; - m_d3dContext->IASetVertexBuffers( + m_sdlRendererData->d3dContext->IASetVertexBuffers( 0, 1, - m_vertexBuffer.GetAddressOf(), + m_sdlRendererData->vertexBuffer.GetAddressOf(), &stride, &offset ); - m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + m_sdlRendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_d3dContext->IASetInputLayout(m_inputLayout.Get()); + m_sdlRendererData->d3dContext->IASetInputLayout(m_sdlRendererData->inputLayout.Get()); - m_d3dContext->VSSetShader( - m_vertexShader.Get(), + m_sdlRendererData->d3dContext->VSSetShader( + m_sdlRendererData->vertexShader.Get(), nullptr, 0 ); - m_d3dContext->PSSetShader( - m_pixelShader.Get(), + m_sdlRendererData->d3dContext->PSSetShader( + m_sdlRendererData->pixelShader.Get(), nullptr, 0 ); - m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf()); + m_sdlRendererData->d3dContext->PSSetShaderResources(0, 1, m_sdlRendererData->mainTextureResourceView.GetAddressOf()); - m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf()); + m_sdlRendererData->d3dContext->PSSetSamplers(0, 1, m_sdlRendererData->mainSampler.GetAddressOf()); - m_d3dContext->Draw(4, 0); + m_sdlRendererData->d3dContext->Draw(4, 0); } // Method to deliver the final image to the display. @@ -563,7 +566,7 @@ void SDL_winrtrenderer::Present() // 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 = m_swapChain->Present(1, 0); + HRESULT hr = m_sdlRendererData->swapChain->Present(1, 0); #else // The application may optionally specify "dirty" or "scroll" // rects to improve efficiency in certain scenarios. @@ -577,13 +580,13 @@ void SDL_winrtrenderer::Present() // 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 = m_swapChain->Present1(1, 0, ¶meters); + HRESULT hr = m_sdlRendererData->swapChain->Present1(1, 0, ¶meters); #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. - m_d3dContext->DiscardView(m_renderTargetView.Get()); + m_sdlRendererData->d3dContext->DiscardView(m_sdlRendererData->renderTargetView.Get()); // If the device was removed either by a disconnect or a driver upgrade, we // must recreate all device resources. diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 62b194f3d..4f771947f 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -2,6 +2,7 @@ #include "DirectXHelper.h" #include "SDL.h" +#include "../../render/direct3d11/SDL_render_d3d11_cpp.h" struct VertexPositionColor { @@ -29,20 +30,11 @@ internal: virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); void ResizeMainTexture(int w, int h); -protected private: - // Direct3D Objects. - Microsoft::WRL::ComPtr m_d3dDevice; - Microsoft::WRL::ComPtr m_d3dContext; - Microsoft::WRL::ComPtr m_swapChain; - Microsoft::WRL::ComPtr m_renderTargetView; - Microsoft::WRL::ComPtr m_inputLayout; - Microsoft::WRL::ComPtr m_vertexBuffer; - Microsoft::WRL::ComPtr m_vertexShader; - Microsoft::WRL::ComPtr m_pixelShader; - Microsoft::WRL::ComPtr m_mainTexture; - Microsoft::WRL::ComPtr m_mainTextureResourceView; - Microsoft::WRL::ComPtr m_mainSampler; +internal: + // Internal SDL rendeerer (likely a temporary addition, for refactoring purposes): + D3D11_RenderData * m_sdlRendererData; +protected private: // UpdateWindowSurface helper objects SDL_Surface * m_mainTextureHelperSurface; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 5b72c92a1..6bd7640db 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -34,6 +34,7 @@ extern "C" { #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" +#include "../../render/SDL_sysrender.h" } #include "SDL_WinRTApp.h" @@ -210,6 +211,19 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) */ SDL_WinRTGlobalApp->SetSDLWindowData(data); + /* For now, create a Direct3D 11 renderer up-front. Eventually, this + won't be done in WINRT_CreateWindow, although it may get done in + SDL_WINRT_CreateWindowFramebuffer. + */ + + // Link SDL_winrtrenderer to the SDL_Renderer temporarily, + // for refactoring purposes. Initialize the SDL_Renderer + // first in order to give it the opportunity to create key + // resources first. + SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); + SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; + SDL_WinRTGlobalApp->m_renderer->Initialize(CoreWindow::GetForCurrentThread()); + /* All done! */ return 0; } From b9299763b62bb9f6af195d700a254d7591fa3bbc Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 2 Feb 2013 21:05:32 -0500 Subject: [PATCH 089/264] WinRT: moved a bit more Direct3D 11.1 code into the SDL_Renderer backend --- src/core/windows/SDL_windows.c | 11 ++++- src/core/windows/SDL_windows.h | 3 ++ src/render/direct3d11/SDL_render_d3d11.cpp | 49 +++++++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.cpp | 6 +++ src/video/windowsrt/SDL_winrtrenderer.cpp | 38 +---------------- src/video/windowsrt/SDL_winrtrenderer.h | 3 +- src/video/windowsrt/SDL_winrtvideo.cpp | 3 ++ 7 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index cd8a0d088..cf3141f5a 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -30,17 +30,24 @@ /* Sets an error message based on GetLastError() */ void -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); SDL_free(message); } +/* Sets an error message based on GetLastError() */ +void +WIN_SetError(const char *prefix) +{ + WIN_SetErrorFromHRESULT(prefix, GetLastError()); +} + HRESULT WIN_CoInitialize(void) { diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index d4a7ecff9..3776b70eb 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -46,6 +46,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 void WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr); + /* Sets an error message based on GetLastError() */ extern void WIN_SetError(const char *prefix); diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 21f89fd01..6914f837b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -62,7 +62,7 @@ static int D3D11_UpdateViewport(SDL_Renderer * renderer); // 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_RenderPresent(SDL_Renderer * renderer); //static void D3D11_DestroyTexture(SDL_Renderer * renderer, // SDL_Texture * texture); //static void D3D11_DestroyRenderer(SDL_Renderer * renderer); @@ -135,7 +135,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) //renderer->RenderCopy = D3D11_RenderCopy; //renderer->RenderCopyEx = D3D11_RenderCopyEx; //renderer->RenderReadPixels = D3D11_RenderReadPixels; - //renderer->RenderPresent = D3D11_RenderPresent; + renderer->RenderPresent = D3D11_RenderPresent; //renderer->DestroyTexture = D3D11_DestroyTexture; //renderer->DestroyRenderer = D3D11_DestroyRenderer; renderer->info = D3D11_RenderDriver.info; @@ -286,6 +286,51 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) 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, ¶meters); +#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->renderTargetView.Get()); + + // If the device was removed either by a disconnect or a driver upgrade, we + // must recreate all device resources. + if (hr == DXGI_ERROR_DEVICE_REMOVED) + { + extern void WINRT_HandleDeviceLost(); // TODO, WinRT: move lost-device handling into the Direct3D 11.1 renderer, as appropriate + WINRT_HandleDeviceLost(); + } + else + { + WIN_SetErrorFromHRESULT(__FUNCTION__, hr); + // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines + } +} + #endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 493d88195..aa204aa4d 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -33,6 +33,12 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; +// HACK: provide a temporary means for the Direct3D 11.1 renderer to handle lost devices, while refactoring is underway +void WINRT_HandleDeviceLost() +{ + SDL_WinRTGlobalApp->m_renderer->HandleDeviceLost(); +} + using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index d8d960cb2..750473a04 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -12,6 +12,7 @@ SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), m_loadingComplete(false), m_vertexCount(0), + m_sdlRenderer(NULL), m_sdlRendererData(NULL) { } @@ -562,42 +563,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr // Method to deliver the final image to the display. void SDL_winrtrenderer::Present() { -#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 = m_sdlRendererData->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 = m_sdlRendererData->swapChain->Present1(1, 0, ¶meters); -#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. - m_sdlRendererData->d3dContext->DiscardView(m_sdlRendererData->renderTargetView.Get()); - - // If the device was removed either by a disconnect or a driver upgrade, we - // must recreate all device resources. - if (hr == DXGI_ERROR_DEVICE_REMOVED) - { - HandleDeviceLost(); - } - else - { - DX::ThrowIfFailed(hr); - } + SDL_RenderPresent(m_sdlRenderer); } // Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 4f771947f..9d074245e 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -31,7 +31,8 @@ internal: void ResizeMainTexture(int w, int h); internal: - // Internal SDL rendeerer (likely a temporary addition, for refactoring purposes): + // Internal SDL renderer (likely a temporary addition, for refactoring purposes): + SDL_Renderer * m_sdlRenderer; D3D11_RenderData * m_sdlRendererData; protected private: diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 6bd7640db..6c9098847 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -220,7 +220,10 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) // for refactoring purposes. Initialize the SDL_Renderer // first in order to give it the opportunity to create key // resources first. + // + // TODO, WinRT: either make WINRT_CreateWindow not call SDL_CreateRenderer, or have it do error checking if it does call it SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); + SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer; SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; SDL_WinRTGlobalApp->m_renderer->Initialize(CoreWindow::GetForCurrentThread()); From e14a2fd8b6660de1af8dac6be5eda5999dee764a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 12:33:15 -0500 Subject: [PATCH 090/264] WinRT: use OS-native vsnprintf, which allows SDL_Log to format wide strings (via %ls) --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 12 ++++++------ include/SDL_config_windowsrt.h | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 53a3bb345..9e5306e39 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -410,7 +410,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console @@ -424,7 +424,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console @@ -438,7 +438,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console @@ -452,7 +452,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console @@ -466,7 +466,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console @@ -480,7 +480,7 @@ NotUsing false ..\..\include;%(AdditionalIncludeDirectories) - _WINDLL;%(PreprocessorDefinitions) + _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index c9af3fda1..98f01579e 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -117,6 +117,7 @@ typedef unsigned int uintptr_t; #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 From 31e3d85727c7e643f473fc609896c834c50e916b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 12:34:34 -0500 Subject: [PATCH 091/264] WinRT: made path retrieval functions return wide-char strings --- include/SDL_system.h | 6 ++--- src/core/windowsrt/SDL_winrtpaths.cpp | 37 ++++++++++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/SDL_system.h b/include/SDL_system.h index 0c5348f4b..9cc1ab80d 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -105,7 +105,7 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); which do not work on Windows Phone 8 (and will return NULL if called from this platform). */ -extern DECLSPEC const char * SDLCALL SDL_WinRTGetLocalFolderPath(); +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetLocalFolderPath(); /* Gets the path to the roaming app data store. Files and directories that should roam to different devices can be @@ -117,7 +117,7 @@ extern DECLSPEC const char * SDLCALL SDL_WinRTGetLocalFolderPath(); as Windows Phone 8 apps do not have an accessible roaming app data store. */ -extern DECLSPEC const char * SDLCALL SDL_WinRTGetRoamingFolderPath(); +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetRoamingFolderPath(); /* Gets the path to the temporary app data store. Files and directories may be written here, however they may be deleted @@ -127,7 +127,7 @@ extern DECLSPEC const char * SDLCALL SDL_WinRTGetRoamingFolderPath(); as Windows Phone 8 apps do not have an accessible temporary app data store. */ -extern DECLSPEC const char * SDLCALL SDL_WinRTGetTemporaryFolderPath(); +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetTemporaryFolderPath(); #endif /* __WINRT__ */ diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index fc33a86ed..40c05dc20 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -7,37 +7,56 @@ #ifdef __WINRT__ extern "C" { +#include "SDL_error.h" +#include "SDL_stdinc.h" #include "SDL_system.h" #include "../windows/SDL_windows.h" } using namespace Windows::Storage; -extern "C" const char * SDL_WinRTGetLocalFolderPath() +static const wchar_t * +WINRT_CopySystemPath(Windows::Storage::StorageFolder ^ folder) { - static const char * path = nullptr; + const wchar_t * srcPath = folder->Path->Data(); + const size_t srcPathLen = SDL_wcslen(srcPath); + wchar_t * destPath = (wchar_t *) SDL_calloc(srcPathLen + 1, sizeof(wchar_t)); + if (!destPath) { + SDL_OutOfMemory(); + return NULL; + } + SDL_wcslcpy(destPath, srcPath, srcPathLen + 1); + return destPath; +} + +extern "C" const wchar_t * +SDL_WinRTGetLocalFolderPath() +{ + static const wchar_t * path = nullptr; if (!path) { - path = WIN_StringToUTF8(ApplicationData::Current->LocalFolder->Path->Data()); + path = WINRT_CopySystemPath(ApplicationData::Current->LocalFolder); } return path; } -extern "C" const char * SDL_WinRTGetRoamingFolderPath() +extern "C" const wchar_t * +SDL_WinRTGetRoamingFolderPath() { // TODO, WinRT: make SDL_WinRTGetRoamingFolderPath return NULL on Windows Phone 8 - static const char * path = nullptr; + static const wchar_t * path = nullptr; if (!path) { - path = WIN_StringToUTF8(ApplicationData::Current->RoamingFolder->Path->Data()); + path = WINRT_CopySystemPath(ApplicationData::Current->RoamingFolder); } return path; } -extern "C" const char * SDL_WinRTGetTemporaryFolderPath() +extern "C" const wchar_t * +SDL_WinRTGetTemporaryFolderPath() { // TODO, WinRT: make SDL_WinRTGetTemporaryFolderPath return NULL on Windows Phone 8 - static const char * path = nullptr; + static const wchar_t * path = nullptr; if (!path) { - path = WIN_StringToUTF8(ApplicationData::Current->TemporaryFolder->Path->Data()); + path = WINRT_CopySystemPath(ApplicationData::Current->TemporaryFolder); } return path; } From 1be3dc951269cb884f6bb085417985b6650b7d90 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 12:38:55 -0500 Subject: [PATCH 092/264] WinRT: made path retrieval functions return NULL on Windows Phone whenever said data isn't available --- src/core/windowsrt/SDL_winrtpaths.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index 40c05dc20..01f3c371a 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -42,23 +42,31 @@ SDL_WinRTGetLocalFolderPath() extern "C" const wchar_t * SDL_WinRTGetRoamingFolderPath() { - // TODO, WinRT: make SDL_WinRTGetRoamingFolderPath return NULL on Windows Phone 8 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + SDL_Unsupported(); + return NULL; +#else static const wchar_t * path = nullptr; if (!path) { path = WINRT_CopySystemPath(ApplicationData::Current->RoamingFolder); } return path; +#endif } extern "C" const wchar_t * SDL_WinRTGetTemporaryFolderPath() { - // TODO, WinRT: make SDL_WinRTGetTemporaryFolderPath return NULL on Windows Phone 8 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + SDL_Unsupported(); + return NULL; +#else static const wchar_t * path = nullptr; if (!path) { path = WINRT_CopySystemPath(ApplicationData::Current->TemporaryFolder); } return path; +#endif } #endif /* __WINRT__ */ From e3d03f99fd0fe5c57ab2bd18dc316b9c8f02608e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 12:49:12 -0500 Subject: [PATCH 093/264] WinRT: added a function to retrieve the root path to the installed app --- include/SDL_system.h | 6 ++++++ src/core/windowsrt/SDL_winrtpaths.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/SDL_system.h b/include/SDL_system.h index 9cc1ab80d..b7de4ab8a 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -96,6 +96,12 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); /* Platform specific functions for Windows RT */ #if defined(__WINRT__) && __WINRT__ +/* Gets the path to the installed app's root directory. + + This function may be used safely on Windows Phone 8. +*/ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetInstalledLocationPath(); + /* Gets the path to the local app data store. Files and directories that should be limited to the local device can be created in this path. diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index 01f3c371a..19ed1d303 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -29,6 +29,16 @@ WINRT_CopySystemPath(Windows::Storage::StorageFolder ^ folder) return destPath; } +extern "C" const wchar_t * +SDL_WinRTGetInstalledLocationPath() +{ + static const wchar_t * path = nullptr; + if (!path) { + path = WINRT_CopySystemPath(Windows::ApplicationModel::Package::Current->InstalledLocation); + } + return path; +} + extern "C" const wchar_t * SDL_WinRTGetLocalFolderPath() { From ce927b6d43fb715496209d85d410d5db020d3c17 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 13:18:31 -0500 Subject: [PATCH 094/264] WinRT: fixed an odd path retrieval bug --- src/core/windowsrt/SDL_winrtpaths.cpp | 49 +++++++++++---------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index 19ed1d303..1c5fb312b 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -13,40 +13,29 @@ extern "C" { #include "../windows/SDL_windows.h" } -using namespace Windows::Storage; +#include -static const wchar_t * -WINRT_CopySystemPath(Windows::Storage::StorageFolder ^ folder) -{ - const wchar_t * srcPath = folder->Path->Data(); - const size_t srcPathLen = SDL_wcslen(srcPath); - wchar_t * destPath = (wchar_t *) SDL_calloc(srcPathLen + 1, sizeof(wchar_t)); - if (!destPath) { - SDL_OutOfMemory(); - return NULL; - } - SDL_wcslcpy(destPath, srcPath, srcPathLen + 1); - return destPath; -} +using namespace std; +using namespace Windows::Storage; extern "C" const wchar_t * SDL_WinRTGetInstalledLocationPath() { - static const wchar_t * path = nullptr; - if (!path) { - path = WINRT_CopySystemPath(Windows::ApplicationModel::Package::Current->InstalledLocation); + static wstring path; + if (path.empty()) { + path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); } - return path; + return path.c_str(); } extern "C" const wchar_t * SDL_WinRTGetLocalFolderPath() { - static const wchar_t * path = nullptr; - if (!path) { - path = WINRT_CopySystemPath(ApplicationData::Current->LocalFolder); + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->LocalFolder->Path->Data(); } - return path; + return path.c_str(); } extern "C" const wchar_t * @@ -56,11 +45,11 @@ SDL_WinRTGetRoamingFolderPath() SDL_Unsupported(); return NULL; #else - static const wchar_t * path = nullptr; - if (!path) { - path = WINRT_CopySystemPath(ApplicationData::Current->RoamingFolder); + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->RoamingFolder->Path->Data(); } - return path; + return path.c_str(); #endif } @@ -71,11 +60,11 @@ SDL_WinRTGetTemporaryFolderPath() SDL_Unsupported(); return NULL; #else - static const wchar_t * path = nullptr; - if (!path) { - path = WINRT_CopySystemPath(ApplicationData::Current->TemporaryFolder); + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->TemporaryFolder->Path->Data(); } - return path; + return path.c_str(); #endif } From 8885ad92d2a5484a79b703651e97b1e3c36f7f3b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 18:56:11 -0500 Subject: [PATCH 095/264] WinRT: made renderer init code be synchronous for now, in order to make error handling be a bit easier in the near future --- src/video/windowsrt/SDL_winrtrenderer.cpp | 222 +++++++++++++--------- 1 file changed, 133 insertions(+), 89 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 750473a04..af1157fc5 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -1,8 +1,13 @@ -#include "SDLmain_WinRT_common.h" + +#include +#include +#include +#include "SDLmain_WinRT_common.h" #include "SDL_winrtrenderer.h" using namespace DirectX; using namespace Microsoft::WRL; +using namespace std; using namespace Windows::UI::Core; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; @@ -47,6 +52,34 @@ void SDL_winrtrenderer::HandleDeviceLost() UpdateForWindowSizeChange(); } +static bool +read_file_contents(const wstring & fileName, vector & 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 +read_shader_contents(const wstring & shaderName, vector & out) +{ + wstring fileName = SDL_WinRTGetInstalledLocationPath(); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + fileName += L"\\"; +#else + fileName += L"\\SDL_VS2012_WinRT\\"; +#endif + fileName += shaderName; + return read_file_contents(fileName, out); +} + // These are the resources that depend on the device. void SDL_winrtrenderer::CreateDeviceResources() { @@ -102,103 +135,114 @@ void SDL_winrtrenderer::CreateDeviceResources() context.As(&m_sdlRendererData->d3dContext) ); -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso"); - auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso"); -#else - auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso"); - auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimplePixelShader.cso"); -#endif + // Start loading GPU shaders: + vector fileData; - auto createVSTask = loadVSTask.then([this](Platform::Array^ fileData) { - DX::ThrowIfFailed( - (m_sdlRendererData->d3dDevice)->CreateVertexShader( - fileData->Data, - fileData->Length, - nullptr, - &m_sdlRendererData->vertexShader - ) - ); + // + // Load in SDL's one and only vertex shader: + // + if (!read_shader_contents(L"SimpleVertexShader.cso", fileData)) { + throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's vertex shader file."); + } - 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 }, - }; + DX::ThrowIfFailed( + (m_sdlRendererData->d3dDevice)->CreateVertexShader( + &fileData[0], + fileData.size(), + nullptr, + &m_sdlRendererData->vertexShader + ) + ); - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateInputLayout( - vertexDesc, - ARRAYSIZE(vertexDesc), - fileData->Data, - fileData->Length, - &m_sdlRendererData->inputLayout - ) - ); - }); + // + // 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 }, + }; - auto createPSTask = loadPSTask.then([this](Platform::Array^ fileData) { - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreatePixelShader( - fileData->Data, - fileData->Length, - nullptr, - &m_sdlRendererData->pixelShader - ) - ); - }); + DX::ThrowIfFailed( + m_sdlRendererData->d3dDevice->CreateInputLayout( + vertexDesc, + ARRAYSIZE(vertexDesc), + &fileData[0], + fileData.size(), + &m_sdlRendererData->inputLayout + ) + ); - auto createVertexBuffer = (createPSTask && createVSTask).then([this] () { - VertexPositionColor vertices[] = - { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - }; + // + // Load in SDL's one and only pixel shader (for now, more are likely to follow): + // + if (!read_shader_contents(L"SimplePixelShader.cso", fileData)) { + throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's pixel shader file."); + } - m_vertexCount = ARRAYSIZE(vertices); + DX::ThrowIfFailed( + m_sdlRendererData->d3dDevice->CreatePixelShader( + &fileData[0], + fileData.size(), + nullptr, + &m_sdlRendererData->pixelShader + ) + ); - D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = vertices; - vertexBufferData.SysMemPitch = 0; - vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateBuffer( - &vertexBufferDesc, - &vertexBufferData, - &m_sdlRendererData->vertexBuffer - ) - ); - }); + // + // Create a vertex buffer: + // + VertexPositionColor vertices[] = + { + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + }; - auto createMainSamplerTask = createVertexBuffer.then([this] () { - 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; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateSamplerState( - &samplerDesc, - &m_sdlRendererData->mainSampler - ) - ); - }); + m_vertexCount = ARRAYSIZE(vertices); - createMainSamplerTask.then([this] () { - m_loadingComplete = true; - }); + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; + vertexBufferData.pSysMem = vertices; + vertexBufferData.SysMemPitch = 0; + vertexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); + DX::ThrowIfFailed( + m_sdlRendererData->d3dDevice->CreateBuffer( + &vertexBufferDesc, + &vertexBufferData, + &m_sdlRendererData->vertexBuffer + ) + ); + + // + // 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; + DX::ThrowIfFailed( + m_sdlRendererData->d3dDevice->CreateSamplerState( + &samplerDesc, + &m_sdlRendererData->mainSampler + ) + ); + + // + // All done! + // + m_loadingComplete = true; // This variable can probably be factored-out } // Allocate all memory resources that change on a window SizeChanged event. From 47036f380fff8c3444077b3df2195dfe08743014 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 3 Feb 2013 18:56:52 -0500 Subject: [PATCH 096/264] WinRT: removed some now-unnecessary file loading code --- src/video/windowsrt/DirectXHelper.h | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/video/windowsrt/DirectXHelper.h b/src/video/windowsrt/DirectXHelper.h index cc8078b42..fc6e820f8 100644 --- a/src/video/windowsrt/DirectXHelper.h +++ b/src/video/windowsrt/DirectXHelper.h @@ -14,28 +14,4 @@ namespace DX throw Platform::Exception::CreateException(hr); } } - - // Function that reads from a binary file asynchronously. - inline Concurrency::task^> ReadDataAsync(Platform::String^ filename) - { - using namespace Windows::Storage; - using namespace Concurrency; - - auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation; - - return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file) - { - return file->OpenReadAsync(); - }).then([] (Streams::IRandomAccessStreamWithContentType^ stream) - { - unsigned int bufferSize = static_cast(stream->Size); - auto fileBuffer = ref new Streams::Buffer(bufferSize); - return stream->ReadAsync(fileBuffer, bufferSize, Streams::InputStreamOptions::None); - }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array^ - { - auto fileData = ref new Platform::Array(fileBuffer->Length); - Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(fileData); - return fileData; - }); - } } From 7eee7ec08fca187480fcaaf0069479348a5cdd2f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 10:43:20 -0500 Subject: [PATCH 097/264] WinRT: Windows Phone build fixes --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index c7156be8f..f2850a547 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -275,16 +275,12 @@ true true true - true - true true true true true - true - true @@ -358,48 +354,36 @@ true true true - true - true true true true true - true - true true true true true - true - true true true true true - true - true true true true true - true - true true true true true - true - true From 0bc7f7eac89e3f53b3086d16f01854bf1b894dc7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 11:42:17 -0500 Subject: [PATCH 098/264] WinRT: more code-moving from SDL_winrtrenderer* to SDL_render_d3d11* --- src/render/direct3d11/SDL_render_d3d11.cpp | 236 ++++++++++++++++++- src/render/direct3d11/SDL_render_d3d11_cpp.h | 10 + src/video/windowsrt/SDL_winrtrenderer.cpp | 193 +-------------- src/video/windowsrt/SDL_winrtrenderer.h | 8 - 4 files changed, 247 insertions(+), 200 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 6914f837b..f8fb349bc 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -27,14 +27,23 @@ 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 "stdio.h" } +#include +#include +#include + #include "SDL_render_d3d11_cpp.h" -/* Direct3D renderer implementation */ +using namespace DirectX; +using namespace Microsoft::WRL; +using namespace std; + +/* Direct3D 11.1 renderer implementation */ static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags); //static void D3D11_WindowEvent(SDL_Renderer * renderer, @@ -67,6 +76,9 @@ static void D3D11_RenderPresent(SDL_Renderer * renderer); // SDL_Texture * texture); //static void D3D11_DestroyRenderer(SDL_Renderer * renderer); +/* Direct3D 11.1 Internal Functions */ +HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer); + extern "C" { SDL_RenderDriver D3D11_RenderDriver = { @@ -114,10 +126,12 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data = new D3D11_RenderData; // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules if (!data) { - delete data; SDL_OutOfMemory(); return NULL; } + data->featureLevel = (D3D_FEATURE_LEVEL) 0; + data->vertexCount = 0; + data->loadingComplete = false; // TODO: Create Direct3D Object(s) @@ -280,6 +294,224 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) return renderer; } +static bool +D3D11_ReadFileContents(const wstring & fileName, vector & 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 & out) +{ + wstring fileName; + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + fileName = SDL_WinRTGetInstalledLocationPath(); + fileName += L"\\SDL_VS2012_WinRT\\"; +#elif WINAPI_FAMILY == WINAPI_PHONE_APP + fileName = SDL_WinRTGetInstalledLocationPath(); + fileName += L"\\"; +#endif + // WinRT, TODO: test Direct3D 11.1 shader loading on Win32 + fileName += shaderName; + return D3D11_ReadFileContents(fileName, out); +} + +HRESULT +WINRT_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 device; + ComPtr 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 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; + } + + // Start loading GPU shaders: + vector fileData; + + // + // Load in SDL's one and only vertex shader: + // + if (!D3D11_ReadShaderContents(L"SimpleVertexShader.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 }, + }; + + 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 one and only pixel shader (for now, more are likely to follow): + // + if (!D3D11_ReadShaderContents(L"SimplePixelShader.cso", fileData)) { + SDL_SetError("Unable to open SDL's pixel shader file."); + return E_FAIL; + } + + result = data->d3dDevice->CreatePixelShader( + &fileData[0], + fileData.size(), + nullptr, + &data->pixelShader + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + // + // Create a vertex buffer: + // + VertexPositionColor vertices[] = + { + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + }; + + data->vertexCount = ARRAYSIZE(vertices); + + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; + vertexBufferData.pSysMem = vertices; + vertexBufferData.SysMemPitch = 0; + vertexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); + result = data->d3dDevice->CreateBuffer( + &vertexBufferDesc, + &vertexBufferData, + &data->vertexBuffer + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + // + // 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; + } + + // + // All done! + // + data->loadingComplete = true; // This variable can probably be factored-out + return S_OK; +} + static int D3D11_UpdateViewport(SDL_Renderer * renderer) { diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 3ec4998f0..936c58579 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -21,6 +21,7 @@ #include "SDL_config.h" #include +#include #include typedef struct @@ -36,10 +37,19 @@ typedef struct Microsoft::WRL::ComPtr mainTexture; Microsoft::WRL::ComPtr mainTextureResourceView; Microsoft::WRL::ComPtr mainSampler; + D3D_FEATURE_LEVEL featureLevel; + unsigned int vertexCount; + bool loadingComplete; } D3D11_RenderData; typedef struct { } D3D11_TextureData; +struct VertexPositionColor +{ + DirectX::XMFLOAT3 pos; + DirectX::XMFLOAT2 tex; +}; + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index af1157fc5..04d296632 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -15,8 +15,6 @@ using namespace Windows::Graphics::Display; // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), - m_loadingComplete(false), - m_vertexCount(0), m_sdlRenderer(NULL), m_sdlRendererData(NULL) { @@ -52,197 +50,12 @@ void SDL_winrtrenderer::HandleDeviceLost() UpdateForWindowSizeChange(); } -static bool -read_file_contents(const wstring & fileName, vector & 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 -read_shader_contents(const wstring & shaderName, vector & out) -{ - wstring fileName = SDL_WinRTGetInstalledLocationPath(); -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - fileName += L"\\"; -#else - fileName += L"\\SDL_VS2012_WinRT\\"; -#endif - fileName += shaderName; - return read_file_contents(fileName, out); -} +extern HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer); // These are the resources that depend on the device. void SDL_winrtrenderer::CreateDeviceResources() { - // 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 device; - ComPtr context; - DX::ThrowIfFailed( - 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. - &m_featureLevel, // Returns feature level of device created. - &context // Returns the device immediate context. - ) - ); - - // Get the Direct3D 11.1 API device and context interfaces. - Microsoft::WRL::ComPtr d3dDevice1; - DX::ThrowIfFailed( - device.As(&(m_sdlRendererData->d3dDevice)) - ); - - DX::ThrowIfFailed( - context.As(&m_sdlRendererData->d3dContext) - ); - - // Start loading GPU shaders: - vector fileData; - - // - // Load in SDL's one and only vertex shader: - // - if (!read_shader_contents(L"SimpleVertexShader.cso", fileData)) { - throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's vertex shader file."); - } - - DX::ThrowIfFailed( - (m_sdlRendererData->d3dDevice)->CreateVertexShader( - &fileData[0], - fileData.size(), - nullptr, - &m_sdlRendererData->vertexShader - ) - ); - - // - // 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 }, - }; - - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateInputLayout( - vertexDesc, - ARRAYSIZE(vertexDesc), - &fileData[0], - fileData.size(), - &m_sdlRendererData->inputLayout - ) - ); - - // - // Load in SDL's one and only pixel shader (for now, more are likely to follow): - // - if (!read_shader_contents(L"SimplePixelShader.cso", fileData)) { - throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's pixel shader file."); - } - - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreatePixelShader( - &fileData[0], - fileData.size(), - nullptr, - &m_sdlRendererData->pixelShader - ) - ); - - // - // Create a vertex buffer: - // - VertexPositionColor vertices[] = - { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - }; - - m_vertexCount = ARRAYSIZE(vertices); - - D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = vertices; - vertexBufferData.SysMemPitch = 0; - vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateBuffer( - &vertexBufferDesc, - &vertexBufferData, - &m_sdlRendererData->vertexBuffer - ) - ); - - // - // 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; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateSamplerState( - &samplerDesc, - &m_sdlRendererData->mainSampler - ) - ); - - // - // All done! - // - m_loadingComplete = true; // This variable can probably be factored-out + DX::ThrowIfFailed(WINRT_CreateDeviceResources(m_sdlRenderer)); } // Allocate all memory resources that change on a window SizeChanged event. @@ -531,7 +344,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr ); // Only draw the screen once it is loaded (some loading is asynchronous). - if (!m_loadingComplete) + if (!m_sdlRendererData->loadingComplete) { return; } diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 9d074245e..e347d7aca 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -4,12 +4,6 @@ #include "SDL.h" #include "../../render/direct3d11/SDL_render_d3d11_cpp.h" -struct VertexPositionColor -{ - DirectX::XMFLOAT3 pos; - DirectX::XMFLOAT2 tex; -}; - // Helper class that initializes DirectX APIs for 3D rendering. ref class SDL_winrtrenderer { @@ -40,12 +34,10 @@ protected private: SDL_Surface * m_mainTextureHelperSurface; // Cached renderer properties. - D3D_FEATURE_LEVEL m_featureLevel; Windows::Foundation::Size m_renderTargetSize; Windows::Foundation::Rect m_windowBounds; Platform::Agile m_window; Windows::Graphics::Display::DisplayOrientations m_orientation; - uint32 m_vertexCount; // Transform used for display orientation. DirectX::XMFLOAT4X4 m_orientationTransform3D; From 4b6b1755fe045e2e42862246ea870bc0f3d10a83 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 14:35:06 -0500 Subject: [PATCH 099/264] WinRT: provided access, via SDL_GetWindowWMInfo, to SDL's WinRT CoreWindow --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 7 ++- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 9 +++- include/SDL_syswm.h | 7 +++ src/video/windowsrt/SDL_winrtvideo.cpp | 45 +++++++++++++++++-- src/video/windowsrt/SDL_winrtvideo.h | 7 +-- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index f2850a547..4ddc0a112 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -299,7 +299,12 @@ - + + true + true + true + true + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 9e5306e39..c5a803fbc 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -78,7 +78,14 @@ - + + true + true + true + true + true + true + diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index a96f42e2d..69a08e19e 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -103,6 +103,7 @@ typedef enum { SDL_SYSWM_UNKNOWN, SDL_SYSWM_WINDOWS, + SDL_SYSWM_WINDOWSRT, SDL_SYSWM_X11, SDL_SYSWM_DIRECTFB, SDL_SYSWM_COCOA, @@ -171,6 +172,12 @@ struct SDL_SysWMinfo HWND window; /**< The window handle */ } win; #endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + struct + { + void * window; /**< The Windows RT CoreWindow, casted from 'CoreWindow ^*' to 'void *' */ + } winrt; +#endif #if defined(SDL_VIDEO_DRIVER_X11) struct { diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 6c9098847..fb067f843 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -35,6 +35,7 @@ extern "C" { #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" #include "../../render/SDL_sysrender.h" +#include "SDL_syswm.h" } #include "SDL_WinRTApp.h" @@ -61,6 +62,7 @@ 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 */ @@ -101,6 +103,7 @@ WINRT_CreateDevice(int devindex) device->CreateWindowFramebuffer = SDL_WINRT_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer; device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer; + device->GetWindowWMInfo = WINRT_GetWindowWMInfo; device->free = WINRT_DeleteDevice; @@ -159,14 +162,13 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) return -1; } - SDL_WindowData *data; - data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + SDL_WindowData *data = new SDL_WindowData; if (!data) { SDL_OutOfMemory(); return -1; } - SDL_zerop(data); data->sdlWindow = window; + data->coreWindow = new CoreWindow^(CoreWindow::GetForCurrentThread()); /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. @@ -222,6 +224,11 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) // resources first. // // TODO, WinRT: either make WINRT_CreateWindow not call SDL_CreateRenderer, or have it do error checking if it does call it + + // HACK: make sure the SDL window references SDL_WindowData data now, in + // order to allow the SDL_Renderer to be created in WINRT_CreateWindow + window->driverdata = data; + SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer; SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; @@ -234,6 +241,21 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) void WINRT_DestroyWindow(_THIS, SDL_Window * window) { + SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + + if (data) { + // Delete the reference to the WinRT CoreWindow: + CoreWindow ^* windowPointer = ((SDL_WindowData *) window->driverdata)->coreWindow; + if (windowPointer) { + *windowPointer = nullptr; // Clear the C++/CX reference to the CoreWindow + delete windowPointer; // Delete the C++/CX reference itself + } + + // Delete the internal window data: + delete data; + data = NULL; + } + if (SDL_WinRTGlobalApp->HasSDLWindowData() && SDL_WinRTGlobalApp->GetSDLWindowData()->sdlWindow == window) { @@ -241,6 +263,23 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) } } +SDL_bool +WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + CoreWindow ^* windowPointer = data->coreWindow; + + if (info->version.major <= SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_WINDOWSRT; + info->info.winrt.window = windowPointer; + 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 */ diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h index fe8063f53..83eb78733 100644 --- a/src/video/windowsrt/SDL_winrtvideo.h +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -23,19 +23,14 @@ #ifndef _SDL_winrtvideo_h #define _SDL_winrtvideo_h -#ifdef __cplusplus extern "C" { -#endif - #include "../SDL_sysvideo.h" - -#ifdef __cplusplus } -#endif struct SDL_WindowData { SDL_Window *sdlWindow; + Windows::UI::Core::CoreWindow ^* coreWindow; }; #endif /* _SDL_winrtvideo_h */ From 9df73a8ba11406a4ee081df3780751e3c240282c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 14:56:32 -0500 Subject: [PATCH 100/264] WinRT: more work on moving rendering code from SDL_winrtrenderer.* to SDL_render_d3d11* --- src/render/direct3d11/SDL_render_d3d11.cpp | 269 ++++++++++++++++++- src/render/direct3d11/SDL_render_d3d11_cpp.h | 8 + src/video/windowsrt/SDL_winrtrenderer.cpp | 220 ++------------- src/video/windowsrt/SDL_winrtrenderer.h | 20 +- src/video/windowsrt/SDL_winrtvideo.cpp | 2 +- 5 files changed, 300 insertions(+), 219 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index f8fb349bc..8fb436143 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -43,6 +43,11 @@ 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); @@ -77,7 +82,7 @@ static void D3D11_RenderPresent(SDL_Renderer * renderer); //static void D3D11_DestroyRenderer(SDL_Renderer * renderer); /* Direct3D 11.1 Internal Functions */ -HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer); +HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); extern "C" { @@ -132,6 +137,8 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data->featureLevel = (D3D_FEATURE_LEVEL) 0; data->vertexCount = 0; data->loadingComplete = false; + data->windowSizeInDIPs = XMFLOAT2(0, 0); + data->renderTargetSize = XMFLOAT2(0, 0); // TODO: Create Direct3D Object(s) @@ -327,7 +334,7 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) } HRESULT -WINRT_CreateDeviceResources(SDL_Renderer * renderer) +D3D11_CreateDeviceResources(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; @@ -512,6 +519,264 @@ WINRT_CreateDeviceResources(SDL_Renderer * renderer) return S_OK; } +#ifdef __WINRT__ + +CoreWindow ^ +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; + } + + CoreWindow ^* coreWindowPointer = (CoreWindow ^*) sdlWindowInfo.info.winrt.window; + if ( ! coreWindowPointer ) { + return nullptr; + } + + return *coreWindowPointer; +} + +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 + +// 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; + Windows::UI::Core::CoreWindow ^ 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. + data->windowSizeInDIPs.x = coreWindow->Bounds.Width; + data->windowSizeInDIPs.y = coreWindow->Bounds.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; + 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(data->renderTargetSize.x), + static_cast(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(data->renderTargetSize.x); // Match the size of the window. + swapChainDesc.Height = static_cast(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 dxgiDevice; + result = data->d3dDevice.As(&dxgiDevice); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + ComPtr dxgiAdapter; + result = dxgiDevice->GetAdapter(&dxgiAdapter); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + ComPtr dxgiFactory; + result = dxgiAdapter->GetParent( + __uuidof(IDXGIFactory2), + &dxgiFactory + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + result = dxgiFactory->CreateSwapChainForCoreWindow( + data->d3dDevice.Get(), + reinterpret_cast(coreWindow), + &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; + data->orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE270; + data->orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE180; + data->orientationTransform3D = 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: + rotation = DXGI_MODE_ROTATION_ROTATE90; + data->orientationTransform3D = 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: + 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 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->renderTargetView + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + // Create a depth stencil view. + CD3D11_TEXTURE2D_DESC depthStencilDesc( + DXGI_FORMAT_D24_UNORM_S8_UINT, + static_cast(data->renderTargetSize.x), + static_cast(data->renderTargetSize.y), + 1, + 1, + D3D11_BIND_DEPTH_STENCIL + ); + + ComPtr depthStencil; + result = data->d3dDevice->CreateTexture2D( + &depthStencilDesc, + nullptr, + &depthStencil + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + // Set the rendering viewport to target the entire window. + CD3D11_VIEWPORT viewport( + 0.0f, + 0.0f, + data->renderTargetSize.x, + data->renderTargetSize.y + ); + + data->d3dContext->RSSetViewports(1, &viewport); + + return S_OK; +} + static int D3D11_UpdateViewport(SDL_Renderer * renderer) { diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 936c58579..644b8bd17 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -40,6 +40,14 @@ typedef struct D3D_FEATURE_LEVEL featureLevel; unsigned int vertexCount; bool loadingComplete; + + // 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 diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index 04d296632..f734771af 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -5,6 +5,10 @@ #include "SDLmain_WinRT_common.h" #include "SDL_winrtrenderer.h" +extern "C" { +#include "SDL_syswm.h" +} + using namespace DirectX; using namespace Microsoft::WRL; using namespace std; @@ -12,6 +16,10 @@ using namespace Windows::UI::Core; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; +extern HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); +extern CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer); +extern HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); + // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), @@ -29,10 +37,8 @@ SDL_winrtrenderer::~SDL_winrtrenderer() } // Initialize the Direct3D resources required to run. -void SDL_winrtrenderer::Initialize(CoreWindow^ window) -{ - m_window = window; - +void SDL_winrtrenderer::Initialize() +{ CreateDeviceResources(); CreateWindowSizeDependentResources(); } @@ -41,8 +47,8 @@ void SDL_winrtrenderer::Initialize(CoreWindow^ window) void SDL_winrtrenderer::HandleDeviceLost() { // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. - m_windowBounds.Width = 0; - m_windowBounds.Height = 0; + m_sdlRendererData->windowSizeInDIPs.x = 0; + m_sdlRendererData->windowSizeInDIPs.y = 0; m_sdlRendererData->swapChain = nullptr; // TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer @@ -50,207 +56,16 @@ void SDL_winrtrenderer::HandleDeviceLost() UpdateForWindowSizeChange(); } -extern HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer); - // These are the resources that depend on the device. void SDL_winrtrenderer::CreateDeviceResources() { - DX::ThrowIfFailed(WINRT_CreateDeviceResources(m_sdlRenderer)); + DX::ThrowIfFailed(D3D11_CreateDeviceResources(m_sdlRenderer)); } // Allocate all memory resources that change on a window SizeChanged event. void SDL_winrtrenderer::CreateWindowSizeDependentResources() { - // Store the window bounds so the next time we get a SizeChanged event we can - // avoid rebuilding everything if the size is identical. - m_windowBounds = m_window->Bounds; - - // Calculate the necessary swap chain and render target size in pixels. - float windowWidth = ConvertDipsToPixels(m_windowBounds.Width); - float windowHeight = ConvertDipsToPixels(m_windowBounds.Height); - - // 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. - m_orientation = DisplayProperties::CurrentOrientation; - bool swapDimensions = - m_orientation == DisplayOrientations::Portrait || - m_orientation == DisplayOrientations::PortraitFlipped; - m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth; - m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight; - - if(m_sdlRendererData->swapChain != nullptr) - { - // If the swap chain already exists, resize it. - DX::ThrowIfFailed( - m_sdlRendererData->swapChain->ResizeBuffers( - 2, // Double-buffered swap chain. - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - DXGI_FORMAT_B8G8R8A8_UNORM, - 0 - ) - ); - } - 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(m_renderTargetSize.Width); // Match the size of the window. - swapChainDesc.Height = static_cast(m_renderTargetSize.Height); - 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 dxgiDevice; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice.As(&dxgiDevice) - ); - - ComPtr dxgiAdapter; - DX::ThrowIfFailed( - dxgiDevice->GetAdapter(&dxgiAdapter) - ); - - ComPtr dxgiFactory; - DX::ThrowIfFailed( - dxgiAdapter->GetParent( - __uuidof(IDXGIFactory2), - &dxgiFactory - ) - ); - - Windows::UI::Core::CoreWindow^ window = m_window.Get(); - DX::ThrowIfFailed( - dxgiFactory->CreateSwapChainForCoreWindow( - m_sdlRendererData->d3dDevice.Get(), - reinterpret_cast(window), - &swapChainDesc, - nullptr, // Allow on all displays. - &m_sdlRendererData->swapChain - ) - ); - - // 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. - DX::ThrowIfFailed( - dxgiDevice->SetMaximumFrameLatency(1) - ); - } - - // 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 (m_orientation) - { - case DisplayOrientations::Landscape: - rotation = DXGI_MODE_ROTATION_IDENTITY; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE270; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE180; - m_orientationTransform3D = 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: - rotation = DXGI_MODE_ROTATION_ROTATE90; - m_orientationTransform3D = 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: - 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. - DX::ThrowIfFailed( - m_sdlRendererData->swapChain->SetRotation(rotation) - ); -#endif - - // Create a render target view of the swap chain back buffer. - ComPtr backBuffer; - DX::ThrowIfFailed( - m_sdlRendererData->swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ) - ); - - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateRenderTargetView( - backBuffer.Get(), - nullptr, - &m_sdlRendererData->renderTargetView - ) - ); - - // Create a depth stencil view. - CD3D11_TEXTURE2D_DESC depthStencilDesc( - DXGI_FORMAT_D24_UNORM_S8_UINT, - static_cast(m_renderTargetSize.Width), - static_cast(m_renderTargetSize.Height), - 1, - 1, - D3D11_BIND_DEPTH_STENCIL - ); - - ComPtr depthStencil; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateTexture2D( - &depthStencilDesc, - nullptr, - &depthStencil - ) - ); - - // Set the rendering viewport to target the entire window. - CD3D11_VIEWPORT viewport( - 0.0f, - 0.0f, - m_renderTargetSize.Width, - m_renderTargetSize.Height - ); - - m_sdlRendererData->d3dContext->RSSetViewports(1, &viewport); + DX::ThrowIfFailed(D3D11_CreateWindowSizeDependentResources(m_sdlRenderer)); } void SDL_winrtrenderer::ResizeMainTexture(int w, int h) @@ -323,9 +138,10 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) // This method is called in the event handler for the SizeChanged event. void SDL_winrtrenderer::UpdateForWindowSizeChange() { - if (m_window->Bounds.Width != m_windowBounds.Width || - m_window->Bounds.Height != m_windowBounds.Height || - m_orientation != DisplayProperties::CurrentOrientation) + CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(m_sdlRenderer); + if (coreWindow->Bounds.Width != m_sdlRendererData->windowSizeInDIPs.x || + coreWindow->Bounds.Height != m_sdlRendererData->windowSizeInDIPs.y || + m_sdlRendererData->orientation != DisplayProperties::CurrentOrientation) { ID3D11RenderTargetView* nullViews[] = {nullptr}; m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index e347d7aca..9fde42517 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -1,9 +1,13 @@ #pragma once #include "DirectXHelper.h" -#include "SDL.h" #include "../../render/direct3d11/SDL_render_d3d11_cpp.h" +extern "C" { +#include "SDL.h" +#include "../../render/SDL_sysrender.h" +} + // Helper class that initializes DirectX APIs for 3D rendering. ref class SDL_winrtrenderer { @@ -12,7 +16,7 @@ internal: public: virtual ~SDL_winrtrenderer(); - virtual void Initialize(Windows::UI::Core::CoreWindow^ window); + virtual void Initialize(); virtual void HandleDeviceLost(); virtual void CreateDeviceResources(); virtual void CreateWindowSizeDependentResources(); @@ -32,16 +36,4 @@ internal: protected private: // UpdateWindowSurface helper objects SDL_Surface * m_mainTextureHelperSurface; - - // Cached renderer properties. - Windows::Foundation::Size m_renderTargetSize; - Windows::Foundation::Rect m_windowBounds; - Platform::Agile m_window; - Windows::Graphics::Display::DisplayOrientations m_orientation; - - // Transform used for display orientation. - DirectX::XMFLOAT4X4 m_orientationTransform3D; - - // Has the renderer finished loading? - bool m_loadingComplete; }; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index fb067f843..596bd9966 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -232,7 +232,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer; SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; - SDL_WinRTGlobalApp->m_renderer->Initialize(CoreWindow::GetForCurrentThread()); + SDL_WinRTGlobalApp->m_renderer->Initialize(); /* All done! */ return 0; From 587165bdd606df174fef64a49e383906b3b00087 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 15:22:49 -0500 Subject: [PATCH 101/264] WinRT: made the Direct3D 11.1 renderer directly initialize more of itself, rather than deferring to code in the WinRT video driver --- src/render/direct3d11/SDL_render_d3d11.cpp | 174 +++------------------ src/video/windowsrt/SDL_winrtrenderer.cpp | 7 - src/video/windowsrt/SDL_winrtrenderer.h | 1 - src/video/windowsrt/SDL_winrtvideo.cpp | 2 +- 4 files changed, 27 insertions(+), 157 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 8fb436143..63dbfe00b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -79,11 +79,11 @@ static int D3D11_UpdateViewport(SDL_Renderer * renderer); static void D3D11_RenderPresent(SDL_Renderer * renderer); //static void D3D11_DestroyTexture(SDL_Renderer * renderer, // SDL_Texture * texture); -//static void D3D11_DestroyRenderer(SDL_Renderer * renderer); +static void D3D11_DestroyRenderer(SDL_Renderer * renderer); /* Direct3D 11.1 Internal Functions */ HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); - +HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); extern "C" { SDL_RenderDriver D3D11_RenderDriver = { @@ -110,17 +110,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; D3D11_RenderData *data; -// SDL_SysWMinfo windowinfo; - // HRESULT result; - // D3DPRESENT_PARAMETERS pparams; - // IDirect3DSwapChain9 *chain; - // D3DCAPS9 caps; - // Uint32 window_flags; - // int w, h; - // SDL_DisplayMode fullscreen_mode; - // D3DMATRIX matrix; - // int d3dxVersion; - //char d3dxDLLFile[50]; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { @@ -158,149 +147,38 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) //renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; //renderer->DestroyTexture = D3D11_DestroyTexture; - //renderer->DestroyRenderer = D3D11_DestroyRenderer; + renderer->DestroyRenderer = D3D11_DestroyRenderer; renderer->info = D3D11_RenderDriver.info; + renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->driverdata = data; - renderer->info.flags = SDL_RENDERER_ACCELERATED; + // 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; - //SDL_VERSION(&windowinfo.version); - //SDL_GetWindowWMInfo(window, &windowinfo); - - //window_flags = SDL_GetWindowFlags(window); - //SDL_GetWindowSize(window, &w, &h); - //SDL_GetWindowDisplayMode(window, &fullscreen_mode); - - //SDL_zero(pparams); - //pparams.hDeviceWindow = windowinfo.info.win.window; - //pparams.BackBufferWidth = w; - //pparams.BackBufferHeight = h; - //if (window_flags & SDL_WINDOW_FULLSCREEN) { - // pparams.BackBufferFormat = - // PixelFormatToD3DFMT(fullscreen_mode.format); - //} else { - // pparams.BackBufferFormat = D3DFMT_UNKNOWN; - //} - //pparams.BackBufferCount = 1; - //pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; - - //if (window_flags & SDL_WINDOW_FULLSCREEN) { - // pparams.Windowed = FALSE; - // pparams.FullScreen_RefreshRateInHz = - // fullscreen_mode.refresh_rate; - //} else { - // pparams.Windowed = TRUE; - // pparams.FullScreen_RefreshRateInHz = 0; - //} - //if (flags & SDL_RENDERER_PRESENTVSYNC) { - // pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - //} else { - // pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - //} - - ///* FIXME: Which adapter? */ - //data->adapter = D3DADAPTER_DEFAULT; - //IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); - - //result = IDirect3D9_CreateDevice(data->d3d, data->adapter, - // D3DDEVTYPE_HAL, - // pparams.hDeviceWindow, - // D3DCREATE_FPU_PRESERVE | ((caps. - // DevCaps & - // D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? - // D3DCREATE_HARDWARE_VERTEXPROCESSING : - // D3DCREATE_SOFTWARE_VERTEXPROCESSING), - // &pparams, &data->device); - //if (FAILED(result)) { - // D3D11_DestroyRenderer(renderer); - // D3D11_SetError("CreateDevice()", result); - // return NULL; - //} - //data->beginScene = SDL_TRUE; - //data->scaleMode = D3DTEXF_FORCE_DWORD; - - ///* Get presentation parameters to fill info */ - //result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); - //if (FAILED(result)) { - // D3D11_DestroyRenderer(renderer); - // D3D11_SetError("GetSwapChain()", result); - // return NULL; - //} - //result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); - //if (FAILED(result)) { - // IDirect3DSwapChain9_Release(chain); - // D3D11_DestroyRenderer(renderer); - // D3D11_SetError("GetPresentParameters()", result); - // return NULL; - //} - //IDirect3DSwapChain9_Release(chain); - //if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { - // renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; - //} - //data->pparams = pparams; - - //IDirect3DDevice9_GetDeviceCaps(data->device, &caps); - //renderer->info.max_texture_width = caps.MaxTextureWidth; - //renderer->info.max_texture_height = caps.MaxTextureHeight; - //if (caps.NumSimultaneousRTs >= 2) { - // renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE; - //} - - ///* Set up parameters for rendering */ - //IDirect3DDevice9_SetVertexShader(data->device, NULL); - //IDirect3DDevice9_SetFVF(data->device, - // D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); - //IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); - //IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, - // D3DCULL_NONE); - //IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); - ///* Enable color modulation by diffuse color */ - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, - // D3DTOP_MODULATE); - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, - // D3DTA_TEXTURE); - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, - // D3DTA_DIFFUSE); - ///* Enable alpha modulation by diffuse alpha */ - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, - // D3DTOP_MODULATE); - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, - // D3DTA_TEXTURE); - //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, - // D3DTA_DIFFUSE); - ///* Disable second texture stage, since we're done */ - //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, - // D3DTOP_DISABLE); - //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, - // D3DTOP_DISABLE); - - ///* Store the default render target */ - //IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget ); - //data->currentRenderTarget = NULL; - - ///* Set an identity world and view matrix */ - //matrix.m[0][0] = 1.0f; - //matrix.m[0][1] = 0.0f; - //matrix.m[0][2] = 0.0f; - //matrix.m[0][3] = 0.0f; - //matrix.m[1][0] = 0.0f; - //matrix.m[1][1] = 1.0f; - //matrix.m[1][2] = 0.0f; - //matrix.m[1][3] = 0.0f; - //matrix.m[2][0] = 0.0f; - //matrix.m[2][1] = 0.0f; - //matrix.m[2][2] = 1.0f; - //matrix.m[2][3] = 0.0f; - //matrix.m[3][0] = 0.0f; - //matrix.m[3][1] = 0.0f; - //matrix.m[3][2] = 0.0f; - //matrix.m[3][3] = 1.0f; - //IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix); - //IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix); + /* Initialize Direct3D resources */ + if (FAILED(D3D11_CreateDeviceResources(renderer))) { + D3D11_DestroyRenderer(renderer); + return NULL; + } + if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) { + D3D11_DestroyRenderer(renderer); + return NULL; + } 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 & out) { diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index f734771af..dcc68fd8e 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -36,13 +36,6 @@ SDL_winrtrenderer::~SDL_winrtrenderer() } } -// Initialize the Direct3D resources required to run. -void SDL_winrtrenderer::Initialize() -{ - CreateDeviceResources(); - CreateWindowSizeDependentResources(); -} - // Recreate all device resources and set them back to the current state. void SDL_winrtrenderer::HandleDeviceLost() { diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 9fde42517..3cab8270d 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,7 +16,6 @@ internal: public: virtual ~SDL_winrtrenderer(); - virtual void Initialize(); virtual void HandleDeviceLost(); virtual void CreateDeviceResources(); virtual void CreateWindowSizeDependentResources(); diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 596bd9966..38c30415f 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -232,7 +232,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer; SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; - SDL_WinRTGlobalApp->m_renderer->Initialize(); + //SDL_WinRTGlobalApp->m_renderer->Initialize(); /* All done! */ return 0; From 0408a58b167217db57e2459d1a746b4fece3c47d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 15:43:13 -0500 Subject: [PATCH 102/264] WinRT: more code-moving from WinRT code to Direct3D 11.1 code --- src/render/direct3d11/SDL_render_d3d11.cpp | 65 +++++++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.cpp | 6 -- src/video/windowsrt/SDL_winrtrenderer.cpp | 47 +--------------- src/video/windowsrt/SDL_winrtrenderer.h | 4 -- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 63dbfe00b..da45862a9 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -84,6 +84,8 @@ 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 = { @@ -211,6 +213,7 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) return D3D11_ReadFileContents(fileName, out); } +// Create resources that depend on the device. HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer) { @@ -425,6 +428,7 @@ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) return *coreWindowPointer; } +// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. static float D3D11_ConvertDipsToPixels(float dips) { @@ -433,6 +437,7 @@ D3D11_ConvertDipsToPixels(float dips) } #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) @@ -655,6 +660,57 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return S_OK; } +HRESULT +D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) +{ + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + HRESULT result = S_OK; + Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + + if (coreWindow->Bounds.Width != data->windowSizeInDIPs.x || + coreWindow->Bounds.Height != data->windowSizeInDIPs.y || + data->orientation != DisplayProperties::CurrentOrientation) + { + ID3D11RenderTargetView* nullViews[] = {nullptr}; + data->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); + data->renderTargetView = 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 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 int D3D11_UpdateViewport(SDL_Renderer * renderer) { @@ -694,15 +750,18 @@ D3D11_RenderPresent(SDL_Renderer * renderer) // 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) { - extern void WINRT_HandleDeviceLost(); // TODO, WinRT: move lost-device handling into the Direct3D 11.1 renderer, as appropriate - WINRT_HandleDeviceLost(); + hr = D3D11_HandleDeviceLost(renderer); + if (FAILED(hr)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, hr); + } } else { WIN_SetErrorFromHRESULT(__FUNCTION__, hr); - // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines } } diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index aa204aa4d..493d88195 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -33,12 +33,6 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; -// HACK: provide a temporary means for the Direct3D 11.1 renderer to handle lost devices, while refactoring is underway -void WINRT_HandleDeviceLost() -{ - SDL_WinRTGlobalApp->m_renderer->HandleDeviceLost(); -} - using namespace Windows::ApplicationModel; using namespace Windows::ApplicationModel::Core; using namespace Windows::ApplicationModel::Activation; diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index dcc68fd8e..ea831ddce 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -16,9 +16,8 @@ using namespace Windows::UI::Core; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; -extern HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer); extern CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer); -extern HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); +extern HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : @@ -36,31 +35,6 @@ SDL_winrtrenderer::~SDL_winrtrenderer() } } -// Recreate all device resources and set them back to the current state. -void SDL_winrtrenderer::HandleDeviceLost() -{ - // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. - m_sdlRendererData->windowSizeInDIPs.x = 0; - m_sdlRendererData->windowSizeInDIPs.y = 0; - m_sdlRendererData->swapChain = nullptr; - - // TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer - CreateDeviceResources(); - UpdateForWindowSizeChange(); -} - -// These are the resources that depend on the device. -void SDL_winrtrenderer::CreateDeviceResources() -{ - DX::ThrowIfFailed(D3D11_CreateDeviceResources(m_sdlRenderer)); -} - -// Allocate all memory resources that change on a window SizeChanged event. -void SDL_winrtrenderer::CreateWindowSizeDependentResources() -{ - DX::ThrowIfFailed(D3D11_CreateWindowSizeDependentResources(m_sdlRenderer)); -} - void SDL_winrtrenderer::ResizeMainTexture(int w, int h) { const int pixelSizeInBytes = 4; @@ -131,17 +105,7 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) // This method is called in the event handler for the SizeChanged event. void SDL_winrtrenderer::UpdateForWindowSizeChange() { - CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(m_sdlRenderer); - if (coreWindow->Bounds.Width != m_sdlRendererData->windowSizeInDIPs.x || - coreWindow->Bounds.Height != m_sdlRendererData->windowSizeInDIPs.y || - m_sdlRendererData->orientation != DisplayProperties::CurrentOrientation) - { - ID3D11RenderTargetView* nullViews[] = {nullptr}; - m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - m_sdlRendererData->renderTargetView = nullptr; - m_sdlRendererData->d3dContext->Flush(); - CreateWindowSizeDependentResources(); - } + DX::ThrowIfFailed(D3D11_UpdateForWindowSizeChange(m_sdlRenderer)); } void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) @@ -231,10 +195,3 @@ void SDL_winrtrenderer::Present() { SDL_RenderPresent(m_sdlRenderer); } - -// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels. -float SDL_winrtrenderer::ConvertDipsToPixels(float dips) -{ - static const float dipsPerInch = 96.0f; - return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer. -} diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 3cab8270d..7d172f8c3 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,12 +16,8 @@ internal: public: virtual ~SDL_winrtrenderer(); - virtual void HandleDeviceLost(); - virtual void CreateDeviceResources(); - virtual void CreateWindowSizeDependentResources(); virtual void UpdateForWindowSizeChange(); virtual void Present(); - virtual float ConvertDipsToPixels(float dips); internal: virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); From 43c3909acdb5d7c62fd0a2f434a4a5913af1b396 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 16:00:55 -0500 Subject: [PATCH 103/264] WinRT: added SDL_WINDOWEVENT_RESIZED support, and moved window-resize-handling code from WinRT rendering code to D3D 11.1 code --- src/render/direct3d11/SDL_render_d3d11.cpp | 23 +++++++++++++++------- src/video/windowsrt/SDL_WinRTApp.cpp | 6 +++++- src/video/windowsrt/SDL_winrtrenderer.cpp | 9 --------- src/video/windowsrt/SDL_winrtrenderer.h | 1 - 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index da45862a9..3ba765769 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -51,8 +51,8 @@ using namespace Windows::UI::Core; /* 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 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 *pixels, @@ -131,9 +131,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data->windowSizeInDIPs = XMFLOAT2(0, 0); data->renderTargetSize = XMFLOAT2(0, 0); - // TODO: Create Direct3D Object(s) - - //renderer->WindowEvent = D3D11_WindowEvent; + renderer->WindowEvent = D3D11_WindowEvent; //renderer->CreateTexture = D3D11_CreateTexture; //renderer->UpdateTexture = D3D11_UpdateTexture; //renderer->LockTexture = D3D11_LockTexture; @@ -402,7 +400,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) #ifdef __WINRT__ -CoreWindow ^ +static CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) { SDL_Window * sdlWindow = renderer->window; @@ -660,6 +658,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return S_OK; } +// This method is called when the window's size changes. HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) { @@ -691,7 +690,7 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer) D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources. + // Reset these member variables to ensure that D3D11_UpdateForWindowSizeChange recreates all resources. data->windowSizeInDIPs.x = 0; data->windowSizeInDIPs.y = 0; data->swapChain = nullptr; @@ -711,6 +710,16 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer) 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_UpdateViewport(SDL_Renderer * renderer) { diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 493d88195..d9f433163 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -151,7 +151,11 @@ void SDL_WinRTApp::Uninitialize() void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { - m_renderer->UpdateForWindowSizeChange(); + SDL_SendWindowEvent( + m_sdlWindowData->sdlWindow, + SDL_WINDOWEVENT_RESIZED, + (int) ceil(args->Size.Width), + (int) ceil(args->Size.Height)); } void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index ea831ddce..bb89580a8 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -16,9 +16,6 @@ using namespace Windows::UI::Core; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; -extern CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer); -extern HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); - // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : m_mainTextureHelperSurface(NULL), @@ -102,12 +99,6 @@ void SDL_winrtrenderer::ResizeMainTexture(int w, int h) ); } -// This method is called in the event handler for the SizeChanged event. -void SDL_winrtrenderer::UpdateForWindowSizeChange() -{ - DX::ThrowIfFailed(D3D11_UpdateForWindowSizeChange(m_sdlRenderer)); -} - void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 7d172f8c3..061cdb3a2 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -16,7 +16,6 @@ internal: public: virtual ~SDL_winrtrenderer(); - virtual void UpdateForWindowSizeChange(); virtual void Present(); internal: From ba872e50c760306fcab2410e22fa637381865520 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 18:58:13 -0500 Subject: [PATCH 104/264] WinRT: moved texture management code from SDL_winrtrenderer to the D3D 11.1 SDL_Renderer backend --- src/render/direct3d11/SDL_render_d3d11.cpp | 232 +++++++++++++++++-- src/render/direct3d11/SDL_render_d3d11_cpp.h | 5 +- src/video/windowsrt/SDL_winrtrenderer.cpp | 169 +++----------- src/video/windowsrt/SDL_winrtrenderer.h | 2 +- 4 files changed, 254 insertions(+), 154 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 3ba765769..0da2c7697 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -53,32 +53,32 @@ using namespace Windows::UI::Core; 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 *pixels, -// int pitch); +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 *pixels, + int pitch); //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_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_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_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); static void D3D11_DestroyRenderer(SDL_Renderer * renderer); /* Direct3D 11.1 Internal Functions */ @@ -91,10 +91,10 @@ extern "C" { SDL_RenderDriver D3D11_RenderDriver = { D3D11_CreateRenderer, { - "direct3d", + "direct3d 11.1", (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), 1, - {SDL_PIXELFORMAT_ARGB8888}, + {SDL_PIXELFORMAT_RGB888}, 0, 0} }; @@ -132,21 +132,21 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data->renderTargetSize = XMFLOAT2(0, 0); renderer->WindowEvent = D3D11_WindowEvent; - //renderer->CreateTexture = D3D11_CreateTexture; - //renderer->UpdateTexture = D3D11_UpdateTexture; + 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->RenderClear = D3D11_RenderClear; //renderer->RenderDrawPoints = D3D11_RenderDrawPoints; //renderer->RenderDrawLines = D3D11_RenderDrawLines; //renderer->RenderFillRects = D3D11_RenderFillRects; - //renderer->RenderCopy = D3D11_RenderCopy; + renderer->RenderCopy = D3D11_RenderCopy; //renderer->RenderCopyEx = D3D11_RenderCopyEx; //renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; - //renderer->DestroyTexture = D3D11_DestroyTexture; + renderer->DestroyTexture = D3D11_DestroyTexture; renderer->DestroyRenderer = D3D11_DestroyRenderer; renderer->info = D3D11_RenderDriver.info; renderer->info.flags = SDL_RENDERER_ACCELERATED; @@ -166,6 +166,8 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } + // TODO, WinRT: fill in renderer->info.texture_formats where appropriate + return renderer; } @@ -720,12 +722,210 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } +static int +D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_TextureData *textureData; + HRESULT result; + + textureData = new D3D11_TextureData; + if (!textureData) { + SDL_OutOfMemory(); + return -1; + } + textureData->pixelFormat = SDL_AllocFormat(texture->format); + + texture->driverdata = textureData; + + const int pixelSizeInBytes = textureData->pixelFormat->BytesPerPixel; + + D3D11_TEXTURE2D_DESC textureDesc = {0}; + textureDesc.Width = texture->w; + textureDesc.Height = texture->h; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DYNAMIC; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + textureDesc.MiscFlags = 0; + + const int numPixels = textureDesc.Width * textureDesc.Height; + std::vector initialTexturePixels(numPixels * pixelSizeInBytes, 0x00); + + // Fill the texture with a non-black color, for debugging purposes: + //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; + result = rendererData->d3dDevice->CreateTexture2D( + &textureDesc, + &initialTextureData, + &textureData->mainTexture + ); + 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 = NULL; + texture->driverdata = NULL; + } +} + +static int +D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + HRESULT result = S_OK; + + D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; + result = rendererData->d3dContext->Map( + textureData->mainTexture.Get(), + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + &textureMemory + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return -1; + } + + // Copy pixel data to the locked texture's memory: + for (int y = 0; y < rect->h; ++y) { + memcpy( + ((Uint8 *)textureMemory.pData) + (textureMemory.RowPitch * y), + ((Uint8 *)pixels) + (pitch * y), + pitch + ); + } + + // Clean up a bit, then commit the texture's memory back to Direct3D: + rendererData->d3dContext->Unmap( + textureData->mainTexture.Get(), + 0); + + return 0; +} + static int D3D11_UpdateViewport(SDL_Renderer * renderer) { return 0; } +static int +D3D11_RenderClear(SDL_Renderer * renderer) +{ + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + const float colorRGBA[] = { + renderer->r, + renderer->g, + renderer->b, + renderer->a + }; + data->d3dContext->ClearRenderTargetView( + data->renderTargetView.Get(), + colorRGBA + ); + 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; + //HRESULT result = S_OK; + + rendererData->d3dContext->OMSetRenderTargets( + 1, + rendererData->renderTargetView.GetAddressOf(), + nullptr + ); + + UINT stride = sizeof(VertexPositionColor); + UINT offset = 0; + rendererData->d3dContext->IASetVertexBuffers( + 0, + 1, + rendererData->vertexBuffer.GetAddressOf(), + &stride, + &offset + ); + + rendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + rendererData->d3dContext->IASetInputLayout(rendererData->inputLayout.Get()); + + rendererData->d3dContext->VSSetShader( + rendererData->vertexShader.Get(), + nullptr, + 0 + ); + + rendererData->d3dContext->PSSetShader( + rendererData->pixelShader.Get(), + nullptr, + 0 + ); + + rendererData->d3dContext->PSSetShaderResources(0, 1, textureData->mainTextureResourceView.GetAddressOf()); + + rendererData->d3dContext->PSSetSamplers(0, 1, rendererData->mainSampler.GetAddressOf()); + + rendererData->d3dContext->Draw(4, 0); + + return 0; +} + static void D3D11_RenderPresent(SDL_Renderer * renderer) { diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 644b8bd17..9baf3df57 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -34,8 +34,6 @@ typedef struct Microsoft::WRL::ComPtr vertexBuffer; Microsoft::WRL::ComPtr vertexShader; Microsoft::WRL::ComPtr pixelShader; - Microsoft::WRL::ComPtr mainTexture; - Microsoft::WRL::ComPtr mainTextureResourceView; Microsoft::WRL::ComPtr mainSampler; D3D_FEATURE_LEVEL featureLevel; unsigned int vertexCount; @@ -52,6 +50,9 @@ typedef struct typedef struct { + Microsoft::WRL::ComPtr mainTexture; + Microsoft::WRL::ComPtr mainTextureResourceView; + SDL_PixelFormat * pixelFormat; } D3D11_TextureData; struct VertexPositionColor diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp index bb89580a8..a84fa7b2e 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ b/src/video/windowsrt/SDL_winrtrenderer.cpp @@ -7,6 +7,7 @@ extern "C" { #include "SDL_syswm.h" +#include "../../core/windows/SDL_windows.h" } using namespace DirectX; @@ -18,167 +19,65 @@ using namespace Windows::Graphics::Display; // Constructor. SDL_winrtrenderer::SDL_winrtrenderer() : - m_mainTextureHelperSurface(NULL), m_sdlRenderer(NULL), - m_sdlRendererData(NULL) + m_sdlRendererData(NULL), + m_mainTexture(NULL) { } SDL_winrtrenderer::~SDL_winrtrenderer() { - if (m_mainTextureHelperSurface) { - SDL_FreeSurface(m_mainTextureHelperSurface); - m_mainTextureHelperSurface = NULL; + if (m_mainTexture) { + SDL_DestroyTexture(m_mainTexture); + m_mainTexture = NULL; } } void SDL_winrtrenderer::ResizeMainTexture(int w, int h) { - const int pixelSizeInBytes = 4; - - D3D11_TEXTURE2D_DESC textureDesc = {0}; - textureDesc.Width = w; - textureDesc.Height = h; - textureDesc.MipLevels = 1; - textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Usage = D3D11_USAGE_DYNAMIC; - textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - textureDesc.MiscFlags = 0; - - const int numPixels = textureDesc.Width * textureDesc.Height; - std::vector initialTexturePixels(numPixels * pixelSizeInBytes, 0x00); - - // Fill the texture with a non-black color, for debugging purposes: - //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; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateTexture2D( - &textureDesc, - &initialTextureData, - &m_sdlRendererData->mainTexture - ) - ); - - if (m_mainTextureHelperSurface) { - SDL_FreeSurface(m_mainTextureHelperSurface); - m_mainTextureHelperSurface = NULL; - } - m_mainTextureHelperSurface = SDL_CreateRGBSurfaceFrom( - NULL, - textureDesc.Width, textureDesc.Height, - (pixelSizeInBytes * 8), - 0, // Use an nil pitch for now. This'll be filled in when updating the texture. - 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); // TODO, WinRT: calculate masks given the Direct3D-defined pixel format of the texture - if (m_mainTextureHelperSurface == NULL) { - DX::ThrowIfFailed(E_FAIL); // TODO, WinRT: generate a better error here, taking into account who's calling this function. + if (m_mainTexture) { + SDL_DestroyTexture(m_mainTexture); + m_mainTexture = NULL; } - 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; - DX::ThrowIfFailed( - m_sdlRendererData->d3dDevice->CreateShaderResourceView( - m_sdlRendererData->mainTexture.Get(), - &resourceViewDesc, - &m_sdlRendererData->mainTextureResourceView) - ); + m_mainTexture = SDL_CreateTexture(m_sdlRenderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, w, h); +} + +static inline Platform::Exception ^ +WINRT_CreateExceptionWithSDLError() +{ + wchar_t * sdlErrorMessage = WIN_UTF8ToString(SDL_GetError()); + Platform::String ^ errorMessage = ref new Platform::String(sdlErrorMessage); + SDL_free(sdlErrorMessage); + throw ref new Platform::FailureException(errorMessage); } void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) { - const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_sdlRendererData->d3dContext->ClearRenderTargetView( - m_sdlRendererData->renderTargetView.Get(), - blackColor - ); + D3D11_TextureData * textureData = (D3D11_TextureData *)m_mainTexture->driverdata; + + SDL_SetRenderDrawColor(m_sdlRenderer, 0, 0, 0, 0); + if (SDL_RenderClear(m_sdlRenderer) != 0) { + throw WINRT_CreateExceptionWithSDLError(); + } // Only draw the screen once it is loaded (some loading is asynchronous). - if (!m_sdlRendererData->loadingComplete) - { + if (!m_sdlRendererData->loadingComplete) { return; } - if (!m_sdlRendererData->mainTextureResourceView) - { + if (!textureData->mainTextureResourceView) { return; } - // Update the main texture (for SDL usage). Start by mapping the SDL - // window's main texture to CPU-accessible memory: - D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; - DX::ThrowIfFailed( - m_sdlRendererData->d3dContext->Map( - m_sdlRendererData->mainTexture.Get(), - 0, - D3D11_MAP_WRITE_DISCARD, - 0, - &textureMemory) - ); - - // Copy pixel data to the locked texture's memory: - m_mainTextureHelperSurface->pixels = textureMemory.pData; - m_mainTextureHelperSurface->pitch = textureMemory.RowPitch; - SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL); + // Update the main texture (for SDL usage). // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything + if (SDL_UpdateTexture(m_mainTexture, NULL, surface->pixels, surface->pitch) != 0) { + throw WINRT_CreateExceptionWithSDLError(); + } - // Clean up a bit, then commit the texture's memory back to Direct3D: - m_mainTextureHelperSurface->pixels = NULL; - m_mainTextureHelperSurface->pitch = 0; - m_sdlRendererData->d3dContext->Unmap( - m_sdlRendererData->mainTexture.Get(), - 0); - - m_sdlRendererData->d3dContext->OMSetRenderTargets( - 1, - m_sdlRendererData->renderTargetView.GetAddressOf(), - nullptr - ); - - UINT stride = sizeof(VertexPositionColor); - UINT offset = 0; - m_sdlRendererData->d3dContext->IASetVertexBuffers( - 0, - 1, - m_sdlRendererData->vertexBuffer.GetAddressOf(), - &stride, - &offset - ); - - m_sdlRendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - m_sdlRendererData->d3dContext->IASetInputLayout(m_sdlRendererData->inputLayout.Get()); - - m_sdlRendererData->d3dContext->VSSetShader( - m_sdlRendererData->vertexShader.Get(), - nullptr, - 0 - ); - - m_sdlRendererData->d3dContext->PSSetShader( - m_sdlRendererData->pixelShader.Get(), - nullptr, - 0 - ); - - m_sdlRendererData->d3dContext->PSSetShaderResources(0, 1, m_sdlRendererData->mainTextureResourceView.GetAddressOf()); - - m_sdlRendererData->d3dContext->PSSetSamplers(0, 1, m_sdlRendererData->mainSampler.GetAddressOf()); - - m_sdlRendererData->d3dContext->Draw(4, 0); + if (SDL_RenderCopy(m_sdlRenderer, m_mainTexture, NULL, NULL) != 0) { + throw WINRT_CreateExceptionWithSDLError(); + } } // Method to deliver the final image to the display. diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h index 061cdb3a2..f99d67c36 100644 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ b/src/video/windowsrt/SDL_winrtrenderer.h @@ -29,5 +29,5 @@ internal: protected private: // UpdateWindowSurface helper objects - SDL_Surface * m_mainTextureHelperSurface; + SDL_Texture * m_mainTexture; }; From 46530ef818fd3579948001f48d9aa0220e17dd8c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 19:39:42 -0500 Subject: [PATCH 105/264] WinRT: made use of SDL's framebuffer emulation code, instead of the custom stuff; then removed SDL_winrtrenderer --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 14 --- .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 12 -- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 18 --- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 12 -- src/video/windowsrt/SDL_WinRTApp.cpp | 20 +--- src/video/windowsrt/SDL_WinRTApp.h | 6 - src/video/windowsrt/SDL_winrtframebuffer.cpp | 104 ------------------ src/video/windowsrt/SDL_winrtframebuffer_c.h | 27 ----- src/video/windowsrt/SDL_winrtrenderer.cpp | 87 --------------- src/video/windowsrt/SDL_winrtrenderer.h | 33 ------ src/video/windowsrt/SDL_winrtvideo.cpp | 29 +---- 11 files changed, 6 insertions(+), 356 deletions(-) delete mode 100644 src/video/windowsrt/SDL_winrtframebuffer.cpp delete mode 100644 src/video/windowsrt/SDL_winrtframebuffer_c.h delete mode 100644 src/video/windowsrt/SDL_winrtrenderer.cpp delete mode 100644 src/video/windowsrt/SDL_winrtrenderer.h diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 4ddc0a112..06bef404f 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -248,9 +248,7 @@ - - @@ -366,24 +364,12 @@ true true - - true - true - true - true - true true true true - - true - true - true - true - true true diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index ec1edad74..4735718d2 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -333,15 +333,9 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files @@ -593,15 +587,9 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index c5a803fbc..925f5c8a3 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -151,14 +151,6 @@ true true - - true - true - true - true - true - true - true true @@ -167,14 +159,6 @@ true true - - true - true - true - true - true - true - true true @@ -293,9 +277,7 @@ - - diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index fec688350..2119bc170 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -234,15 +234,9 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files @@ -356,9 +350,6 @@ Source Files - - Source Files - Source Files @@ -578,9 +569,6 @@ Source Files - - Source Files - Source Files diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index d9f433163..03283e639 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -1,5 +1,6 @@ #include "SDLmain_WinRT_common.h" #include "SDL_WinRTApp.h" +#include "ppltasks.h" extern "C" { #include "SDL_assert.h" @@ -47,8 +48,7 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), m_sdlWindowData(NULL), - m_useRelativeMouseMode(false), - m_renderer(nullptr) + m_useRelativeMouseMode(false) { } @@ -62,8 +62,6 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Resuming += ref new EventHandler(this, &SDL_WinRTApp::OnResuming); - - m_renderer = ref new SDL_winrtrenderer(); } void SDL_WinRTApp::SetWindow(CoreWindow^ window) @@ -136,15 +134,6 @@ void SDL_WinRTApp::PumpEvents() } } -void SDL_WinRTApp::UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects) -{ - if (!m_windowClosed && m_windowVisible) - { - m_renderer->Render(surface, rects, numrects); - m_renderer->Present(); // This call is synchronized to the display frame rate. - } -} - void SDL_WinRTApp::Uninitialize() { } @@ -649,11 +638,6 @@ void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData) m_sdlWindowData = windowData; } -void SDL_WinRTApp::ResizeMainTexture(int w, int h) -{ - m_renderer->ResizeMainTexture(w, h); -} - IFrameworkView^ Direct3DApplicationSource::CreateView() { // TODO, WinRT: see if this function (CreateView) can ever get called diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index b6dd25749..7c03ecafe 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -2,7 +2,6 @@ #include "SDLmain_WinRT_common.h" #include "SDL_winrtvideo.h" -#include "SDL_winrtrenderer.h" #include using namespace Windows::UI::Core; @@ -27,8 +26,6 @@ internal: bool HasSDLWindowData() const; void SetRelativeMouseMode(bool enable); void SetSDLWindowData(const SDL_WindowData * windowData); - void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects); - void ResizeMainTexture(int w, int h); Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); protected: @@ -47,9 +44,6 @@ protected: void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); -internal: - SDL_winrtrenderer^ m_renderer; - private: bool m_windowClosed; bool m_windowVisible; diff --git a/src/video/windowsrt/SDL_winrtframebuffer.cpp b/src/video/windowsrt/SDL_winrtframebuffer.cpp deleted file mode 100644 index a30990e19..000000000 --- a/src/video/windowsrt/SDL_winrtframebuffer.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 "../SDL_sysvideo.h" -#include "SDL_winrtframebuffer_c.h" -#include "SDL_WinRTApp.h" - -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; - - -#define WINRT_SURFACE "_SDL_WinRTSurface" - -int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) -{ - SDL_Surface *surface; - const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; - int w, h; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - /* Free the old framebuffer surface */ - surface = (SDL_Surface *) SDL_GetWindowData(window, WINRT_SURFACE); - if (surface) { - SDL_FreeSurface(surface); - } - - /* Create a new one */ - SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_GetWindowSize(window, &w, &h); - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); - if (!surface) { - return -1; - } - - /* Save info on the surface */ - SDL_SetWindowData(window, WINRT_SURFACE, surface); - *format = surface_format; - *pixels = surface->pixels; - *pitch = surface->pitch; - - /* Make sure a Direct3D texture exists to draw the surface onto */ - SDL_WinRTGlobalApp->ResizeMainTexture(surface->w, surface->h); - - return 0; -} - -int SDL_WINRT_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects) -{ - static int frame_number; - SDL_Surface *surface; - - surface = (SDL_Surface *) SDL_GetWindowData(window, WINRT_SURFACE); - if (!surface) { - SDL_SetError("Couldn't find WinRT surface for window"); - return -1; - } - - /* Send the data to the display */ - if (SDL_getenv("SDL_VIDEO_WINRT_SAVE_FRAMES")) { - char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); - SDL_SaveBMP(surface, file); - } - - SDL_WinRTGlobalApp->UpdateWindowFramebuffer(surface, rects, numrects); - - return 0; -} - -void SDL_WINRT_DestroyWindowFramebuffer(_THIS, SDL_Window * window) -{ - SDL_Surface *surface; - - surface = (SDL_Surface *) SDL_SetWindowData(window, WINRT_SURFACE, NULL); - if (surface) { - SDL_FreeSurface(surface); - } -} - -#endif /* SDL_VIDEO_DRIVER_WINRT */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtframebuffer_c.h b/src/video/windowsrt/SDL_winrtframebuffer_c.h deleted file mode 100644 index d6531cfd0..000000000 --- a/src/video/windowsrt/SDL_winrtframebuffer_c.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 int SDL_WINRT_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); -extern int SDL_WINRT_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects); -extern void SDL_WINRT_DestroyWindowFramebuffer(_THIS, SDL_Window * window); - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SDL_winrtrenderer.cpp b/src/video/windowsrt/SDL_winrtrenderer.cpp deleted file mode 100644 index a84fa7b2e..000000000 --- a/src/video/windowsrt/SDL_winrtrenderer.cpp +++ /dev/null @@ -1,87 +0,0 @@ - -#include -#include -#include -#include "SDLmain_WinRT_common.h" -#include "SDL_winrtrenderer.h" - -extern "C" { -#include "SDL_syswm.h" -#include "../../core/windows/SDL_windows.h" -} - -using namespace DirectX; -using namespace Microsoft::WRL; -using namespace std; -using namespace Windows::UI::Core; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; - -// Constructor. -SDL_winrtrenderer::SDL_winrtrenderer() : - m_sdlRenderer(NULL), - m_sdlRendererData(NULL), - m_mainTexture(NULL) -{ -} - -SDL_winrtrenderer::~SDL_winrtrenderer() -{ - if (m_mainTexture) { - SDL_DestroyTexture(m_mainTexture); - m_mainTexture = NULL; - } -} - -void SDL_winrtrenderer::ResizeMainTexture(int w, int h) -{ - if (m_mainTexture) { - SDL_DestroyTexture(m_mainTexture); - m_mainTexture = NULL; - } - - m_mainTexture = SDL_CreateTexture(m_sdlRenderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, w, h); -} - -static inline Platform::Exception ^ -WINRT_CreateExceptionWithSDLError() -{ - wchar_t * sdlErrorMessage = WIN_UTF8ToString(SDL_GetError()); - Platform::String ^ errorMessage = ref new Platform::String(sdlErrorMessage); - SDL_free(sdlErrorMessage); - throw ref new Platform::FailureException(errorMessage); -} - -void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects) -{ - D3D11_TextureData * textureData = (D3D11_TextureData *)m_mainTexture->driverdata; - - SDL_SetRenderDrawColor(m_sdlRenderer, 0, 0, 0, 0); - if (SDL_RenderClear(m_sdlRenderer) != 0) { - throw WINRT_CreateExceptionWithSDLError(); - } - - // Only draw the screen once it is loaded (some loading is asynchronous). - if (!m_sdlRendererData->loadingComplete) { - return; - } - if (!textureData->mainTextureResourceView) { - return; - } - - // Update the main texture (for SDL usage). - // TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything - if (SDL_UpdateTexture(m_mainTexture, NULL, surface->pixels, surface->pitch) != 0) { - throw WINRT_CreateExceptionWithSDLError(); - } - - if (SDL_RenderCopy(m_sdlRenderer, m_mainTexture, NULL, NULL) != 0) { - throw WINRT_CreateExceptionWithSDLError(); - } -} - -// Method to deliver the final image to the display. -void SDL_winrtrenderer::Present() -{ - SDL_RenderPresent(m_sdlRenderer); -} diff --git a/src/video/windowsrt/SDL_winrtrenderer.h b/src/video/windowsrt/SDL_winrtrenderer.h deleted file mode 100644 index f99d67c36..000000000 --- a/src/video/windowsrt/SDL_winrtrenderer.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "DirectXHelper.h" -#include "../../render/direct3d11/SDL_render_d3d11_cpp.h" - -extern "C" { -#include "SDL.h" -#include "../../render/SDL_sysrender.h" -} - -// Helper class that initializes DirectX APIs for 3D rendering. -ref class SDL_winrtrenderer -{ -internal: - SDL_winrtrenderer(); - -public: - virtual ~SDL_winrtrenderer(); - virtual void Present(); - -internal: - virtual void Render(SDL_Surface * surface, SDL_Rect * rects, int numrects); - void ResizeMainTexture(int w, int h); - -internal: - // Internal SDL renderer (likely a temporary addition, for refactoring purposes): - SDL_Renderer * m_sdlRenderer; - D3D11_RenderData * m_sdlRendererData; - -protected private: - // UpdateWindowSurface helper objects - SDL_Texture * m_mainTexture; -}; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 38c30415f..682ea386e 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -41,7 +41,6 @@ extern "C" { #include "SDL_WinRTApp.h" #include "SDL_winrtvideo.h" #include "SDL_winrtevents_c.h" -#include "SDL_winrtframebuffer_c.h" #include "SDL_winrtmouse.h" /* On Windows, windows.h defines CreateWindow */ @@ -100,9 +99,9 @@ WINRT_CreateDevice(int devindex) 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->CreateWindowFramebuffer = SDL_WINRT_CreateWindowFramebuffer; + //device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer; + //device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; device->free = WINRT_DeleteDevice; @@ -167,6 +166,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_OutOfMemory(); return -1; } + window->driverdata = data; data->sdlWindow = window; data->coreWindow = new CoreWindow^(CoreWindow::GetForCurrentThread()); @@ -213,27 +213,6 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) */ SDL_WinRTGlobalApp->SetSDLWindowData(data); - /* For now, create a Direct3D 11 renderer up-front. Eventually, this - won't be done in WINRT_CreateWindow, although it may get done in - SDL_WINRT_CreateWindowFramebuffer. - */ - - // Link SDL_winrtrenderer to the SDL_Renderer temporarily, - // for refactoring purposes. Initialize the SDL_Renderer - // first in order to give it the opportunity to create key - // resources first. - // - // TODO, WinRT: either make WINRT_CreateWindow not call SDL_CreateRenderer, or have it do error checking if it does call it - - // HACK: make sure the SDL window references SDL_WindowData data now, in - // order to allow the SDL_Renderer to be created in WINRT_CreateWindow - window->driverdata = data; - - SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); - SDL_WinRTGlobalApp->m_renderer->m_sdlRenderer = renderer; - SDL_WinRTGlobalApp->m_renderer->m_sdlRendererData = (D3D11_RenderData *) renderer->driverdata; - //SDL_WinRTGlobalApp->m_renderer->Initialize(); - /* All done! */ return 0; } From 8b75a125cc605567ac9d4d04f7ff9b0bd40e06c1 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 20:26:39 -0500 Subject: [PATCH 106/264] WinRT: made sure the device orientation transform gets applied (by the D3D 11.1 renderer) when drawing --- src/render/direct3d11/SDL_render_d3d11.cpp | 45 ++++++++++++++++---- src/render/direct3d11/SDL_render_d3d11_cpp.h | 9 ++++ src/video/windowsrt/SimpleVertexShader.hlsl | 14 +++++- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 0da2c7697..9712a5d1e 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -339,6 +339,20 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) 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; + } + // // Create a vertex buffer: // @@ -553,7 +567,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) { case DisplayOrientations::Landscape: rotation = DXGI_MODE_ROTATION_IDENTITY; - data->orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation + 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, @@ -563,9 +577,9 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) case DisplayOrientations::Portrait: rotation = DXGI_MODE_ROTATION_ROTATE270; - data->orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation - 0.0f, 1.0f, 0.0f, 0.0f, - -1.0f, 0.0f, 0.0f, 0.0f, + 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 ); @@ -573,7 +587,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) case DisplayOrientations::LandscapeFlipped: rotation = DXGI_MODE_ROTATION_ROTATE180; - data->orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation + 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, @@ -583,9 +597,9 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) case DisplayOrientations::PortraitFlipped: rotation = DXGI_MODE_ROTATION_ROTATE90; - data->orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation - 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f, + 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 ); @@ -891,6 +905,15 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, nullptr ); + rendererData->d3dContext->UpdateSubresource( + rendererData->vertexShaderConstants.Get(), + 0, + NULL, + &rendererData->vertexShaderConstantsData, + 0, + 0 + ); + UINT stride = sizeof(VertexPositionColor); UINT offset = 0; rendererData->d3dContext->IASetVertexBuffers( @@ -911,6 +934,12 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 0 ); + rendererData->d3dContext->VSSetConstantBuffers( + 0, + 1, + rendererData->vertexShaderConstants.GetAddressOf() + ); + rendererData->d3dContext->PSSetShader( rendererData->pixelShader.Get(), nullptr, diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 9baf3df57..3933dd735 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -24,6 +24,11 @@ #include #include +struct SDL_VertexShaderConstants +{ + DirectX::XMFLOAT4X4 projection; +}; + typedef struct { Microsoft::WRL::ComPtr d3dDevice; @@ -39,6 +44,10 @@ typedef struct unsigned int vertexCount; bool loadingComplete; + // Vertex buffer constants: + SDL_VertexShaderConstants vertexShaderConstantsData; + Microsoft::WRL::ComPtr vertexShaderConstants; + // Cached renderer properties. DirectX::XMFLOAT2 windowSizeInDIPs; DirectX::XMFLOAT2 renderTargetSize; diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index adaf896e9..9065ecb03 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -1,6 +1,11 @@ //#pragma pack_matrix( row_major ) +cbuffer SDL_VertexShaderConstants : register(b0) +{ + matrix projection; +}; + struct VertexShaderInput { float3 pos : POSITION; @@ -16,7 +21,14 @@ struct VertexShaderOutput VertexShaderOutput main(VertexShaderInput input) { VertexShaderOutput output; - output.pos = float4(input.pos, 1.0f); + float4 pos = float4(input.pos, 1.0f); + + // Transform the vertex position into projected space. + pos = mul(pos, projection); + output.pos = pos; + + // Pass through the texture's color without modification. output.tex = input.tex; + return output; } From af0c2dad3db13c7e5cc769223e9eeefb41a4bd0f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 20:30:53 -0500 Subject: [PATCH 107/264] WinRT: fixed a crash that occurred after rotating the host device --- src/render/direct3d11/SDL_render_d3d11.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 9712a5d1e..3038b3d25 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -825,7 +825,6 @@ D3D11_DestroyTexture(SDL_Renderer * renderer, } delete textureData; - texture = NULL; texture->driverdata = NULL; } } From 2649db8b6551001c0a3f5a8f556f6b0b9696a5cc Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 9 Feb 2013 22:48:19 -0500 Subject: [PATCH 108/264] WinRT: consolidated all WinRT path-retrieval functions into one function --- include/SDL_system.h | 70 +++++++++--------- src/core/windowsrt/SDL_winrtpaths.cpp | 84 +++++++++++----------- src/render/direct3d11/SDL_render_d3d11.cpp | 4 +- 3 files changed, 80 insertions(+), 78 deletions(-) diff --git a/include/SDL_system.h b/include/SDL_system.h index b7de4ab8a..eb7e81138 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -96,44 +96,46 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); /* Platform specific functions for Windows RT */ #if defined(__WINRT__) && __WINRT__ -/* Gets the path to the installed app's root directory. - - This function may be used safely on Windows Phone 8. -*/ -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetInstalledLocationPath(); - -/* Gets the path to the local app data store. - Files and directories that should be limited to the local device can be - created in this path. - - This function may be used safely on Windows Phone 8, as opposed to - SDL_WinRTGetRoamingFolderPath() and SDL_WinRTGetTemporaryFolderPath(), - which do not work on Windows Phone 8 (and will return NULL if called - from this platform). +/** + * \brief Windows RT / Windows Phone path types */ -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetLocalFolderPath(); +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, -/* Gets the path to the roaming app data store. - Files and directories that should roam to different devices can be - created in this path. Be sure to read Microsoft's documentation on - roaming files for more information on how this works, as restrictions - do apply. + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, - Please note that on Windows Phone 8, this function will return NULL, - as Windows Phone 8 apps do not have an accessible roaming app data - store. + /** \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_WinRTGetRoamingFolderPath(); - -/* Gets the path to the temporary app data store. - Files and directories may be written here, however they may be deleted - by Windows at a future date. - - Please note that on Windows Phone 8, this function will return NULL, - as Windows Phone 8 apps do not have an accessible temporary app data - store. -*/ -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetTemporaryFolderPath(); +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFileSystemPath(SDL_WinRT_Path pathType); #endif /* __WINRT__ */ diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index 1c5fb312b..eecfd9652 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -19,53 +19,53 @@ using namespace std; using namespace Windows::Storage; extern "C" const wchar_t * -SDL_WinRTGetInstalledLocationPath() +SDL_WinRTGetFileSystemPath(SDL_WinRT_Path pathType) { - static wstring path; - if (path.empty()) { - path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); - } - return path.c_str(); -} + 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(); + } -extern "C" const wchar_t * -SDL_WinRTGetLocalFolderPath() -{ - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->LocalFolder->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; + } -extern "C" const wchar_t * -SDL_WinRTGetRoamingFolderPath() -{ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP SDL_Unsupported(); return NULL; -#else - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->RoamingFolder->Path->Data(); - } - return path.c_str(); -#endif -} - -extern "C" const wchar_t * -SDL_WinRTGetTemporaryFolderPath() -{ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - SDL_Unsupported(); - return NULL; -#else - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->TemporaryFolder->Path->Data(); - } - return path.c_str(); -#endif } #endif /* __WINRT__ */ diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 3038b3d25..82f798383 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -202,10 +202,10 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) wstring fileName; #if WINAPI_FAMILY == WINAPI_FAMILY_APP - fileName = SDL_WinRTGetInstalledLocationPath(); + fileName = SDL_WinRTGetFileSystemPath(SDL_WINRT_PATH_INSTALLED_LOCATION); fileName += L"\\SDL_VS2012_WinRT\\"; #elif WINAPI_FAMILY == WINAPI_PHONE_APP - fileName = SDL_WinRTGetInstalledLocationPath(); + fileName = SDL_WinRTGetFileSystemPath(SDL_WINRT_PATH_INSTALLED_LOCATION); fileName += L"\\"; #endif // WinRT, TODO: test Direct3D 11.1 shader loading on Win32 From 805c1ffa95d6524dabac4f0e81d49dc6e0cf6eb5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 10 Feb 2013 10:28:52 -0500 Subject: [PATCH 109/264] WinRT: made mouse button events include the correct button type (left, right, middle, x1, or x2) --- src/video/windowsrt/SDL_WinRTApp.cpp | 103 +++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 03283e639..e459f9910 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -14,6 +14,7 @@ extern "C" { #include "SDL_log.h" } +#include #include // TODO, WinRT: Remove reference(s) to BasicTimer.h @@ -34,11 +35,13 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; +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::UI::Core; +using namespace Windows::UI::Input; using namespace Windows::System; using namespace Windows::Foundation; using namespace Windows::Graphics::Display; @@ -174,19 +177,107 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) 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) +{ + PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", + header.c_str(), + pt->Position.X, pt->Position.Y, + pt->FrameId, + pt->PointerId, + WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind)); +} + void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - if (m_sdlWindowData) - { - SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, SDL_BUTTON_LEFT); +#if 0 + WINRT_LogPointerEvent("mouse down", args); +#endif + + if (m_sdlWindowData) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + if (button) { + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_PRESSED, button); + } } } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { - if (m_sdlWindowData) - { - SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, SDL_BUTTON_LEFT); +#if 0 + WINRT_LogPointerEvent("mouse up", args); +#endif + + if (m_sdlWindowData) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + if (button) { + SDL_SendMouseButton(m_sdlWindowData->sdlWindow, SDL_RELEASED, button); + } } } From 55865b391772dada78b0a8fbc8610b548d531b18 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 10 Feb 2013 10:39:24 -0500 Subject: [PATCH 110/264] WinRT: emit SDL_MOUSEWHEEL events --- src/video/windowsrt/SDL_WinRTApp.cpp | 17 ++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index e459f9910..f5fd02fa4 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -88,6 +88,9 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerReleased += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); + window->PointerWheelChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); + window->PointerMoved += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); @@ -245,9 +248,10 @@ static void WINRT_LogPointerEvent(const string & header, PointerEventArgs ^ args) { PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", + SDL_Log("%s: Position={%f,%f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", header.c_str(), pt->Position.X, pt->Position.Y, + pt->Properties->MouseWheelDelta, pt->FrameId, pt->PointerId, WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind)); @@ -281,6 +285,17 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) } } +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if 0 + WINRT_LogPointerEvent("wheel changed", args); +#endif + + if (m_sdlWindowData) { + SDL_SendMouseWheel(m_sdlWindowData->sdlWindow, 0, args->CurrentPoint->Properties->MouseWheelDelta); + } +} + static inline int _lround(float arg) { if (arg >= 0.0f) { return (int)floor(arg + 0.5f); diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 7c03ecafe..d43f42b12 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -39,6 +39,7 @@ protected: 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); From 754df984f0d83a698c41dde7429c8efc9340a4d5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 10 Feb 2013 17:35:38 -0500 Subject: [PATCH 111/264] WinRT: made SDL_RenderClear display the correct color via Direct3D 11.1 --- src/render/direct3d11/SDL_render_d3d11.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 82f798383..251920c3f 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -879,10 +879,10 @@ D3D11_RenderClear(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; const float colorRGBA[] = { - renderer->r, - renderer->g, - renderer->b, - renderer->a + (renderer->r / 255.0f), + (renderer->g / 255.0f), + (renderer->b / 255.0f), + (renderer->a / 255.0f) }; data->d3dContext->ClearRenderTargetView( data->renderTargetView.Get(), From 0f985feb1594415ffecefeb0245962739a4798cf Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 12 Feb 2013 12:57:06 -0500 Subject: [PATCH 112/264] WinRT: fixed bug: SDL_CreateWindow wouldn't work after an initial window was created + destroyed --- src/video/windowsrt/SDL_winrtvideo.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 682ea386e..1d56e0c72 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -222,6 +222,12 @@ 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 reference to the WinRT CoreWindow: CoreWindow ^* windowPointer = ((SDL_WindowData *) window->driverdata)->coreWindow; @@ -234,12 +240,6 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) delete data; data = NULL; } - - if (SDL_WinRTGlobalApp->HasSDLWindowData() && - SDL_WinRTGlobalApp->GetSDLWindowData()->sdlWindow == window) - { - SDL_WinRTGlobalApp->SetSDLWindowData(NULL); - } } SDL_bool From 48ce80d49a5ef058d33de765fd32de91235f49f0 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 12 Feb 2013 19:08:35 -0500 Subject: [PATCH 113/264] WinRT: made d3d 11.1 vertex buffers get created, and updated, when a render op is invoked --- src/render/direct3d11/SDL_render_d3d11.cpp | 61 +++++++++++--------- src/render/direct3d11/SDL_render_d3d11_cpp.h | 1 - 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 251920c3f..303a7da0b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -126,7 +126,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } data->featureLevel = (D3D_FEATURE_LEVEL) 0; - data->vertexCount = 0; data->loadingComplete = false; data->windowSizeInDIPs = XMFLOAT2(0, 0); data->renderTargetSize = XMFLOAT2(0, 0); @@ -354,32 +353,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) } // - // Create a vertex buffer: + // Make sure that the vertex buffer, if already created, gets freed. + // It will be recreated later. // - VertexPositionColor vertices[] = - { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - }; - - data->vertexCount = ARRAYSIZE(vertices); - - D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = vertices; - vertexBufferData.SysMemPitch = 0; - vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); - result = data->d3dDevice->CreateBuffer( - &vertexBufferDesc, - &vertexBufferData, - &data->vertexBuffer - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); - return result; - } + data->vertexBuffer = nullptr; // // Create a sampler to use when drawing textures: @@ -896,7 +873,7 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; - //HRESULT result = S_OK; + HRESULT result = S_OK; rendererData->d3dContext->OMSetRenderTargets( 1, @@ -913,6 +890,36 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 0 ); + // + // Create or update the vertex buffer: + // + VertexPositionColor vertices[] = + { + {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + }; + + if (rendererData->vertexBuffer) { + rendererData->d3dContext->UpdateSubresource(rendererData->vertexBuffer.Get(), 0, NULL, vertices, sizeof(vertices), 0); + } else { + D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; + vertexBufferData.pSysMem = vertices; + vertexBufferData.SysMemPitch = 0; + vertexBufferData.SysMemSlicePitch = 0; + CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); + 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( diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 3933dd735..5811766bd 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -41,7 +41,6 @@ typedef struct Microsoft::WRL::ComPtr pixelShader; Microsoft::WRL::ComPtr mainSampler; D3D_FEATURE_LEVEL featureLevel; - unsigned int vertexCount; bool loadingComplete; // Vertex buffer constants: From 5e66f60ffa7d5f1d016dbd88fe62991566602007 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 12 Feb 2013 20:49:26 -0500 Subject: [PATCH 114/264] WinRT: fixed bug: SDL_RenderCopy was always filling the entire screen --- src/render/direct3d11/SDL_render_d3d11.cpp | 52 ++++++++++++++++++-- src/render/direct3d11/SDL_render_d3d11_cpp.h | 2 + src/video/windowsrt/SimpleVertexShader.hlsl | 4 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 303a7da0b..c724114d5 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -384,6 +384,27 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) 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; + } + // // All done! // @@ -595,6 +616,17 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) } #endif + // + // Update the view matrix + // + XMStoreFloat4x4(&data->vertexShaderConstantsData.view, // (4) + XMMatrixMultiply( + XMMatrixScaling(2.0f / windowWidth, 2.0f / windowHeight, 1.0f), + XMMatrixMultiply( + XMMatrixTranslation(-1, -1, 0), + XMMatrixRotationX(XM_PI) + ))); + // Create a render target view of the swap chain back buffer. ComPtr backBuffer; result = data->swapChain->GetBuffer( @@ -893,12 +925,20 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, // // Create or update the vertex buffer: // - VertexPositionColor vertices[] = + + // WinRT, TODO: get srcrect working in tandem with SDL_RenderCopy, etc. + //SDL_FRect fSrcRect; + //fSrcRect.x = (float)srcrect->x; + //fSrcRect.y = (float)srcrect->y; + //fSrcRect.w = (float)srcrect->w; + //fSrcRect.h = (float)srcrect->h; + + VertexPositionColor vertices[] = { - {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(0.0f, 0.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(0.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->h, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + {XMFLOAT3(dstrect->x + dstrect->h, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f)}, }; if (rendererData->vertexBuffer) { @@ -956,6 +996,8 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, rendererData->d3dContext->PSSetSamplers(0, 1, rendererData->mainSampler.GetAddressOf()); + rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get()); + rendererData->d3dContext->Draw(4, 0); return 0; diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 5811766bd..74aaf46ce 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -26,6 +26,7 @@ struct SDL_VertexShaderConstants { + DirectX::XMFLOAT4X4 view; DirectX::XMFLOAT4X4 projection; }; @@ -40,6 +41,7 @@ typedef struct Microsoft::WRL::ComPtr vertexShader; Microsoft::WRL::ComPtr pixelShader; Microsoft::WRL::ComPtr mainSampler; + Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; bool loadingComplete; diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index 9065ecb03..6b650f1e0 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -1,8 +1,9 @@ -//#pragma pack_matrix( row_major ) +#pragma pack_matrix( row_major ) cbuffer SDL_VertexShaderConstants : register(b0) { + matrix view; matrix projection; }; @@ -24,6 +25,7 @@ VertexShaderOutput main(VertexShaderInput input) float4 pos = float4(input.pos, 1.0f); // Transform the vertex position into projected space. + pos = mul(pos, view); pos = mul(pos, projection); output.pos = pos; From 1d2bde71311bb6db74c12ee129616c6565e42114 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 12 Feb 2013 21:25:26 -0500 Subject: [PATCH 115/264] WinRT: fixed one scaling bug (more remain) in the Direct3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index c724114d5..2a670aebe 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -937,8 +937,8 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, { {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(0.0f, 0.0f)}, {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->h, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - {XMFLOAT3(dstrect->x + dstrect->h, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f)}, }; if (rendererData->vertexBuffer) { From d193b5e36465214e6b94a868a18986ada5f2b2f5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 12 Feb 2013 21:26:04 -0500 Subject: [PATCH 116/264] WinRT: made SDL_CreateRenderer default to using the SW renderer, for now --- src/render/SDL_render.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 0e5edfe36..3937c04fa 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -49,9 +49,9 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_D3D &D3D_RenderDriver, #endif -#if SDL_VIDEO_RENDER_D3D11 - &D3D11_RenderDriver, -#endif +//#if SDL_VIDEO_RENDER_D3D11 +// &D3D11_RenderDriver, +//#endif #if SDL_VIDEO_RENDER_OGL &GL_RenderDriver, #endif @@ -67,7 +67,11 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_NDS &NDS_RenderDriver, #endif - &SW_RenderDriver + &SW_RenderDriver, +#if SDL_VIDEO_RENDER_D3D11 + // WinRT, TODO: once the Direct3D 11.1 renderer is ready, make it be used over the SW renderer via SDL_CreateRenderer(window, -1, 0) + &D3D11_RenderDriver +#endif #endif /* !SDL_RENDER_DISABLED */ }; static char renderer_magic; From c89549682829914ac03c2289eb03e492c6410eba Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 16 Feb 2013 09:10:43 -0500 Subject: [PATCH 117/264] WinRT: implemented SDL_RenderFillRect and SDL_RenderFillRects for the D3D 11.1 renderer --HG-- rename : src/video/windowsrt/SimplePixelShader.hlsl => src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 9 +- .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 7 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 13 +- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 7 +- .../SDL_D3D11_PixelShader_FixedColor.hlsl | 12 + .../SDL_D3D11_PixelShader_TextureCopy.hlsl} | 3 +- src/render/direct3d11/SDL_render_d3d11.cpp | 239 ++++++++++++------ src/render/direct3d11/SDL_render_d3d11_cpp.h | 4 +- src/video/windowsrt/SimpleVertexShader.hlsl | 5 +- 9 files changed, 203 insertions(+), 96 deletions(-) create mode 100644 src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl rename src/{video/windowsrt/SimplePixelShader.hlsl => render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl} (83%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 06bef404f..b209f40b7 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -378,8 +378,13 @@ - - Document + + Pixel + Pixel + Pixel + Pixel + + Pixel Pixel Pixel diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 4735718d2..9298d3b0c 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -598,10 +598,13 @@ - + GPU Shaders - + + GPU Shaders + + GPU Shaders diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 925f5c8a3..73a306f68 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -281,11 +281,18 @@ - - Document - Pixel + Pixel Pixel + Pixel + Pixel + Pixel + Pixel + + + Pixel + Pixel + Pixel Pixel Pixel Pixel diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 2119bc170..f293aea2c 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -1,10 +1,13 @@  - + GPU Shaders - + + GPU Shaders + + GPU Shaders diff --git a/src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl b/src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl new file mode 100644 index 000000000..84de709f5 --- /dev/null +++ b/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; +} diff --git a/src/video/windowsrt/SimplePixelShader.hlsl b/src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl similarity index 83% rename from src/video/windowsrt/SimplePixelShader.hlsl rename to src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl index d0a804439..a48ba426c 100644 --- a/src/video/windowsrt/SimplePixelShader.hlsl +++ b/src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl @@ -4,12 +4,11 @@ SamplerState theSampler : register(s0); struct PixelShaderInput { float4 pos : SV_POSITION; - float2 tex : TEXCOORD0; + float4 color : COLOR0; }; float4 main(PixelShaderInput input) : SV_TARGET { - //return float4(input.color,1.0f); return theTexture.Sample(theSampler, input.tex); } diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 2a670aebe..53b516b58 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -67,8 +67,8 @@ static int D3D11_RenderClear(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_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, @@ -140,7 +140,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderClear = D3D11_RenderClear; //renderer->RenderDrawPoints = D3D11_RenderDrawPoints; //renderer->RenderDrawLines = D3D11_RenderDrawLines; - //renderer->RenderFillRects = D3D11_RenderFillRects; + renderer->RenderFillRects = D3D11_RenderFillRects; renderer->RenderCopy = D3D11_RenderCopy; //renderer->RenderCopyEx = D3D11_RenderCopyEx; //renderer->RenderReadPixels = D3D11_RenderReadPixels; @@ -212,6 +212,34 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) 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 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; +} + // Create resources that depend on the device. HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer) @@ -276,12 +304,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) return result; } - // Start loading GPU shaders: - vector fileData; - // // Load in SDL's one and only vertex shader: // + vector fileData; if (!D3D11_ReadShaderContents(L"SimpleVertexShader.cso", fileData)) { SDL_SetError("Unable to open SDL's vertex shader file."); return E_FAIL; @@ -303,8 +329,9 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "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( @@ -320,21 +347,17 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) } // - // Load in SDL's one and only pixel shader (for now, more are likely to follow): + // Load in SDL's pixel shaders // - if (!D3D11_ReadShaderContents(L"SimplePixelShader.cso", fileData)) { - SDL_SetError("Unable to open SDL's pixel shader file."); - return E_FAIL; + result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_TextureCopy.cso", &data->texturePixelShader); + if (FAILED(result)) { + // D3D11_LoadPixelShader will have aleady set the SDL error + return result; } - result = data->d3dDevice->CreatePixelShader( - &fileData[0], - fileData.size(), - nullptr, - &data->pixelShader - ); + result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_FixedColor.cso", &data->colorPixelShader); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + // D3D11_LoadPixelShader will have aleady set the SDL error return result; } @@ -900,55 +923,21 @@ D3D11_RenderClear(SDL_Renderer * renderer) return 0; } -static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) +static int +D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, + const void * vertexData, unsigned int dataSizeInBytes) { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; HRESULT result = S_OK; - - rendererData->d3dContext->OMSetRenderTargets( - 1, - rendererData->renderTargetView.GetAddressOf(), - nullptr - ); - - rendererData->d3dContext->UpdateSubresource( - rendererData->vertexShaderConstants.Get(), - 0, - NULL, - &rendererData->vertexShaderConstantsData, - 0, - 0 - ); - - // - // Create or update the vertex buffer: - // - - // WinRT, TODO: get srcrect working in tandem with SDL_RenderCopy, etc. - //SDL_FRect fSrcRect; - //fSrcRect.x = (float)srcrect->x; - //fSrcRect.y = (float)srcrect->y; - //fSrcRect.w = (float)srcrect->w; - //fSrcRect.h = (float)srcrect->h; - - VertexPositionColor vertices[] = - { - {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(0.0f, 0.0f)}, - {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(0.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f)}, - }; if (rendererData->vertexBuffer) { - rendererData->d3dContext->UpdateSubresource(rendererData->vertexBuffer.Get(), 0, NULL, vertices, sizeof(vertices), 0); + rendererData->d3dContext->UpdateSubresource(rendererData->vertexBuffer.Get(), 0, NULL, vertexData, dataSizeInBytes, 0); } else { D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; - vertexBufferData.pSysMem = vertices; + vertexBufferData.pSysMem = vertexData; vertexBufferData.SysMemPitch = 0; vertexBufferData.SysMemSlicePitch = 0; - CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); + CD3D11_BUFFER_DESC vertexBufferDesc(dataSizeInBytes, D3D11_BIND_VERTEX_BUFFER); result = rendererData->d3dDevice->CreateBuffer( &vertexBufferDesc, &vertexBufferData, @@ -968,37 +957,121 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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, + rendererData->renderTargetView.GetAddressOf(), + nullptr ); - rendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - rendererData->d3dContext->IASetInputLayout(rendererData->inputLayout.Get()); - - rendererData->d3dContext->VSSetShader( - rendererData->vertexShader.Get(), - nullptr, - 0 - ); - - rendererData->d3dContext->VSSetConstantBuffers( + rendererData->d3dContext->UpdateSubresource( + rendererData->vertexShaderConstants.Get(), 0, - 1, - rendererData->vertexShaderConstants.GetAddressOf() + NULL, + &rendererData->vertexShaderConstantsData, + 0, + 0 ); - - rendererData->d3dContext->PSSetShader( - rendererData->pixelShader.Get(), - nullptr, - 0 - ); - - rendererData->d3dContext->PSSetShaderResources(0, 1, textureData->mainTextureResourceView.GetAddressOf()); - - rendererData->d3dContext->PSSetSamplers(0, 1, rendererData->mainSampler.GetAddressOf()); - +} + +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) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + 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(4, 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); + g = (float)(renderer->g / 255); + b = (float)(renderer->b / 255); + a = (float)(renderer->a / 255); + + D3D11_RenderStartDrawOp(renderer); + + for (int i = 0; i < count; ++i) { + 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); + } + + 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); + + // WinRT, TODO: get srcrect working in tandem with SDL_RenderCopy, etc. + VertexPositionColor vertices[] = { + {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + }; + 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); return 0; } diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 74aaf46ce..bb41761b7 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -39,7 +39,8 @@ typedef struct Microsoft::WRL::ComPtr inputLayout; Microsoft::WRL::ComPtr vertexBuffer; Microsoft::WRL::ComPtr vertexShader; - Microsoft::WRL::ComPtr pixelShader; + Microsoft::WRL::ComPtr texturePixelShader; + Microsoft::WRL::ComPtr colorPixelShader; Microsoft::WRL::ComPtr mainSampler; Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; @@ -69,6 +70,7 @@ struct VertexPositionColor { DirectX::XMFLOAT3 pos; DirectX::XMFLOAT2 tex; + DirectX::XMFLOAT4 color; }; /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/video/windowsrt/SimpleVertexShader.hlsl index 6b650f1e0..c5131007a 100644 --- a/src/video/windowsrt/SimpleVertexShader.hlsl +++ b/src/video/windowsrt/SimpleVertexShader.hlsl @@ -11,12 +11,14 @@ 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) @@ -29,8 +31,9 @@ VertexShaderOutput main(VertexShaderInput input) pos = mul(pos, projection); output.pos = pos; - // Pass through the texture's color without modification. + // Pass through texture coordinates and color values without transformation output.tex = input.tex; + output.color = input.color; return output; } From a6c8d3284344ef5028ef1d156110e09e2cc0e5e9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 16 Feb 2013 16:13:48 -0500 Subject: [PATCH 118/264] WinRT: took out an unneeded depth stencil view from the D3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 53b516b58..510a7e83d 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -672,27 +672,6 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return result; } - // Create a depth stencil view. - CD3D11_TEXTURE2D_DESC depthStencilDesc( - DXGI_FORMAT_D24_UNORM_S8_UINT, - static_cast(data->renderTargetSize.x), - static_cast(data->renderTargetSize.y), - 1, - 1, - D3D11_BIND_DEPTH_STENCIL - ); - - ComPtr depthStencil; - result = data->d3dDevice->CreateTexture2D( - &depthStencilDesc, - nullptr, - &depthStencil - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); - return result; - } - // Set the rendering viewport to target the entire window. CD3D11_VIEWPORT viewport( 0.0f, From bafdb176fa2e7dd01ba59b0214cbd52a6d901412 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 16 Feb 2013 16:53:06 -0500 Subject: [PATCH 119/264] WinRT: D3D 11.1 blending mode support added; FillRects coloring bug-fix --- src/render/direct3d11/SDL_render_d3d11.cpp | 92 ++++++++++++++++++-- src/render/direct3d11/SDL_render_d3d11_cpp.h | 3 + 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 510a7e83d..0d7670420 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -240,6 +240,37 @@ D3D11_LoadPixelShader(SDL_Renderer * renderer, 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) @@ -428,6 +459,42 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) 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! // @@ -960,6 +1027,21 @@ D3D11_RenderStartDrawOp(SDL_Renderer * renderer) 0, 0 ); + + switch (renderer->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 @@ -994,12 +1076,12 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; float r, g, b, a; - r = (float)(renderer->r / 255); - g = (float)(renderer->g / 255); - b = (float)(renderer->b / 255); - a = (float)(renderer->a / 255); + r = (float)(renderer->r / 255.0f); + g = (float)(renderer->g / 255.0f); + b = (float)(renderer->b / 255.0f); + a = (float)(renderer->a / 255.0f); - D3D11_RenderStartDrawOp(renderer); + D3D11_RenderStartDrawOp(renderer); for (int i = 0; i < count; ++i) { VertexPositionColor vertices[] = { diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index bb41761b7..eebc97200 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -41,6 +41,9 @@ typedef struct Microsoft::WRL::ComPtr vertexShader; Microsoft::WRL::ComPtr texturePixelShader; Microsoft::WRL::ComPtr colorPixelShader; + Microsoft::WRL::ComPtr blendModeBlend; + Microsoft::WRL::ComPtr blendModeAdd; + Microsoft::WRL::ComPtr blendModeMod; Microsoft::WRL::ComPtr mainSampler; Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; From 19ff37c4b370acd766dec0c14dbb6ba69395f70d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 17 Feb 2013 11:09:07 -0500 Subject: [PATCH 120/264] WinRT: made SDL_RenderSetViewport work with the D3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 123 +++++++++++++-------- 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 0d7670420..8cffaa237 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -655,42 +655,18 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) { case DisplayOrientations::Landscape: rotation = DXGI_MODE_ROTATION_IDENTITY; - 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: rotation = DXGI_MODE_ROTATION_ROTATE270; - 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; case DisplayOrientations::LandscapeFlipped: rotation = DXGI_MODE_ROTATION_ROTATE180; - 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: rotation = DXGI_MODE_ROTATION_ROTATE90; - 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; default: @@ -706,17 +682,6 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) } #endif - // - // Update the view matrix - // - XMStoreFloat4x4(&data->vertexShaderConstantsData.view, // (4) - XMMatrixMultiply( - XMMatrixScaling(2.0f / windowWidth, 2.0f / windowHeight, 1.0f), - XMMatrixMultiply( - XMMatrixTranslation(-1, -1, 0), - XMMatrixRotationX(XM_PI) - ))); - // Create a render target view of the swap chain back buffer. ComPtr backBuffer; result = data->swapChain->GetBuffer( @@ -739,15 +704,10 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return result; } - // Set the rendering viewport to target the entire window. - CD3D11_VIEWPORT viewport( - 0.0f, - 0.0f, - data->renderTargetSize.x, - data->renderTargetSize.y - ); - - data->d3dContext->RSSetViewports(1, &viewport); + if (D3D11_UpdateViewport(renderer) != 0) { + // D3D11_UpdateViewport will set the SDL error if it fails. + return E_FAIL; + } return S_OK; } @@ -949,6 +909,81 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 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( // 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; + + 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( // 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; + + default: + SDL_SetError("An unknown DisplayOrientation is being used"); + return -1; + } + + // + // Update the view matrix + // + float windowWidth = (float) renderer->viewport.w; + float windowHeight = (float) renderer->viewport.h; + XMStoreFloat4x4(&data->vertexShaderConstantsData.view, // (4) + XMMatrixMultiply( + XMMatrixScaling(2.0f / windowWidth, 2.0f / windowHeight, 1.0f), + XMMatrixMultiply( + XMMatrixTranslation(-1, -1, 0), + XMMatrixRotationX(XM_PI) + ))); + + D3D11_VIEWPORT viewport; + memset(&viewport, 0, sizeof(viewport)); + viewport.TopLeftX = (float) renderer->viewport.x; + viewport.TopLeftY = (float) renderer->viewport.y; + viewport.Width = (float) renderer->viewport.w; + viewport.Height = (float) renderer->viewport.h; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + data->d3dContext->RSSetViewports(1, &viewport); + return 0; } From 4a906d9edfc9a0f6cca0e8397a568b6d7818f955 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 17 Feb 2013 23:23:59 -0500 Subject: [PATCH 121/264] WinRT: bug fixes for device orientation + Direct3D 11.1 rendering --- src/render/direct3d11/SDL_render_d3d11.cpp | 90 ++++++++++++++++++---- src/video/windowsrt/SDL_WinRTApp.cpp | 42 ++++++++-- src/video/windowsrt/SDL_WinRTApp.h | 2 + src/video/windowsrt/SDL_winrtvideo.cpp | 4 +- 4 files changed, 115 insertions(+), 23 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 8cffaa237..e742eed0b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -30,6 +30,8 @@ extern "C" { #include "SDL_system.h" #include "SDL_syswm.h" #include "../SDL_sysrender.h" +#include "SDL_log.h" +#include "../../video/SDL_sysvideo.h" //#include "stdio.h" } @@ -561,7 +563,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) // landscape-oriented width and height. If the window is in a portrait // orientation, the dimensions must be reversed. data->orientation = DisplayProperties::CurrentOrientation; - bool swapDimensions = + const bool swapDimensions = data->orientation == DisplayOrientations::Portrait || data->orientation == DisplayOrientations::PortraitFlipped; data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth; @@ -930,9 +932,9 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) break; case DisplayOrientations::Portrait: - data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 270-degree Z-rotation - 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f, + 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 ); @@ -948,9 +950,9 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) break; case DisplayOrientations::PortraitFlipped: - data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 90-degree Z-rotation - 0.0f, 1.0f, 0.0f, 0.0f, - -1.0f, 0.0f, 0.0f, 0.0f, + 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 ); @@ -964,26 +966,58 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // // Update the view matrix // - float windowWidth = (float) renderer->viewport.w; - float windowHeight = (float) renderer->viewport.h; - XMStoreFloat4x4(&data->vertexShaderConstantsData.view, // (4) + float viewportWidth = (float) renderer->viewport.w; + float viewportHeight = (float) renderer->viewport.h; + XMStoreFloat4x4(&data->vertexShaderConstantsData.view, XMMatrixMultiply( - XMMatrixScaling(2.0f / windowWidth, 2.0f / windowHeight, 1.0f), + XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f), XMMatrixMultiply( XMMatrixTranslation(-1, -1, 0), XMMatrixRotationX(XM_PI) ))); + + // + // 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 = (float) renderer->viewport.x; - viewport.TopLeftY = (float) renderer->viewport.y; - viewport.Width = (float) renderer->viewport.w; - viewport.Height = (float) renderer->viewport.h; + 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; } @@ -1116,9 +1150,33 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, b = (float)(renderer->b / 255.0f); a = (float)(renderer->a / 255.0f); - D3D11_RenderStartDrawOp(renderer); +#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); +#endif for (int i = 0; i < count; ++i) { + D3D11_RenderStartDrawOp(renderer); + +#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)}, diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index f5fd02fa4..478297d9c 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -51,6 +51,7 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), m_sdlWindowData(NULL), + m_sdlVideoDevice(NULL), m_useRelativeMouseMode(false) { } @@ -146,11 +147,35 @@ void SDL_WinRTApp::Uninitialize() void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { - SDL_SendWindowEvent( - m_sdlWindowData->sdlWindow, - SDL_WINDOWEVENT_RESIZED, - (int) ceil(args->Size.Width), - (int) ceil(args->Size.Height)); +#if 0 + SDL_Log("%s, {%f,%f}\n", __FUNCTION__, args->Size.Width, args->Size.Height); +#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); + + 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); + } } void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) @@ -739,11 +764,16 @@ void SDL_WinRTApp::SetRelativeMouseMode(bool enable) m_useRelativeMouseMode = enable; } -void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData) +void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData * windowData) { m_sdlWindowData = windowData; } +void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice) +{ + m_sdlVideoDevice = videoDevice; +} + IFrameworkView^ Direct3DApplicationSource::CreateView() { // TODO, WinRT: see if this function (CreateView) can ever get called diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index d43f42b12..0a12e327e 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -26,6 +26,7 @@ internal: 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: @@ -49,6 +50,7 @@ private: bool m_windowClosed; bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; + const SDL_VideoDevice* m_sdlVideoDevice; bool m_useRelativeMouseMode; }; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 1d56e0c72..0e640a4ba 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -74,6 +74,7 @@ WINRT_Available(void) static void WINRT_DeleteDevice(SDL_VideoDevice * device) { + SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL); SDL_free(device); } @@ -103,9 +104,10 @@ WINRT_CreateDevice(int devindex) //device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer; //device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; - device->free = WINRT_DeleteDevice; + SDL_WinRTGlobalApp->SetSDLVideoDevice(device); + return device; } From 0cc80148f4078b24226ffa8b8b7dc3aaa1d88d97 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 19 Feb 2013 22:07:07 -0500 Subject: [PATCH 122/264] WinRT: another device-rotation and rendering fix --- src/render/direct3d11/SDL_render_d3d11.cpp | 8 ++++-- src/video/windowsrt/SDL_WinRTApp.cpp | 31 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index e742eed0b..540c1f5fb 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -975,6 +975,9 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) XMMatrixTranslation(-1, -1, 0), XMMatrixRotationX(XM_PI) ))); +#if 0 + data->vertexShaderConstantsData.view = XMMatrixIdentity(); +#endif // // Update the Direct3D viewport, which seems to be aligned to the @@ -1152,14 +1155,15 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, #if 0 // Set up a test pattern: - SDL_FRect rects[] = { + 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); + count = sizeof(_rects) / sizeof(SDL_FRect); +#define rects _rects #endif for (int i = 0; i < count; ++i) { diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 478297d9c..cc5b21f6c 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -12,6 +12,8 @@ extern "C" { #include "../../events/scancodes_windows.h" #include "SDL_events.h" #include "SDL_log.h" +#include "SDL_render.h" +#include "../../render/SDL_sysrender.h" } #include @@ -168,6 +170,30 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven 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( @@ -175,6 +201,11 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven SDL_WINDOWEVENT_RESIZED, windowWidth, windowHeight); + + // Viewport hack, part two: + if (usingD3D11Renderer) { + rendererForMainWindow->resized = wasD3D11RendererResized; + } } } From 8afd520d295d318f402d55ba88efd54679a9526e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 22 Feb 2013 23:23:53 -0500 Subject: [PATCH 123/264] WinRT: allowed setting the device rotation preference via SDL_HINT_ORIENTATIONS --- src/video/windowsrt/SDL_WinRTApp.cpp | 64 +++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index cc5b21f6c..ead5e33ab 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -14,10 +14,15 @@ extern "C" { #include "SDL_log.h" #include "SDL_render.h" #include "../../render/SDL_sysrender.h" +#include "SDL_hints.h" +#include "../../SDL_hints_c.h" } #include #include +#include + +using namespace Windows::Graphics::Display; // TODO, WinRT: Remove reference(s) to BasicTimer.h //#include "BasicTimer.h" @@ -28,6 +33,55 @@ extern "C" { typedef int (*SDL_WinRT_MainFunction)(int, char **); static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; +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; +} + // HACK, DLudwig: record a reference to the global, Windows RT 'app'/view. // SDL/WinRT will use this throughout its code. // @@ -68,6 +122,14 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Resuming += ref new EventHandler(this, &SDL_WinRTApp::OnResuming); + + // 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::SetWindow(CoreWindow^ window) @@ -661,7 +723,7 @@ TranslateKeycode(int keycode) void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { -#if 0 +#if 1 SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\n", (args->Handled ? "1" : "0"), (args->KeyStatus.IsExtendedKey ? "1" : "0"), From cb6f37ccf7daa5d2a04106d7cee1e218f2a485c0 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 22 Feb 2013 23:44:34 -0500 Subject: [PATCH 124/264] WinRT: minor cleanup in top-level app code --- src/video/windowsrt/SDL_WinRTApp.cpp | 45 ++++++++++++---------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index ead5e33ab..bd8592c90 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -22,10 +22,17 @@ extern "C" { #include #include +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; - -// TODO, WinRT: Remove reference(s) to BasicTimer.h -//#include "BasicTimer.h" +using namespace Windows::Foundation; +using namespace Windows::System; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; // HACK, DLudwig: The C-style main() will get loaded via the app's // WinRT-styled main(), which is part of SDLmain_for_WinRT.cpp. @@ -33,6 +40,15 @@ using namespace Windows::Graphics::Display; 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; + static void WINRT_SetDisplayOrientationsPreference(const char *name, const char *oldValue, const char *newValue) { SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); @@ -82,27 +98,6 @@ static void WINRT_SetDisplayOrientationsPreference(const char *name, const char DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags; } -// 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; - -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::UI::Core; -using namespace Windows::UI::Input; -using namespace Windows::System; -using namespace Windows::Foundation; -using namespace Windows::Graphics::Display; -using namespace concurrency; - SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), @@ -170,8 +165,6 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->KeyUp += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); - - //m_renderer->Initialize(CoreWindow::GetForCurrentThread()); // DLudwig: moved this call to WINRT_CreateWindow, likely elsewhere in the future } void SDL_WinRTApp::Load(Platform::String^ entryPoint) From 44ca4f35a471a2d697e4c6b8f0ac308ccdf52b90 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 22 Feb 2013 23:53:37 -0500 Subject: [PATCH 125/264] WinRT: more minor code cleanups --- src/video/windowsrt/SDL_WinRTApp.cpp | 50 ++++++++++++++------------ src/video/windowsrt/SDL_WinRTApp.h | 9 ----- src/video/windowsrt/SDL_winrtmouse.cpp | 1 + src/video/windowsrt/SDL_winrtvideo.cpp | 2 ++ 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index bd8592c90..9cb0acba8 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -49,6 +49,34 @@ static SDL_WinRT_MainFunction SDL_WinRT_main = nullptr; // 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); @@ -859,25 +887,3 @@ void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice) { m_sdlVideoDevice = videoDevice; } - -IFrameworkView^ Direct3DApplicationSource::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 Direct3DApplicationSource(); - CoreApplication::Run(direct3DApplicationSource); - return 0; -} diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 0a12e327e..9503af7d7 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -2,9 +2,6 @@ #include "SDLmain_WinRT_common.h" #include "SDL_winrtvideo.h" -#include - -using namespace Windows::UI::Core; ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { @@ -53,9 +50,3 @@ private: const SDL_VideoDevice* m_sdlVideoDevice; bool m_useRelativeMouseMode; }; - -ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource -{ -public: - virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); -}; diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/windowsrt/SDL_winrtmouse.cpp index 5d6bcc607..e0450c655 100644 --- a/src/video/windowsrt/SDL_winrtmouse.cpp +++ b/src/video/windowsrt/SDL_winrtmouse.cpp @@ -32,6 +32,7 @@ extern "C" { #include "SDL_WinRTApp.h" #include "SDL_winrtmouse.h" +using namespace Windows::UI::Core; using Windows::UI::Core::CoreCursor; extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 0e640a4ba..846debb50 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -43,6 +43,8 @@ extern "C" { #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse.h" +using namespace Windows::UI::Core; + /* On Windows, windows.h defines CreateWindow */ #ifdef CreateWindow #undef CreateWindow From c47e35498e0049cb4186d643ec3b369f67ba016e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 23 Feb 2013 18:08:27 -0500 Subject: [PATCH 126/264] WinRT: turned off some keyboard debugging code that got inadvertently left on --- src/video/windowsrt/SDL_WinRTApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 9cb0acba8..14c93b13c 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -744,7 +744,7 @@ TranslateKeycode(int keycode) void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { -#if 1 +#if 0 SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\n", (args->Handled ? "1" : "0"), (args->KeyStatus.IsExtendedKey ? "1" : "0"), From 52fd9b7f711cb223d054fc32ecfd5d2a8566139e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 23 Feb 2013 20:12:14 -0500 Subject: [PATCH 127/264] WinRT: build fixes --- include/SDL_config_windowsrt.h | 3 ++- src/file/SDL_rwops.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 98f01579e..a21777451 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -104,7 +104,7 @@ typedef unsigned int uintptr_t; #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 -#define HAVE_ITOA 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 @@ -134,6 +134,7 @@ typedef unsigned int uintptr_t; #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 diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 1aab8e987..e521588db 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -325,6 +325,10 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence) 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)); From 76a8817338b00c6cb90898ad126a8753896a0943 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 23 Feb 2013 20:22:19 -0500 Subject: [PATCH 128/264] WinRT: made mouse wheel motion increments more closely match their values on Win32 --- src/video/windowsrt/SDL_WinRTApp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 14c93b13c..8780cac7e 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -431,7 +431,9 @@ void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ a #endif if (m_sdlWindowData) { - SDL_SendMouseWheel(m_sdlWindowData->sdlWindow, 0, args->CurrentPoint->Properties->MouseWheelDelta); + // 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, motion); } } From 5520a12a338210fbbc5a383a99aa043d007a0af1 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 23 Feb 2013 22:58:09 -0500 Subject: [PATCH 129/264] WinRT: added support for alpha-blended texture rendering --- src/render/direct3d11/SDL_render_d3d11.cpp | 49 ++++++++++++++++------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 540c1f5fb..52c40583a 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -89,18 +89,22 @@ HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer); -extern "C" { - SDL_RenderDriver D3D11_RenderDriver = { +// WinRT, TODO: fill in the Direct3D 11.1 renderer's max texture width and height +extern "C" SDL_RenderDriver D3D11_RenderDriver = { D3D11_CreateRenderer, { - "direct3d 11.1", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), - 1, - {SDL_PIXELFORMAT_RGB888}, - 0, - 0} - }; -} + "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 + 0 // max_texture_height + } +}; + //typedef struct //{ @@ -782,6 +786,20 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; D3D11_TextureData *textureData; HRESULT result; + DXGI_FORMAT textureFormat = DXGI_FORMAT_UNKNOWN; + + switch (texture->format) { + case SDL_PIXELFORMAT_ARGB8888: + textureFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + case SDL_PIXELFORMAT_RGB888: + textureFormat = DXGI_FORMAT_B8G8R8X8_UNORM; + break; + default: + SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", + __FUNCTION__, texture->format); + return -1; + } textureData = new D3D11_TextureData; if (!textureData) { @@ -799,7 +817,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) textureDesc.Height = texture->h; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + textureDesc.Format = textureFormat; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Usage = D3D11_USAGE_DYNAMIC; @@ -1099,8 +1117,13 @@ D3D11_RenderStartDrawOp(SDL_Renderer * renderer) 0, 0 ); +} - switch (renderer->blendMode) { +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; @@ -1168,6 +1191,7 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, for (int i = 0; i < count; ++i) { D3D11_RenderStartDrawOp(renderer); + D3D11_RenderSetBlendMode(renderer, renderer->blendMode); #if 0 // Set colors for the test pattern: @@ -1211,6 +1235,7 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; D3D11_RenderStartDrawOp(renderer); + D3D11_RenderSetBlendMode(renderer, texture->blendMode); // WinRT, TODO: get srcrect working in tandem with SDL_RenderCopy, etc. VertexPositionColor vertices[] = { From a53fe847a11158aed51cfc033ce0b2c025a79cc7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 10:02:57 -0500 Subject: [PATCH 130/264] WinRT: cleaned up headers in src\video\windowsrt\ --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 2 -- .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 ----- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 2 -- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 ----- src/video/windowsrt/DirectXHelper.h | 17 ------------- src/video/windowsrt/SDL_WinRTApp.cpp | 24 ++++++++++--------- src/video/windowsrt/SDL_WinRTApp.h | 3 +-- src/video/windowsrt/SDLmain_WinRT_common.h | 15 ------------ 8 files changed, 14 insertions(+), 61 deletions(-) delete mode 100644 src/video/windowsrt/DirectXHelper.h delete mode 100644 src/video/windowsrt/SDLmain_WinRT_common.h diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index b209f40b7..33fcf9856 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -244,8 +244,6 @@ - - diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 9298d3b0c..f2b727195 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -321,12 +321,6 @@ Source Files - - Source Files - - - Source Files - Source Files diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 73a306f68..afdc18d2c 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -273,8 +273,6 @@ - - diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index f293aea2c..41ec53576 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -578,12 +578,6 @@ Source Files - - Source Files - - - Source Files - Source Files diff --git a/src/video/windowsrt/DirectXHelper.h b/src/video/windowsrt/DirectXHelper.h deleted file mode 100644 index fc6e820f8..000000000 --- a/src/video/windowsrt/DirectXHelper.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace DX -{ - inline void ThrowIfFailed(HRESULT hr) - { - if (FAILED(hr)) - { - // Set a breakpoint on this line to catch Win32 API errors. - throw Platform::Exception::CreateException(hr); - } - } -} diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 8780cac7e..f8e9b444a 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -1,26 +1,28 @@ -#include "SDLmain_WinRT_common.h" -#include "SDL_WinRTApp.h" + +#include +#include +#include + #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 "../../events/scancodes_windows.h" -#include "SDL_events.h" -#include "SDL_log.h" -#include "SDL_render.h" #include "../../render/SDL_sysrender.h" -#include "SDL_hints.h" -#include "../../SDL_hints_c.h" } -#include -#include -#include +#include "SDL_winrtvideo.h" +#include "SDL_WinRTApp.h" using namespace concurrency; using namespace std; diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 9503af7d7..8712d51e0 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -1,7 +1,6 @@ #pragma once -#include "SDLmain_WinRT_common.h" -#include "SDL_winrtvideo.h" +struct SDL_WindowData; ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { diff --git a/src/video/windowsrt/SDLmain_WinRT_common.h b/src/video/windowsrt/SDLmain_WinRT_common.h deleted file mode 100644 index 4867b7a94..000000000 --- a/src/video/windowsrt/SDLmain_WinRT_common.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "../SDL_sysvideo.h" -} - -#include "SDL_winrtvideo.h" - From 046494640937fef034e598b920d640dbb52fa062 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 10:11:58 -0500 Subject: [PATCH 131/264] WinRT: moved the default vertex shader into the Direct3D 11.1 renderer's folder --HG-- rename : src/video/windowsrt/SimpleVertexShader.hlsl => src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 3 +-- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 +++--- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 5 ++--- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +++--- .../direct3d11/SDL_D3D11_VertexShader_Default.hlsl} | 0 src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- 6 files changed, 10 insertions(+), 12 deletions(-) rename src/{video/windowsrt/SimpleVertexShader.hlsl => render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl} (100%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 33fcf9856..c8c7e55dd 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -388,8 +388,7 @@ Pixel Pixel - - Document + Vertex Vertex Vertex diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index f2b727195..3471b4635 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -592,14 +592,14 @@ - - GPU Shaders - GPU Shaders GPU Shaders + + GPU Shaders + \ No newline at end of file diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index afdc18d2c..26489fd08 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -295,11 +295,10 @@ Pixel Pixel - - Document - Vertex + Vertex Vertex + Vertex Vertex Vertex Vertex diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 41ec53576..e8a704b70 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -1,15 +1,15 @@  - - GPU Shaders - GPU Shaders GPU Shaders + + GPU Shaders + diff --git a/src/video/windowsrt/SimpleVertexShader.hlsl b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl similarity index 100% rename from src/video/windowsrt/SimpleVertexShader.hlsl rename to src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 52c40583a..289deee26 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -345,7 +345,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // Load in SDL's one and only vertex shader: // vector fileData; - if (!D3D11_ReadShaderContents(L"SimpleVertexShader.cso", fileData)) { + if (!D3D11_ReadShaderContents(L"SDL_D3D11_VertexShader_Default.cso", fileData)) { SDL_SetError("Unable to open SDL's vertex shader file."); return E_FAIL; } From 0a9710e1e53def6dc226ae3721c3ad0ba463decb Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 10:14:23 -0500 Subject: [PATCH 132/264] WinRT: made the Direct3D 11.1 renderer correctly report its status regarding render-to-texture (not supported, yet) --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 289deee26..ede0568ba 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -94,7 +94,7 @@ extern "C" SDL_RenderDriver D3D11_RenderDriver = { D3D11_CreateRenderer, { "direct3d 11.1", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), // flags. see SDL_RendererFlags + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), // flags. see SDL_RendererFlags 2, // num_texture_formats { // texture_formats SDL_PIXELFORMAT_RGB888, From 8d55f67a2ff88fa66dc2e0b678e4b3d40cad555d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 10:30:12 -0500 Subject: [PATCH 133/264] WinRT: allowed for querying of max texture size (via Direct3D 11.1) --- src/render/direct3d11/SDL_render_d3d11.cpp | 31 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index ede0568ba..095a73f2c 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -89,7 +89,6 @@ HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer); HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer); -// WinRT, TODO: fill in the Direct3D 11.1 renderer's max texture width and height extern "C" SDL_RenderDriver D3D11_RenderDriver = { D3D11_CreateRenderer, { @@ -100,8 +99,8 @@ extern "C" SDL_RenderDriver D3D11_RenderDriver = { SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_ARGB8888 }, - 0, // max_texture_width - 0 // max_texture_height + 0, // max_texture_width: will be filled in later + 0 // max_texture_height: will be filled in later } }; @@ -341,6 +340,32 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) 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: // From 8a321ffe64d46fc05b5a1e3a6daeaa5fb450c031 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 10:41:35 -0500 Subject: [PATCH 134/264] WinRT: made GPU shaders get compiled at a lower level, for compatibility: 4_0_level_9_1 --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 26489fd08..7c869f41b 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -286,6 +286,12 @@ Pixel Pixel Pixel + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 Pixel @@ -294,6 +300,12 @@ Pixel Pixel Pixel + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 Vertex @@ -302,6 +314,12 @@ Vertex Vertex Vertex + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 + 4.0_level_9_1 From 88be4332559f14ce3d8f6d27cd343c1fc7101507 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Feb 2013 12:27:28 -0500 Subject: [PATCH 135/264] WinRT: made the D3D 11.1 renderer respect the 'srcrect' parameter of SDL_RenderCopy --- src/render/direct3d11/SDL_render_d3d11.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 095a73f2c..c606c175d 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1261,13 +1261,17 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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; - // WinRT, TODO: get srcrect working in tandem with SDL_RenderCopy, etc. VertexPositionColor vertices[] = { - {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, }; if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) { return -1; From 7cb5ae426fa20fa6321774d7d5241989f6e0fd65 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Mar 2013 21:19:26 -0400 Subject: [PATCH 136/264] WinRT: added line drawing support to the Direct3D 11.1 rendering backend --- src/render/direct3d11/SDL_render_d3d11.cpp | 67 ++++++++++++++++++---- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index c606c175d..b2c8d1059 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -67,8 +67,8 @@ 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_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, @@ -144,7 +144,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->UpdateViewport = D3D11_UpdateViewport; renderer->RenderClear = D3D11_RenderClear; //renderer->RenderDrawPoints = D3D11_RenderDrawPoints; - //renderer->RenderDrawLines = D3D11_RenderDrawLines; + renderer->RenderDrawLines = D3D11_RenderDrawLines; renderer->RenderFillRects = D3D11_RenderFillRects; renderer->RenderCopy = D3D11_RenderCopy; //renderer->RenderCopyEx = D3D11_RenderCopyEx; @@ -1090,15 +1090,25 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - - if (rendererData->vertexBuffer) { + 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; - CD3D11_BUFFER_DESC vertexBufferDesc(dataSizeInBytes, D3D11_BIND_VERTEX_BUFFER); + result = rendererData->d3dDevice->CreateBuffer( &vertexBufferDesc, &vertexBufferData, @@ -1178,7 +1188,8 @@ D3D11_SetPixelShader(SDL_Renderer * renderer, static void D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, - D3D11_PRIMITIVE_TOPOLOGY primitiveTopology) + D3D11_PRIMITIVE_TOPOLOGY primitiveTopology, + UINT vertexCount) { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; rendererData->d3dContext->IASetPrimitiveTopology(primitiveTopology); @@ -1186,7 +1197,43 @@ D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, 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(4, 0); + rendererData->d3dContext->Draw(vertexCount, 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 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 @@ -1246,7 +1293,7 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, nullptr, nullptr); - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); } return 0; @@ -1283,7 +1330,7 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, textureData->mainTextureResourceView.Get(), rendererData->mainSampler.Get()); - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); return 0; } From b7476a788ad56588513038637cb38e883680591f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 24 Mar 2013 21:57:40 -0400 Subject: [PATCH 137/264] WinRT: added point drawing support to the Direct3D 11.1 rendering backend --- src/render/direct3d11/SDL_render_d3d11.cpp | 42 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index b2c8d1059..21807137f 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -65,8 +65,8 @@ static int D3D11_UpdateTexture(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_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, @@ -143,7 +143,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) //renderer->SetRenderTarget = D3D11_SetRenderTarget; renderer->UpdateViewport = D3D11_UpdateViewport; renderer->RenderClear = D3D11_RenderClear; - //renderer->RenderDrawPoints = D3D11_RenderDrawPoints; + renderer->RenderDrawPoints = D3D11_RenderDrawPoints; renderer->RenderDrawLines = D3D11_RenderDrawLines; renderer->RenderFillRects = D3D11_RenderFillRects; renderer->RenderCopy = D3D11_RenderCopy; @@ -1200,6 +1200,42 @@ D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, 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 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) From da65f35eaf00e444f3e1b0ef013856aea89e9818 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 31 Mar 2013 11:16:31 -0400 Subject: [PATCH 138/264] WinRT: added SDL_LockTexture and SDL_UnlockTexture support to the D3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 99 +++++++++++++++++++- src/render/direct3d11/SDL_render_d3d11_cpp.h | 3 + 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 21807137f..37699c21b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -59,9 +59,9 @@ 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 *pixels, int pitch); -//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_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); @@ -138,8 +138,8 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->WindowEvent = D3D11_WindowEvent; renderer->CreateTexture = D3D11_CreateTexture; renderer->UpdateTexture = D3D11_UpdateTexture; - //renderer->LockTexture = D3D11_LockTexture; - //renderer->UnlockTexture = D3D11_UnlockTexture; + renderer->LockTexture = D3D11_LockTexture; + renderer->UnlockTexture = D3D11_UnlockTexture; //renderer->SetRenderTarget = D3D11_SetRenderTarget; renderer->UpdateViewport = D3D11_UpdateViewport; renderer->RenderClear = D3D11_RenderClear; @@ -832,6 +832,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } textureData->pixelFormat = SDL_AllocFormat(texture->format); + textureData->lockedTexturePosition = XMINT2(0, 0); texture->driverdata = textureData; @@ -951,6 +952,94 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 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_UpdateViewport(SDL_Renderer * renderer) { diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index eebc97200..a879fdeba 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -23,6 +23,7 @@ #include #include #include +#include struct SDL_VertexShaderConstants { @@ -67,6 +68,8 @@ typedef struct Microsoft::WRL::ComPtr mainTexture; Microsoft::WRL::ComPtr mainTextureResourceView; SDL_PixelFormat * pixelFormat; + Microsoft::WRL::ComPtr stagingTexture; + DirectX::XMINT2 lockedTexturePosition; } D3D11_TextureData; struct VertexPositionColor From 2e29d030b959dcfe7c30dab6ff9aca1e41bc6060 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 31 Mar 2013 11:44:50 -0400 Subject: [PATCH 139/264] WinRT: removed code that unnecessarily set a blank D3D 11.1 texture's contents --- src/render/direct3d11/SDL_render_d3d11.cpp | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 37699c21b..00e532478 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -836,8 +836,6 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture->driverdata = textureData; - const int pixelSizeInBytes = textureData->pixelFormat->BytesPerPixel; - D3D11_TEXTURE2D_DESC textureDesc = {0}; textureDesc.Width = texture->w; textureDesc.Height = texture->h; @@ -851,24 +849,26 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; textureDesc.MiscFlags = 0; - const int numPixels = textureDesc.Width * textureDesc.Height; - std::vector initialTexturePixels(numPixels * pixelSizeInBytes, 0x00); - +#if 0 // Fill the texture with a non-black color, for debugging purposes: - //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; - //} - + const int numPixels = textureDesc.Width * textureDesc.Height; + const int pixelSizeInBytes = textureData->pixelFormat->BytesPerPixel; + std::vector 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, - &initialTextureData, + NULL, // &initialTextureData, &textureData->mainTexture ); if (FAILED(result)) { From df42edd5e127e7bd81d6a64082b05311785f4c81 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 1 Apr 2013 21:33:06 -0400 Subject: [PATCH 140/264] WinRT: made WinRT path retrieval be available in both UCS-2 and UTF-8 flavors --- include/SDL_system.h | 20 +++++++++++++++++++- src/core/windowsrt/SDL_winrtpaths.cpp | 25 ++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/SDL_system.h b/include/SDL_system.h index 99bd19982..99ca46383 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -135,7 +135,25 @@ typedef enum * SDL_WinRT_Path for more information on which path types are * supported where. */ -extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFileSystemPath(SDL_WinRT_Path pathType); +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__ */ diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/windowsrt/SDL_winrtpaths.cpp index eecfd9652..4c10b78b7 100644 --- a/src/core/windowsrt/SDL_winrtpaths.cpp +++ b/src/core/windowsrt/SDL_winrtpaths.cpp @@ -14,12 +14,13 @@ extern "C" { } #include +#include using namespace std; using namespace Windows::Storage; extern "C" const wchar_t * -SDL_WinRTGetFileSystemPath(SDL_WinRT_Path pathType) +SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType) { switch (pathType) { case SDL_WINRT_PATH_INSTALLED_LOCATION: @@ -68,4 +69,26 @@ SDL_WinRTGetFileSystemPath(SDL_WinRT_Path pathType) return NULL; } +extern "C" const char * +SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType) +{ + typedef unordered_map 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__ */ From 33ab98cceee132d49aa967284340182f5921993e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 1 Apr 2013 21:34:47 -0400 Subject: [PATCH 141/264] WinRT: implemented SDL_RenderReadPixels in Direct3D 11.1 --- src/render/direct3d11/SDL_render_d3d11.cpp | 149 ++++++++++++++++++--- 1 file changed, 131 insertions(+), 18 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 00e532478..2ca8054f0 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -76,8 +76,8 @@ static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, //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 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); @@ -105,6 +105,32 @@ extern "C" SDL_RenderDriver D3D11_RenderDriver = { }; +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; @@ -148,7 +174,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderFillRects = D3D11_RenderFillRects; renderer->RenderCopy = D3D11_RenderCopy; //renderer->RenderCopyEx = D3D11_RenderCopyEx; - //renderer->RenderReadPixels = D3D11_RenderReadPixels; + renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; renderer->DestroyTexture = D3D11_DestroyTexture; renderer->DestroyRenderer = D3D11_DestroyRenderer; @@ -206,10 +232,10 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) wstring fileName; #if WINAPI_FAMILY == WINAPI_FAMILY_APP - fileName = SDL_WinRTGetFileSystemPath(SDL_WINRT_PATH_INSTALLED_LOCATION); + fileName = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_INSTALLED_LOCATION); fileName += L"\\SDL_VS2012_WinRT\\"; #elif WINAPI_FAMILY == WINAPI_PHONE_APP - fileName = SDL_WinRTGetFileSystemPath(SDL_WINRT_PATH_INSTALLED_LOCATION); + fileName = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_INSTALLED_LOCATION); fileName += L"\\"; #endif // WinRT, TODO: test Direct3D 11.1 shader loading on Win32 @@ -811,19 +837,11 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; D3D11_TextureData *textureData; HRESULT result; - DXGI_FORMAT textureFormat = DXGI_FORMAT_UNKNOWN; - - switch (texture->format) { - case SDL_PIXELFORMAT_ARGB8888: - textureFormat = DXGI_FORMAT_B8G8R8A8_UNORM; - break; - case SDL_PIXELFORMAT_RGB888: - textureFormat = DXGI_FORMAT_B8G8R8X8_UNORM; - break; - default: - SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", - __FUNCTION__, texture->format); - return -1; + 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; @@ -1460,6 +1478,101 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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 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 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) { From 5230205e270414343fe5e758b8cf294aade7c847 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 1 Apr 2013 22:33:37 -0400 Subject: [PATCH 142/264] WinRT: implemented SDL_RenderCopyEx, w/ SDL_RendererFlip support, in D3D 11.1 --- src/render/direct3d11/SDL_render_d3d11.cpp | 56 ++++++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 2ca8054f0..6ab401918 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -73,9 +73,9 @@ 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_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); @@ -173,7 +173,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->RenderDrawLines = D3D11_RenderDrawLines; renderer->RenderFillRects = D3D11_RenderFillRects; renderer->RenderCopy = D3D11_RenderCopy; - //renderer->RenderCopyEx = D3D11_RenderCopyEx; + renderer->RenderCopyEx = D3D11_RenderCopyEx; renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; renderer->DestroyTexture = D3D11_DestroyTexture; @@ -1478,6 +1478,54 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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; + + if (flip & SDL_FLIP_HORIZONTAL) { + float tmp = maxu; + maxu = minu; + minu = tmp; + } + if (flip & SDL_FLIP_VERTICAL) { + float tmp = maxv; + maxv = minv; + minv = tmp; + } + + VertexPositionColor vertices[] = { + {XMFLOAT3(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + }; + 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_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) From b7887dd3264e6e0bb824566e4cc9eb7f26451a91 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 2 Apr 2013 00:09:49 -0400 Subject: [PATCH 143/264] WinRT: added rotation support to SDL_RenderCopyEx via D3D 11.1 --- .../SDL_D3D11_VertexShader_Default.hlsl | 6 ++- src/render/direct3d11/SDL_render_d3d11.cpp | 47 ++++++++++++++----- src/render/direct3d11/SDL_render_d3d11_cpp.h | 5 +- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl index c5131007a..b5cac4fa9 100644 --- a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl +++ b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl @@ -3,8 +3,9 @@ cbuffer SDL_VertexShaderConstants : register(b0) { - matrix view; - matrix projection; + matrix model; + matrix view; + matrix projection; }; struct VertexShaderInput @@ -27,6 +28,7 @@ VertexShaderOutput main(VertexShaderInput input) 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; diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 6ab401918..0aa1d3a96 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1129,6 +1129,11 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) 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: @@ -1250,15 +1255,6 @@ D3D11_RenderStartDrawOp(SDL_Renderer * renderer) rendererData->renderTargetView.GetAddressOf(), nullptr ); - - rendererData->d3dContext->UpdateSubresource( - rendererData->vertexShaderConstants.Get(), - 0, - NULL, - &rendererData->vertexShaderConstantsData, - 0, - 0 - ); } static void @@ -1299,6 +1295,16 @@ D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, 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); @@ -1504,12 +1510,25 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, 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(dstrect->x, dstrect->y, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(minx, miny, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(minx, maxy, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(maxx, miny, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {XMFLOAT3(maxx, maxy, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, }; if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) { return -1; @@ -1522,6 +1541,8 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, rendererData->mainSampler.Get()); D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); + + rendererData->vertexShaderConstantsData.model = oldModelMatrix; return 0; } diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index a879fdeba..be322832e 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -27,8 +27,9 @@ struct SDL_VertexShaderConstants { - DirectX::XMFLOAT4X4 view; - DirectX::XMFLOAT4X4 projection; + DirectX::XMFLOAT4X4 model; + DirectX::XMFLOAT4X4 view; + DirectX::XMFLOAT4X4 projection; }; typedef struct From b1b2ba3f09ccdd1451aa251a88c1bcd25082ba17 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 2 Apr 2013 00:21:01 -0400 Subject: [PATCH 144/264] WinRT: removed a bit of unused code from the D3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 -- src/render/direct3d11/SDL_render_d3d11_cpp.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 0aa1d3a96..69205bd7d 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -157,7 +157,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } data->featureLevel = (D3D_FEATURE_LEVEL) 0; - data->loadingComplete = false; data->windowSizeInDIPs = XMFLOAT2(0, 0); data->renderTargetSize = XMFLOAT2(0, 0); @@ -555,7 +554,6 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // // All done! // - data->loadingComplete = true; // This variable can probably be factored-out return S_OK; } diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index be322832e..3e4c88f6d 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -49,7 +49,6 @@ typedef struct Microsoft::WRL::ComPtr mainSampler; Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; - bool loadingComplete; // Vertex buffer constants: SDL_VertexShaderConstants vertexShaderConstantsData; From b74856f7b74e0240ffa6ec347b72e245e0bc613b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 7 Apr 2013 22:35:58 -0400 Subject: [PATCH 145/264] WinRT: added texture channel color-modulation support for D3D 11.1 --HG-- rename : src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl => src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 2 +- .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 +-- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 4 +- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +-- ...SDL_D3D11_PixelShader_TextureColored.hlsl} | 2 +- src/render/direct3d11/SDL_render_d3d11.cpp | 44 +++++++++++++++---- 6 files changed, 44 insertions(+), 20 deletions(-) rename src/render/direct3d11/{SDL_D3D11_PixelShader_TextureCopy.hlsl => SDL_D3D11_PixelShader_TextureColored.hlsl} (75%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index c8c7e55dd..25884c9c5 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -382,7 +382,7 @@ Pixel Pixel - + Pixel Pixel Pixel diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 3471b4635..f9f0227dd 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -592,14 +592,14 @@ - - GPU Shaders - GPU Shaders GPU Shaders + + GPU Shaders + \ No newline at end of file diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 7c869f41b..0d462941e 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -293,7 +293,7 @@ 4.0_level_9_1 4.0_level_9_1 - + Pixel Pixel Pixel @@ -304,8 +304,6 @@ 4.0_level_9_1 4.0_level_9_1 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 Vertex diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index e8a704b70..16ca97f6d 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -1,15 +1,15 @@  - - GPU Shaders - GPU Shaders GPU Shaders + + GPU Shaders + diff --git a/src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl b/src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl similarity index 75% rename from src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl rename to src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl index a48ba426c..503b4fdcb 100644 --- a/src/render/direct3d11/SDL_D3D11_PixelShader_TextureCopy.hlsl +++ b/src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl @@ -10,5 +10,5 @@ struct PixelShaderInput float4 main(PixelShaderInput input) : SV_TARGET { - return theTexture.Sample(theSampler, input.tex); + return theTexture.Sample(theSampler, input.tex) * input.color; } diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 69205bd7d..271dbeaea 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -436,7 +436,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // // Load in SDL's pixel shaders // - result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_TextureCopy.cso", &data->texturePixelShader); + 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; @@ -1460,12 +1460,25 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {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; @@ -1498,6 +1511,19 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, 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; @@ -1523,10 +1549,10 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const float maxy = dstrect->h - center->y; VertexPositionColor vertices[] = { - {XMFLOAT3(minx, miny, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(minx, maxy, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(maxx, miny, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, - {XMFLOAT3(maxx, maxy, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)}, + {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; From e40e111591d1e707ba137fa37c3e6aa5f9b3f338 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 13 Apr 2013 23:03:46 -0400 Subject: [PATCH 146/264] WinRT: added render-to-texture support for D3D 11.1, via SDL_SetRenderTarget --- src/render/direct3d11/SDL_render_d3d11.cpp | 132 +++++++++++++------ src/render/direct3d11/SDL_render_d3d11_cpp.h | 4 +- 2 files changed, 98 insertions(+), 38 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 271dbeaea..374c39b6e 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -57,12 +57,12 @@ 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 *pixels, - int pitch); + 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_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, @@ -93,7 +93,11 @@ extern "C" SDL_RenderDriver D3D11_RenderDriver = { D3D11_CreateRenderer, { "direct3d 11.1", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), // flags. see SDL_RendererFlags + ( + SDL_RENDERER_ACCELERATED | + SDL_RENDERER_PRESENTVSYNC | + SDL_RENDERER_TARGETTEXTURE + ), // flags. see SDL_RendererFlags 2, // num_texture_formats { // texture_formats SDL_PIXELFORMAT_RGB888, @@ -165,7 +169,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->UpdateTexture = D3D11_UpdateTexture; renderer->LockTexture = D3D11_LockTexture; renderer->UnlockTexture = D3D11_UnlockTexture; - //renderer->SetRenderTarget = D3D11_SetRenderTarget; + renderer->SetRenderTarget = D3D11_SetRenderTarget; renderer->UpdateViewport = D3D11_UpdateViewport; renderer->RenderClear = D3D11_RenderClear; renderer->RenderDrawPoints = D3D11_RenderDrawPoints; @@ -178,7 +182,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->DestroyTexture = D3D11_DestroyTexture; renderer->DestroyRenderer = D3D11_DestroyRenderer; renderer->info = D3D11_RenderDriver.info; - renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->driverdata = data; // HACK: make sure the SDL_Renderer references the SDL_Window data now, in @@ -752,7 +755,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) result = data->d3dDevice->CreateRenderTargetView( backBuffer.Get(), nullptr, - &data->renderTargetView + &data->mainRenderTargetView ); if (FAILED(result)) { WIN_SetErrorFromHRESULT(__FUNCTION__, result); @@ -781,7 +784,7 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) { ID3D11RenderTargetView* nullViews[] = {nullptr}; data->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); - data->renderTargetView = nullptr; + data->mainRenderTargetView = nullptr; data->d3dContext->Flush(); result = D3D11_CreateWindowSizeDependentResources(renderer); if (FAILED(result)) { @@ -860,11 +863,22 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) textureDesc.Format = textureFormat; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; - textureDesc.Usage = D3D11_USAGE_DYNAMIC; - textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 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; @@ -893,6 +907,23 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 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; @@ -931,40 +962,33 @@ D3D11_DestroyTexture(SDL_Renderer * renderer, static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, - int pitch) + const SDL_Rect * rect, const void * srcPixels, + int srcPitch) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; - HRESULT result = S_OK; - - D3D11_MAPPED_SUBRESOURCE textureMemory = {0}; - result = rendererData->d3dContext->Map( - textureData->mainTexture.Get(), - 0, - D3D11_MAP_WRITE_DISCARD, - 0, - &textureMemory - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + // 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 *)textureMemory.pData) + (textureMemory.RowPitch * y), - ((Uint8 *)pixels) + (pitch * y), - pitch + ((Uint8 *)destPixels) + (destPitch * y), + ((Uint8 *)srcPixels) + (srcPitch * y), + srcPitch ); } - // Clean up a bit, then commit the texture's memory back to Direct3D: - rendererData->d3dContext->Unmap( - textureData->mainTexture.Get(), - 0); + // Commit the texture's memory back to Direct3D: + D3D11_UnlockTexture(renderer, texture); + // Return to the caller: return 0; } @@ -1056,6 +1080,29 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) 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) { @@ -1177,6 +1224,17 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) return 0; } +static ComPtr & +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) { @@ -1188,7 +1246,7 @@ D3D11_RenderClear(SDL_Renderer * renderer) (renderer->a / 255.0f) }; data->d3dContext->ClearRenderTargetView( - data->renderTargetView.Get(), + D3D11_GetCurrentRenderTargetView(renderer).Get(), colorRGBA ); return 0; @@ -1250,7 +1308,7 @@ D3D11_RenderStartDrawOp(SDL_Renderer * renderer) rendererData->d3dContext->OMSetRenderTargets( 1, - rendererData->renderTargetView.GetAddressOf(), + D3D11_GetCurrentRenderTargetView(renderer).GetAddressOf(), nullptr ); } @@ -1695,7 +1753,7 @@ D3D11_RenderPresent(SDL_Renderer * renderer) // 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->renderTargetView.Get()); + 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. diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 3e4c88f6d..14fc61270 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -37,7 +37,8 @@ typedef struct Microsoft::WRL::ComPtr d3dDevice; Microsoft::WRL::ComPtr d3dContext; Microsoft::WRL::ComPtr swapChain; - Microsoft::WRL::ComPtr renderTargetView; + Microsoft::WRL::ComPtr mainRenderTargetView; + Microsoft::WRL::ComPtr currentOffscreenRenderTargetView; Microsoft::WRL::ComPtr inputLayout; Microsoft::WRL::ComPtr vertexBuffer; Microsoft::WRL::ComPtr vertexShader; @@ -67,6 +68,7 @@ typedef struct { Microsoft::WRL::ComPtr mainTexture; Microsoft::WRL::ComPtr mainTextureResourceView; + Microsoft::WRL::ComPtr mainTextureRenderTargetView; SDL_PixelFormat * pixelFormat; Microsoft::WRL::ComPtr stagingTexture; DirectX::XMINT2 lockedTexturePosition; From 14337669a235a34bd536d73a5db5bf9e975db3fe Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 14 Apr 2013 11:45:01 -0400 Subject: [PATCH 147/264] WinRT: hack-fixed C++/CX compile errors regarding the 'generic' field in SDL_Event, which conflicts with a C++/CX keyword --- include/begin_code.h | 5 +++++ include/close_code.h | 5 +++++ src/events/SDL_events.c | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/include/begin_code.h b/include/begin_code.h index 0a4b4a65c..11820bb41 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -148,3 +148,8 @@ #endif #endif /* NULL */ #endif /* ! Mac OS X - breaks precompiled headers */ + +/* HACK: Make sure C++/CX works when compiling WinRT code */ +#if defined(__WINRT__) +#define generic generic_ +#endif diff --git a/include/close_code.h b/include/close_code.h index 410060370..3867d36b3 100644 --- a/include/close_code.h +++ b/include/close_code.h @@ -35,3 +35,8 @@ #endif #pragma pack(pop) #endif /* Compiler needs structure packing set */ + +/* Revert hack used to get C++/CX (WinRT) code compiling. */ +#if defined(__WINRT__) +#undef generic +#endif diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index ade28a697..888cc86fa 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -33,6 +33,15 @@ #endif #include "../video/SDL_sysvideo.h" +/* HACK: Make sure the 'generic' field in SDL_Event works on + WinRT, whereby 'generic' is redefined as 'generic_', in order to + allow SDL.h to be included in code compiled with Microsoft's + C++/CX extension. +*/ +#if defined(__WINRT__) +#define generic generic_ +#endif + /* Public data -- the event filter */ SDL_EventFilter SDL_EventOK = NULL; void *SDL_EventOKParam; From 3a0f7dfe3079d0a53f7c12ce87bf3f8f2b79b86e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 14 Apr 2013 12:06:58 -0400 Subject: [PATCH 148/264] WinRT: build fixes for the loopwave and testthread test apps --- VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj | 4 ++-- VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index fcaee1d24..14e57e5fd 100644 --- a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -106,7 +106,7 @@ - NDEBUG;%(PreprocessorDefinitions) + NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing @@ -114,7 +114,7 @@ - _DEBUG;%(PreprocessorDefinitions) + _DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing diff --git a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index 2a515b31e..1940fe315 100644 --- a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -106,7 +106,7 @@ - NDEBUG;%(PreprocessorDefinitions) + NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing @@ -117,7 +117,7 @@ - _DEBUG;%(PreprocessorDefinitions) + _DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) NotUsing NotUsing NotUsing From 52a3b9b1f5ff23c2c5474daac6fab995383c0b65 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 16 Apr 2013 23:40:03 -0400 Subject: [PATCH 149/264] WinRT: made SDL's inner WinRT CoreWindow be accessible to non-C++/CX code, in theory --- include/SDL_syswm.h | 6 ++- src/render/direct3d11/SDL_render_d3d11.cpp | 52 +++++++++++++++++----- src/video/windowsrt/SDL_winrtvideo.cpp | 12 +---- src/video/windowsrt/SDL_winrtvideo.h | 4 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index f6e824672..c01c27141 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -58,6 +58,10 @@ struct SDL_SysWMinfo; #include #endif +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + /* This is the structure for custom window manager events */ #if defined(SDL_VIDEO_DRIVER_X11) #if defined(__APPLE__) && defined(__MACH__) @@ -175,7 +179,7 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_WINRT) struct { - void * window; /**< The Windows RT CoreWindow, casted from 'CoreWindow ^*' to 'void *' */ + IUnknown * window; /**< The Windows RT CoreWindow */ } winrt; #endif #if defined(SDL_VIDEO_DRIVER_X11) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 374c39b6e..ed741c278 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -23,6 +23,11 @@ #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#ifdef __WINRT__ +#include +#include +#endif + extern "C" { #include "../../core/windows/SDL_windows.h" //#include "SDL_hints.h" @@ -562,7 +567,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) #ifdef __WINRT__ -static CoreWindow ^ +static ABI::Windows::UI::Core::ICoreWindow * D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) { SDL_Window * sdlWindow = renderer->window; @@ -580,12 +585,16 @@ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) return nullptr; } - CoreWindow ^* coreWindowPointer = (CoreWindow ^*) sdlWindowInfo.info.winrt.window; - if ( ! coreWindowPointer ) { + if ( ! sdlWindowInfo.info.winrt.window ) { return nullptr; } - return *coreWindowPointer; + 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. @@ -604,12 +613,19 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + 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. - data->windowSizeInDIPs.x = coreWindow->Bounds.Width; - data->windowSizeInDIPs.y = coreWindow->Bounds.Height; + 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); @@ -685,9 +701,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) 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(), - reinterpret_cast(coreWindow), + coreWindowAsIUnknown, &swapChainDesc, nullptr, // Allow on all displays. &data->swapChain @@ -776,10 +799,17 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; - Windows::UI::Core::CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); + ABI::Windows::Foundation::Rect coreWindowBounds; - if (coreWindow->Bounds.Width != data->windowSizeInDIPs.x || - coreWindow->Bounds.Height != data->windowSizeInDIPs.y || + 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}; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 846debb50..cdd8b3e03 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -172,7 +172,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) } window->driverdata = data; data->sdlWindow = window; - data->coreWindow = new CoreWindow^(CoreWindow::GetForCurrentThread()); + data->coreWindow = CoreWindow::GetForCurrentThread(); /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. @@ -233,13 +233,6 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) } if (data) { - // Delete the reference to the WinRT CoreWindow: - CoreWindow ^* windowPointer = ((SDL_WindowData *) window->driverdata)->coreWindow; - if (windowPointer) { - *windowPointer = nullptr; // Clear the C++/CX reference to the CoreWindow - delete windowPointer; // Delete the C++/CX reference itself - } - // Delete the internal window data: delete data; data = NULL; @@ -250,11 +243,10 @@ SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - CoreWindow ^* windowPointer = data->coreWindow; if (info->version.major <= SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_WINDOWSRT; - info->info.winrt.window = windowPointer; + info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); return SDL_TRUE; } else { SDL_SetError("Application not compiled with SDL %d.%d\n", diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/windowsrt/SDL_winrtvideo.h index 83eb78733..4418754c2 100644 --- a/src/video/windowsrt/SDL_winrtvideo.h +++ b/src/video/windowsrt/SDL_winrtvideo.h @@ -27,10 +27,12 @@ extern "C" { #include "../SDL_sysvideo.h" } +#include + struct SDL_WindowData { SDL_Window *sdlWindow; - Windows::UI::Core::CoreWindow ^* coreWindow; + Platform::Agile coreWindow; }; #endif /* _SDL_winrtvideo_h */ From 5d23da74187b9a7c014570d656d4fb3013058ba2 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 21 Apr 2013 12:49:15 -0400 Subject: [PATCH 150/264] WinRT: removed the "generic" + C++/CX hack-fix, now that a better fix is in official-SDL --- include/begin_code.h | 5 ----- include/close_code.h | 5 ----- src/events/SDL_events.c | 9 --------- 3 files changed, 19 deletions(-) diff --git a/include/begin_code.h b/include/begin_code.h index 11820bb41..0a4b4a65c 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -148,8 +148,3 @@ #endif #endif /* NULL */ #endif /* ! Mac OS X - breaks precompiled headers */ - -/* HACK: Make sure C++/CX works when compiling WinRT code */ -#if defined(__WINRT__) -#define generic generic_ -#endif diff --git a/include/close_code.h b/include/close_code.h index 3867d36b3..410060370 100644 --- a/include/close_code.h +++ b/include/close_code.h @@ -35,8 +35,3 @@ #endif #pragma pack(pop) #endif /* Compiler needs structure packing set */ - -/* Revert hack used to get C++/CX (WinRT) code compiling. */ -#if defined(__WINRT__) -#undef generic -#endif diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 8f0df27f4..ecba3bb5b 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -33,15 +33,6 @@ #endif #include "../video/SDL_sysvideo.h" -/* HACK: Make sure the 'generic' field in SDL_Event works on - WinRT, whereby 'generic' is redefined as 'generic_', in order to - allow SDL.h to be included in code compiled with Microsoft's - C++/CX extension. -*/ -#if defined(__WINRT__) -#define generic generic_ -#endif - /* Public data -- the event filter */ SDL_EventFilter SDL_EventOK = NULL; void *SDL_EventOKParam; From 3fc03faf5546d9287013fdc5c83814560c5b89fb Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 5 May 2013 10:27:14 -0400 Subject: [PATCH 151/264] WinRT: added additional, optional code to aid with keyboard event debugging --- src/video/windowsrt/SDL_WinRTApp.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index a7461e3b2..8fa12b3fb 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -749,8 +749,10 @@ TranslateKeycode(int keycode) void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { + SDL_Scancode sdlScancode = TranslateKeycode((int)args->VirtualKey); #if 0 - SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\n", + 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"), @@ -758,17 +760,23 @@ void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI: args->KeyStatus.RepeatCount, args->KeyStatus.ScanCode, (args->KeyStatus.WasKeyDown ? "1" : "0"), - args->VirtualKey); + args->VirtualKey, + sdlScancode, + SDL_GetScancodeName(sdlScancode), + keycode, + SDL_GetKeyName(keycode)); //args->Handled = true; //VirtualKey vkey = args->VirtualKey; #endif - SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode((int)args->VirtualKey)); + 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_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, repeat count=%d, scan code=%d, was down?=%s, vkey=%d\n", + 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"), @@ -776,10 +784,14 @@ void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::C args->KeyStatus.RepeatCount, args->KeyStatus.ScanCode, (args->KeyStatus.WasKeyDown ? "1" : "0"), - args->VirtualKey); + args->VirtualKey, + sdlScancode, + SDL_GetScancodeName(sdlScancode), + keycode, + SDL_GetKeyName(keycode)); //args->Handled = true; #endif - SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode((int)args->VirtualKey)); + SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode); } void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) From 799e5d65ead7de9f4858a1993be1bd7c82896288 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 5 May 2013 11:27:58 -0400 Subject: [PATCH 152/264] WinRT: fixed a display mode reporting bug, whereby DPI wasn't getting taken into account. (Thanks to Sylvain Becker for the fix!) --- src/video/windowsrt/SDL_WinRTApp.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index 8fa12b3fb..f3ddb9f8a 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -870,13 +870,22 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) 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.w = (int) CoreWindow::GetForCurrentThread()->Bounds.Width; - mode.h = (int) CoreWindow::GetForCurrentThread()->Bounds.Height; 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; } From b753a203e343406c1840e2c85bc10cd2b8f7fccf Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 5 May 2013 11:30:44 -0400 Subject: [PATCH 153/264] WinRT: mouse-pointer debugging improvements --- src/video/windowsrt/SDL_WinRTApp.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index f3ddb9f8a..fdc3582ed 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -36,6 +36,10 @@ 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 + // 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. @@ -386,12 +390,13 @@ WINRT_ConvertPointerUpdateKindToString(PointerUpdateKind kind) } static void -WINRT_LogPointerEvent(const string & header, PointerEventArgs ^ args) +WINRT_LogPointerEvent(const string & header, PointerEventArgs ^ args, Point transformedPoint) { PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", + 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, @@ -400,8 +405,8 @@ WINRT_LogPointerEvent(const string & header, PointerEventArgs ^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { -#if 0 - WINRT_LogPointerEvent("mouse down", args); +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position)); #endif if (m_sdlWindowData) { @@ -414,8 +419,8 @@ void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { -#if 0 - WINRT_LogPointerEvent("mouse up", args); +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position)); #endif if (m_sdlWindowData) { @@ -428,8 +433,8 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { -#if 0 - WINRT_LogPointerEvent("wheel changed", args); +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("wheel changed", args, TransformCursor(args->CurrentPoint->Position)); #endif if (m_sdlWindowData) { @@ -532,6 +537,10 @@ Point SDL_WinRTApp::TransformCursor(Point rawPosition) 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); From 63b227b811ef91ebd76edb7fc061dfa6c80a3281 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 11 May 2013 21:54:10 -0400 Subject: [PATCH 154/264] WinRT: made sure SDL_GameController APIs get linked in (to SDL.dll) --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 1 + VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 0d462941e..f63116d04 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -76,6 +76,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 16ca97f6d..90608e46a 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -264,6 +264,9 @@ Source Files + + Source Files + From b2ea4f6eca17ed33ddb24dbb5d4077f6122d13f4 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 12 May 2013 22:38:39 -0400 Subject: [PATCH 155/264] WinRT: Windows Phone 8 build/project updates --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 1 + VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 25884c9c5..5c5951528 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -293,6 +293,7 @@ + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index f9f0227dd..4eb56ac03 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -590,6 +590,9 @@ Source Files + + Source Files + From b919f57c1252a7dfc418353579b7911ad34e8ecb Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 19 May 2013 23:30:34 -0400 Subject: [PATCH 156/264] WinRT: added preliminary joystick / game controller support (minus hotplugging) --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 6 +- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +- include/SDL_config_windowsrt.h | 8 +- src/joystick/SDL_gamecontroller.c | 14 +- src/joystick/SDL_sysjoystick.h | 2 +- src/joystick/windowsrt/SDL_xinputjoystick.c | 378 ++++++++++++++++++ 6 files changed, 399 insertions(+), 15 deletions(-) create mode 100644 src/joystick/windowsrt/SDL_xinputjoystick.c diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index f63116d04..468f85536 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -75,9 +75,9 @@ - + true @@ -426,7 +426,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -440,7 +440,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 90608e46a..74dd2dc86 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -192,9 +192,6 @@ Source Files - - Source Files - Source Files @@ -267,6 +264,9 @@ Source Files + + Source Files + diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index 5e48338f4..b6ecc00fe 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -144,8 +144,12 @@ typedef unsigned int uintptr_t; /* Enable various input drivers */ // TODO, WinRT: Get haptic support working #define SDL_HAPTIC_DISABLED 1 -// TODO, WinRT: Get joystick support working -#define SDL_JOYSTICK_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 diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 2e856d359..9bf87a30c 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -89,8 +89,10 @@ typedef struct _ControllerMapping_t /* default mappings we support */ const char *s_ControllerMappings [] = { -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) "xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5", +#endif +#ifdef SDL_JOYSTICK_DINPUT "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12", "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", @@ -119,7 +121,7 @@ const char *s_ControllerMappings [] = }; static ControllerMapping_t *s_pSupportedControllers = NULL; -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) static ControllerMapping_t *s_pXInputMapping = NULL; #endif @@ -310,7 +312,7 @@ ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *gu */ ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) { -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping ) { return s_pXInputMapping; @@ -699,7 +701,7 @@ SDL_GameControllerAddMapping( const char *mappingString ) char *pchMapping; SDL_JoystickGUID jGUID; ControllerMapping_t *pControllerMapping; -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) SDL_bool is_xinput_mapping = SDL_FALSE; #endif @@ -707,7 +709,7 @@ SDL_GameControllerAddMapping( const char *mappingString ) if (!pchGUID) { return -1; } -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) { is_xinput_mapping = SDL_TRUE; } @@ -742,7 +744,7 @@ SDL_GameControllerAddMapping( const char *mappingString ) SDL_free( pchMapping ); return SDL_OutOfMemory(); } -#ifdef SDL_JOYSTICK_DINPUT +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) if ( is_xinput_mapping ) { s_pXInputMapping = pControllerMapping; diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 4a5019e73..f75aabc07 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/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 diff --git a/src/joystick/windowsrt/SDL_xinputjoystick.c b/src/joystick/windowsrt/SDL_xinputjoystick.c new file mode 100644 index 000000000..63e8a1ff1 --- /dev/null +++ b/src/joystick/windowsrt/SDL_xinputjoystick.c @@ -0,0 +1,378 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 +#include + +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)? +}; + +/* 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() +{ +} + +SDL_bool SDL_SYS_JoystickNeedsPolling() +{ + return SDL_FALSE; +} + +/* 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) { + /* TODO, WinRT: set a flag to indicate that a device-removal event + needs to be emitted. + */ + //joystick->hwdata->send_remove_event = 1; + //joystick->hwdata->removed = 1; + joystick->hwdata->isDeviceConnected = SDL_FALSE; + 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: */ From 6f8a3ac5cf26f97439a3d226ab65ac66ec125d15 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 20 May 2013 11:09:08 -0400 Subject: [PATCH 157/264] WinRT: fixed XInput-related linker errors on non-x86 platforms (such as ARM) --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 468f85536..40a8ffd9e 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -454,7 +454,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -468,7 +468,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -482,7 +482,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) @@ -496,7 +496,7 @@ Console false false - xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) + xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies) From 95ad1c10fb89ec82fbeaa43ad4a0f0a25111d1a9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 21 May 2013 20:08:53 -0400 Subject: [PATCH 158/264] WinRT: added hotplug support for joysticks/game-controllers --- src/joystick/windowsrt/SDL_xinputjoystick.c | 71 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/src/joystick/windowsrt/SDL_xinputjoystick.c b/src/joystick/windowsrt/SDL_xinputjoystick.c index 63e8a1ff1..6b3e59f0e 100644 --- a/src/joystick/windowsrt/SDL_xinputjoystick.c +++ b/src/joystick/windowsrt/SDL_xinputjoystick.c @@ -37,6 +37,7 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" #include "SDL_events.h" +#include "../../events/SDL_events_c.h" #include #include @@ -46,6 +47,7 @@ struct joystick_hwdata { 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 @@ -96,11 +98,67 @@ int SDL_SYS_NumJoysticks() 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() { - return SDL_FALSE; + /* 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. @@ -261,12 +319,11 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) /* Poll for new data */ result = XInputGetState(joystick->hwdata->userIndex, &joystick->hwdata->XInputState); if (result == ERROR_DEVICE_NOT_CONNECTED) { - /* TODO, WinRT: set a flag to indicate that a device-removal event - needs to be emitted. - */ - //joystick->hwdata->send_remove_event = 1; - //joystick->hwdata->removed = 1; - joystick->hwdata->isDeviceConnected = SDL_FALSE; + 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; } From 62792cc20f1e113ad07f3bee24f569c9b3fe6aac Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 26 May 2013 19:40:12 -0400 Subject: [PATCH 159/264] WinRT: added code to help debug events related to window-sizing and device-orientation --- src/video/windowsrt/SDL_WinRTApp.cpp | 58 +++++++++++++++++++++++++++- src/video/windowsrt/SDL_WinRTApp.h | 1 + 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index fdc3582ed..a807bda7f 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -39,6 +39,9 @@ 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. @@ -152,6 +155,9 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Resuming += ref new EventHandler(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. @@ -161,8 +167,40 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) 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(this, &SDL_WinRTApp::OnWindowSizeChanged); @@ -238,8 +276,14 @@ void SDL_WinRTApp::Uninitialize() void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { -#if 0 - SDL_Log("%s, {%f,%f}\n", __FUNCTION__, args->Size.Width, args->Size.Height); +#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) { @@ -300,6 +344,13 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven 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; @@ -322,6 +373,9 @@ void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEven void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) { +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s\n", __FUNCTION__); +#endif m_windowClosed = true; } diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index 8712d51e0..cd0c379fc 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -27,6 +27,7 @@ internal: 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); From 8b555c027d42ee9ed80ea0706b4441a3b21ddd17 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 26 May 2013 20:27:13 -0400 Subject: [PATCH 160/264] WinRT: fixed bug whereby landscape-only apps, as configured via an app's Package.appxmanifest file, would report an incorrect display mode on app init, if the device was in portrait mode --- src/video/windowsrt/SDL_winrtvideo.cpp | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index cdd8b3e03..b3a967f9d 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -121,10 +121,49 @@ VideoBootStrap WINRT_bootstrap = { int WINRT_VideoInit(_THIS) { + // Pump events once, in order to flush out and process any pending + // window-size change events. Doing this addresses the following: + // + // 1. An app, set to start up as a Landscape-only app (via a + // Package.appxmanifest file), starts up on a device that is in Portrait + // mode. + // 2. Control of the app reaches this function (WINRT_VideoInit). + // 3. The 'Size' property of the app's CoreWindow (a WinRT-defined object) + // is not sized as if it were running on a device in landscape mode, but + // rather, it's sized in portrait mode. To note, this property will + // normally changes as a device rotates, however it hasn't changed just yet. + // 4. WINRT_VideoInit calls WINRT_InitModes, which uses the app's + // CoreWindow to register a display mode, whose width and height are + // still oriented in portrait. + // 5. Once WINRT_VideoInit returns, and once control leaves SDL (and back + // into its calling app), SDL_GetDisplayMode is called, which returns the + // portrait-oriented display mode. (Remember, this is supposed to be a + // landscape-only app.) + // 6. The portrait-oriented display mode is used to initialize other + // things. The CoreWindow's size eventually changes (and window-resize + // events are sent out accordingly), but damage has already been done, + // as a variety of things were set up using the portrait-oriented + // display mode (rather than a landscape-oriented display mode). + // + // By pumping events once, WinRT will make sure that the app's + // CoreWindow will get its size updated, and that a correctly-oriented + // display mode gets registered. + // + // Please note that if SDL_SetHint is used to set the app's orientation + // (in conjunction with SDL_HINT_ORIENTATION), then this technique will + // not work. The size of the app's CoreWindow will still be off. This + // technique is only known to fix cases where an app's orientation is set + // via its app-settings file, Package.appxmanifest. + SDL_WinRTGlobalApp->PumpEvents(); + + // + // Now that any pending window-size change events have been processed, + // continue initializing the SDL/WinRT video backend: + // + if (WINRT_InitModes(_this) < 0) { return -1; } - WINRT_InitMouse(_this); return 0; From 7b826031611e4649e6ababac1921ccc4b03c8155 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 8 Jun 2013 14:34:09 -0400 Subject: [PATCH 161/264] WinRT: removed hack to flush out pending window-size-change events on app startup. The hack appeared to work in the Windows Simulator, but not on real hardware, and notably not on a Surface RT. Room may exist for a different, and more thorough hack. --- src/video/windowsrt/SDL_winrtvideo.cpp | 40 +------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index b3a967f9d..7a459fb95 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -121,45 +121,7 @@ VideoBootStrap WINRT_bootstrap = { int WINRT_VideoInit(_THIS) { - // Pump events once, in order to flush out and process any pending - // window-size change events. Doing this addresses the following: - // - // 1. An app, set to start up as a Landscape-only app (via a - // Package.appxmanifest file), starts up on a device that is in Portrait - // mode. - // 2. Control of the app reaches this function (WINRT_VideoInit). - // 3. The 'Size' property of the app's CoreWindow (a WinRT-defined object) - // is not sized as if it were running on a device in landscape mode, but - // rather, it's sized in portrait mode. To note, this property will - // normally changes as a device rotates, however it hasn't changed just yet. - // 4. WINRT_VideoInit calls WINRT_InitModes, which uses the app's - // CoreWindow to register a display mode, whose width and height are - // still oriented in portrait. - // 5. Once WINRT_VideoInit returns, and once control leaves SDL (and back - // into its calling app), SDL_GetDisplayMode is called, which returns the - // portrait-oriented display mode. (Remember, this is supposed to be a - // landscape-only app.) - // 6. The portrait-oriented display mode is used to initialize other - // things. The CoreWindow's size eventually changes (and window-resize - // events are sent out accordingly), but damage has already been done, - // as a variety of things were set up using the portrait-oriented - // display mode (rather than a landscape-oriented display mode). - // - // By pumping events once, WinRT will make sure that the app's - // CoreWindow will get its size updated, and that a correctly-oriented - // display mode gets registered. - // - // Please note that if SDL_SetHint is used to set the app's orientation - // (in conjunction with SDL_HINT_ORIENTATION), then this technique will - // not work. The size of the app's CoreWindow will still be off. This - // technique is only known to fix cases where an app's orientation is set - // via its app-settings file, Package.appxmanifest. - SDL_WinRTGlobalApp->PumpEvents(); - - // - // Now that any pending window-size change events have been processed, - // continue initializing the SDL/WinRT video backend: - // + // 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; From ef0a40b7044c056083c95d193a1a1c2ca9a5bd09 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 13 Aug 2013 20:09:52 -0400 Subject: [PATCH 162/264] WinRT: build fixes and additional WinRT-related integrations with SDL 2.0.0 --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 3 +- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 9 +++-- include/SDL_config_windowsrt.h | 4 ++- include/SDL_platform.h | 25 ++++++++++--- include/SDL_stdinc.h | 3 ++ src/SDL_log.c | 5 +++ src/audio/xaudio2/SDL_xaudio2.c | 6 +--- src/joystick/SDL_gamecontrollerdb.h | 2 ++ src/render/SDL_render.c | 3 ++ src/stdlib/SDL_stdlib.c | 4 +++ src/thread/stdcpp/SDL_systhread.cpp | 16 ++++++++- src/timer/windows/SDL_systimer.c | 25 +++++++++++++ src/video/windowsrt/SDL_WinRTApp.cpp | 36 ++++++++++--------- 13 files changed, 110 insertions(+), 31 deletions(-) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 40a8ffd9e..3a770d61e 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -100,11 +100,11 @@ - + @@ -239,6 +239,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 74dd2dc86..9e8007cf2 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -96,9 +96,6 @@ Source Files - - Source Files - Source Files @@ -267,6 +264,9 @@ Source Files + + Source Files + @@ -593,6 +593,9 @@ Source Files + + Header Files + diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h index b6ecc00fe..712a9149f 100644 --- a/include/SDL_config_windowsrt.h +++ b/include/SDL_config_windowsrt.h @@ -83,6 +83,7 @@ typedef unsigned int uintptr_t; #define HAVE_STRING_H 1 #define HAVE_CTYPE_H 1 #define HAVE_MATH_H 1 +#define HAVE_FLOAT_H 1 #define HAVE_SIGNAL_H 1 /* C library functions */ @@ -123,7 +124,7 @@ typedef unsigned int uintptr_t; #define HAVE_ATAN 1 #define HAVE_ATAN2 1 #define HAVE_CEIL 1 -//#define HAVE_COPYSIGN 1 // TODO, WinRT: consider using _copysign instead +#define HAVE__COPYSIGN 1 #define HAVE_COS 1 #define HAVE_COSF 1 #define HAVE_FABS 1 @@ -131,6 +132,7 @@ typedef unsigned int uintptr_t; #define HAVE_LOG 1 #define HAVE_POW 1 //#define HAVE_SCALBN 1 +#define HAVE__SCALB 1 #define HAVE_SIN 1 #define HAVE_SINF 1 #define HAVE_SQRT 1 diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 1e8e0d9f4..419b6336c 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -120,10 +120,27 @@ #undef __SOLARIS__ #define __SOLARIS__ 1 #endif -#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) -#undef __WIN32__ -#define __WIN32__ 1 -#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) +/* Try to find out what version of Windows we are compiling for */ +#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */ +#include +#endif +/* Default to classic, Win32 / Desktop compilation either if: + 1. the version of Windows is explicity set to a 'Desktop' (non-Metro) app + 2. the version of Windows cannot be determined via winapifamily.h + If neither is true, see if we're compiling for WinRT. + */ +#if ! defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#undef __WIN32__ +#define __WIN32__ 1 +/* See if we're compiling for WinRT: */ +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#undef __WINRT__ +#define __WINRT__ 1 +#endif /* ! defined(WINAPI_FAMILY_PARTITION) */ +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + #if defined(__PSP__) #undef __PSP__ #define __PSP__ 1 diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index bc39c2a90..bfd6bb8bc 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -80,6 +80,9 @@ # endif # include #endif +#ifdef HAVE_FLOAT_H +# include +#endif #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) # include #endif diff --git a/src/SDL_log.c b/src/SDL_log.c index a19a2c425..1bd8ae69d 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -322,6 +322,8 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, char *output; size_t length; LPTSTR tstr; + +#ifndef __WINRT__ BOOL attachResult; DWORD attachError; unsigned long charsWritten; @@ -353,6 +355,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, stderrHandle = GetStdHandle(STD_ERROR_HANDLE); } } +#endif /* ifndef __WINRT__ */ length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1; output = SDL_stack_alloc(char, length); @@ -362,6 +365,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, /* Output to debugger */ OutputDebugString(tstr); +#ifndef __WINRT__ /* Screen output to stderr, if console was attached. */ if (consoleAttached == 1) { if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) { @@ -371,6 +375,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, OutputDebugString(TEXT("Insufficient heap memory to write message")); } } +#endif /* ifndef __WINRT__ */ SDL_free(tstr); SDL_stack_free(output); diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 19f7cdc5c..2816e6c77 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -91,15 +91,11 @@ extern "C" { } #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 +/* WinRT always has access to the .the XAudio 2 SDK */ # define SDL_XAUDIO2_HAS_SDK #else #include /* XAudio2 exists as of the March 2008 DirectX SDK */ diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 7f6c7b29f..dcdbafb17 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -38,6 +38,8 @@ static const char *s_ControllerMappings [] = "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,", "xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", +#elif defined(SDL_JOYSTICK_XINPUT) + "xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", #elif defined(__MACOSX__) "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 5dfc38dcb..5827a55e1 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -49,6 +49,9 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_D3D &D3D_RenderDriver, #endif +#if SDL_VIDEO_RENDER_D3D11 + &D3D11_RenderDriver, +#endif #if SDL_VIDEO_RENDER_OGL &GL_RenderDriver, #endif diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c index 2ee62beee..f5ea27d3f 100644 --- a/src/stdlib/SDL_stdlib.c +++ b/src/stdlib/SDL_stdlib.c @@ -61,6 +61,8 @@ SDL_copysign(double x, double y) { #if defined(HAVE_COPYSIGN) return copysign(x, y); +#elif defined(HAVE__COPYSIGN) + return _copysign(x, y); #else return SDL_uclibc_copysign(x, y); #endif /* HAVE_COPYSIGN */ @@ -131,6 +133,8 @@ SDL_scalbn(double x, int n) { #if defined(HAVE_SCALBN) return scalbn(x, n); +#elif defined(HAVE__SCALB) + return _scalb(x, n); #else return SDL_uclibc_scalbn(x, n); #endif /* HAVE_SCALBN */ diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index fd4cdafb3..fb1ca31b5 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -24,8 +24,8 @@ extern "C" { #include "SDL_thread.h" -#include "../SDL_systhread.h" #include "../SDL_thread_c.h" +#include "../SDL_systhread.h" #include "SDL_log.h" } @@ -121,4 +121,18 @@ SDL_SYS_WaitThread(SDL_Thread * thread) } } +extern "C" +SDL_TLSData * +SDL_SYS_GetTLSData() +{ + return SDL_Generic_GetTLSData(); +} + +extern "C" +int +SDL_SYS_SetTLSData(SDL_TLSData *data) +{ + return SDL_Generic_SetTLSData(data); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/windows/SDL_systimer.c b/src/timer/windows/SDL_systimer.c index ce6bd7a70..f71aecf35 100644 --- a/src/timer/windows/SDL_systimer.c +++ b/src/timer/windows/SDL_systimer.c @@ -41,6 +41,7 @@ static LARGE_INTEGER hires_start_ticks; static LARGE_INTEGER hires_ticks_per_second; #endif +#ifndef __WINRT__ static void timeSetPeriod(UINT uPeriod) { @@ -74,6 +75,7 @@ SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValu timeSetPeriod(uPeriod); } } +#endif /* ifndef __WINRT__ */ void SDL_StartTicks(void) @@ -90,13 +92,19 @@ SDL_StartTicks(void) QueryPerformanceCounter(&hires_start_ticks); } else { hires_timer_available = FALSE; +#ifdef __WINRT__ + start = 0; /* the timer failed to start! */ +#else timeSetPeriod(1); /* use 1 ms timer precision */ start = timeGetTime(); +#endif /* ifdef __WINRT__ */ } #endif +#ifndef __WINRT__ SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION, SDL_TimerResolutionChanged, NULL); +#endif } Uint32 @@ -119,7 +127,11 @@ SDL_GetTicks(void) return (DWORD) hires_now.QuadPart; } else { +#ifdef __WINRT__ + now = 0; +#else now = timeGetTime(); +#endif // ifdef __WINRT__ } #endif @@ -148,6 +160,19 @@ SDL_GetPerformanceFrequency(void) return frequency.QuadPart; } +#ifdef __WINRT__ +static void +Sleep(DWORD timeout) +{ + static HANDLE mutex = 0; + if ( ! mutex ) + { + mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); + } + WaitForSingleObjectEx(mutex, timeout, FALSE); +} +#endif + void SDL_Delay(Uint32 ms) { diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index a807bda7f..bac38e447 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -13,7 +13,7 @@ extern "C" { #include "SDL_stdinc.h" #include "SDL_render.h" #include "../SDL_sysvideo.h" -#include "../../SDL_hints_c.h" +//#include "../../SDL_hints_c.h" #include "../../events/scancodes_windows.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" @@ -86,7 +86,7 @@ __declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFu return 0; } -static void WINRT_SetDisplayOrientationsPreference(const char *name, const char *oldValue, const char *newValue) +static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue) { SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); @@ -163,8 +163,8 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) // 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); + //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback) + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); } void SDL_WinRTApp::OnOrientationChanged(Object^ sender) @@ -316,15 +316,19 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // Windows device. // // Commencing hack in 3... 2... 1... - SDL_Renderer * rendererForMainWindow = SDL_GetRenderer(m_sdlWindowData->sdlWindow); + // + // UPDATE, SDL 2.0.0 update: the 'resized' flag is now gone. This + // hack might not be necessary any more. + // + //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; - } + //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); @@ -335,10 +339,10 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven windowWidth, windowHeight); - // Viewport hack, part two: - if (usingD3D11Renderer) { - rendererForMainWindow->resized = wasD3D11RendererResized; - } + //// Viewport hack, part two: + //if (usingD3D11Renderer) { + // rendererForMainWindow->resized = wasD3D11RendererResized; + //} } } From 7c618123701513e796f43c86202909278c1e84cf Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 13 Aug 2013 20:11:51 -0400 Subject: [PATCH 163/264] WinRT: Windows Phone 8 build fixes --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 2 +- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 5c5951528..9da6c8431 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -315,11 +315,11 @@ - + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 4eb56ac03..2e3dcb4c6 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -467,9 +467,6 @@ Source Files - - Source Files - Source Files @@ -593,6 +590,9 @@ Source Files + + Source Files + From 40df4ea9431225c7e3ec499b5b9398ddd2a6fb0e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 13 Aug 2013 20:28:10 -0400 Subject: [PATCH 164/264] WinRT: made sure SDL_main gets used in the latest SDL 2.0.0 based code --- include/SDL_main.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/SDL_main.h b/include/SDL_main.h index bbb7e859b..21fedaaf9 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -39,6 +39,16 @@ */ #define SDL_MAIN_AVAILABLE +#elif defined(__WINRT__) +/* On Windows RT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. The file, src/main/windowsrt/SDL_WinRT_main.cpp, or a copy + of it, must be compiled into the app itself. +*/ +#define SDL_MAIN_NEEDED + #elif defined(__IPHONEOS__) /* On iOS SDL provides a main function that creates an application delegate and starts the iOS application run loop. From 8fe97d0465d657b56caa6997a5e1c97535386d8c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 13 Aug 2013 20:28:48 -0400 Subject: [PATCH 165/264] WinRT: fixed a crash in some display orientation hint code --- src/video/windowsrt/SDL_WinRTApp.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index bac38e447..f58639ac0 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -10,6 +10,7 @@ extern "C" { #include "SDL_events.h" #include "SDL_hints.h" #include "SDL_log.h" +#include "SDL_main.h" #include "SDL_stdinc.h" #include "SDL_render.h" #include "../SDL_sysvideo.h" @@ -93,18 +94,20 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n // 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 (newValue) { + 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; + } } } @@ -245,6 +248,7 @@ void SDL_WinRTApp::Load(Platform::String^ entryPoint) void SDL_WinRTApp::Run() { + SDL_SetMainReady(); if (SDL_WinRT_main) { // TODO, WinRT: pass the C-style main() a reasonably realistic From a49f0e4f745b5b392d010798f221e43c27e95bd8 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 13 Aug 2013 20:33:15 -0400 Subject: [PATCH 166/264] WinRT: added a stub implementation of UpdateClipRect to the D3D 11.1 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index ed741c278..9d34d0d81 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -69,6 +69,7 @@ static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 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_UpdateClipRect(SDL_Renderer * renderer); static int D3D11_RenderClear(SDL_Renderer * renderer); static int D3D11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count); @@ -176,6 +177,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->UnlockTexture = D3D11_UnlockTexture; renderer->SetRenderTarget = D3D11_SetRenderTarget; renderer->UpdateViewport = D3D11_UpdateViewport; + renderer->UpdateClipRect = D3D11_UpdateClipRect; renderer->RenderClear = D3D11_RenderClear; renderer->RenderDrawPoints = D3D11_RenderDrawPoints; renderer->RenderDrawLines = D3D11_RenderDrawLines; @@ -1254,6 +1256,13 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) return 0; } +static int +D3D11_UpdateClipRect(SDL_Renderer * renderer) +{ + // TODO, WinRT: implement D3D11_UpdateClipRect + return 0; +} + static ComPtr & D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer) { From bfb6a12e2c4aee222e97a74f4103638d23106e68 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 21:22:32 -0400 Subject: [PATCH 167/264] WinRT: file naming and placement cleanup - moved SDL_WinRTApp.* from src/video/windowsrt/ to src/core/winrt/, and renamed them to SDL_winrtapp.* (to mimick case-sensitivity used elsewhere in SDL) - renamed all "windowsrt" directories (in src) to "winrt", as the shorthand name is used more often (and, IMO, "WinRT" != "Windows RT", not entirely at least) --HG-- rename : src/video/windowsrt/SDL_WinRTApp.cpp => src/core/winrt/SDL_winrtapp.cpp rename : src/video/windowsrt/SDL_WinRTApp.h => src/core/winrt/SDL_winrtapp.h rename : src/core/windowsrt/SDL_winrtpaths.cpp => src/core/winrt/SDL_winrtpaths.cpp rename : src/video/windowsrt/SDL_winrtevents.cpp => src/video/winrt/SDL_winrtevents.cpp rename : src/video/windowsrt/SDL_winrtevents_c.h => src/video/winrt/SDL_winrtevents_c.h rename : src/video/windowsrt/SDL_winrtmouse.cpp => src/video/winrt/SDL_winrtmouse.cpp rename : src/video/windowsrt/SDL_winrtmouse.h => src/video/winrt/SDL_winrtmouse.h rename : src/video/windowsrt/SDL_winrtvideo.cpp => src/video/winrt/SDL_winrtvideo.cpp rename : src/video/windowsrt/SDL_winrtvideo.h => src/video/winrt/SDL_winrtvideo.h --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 30 +++++------ .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 54 +++++++++---------- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 34 ++++++------ .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 54 +++++++++---------- .../winrt/SDL_winrtapp.cpp} | 6 +-- .../winrt/SDL_winrtapp.h} | 0 .../{windowsrt => winrt}/SDL_winrtpaths.cpp | 0 .../{windowsrt => winrt}/SDL_winrtevents.cpp | 2 +- .../{windowsrt => winrt}/SDL_winrtevents_c.h | 0 .../{windowsrt => winrt}/SDL_winrtmouse.cpp | 2 +- .../{windowsrt => winrt}/SDL_winrtmouse.h | 0 .../{windowsrt => winrt}/SDL_winrtvideo.cpp | 2 +- .../{windowsrt => winrt}/SDL_winrtvideo.h | 0 13 files changed, 92 insertions(+), 92 deletions(-) rename src/{video/windowsrt/SDL_WinRTApp.cpp => core/winrt/SDL_winrtapp.cpp} (97%) rename src/{video/windowsrt/SDL_WinRTApp.h => core/winrt/SDL_winrtapp.h} (100%) rename src/core/{windowsrt => winrt}/SDL_winrtpaths.cpp (100%) rename src/video/{windowsrt => winrt}/SDL_winrtevents.cpp (96%) rename src/video/{windowsrt => winrt}/SDL_winrtevents_c.h (100%) rename src/video/{windowsrt => winrt}/SDL_winrtmouse.cpp (99%) rename src/video/{windowsrt => winrt}/SDL_winrtmouse.h (100%) rename src/video/{windowsrt => winrt}/SDL_winrtvideo.cpp (98%) rename src/video/{windowsrt => winrt}/SDL_winrtvideo.h (100%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 9da6c8431..90a89b389 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -197,6 +197,7 @@ + @@ -244,10 +245,9 @@ - - - - + + + @@ -272,13 +272,19 @@ true true - + + + true + true + true + true + + true true true true - @@ -351,25 +357,19 @@ - + true true true true - + true true true true - - true - true - true - true - - + true true true diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 2e3dcb4c6..e3c9237f1 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -321,21 +321,21 @@ Source Files - - Source Files - - - Source Files - - - Source Files - - - Source Files - Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -374,9 +374,6 @@ Source Files - - Source Files - Source Files @@ -572,18 +569,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - - - Source Files - Source Files @@ -593,6 +578,21 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 3a770d61e..1956f6399 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -53,7 +53,16 @@ true true - + + + true + true + true + true + true + true + + true true true @@ -61,7 +70,6 @@ true true - @@ -136,7 +144,7 @@ - + true true true @@ -144,7 +152,7 @@ true true - + true true true @@ -152,15 +160,7 @@ true true - - true - true - true - true - true - true - - + true true true @@ -227,6 +227,7 @@ + @@ -275,10 +276,9 @@ - - - - + + + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 9e8007cf2..d6a0cbee5 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -225,18 +225,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - - - Source Files - Source Files @@ -252,9 +240,6 @@ Source Files - - Source Files - Source Files @@ -267,6 +252,21 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -353,9 +353,6 @@ Source Files - - Source Files - Source Files @@ -569,15 +566,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -596,6 +584,18 @@ Header Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/core/winrt/SDL_winrtapp.cpp similarity index 97% rename from src/video/windowsrt/SDL_WinRTApp.cpp rename to src/core/winrt/SDL_winrtapp.cpp index f58639ac0..2cb2048b2 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -13,7 +13,7 @@ extern "C" { #include "SDL_main.h" #include "SDL_stdinc.h" #include "SDL_render.h" -#include "../SDL_sysvideo.h" +#include "../../video/SDL_sysvideo.h" //#include "../../SDL_hints_c.h" #include "../../events/scancodes_windows.h" #include "../../events/SDL_mouse_c.h" @@ -22,8 +22,8 @@ extern "C" { #include "../../render/SDL_sysrender.h" } -#include "SDL_winrtvideo.h" -#include "SDL_WinRTApp.h" +#include "../../video/winrt/SDL_winrtvideo.h" +#include "SDL_winrtapp.h" using namespace concurrency; using namespace std; diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/core/winrt/SDL_winrtapp.h similarity index 100% rename from src/video/windowsrt/SDL_WinRTApp.h rename to src/core/winrt/SDL_winrtapp.h diff --git a/src/core/windowsrt/SDL_winrtpaths.cpp b/src/core/winrt/SDL_winrtpaths.cpp similarity index 100% rename from src/core/windowsrt/SDL_winrtpaths.cpp rename to src/core/winrt/SDL_winrtpaths.cpp diff --git a/src/video/windowsrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp similarity index 96% rename from src/video/windowsrt/SDL_winrtevents.cpp rename to src/video/winrt/SDL_winrtevents.cpp index f445b8b65..8438ac279 100644 --- a/src/video/windowsrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -26,7 +26,7 @@ #include "SDL_winrtvideo.h" #include "SDL_winrtevents_c.h" -#include "SDL_WinRTApp.h" +#include "../../core/winrt/SDL_winrtapp.h" extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/src/video/windowsrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h similarity index 100% rename from src/video/windowsrt/SDL_winrtevents_c.h rename to src/video/winrt/SDL_winrtevents_c.h diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp similarity index 99% rename from src/video/windowsrt/SDL_winrtmouse.cpp rename to src/video/winrt/SDL_winrtmouse.cpp index e0450c655..12c97d064 100644 --- a/src/video/windowsrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -29,7 +29,7 @@ extern "C" { #include "../SDL_sysvideo.h" } -#include "SDL_WinRTApp.h" +#include "../../core/winrt/SDL_winrtapp.h" #include "SDL_winrtmouse.h" using namespace Windows::UI::Core; diff --git a/src/video/windowsrt/SDL_winrtmouse.h b/src/video/winrt/SDL_winrtmouse.h similarity index 100% rename from src/video/windowsrt/SDL_winrtmouse.h rename to src/video/winrt/SDL_winrtmouse.h diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp similarity index 98% rename from src/video/windowsrt/SDL_winrtvideo.cpp rename to src/video/winrt/SDL_winrtvideo.cpp index 7a459fb95..b5295dd13 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -38,7 +38,7 @@ extern "C" { #include "SDL_syswm.h" } -#include "SDL_WinRTApp.h" +#include "../../core/winrt/SDL_winrtapp.h" #include "SDL_winrtvideo.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse.h" diff --git a/src/video/windowsrt/SDL_winrtvideo.h b/src/video/winrt/SDL_winrtvideo.h similarity index 100% rename from src/video/windowsrt/SDL_winrtvideo.h rename to src/video/winrt/SDL_winrtvideo.h From 1b1aa5ec4eda8d7605c5d031b7a4795fda27e427 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 21:54:34 -0400 Subject: [PATCH 168/264] WinRT: made the C++11-based threading backend only try to catch exceptions that it knows it (the threading APIs) might throw, rather than all exceptions --- src/thread/stdcpp/SDL_syscond.cpp | 43 ++++++++--------------------- src/thread/stdcpp/SDL_sysmutex.cpp | 33 +++++++--------------- src/thread/stdcpp/SDL_systhread.cpp | 17 ++++++------ 3 files changed, 31 insertions(+), 62 deletions(-) diff --git a/src/thread/stdcpp/SDL_syscond.cpp b/src/thread/stdcpp/SDL_syscond.cpp index 4ca1d96f7..a355607a1 100644 --- a/src/thread/stdcpp/SDL_syscond.cpp +++ b/src/thread/stdcpp/SDL_syscond.cpp @@ -26,8 +26,8 @@ extern "C" { #include #include -#include #include +#include #include "SDL_sysmutex_c.h" @@ -45,11 +45,11 @@ SDL_CreateCond(void) try { SDL_cond * cond = new SDL_cond; return cond; - } catch (std::exception & ex) { - SDL_SetError("unable to create C++ condition variable: %s", ex.what()); + } catch (std::system_error & ex) { + SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what()); return NULL; - } catch (...) { - SDL_SetError("unable to create C++ condition variable due to an unknown exception"); + } catch (std::bad_alloc &) { + SDL_OutOfMemory(); return NULL; } } @@ -60,11 +60,7 @@ void SDL_DestroyCond(SDL_cond * cond) { if (cond) { - try { - delete cond; - } catch (...) { - // catch any and all exceptions, just in case something happens - } + delete cond; } } @@ -78,14 +74,8 @@ SDL_CondSignal(SDL_cond * cond) 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; - } + cond->cpp_cond.notify_one(); + return 0; } /* Restart all threads that are waiting on the condition variable */ @@ -98,14 +88,8 @@ SDL_CondBroadcast(SDL_cond * cond) 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; - } + cond->cpp_cond.notify_all(); + return 0; } /* Wait on the condition variable for at most 'ms' milliseconds. @@ -163,11 +147,8 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) 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"); + } catch (std::system_error & ex) { + SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); return -1; } } diff --git a/src/thread/stdcpp/SDL_sysmutex.cpp b/src/thread/stdcpp/SDL_sysmutex.cpp index e43b255e8..df91a0d44 100644 --- a/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/src/thread/stdcpp/SDL_sysmutex.cpp @@ -26,7 +26,7 @@ extern "C" { #include "SDL_log.h" } -#include +#include #include "SDL_sysmutex_c.h" #include @@ -41,11 +41,11 @@ SDL_CreateMutex(void) try { SDL_mutex * mutex = new SDL_mutex; return mutex; - } catch (std::exception & ex) { - SDL_SetError("unable to create C++ mutex: %s", ex.what()); + } catch (std::system_error & ex) { + SDL_SetError("unable to create a C++ mutex: code=%d; %s", ex.code(), ex.what()); return NULL; - } catch (...) { - SDL_SetError("unable to create C++ mutex due to an unknown exception"); + } catch (std::bad_alloc &) { + SDL_OutOfMemory(); return NULL; } } @@ -56,11 +56,7 @@ void SDL_DestroyMutex(SDL_mutex * mutex) { if (mutex) { - try { - delete mutex; - } catch (...) { - // catch any and all exceptions, just in case something happens - } + delete mutex; } } @@ -79,11 +75,8 @@ SDL_mutexP(SDL_mutex * mutex) 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"); + } catch (std::system_error & ex) { + SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what()); return -1; } } @@ -100,14 +93,8 @@ SDL_mutexV(SDL_mutex * 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; - } + mutex->cpp_mutex.unlock(); + return 0; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index fb1ca31b5..b9252e75e 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -31,6 +31,7 @@ extern "C" { #include #include +#include // 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 @@ -55,11 +56,11 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) 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()); + } catch (std::system_error & ex) { + SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what()); return -1; - } catch (...) { - SDL_SetError("unable to create a C++ thread due to an unknown exception"); + } catch (std::bad_alloc &) { + SDL_OutOfMemory(); return -1; } } @@ -114,10 +115,10 @@ SDL_SYS_WaitThread(SDL_Thread * thread) 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. + } catch (std::system_error &) { + // An error occurred when joining the thread. SDL_WaitThread does not, + // however, seem to provide a means to report errors to its callers + // though! } } From d8672afbe490682173326cf3888a4ba31d30045b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 21:55:13 -0400 Subject: [PATCH 169/264] WinRT: made testthread log output via SDL_Log - this will allow output to be read via Visual C++'s Output pane --- test/testthread.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/testthread.c b/test/testthread.c index 949e44e3a..9cea7576b 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -34,20 +34,20 @@ int SDLCALL ThreadFunc(void *data) { SDL_TLSSet(tls, "baby thread", NULL); - printf("Started thread %s: My thread id is %lu, thread data = %s\n", + SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n", (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls)); while (alive) { - printf("Thread '%s' is alive!\n", (char *) data); + SDL_Log("Thread '%s' is alive!\n", (char *) data); SDL_Delay(1 * 1000); } - printf("Thread '%s' exiting!\n", (char *) data); + SDL_Log("Thread '%s' exiting!\n", (char *) data); return (0); } static void killed(int sig) { - printf("Killed with SIGTERM, waiting 5 seconds to exit\n"); + SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); SDL_Delay(5 * 1000); alive = 0; quit(0); @@ -60,33 +60,33 @@ main(int argc, char *argv[]) /* Load the SDL library */ if (SDL_Init(0) < 0) { - fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError()); return (1); } tls = SDL_TLSCreate(); SDL_assert(tls); SDL_TLSSet(tls, "main thread", NULL); - printf("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); + SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); alive = 1; thread = SDL_CreateThread(ThreadFunc, "One", "#1"); if (thread == NULL) { - fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); + SDL_Log("Couldn't create thread: %s\n", SDL_GetError()); quit(1); } SDL_Delay(5 * 1000); - printf("Waiting for thread #1\n"); + SDL_Log("Waiting for thread #1\n"); alive = 0; SDL_WaitThread(thread, NULL); - printf("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); + SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); alive = 1; signal(SIGTERM, killed); thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); if (thread == NULL) { - fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError()); + SDL_Log("Couldn't create thread: %s\n", SDL_GetError()); quit(1); } raise(SIGTERM); From 3a2e64540b2b3b5da1169b76bd973702013e3414 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 22:04:09 -0400 Subject: [PATCH 170/264] WinRT: made SDL_ThreadID() return the native thread ID, rather than a fake one --- src/thread/stdcpp/SDL_systhread.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index b9252e75e..c580481ce 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -33,13 +33,8 @@ extern "C" { #include #include -// 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 +#ifdef __WINRT__ +#include #endif static void @@ -78,6 +73,10 @@ extern "C" SDL_threadID SDL_ThreadID(void) { +#ifdef __WINRT__ + return GetCurrentThreadId(); +#else + // HACK: Mimick a thread ID, if one isn't otherwise available. static thread_local SDL_threadID current_thread_id = 0; static SDL_threadID next_thread_id = 1; static std::mutex next_thread_id_mutex; @@ -89,6 +88,7 @@ SDL_ThreadID(void) } return current_thread_id; +#endif } extern "C" From 2e2d2a0bd435e5c6bd85b7beb7b92e343555aab2 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 22:16:09 -0400 Subject: [PATCH 171/264] WinRT: made a note that WinRT doesn't appear to support modifying a thread's priority --- src/thread/stdcpp/SDL_systhread.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index c580481ce..02fcf76aa 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -99,6 +99,14 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) // 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. + // + // WinRT: UPDATE (Aug 20, 2013): thread priorities cannot be changed + // on WinRT, at least not for any thread that's already been created. + // WinRT threads appear to be based off of the WinRT class, + // ThreadPool, more info on which can be found at: + // http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.threading.threadpool.aspx + // + // For compatibility sake, 0 will be returned here. return (0); } From 6a6cc6b5e8299cbd128a805f692c4c25d58a01b7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 20 Aug 2013 22:18:48 -0400 Subject: [PATCH 172/264] WinRT: removed some old debugging code from SDL_mutexP and SDL_mutexV --- src/thread/stdcpp/SDL_sysmutex.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/thread/stdcpp/SDL_sysmutex.cpp b/src/thread/stdcpp/SDL_sysmutex.cpp index df91a0d44..f5283e4a5 100644 --- a/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/src/thread/stdcpp/SDL_sysmutex.cpp @@ -65,8 +65,6 @@ 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; @@ -86,8 +84,6 @@ 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; From b06f02e4e505765c4a43045b229696060530c29b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 26 Aug 2013 17:17:53 -0400 Subject: [PATCH 173/264] WinRT: moved most platform-specific keyboard and mouse code to shared locations --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 1 + .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 3 + VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 8 + .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 3 + src/core/winrt/SDL_winrtapp.cpp | 475 +----------------- src/core/winrt/SDL_winrtapp.h | 2 - src/video/winrt/SDL_winrtevents_c.h | 32 +- src/video/winrt/SDL_winrtkeyboard.cpp | 300 +++++++++++ src/video/winrt/SDL_winrtmouse.cpp | 260 +++++++++- 9 files changed, 617 insertions(+), 467 deletions(-) create mode 100644 src/video/winrt/SDL_winrtkeyboard.cpp diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 90a89b389..e2459fa0f 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -363,6 +363,7 @@ true true + true true diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index e3c9237f1..bd2128a3b 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -593,6 +593,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 1956f6399..200b6d58b 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -152,6 +152,14 @@ true true + + true + true + true + true + true + true + true true diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index d6a0cbee5..9a0961341 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -267,6 +267,9 @@ Source Files + + Source Files + diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 2cb2048b2..557c3a1ec 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -1,6 +1,6 @@  +#include #include -#include #include #include "ppltasks.h" @@ -15,13 +15,12 @@ extern "C" { #include "SDL_render.h" #include "../../video/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 "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo.h" #include "SDL_winrtapp.h" @@ -142,8 +141,7 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), m_sdlWindowData(NULL), - m_sdlVideoDevice(NULL), - m_useRelativeMouseMode(false) + m_sdlVideoDevice(NULL) { } @@ -387,482 +385,44 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) 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); - } - } + SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); + WINRT_ProcessPointerPressedEvent(window, args); } 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); - } - } + SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); + WINRT_ProcessPointerReleasedEvent(window, args); } 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); - } + SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); + WINRT_ProcessPointerWheelChangedEvent(window, args); } 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; + SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); + WINRT_ProcessMouseMovedEvent(window, args); } 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 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; + SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); + WINRT_ProcessPointerMovedEvent(window, args); } 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); + WINRT_ProcessKeyDownEvent(args); } 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); + WINRT_ProcessKeyUpEvent(args); } void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) @@ -970,11 +530,6 @@ 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; diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index cd0c379fc..053a0dfd7 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -20,7 +20,6 @@ internal: 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); @@ -48,5 +47,4 @@ private: bool m_windowVisible; const SDL_WindowData* m_sdlWindowData; const SDL_VideoDevice* m_sdlVideoDevice; - bool m_useRelativeMouseMode; }; diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index afbd6862c..f4b179e62 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -19,9 +19,39 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_config.h" - #include "SDL_winrtvideo.h" +/* + * Internal-use, C-style functions: + */ + +#ifdef __cplusplus +extern "C" { +#endif + extern void WINRT_PumpEvents(_THIS); +#ifdef __cplusplus +} +#endif + + +/* + * Internal-use, C++/CX functions: + */ +#ifdef __cplusplus_winrt + +/* Keyboard */ +extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); +extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); + +/* Pointers (Mice, Touch, etc.) */ +extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); +extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); +extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); +extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); + +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtkeyboard.cpp b/src/video/winrt/SDL_winrtkeyboard.cpp new file mode 100644 index 000000000..52b8c2a39 --- /dev/null +++ b/src/video/winrt/SDL_winrtkeyboard.cpp @@ -0,0 +1,300 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 + +// Standard C++11 headers: +#include + + +// Windows-specific headers: +#include + + +// SDL-specific headers: +#include +#include "SDL_winrtevents_c.h" + +extern "C" { +#include "../../events/scancodes_windows.h" +#include "../../events/SDL_keyboard_c.h" +} + + +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 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 +WINRT_ProcessKeyDownEvent(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 +WINRT_ProcessKeyUpEvent(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); +} + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 12c97d064..ec32a2ab2 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -23,19 +23,29 @@ #if SDL_VIDEO_DRIVER_WINRT +/* + * Windows includes: + */ +#include +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ extern "C" { #include "SDL_assert.h" #include "../../events/SDL_mouse_c.h" #include "../SDL_sysvideo.h" +#include "SDL_events.h" +#include "SDL_log.h" } #include "../../core/winrt/SDL_winrtapp.h" #include "SDL_winrtmouse.h" -using namespace Windows::UI::Core; -using Windows::UI::Core::CoreCursor; -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; +static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE; static SDL_Cursor * @@ -112,7 +122,7 @@ WINRT_ShowCursor(SDL_Cursor * cursor) static int WINRT_SetRelativeMouseMode(SDL_bool enabled) { - SDL_WinRTGlobalApp->SetRelativeMouseMode(enabled ? true : false); + WINRT_UseRelativeMouseMode = enabled; return 0; } @@ -144,6 +154,248 @@ WINRT_QuitMouse(_THIS) { } +// Applies necessary geometric transformations to raw cursor positions: +static Windows::Foundation::Point +TransformCursor(SDL_Window * window, Windows::Foundation::Point rawPosition) +{ + if (!window) { + return rawPosition; + } + CoreWindow ^ nativeWindow = CoreWindow::GetForCurrentThread(); + Windows::Foundation::Point outputPosition; + outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + return outputPosition; +} + +static inline int +_lround(float arg) +{ + if (arg >= 0.0f) { + return (int)floor(arg + 0.5f); + } else { + return (int)ceil(arg - 0.5f); + } +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UseRelativeMouseMode) { + return; + } + + // 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = TransformCursor(window, mouseDeltaInDIPs); + SDL_SendMouseMotion( + window, + 0, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); +} + +static Uint8 +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +{ + using namespace Windows::UI::Input; + + 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(Windows::UI::Input::PointerUpdateKind kind) +{ + using namespace Windows::UI::Input; + + 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 char * header, PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind)); +} + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, TransformCursor(args->CurrentPoint->Position)); +#endif + + if (!window || WINRT_UseRelativeMouseMode) { + return; + } + + Windows::Foundation::Point transformedPoint = TransformCursor(window, args->CurrentPoint->Position); + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("wheel changed", args, TransformCursor(args->CurrentPoint->Position)); +#endif + + if (!window) { + return; + } + + // FIXME: This may need to accumulate deltas up to WHEEL_DELTA + short motion = args->CurrentPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, motion); +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position)); +#endif + + if (!window) { + return; + } + + Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } +} + +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position)); +#endif + + if (!window) { + return; + } + + Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } +} + #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ From 766ce058bc5a791f550a04ad30623c47b9052b7a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 09:53:58 -0400 Subject: [PATCH 174/264] WinRT: removed a deprecated hack regarding window resizing and Direct3D viewports --- src/core/winrt/SDL_winrtapp.cpp | 34 +-------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 557c3a1ec..00d4762be 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -302,36 +302,9 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // 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(); + m_sdlWindowData->sdlWindow->fullscreen_mode = 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... - // - // UPDATE, SDL 2.0.0 update: the 'resized' flag is now gone. This - // hack might not be necessary any more. - // - //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); @@ -340,11 +313,6 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven SDL_WINDOWEVENT_RESIZED, windowWidth, windowHeight); - - //// Viewport hack, part two: - //if (usingD3D11Renderer) { - // rendererForMainWindow->resized = wasD3D11RendererResized; - //} } } From 2d5990892afc10c291ffbd3964f3bf83617304db Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 10:56:10 -0400 Subject: [PATCH 175/264] WinRT: made all SDL_Windows get sized to the WinRT-defined window size This change removes some code that attempted to allow non-standard window sizes, the idea of which was to do display scaling, and a hackish one at that. If display scaling is needed, use SDL_Renderer as appropriate. --- src/core/winrt/SDL_winrtapp.cpp | 10 ++++++---- src/video/winrt/SDL_winrtvideo.cpp | 29 ++++++----------------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 00d4762be..22df55b35 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -300,10 +300,12 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // 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 = GetMainDisplayMode(); - SDL_AddDisplayMode(&m_sdlVideoDevice->displays[0], &m_sdlWindowData->sdlWindow->fullscreen_mode); + SDL_DisplayMode newDisplayMode = GetMainDisplayMode(); + m_sdlVideoDevice->displays[0].current_mode = newDisplayMode; + m_sdlVideoDevice->displays[0].desktop_mode = newDisplayMode; + m_sdlVideoDevice->displays[0].display_modes[0] = newDisplayMode; + + m_sdlWindowData->sdlWindow->fullscreen_mode = newDisplayMode; // Send the window-resize event to the rest of SDL, and to apps: const int windowWidth = (int) ceil(args->Size.Width); diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index b5295dd13..48e6ed8dd 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -187,31 +187,14 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) 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; + /* WinRT does not, as of this writing, appear to support app-adjustable + window sizes. Set the window size to whatever the native WinRT + CoreWindow is set at. - /* 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. + TODO, WinRT: if and when non-fullscreen XAML control support is added to SDL, consider making those resizable via SDL_Window's interfaces. */ - 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. */ + window->w = _this->displays[0].current_mode.w; + window->h = _this->displays[0].current_mode.h; /* Make sure the WinRT app's IFramworkView can post events on behalf of SDL: From 93e2bef145b89b1506e1ff744622443781057c09 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 10:57:55 -0400 Subject: [PATCH 176/264] WinRT: minor function and variable name cleanup --- src/core/winrt/SDL_winrtapp.cpp | 12 ++++++------ src/core/winrt/SDL_winrtapp.h | 2 +- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 22df55b35..e2fbba77d 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -300,12 +300,12 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // 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. - SDL_DisplayMode newDisplayMode = GetMainDisplayMode(); - m_sdlVideoDevice->displays[0].current_mode = newDisplayMode; - m_sdlVideoDevice->displays[0].desktop_mode = newDisplayMode; - m_sdlVideoDevice->displays[0].display_modes[0] = newDisplayMode; + SDL_DisplayMode resizedDisplayMode = CalcCurrentDisplayMode(); + m_sdlVideoDevice->displays[0].current_mode = resizedDisplayMode; + m_sdlVideoDevice->displays[0].desktop_mode = resizedDisplayMode; + m_sdlVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; - m_sdlWindowData->sdlWindow->fullscreen_mode = newDisplayMode; + m_sdlWindowData->sdlWindow->fullscreen_mode = resizedDisplayMode; // Send the window-resize event to the rest of SDL, and to apps: const int windowWidth = (int) ceil(args->Size.Width); @@ -469,7 +469,7 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) } } -SDL_DisplayMode SDL_WinRTApp::GetMainDisplayMode() +SDL_DisplayMode SDL_WinRTApp::CalcCurrentDisplayMode() { // Create an empty, zeroed-out display mode: SDL_DisplayMode mode; diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index 053a0dfd7..db19e8c6a 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -16,7 +16,7 @@ public: internal: // SDL-specific methods - SDL_DisplayMode GetMainDisplayMode(); + SDL_DisplayMode CalcCurrentDisplayMode(); void PumpEvents(); const SDL_WindowData * GetSDLWindowData() const; bool HasSDLWindowData() const; diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 48e6ed8dd..e87e056c5 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -134,7 +134,7 @@ WINRT_VideoInit(_THIS) static int WINRT_InitModes(_THIS) { - SDL_DisplayMode mode = SDL_WinRTGlobalApp->GetMainDisplayMode(); + SDL_DisplayMode mode = SDL_WinRTGlobalApp->CalcCurrentDisplayMode(); if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } From a52281f4e55166ad4b1e38e8485e37bbd1101103 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 11:00:52 -0400 Subject: [PATCH 177/264] WinRT: removed more hack-code that attempted to help have non-standard window sizes "Non-standard" is defined here as any window size that differs from that provided by WinRT's CoreWindow. --- src/core/winrt/SDL_winrtapp.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index e2fbba77d..2ce66b5d1 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -290,8 +290,8 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven 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. + // This change was initially 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 @@ -305,8 +305,6 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven m_sdlVideoDevice->displays[0].desktop_mode = resizedDisplayMode; m_sdlVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; - m_sdlWindowData->sdlWindow->fullscreen_mode = resizedDisplayMode; - // 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); From 690391390b99e414627fbd2dc9b135224bd25f3a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 11:39:44 -0400 Subject: [PATCH 178/264] WinRT: misc code cleanups --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 1 - .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 3 - src/core/winrt/SDL_winrtapp.cpp | 88 +++++++++---------- src/core/winrt/SDL_winrtapp.h | 9 +- src/video/winrt/SDL_winrtevents.cpp | 12 ++- src/video/winrt/SDL_winrtevents_c.h | 5 +- src/video/winrt/SDL_winrtkeyboard.cpp | 7 +- src/video/winrt/SDL_winrtvideo.cpp | 41 ++++----- src/video/winrt/SDL_winrtvideo.h | 40 --------- 9 files changed, 82 insertions(+), 124 deletions(-) delete mode 100644 src/video/winrt/SDL_winrtvideo.h diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 200b6d58b..1e8291494 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -286,7 +286,6 @@ - diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 9a0961341..d28d017d4 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -593,9 +593,6 @@ Source Files - - Source Files - Source Files diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 2ce66b5d1..7622314fd 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -1,10 +1,26 @@  +/* Standard C++11 includes */ #include #include #include +using namespace std; + +/* Windows includes */ #include "ppltasks.h" +using namespace concurrency; +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; + +/* SDL includes */ extern "C" { #include "SDL_assert.h" #include "SDL_events.h" @@ -21,20 +37,8 @@ extern "C" { } #include "../../video/winrt/SDL_winrtevents_c.h" -#include "../../video/winrt/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. @@ -140,7 +144,7 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), - m_sdlWindowData(NULL), + m_sdlWindow(NULL), m_sdlVideoDevice(NULL) { } @@ -279,16 +283,16 @@ 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", + SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, m_sdlWindow?=%s\n", __FUNCTION__, args->Size.Width, args->Size.Height, (int)DisplayProperties::CurrentOrientation, (int)DisplayProperties::NativeOrientation, (int)DisplayProperties::AutoRotationPreferences, - (m_sdlWindowData ? "yes" : "no")); + (m_sdlWindow ? "yes" : "no")); #endif - if (m_sdlWindowData) { + if (m_sdlWindow) { // Make the new window size be the one true fullscreen mode. // This change was initially done, in part, to allow the Direct3D 11.1 // renderer to receive window-resize events as a device rotates. @@ -309,7 +313,7 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven const int windowWidth = (int) ceil(args->Size.Width); const int windowHeight = (int) ceil(args->Size.Height); SDL_SendWindowEvent( - m_sdlWindowData->sdlWindow, + m_sdlWindow, SDL_WINDOWEVENT_RESIZED, windowWidth, windowHeight); @@ -319,20 +323,20 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { #if LOG_WINDOW_EVENTS==1 - SDL_Log("%s, visible?=%s, m_sdlWindowData?=%s\n", + SDL_Log("%s, visible?=%s, m_sdlWindow?=%s\n", __FUNCTION__, (args->Visible ? "yes" : "no"), - (m_sdlWindowData ? "yes" : "no")); + (m_sdlWindow ? "yes" : "no")); #endif m_windowVisible = args->Visible; - if (m_sdlWindowData) { - SDL_bool wasSDLWindowSurfaceValid = m_sdlWindowData->sdlWindow->surface_valid; + if (m_sdlWindow) { + SDL_bool wasSDLWindowSurfaceValid = m_sdlWindow->surface_valid; if (args->Visible) { - SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(m_sdlWindowData->sdlWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); } // HACK: Prevent SDL's window-hide handling code, which currently @@ -341,7 +345,7 @@ void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEven // // A better solution to this probably involves figuring out if the // fake window resize can be prevented. - m_sdlWindowData->sdlWindow->surface_valid = wasSDLWindowSurfaceValid; + m_sdlWindow->surface_valid = wasSDLWindowSurfaceValid; } } @@ -355,32 +359,27 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); - WINRT_ProcessPointerPressedEvent(window, args); + WINRT_ProcessPointerPressedEvent(m_sdlWindow, args); } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { - SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); - WINRT_ProcessPointerReleasedEvent(window, args); + WINRT_ProcessPointerReleasedEvent(m_sdlWindow, args); } void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { - SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); - WINRT_ProcessPointerWheelChangedEvent(window, args); + WINRT_ProcessPointerWheelChangedEvent(m_sdlWindow, args); } void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) { - SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); - WINRT_ProcessMouseMovedEvent(window, args); + WINRT_ProcessMouseMovedEvent(m_sdlWindow, args); } void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { - SDL_Window * window = (m_sdlWindowData ? m_sdlWindowData->sdlWindow : nullptr); - WINRT_ProcessPointerMovedEvent(window, args); + WINRT_ProcessPointerMovedEvent(m_sdlWindow, args); } void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) @@ -439,9 +438,9 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a // 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) + if (m_sdlWindow) { - 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_SendWindowEvent(m_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(); @@ -453,9 +452,9 @@ 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) + if (m_sdlWindow) { - 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) + SDL_SendWindowEvent(m_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. @@ -488,19 +487,14 @@ SDL_DisplayMode SDL_WinRTApp::CalcCurrentDisplayMode() return mode; } -const SDL_WindowData * SDL_WinRTApp::GetSDLWindowData() const +SDL_Window * SDL_WinRTApp::GetSDLWindow() { - return m_sdlWindowData; + return m_sdlWindow; } -bool SDL_WinRTApp::HasSDLWindowData() const +void SDL_WinRTApp::SetSDLWindow(SDL_Window * window) { - return (m_sdlWindowData != NULL); -} - -void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData * windowData) -{ - m_sdlWindowData = windowData; + m_sdlWindow = window; } void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice) diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index db19e8c6a..ada19634c 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -1,7 +1,5 @@ #pragma once -struct SDL_WindowData; - ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { public: @@ -18,9 +16,8 @@ internal: // SDL-specific methods SDL_DisplayMode CalcCurrentDisplayMode(); void PumpEvents(); - const SDL_WindowData * GetSDLWindowData() const; - bool HasSDLWindowData() const; - void SetSDLWindowData(const SDL_WindowData * windowData); + SDL_Window * GetSDLWindow(); + void SetSDLWindow(SDL_Window * window); void SetSDLVideoDevice(const SDL_VideoDevice * videoDevice); Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); @@ -45,6 +42,6 @@ protected: private: bool m_windowClosed; bool m_windowVisible; - const SDL_WindowData* m_sdlWindowData; + SDL_Window* m_sdlWindow; const SDL_VideoDevice* m_sdlVideoDevice; }; diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index 8438ac279..ef1cb690e 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -22,14 +22,20 @@ #if SDL_VIDEO_DRIVER_WINRT -#include "../../events/SDL_events_c.h" - -#include "SDL_winrtvideo.h" +/* SDL includes */ #include "SDL_winrtevents_c.h" #include "../../core/winrt/SDL_winrtapp.h" +extern "C" { +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" +} + extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; + +/* General event-management function(s) */ + void WINRT_PumpEvents(_THIS) { diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index f4b179e62..68e746a72 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -19,7 +19,10 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_config.h" -#include "SDL_winrtvideo.h" + +extern "C" { +#include "../SDL_sysvideo.h" +} /* * Internal-use, C-style functions: diff --git a/src/video/winrt/SDL_winrtkeyboard.cpp b/src/video/winrt/SDL_winrtkeyboard.cpp index 52b8c2a39..a68b6d50c 100644 --- a/src/video/winrt/SDL_winrtkeyboard.cpp +++ b/src/video/winrt/SDL_winrtkeyboard.cpp @@ -22,15 +22,16 @@ #if SDL_VIDEO_DRIVER_WINRT -// Standard C++11 headers: +/* Standard C++11 includes */ #include -// Windows-specific headers: +/* Windows-specific includes */ #include +#include -// SDL-specific headers: +/* SDL-specific includes */ #include #include "SDL_winrtevents_c.h" diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index e87e056c5..03ff7730e 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -28,6 +28,12 @@ was based off of SDL's "dummy" video driver. */ +/* Windows includes */ +#include +using namespace Windows::UI::Core; + + +/* SDL includes */ extern "C" { #include "SDL_video.h" #include "SDL_mouse.h" @@ -39,20 +45,11 @@ extern "C" { } #include "../../core/winrt/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); @@ -60,11 +57,21 @@ 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); + +/* Internal window data */ +struct SDL_WindowData +{ + SDL_Window *sdlWindow; + Platform::Agile coreWindow; +}; + + /* WinRT driver bootstrap functions */ static int @@ -102,17 +109,14 @@ WINRT_CreateDevice(int devindex) 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; } +#define WINRTVID_DRIVER_NAME "winrt" VideoBootStrap WINRT_bootstrap = { WINRTVID_DRIVER_NAME, "SDL Windows RT video driver", WINRT_Available, WINRT_CreateDevice @@ -160,8 +164,7 @@ 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()) - { + if (SDL_WinRTGlobalApp->GetSDLWindow() != NULL) { SDL_SetError("WinRT only supports one window"); return -1; } @@ -199,7 +202,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) /* Make sure the WinRT app's IFramworkView can post events on behalf of SDL: */ - SDL_WinRTGlobalApp->SetSDLWindowData(data); + SDL_WinRTGlobalApp->SetSDLWindow(window); /* All done! */ return 0; @@ -210,10 +213,8 @@ 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 (SDL_WinRTGlobalApp->GetSDLWindow() == window) { + SDL_WinRTGlobalApp->SetSDLWindow(NULL); } if (data) { diff --git a/src/video/winrt/SDL_winrtvideo.h b/src/video/winrt/SDL_winrtvideo.h deleted file mode 100644 index 4418754c2..000000000 --- a/src/video/winrt/SDL_winrtvideo.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 - -struct SDL_WindowData -{ - SDL_Window *sdlWindow; - Platform::Agile coreWindow; -}; - -#endif /* _SDL_winrtvideo_h */ - -/* vi: set ts=4 sw=4 expandtab: */ From 6964e2e325c76f8559ef2490fea87cec0e84e643 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 11:40:06 -0400 Subject: [PATCH 179/264] WinRT: Windows Phone build fix --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 8 ++++++-- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 3 --- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index e2459fa0f..1122a94ee 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -247,7 +247,6 @@ - @@ -363,7 +362,12 @@ true true - + + true + true + true + true + true true diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index bd2128a3b..fce316fe6 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -333,9 +333,6 @@ Source Files - - Source Files - From 45a13dac178ec73f81d65addf21ef86c9d13d8fd Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 11:44:43 -0400 Subject: [PATCH 180/264] WinRT: renamed SDL_SYSWM_WINDOWSRT to SDL_SYSWM_WINRT This is part of an overall effort to use the name, "WinRT", rather than "WindowsRT" (or "Windows RT"), as the shorthand name often seems to mean something different than the longhand name. (WinRT is an API, Windows RT is a product name) --- include/SDL_syswm.h | 2 +- src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 3b503ae74..5fc8fc419 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -105,7 +105,7 @@ typedef enum { SDL_SYSWM_UNKNOWN, SDL_SYSWM_WINDOWS, - SDL_SYSWM_WINDOWSRT, + SDL_SYSWM_WINRT, SDL_SYSWM_X11, SDL_SYSWM_DIRECTFB, SDL_SYSWM_COCOA, diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 9d34d0d81..fd6e03459 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -583,7 +583,7 @@ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) return nullptr; } - if (sdlWindowInfo.subsystem != SDL_SYSWM_WINDOWSRT) { + if (sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) { return nullptr; } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 03ff7730e..bc6dd1dc8 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -230,7 +230,7 @@ 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->subsystem = SDL_SYSWM_WINRT; info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); return SDL_TRUE; } else { From 40a51bf86b8b93b1840bb157f3288adf17500535 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 11:51:17 -0400 Subject: [PATCH 181/264] WinRT: moved the pointer to the global SDL_Window to a separate variable This is a cleanup that is being done to help with WIP XAML support. It may be reverted in the future. --- src/core/winrt/SDL_winrtapp.cpp | 53 +++++++++++++----------------- src/core/winrt/SDL_winrtapp.h | 3 -- src/video/winrt/SDL_winrtvideo.cpp | 15 ++++++--- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 7622314fd..2a97fc5fc 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -39,6 +39,8 @@ extern "C" { #include "../../video/winrt/SDL_winrtevents_c.h" #include "SDL_winrtapp.h" +extern SDL_Window * WINRT_GlobalSDLWindow; + // Compile-time debugging options: // To enable, uncomment; to disable, comment them out. @@ -144,7 +146,6 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true), - m_sdlWindow(NULL), m_sdlVideoDevice(NULL) { } @@ -283,16 +284,16 @@ 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_sdlWindow?=%s\n", + SDL_Log("%s, size={%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n", __FUNCTION__, args->Size.Width, args->Size.Height, (int)DisplayProperties::CurrentOrientation, (int)DisplayProperties::NativeOrientation, (int)DisplayProperties::AutoRotationPreferences, - (m_sdlWindow ? "yes" : "no")); + (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif - if (m_sdlWindow) { + if (WINRT_GlobalSDLWindow) { // Make the new window size be the one true fullscreen mode. // This change was initially done, in part, to allow the Direct3D 11.1 // renderer to receive window-resize events as a device rotates. @@ -313,7 +314,7 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven const int windowWidth = (int) ceil(args->Size.Width); const int windowHeight = (int) ceil(args->Size.Height); SDL_SendWindowEvent( - m_sdlWindow, + WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESIZED, windowWidth, windowHeight); @@ -323,20 +324,20 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { #if LOG_WINDOW_EVENTS==1 - SDL_Log("%s, visible?=%s, m_sdlWindow?=%s\n", + SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n", __FUNCTION__, (args->Visible ? "yes" : "no"), - (m_sdlWindow ? "yes" : "no")); + (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif m_windowVisible = args->Visible; - if (m_sdlWindow) { - SDL_bool wasSDLWindowSurfaceValid = m_sdlWindow->surface_valid; + if (WINRT_GlobalSDLWindow) { + SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid; if (args->Visible) { - SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0); } // HACK: Prevent SDL's window-hide handling code, which currently @@ -345,7 +346,7 @@ void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEven // // A better solution to this probably involves figuring out if the // fake window resize can be prevented. - m_sdlWindow->surface_valid = wasSDLWindowSurfaceValid; + WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid; } } @@ -359,27 +360,27 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerPressedEvent(m_sdlWindow, args); + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args); } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerReleasedEvent(m_sdlWindow, args); + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args); } void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerWheelChangedEvent(m_sdlWindow, args); + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args); } void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) { - WINRT_ProcessMouseMovedEvent(m_sdlWindow, args); + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); } void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerMovedEvent(m_sdlWindow, args); + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args); } void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) @@ -438,9 +439,9 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a // 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_sdlWindow) + if (WINRT_GlobalSDLWindow) { - SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently) + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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(); @@ -452,9 +453,9 @@ 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_sdlWindow) + if (WINRT_GlobalSDLWindow) { - SDL_SendWindowEvent(m_sdlWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently) + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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. @@ -487,16 +488,6 @@ SDL_DisplayMode SDL_WinRTApp::CalcCurrentDisplayMode() return mode; } -SDL_Window * SDL_WinRTApp::GetSDLWindow() -{ - return m_sdlWindow; -} - -void SDL_WinRTApp::SetSDLWindow(SDL_Window * window) -{ - m_sdlWindow = window; -} - void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice) { m_sdlVideoDevice = videoDevice; diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index ada19634c..a8b5bd343 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -16,8 +16,6 @@ internal: // SDL-specific methods SDL_DisplayMode CalcCurrentDisplayMode(); void PumpEvents(); - SDL_Window * GetSDLWindow(); - void SetSDLWindow(SDL_Window * window); void SetSDLVideoDevice(const SDL_VideoDevice * videoDevice); Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); @@ -42,6 +40,5 @@ protected: private: bool m_windowClosed; bool m_windowVisible; - SDL_Window* m_sdlWindow; const SDL_VideoDevice* m_sdlVideoDevice; }; diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index bc6dd1dc8..8d2f612df 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -72,6 +72,13 @@ struct SDL_WindowData }; +/* The global, WinRT, SDL Window. + For now, SDL/WinRT only supports one window (due to platform limitations of + WinRT. +*/ +SDL_Window * WINRT_GlobalSDLWindow = NULL; + + /* WinRT driver bootstrap functions */ static int @@ -164,7 +171,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) { // Make sure that only one window gets created, at least until multimonitor // support is added. - if (SDL_WinRTGlobalApp->GetSDLWindow() != NULL) { + if (WINRT_GlobalSDLWindow != NULL) { SDL_SetError("WinRT only supports one window"); return -1; } @@ -202,7 +209,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) /* Make sure the WinRT app's IFramworkView can post events on behalf of SDL: */ - SDL_WinRTGlobalApp->SetSDLWindow(window); + WINRT_GlobalSDLWindow = window; /* All done! */ return 0; @@ -213,8 +220,8 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) { SDL_WindowData * data = (SDL_WindowData *) window->driverdata; - if (SDL_WinRTGlobalApp->GetSDLWindow() == window) { - SDL_WinRTGlobalApp->SetSDLWindow(NULL); + if (WINRT_GlobalSDLWindow == window) { + WINRT_GlobalSDLWindow = NULL; } if (data) { From ed9b57c0524bab86675498a3046510093b9e6bf4 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:13:45 -0400 Subject: [PATCH 182/264] WinRT: moved the WinRT SDL_VideoDevice out of SDL_WinRTApp This was done to help pave the way for XAML support. --- src/core/winrt/SDL_winrtapp.cpp | 15 +++++---------- src/core/winrt/SDL_winrtapp.h | 2 -- src/video/winrt/SDL_winrtvideo.cpp | 11 +++++++++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 2a97fc5fc..df23ca9c2 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -40,6 +40,7 @@ extern "C" { #include "SDL_winrtapp.h" extern SDL_Window * WINRT_GlobalSDLWindow; +extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; // Compile-time debugging options: @@ -145,8 +146,7 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), - m_windowVisible(true), - m_sdlVideoDevice(NULL) + m_windowVisible(true) { } @@ -306,9 +306,9 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // size, and the Direct3D 11.1 renderer wouldn't resize its swap // chain. SDL_DisplayMode resizedDisplayMode = CalcCurrentDisplayMode(); - m_sdlVideoDevice->displays[0].current_mode = resizedDisplayMode; - m_sdlVideoDevice->displays[0].desktop_mode = resizedDisplayMode; - m_sdlVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; // Send the window-resize event to the rest of SDL, and to apps: const int windowWidth = (int) ceil(args->Size.Width); @@ -487,8 +487,3 @@ SDL_DisplayMode SDL_WinRTApp::CalcCurrentDisplayMode() return mode; } - -void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice) -{ - m_sdlVideoDevice = videoDevice; -} diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index a8b5bd343..0b76621f6 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -16,7 +16,6 @@ internal: // SDL-specific methods SDL_DisplayMode CalcCurrentDisplayMode(); void PumpEvents(); - void SetSDLVideoDevice(const SDL_VideoDevice * videoDevice); Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); protected: @@ -40,5 +39,4 @@ protected: private: bool m_windowClosed; bool m_windowVisible; - const SDL_VideoDevice* m_sdlVideoDevice; }; diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 8d2f612df..b2534c6ae 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -79,6 +79,11 @@ struct SDL_WindowData SDL_Window * WINRT_GlobalSDLWindow = NULL; +/* The global, WinRT, video device. +*/ +SDL_VideoDevice * WINRT_GlobalSDLVideoDevice = NULL; + + /* WinRT driver bootstrap functions */ static int @@ -90,7 +95,9 @@ WINRT_Available(void) static void WINRT_DeleteDevice(SDL_VideoDevice * device) { - SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL); + if (device == WINRT_GlobalSDLVideoDevice) { + WINRT_GlobalSDLVideoDevice = NULL; + } SDL_free(device); } @@ -118,7 +125,7 @@ WINRT_CreateDevice(int devindex) device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; device->free = WINRT_DeleteDevice; - SDL_WinRTGlobalApp->SetSDLVideoDevice(device); + WINRT_GlobalSDLVideoDevice = NULL; return device; } From b7ee7b082cd0a1c772a95b9b6b750fc9d0d692cd Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:16:42 -0400 Subject: [PATCH 183/264] WinRT: took out a deprecated TODO-comment --- src/video/winrt/SDL_winrtvideo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index b2534c6ae..4fce058c6 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -139,8 +139,6 @@ VideoBootStrap WINRT_bootstrap = { 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; } From 76880e2b8b707f9d71814fc16a08163dfa12a226 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:20:35 -0400 Subject: [PATCH 184/264] WinRT: more "Windows RT" to "WinRT" renaming --- include/SDL_main.h | 2 +- include/SDL_stdinc.h | 2 +- include/SDL_system.h | 12 +- include/SDL_syswm.h | 2 +- src/audio/xaudio2/SDL_xaudio2.c | 8 +- src/audio/xaudio2/SDL_xaudio2_winrthelpers.h | 34 +- src/core/winrt/SDL_winrtapp.cpp | 4 +- src/video/winrt/SDL_winrtmouse.cpp | 372 +++++++++---------- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 9 files changed, 219 insertions(+), 219 deletions(-) diff --git a/include/SDL_main.h b/include/SDL_main.h index 21fedaaf9..946ead990 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -40,7 +40,7 @@ #define SDL_MAIN_AVAILABLE #elif defined(__WINRT__) -/* On Windows RT, SDL provides a main function that initializes CoreApplication, +/* On WinRT, SDL provides a main function that initializes CoreApplication, creating an instance of IFrameworkView in the process. Please note that #include'ing SDL_main.h is not enough to get a main() diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index bfd6bb8bc..e4a71d35c 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -73,7 +73,7 @@ #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 + WinRT. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx for more information. */ # define _USE_MATH_DEFINES diff --git a/include/SDL_system.h b/include/SDL_system.h index cb7490664..0610dd22e 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -94,11 +94,11 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); #endif /* __ANDROID__ */ -/* Platform specific functions for Windows RT */ +/* Platform specific functions for WinRT */ #if defined(__WINRT__) && __WINRT__ /** - * \brief Windows RT / Windows Phone path types + * \brief WinRT / Windows Phone path types */ typedef enum { @@ -122,9 +122,9 @@ typedef enum /** - * \brief Retrieves a Windows RT defined path on the local file system + * \brief Retrieves a WinRT defined path on the local file system * - * \note Documentation on most app-specific path types on Windows RT + * \note Documentation on most app-specific path types on WinRT * can be found on MSDN, at the URL: * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx * @@ -139,9 +139,9 @@ typedef enum extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); /** - * \brief Retrieves a Windows RT defined path on the local file system + * \brief Retrieves a WinRT defined path on the local file system * - * \note Documentation on most app-specific path types on Windows RT + * \note Documentation on most app-specific path types on WinRT * can be found on MSDN, at the URL: * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx * diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 5fc8fc419..ed8f6a93b 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -177,7 +177,7 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_WINRT) struct { - IUnknown * window; /**< The Windows RT CoreWindow */ + IUnknown * window; /**< The WinRT CoreWindow */ } winrt; #endif #if defined(SDL_VIDEO_DRIVER_X11) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 2816e6c77..08cb9112c 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -22,7 +22,7 @@ /* WinRT NOTICE: A number of changes were warranted to SDL's XAudio2 backend in order to - get it compiling for Windows RT. + get it compiling for WinRT. 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 @@ -57,13 +57,13 @@ 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. + from WinRT. 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. + 3. CoInitialize and CoUninitialize are not available in WinRT. 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^)). (DLudwig: @@ -71,7 +71,7 @@ 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 + argument to a string-based one, 'szDeviceId'. In WinRT, the string-based argument will be used. */ diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h index a72804faa..7c3ba81b1 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h @@ -2,7 +2,7 @@ #pragma once // -// Re-implementation of methods removed from XAudio2 (in Windows RT): +// Re-implementation of methods removed from XAudio2 (in WinRT): // typedef struct XAUDIO2_DEVICE_DETAILS @@ -22,19 +22,19 @@ HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVIC // 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)) +#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)) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index df23ca9c2..28bd8e0b5 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -56,7 +56,7 @@ extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; 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. +// HACK, DLudwig: record a reference to the global, WinRT 'app'/view. // SDL/WinRT will use this throughout its code. // // TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something @@ -129,7 +129,7 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n // 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] + // orientations. According to Microsoft's documentation on WinRT [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. diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index ec32a2ab2..1cbb4af3c 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -1,159 +1,159 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 - -/* - * Windows includes: - */ -#include -using namespace Windows::UI::Core; -using Windows::UI::Core::CoreCursor; - -/* - * SDL includes: - */ -extern "C" { -#include "SDL_assert.h" -#include "../../events/SDL_mouse_c.h" -#include "../SDL_sysvideo.h" -#include "SDL_events.h" -#include "SDL_log.h" -} - -#include "../../core/winrt/SDL_winrtapp.h" -#include "SDL_winrtmouse.h" - - -static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE; - - -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) -{ - WINRT_UseRelativeMouseMode = enabled; - 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) -{ -} - +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +/* + * Windows includes: + */ +#include +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ +extern "C" { +#include "SDL_assert.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_events.h" +#include "SDL_log.h" +} + +#include "../../core/winrt/SDL_winrtapp.h" +#include "SDL_winrtmouse.h" + + +static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE; + + +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) +{ + WINRT_UseRelativeMouseMode = enabled; + return 0; +} + +void +WINRT_InitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + /* DLudwig, Dec 3, 2012: WinRT 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) +{ +} + // Applies necessary geometric transformations to raw cursor positions: static Windows::Foundation::Point TransformCursor(SDL_Window * window, Windows::Foundation::Point rawPosition) @@ -166,8 +166,8 @@ TransformCursor(SDL_Window * window, Windows::Foundation::Point rawPosition) outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); return outputPosition; -} - +} + static inline int _lround(float arg) { @@ -176,15 +176,15 @@ _lround(float arg) } else { return (int)ceil(arg - 0.5f); } -} - -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) -{ - if (!window || !WINRT_UseRelativeMouseMode) { - return; - } - +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UseRelativeMouseMode) { + return; + } + // 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 @@ -228,7 +228,7 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse // // 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 + // however WinRT 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 @@ -249,8 +249,8 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse 1, _lround(mouseDeltaInSDLWindowCoords.X), _lround(mouseDeltaInSDLWindowCoords.Y)); -} - +} + static Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) { @@ -331,10 +331,10 @@ WINRT_LogPointerEvent(const char * header, PointerEventArgs ^ args, Windows::Fou pt->FrameId, pt->PointerId, WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind)); -} - -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +} + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer moved", args, TransformCursor(args->CurrentPoint->Position)); @@ -346,9 +346,9 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEve Windows::Foundation::Point transformedPoint = TransformCursor(window, args->CurrentPoint->Position); SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); -} - -void +} + +void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) { #if LOG_POINTER_EVENTS @@ -362,8 +362,8 @@ WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::Poi // FIXME: This may need to accumulate deltas up to WHEEL_DELTA short motion = args->CurrentPoint->Properties->MouseWheelDelta / WHEEL_DELTA; SDL_SendMouseWheel(window, 0, 0, motion); -} - +} + void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) { #if LOG_POINTER_EVENTS @@ -378,8 +378,8 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::Po if (button) { SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } -} - +} + void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) { #if LOG_POINTER_EVENTS @@ -394,8 +394,8 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::Poi if (button) { SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } -} - -#endif /* SDL_VIDEO_DRIVER_WINRT */ - -/* vi: set ts=4 sw=4 expandtab: */ +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 4fce058c6..55a705928 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -132,7 +132,7 @@ WINRT_CreateDevice(int devindex) #define WINRTVID_DRIVER_NAME "winrt" VideoBootStrap WINRT_bootstrap = { - WINRTVID_DRIVER_NAME, "SDL Windows RT video driver", + WINRTVID_DRIVER_NAME, "SDL WinRT video driver", WINRT_Available, WINRT_CreateDevice }; From 173374030b6c79d58518144efa2679b5605057ab Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:22:02 -0400 Subject: [PATCH 185/264] WinRT: fixed a crash that occurred on device rotation (oops!) --- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 55a705928..756162e5b 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -125,7 +125,7 @@ WINRT_CreateDevice(int devindex) device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; device->free = WINRT_DeleteDevice; - WINRT_GlobalSDLVideoDevice = NULL; + WINRT_GlobalSDLVideoDevice = device; return device; } From 643ea6407e228d7fb2e3f553a7cc71dbe87994e7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:33:36 -0400 Subject: [PATCH 186/264] WinRT: renamed "windowsrt" directories to "winrt" --HG-- rename : src/joystick/windowsrt/SDL_xinputjoystick.c => src/joystick/winrt/SDL_xinputjoystick.c rename : src/main/windowsrt/SDL_winrt_main.cpp => src/main/winrt/SDL_winrt_main.cpp --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 2 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +++--- VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj | 2 +- VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj | 2 +- src/joystick/{windowsrt => winrt}/SDL_xinputjoystick.c | 0 src/main/{windowsrt => winrt}/SDL_winrt_main.cpp | 0 6 files changed, 6 insertions(+), 6 deletions(-) rename src/joystick/{windowsrt => winrt}/SDL_xinputjoystick.c (100%) rename src/main/{windowsrt => winrt}/SDL_winrt_main.cpp (100%) diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 1e8291494..6a3c609f2 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -85,7 +85,7 @@ - + true diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index d28d017d4..5889533ec 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -246,9 +246,6 @@ Source Files - - Source Files - Source Files @@ -270,6 +267,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index 14e57e5fd..9f778532f 100644 --- a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -133,7 +133,7 @@ - + false false diff --git a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index 1940fe315..f0ea0ff9e 100644 --- a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -139,7 +139,7 @@ - + true true true diff --git a/src/joystick/windowsrt/SDL_xinputjoystick.c b/src/joystick/winrt/SDL_xinputjoystick.c similarity index 100% rename from src/joystick/windowsrt/SDL_xinputjoystick.c rename to src/joystick/winrt/SDL_xinputjoystick.c diff --git a/src/main/windowsrt/SDL_winrt_main.cpp b/src/main/winrt/SDL_winrt_main.cpp similarity index 100% rename from src/main/windowsrt/SDL_winrt_main.cpp rename to src/main/winrt/SDL_winrt_main.cpp From e2f7adfd33a33a47a6d292223bccdff2457d65d6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 12:56:49 -0400 Subject: [PATCH 187/264] WinRT: code cleanup wrt. display mode(s) --- src/core/winrt/SDL_winrtapp.cpp | 24 ++---------------------- src/core/winrt/SDL_winrtapp.h | 1 - src/video/winrt/SDL_winrtvideo.cpp | 25 ++++++++++++++++++++++++- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 28bd8e0b5..70937e3a6 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -41,6 +41,7 @@ extern "C" { extern SDL_Window * WINRT_GlobalSDLWindow; extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; +extern SDL_DisplayMode WINRT_CalcDisplayModeUsingNativeWindow(); // Compile-time debugging options: @@ -305,7 +306,7 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven // 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. - SDL_DisplayMode resizedDisplayMode = CalcCurrentDisplayMode(); + SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow(); WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode; WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; @@ -466,24 +467,3 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); } } - -SDL_DisplayMode SDL_WinRTApp::CalcCurrentDisplayMode() -{ - // 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; -} diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index 0b76621f6..5136643ca 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -14,7 +14,6 @@ public: internal: // SDL-specific methods - SDL_DisplayMode CalcCurrentDisplayMode(); void PumpEvents(); Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 756162e5b..fcaca6a98 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -147,10 +147,33 @@ WINRT_VideoInit(_THIS) return 0; } +SDL_DisplayMode +WINRT_CalcDisplayModeUsingNativeWindow() +{ + // 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; +} + + static int WINRT_InitModes(_THIS) { - SDL_DisplayMode mode = SDL_WinRTGlobalApp->CalcCurrentDisplayMode(); + SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow(); if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } From 1cfe2a9412796fd19397bd66451579fc8b44bfdb Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 13:03:43 -0400 Subject: [PATCH 188/264] WinRT: made all WinRT-related TODO comments use the same prefix, "TODO, WinRT" --- src/core/winrt/SDL_winrtapp.cpp | 2 +- src/render/direct3d11/SDL_render_d3d11.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 70937e3a6..ef800f6f4 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -169,7 +169,7 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) // 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. + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback) SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); } diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index fd6e03459..c7d633444 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -247,7 +247,7 @@ D3D11_ReadShaderContents(const wstring & shaderName, vector & out) fileName = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_INSTALLED_LOCATION); fileName += L"\\"; #endif - // WinRT, TODO: test Direct3D 11.1 shader loading on Win32 + // TODO, WinRT: test Direct3D 11.1 shader loading on Win32 fileName += shaderName; return D3D11_ReadFileContents(fileName, out); } @@ -609,7 +609,7 @@ D3D11_ConvertDipsToPixels(float dips) #endif // Initialize all resources that change when the window's size changes. -// WinRT, TODO: get D3D11_CreateWindowSizeDependentResources working on Win32 +// TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32 HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) { @@ -1230,7 +1230,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) 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) + // TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) D3D11_VIEWPORT viewport; memset(&viewport, 0, sizeof(viewport)); From 5248a0701de9965ecb99ba680cb452c30af8a14a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 27 Aug 2013 21:21:09 -0400 Subject: [PATCH 189/264] WinRT: experimental and preliminary support for XAML-based overlays on Windows 8/RT The XAML support here is still rudimentary. Bugs do exist. You've been warned. XAML support in Windows Phone 8 is not yet available (in SDL/WinRT). --- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 8 + .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 3 + include/SDL_system.h | 14 ++ src/core/winrt/SDL_winrtapp.cpp | 8 +- src/core/winrt/SDL_winrtxaml.cpp | 162 ++++++++++++++++++ src/render/direct3d11/SDL_render_d3d11.cpp | 104 ++++++++--- src/video/winrt/SDL_winrtevents.cpp | 98 ++++++++++- src/video/winrt/SDL_winrtevents_c.h | 11 +- src/video/winrt/SDL_winrtmouse.cpp | 25 +-- src/video/winrt/SDL_winrtvideo.cpp | 30 +++- 10 files changed, 415 insertions(+), 48 deletions(-) create mode 100644 src/core/winrt/SDL_winrtxaml.cpp diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 6a3c609f2..d662e6942 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -70,6 +70,14 @@ true true + + true + true + true + true + true + true + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 5889533ec..4d4fee55d 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -270,6 +270,9 @@ Source Files + + Source Files + diff --git a/include/SDL_system.h b/include/SDL_system.h index 0610dd22e..447d5f743 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -155,6 +155,20 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path */ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); +#ifdef __cplusplus_winrt +/** + * \brief Initializes a WinRT and XAML based application. + * + * \param backgroundPanel The XAML background panel to draw onto and receive + * events from. + * \param mainFunction The SDL app's C-style main(). + * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more + * information on the failure. + */ +/* TODO, WinRT: consider making SDL_WinRTInitXAMLApp accept a void pointer to IUnknown, rather than a C++/CX reference */ +extern DECLSPEC int SDLCALL SDL_WinRTInitXAMLApp(Platform::Object^ backgroundPanel, int (*mainFunction)(int, char **)); + +#endif // ifdef __cplusplus_winrt #endif /* __WINRT__ */ diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index ef800f6f4..167489237 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -361,17 +361,17 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args); + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args); + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args); + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) @@ -381,7 +381,7 @@ void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args); + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) diff --git a/src/core/winrt/SDL_winrtxaml.cpp b/src/core/winrt/SDL_winrtxaml.cpp new file mode 100644 index 000000000..811f332d4 --- /dev/null +++ b/src/core/winrt/SDL_winrtxaml.cpp @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/* Windows includes */ +#include +#include + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +#include +#endif + + +/* SDL includes */ +#include "SDL.h" +//#include "SDL_error.h" +//#include "SDL_log.h" +//#include "SDL_main.h" +//#include "SDL_system.h" +#include "../../video/winrt/SDL_winrtevents_c.h" + + +/* External globals: */ +extern SDL_Window * WINRT_GlobalSDLWindow; + + +/* Internal globals: */ +SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; +int (*WINRT_XAMLAppMainFunction)(int, char **) = NULL; + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; +static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; +#endif + + +/* + * Input event handlers (XAML) + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + +static void +WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +static void +WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + +#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP + + +/* + * XAML-to-SDL Rendering Callback + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + +static void +WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args) +{ + WINRT_CycleXAMLThread(); +} + +#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP + + +/* + * SDL + XAML Initialization + */ + +extern "C" int +SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, char **)) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return SDL_SetError("XAML support is not yet available in Windows Phone."); +#else + // Declare C++/CX namespaces: + using namespace Platform; + using namespace Windows::Foundation; + using namespace Windows::UI::Core; + using namespace Windows::UI::Xaml; + using namespace Windows::UI::Xaml::Controls; + using namespace Windows::UI::Xaml::Input; + using namespace Windows::UI::Xaml::Media; + + // Make sure we have a valid XAML element (to draw onto): + if ( ! backgroundPanel) { + return SDL_SetError("'backgroundPanel' can't be NULL"); + } + + SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); + if ( ! swapChainBackgroundPanel) { + return SDL_SetError("An unknown or unsupported type of XAML control was specified."); + } + + // Setup event handlers: + swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML); + swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML); + swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML); + swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML); + + // Setup for rendering: + IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); + panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); + + WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); + + // Make sure the app is ready to call the SDL-centric main() function: + WINRT_XAMLAppMainFunction = mainFunction; + SDL_SetMainReady(); + + // Make sure video-init knows that we're initializing XAML: + SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled; + WINRT_XAMLWasEnabled = SDL_TRUE; + + // Make sure video modes are detected now, while we still have access to the WinRT + // CoreWindow. WinRT will not allow the app's CoreWindow to be accessed via the + // SDL/WinRT thread. + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { + // SDL_InitSubSystem will, on error, set the SDL error. Let that propogate to + // the caller to here: + WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue; + return -1; + } + + // All done, for now. + return 0; +#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else +} diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index c7d633444..cee1edb9c 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -26,6 +26,11 @@ #ifdef __WINRT__ #include #include + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +#include +#endif + #endif extern "C" { @@ -608,6 +613,13 @@ D3D11_ConvertDipsToPixels(float dips) } #endif + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +// TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var +extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative; +#endif + + // Initialize all resources that change when the window's size changes. // TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32 HRESULT @@ -619,15 +631,28 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * 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; + ABI::Windows::Foundation::Rect nativeWindowBounds; + if (coreWindow) { + result = coreWindow->get_Bounds(&nativeWindowBounds); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result); + return result; + } + } else { + // TODO, WinRT, XAML: clean up window-bounds code in D3D11_CreateWindowSizeDependentResources + SDL_DisplayMode displayMode; + if (SDL_GetDesktopDisplayMode(0, &displayMode) < 0) { + SDL_SetError(__FUNCTION__", Get Window Bounds (XAML): Unable to retrieve the native window's size"); + return E_FAIL; + } + + nativeWindowBounds.Width = (FLOAT) displayMode.w; + nativeWindowBounds.Height = (FLOAT) displayMode.h; } - data->windowSizeInDIPs.x = coreWindowBounds.Width; - data->windowSizeInDIPs.y = coreWindowBounds.Height; + // TODO, WinRT, XAML: see if window/control sizes are in DIPs, or something else. If something else, then adjust renderer size tracking accordingly. + data->windowSizeInDIPs.x = nativeWindowBounds.Width; + data->windowSizeInDIPs.y = nativeWindowBounds.Height; // Calculate the necessary swap chain and render target size in pixels. float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x); @@ -660,6 +685,8 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) } else { + const bool usingXAML = (coreWindow == nullptr); + // Otherwise, create a new one using the same adapter as the existing Direct3D device. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = static_cast(data->renderTargetSize.x); // Match the size of the window. @@ -674,7 +701,11 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) 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; + if (usingXAML) { + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + } 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; @@ -703,25 +734,48 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) return result; } - IUnknown * coreWindowAsIUnknown = nullptr; - result = coreWindow->QueryInterface(&coreWindowAsIUnknown); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CoreWindow to IUnknown", result); - return result; - } + if (usingXAML) { + result = dxgiFactory->CreateSwapChainForComposition( + data->d3dDevice.Get(), + &swapChainDesc, + nullptr, + &data->swapChain); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateSwapChainForComposition", 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; +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + result = WINRT_GlobalSwapChainBackgroundPanelNative->SetSwapChain(data->swapChain.Get()); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result); + return result; + } +#else + SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone"); + return E_FAIL; +#endif + } else { + 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); diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index ef1cb690e..10f4137af 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -25,23 +25,117 @@ /* SDL includes */ #include "SDL_winrtevents_c.h" #include "../../core/winrt/SDL_winrtapp.h" +#include "SDL_assert.h" +#include "SDL_system.h" extern "C" { #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" } + +/* Forward declarations and globals */ extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; +extern int (*WINRT_XAMLAppMainFunction)(int, char **); +extern void WINRT_YieldXAMLThread(); -/* General event-management function(s) */ +/* Global event management */ void WINRT_PumpEvents(_THIS) { - SDL_WinRTGlobalApp->PumpEvents(); + if (SDL_WinRTGlobalApp) { + SDL_WinRTGlobalApp->PumpEvents(); + } else if (WINRT_XAMLAppMainFunction) { + WINRT_YieldXAMLThread(); + } } + +/* XAML Thread management */ + +enum SDL_XAMLAppThreadState +{ + ThreadState_NotLaunched = 0, + ThreadState_Running, + ThreadState_Yielding +}; + +static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched; +static SDL_Thread * _XAMLThread = nullptr; +static SDL_mutex * _mutex = nullptr; +static SDL_cond * _cond = nullptr; + +static void +WINRT_YieldXAMLThread() +{ + SDL_LockMutex(_mutex); + SDL_assert(_threadState == ThreadState_Running); + _threadState = ThreadState_Yielding; + SDL_UnlockMutex(_mutex); + + SDL_CondSignal(_cond); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Running) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); +} + +static int +WINRT_XAMLThreadMain(void * userdata) +{ + return WINRT_XAMLAppMainFunction(0, NULL); +} + +void +WINRT_CycleXAMLThread() +{ + switch (_threadState) { + case ThreadState_NotLaunched: + { + _cond = SDL_CreateCond(); + + _mutex = SDL_CreateMutex(); + _threadState = ThreadState_Running; + _XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); + + break; + } + + case ThreadState_Running: + { + SDL_assert(false); + break; + } + + case ThreadState_Yielding: + { + SDL_LockMutex(_mutex); + SDL_assert(_threadState == ThreadState_Yielding); + _threadState = ThreadState_Running; + SDL_UnlockMutex(_mutex); + + SDL_CondSignal(_cond); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); + } + } +} + + #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index 68e746a72..6038a7c9f 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -50,10 +50,13 @@ extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); /* Pointers (Mice, Touch, etc.) */ extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); -extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); -extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); -extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); -extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args); +extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); + +/* XAML Thread Management */ +extern void WINRT_CycleXAMLThread(); #endif diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 1cbb4af3c..841a28cc2 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -110,6 +110,11 @@ WINRT_FreeCursor(SDL_Cursor * cursor) static int WINRT_ShowCursor(SDL_Cursor * cursor) { + // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled. + if ( ! CoreWindow::GetForCurrentThread()) { + return 0; + } + if (cursor) { CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor; @@ -334,25 +339,25 @@ WINRT_LogPointerEvent(const char * header, PointerEventArgs ^ args, Windows::Fou } void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, TransformCursor(args->CurrentPoint->Position)); + WINRT_LogPointerEvent("pointer moved", args, TransformCursor(pointerPoint->Position)); #endif if (!window || WINRT_UseRelativeMouseMode) { return; } - Windows::Foundation::Point transformedPoint = TransformCursor(window, args->CurrentPoint->Position); + Windows::Foundation::Point transformedPoint = TransformCursor(window, pointerPoint->Position); SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); } void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("wheel changed", args, TransformCursor(args->CurrentPoint->Position)); + WINRT_LogPointerEvent("wheel changed", args, TransformCursor(pointerPoint->Position)); #endif if (!window) { @@ -360,11 +365,11 @@ WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Core::Poi } // FIXME: This may need to accumulate deltas up to WHEEL_DELTA - short motion = args->CurrentPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; SDL_SendMouseWheel(window, 0, 0, motion); } -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position)); @@ -374,13 +379,13 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Core::Po return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); if (button) { SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } } -void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::PointerEventArgs ^args) +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position)); @@ -390,7 +395,7 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Core::Poi return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(args->CurrentPoint); + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); if (button) { SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index fcaca6a98..8fecf2cd2 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -47,8 +47,11 @@ extern "C" { #include "../../core/winrt/SDL_winrtapp.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse.h" +#include "SDL_main.h" +#include "SDL_system.h" extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; +extern SDL_bool WINRT_XAMLWasEnabled; /* Initialization/Query functions */ @@ -84,6 +87,7 @@ SDL_Window * WINRT_GlobalSDLWindow = NULL; SDL_VideoDevice * WINRT_GlobalSDLVideoDevice = NULL; + /* WinRT driver bootstrap functions */ static int @@ -154,6 +158,13 @@ WINRT_CalcDisplayModeUsingNativeWindow() SDL_DisplayMode mode; SDL_zero(mode); + // Go no further if a native window cannot be accessed. This can happen, + // for example, if this function is called from certain threads, such as + // the SDL/XAML thread. + if (!CoreWindow::GetForCurrentThread()) { + return 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) @@ -169,11 +180,15 @@ WINRT_CalcDisplayModeUsingNativeWindow() return mode; } - -static int +int WINRT_InitModes(_THIS) { + // Retrieve the display mode: SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow(); + if (mode.w == 0 || mode.h == 0) { + return SDL_SetError("Unable to calculate the WinRT window/display's size"); + } + if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } @@ -211,7 +226,16 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) } window->driverdata = data; data->sdlWindow = window; - data->coreWindow = CoreWindow::GetForCurrentThread(); + + /* To note, when XAML support is enabled, access to the CoreWindow will not + be possible, at least not via the SDL/XAML thread. Attempts to access it + from there will throw exceptions. As such, the SDL_WindowData's + 'coreWindow' field will only be set (to a non-null value) if XAML isn't + enabled. + */ + if (!WINRT_XAMLWasEnabled) { + data->coreWindow = CoreWindow::GetForCurrentThread(); + } /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. From 95b429d98efc89125e9b8119c8187ee742d8eb7b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 11:45:22 -0400 Subject: [PATCH 190/264] WinRT: build fix for Windows Phone --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 6 ++++++ VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 3 +++ 2 files changed, 9 insertions(+) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 1122a94ee..9ed2b0ce7 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -284,6 +284,12 @@ true true + + true + true + true + true + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index fce316fe6..4f6a1b35d 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -593,6 +593,9 @@ Source Files + + Source Files + From 179a4d036775a65c0dcd6803d285fa3e38172208 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 11:46:02 -0400 Subject: [PATCH 191/264] WinRT: fixed a potential memory-related crash in SDL_Renderer on Windows Phone --- src/render/direct3d11/SDL_render_d3d11.cpp | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index cee1edb9c..98b48adab 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1474,16 +1474,16 @@ D3D11_RenderDrawPoints(SDL_Renderer * renderer, b = (float)(renderer->b / 255.0f); a = (float)(renderer->a / 255.0f); - vector 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); + VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, count); + for (int i = 0; i < min(count, 128); ++i) { + const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; + vertices[i] = v; } D3D11_RenderStartDrawOp(renderer); D3D11_RenderSetBlendMode(renderer, renderer->blendMode); - if (D3D11_UpdateVertexBuffer(renderer, &vertices[0], vertices.size() * sizeof(VertexPositionColor)) != 0) { + if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { + SDL_stack_free(vertices); return -1; } @@ -1493,8 +1493,8 @@ D3D11_RenderDrawPoints(SDL_Renderer * renderer, nullptr, nullptr); - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, vertices.size()); - + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count); + SDL_stack_free(vertices); return 0; } @@ -1510,16 +1510,16 @@ D3D11_RenderDrawLines(SDL_Renderer * renderer, b = (float)(renderer->b / 255.0f); a = (float)(renderer->a / 255.0f); - vector vertices; - vertices.reserve(count); + VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, 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); + const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; + vertices[i] = v; } D3D11_RenderStartDrawOp(renderer); D3D11_RenderSetBlendMode(renderer, renderer->blendMode); - if (D3D11_UpdateVertexBuffer(renderer, &vertices[0], vertices.size() * sizeof(VertexPositionColor)) != 0) { + if (D3D11_UpdateVertexBuffer(renderer,&vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { + SDL_stack_free(vertices); return -1; } @@ -1529,8 +1529,8 @@ D3D11_RenderDrawLines(SDL_Renderer * renderer, nullptr, nullptr); - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, vertices.size()); - + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count); + SDL_stack_free(vertices); return 0; } From a5667cf3ba505a0b13c78afd82b6ed752f509d8c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 12:38:30 -0400 Subject: [PATCH 192/264] WinRT: rendering orientation fixes for Windows Phone, part 1 This change should allow apps to render correctly in Portrait mode, at minimum, Support for orientation changes is pending. Thanks to Pierre-Yves for assistance! --- src/render/direct3d11/SDL_render_d3d11.cpp | 71 +++++++++++++--------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 98b48adab..1de471a81 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -662,9 +662,14 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) // landscape-oriented width and height. If the window is in a portrait // orientation, the dimensions must be reversed. data->orientation = DisplayProperties::CurrentOrientation; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + const bool swapDimensions = false; +#else const bool swapDimensions = data->orientation == DisplayOrientations::Portrait || data->orientation == DisplayOrientations::PortraitFlipped; +#endif data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth; data->renderTargetSize.y = swapDimensions ? windowWidth : windowHeight; @@ -785,6 +790,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) } } +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP // 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; @@ -810,7 +816,6 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) 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)) { @@ -1203,41 +1208,47 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) switch (data->orientation) { +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // + // Windows Phone rotations + // 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 - ); + // 90-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); 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 - ); + // 0-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); 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 - ); + // 270-degree (-90 degree) Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); 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 - ); + // 180-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI)); + break; +#else + // + // Non-Windows-Phone rotations (ex: Windows 8, Windows RT) + // + case DisplayOrientations::Landscape: + // 0-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); break; + case DisplayOrientations::Portrait: + // 90-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); + break; + case DisplayOrientations::LandscapeFlipped: + // 180-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI)); + break; + case DisplayOrientations::PortraitFlipped: + // 270-degree (-90 degree) Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); + break; +#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP default: SDL_SetError("An unknown DisplayOrientation is being used"); @@ -1270,9 +1281,13 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // swap buffer's coordinate space, which is always in landscape: // SDL_FRect orientationAlignedViewport; +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + const bool swapDimensions = false; +#else const bool swapDimensions = data->orientation == DisplayOrientations::Portrait || data->orientation == DisplayOrientations::PortraitFlipped; +#endif if (swapDimensions) { orientationAlignedViewport.x = (float) renderer->viewport.y; orientationAlignedViewport.y = (float) renderer->viewport.x; From 591af1b9f8c7d1b4d8fceb27561a719152407767 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 12:45:43 -0400 Subject: [PATCH 193/264] WinRT: removed a comment regarding a dealt-with TODO --- src/render/direct3d11/SDL_render_d3d11.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 1de471a81..44032ddd7 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -793,6 +793,9 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP // Set the proper orientation for the swap chain, and generate the // 3D matrix transformation for rendering to the rotated swap chain. + // + // To note, his operation is not necessary on Windows Phone, nor is it + // even supported there. It's only needed in Windows 8/RT. DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED; switch (data->orientation) { @@ -816,7 +819,6 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) throw ref new Platform::FailureException(); } - // 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); From d5622eb2df4e04706d4ac6197b82b1972e8593d9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 15:27:01 -0400 Subject: [PATCH 194/264] WinRT: made rendering work with orientation changes on Windows Phone Pointer event geometry still needs to be adjusted on Windows Phone, to note. --- src/core/winrt/SDL_winrtapp.cpp | 105 ++++++++++++++++----- src/render/direct3d11/SDL_render_d3d11.cpp | 18 ++-- src/video/winrt/SDL_winrtvideo.cpp | 28 +++++- 3 files changed, 117 insertions(+), 34 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 167489237..de62b410f 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -145,6 +145,77 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags; } +static void +WINRT_ProcessWindowSizeChange() +{ + // Make the new window size be the one true fullscreen mode. + // This change was initially 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. + SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow(); + if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) { + return; + } + + SDL_DisplayMode oldDisplayMode; + SDL_zero(oldDisplayMode); + if (WINRT_GlobalSDLVideoDevice) { + oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode; + WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; + } + + if (WINRT_GlobalSDLWindow) { + // Send a window-resize event to the rest of SDL, and to apps: + SDL_SendWindowEvent( + WINRT_GlobalSDLWindow, + SDL_WINDOWEVENT_RESIZED, + resizedDisplayMode.w, + resizedDisplayMode.h); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // HACK: On Windows Phone, make sure that orientation changes from + // Landscape to LandscapeFlipped, Portrait to PortraitFlipped, + // or vice-versa on either of those two, lead to the Direct3D renderer + // getting updated. + const DisplayOrientations oldOrientation = (DisplayOrientations) (unsigned int) oldDisplayMode.driverdata; + const DisplayOrientations newOrientation = (DisplayOrientations) (unsigned int) resizedDisplayMode.driverdata; + + if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) || + (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) || + (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) || + (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait)) + { + // One of the reasons this event is getting sent out is because SDL + // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events + // if and when the event size doesn't change (and the Direct3D 11.1 + // renderer doesn't get the memo). + // + // Make sure that the display/window size really didn't change. If + // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and + // the Direct3D 11.1 renderer picked it up, presumably. + if (oldDisplayMode.w == resizedDisplayMode.w && + oldDisplayMode.h == resizedDisplayMode.h) + { + SDL_SendWindowEvent( + WINRT_GlobalSDLWindow, + SDL_WINDOWEVENT_SIZE_CHANGED, + resizedDisplayMode.w, + resizedDisplayMode.h); + } + } +#endif + } +} + SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), m_windowVisible(true) @@ -194,6 +265,13 @@ void SDL_WinRTApp::OnOrientationChanged(Object^ sender) (int)DisplayProperties::AutoRotationPreferences); } #endif + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // On Windows Phone, treat an orientation change as a change in window size. + // The native window's size doesn't seem to change, however SDL will simulate + // a window size change. + WINRT_ProcessWindowSizeChange(); +#endif } void SDL_WinRTApp::SetWindow(CoreWindow^ window) @@ -294,32 +372,7 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif - if (WINRT_GlobalSDLWindow) { - // Make the new window size be the one true fullscreen mode. - // This change was initially 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. - SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow(); - WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; - WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode; - WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; - - // 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( - WINRT_GlobalSDLWindow, - SDL_WINDOWEVENT_RESIZED, - windowWidth, - windowHeight); - } + WINRT_ProcessWindowSizeChange(); } void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 44032ddd7..c9e11b5e6 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -920,7 +920,7 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { //D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; - if (event->event == SDL_WINDOWEVENT_RESIZED) { + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { D3D11_UpdateForWindowSizeChange(renderer); } } @@ -1215,16 +1215,16 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // Windows Phone rotations // case DisplayOrientations::Landscape: - // 90-degree Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); + // 270-degree (-90 degree) Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); break; case DisplayOrientations::Portrait: // 0-degree Z-rotation XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); break; case DisplayOrientations::LandscapeFlipped: - // 270-degree (-90 degree) Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); + // 90-degree Z-rotation + XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); break; case DisplayOrientations::PortraitFlipped: // 180-degree Z-rotation @@ -1280,11 +1280,15 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // // Update the Direct3D viewport, which seems to be aligned to the - // swap buffer's coordinate space, which is always in landscape: + // swap buffer's coordinate space, which is always in either + // a landscape mode, for all Windows 8/RT devices, or a portrait mode, + // for Windows Phone devices. // SDL_FRect orientationAlignedViewport; #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - const bool swapDimensions = false; + const bool swapDimensions = + data->orientation == DisplayOrientations::Landscape || + data->orientation == DisplayOrientations::LandscapeFlipped; #else const bool swapDimensions = data->orientation == DisplayOrientations::Portrait || diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 8fecf2cd2..940798bab 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -154,6 +154,8 @@ WINRT_VideoInit(_THIS) SDL_DisplayMode WINRT_CalcDisplayModeUsingNativeWindow() { + using namespace Windows::Graphics::Display; + // Create an empty, zeroed-out display mode: SDL_DisplayMode mode; SDL_zero(mode); @@ -168,7 +170,7 @@ WINRT_CalcDisplayModeUsingNativeWindow() // 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; + mode.driverdata = (void *) DisplayProperties::CurrentOrientation; // Calculate the display size given the window size, taking into account // the current display's DPI: @@ -177,6 +179,30 @@ WINRT_CalcDisplayModeUsingNativeWindow() mode.w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch); mode.h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // On Windows Phone, the native window's size is always in portrait, + // regardless of the device's orientation. This is in contrast to + // Windows 8/RT, which will resize the native window as the device's + // orientation changes. In order to compensate for this behavior, + // on Windows Phone, the mode's width and height will be swapped when + // the device is in a landscape (non-portrait) mode. + switch (DisplayProperties::CurrentOrientation) { + case DisplayOrientations::Landscape: + case DisplayOrientations::LandscapeFlipped: + { + const int tmp = mode.h; + mode.h = mode.w; + mode.w = tmp; + break; + } + + default: + break; + } + + // Attach the mode to te +#endif + return mode; } From 20f836516186927cd5ac3aafbe486b95d4b1783d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 16:14:27 -0400 Subject: [PATCH 195/264] WinRT: made simulated-mouse (via touch) input work on Windows Phone in Portrait mode Proper SDL_MOUSE* event support for non-Portrait orientations in Windows Phone is pending. --- src/core/winrt/SDL_winrtapp.cpp | 40 ++++++++-- src/core/winrt/SDL_winrtapp.h | 1 - src/video/winrt/SDL_winrtevents_c.h | 2 + src/video/winrt/SDL_winrtmouse.cpp | 114 +++++++++++----------------- 4 files changed, 83 insertions(+), 74 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index de62b410f..aecab9a62 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -412,31 +412,61 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) m_windowClosed = true; } +static void +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_GetSDLButtonForPointerPoint(pt)); +} + void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) { WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); } -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) -{ - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { WINRT_ProcessKeyDownEvent(args); diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index 5136643ca..93fd61ade 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -15,7 +15,6 @@ public: internal: // SDL-specific methods void PumpEvents(); - Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition); protected: // Event Handlers. diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index 6038a7c9f..b8f132fd5 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -54,6 +54,8 @@ extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Inpu extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(); diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 841a28cc2..40530bf09 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -160,8 +160,8 @@ WINRT_QuitMouse(_THIS) } // Applies necessary geometric transformations to raw cursor positions: -static Windows::Foundation::Point -TransformCursor(SDL_Window * window, Windows::Foundation::Point rawPosition) +Windows::Foundation::Point +WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) { if (!window) { return rawPosition; @@ -247,7 +247,7 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse // to SDL window coordinates. // const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = TransformCursor(window, mouseDeltaInDIPs); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); SDL_SendMouseMotion( window, 0, @@ -256,11 +256,14 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse _lround(mouseDeltaInSDLWindowCoords.Y)); } -static Uint8 +Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) { using namespace Windows::UI::Input; +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return SDL_BUTTON_LEFT; +#else switch (pt->Properties->PointerUpdateKind) { case PointerUpdateKind::LeftButtonPressed: @@ -286,80 +289,59 @@ WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) default: break; } +#endif return 0; } -static const char * -WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) -{ - using namespace Windows::UI::Input; - - 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 char * header, PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) -{ - Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, PointerUpdateKind=%s\n", - header, - pt->Position.X, pt->Position.Y, - transformedPoint.X, transformedPoint.Y, - pt->Properties->MouseWheelDelta, - pt->FrameId, - pt->PointerId, - WINRT_ConvertPointerUpdateKindToString(args->CurrentPoint->Properties->PointerUpdateKind)); -} +//const char * +//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) +//{ +// using namespace Windows::UI::Input; +// +// 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 ""; +//} void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, TransformCursor(pointerPoint->Position)); -#endif - if (!window || WINRT_UseRelativeMouseMode) { return; } - Windows::Foundation::Point transformedPoint = TransformCursor(window, pointerPoint->Position); + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); } void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("wheel changed", args, TransformCursor(pointerPoint->Position)); -#endif - if (!window) { return; } @@ -371,10 +353,6 @@ WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::Po void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("mouse up", args, TransformCursor(args->CurrentPoint->Position)); -#endif - if (!window) { return; } @@ -387,16 +365,16 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("mouse down", args, TransformCursor(args->CurrentPoint->Position)); -#endif - if (!window) { return; } Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); if (button) { +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); +#endif SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } } From edb51d848516f9247cec2a7ec81cc3c4b1d9c429 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 28 Aug 2013 16:51:07 -0400 Subject: [PATCH 196/264] WinRT: corrected SDL_MOUSE* coordinates in non-Portrait modes Thanks to Pierre-Yves Gueniffey for proper pointer geometry transform code! --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 1 + .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 3 ++ VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 1 + .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 3 ++ src/video/winrt/SDL_winrtmouse.cpp | 44 ++++++++++++++++++- src/video/winrt/SDL_winrtvideo.cpp | 9 +--- src/video/winrt/SDL_winrtvideo_cpp.h | 41 +++++++++++++++++ 7 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 src/video/winrt/SDL_winrtvideo_cpp.h diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 9ed2b0ce7..1db16b019 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -247,6 +247,7 @@ + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 4f6a1b35d..4c726d7a3 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -333,6 +333,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index d662e6942..97286011f 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -294,6 +294,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 4d4fee55d..847d900e0 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -599,6 +599,9 @@ Source Files + + Source Files + diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 40530bf09..fb6f5af72 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -42,6 +42,7 @@ extern "C" { } #include "../../core/winrt/SDL_winrtapp.h" +#include "SDL_winrtvideo_cpp.h" #include "SDL_winrtmouse.h" @@ -163,13 +164,54 @@ WINRT_QuitMouse(_THIS) Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) { + using namespace Windows::Graphics::Display; + if (!window) { return rawPosition; } - CoreWindow ^ nativeWindow = CoreWindow::GetForCurrentThread(); + + SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; + if (windowData->coreWindow == nullptr) { + // For some reason, the window isn't associated with a CoreWindow. + // This might end up being the case as XAML support is extended. + // For now, if there's no CoreWindow attached to the SDL_Window, + // don't do any transforms. + return rawPosition; + } + + // The CoreWindow can only be accessed on certain thread(s). + SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); + + CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); Windows::Foundation::Point outputPosition; + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); +#else + switch (DisplayProperties::CurrentOrientation) + { + case DisplayOrientations::Portrait: + outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::PortraitFlipped: + outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::Landscape: + outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); + outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + break; + case DisplayOrientations::LandscapeFlipped: + outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); + outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + break; + default: + break; + } +#endif + return outputPosition; } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 940798bab..621b2edaa 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -45,6 +45,7 @@ extern "C" { } #include "../../core/winrt/SDL_winrtapp.h" +#include "SDL_winrtvideo_cpp.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse.h" #include "SDL_main.h" @@ -67,14 +68,6 @@ static void WINRT_DestroyWindow(_THIS, SDL_Window * window); static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); -/* Internal window data */ -struct SDL_WindowData -{ - SDL_Window *sdlWindow; - Platform::Agile coreWindow; -}; - - /* The global, WinRT, SDL Window. For now, SDL/WinRT only supports one window (due to platform limitations of WinRT. diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h new file mode 100644 index 000000000..eb4d788fa --- /dev/null +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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. +*/ + +/* Windows includes: */ +#include +#ifdef __cplusplus_winrt +#include +#endif + +/* SDL includes: */ +#include "SDL_events.h" + + +#ifdef __cplusplus_winrt + +/* Internal window data */ +struct SDL_WindowData +{ + SDL_Window *sdlWindow; + Platform::Agile coreWindow; +}; + +#endif // ifdef __cplusplus_winrt From 3230bf956cc34cc14c6ef6322dc0298129f7d8d5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 29 Aug 2013 10:32:16 -0400 Subject: [PATCH 197/264] WinRT: added touch-event support for Windows Phone devices Support for touch events in Windows 8/RT is pending on further R+D. --- src/video/winrt/SDL_winrtmouse.cpp | 69 ++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index fb6f5af72..4b200db32 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -36,6 +36,7 @@ using Windows::UI::Core::CoreCursor; extern "C" { #include "SDL_assert.h" #include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" #include "../SDL_sysvideo.h" #include "SDL_events.h" #include "SDL_log.h" @@ -47,6 +48,8 @@ extern "C" { static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE; +static SDL_TouchID WINRT_TouchID = 1; +static unsigned int WINRT_LeftFingerDown = 0; static SDL_Cursor * @@ -153,6 +156,11 @@ WINRT_InitMouse(_THIS) SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); #endif + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + /* Init touch: */ + SDL_AddTouch(WINRT_TouchID, ""); +#endif } void @@ -378,7 +386,20 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo } Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + } + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // TODO, WinRT: make touch input work with Windows 8/RT, seeing if touches can be distinguished from mouse input. + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); +#endif } void @@ -399,10 +420,25 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; } + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); +#endif } void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) @@ -411,14 +447,29 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (!WINRT_LeftFingerDown) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); #endif - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } + + WINRT_LeftFingerDown = pointerPoint->PointerId; } + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_TRUE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); +#endif } #endif /* SDL_VIDEO_DRIVER_WINRT */ From 0d34ae0804e3a6e5c7dfcb090b78d064e0b6377f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 1 Sep 2013 10:20:17 -0400 Subject: [PATCH 198/264] WinRT: added touch input event support for Windows 8/RT devices --- src/video/winrt/SDL_winrtmouse.cpp | 72 ++++++++++++++++++------------ 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 4b200db32..d639210a5 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -157,10 +157,8 @@ WINRT_InitMouse(_THIS) SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); #endif -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP /* Init touch: */ SDL_AddTouch(WINRT_TouchID, ""); -#endif } void @@ -378,6 +376,23 @@ WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) // return ""; //} +static bool +WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return true; +#else + using namespace Windows::Devices::Input; + switch (pointerPoint->PointerDevice->PointerDeviceType) { + case PointerDeviceType::Touch: + case PointerDeviceType::Pen: + return true; + default: + return false; + } +#endif +} + void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { @@ -391,15 +406,14 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); } -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - // TODO, WinRT: make touch input work with Windows 8/RT, seeing if touches can be distinguished from mouse input. - SDL_SendTouchMotion( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); -#endif + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } } void @@ -430,15 +444,15 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P WINRT_LeftFingerDown = 0; } -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_FALSE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); -#endif + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } } void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) @@ -461,15 +475,15 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po WINRT_LeftFingerDown = pointerPoint->PointerId; } -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_TRUE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); -#endif + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_TRUE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } } #endif /* SDL_VIDEO_DRIVER_WINRT */ From 76c97b1caa31af726134ceefcf47ec6a96735123 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 2 Sep 2013 15:23:33 -0400 Subject: [PATCH 199/264] WinRT: misc code cleanups regarding touch and mouse events, and also SDL-internal globals --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 7 + .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 + VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 9 + .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 + src/core/winrt/SDL_winrtapp.cpp | 5 +- src/core/winrt/SDL_winrtapp.h | 2 + src/core/winrt/SDL_winrtxaml.cpp | 11 +- src/core/winrt/SDL_winrtxaml_cpp.h | 33 ++ src/video/winrt/SDL_winrtevents.cpp | 19 +- src/video/winrt/SDL_winrtevents_c.h | 3 +- src/video/winrt/SDL_winrtmouse.cpp | 329 +--------------- src/video/winrt/SDL_winrtmouse.h | 13 +- src/video/winrt/SDL_winrtpointerinput.cpp | 372 ++++++++++++++++++ src/video/winrt/SDL_winrtvideo.cpp | 15 +- src/video/winrt/SDL_winrtvideo_cpp.h | 13 + 15 files changed, 483 insertions(+), 360 deletions(-) create mode 100644 src/core/winrt/SDL_winrtxaml_cpp.h create mode 100644 src/video/winrt/SDL_winrtpointerinput.cpp diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 1db16b019..231f4afe8 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -198,6 +198,7 @@ + @@ -381,6 +382,12 @@ true true + + true + true + true + true + true true diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 4c726d7a3..0f039415e 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -336,6 +336,9 @@ Source Files + + Source Files + @@ -599,6 +602,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 97286011f..613775e9f 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -176,6 +176,14 @@ true true + + true + true + true + true + true + true + true true @@ -244,6 +252,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 847d900e0..927ce6c73 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -270,6 +270,9 @@ Source Files + + Source Files + Source Files @@ -602,6 +605,9 @@ Source Files + + Source Files + diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index aecab9a62..6b4de54b1 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -37,12 +37,9 @@ extern "C" { } #include "../../video/winrt/SDL_winrtevents_c.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" #include "SDL_winrtapp.h" -extern SDL_Window * WINRT_GlobalSDLWindow; -extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; -extern SDL_DisplayMode WINRT_CalcDisplayModeUsingNativeWindow(); - // Compile-time debugging options: // To enable, uncomment; to disable, comment them out. diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp.h index 93fd61ade..d9cf33e9e 100644 --- a/src/core/winrt/SDL_winrtapp.h +++ b/src/core/winrt/SDL_winrtapp.h @@ -38,3 +38,5 @@ private: bool m_windowClosed; bool m_windowVisible; }; + +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/src/core/winrt/SDL_winrtxaml.cpp b/src/core/winrt/SDL_winrtxaml.cpp index 811f332d4..8b78a1f18 100644 --- a/src/core/winrt/SDL_winrtxaml.cpp +++ b/src/core/winrt/SDL_winrtxaml.cpp @@ -30,18 +30,13 @@ /* SDL includes */ #include "SDL.h" -//#include "SDL_error.h" -//#include "SDL_log.h" -//#include "SDL_main.h" -//#include "SDL_system.h" #include "../../video/winrt/SDL_winrtevents_c.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtxaml_cpp.h" -/* External globals: */ -extern SDL_Window * WINRT_GlobalSDLWindow; - -/* Internal globals: */ +/* SDL-internal globals: */ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; int (*WINRT_XAMLAppMainFunction)(int, char **) = NULL; diff --git a/src/core/winrt/SDL_winrtxaml_cpp.h b/src/core/winrt/SDL_winrtxaml_cpp.h new file mode 100644 index 000000000..e0997becc --- /dev/null +++ b/src/core/winrt/SDL_winrtxaml_cpp.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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_winrtxaml_h +#define _SDL_winrtxaml_h + +#include "SDL_types.h" + +#ifdef __cplusplus +extern SDL_bool WINRT_XAMLWasEnabled; +extern int (*WINRT_XAMLAppMainFunction)(int, char **); +#endif // ifdef __cplusplus + +#endif // ifndef _SDL_winrtxaml_h diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index 10f4137af..94d71590a 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -22,9 +22,19 @@ #if SDL_VIDEO_DRIVER_WINRT -/* SDL includes */ +/* + * Windows includes: + */ +#include +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ #include "SDL_winrtevents_c.h" #include "../../core/winrt/SDL_winrtapp.h" +#include "../../core/winrt/SDL_winrtxaml_cpp.h" #include "SDL_assert.h" #include "SDL_system.h" @@ -34,10 +44,8 @@ extern "C" { } -/* Forward declarations and globals */ -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; -extern int (*WINRT_XAMLAppMainFunction)(int, char **); -extern void WINRT_YieldXAMLThread(); +/* Forward declarations */ +static void WINRT_YieldXAMLThread(); /* Global event management */ @@ -135,7 +143,6 @@ WINRT_CycleXAMLThread() } } - #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index b8f132fd5..4d9ae6d4d 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -32,6 +32,7 @@ extern "C" { extern "C" { #endif +extern void WINRT_InitTouch(_THIS); extern void WINRT_PumpEvents(_THIS); #ifdef __cplusplus @@ -60,6 +61,6 @@ extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * win /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(); -#endif +#endif // ifdef __cplusplus_winrt /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index d639210a5..6f385bab0 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -47,9 +47,7 @@ extern "C" { #include "SDL_winrtmouse.h" -static SDL_bool WINRT_UseRelativeMouseMode = SDL_FALSE; -static SDL_TouchID WINRT_TouchID = 1; -static unsigned int WINRT_LeftFingerDown = 0; +extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; static SDL_Cursor * @@ -131,7 +129,7 @@ WINRT_ShowCursor(SDL_Cursor * cursor) static int WINRT_SetRelativeMouseMode(SDL_bool enabled) { - WINRT_UseRelativeMouseMode = enabled; + WINRT_UsingRelativeMouseMode = enabled; return 0; } @@ -156,9 +154,6 @@ WINRT_InitMouse(_THIS) SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); #endif - - /* Init touch: */ - SDL_AddTouch(WINRT_TouchID, ""); } void @@ -166,326 +161,6 @@ WINRT_QuitMouse(_THIS) { } -// Applies necessary geometric transformations to raw cursor positions: -Windows::Foundation::Point -WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) -{ - using namespace Windows::Graphics::Display; - - if (!window) { - return rawPosition; - } - - SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; - if (windowData->coreWindow == nullptr) { - // For some reason, the window isn't associated with a CoreWindow. - // This might end up being the case as XAML support is extended. - // For now, if there's no CoreWindow attached to the SDL_Window, - // don't do any transforms. - return rawPosition; - } - - // The CoreWindow can only be accessed on certain thread(s). - SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); - - CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); - Windows::Foundation::Point outputPosition; - -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); -#else - switch (DisplayProperties::CurrentOrientation) - { - case DisplayOrientations::Portrait: - outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); - break; - case DisplayOrientations::PortraitFlipped: - outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); - break; - case DisplayOrientations::Landscape: - outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); - outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); - break; - case DisplayOrientations::LandscapeFlipped: - outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); - outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); - break; - default: - break; - } -#endif - - return outputPosition; -} - -static inline int -_lround(float arg) -{ - if (arg >= 0.0f) { - return (int)floor(arg + 0.5f); - } else { - return (int)ceil(arg - 0.5f); - } -} - -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) -{ - if (!window || !WINRT_UseRelativeMouseMode) { - return; - } - - // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); - SDL_SendMouseMotion( - window, - 0, - 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); -} - -Uint8 -WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) -{ - using namespace Windows::UI::Input; - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return SDL_BUTTON_LEFT; -#else - 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; - } -#endif - - return 0; -} - -//const char * -//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) -//{ -// using namespace Windows::UI::Input; -// -// 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 bool -WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) -{ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return true; -#else - using namespace Windows::Devices::Input; - switch (pointerPoint->PointerDevice->PointerDeviceType) { - case PointerDeviceType::Touch: - case PointerDeviceType::Pen: - return true; - default: - return false; - } -#endif -} - -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window || WINRT_UseRelativeMouseMode) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouchMotion( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - -void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - // FIXME: This may need to accumulate deltas up to WHEEL_DELTA - short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; - SDL_SendMouseWheel(window, 0, 0, motion); -} - -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (WINRT_LeftFingerDown == pointerPoint->PointerId) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - } - WINRT_LeftFingerDown = 0; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_FALSE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - -void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (!WINRT_LeftFingerDown) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); -#endif - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); - } - - WINRT_LeftFingerDown = pointerPoint->PointerId; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_TRUE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtmouse.h b/src/video/winrt/SDL_winrtmouse.h index 50bdbe24d..24c6e015e 100644 --- a/src/video/winrt/SDL_winrtmouse.h +++ b/src/video/winrt/SDL_winrtmouse.h @@ -20,11 +20,20 @@ */ #include "SDL_config.h" -#ifndef _SDL_windowsmouse_h -#define _SDL_windowsmouse_h +#ifndef _SDL_winrtmouse_h +#define _SDL_winrtmouse_h + +#ifdef __cplusplus +extern "C" { +#endif extern void WINRT_InitMouse(_THIS); extern void WINRT_QuitMouse(_THIS); +extern SDL_bool WINRT_UsingRelativeMouseMode; + +#ifdef __cplusplus +} +#endif #endif /* _SDL_windowsmouse_h */ diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp new file mode 100644 index 000000000..ee1dc80e5 --- /dev/null +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -0,0 +1,372 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +/* SDL includes */ +#include "SDL_winrtevents_c.h" +#include "SDL_winrtmouse.h" +#include "SDL_winrtvideo_cpp.h" +#include "SDL_assert.h" +#include "SDL_system.h" + +extern "C" { +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +} + +/* File-specific globals: */ +static SDL_TouchID WINRT_TouchID = 1; +static unsigned int WINRT_LeftFingerDown = 0; + + +void +WINRT_InitTouch(_THIS) +{ + SDL_AddTouch(WINRT_TouchID, ""); +} + + +// Applies necessary geometric transformations to raw cursor positions: +Windows::Foundation::Point +WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) +{ + using namespace Windows::UI::Core; + using namespace Windows::Graphics::Display; + + if (!window) { + return rawPosition; + } + + SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; + if (windowData->coreWindow == nullptr) { + // For some reason, the window isn't associated with a CoreWindow. + // This might end up being the case as XAML support is extended. + // For now, if there's no CoreWindow attached to the SDL_Window, + // don't do any transforms. + return rawPosition; + } + + // The CoreWindow can only be accessed on certain thread(s). + SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); + + CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); + Windows::Foundation::Point outputPosition; + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); +#else + switch (DisplayProperties::CurrentOrientation) + { + case DisplayOrientations::Portrait: + outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::PortraitFlipped: + outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); + outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::Landscape: + outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); + outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + break; + case DisplayOrientations::LandscapeFlipped: + outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); + outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + break; + default: + break; + } +#endif + + return outputPosition; +} + +static inline int +_lround(float arg) +{ + if (arg >= 0.0f) { + return (int)floor(arg + 0.5f); + } else { + return (int)ceil(arg - 0.5f); + } +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UsingRelativeMouseMode) { + return; + } + + // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); + SDL_SendMouseMotion( + window, + 0, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); +} + +Uint8 +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +{ + using namespace Windows::UI::Input; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return SDL_BUTTON_LEFT; +#else + 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; + } +#endif + + return 0; +} + +//const char * +//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) +//{ +// using namespace Windows::UI::Input; +// +// 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 bool +WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return true; +#else + using namespace Windows::Devices::Input; + switch (pointerPoint->PointerDevice->PointerDeviceType) { + case PointerDeviceType::Touch: + case PointerDeviceType::Pen: + return true; + default: + return false; + } +#endif +} + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window || WINRT_UsingRelativeMouseMode) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + // FIXME: This may need to accumulate deltas up to WHEEL_DELTA + short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, motion); +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (!WINRT_LeftFingerDown) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); +#endif + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } + + WINRT_LeftFingerDown = pointerPoint->PointerId; + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_TRUE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 621b2edaa..5e5c75e2b 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -45,15 +45,13 @@ extern "C" { } #include "../../core/winrt/SDL_winrtapp.h" +#include "../../core/winrt/SDL_winrtxaml_cpp.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse.h" #include "SDL_main.h" #include "SDL_system.h" -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; -extern SDL_bool WINRT_XAMLWasEnabled; - /* Initialization/Query functions */ static int WINRT_VideoInit(_THIS); @@ -68,19 +66,11 @@ static void WINRT_DestroyWindow(_THIS, SDL_Window * window); static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); -/* The global, WinRT, SDL Window. - For now, SDL/WinRT only supports one window (due to platform limitations of - WinRT. -*/ +/* SDL-internal globals: */ SDL_Window * WINRT_GlobalSDLWindow = NULL; - - -/* The global, WinRT, video device. -*/ SDL_VideoDevice * WINRT_GlobalSDLVideoDevice = NULL; - /* WinRT driver bootstrap functions */ static int @@ -140,6 +130,7 @@ WINRT_VideoInit(_THIS) return -1; } WINRT_InitMouse(_this); + WINRT_InitTouch(_this); return 0; } diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index eb4d788fa..a36cc308d 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -29,6 +29,19 @@ #include "SDL_events.h" +/* The global, WinRT, SDL Window. + For now, SDL/WinRT only supports one window (due to platform limitations of + WinRT. +*/ +extern SDL_Window * WINRT_GlobalSDLWindow; + +/* The global, WinRT, video device. */ +extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; + +/* Computes the current display mode for Plain Direct3D (non-XAML) apps */ +extern SDL_DisplayMode WINRT_CalcDisplayModeUsingNativeWindow(); + + #ifdef __cplusplus_winrt /* Internal window data */ From 12ca6364f9d76a96ae8c3a90fd82b3e2ae59d702 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 2 Sep 2013 15:29:46 -0400 Subject: [PATCH 200/264] WinRT: renamed a mouse-related header file for naming-consistency's sake --HG-- rename : src/video/winrt/SDL_winrtmouse.h => src/video/winrt/SDL_winrtmouse_c.h --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 2 +- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 +++--- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 2 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +++--- src/video/winrt/SDL_winrtmouse.cpp | 2 +- src/video/winrt/{SDL_winrtmouse.h => SDL_winrtmouse_c.h} | 0 src/video/winrt/SDL_winrtpointerinput.cpp | 2 +- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) rename src/video/winrt/{SDL_winrtmouse.h => SDL_winrtmouse_c.h} (100%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 231f4afe8..92d85333d 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -247,7 +247,7 @@ - + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 0f039415e..d02173762 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -330,15 +330,15 @@ Source Files - - Source Files - Source Files Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 613775e9f..73639f543 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -302,7 +302,7 @@ - + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 927ce6c73..6a9166aa5 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -596,9 +596,6 @@ Source Files - - Source Files - Source Files @@ -608,6 +605,9 @@ Source Files + + Source Files + diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 6f385bab0..8f07f4302 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -44,7 +44,7 @@ extern "C" { #include "../../core/winrt/SDL_winrtapp.h" #include "SDL_winrtvideo_cpp.h" -#include "SDL_winrtmouse.h" +#include "SDL_winrtmouse_c.h" extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; diff --git a/src/video/winrt/SDL_winrtmouse.h b/src/video/winrt/SDL_winrtmouse_c.h similarity index 100% rename from src/video/winrt/SDL_winrtmouse.h rename to src/video/winrt/SDL_winrtmouse_c.h diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index ee1dc80e5..ec95b2b64 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -24,7 +24,7 @@ /* SDL includes */ #include "SDL_winrtevents_c.h" -#include "SDL_winrtmouse.h" +#include "SDL_winrtmouse_c.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_assert.h" #include "SDL_system.h" diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 5e5c75e2b..d7de493e7 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -48,7 +48,7 @@ extern "C" { #include "../../core/winrt/SDL_winrtxaml_cpp.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtevents_c.h" -#include "SDL_winrtmouse.h" +#include "SDL_winrtmouse_c.h" #include "SDL_main.h" #include "SDL_system.h" From 4348ee8893a22d32a563a5d0d1bf4a232ed72435 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 4 Sep 2013 19:55:45 -0400 Subject: [PATCH 201/264] WinRT: more renaming of "windowsrt" to "winrt" --HG-- rename : include/SDL_config_windowsrt.h => include/SDL_config_winrt.h --- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj | 2 +- VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters | 6 +++--- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 2 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters | 6 +++--- include/SDL_config.h | 2 +- include/{SDL_config_windowsrt.h => SDL_config_winrt.h} | 0 include/SDL_main.h | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename include/{SDL_config_windowsrt.h => SDL_config_winrt.h} (100%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 92d85333d..59bb72d13 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -150,7 +150,7 @@ - + diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index d02173762..2b5524e9c 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -42,9 +42,6 @@ Header Files - - Header Files - Header Files @@ -339,6 +336,9 @@ Source Files + + Header Files + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 73639f543..2fe031891 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -204,7 +204,7 @@ - + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 6a9166aa5..4c22c3f81 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -410,9 +410,6 @@ Header Files - - Header Files - Header Files @@ -608,6 +605,9 @@ Source Files + + Header Files + diff --git a/include/SDL_config.h b/include/SDL_config.h index 9022af81e..ae69e37bd 100644 --- a/include/SDL_config.h +++ b/include/SDL_config.h @@ -32,7 +32,7 @@ #if defined(__WIN32__) #include "SDL_config_windows.h" #elif defined(__WINRT__) -#include "SDL_config_windowsrt.h" +#include "SDL_config_winrt.h" #elif defined(__MACOSX__) #include "SDL_config_macosx.h" #elif defined(__IPHONEOS__) diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_winrt.h similarity index 100% rename from include/SDL_config_windowsrt.h rename to include/SDL_config_winrt.h diff --git a/include/SDL_main.h b/include/SDL_main.h index 946ead990..876ee341a 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -44,7 +44,7 @@ creating an instance of IFrameworkView in the process. Please note that #include'ing SDL_main.h is not enough to get a main() - function working. The file, src/main/windowsrt/SDL_WinRT_main.cpp, or a copy + function working. The file, src/main/winrt/SDL_WinRT_main.cpp, or a copy of it, must be compiled into the app itself. */ #define SDL_MAIN_NEEDED From 9baaebaa6663ff158a7bff499de4e15bb461fb69 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 4 Sep 2013 20:20:36 -0400 Subject: [PATCH 202/264] WinRT: minor code cleanup in SDL_xaudio2.c --- src/audio/xaudio2/SDL_xaudio2.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 08cb9112c..c540be37f 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -325,7 +325,6 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; #if defined(__WINRT__) - WCHAR devIdBuffer[256]; LPCWSTR devId = 0; #else UINT32 devId = 0; /* 0 == system default device. */ @@ -347,15 +346,12 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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; @@ -367,7 +363,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) ixa2->SetDebugConfiguration(&debugConfig); */ -#if ! defined(__WINRT__) || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#if ! defined(__WINRT__) if (devname != NULL) { UINT32 devcount = 0; UINT32 i = 0; @@ -384,12 +380,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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; } } From 63a6d98f4498d8842393a17cded299d130d8f4a7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 19:07:15 -0400 Subject: [PATCH 203/264] WinRT: made SDL_xaudio2.c compile as C code when building for WinRT XAudio2 2.8's header file, xaudio2.h, doesn't compile in plain C code for WinRT apps, not automatically at least. Initially, this file was adapted to compile as C++, however these changes are now deprecated in favor of some preprocessor based hacks that should get xaudio2.h to compile (while making sure XAudio2 still works). --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 7 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 9 +-- src/audio/xaudio2/SDL_xaudio2.c | 65 +++++++++---------- .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 4 +- src/audio/xaudio2/SDL_xaudio2_winrthelpers.h | 14 +++- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 59bb72d13..474039e85 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -261,12 +261,7 @@ - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - + true true diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 2fe031891..66bdee538 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -37,14 +37,7 @@ - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - + true true diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index c540be37f..0b2eea3ae 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -21,37 +21,7 @@ /* WinRT NOTICE: - A number of changes were warranted to SDL's XAudio2 backend in order to - get it compiling for WinRT. - - 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 + A few 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 @@ -108,14 +78,29 @@ extern "C" { #ifdef SDL_XAUDIO2_HAS_SDK +/* Check to see if we're compiling for XAudio 2.8, or higher. */ +#ifdef WINVER +#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */ +#define SDL_XAUDIO2_2_8 1 +#endif +#endif + +/* The XAudio header file, when #include'd on WinRT, will only compile in C++ + files, but not C. A few preprocessor-based hacks are defined below in order + to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c. + */ +#ifdef __WINRT__ +#define uuid(x) +#define DX_BUILD +#endif + #define INITGUID 1 #include /* Hidden "this" pointer for the audio functions */ #define _THIS SDL_AudioDevice *this -#ifdef __cplusplus -#define this _this +#ifdef __WINRT__ #include "SDL_xaudio2_winrthelpers.h" #endif @@ -273,10 +258,18 @@ XAUDIO2_WaitDone(_THIS) XAUDIO2_VOICE_STATE state; SDL_assert(!this->enabled); /* flag that stops playing. */ IXAudio2SourceVoice_Discontinuity(source); +#if SDL_XAUDIO2_2_8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else IXAudio2SourceVoice_GetState(source, &state); +#endif while (state.BuffersQueued > 0) { SDL_SemWait(this->hidden->semaphore); +#if SDL_XAUDIO2_2_8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else IXAudio2SourceVoice_GetState(source, &state); +#endif } } @@ -447,9 +440,15 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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. */ +#if SDL_XAUDIO2_2_8 + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, + XAUDIO2_DEFAULT_CHANNELS, + this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); +#else result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, this->spec.freq, 0, devId, NULL); +#endif if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create mastering voice"); diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp index aa88fd6c1..9c0fe0ed7 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -8,7 +8,7 @@ using Windows::Devices::Enumeration::DeviceInformation; using Windows::Devices::Enumeration::DeviceInformationCollection; #endif -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) +extern "C" HRESULT __cdecl 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. @@ -29,7 +29,7 @@ HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) #endif } -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details) +extern "C" 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 diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h index 7c3ba81b1..ee5afcd45 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h @@ -14,14 +14,24 @@ typedef struct XAUDIO2_DEVICE_DETAILS */ } XAUDIO2_DEVICE_DETAILS; + +#ifdef __cplusplus +extern "C" { +#endif + HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount); HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details); +#ifdef __cplusplus +} +#endif + // // C-style macros to call XAudio2's methods in C++: // - +#ifdef __cplusplus +/* #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)) @@ -38,3 +48,5 @@ HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVIC #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)) +*/ +#endif // ifdef __cplusplus From f6d0ef462e014512eebe91dfb1b699eec8307671 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 19:23:42 -0400 Subject: [PATCH 204/264] WinRT: removed chunks of C++ hack code from SDL_xaudio2.c --- src/audio/xaudio2/SDL_xaudio2.c | 58 +++++---------------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index 0b2eea3ae..88803e6d9 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -49,17 +49,11 @@ #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 #ifdef __GNUC__ /* The configure script already did any necessary checking */ @@ -81,7 +75,7 @@ extern "C" { /* Check to see if we're compiling for XAudio 2.8, or higher. */ #ifdef WINVER #if WINVER >= 0x0602 /* Windows 8 SDK or higher? */ -#define SDL_XAUDIO2_2_8 1 +#define SDL_XAUDIO2_WIN8 1 #endif #endif @@ -171,33 +165,6 @@ 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) @@ -258,14 +225,14 @@ XAUDIO2_WaitDone(_THIS) XAUDIO2_VOICE_STATE state; SDL_assert(!this->enabled); /* flag that stops playing. */ IXAudio2SourceVoice_Discontinuity(source); -#if SDL_XAUDIO2_2_8 +#if SDL_XAUDIO2_WIN8 IXAudio2SourceVoice_GetState(source, &state, 0); #else IXAudio2SourceVoice_GetState(source, &state); #endif while (state.BuffersQueued > 0) { SDL_SemWait(this->hidden->semaphore); -#if SDL_XAUDIO2_2_8 +#if SDL_XAUDIO2_WIN8 IXAudio2SourceVoice_GetState(source, &state, 0); #else IXAudio2SourceVoice_GetState(source, &state); @@ -317,17 +284,14 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; -#if defined(__WINRT__) - LPCWSTR devId = 0; +#if defined(SDL_XAUDIO2_WIN8) + LPCWSTR devId = NULL; #else UINT32 devId = 0; /* 0 == system default device. */ #endif -#if defined(__cplusplus) - static SDL_XAudio2VoiceCallback callbacks; -#else - static IXAudio2VoiceCallbackVtbl callbacks_vtable = { - VoiceCBOnVoiceProcessPassStart, + static IXAudio2VoiceCallbackVtbl callbacks_vtable = { + VoiceCBOnVoiceProcessPassStart, VoiceCBOnVoiceProcessPassEnd, VoiceCBOnStreamEnd, VoiceCBOnBufferStart, @@ -336,8 +300,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) VoiceCBOnVoiceError }; - static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; -#endif // ! defined(__cplusplus) + static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; if (iscapture) { return SDL_SetError("XAudio2: capture devices unsupported."); @@ -440,7 +403,7 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) 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. */ -#if SDL_XAUDIO2_2_8 +#if SDL_XAUDIO2_WIN8 result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); @@ -557,9 +520,6 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) #endif } -#if defined(__cplusplus) -extern "C" -#endif AudioBootStrap XAUDIO2_bootstrap = { "xaudio2", "XAudio2", XAUDIO2_Init, 0 }; From 38ffd780f4410e3b381e6d919ff48ed17bcc24cd Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 21:00:52 -0400 Subject: [PATCH 205/264] WinRT: minor code cleanup regarding events Some event handling functions got sorted in a somewhat consistent manner, and in some cases, were also segregated a bit from app-lifecycle code. --- src/core/winrt/SDL_winrtapp.cpp | 136 +++++------ src/core/winrt/SDL_winrtxaml.cpp | 12 +- src/video/winrt/SDL_winrtevents_c.h | 18 +- src/video/winrt/SDL_winrtpointerinput.cpp | 271 +++++++++++----------- 4 files changed, 218 insertions(+), 219 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp.cpp index 6b4de54b1..f421ea45e 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp.cpp @@ -299,15 +299,15 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->PointerPressed += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + window->PointerMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + window->PointerReleased += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); window->PointerWheelChanged += ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); - window->PointerMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); - #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP // Retrieves relative-only mouse movements: Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += @@ -409,71 +409,6 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) m_windowClosed = true; } -static void -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) -{ - Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", - header, - pt->Position.X, pt->Position.Y, - transformedPoint.X, transformedPoint.Y, - pt->Properties->MouseWheelDelta, - pt->FrameId, - pt->PointerId, - WINRT_GetSDLButtonForPointerPoint(pt)); -} - -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); -#endif - - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) -{ - WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); -} - -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyDownEvent(args); -} - -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyUpEvent(args); -} - void SDL_WinRTApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) { CoreWindow::GetForCurrentThread()->Activate(); @@ -547,3 +482,68 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); } } + +static void +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_GetSDLButtonForPointerPoint(pt)); +} + +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); +#endif + + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) +{ + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); +} + +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyDownEvent(args); +} + +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyUpEvent(args); +} diff --git a/src/core/winrt/SDL_winrtxaml.cpp b/src/core/winrt/SDL_winrtxaml.cpp index 8b78a1f18..42500c3b5 100644 --- a/src/core/winrt/SDL_winrtxaml.cpp +++ b/src/core/winrt/SDL_winrtxaml.cpp @@ -57,6 +57,12 @@ WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } +static void +WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +} + static void WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) { @@ -69,12 +75,6 @@ WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml:: WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); -} - #endif // WINAPI_FAMILY == WINAPI_FAMILY_APP diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index 4d9ae6d4d..ea09347ae 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -45,19 +45,19 @@ extern void WINRT_PumpEvents(_THIS); */ #ifdef __cplusplus_winrt +/* Pointers (Mice, Touch, etc.) */ +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); +extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); +extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); +extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); + /* Keyboard */ extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); -/* Pointers (Mice, Touch, etc.) */ -extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); -extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); -extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); - /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(); diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index ec95b2b64..962ec3cbd 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -47,7 +47,6 @@ WINRT_InitTouch(_THIS) SDL_AddTouch(WINRT_TouchID, ""); } - // Applies necessary geometric transformations to raw cursor positions: Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) @@ -114,79 +113,6 @@ _lround(float arg) } } -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) -{ - if (!window || !WINRT_UsingRelativeMouseMode) { - return; - } - - // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); - SDL_SendMouseMotion( - window, - 0, - 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); -} - Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) { @@ -276,68 +202,6 @@ WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) #endif } -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window || WINRT_UsingRelativeMouseMode) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouchMotion( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - -void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - // FIXME: This may need to accumulate deltas up to WHEEL_DELTA - short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; - SDL_SendMouseWheel(window, 0, 0, motion); -} - -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - - if (WINRT_LeftFingerDown == pointerPoint->PointerId) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - } - WINRT_LeftFingerDown = 0; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_FALSE, - transformedPoint.X, - transformedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) { if (!window) { @@ -368,5 +232,140 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po pointerPoint->Properties->Pressure); } } + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window || WINRT_UsingRelativeMouseMode) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; + } + + if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + transformedPoint.X, + transformedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + // FIXME: This may need to accumulate deltas up to WHEEL_DELTA + short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, motion); +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UsingRelativeMouseMode) { + return; + } + + // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); + SDL_SendMouseMotion( + window, + 0, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); +} #endif // SDL_VIDEO_DRIVER_WINRT From e0af19f03389de877faab6975f8f608b1050a02e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 21:13:15 -0400 Subject: [PATCH 206/264] WinRT: code cleanup: attempted to make it more clear what code is specific to what app type (plain Direct3D or XAML) --HG-- rename : src/core/winrt/SDL_winrtapp.cpp => src/core/winrt/SDL_winrtapp_direct3d.cpp rename : src/core/winrt/SDL_winrtapp.h => src/core/winrt/SDL_winrtapp_direct3d.h rename : src/core/winrt/SDL_winrtxaml.cpp => src/core/winrt/SDL_winrtapp_xaml.cpp rename : src/core/winrt/SDL_winrtxaml_cpp.h => src/core/winrt/SDL_winrtapp_xaml.h --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 18 +- .../SDL/SDL_VS2012-WinPhone.vcxproj.filters | 22 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 22 +- .../SDL/SDL_VS2012-WinRT.vcxproj.filters | 20 +- ...winrtapp.cpp => SDL_winrtapp_direct3d.cpp} | 2 +- ...SDL_winrtapp.h => SDL_winrtapp_direct3d.h} | 0 ...DL_winrtxaml.cpp => SDL_winrtapp_xaml.cpp} | 36 +-- ...DL_winrtxaml_cpp.h => SDL_winrtapp_xaml.h} | 6 +- src/video/winrt/SDL_winrtevents.cpp | 4 +- src/video/winrt/SDL_winrtmouse.cpp | 2 +- src/video/winrt/SDL_winrtvideo.cpp | 276 +++++++++--------- 11 files changed, 204 insertions(+), 204 deletions(-) rename src/core/winrt/{SDL_winrtapp.cpp => SDL_winrtapp_direct3d.cpp} (97%) rename src/core/winrt/{SDL_winrtapp.h => SDL_winrtapp_direct3d.h} (100%) rename src/core/winrt/{SDL_winrtxaml.cpp => SDL_winrtapp_xaml.cpp} (99%) rename src/core/winrt/{SDL_winrtxaml_cpp.h => SDL_winrtapp_xaml.h} (92%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 474039e85..fce026f16 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -197,8 +197,8 @@ - - + + @@ -269,7 +269,13 @@ true - + + true + true + true + true + + true true true @@ -281,12 +287,6 @@ true true - - true - true - true - true - diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters index 2b5524e9c..9e2d8ee27 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters @@ -321,24 +321,24 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files Header Files + + Source Files + + + Source Files + @@ -581,9 +581,6 @@ Source Files - - Source Files - Source Files @@ -599,10 +596,13 @@ Source Files - + Source Files - + + Source Files + + Source Files diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 66bdee538..c383a2615 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -47,7 +47,15 @@ true - + + true + true + true + true + true + true + + true true true @@ -63,14 +71,6 @@ true true - - true - true - true - true - true - true - @@ -244,8 +244,8 @@ - - + + diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters index 4c22c3f81..fad8ce82b 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters @@ -258,9 +258,6 @@ Source Files - - Source Files - Source Files @@ -273,7 +270,10 @@ Source Files - + + Source Files + + Source Files @@ -593,21 +593,21 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files Header Files + + Source Files + + + Source Files + diff --git a/src/core/winrt/SDL_winrtapp.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp similarity index 97% rename from src/core/winrt/SDL_winrtapp.cpp rename to src/core/winrt/SDL_winrtapp_direct3d.cpp index f421ea45e..7bcd528d7 100644 --- a/src/core/winrt/SDL_winrtapp.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -38,7 +38,7 @@ extern "C" { #include "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" -#include "SDL_winrtapp.h" +#include "SDL_winrtapp_direct3d.h" // Compile-time debugging options: diff --git a/src/core/winrt/SDL_winrtapp.h b/src/core/winrt/SDL_winrtapp_direct3d.h similarity index 100% rename from src/core/winrt/SDL_winrtapp.h rename to src/core/winrt/SDL_winrtapp_direct3d.h diff --git a/src/core/winrt/SDL_winrtxaml.cpp b/src/core/winrt/SDL_winrtapp_xaml.cpp similarity index 99% rename from src/core/winrt/SDL_winrtxaml.cpp rename to src/core/winrt/SDL_winrtapp_xaml.cpp index 42500c3b5..055569377 100644 --- a/src/core/winrt/SDL_winrtxaml.cpp +++ b/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -32,7 +32,7 @@ #include "SDL.h" #include "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" -#include "SDL_winrtxaml_cpp.h" +#include "SDL_winrtapp_xaml.h" @@ -51,28 +51,28 @@ static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; */ #if WINAPI_FAMILY == WINAPI_FAMILY_APP -static void -WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +static void +WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +static void +WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +static void +WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) -{ - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); +static void +WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +{ + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } #endif // WINAPI_FAMILY == WINAPI_FAMILY_APP @@ -128,7 +128,7 @@ SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML); // Setup for rendering: - IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); + IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); diff --git a/src/core/winrt/SDL_winrtxaml_cpp.h b/src/core/winrt/SDL_winrtapp_xaml.h similarity index 92% rename from src/core/winrt/SDL_winrtxaml_cpp.h rename to src/core/winrt/SDL_winrtapp_xaml.h index e0997becc..2beaad807 100644 --- a/src/core/winrt/SDL_winrtxaml_cpp.h +++ b/src/core/winrt/SDL_winrtapp_xaml.h @@ -20,8 +20,8 @@ */ #include "SDL_config.h" -#ifndef _SDL_winrtxaml_h -#define _SDL_winrtxaml_h +#ifndef _SDL_winrtapp_xaml_h +#define _SDL_winrtapp_xaml_h #include "SDL_types.h" @@ -30,4 +30,4 @@ extern SDL_bool WINRT_XAMLWasEnabled; extern int (*WINRT_XAMLAppMainFunction)(int, char **); #endif // ifdef __cplusplus -#endif // ifndef _SDL_winrtxaml_h +#endif // ifndef _SDL_winrtapp_xaml_h diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index 94d71590a..b76617783 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -33,8 +33,8 @@ using Windows::UI::Core::CoreCursor; * SDL includes: */ #include "SDL_winrtevents_c.h" -#include "../../core/winrt/SDL_winrtapp.h" -#include "../../core/winrt/SDL_winrtxaml_cpp.h" +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "../../core/winrt/SDL_winrtapp_xaml.h" #include "SDL_assert.h" #include "SDL_system.h" diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index 8f07f4302..c2605e47f 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -42,7 +42,7 @@ extern "C" { #include "SDL_log.h" } -#include "../../core/winrt/SDL_winrtapp.h" +#include "../../core/winrt/SDL_winrtapp_direct3d.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtmouse_c.h" diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index d7de493e7..2bd444471 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -44,8 +44,8 @@ extern "C" { #include "SDL_syswm.h" } -#include "../../core/winrt/SDL_winrtapp.h" -#include "../../core/winrt/SDL_winrtxaml_cpp.h" +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "../../core/winrt/SDL_winrtapp_xaml.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse_c.h" @@ -61,7 +61,7 @@ static void WINRT_VideoQuit(_THIS); /* Window functions */ -static int WINRT_CreateWindow(_THIS, SDL_Window * window); +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); @@ -131,76 +131,76 @@ WINRT_VideoInit(_THIS) } WINRT_InitMouse(_this); WINRT_InitTouch(_this); - + return 0; } -SDL_DisplayMode -WINRT_CalcDisplayModeUsingNativeWindow() -{ - using namespace Windows::Graphics::Display; - - // Create an empty, zeroed-out display mode: - SDL_DisplayMode mode; - SDL_zero(mode); - - // Go no further if a native window cannot be accessed. This can happen, - // for example, if this function is called from certain threads, such as - // the SDL/XAML thread. - if (!CoreWindow::GetForCurrentThread()) { - return 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 = (void *) DisplayProperties::CurrentOrientation; - - // 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); - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - // On Windows Phone, the native window's size is always in portrait, - // regardless of the device's orientation. This is in contrast to - // Windows 8/RT, which will resize the native window as the device's - // orientation changes. In order to compensate for this behavior, - // on Windows Phone, the mode's width and height will be swapped when - // the device is in a landscape (non-portrait) mode. - switch (DisplayProperties::CurrentOrientation) { - case DisplayOrientations::Landscape: - case DisplayOrientations::LandscapeFlipped: - { - const int tmp = mode.h; - mode.h = mode.w; - mode.w = tmp; - break; - } - - default: - break; - } - - // Attach the mode to te -#endif - - return mode; -} +SDL_DisplayMode +WINRT_CalcDisplayModeUsingNativeWindow() +{ + using namespace Windows::Graphics::Display; + + // Create an empty, zeroed-out display mode: + SDL_DisplayMode mode; + SDL_zero(mode); + + // Go no further if a native window cannot be accessed. This can happen, + // for example, if this function is called from certain threads, such as + // the SDL/XAML thread. + if (!CoreWindow::GetForCurrentThread()) { + return 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 = (void *) DisplayProperties::CurrentOrientation; + + // 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); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // On Windows Phone, the native window's size is always in portrait, + // regardless of the device's orientation. This is in contrast to + // Windows 8/RT, which will resize the native window as the device's + // orientation changes. In order to compensate for this behavior, + // on Windows Phone, the mode's width and height will be swapped when + // the device is in a landscape (non-portrait) mode. + switch (DisplayProperties::CurrentOrientation) { + case DisplayOrientations::Landscape: + case DisplayOrientations::LandscapeFlipped: + { + const int tmp = mode.h; + mode.h = mode.w; + mode.w = tmp; + break; + } + + default: + break; + } + + // Attach the mode to te +#endif + + return mode; +} int WINRT_InitModes(_THIS) { // Retrieve the display mode: - SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow(); - if (mode.w == 0 || mode.h == 0) { - return SDL_SetError("Unable to calculate the WinRT window/display's size"); - } - - if (SDL_AddBasicVideoDisplay(&mode) < 0) { - return -1; + SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow(); + if (mode.w == 0 || mode.h == 0) { + return SDL_SetError("Unable to calculate the WinRT window/display's size"); + } + + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; } SDL_AddDisplayMode(&_this->displays[0], &mode); @@ -219,64 +219,64 @@ 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 (WINRT_GlobalSDLWindow != NULL) { - 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; - - /* To note, when XAML support is enabled, access to the CoreWindow will not - be possible, at least not via the SDL/XAML thread. Attempts to access it - from there will throw exceptions. As such, the SDL_WindowData's - 'coreWindow' field will only be set (to a non-null value) if XAML isn't - enabled. - */ - if (!WINRT_XAMLWasEnabled) { - 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; - - /* WinRT does not, as of this writing, appear to support app-adjustable - window sizes. Set the window size to whatever the native WinRT - CoreWindow is set at. - - TODO, WinRT: if and when non-fullscreen XAML control support is added to SDL, consider making those resizable via SDL_Window's interfaces. - */ - window->w = _this->displays[0].current_mode.w; - window->h = _this->displays[0].current_mode.h; - - /* Make sure the WinRT app's IFramworkView can post events on - behalf of SDL: - */ - WINRT_GlobalSDLWindow = window; - - /* All done! */ - return 0; -} - +int +WINRT_CreateWindow(_THIS, SDL_Window * window) +{ + // Make sure that only one window gets created, at least until multimonitor + // support is added. + if (WINRT_GlobalSDLWindow != NULL) { + 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; + + /* To note, when XAML support is enabled, access to the CoreWindow will not + be possible, at least not via the SDL/XAML thread. Attempts to access it + from there will throw exceptions. As such, the SDL_WindowData's + 'coreWindow' field will only be set (to a non-null value) if XAML isn't + enabled. + */ + if (!WINRT_XAMLWasEnabled) { + 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; + + /* WinRT does not, as of this writing, appear to support app-adjustable + window sizes. Set the window size to whatever the native WinRT + CoreWindow is set at. + + TODO, WinRT: if and when non-fullscreen XAML control support is added to SDL, consider making those resizable via SDL_Window's interfaces. + */ + window->w = _this->displays[0].current_mode.w; + window->h = _this->displays[0].current_mode.h; + + /* Make sure the WinRT app's IFramworkView can post events on + behalf of SDL: + */ + WINRT_GlobalSDLWindow = window; + + /* All done! */ + return 0; +} + void WINRT_DestroyWindow(_THIS, SDL_Window * window) { @@ -293,21 +293,21 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) } } -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_WINRT; - info->info.winrt.window = reinterpret_cast(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; +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_WINRT; + info->info.winrt.window = reinterpret_cast(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 */ From 5d50184a6f71fe885e4476b157db0632c88658b2 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 14 Sep 2013 23:34:27 -0400 Subject: [PATCH 207/264] WinRT: project-naming cleanup. Projects that link to SDL will need updating. To update: 1. remove references to SDL's project files from the Visual Studio Solution. To note, these project files have been renamed, and will show up in Visual Studio with the text, "load failed". 2. add the SDL project files back into the Visual Studio Solution 3. for each project that should link to SDL, add a reference to it. This can be done by right-clicking on it in Visual Studio, selecting "References...", clicking "Add New Reference", checking the box next to the SDL project, then closing each dialog by clicking OK. SDL_mixer, SDL_ttf, and SDL_image for WinRT have been updated, and will be pushed to my Bitbucket repos with these changes having been made. If you do not pull in these changes, be sure to re-add to them the reference to the SDL project, as described above. --HG-- rename : VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj => VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj rename : VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters => VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters rename : VisualC-WinRT/SDL_VS2012-WinRT.sln => VisualC-WinRT/SDL-WinRT_VS2012.sln rename : VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj => VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj rename : VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters => VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters --- ...{SDL_VS2012-WinPhone.vcxproj => SDL-WinPhone_VS2012.vcxproj} | 0 ...hone.vcxproj.filters => SDL-WinPhone_VS2012.vcxproj.filters} | 0 VisualC-WinRT/{SDL_VS2012-WinRT.sln => SDL-WinRT_VS2012.sln} | 0 .../SDL/{SDL_VS2012-WinRT.vcxproj => SDL-WinRT_VS2012.vcxproj} | 0 ...2-WinRT.vcxproj.filters => SDL-WinRT_VS2012.vcxproj.filters} | 0 VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj | 2 +- VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj | 2 +- 7 files changed, 2 insertions(+), 2 deletions(-) rename VisualC-WinPhone/SDL/{SDL_VS2012-WinPhone.vcxproj => SDL-WinPhone_VS2012.vcxproj} (100%) rename VisualC-WinPhone/SDL/{SDL_VS2012-WinPhone.vcxproj.filters => SDL-WinPhone_VS2012.vcxproj.filters} (100%) rename VisualC-WinRT/{SDL_VS2012-WinRT.sln => SDL-WinRT_VS2012.sln} (100%) rename VisualC-WinRT/SDL/{SDL_VS2012-WinRT.vcxproj => SDL-WinRT_VS2012.vcxproj} (100%) rename VisualC-WinRT/SDL/{SDL_VS2012-WinRT.vcxproj.filters => SDL-WinRT_VS2012.vcxproj.filters} (100%) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj similarity index 100% rename from VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj rename to VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters similarity index 100% rename from VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj.filters rename to VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters diff --git a/VisualC-WinRT/SDL_VS2012-WinRT.sln b/VisualC-WinRT/SDL-WinRT_VS2012.sln similarity index 100% rename from VisualC-WinRT/SDL_VS2012-WinRT.sln rename to VisualC-WinRT/SDL-WinRT_VS2012.sln diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj similarity index 100% rename from VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj rename to VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters similarity index 100% rename from VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters rename to VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters diff --git a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index 9f778532f..a74bb13e8 100644 --- a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -147,7 +147,7 @@ - + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} diff --git a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index f0ea0ff9e..f9b5ef0aa 100644 --- a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -150,7 +150,7 @@ - + {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} From 9ac09266a12bacf94b60232adb63eb44272347b5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 14 Sep 2013 23:44:50 -0400 Subject: [PATCH 208/264] WinRT: build fix for the SDL-WinRT-only .sln --- VisualC-WinRT/SDL-WinRT_VS2012.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VisualC-WinRT/SDL-WinRT_VS2012.sln b/VisualC-WinRT/SDL-WinRT_VS2012.sln index 046e6b7ba..921cebd6d 100644 --- a/VisualC-WinRT/SDL-WinRT_VS2012.sln +++ b/VisualC-WinRT/SDL-WinRT_VS2012.sln @@ -1,7 +1,7 @@  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}" +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL-WinRT", "SDL\SDL-WinRT_VS2012.vcxproj", "{AEAEA3A2-D4E6-45B1-8EC6-53D84287FC14}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From cb9cb21fbfdbeac1320b7c6f220764128a0b96e3 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 15 Sep 2013 23:53:51 -0400 Subject: [PATCH 209/264] WinRT: made SDL_winrt_main.cpp not have to be compiled as C++/CX (via the /ZW compiler flag) This file can still be compiled as C++/CX, however that is now optional/not-required. --- src/main/winrt/SDL_winrt_main.cpp | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/winrt/SDL_winrt_main.cpp b/src/main/winrt/SDL_winrt_main.cpp index 9cc046de5..b06def8a7 100644 --- a/src/main/winrt/SDL_winrt_main.cpp +++ b/src/main/winrt/SDL_winrt_main.cpp @@ -1,14 +1,36 @@ -//#include "pch.h" +#include -// The app's C-style main will be passed into SDL.dll as a function -// pointer, and called at the appropriate time. +/* 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^) +/* Prevent MSVC++ from warning about threading models when defining our + custom WinMain. The threading model will instead be set via a direct + call to Windows::Foundation::Initialize (rather than via an attributed + function). + + To note, this warning (C4447) does not seem to come up unless this file + is compiled with C++/CX enabled (via the /ZW compiler flag). +*/ +#ifdef _MSC_VER +#pragma warning(disable:4447) +#endif + +/* Make sure the function to initialize the Windows Runtime gets linked in. */ +#ifdef _MSC_VER +#pragma comment(lib, "runtimeobject.lib") +#endif + +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { - return SDL_WinRT_RunApplication(SDL_main); + if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { + return 1; + } + + SDL_WinRT_RunApplication(SDL_main); + return 0; } From 1dfe43a8b163562bc6f3ee398808c8012caece2c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 16 Sep 2013 00:31:01 -0400 Subject: [PATCH 210/264] WinRT: fixed a line-rendering bug in the D3D 11.1 backend --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index c9e11b5e6..292ecfbba 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1539,7 +1539,7 @@ D3D11_RenderDrawLines(SDL_Renderer * renderer, D3D11_RenderStartDrawOp(renderer); D3D11_RenderSetBlendMode(renderer, renderer->blendMode); - if (D3D11_UpdateVertexBuffer(renderer,&vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { + if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { SDL_stack_free(vertices); return -1; } From 95727847d7b20fbc7ddf25bbf52002ca0b0fae7c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 16 Sep 2013 11:02:18 -0400 Subject: [PATCH 211/264] WinRT: made SDL_GetWindowWMInfo return window data in a slightly easier-to-use format Having the window pointer available as a WinRT IInspectable should make it a bit easier to use in conjunction with WRL-based weak references. --- include/SDL_syswm.h | 4 ++-- src/video/winrt/SDL_winrtvideo.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index ed8f6a93b..df54eca2a 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -57,7 +57,7 @@ struct SDL_SysWMinfo; #endif #if defined(SDL_VIDEO_DRIVER_WINRT) -#include +#include #endif /* This is the structure for custom window manager events */ @@ -177,7 +177,7 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_WINRT) struct { - IUnknown * window; /**< The WinRT CoreWindow */ + IInspectable * window; /**< The WinRT CoreWindow */ } winrt; #endif #if defined(SDL_VIDEO_DRIVER_X11) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 2bd444471..c0b75c0eb 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -300,7 +300,7 @@ WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) if (info->version.major <= SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_WINRT; - info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); + info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); return SDL_TRUE; } else { SDL_SetError("Application not compiled with SDL %d.%d\n", From 96681f346ee2518ed74f6b07d1585988c59d5d47 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 16 Sep 2013 21:09:58 -0400 Subject: [PATCH 212/264] WinRT: reduced the size of SDL_winrt_main.cpp by a little bit --- src/main/winrt/SDL_winrt_main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/winrt/SDL_winrt_main.cpp b/src/main/winrt/SDL_winrt_main.cpp index b06def8a7..81ccfb310 100644 --- a/src/main/winrt/SDL_winrt_main.cpp +++ b/src/main/winrt/SDL_winrt_main.cpp @@ -4,8 +4,7 @@ /* 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 __declspec(dllimport) int SDL_WinRT_RunApplication(int (*)(int, char **)); extern "C" int SDL_main(int, char **); /* Prevent MSVC++ from warning about threading models when defining our From d760825693ef2ea5dda302930701c43d1d62a249 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 16 Sep 2013 22:27:30 -0400 Subject: [PATCH 213/264] WinRT: renamed SDL_winrt_main.cpp to indicate that it should only be used in non-XAML apps This can break builds of existing SDL/WinRT apps. To fix, remove the reference to SDL_winrt_main.cpp, then add a reference to the renamed file, SDL_winrt_main_NonXAML.cpp. If you get a build error about a missing .winmd file, enable the /ZW compiler flag for that one file (at minimum). --HG-- rename : src/main/winrt/SDL_winrt_main.cpp => src/main/winrt/SDL_winrt_main_NonXAML.cpp --- .../tests/loopwave/loopwave_VS2012.vcxproj | 15 ++++++++++++++- .../tests/testthread/testthread_VS2012.vcxproj | 2 +- ..._winrt_main.cpp => SDL_winrt_main_NonXAML.cpp} | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) rename src/main/winrt/{SDL_winrt_main.cpp => SDL_winrt_main_NonXAML.cpp} (91%) diff --git a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj index a74bb13e8..bd1750942 100644 --- a/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj +++ b/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj @@ -110,6 +110,9 @@ NotUsing NotUsing NotUsing + false + false + false @@ -118,6 +121,9 @@ NotUsing NotUsing NotUsing + false + false + false @@ -133,7 +139,14 @@ - + + true + true + true + true + true + true + false false diff --git a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj index f9b5ef0aa..eb2558fa4 100644 --- a/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj +++ b/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj @@ -139,7 +139,7 @@ - + true true true diff --git a/src/main/winrt/SDL_winrt_main.cpp b/src/main/winrt/SDL_winrt_main_NonXAML.cpp similarity index 91% rename from src/main/winrt/SDL_winrt_main.cpp rename to src/main/winrt/SDL_winrt_main_NonXAML.cpp index 81ccfb310..a9956afb0 100644 --- a/src/main/winrt/SDL_winrt_main.cpp +++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -24,7 +24,7 @@ extern "C" int SDL_main(int, char **); #pragma comment(lib, "runtimeobject.lib") #endif -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { return 1; @@ -33,3 +33,4 @@ int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) SDL_WinRT_RunApplication(SDL_main); return 0; } + From 2aa11eef543282a37435f3b121a50bbfc2c03eb3 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 16 Sep 2013 22:43:12 -0400 Subject: [PATCH 214/264] WinRT: ugh, at least one file in an app's project seems to require C++/CX compilation. Assuming this is true, that file might as well be the one that contains WinMain. --- src/main/winrt/SDL_winrt_main_NonXAML.cpp | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/winrt/SDL_winrt_main_NonXAML.cpp b/src/main/winrt/SDL_winrt_main_NonXAML.cpp index a9956afb0..6e61a40c0 100644 --- a/src/main/winrt/SDL_winrt_main_NonXAML.cpp +++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -1,6 +1,33 @@ #include +/* At least one file in any SDL/WinRT app appears to require compilation + with C++/CX, otherwise a Windows Metadata file won't get created, and + an APPX0702 build error can appear shortly after linking. + + The following set of preprocessor code forces this file to be compiled + as C++/CX, which appears to cause Visual C++ 2012's build tools to + create this .winmd file, and will help allow builds of SDL/WinRT apps + to proceed without error. + + If other files in an app's project enable C++/CX compilation, then it might + be possible for SDL_winrt_main_NonXAML.cpp to be compiled without /ZW, + for Visual C++'s build tools to create a winmd file, and for the app to + build without APPX0702 errors. In this case, if + SDL_WINRT_METADATA_FILE_AVAILABLE is defined as a C/C++ macro, then + the #error (to force C++/CX compilation) will be disabled. + + Please note that /ZW can be specified on a file-by-file basis. To do this, + right click on the file in Visual C++, click Properties, then change the + setting through the dialog that comes up. +*/ +#ifndef SDL_WINRT_METADATA_FILE_AVAILABLE +#ifndef __cplusplus_winrt +#error SDL_winrt_main_NonXAML.cpp must be compiled with /ZW, otherwise build errors due to missing .winmd files can occur. +#endif +#endif + + /* The app's C-style main will be passed into SDL.dll as a function pointer, and called at the appropriate time. */ From 79f80241a85778447921215677124377dda0c025 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 22 Sep 2013 12:26:53 -0400 Subject: [PATCH 215/264] WinRT: unified the two, public, app-init functions This function, SDL_WinRTRunApp, can be used to help launch either XAML or non-XAML/Direct3D-only based apps. --- .../SDL/SDL-WinPhone_VS2012.vcxproj | 7 ++++++ .../SDL/SDL-WinPhone_VS2012.vcxproj.filters | 6 +++++ VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 9 +++++++ .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 6 +++++ include/SDL_main.h | 24 +++++++++++++++++-- include/SDL_system.h | 15 ------------ src/core/winrt/SDL_winrtapp_direct3d.cpp | 15 ++++-------- src/core/winrt/SDL_winrtapp_direct3d.h | 4 ++++ src/core/winrt/SDL_winrtapp_xaml.cpp | 13 +++++----- src/core/winrt/SDL_winrtapp_xaml.h | 2 +- src/main/winrt/SDL_winrt_main_NonXAML.cpp | 13 +++------- src/video/winrt/SDL_winrtevents.cpp | 9 +++++-- 12 files changed, 77 insertions(+), 46 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj index fce026f16..501c929c1 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj @@ -197,6 +197,7 @@ + @@ -269,6 +270,12 @@ true + + true + true + true + true + true true diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters index 9e2d8ee27..346e0735d 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters @@ -339,6 +339,9 @@ Source Files + + Source Files + @@ -605,6 +608,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index c383a2615..0be3fc4e0 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -47,6 +47,14 @@ true + + true + true + true + true + true + true + true true @@ -244,6 +252,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index fad8ce82b..ffeb7165f 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -276,6 +276,9 @@ Source Files + + Source Files + @@ -608,6 +611,9 @@ Source Files + + Source Files + diff --git a/include/SDL_main.h b/include/SDL_main.h index 876ee341a..8151b4a1a 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -44,8 +44,10 @@ creating an instance of IFrameworkView in the process. Please note that #include'ing SDL_main.h is not enough to get a main() - function working. The file, src/main/winrt/SDL_WinRT_main.cpp, or a copy - of it, must be compiled into the app itself. + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. */ #define SDL_MAIN_NEEDED @@ -125,6 +127,24 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); #endif /* __WIN32__ */ +#ifdef __WINRT__ + +/** + * \brief Initializes and launches an SDL/WinRT application. + * + * \param mainFunction The SDL app's C-style main(). + * \param xamlBackgroundPanel An optional, XAML-based, background panel. + * For Non-XAML apps, this value must be set to NULL. For XAML apps, + * pass in a pointer to a SwapChainBackgroundPanel, casted to an + * IInspectable (via reinterpret_cast). + * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more + * information on the failure. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel); + +#endif /* __WINRT__ */ + + #ifdef __cplusplus } #endif diff --git a/include/SDL_system.h b/include/SDL_system.h index 447d5f743..056d07fcd 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -155,21 +155,6 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path */ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); -#ifdef __cplusplus_winrt -/** - * \brief Initializes a WinRT and XAML based application. - * - * \param backgroundPanel The XAML background panel to draw onto and receive - * events from. - * \param mainFunction The SDL app's C-style main(). - * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more - * information on the failure. - */ -/* TODO, WinRT: consider making SDL_WinRTInitXAMLApp accept a void pointer to IUnknown, rather than a C++/CX reference */ -extern DECLSPEC int SDLCALL SDL_WinRTInitXAMLApp(Platform::Object^ backgroundPanel, int (*mainFunction)(int, char **)); - -#endif // ifdef __cplusplus_winrt - #endif /* __WINRT__ */ diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 7bcd528d7..a5027fa4e 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -38,6 +38,7 @@ extern "C" { #include "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" #include "SDL_winrtapp_direct3d.h" @@ -48,12 +49,6 @@ extern "C" { //#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, WinRT 'app'/view. // SDL/WinRT will use this throughout its code. // @@ -83,9 +78,9 @@ IFrameworkView^ SDLApplicationSource::CreateView() return app; } -__declspec(dllexport) int SDL_WinRT_RunApplication(SDL_WinRT_MainFunction mainFunction) +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) { - SDL_WinRT_main = mainFunction; + WINRT_SDLAppEntryPoint = mainFunction; auto direct3DApplicationSource = ref new SDLApplicationSource(); CoreApplication::Run(direct3DApplicationSource); return 0; @@ -328,13 +323,13 @@ void SDL_WinRTApp::Load(Platform::String^ entryPoint) void SDL_WinRTApp::Run() { SDL_SetMainReady(); - if (SDL_WinRT_main) + if (WINRT_SDLAppEntryPoint) { // 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); + WINRT_SDLAppEntryPoint(argc, argv); } } diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index d9cf33e9e..837afdca6 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -1,5 +1,9 @@ #pragma once +#include + +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); + ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView { public: diff --git a/src/core/winrt/SDL_winrtapp_xaml.cpp b/src/core/winrt/SDL_winrtapp_xaml.cpp index 055569377..8b8a8ee63 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -32,13 +32,13 @@ #include "SDL.h" #include "../../video/winrt/SDL_winrtevents_c.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" #include "SDL_winrtapp_xaml.h" /* SDL-internal globals: */ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; -int (*WINRT_XAMLAppMainFunction)(int, char **) = NULL; #if WINAPI_FAMILY == WINAPI_FAMILY_APP ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; @@ -96,8 +96,8 @@ WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args * SDL + XAML Initialization */ -extern "C" int -SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, char **)) +int +SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable) { #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP return SDL_SetError("XAML support is not yet available in Windows Phone."); @@ -112,10 +112,11 @@ SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, using namespace Windows::UI::Xaml::Media; // Make sure we have a valid XAML element (to draw onto): - if ( ! backgroundPanel) { - return SDL_SetError("'backgroundPanel' can't be NULL"); + if ( ! backgroundPanelAsIInspectable) { + return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL"); } + Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *) backgroundPanelAsIInspectable); SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); if ( ! swapChainBackgroundPanel) { return SDL_SetError("An unknown or unsupported type of XAML control was specified."); @@ -134,7 +135,7 @@ SDL_WinRTInitXAMLApp(Platform::Object ^backgroundPanel, int (*mainFunction)(int, WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); // Make sure the app is ready to call the SDL-centric main() function: - WINRT_XAMLAppMainFunction = mainFunction; + WINRT_SDLAppEntryPoint = mainFunction; SDL_SetMainReady(); // Make sure video-init knows that we're initializing XAML: diff --git a/src/core/winrt/SDL_winrtapp_xaml.h b/src/core/winrt/SDL_winrtapp_xaml.h index 2beaad807..875b768aa 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.h +++ b/src/core/winrt/SDL_winrtapp_xaml.h @@ -27,7 +27,7 @@ #ifdef __cplusplus extern SDL_bool WINRT_XAMLWasEnabled; -extern int (*WINRT_XAMLAppMainFunction)(int, char **); +extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable); #endif // ifdef __cplusplus #endif // ifndef _SDL_winrtapp_xaml_h diff --git a/src/main/winrt/SDL_winrt_main_NonXAML.cpp b/src/main/winrt/SDL_winrt_main_NonXAML.cpp index 6e61a40c0..19eb7b919 100644 --- a/src/main/winrt/SDL_winrt_main_NonXAML.cpp +++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -1,4 +1,5 @@ +#include #include /* At least one file in any SDL/WinRT app appears to require compilation @@ -27,13 +28,6 @@ #endif #endif - -/* The app's C-style main will be passed into SDL.dll as a function - pointer, and called at the appropriate time. -*/ -extern __declspec(dllimport) int SDL_WinRT_RunApplication(int (*)(int, char **)); -extern "C" int SDL_main(int, char **); - /* Prevent MSVC++ from warning about threading models when defining our custom WinMain. The threading model will instead be set via a direct call to Windows::Foundation::Initialize (rather than via an attributed @@ -51,13 +45,12 @@ extern "C" int SDL_main(int, char **); #pragma comment(lib, "runtimeobject.lib") #endif -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { return 1; } - SDL_WinRT_RunApplication(SDL_main); + SDL_WinRTRunApp(SDL_main, NULL); return 0; } - diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index b76617783..021ad406c 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -33,6 +33,7 @@ using Windows::UI::Core::CoreCursor; * SDL includes: */ #include "SDL_winrtevents_c.h" +#include "../../core/winrt/SDL_winrtapp_common.h" #include "../../core/winrt/SDL_winrtapp_direct3d.h" #include "../../core/winrt/SDL_winrtapp_xaml.h" #include "SDL_assert.h" @@ -55,7 +56,7 @@ WINRT_PumpEvents(_THIS) { if (SDL_WinRTGlobalApp) { SDL_WinRTGlobalApp->PumpEvents(); - } else if (WINRT_XAMLAppMainFunction) { + } else if (WINRT_XAMLWasEnabled) { WINRT_YieldXAMLThread(); } } @@ -95,7 +96,11 @@ WINRT_YieldXAMLThread() static int WINRT_XAMLThreadMain(void * userdata) { - return WINRT_XAMLAppMainFunction(0, NULL); + // TODO, WinRT: pass the C-style main() a reasonably realistic + // representation of command line arguments. + int argc = 0; + char **argv = NULL; + return WINRT_SDLAppEntryPoint(argc, argv); } void From 97a9be160886651a084bdf3912e793c565d7ba6c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 22 Sep 2013 23:17:25 -0400 Subject: [PATCH 216/264] WinRT: added missing files --- src/core/winrt/SDL_winrtapp_common.cpp | 16 +++++++++++++ src/core/winrt/SDL_winrtapp_common.h | 31 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/core/winrt/SDL_winrtapp_common.cpp create mode 100644 src/core/winrt/SDL_winrtapp_common.h diff --git a/src/core/winrt/SDL_winrtapp_common.cpp b/src/core/winrt/SDL_winrtapp_common.cpp new file mode 100644 index 000000000..6699e6811 --- /dev/null +++ b/src/core/winrt/SDL_winrtapp_common.cpp @@ -0,0 +1,16 @@ + +#include +#include "SDL_winrtapp_direct3d.h" +#include "SDL_winrtapp_xaml.h" + +int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; + +extern "C" DECLSPEC int +SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel) +{ + if (xamlBackgroundPanel) { + return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); + } else { + return SDL_WinRTInitNonXAMLApp(mainFunction); + } +} diff --git a/src/core/winrt/SDL_winrtapp_common.h b/src/core/winrt/SDL_winrtapp_common.h new file mode 100644 index 000000000..503a785aa --- /dev/null +++ b/src/core/winrt/SDL_winrtapp_common.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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_winrtapp_common_h +#define _SDL_winrtapp_common_h + +/* A pointer to the app's C-style main() function (which is a different + function than the WinRT app's actual entry point). + */ +extern int (*WINRT_SDLAppEntryPoint)(int, char **); + +#endif // ifndef _SDL_winrtapp_common_h From 69cd08bc138b6f36743ea9c653d1a9e4b8205269 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 25 Oct 2013 20:31:43 -0400 Subject: [PATCH 217/264] WinRT: made the Direct3D 11.x 'Debug Layer' be enable-able in any app via a hint To enable the Debug Layer, set the hint, SDL_HINT_RENDER_DIRECT3D11_DEBUG to '1'. The Debug Layer will be turned off by default, both in Release and Debug builds (of SDL). --- include/SDL_hints.h | 14 ++++++++++++++ src/render/direct3d11/SDL_render_d3d11.cpp | 13 ++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 74b63ee09..6e2a78568 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -117,6 +117,20 @@ extern "C" { */ #define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer, + * which is used in Win32-based (aka Windows Desktop) apps. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Lyaer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_HINT_RENDER_DIRECT3D11_DEBUG" + /** * \brief A variable controlling whether the X11 VidMode extension should be used. * diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 292ecfbba..eaae09e7b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -35,7 +35,7 @@ extern "C" { #include "../../core/windows/SDL_windows.h" -//#include "SDL_hints.h" +#include "SDL_hints.h" //#include "SDL_loadso.h" #include "SDL_system.h" #include "SDL_syswm.h" @@ -326,10 +326,13 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // 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 + // Make sure Direct3D's debugging feature gets used, if the app requests it. + const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); + if (hint) { + if (*hint == '1') { + creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + } + } // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. From b35781fdb34305ea1da597696b6ac9012c36ef32 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 27 Oct 2013 14:31:57 -0400 Subject: [PATCH 218/264] WinRT: fixed two bugs regarding mouse events The first bug had mouse motion events not getting sent out on non-touch devices, if and when a mouse button wasn't pressed. The second bug caused virtual mouse motion events to get sent out-of-order on touch devices: the motion event would get sent after the touch occurred, rather than before. --- src/video/winrt/SDL_winrtpointerinput.cpp | 48 ++++++++++++----------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index 962ec3cbd..9e64138a5 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -209,20 +209,20 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po } Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (!WINRT_LeftFingerDown) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); -#endif - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + if (!WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } else { + if (!WINRT_LeftFingerDown) { + if (button) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } + + WINRT_LeftFingerDown = pointerPoint->PointerId; } - WINRT_LeftFingerDown = pointerPoint->PointerId; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { SDL_SendTouch( WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, @@ -242,11 +242,13 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); - if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + if (!WINRT_IsTouchEvent(pointerPoint)) { SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); - } + } else if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + } - if (WINRT_IsTouchEvent(pointerPoint)) { SDL_SendTouchMotion( WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, @@ -263,16 +265,18 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P } Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (WINRT_LeftFingerDown == pointerPoint->PointerId) { - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + if (!WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } else { + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; } - WINRT_LeftFingerDown = 0; - } - - if (WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendTouch( WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, From 3f62c9892a04edca1a93e7939e9fc5fc1cd25766 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 27 Oct 2013 23:03:11 -0400 Subject: [PATCH 219/264] WinRT: build fixes, post SDL 2.0.1 update --- src/SDL_log.c | 2 +- src/atomic/SDL_spinlock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL_log.c b/src/SDL_log.c index 4ad5c4273..bc9f954fb 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -20,7 +20,7 @@ */ #include "SDL_config.h" -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__WINRT__) #include "core/windows/SDL_windows.h" #endif diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index ac9b61e87..ac78729c7 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -20,7 +20,7 @@ */ #include "SDL_config.h" -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINRT__) #include "../core/windows/SDL_windows.h" #endif From f810dc252435d997862d3d78e1b93fad4fdd9f65 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 27 Oct 2013 23:19:35 -0400 Subject: [PATCH 220/264] WinRT: spelling fix in SDL_hints.h --- include/SDL_hints.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index d195d9662..42026d0fc 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -136,7 +136,7 @@ extern "C" { * * This variable can be set to the following values: * "0" - Disable Debug Layer use - * "1" - Enable Debug Lyaer use + * "1" - Enable Debug Layer use * * By default, SDL does not use Direct3D Debug Layer. */ From e918745db0309410ccc3985030f812dd366d306d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 28 Oct 2013 15:41:22 -0400 Subject: [PATCH 221/264] WinRT: implemented SDL_GetBasePath and SDL_GetPrefPath --HG-- rename : src/core/winrt/SDL_winrtpaths.cpp => src/filesystem/winrt/SDL_sysfilesystem.cpp --- .../SDL/SDL-WinPhone_VS2012.vcxproj | 13 +++-- .../SDL/SDL-WinPhone_VS2012.vcxproj.filters | 9 ++- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 17 +++--- .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 9 ++- .../winrt/SDL_sysfilesystem.cpp} | 58 ++++++++++++++++++- 5 files changed, 84 insertions(+), 22 deletions(-) rename src/{core/winrt/SDL_winrtpaths.cpp => filesystem/winrt/SDL_sysfilesystem.cpp} (54%) diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj index 501c929c1..882fe3b6c 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj @@ -156,6 +156,7 @@ + @@ -288,12 +289,6 @@ true true - - true - true - true - true - @@ -304,6 +299,12 @@ + + true + true + true + true + diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters index 346e0735d..f99bb9488 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters @@ -342,6 +342,9 @@ Source Files + + Header Files + @@ -584,9 +587,6 @@ Source Files - - Source Files - Source Files @@ -611,6 +611,9 @@ Source Files + + Source Files + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index 0be3fc4e0..e50293e24 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -71,14 +71,6 @@ true true - - true - true - true - true - true - true - @@ -89,6 +81,14 @@ + + true + true + true + true + true + true + @@ -211,6 +211,7 @@ + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index ffeb7165f..8a7f94d53 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -258,9 +258,6 @@ Source Files - - Source Files - Source Files @@ -279,6 +276,9 @@ Source Files + + Source Files + @@ -614,6 +614,9 @@ Source Files + + Header Files + diff --git a/src/core/winrt/SDL_winrtpaths.cpp b/src/filesystem/winrt/SDL_sysfilesystem.cpp similarity index 54% rename from src/core/winrt/SDL_winrtpaths.cpp rename to src/filesystem/winrt/SDL_sysfilesystem.cpp index 4c10b78b7..c70113200 100644 --- a/src/core/winrt/SDL_winrtpaths.cpp +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -1,5 +1,5 @@ /* 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 + TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all */ #include "SDL_config.h" @@ -7,10 +7,11 @@ #ifdef __WINRT__ extern "C" { +#include "SDL_filesystem.h" #include "SDL_error.h" #include "SDL_stdinc.h" #include "SDL_system.h" -#include "../windows/SDL_windows.h" +#include "../../core/windows/SDL_windows.h" } #include @@ -91,4 +92,57 @@ SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType) return utf8Paths[pathType].c_str(); } +extern "C" char * +SDL_GetBasePath(void) +{ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION); + size_t destPathLen; + char * destPath = NULL; + + if (!srcPath) { + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); + return NULL; + } + + destPathLen = SDL_strlen(srcPath) + 2; + destPath = (char *) SDL_malloc(destPathLen); + if (!destPath) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(destPath, destPathLen, "%s\\", srcPath); + return destPath; +} + +extern "C" char * +SDL_GetPrefPath(const char *org, const char *app) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER); +#else + /* A 'Roaming' folder is available on Windows 8 and 8.1. Use that. */ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_ROAMING_FOLDER); +#endif + + size_t destPathLen; + char * destPath = NULL; + + if (!srcPath) { + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); + return NULL; + } + + destPathLen = SDL_strlen(srcPath) + SDL_strlen(org) + SDL_strlen(app) + 4; + destPath = (char *) SDL_malloc(destPathLen); + if (!destPath) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(destPath, destPathLen, "%s\\%s\\%s\\", srcPath, org, app); + return destPath; +} + #endif /* __WINRT__ */ From f6e52c362ad3756e108dd5e887f88cb2b8decfc9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 28 Oct 2013 15:52:04 -0400 Subject: [PATCH 222/264] WinRT: added a comment regarding the lack of SHGetFolderPath on WinRT --- src/filesystem/winrt/SDL_sysfilesystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/filesystem/winrt/SDL_sysfilesystem.cpp b/src/filesystem/winrt/SDL_sysfilesystem.cpp index c70113200..2e9f7e710 100644 --- a/src/filesystem/winrt/SDL_sysfilesystem.cpp +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -118,6 +118,12 @@ SDL_GetBasePath(void) extern "C" char * SDL_GetPrefPath(const char *org, const char *app) { + /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and + * earlier is not available on WinRT or Windows Phone. WinRT provides + * a similar API, but SHGetFolderPath can't be called, at least not + * without violating Microsoft's app-store requirements. + */ + #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */ const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER); From 23f6ff5673baa7530f37370880e39c654c36f54b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 1 Nov 2013 22:54:39 -0400 Subject: [PATCH 223/264] WinRT: added support for SDL_HINT_RENDER_SCALE_QUALITY --- src/render/direct3d11/SDL_render_d3d11.cpp | 54 ++++++++++++++++++-- src/render/direct3d11/SDL_render_d3d11_cpp.h | 4 +- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index eaae09e7b..2c2d49a9c 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -60,6 +60,10 @@ using namespace Windows::Graphics::Display; using namespace Windows::UI::Core; #endif +/* Texture sampling types */ +static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_MIP_POINT; +static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + /* Direct3D 11.1 renderer implementation */ static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags); @@ -487,10 +491,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) data->vertexBuffer = nullptr; // - // Create a sampler to use when drawing textures: + // Create samplers to use when drawing textures: // D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.Filter = SDL_D3D11_NEAREST_PIXEL_FILTER; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; @@ -505,7 +509,17 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = data->d3dDevice->CreateSamplerState( &samplerDesc, - &data->mainSampler + &data->nearestPixelSampler + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return result; + } + + samplerDesc.Filter = SDL_D3D11_LINEAR_FILTER; + result = data->d3dDevice->CreateSamplerState( + &samplerDesc, + &data->linearSampler ); if (FAILED(result)) { WIN_SetErrorFromHRESULT(__FUNCTION__, result); @@ -928,6 +942,17 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } +static D3D11_FILTER +GetScaleQuality(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); + if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) { + return SDL_D3D11_NEAREST_PIXEL_FILTER; + } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ { + return SDL_D3D11_LINEAR_FILTER; + } +} + static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { @@ -948,6 +973,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } textureData->pixelFormat = SDL_AllocFormat(texture->format); textureData->lockedTexturePosition = XMINT2(0, 0); + textureData->scaleMode = GetScaleQuality(); texture->driverdata = textureData; @@ -1621,6 +1647,22 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, return 0; } +static ID3D11SamplerState * +D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + + switch (textureData->scaleMode) { + case SDL_D3D11_NEAREST_PIXEL_FILTER: + return rendererData->nearestPixelSampler.Get(); + case SDL_D3D11_LINEAR_FILTER: + return rendererData->linearSampler.Get(); + default: + return NULL; + } +} + static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) @@ -1659,11 +1701,12 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } + ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); D3D11_SetPixelShader( renderer, rendererData->texturePixelShader.Get(), textureData->mainTextureResourceView.Get(), - rendererData->mainSampler.Get()); + textureSampler); D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); @@ -1733,11 +1776,12 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } + ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); D3D11_SetPixelShader( renderer, rendererData->texturePixelShader.Get(), textureData->mainTextureResourceView.Get(), - rendererData->mainSampler.Get()); + textureSampler); D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h index 14fc61270..6c8584683 100644 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ b/src/render/direct3d11/SDL_render_d3d11_cpp.h @@ -47,7 +47,8 @@ typedef struct Microsoft::WRL::ComPtr blendModeBlend; Microsoft::WRL::ComPtr blendModeAdd; Microsoft::WRL::ComPtr blendModeMod; - Microsoft::WRL::ComPtr mainSampler; + Microsoft::WRL::ComPtr nearestPixelSampler; + Microsoft::WRL::ComPtr linearSampler; Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; @@ -72,6 +73,7 @@ typedef struct SDL_PixelFormat * pixelFormat; Microsoft::WRL::ComPtr stagingTexture; DirectX::XMINT2 lockedTexturePosition; + D3D11_FILTER scaleMode; } D3D11_TextureData; struct VertexPositionColor From a5069b7ae168ca6dc7c1f03b8de00f4a785695f9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 4 Nov 2013 19:54:29 -0500 Subject: [PATCH 224/264] WinRT: added experimental OpenGL ES 2.0 support A port of the ANGLE library (OpenGL ES 2.0 for Direct3D) to WinRT, via https://github.com/stammen/angleproject, is used as a base. To enable, clone 'angleproject' into the directory one above where SDL/WinRT is, open the file SDL/include/SDL_config_winrt.h, and uncomment the #defines that begin with 'SDL_VIDEO_OPENGL'. From there, apps can create an OpenGL capable SDL_Window via the flag, SDL_WINDOW_OPENGL, and an OpenGL ES 2 context via SDL_GL_CreateContext. The Direct3D 11.1 renderer cannot be used alongside SDL_WINDOW_OPENGL. Only Windows 8/8.1 is supported for now. Shaders may need to be precompiled, in some (all?) cases. --- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 25 ++- .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 18 ++ include/SDL_config_winrt.h | 9 + include/SDL_opengles2.h | 2 + src/video/SDL_egl.c | 16 ++ src/video/SDL_egl.h | 70 +++++--- src/video/SDL_video.c | 2 +- src/video/winrt/SDL_winrtegl.h | 166 ++++++++++++++++++ src/video/winrt/SDL_winrtopengles.cpp | 55 ++++++ src/video/winrt/SDL_winrtopengles.h | 48 +++++ src/video/winrt/SDL_winrtvideo.cpp | 34 ++++ src/video/winrt/SDL_winrtvideo_cpp.h | 9 + 12 files changed, 419 insertions(+), 35 deletions(-) create mode 100644 src/video/winrt/SDL_winrtegl.h create mode 100644 src/video/winrt/SDL_winrtopengles.cpp create mode 100644 src/video/winrt/SDL_winrtopengles.h diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index e50293e24..a7ffb4d5f 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -145,6 +145,7 @@ + @@ -177,6 +178,14 @@ true true + + true + true + true + true + true + true + true true @@ -224,6 +233,7 @@ + @@ -299,13 +309,16 @@ + + + @@ -448,7 +461,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -462,7 +475,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -476,7 +489,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -490,7 +503,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -504,7 +517,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -518,7 +531,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index 8a7f94d53..82cbcb344 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -279,6 +279,12 @@ Source Files + + Source Files + + + Source Files + @@ -617,6 +623,18 @@ Header Files + + Source Files + + + Source Files + + + Source Files + + + Header Files + diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 712a9149f..210d1e660 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -166,6 +166,15 @@ typedef unsigned int uintptr_t; #define SDL_VIDEO_DRIVER_WINRT 1 #define SDL_VIDEO_DRIVER_DUMMY 1 +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */ +/* Uncomment the following two #defines to enable experimental OpenGL ES 2 support + (via a WinRT port of the ANGLE library). +*/ +//#define SDL_VIDEO_OPENGL_ES2 1 +//#define SDL_VIDEO_OPENGL_EGL 1 +#endif + // TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. /* Enable appropriate renderer(s) */ #define SDL_VIDEO_RENDER_D3D11 1 diff --git a/include/SDL_opengles2.h b/include/SDL_opengles2.h index 7697626f4..d090c8db7 100644 --- a/include/SDL_opengles2.h +++ b/include/SDL_opengles2.h @@ -33,6 +33,8 @@ #include #endif +#ifndef __WINRT__ #ifndef APIENTRY #define APIENTRY #endif +#endif diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index ccfb92e18..6d4130bd4 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -40,6 +40,13 @@ #define DEFAULT_OGL_ES_PVR "libGLES_CM.so" #define DEFAULT_OGL_ES "libGLESv1_CM.so" +#elif SDL_VIDEO_DRIVER_WINRT +/* WinRT (via a modified version of Google's ANGLE library) */ +#define DEFAULT_EGL "libEGL.dll" +#define DEFAULT_OGL_ES2 "libGLESv2.dll" +#define DEFAULT_OGL_ES_PVR NULL +#define DEFAULT_OGL_ES NULL + #else /* Desktop Linux */ #define DEFAULT_EGL "libEGL.so.1" @@ -134,8 +141,13 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa #endif /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ +#ifdef __WINRT__ + path = NULL; + egl_dll_handle = NULL; +#else path = getenv("SDL_VIDEO_GL_DRIVER"); egl_dll_handle = dlopen(path, dlopen_flags); +#endif if ((path == NULL) | (egl_dll_handle == NULL)) { if (_this->gl_config.major_version > 1) { path = DEFAULT_OGL_ES2; @@ -160,7 +172,11 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa /* Catch the case where the application isn't linked with EGL */ if ((dlsym(dll_handle, "eglChooseConfig") == NULL) && (egl_path == NULL)) { dlclose(dll_handle); +#ifdef __WINRT__ + path = NULL; +#else path = getenv("SDL_VIDEO_EGL_DRIVER"); +#endif if (path == NULL) { path = DEFAULT_EGL; } diff --git a/src/video/SDL_egl.h b/src/video/SDL_egl.h index d6139058d..00bb26f5a 100644 --- a/src/video/SDL_egl.h +++ b/src/video/SDL_egl.h @@ -25,6 +25,18 @@ #if SDL_VIDEO_OPENGL_EGL +#if defined(__WINRT__) + +// DavidL: including this here leads to a compiler error: +// C2016: C requires that a struct or union has at least one member +// The error originates from a WinRT header file itself, roapi.h. +// +// Instead of including that file (EGL/egl.h), a subset of its contents is +// made available as part of winrt/SDL_winrtegl.h +//#include +#include "winrt/SDL_winrtegl.h" + +#else #include #include @@ -32,6 +44,8 @@ #define dlsym(x,y) dlsym(x, "_" y) #endif +#endif /* ! defined(__WINRT__) */ + #include "SDL_sysvideo.h" typedef struct SDL_EGL_VideoData @@ -41,46 +55,46 @@ typedef struct SDL_EGL_VideoData EGLConfig egl_config; int egl_swapinterval; - EGLDisplay(*eglGetDisplay) (NativeDisplayType display); - EGLBoolean(*eglInitialize) (EGLDisplay dpy, EGLint * major, - EGLint * minor); - EGLBoolean(*eglTerminate) (EGLDisplay dpy); + EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display); + EGLBoolean(EGLAPIENTRY *eglInitialize) (EGLDisplay dpy, EGLint * major, + EGLint * minor); + EGLBoolean(EGLAPIENTRY *eglTerminate) (EGLDisplay dpy); - void *(*eglGetProcAddress) (const char * procName); + void *(EGLAPIENTRY *eglGetProcAddress) (const char * procName); - EGLBoolean(*eglChooseConfig) (EGLDisplay dpy, - const EGLint * attrib_list, - EGLConfig * configs, - EGLint config_size, EGLint * num_config); + EGLBoolean(EGLAPIENTRY *eglChooseConfig) (EGLDisplay dpy, + const EGLint * attrib_list, + EGLConfig * configs, + EGLint config_size, EGLint * num_config); - EGLContext(*eglCreateContext) (EGLDisplay dpy, - EGLConfig config, - EGLContext share_list, - const EGLint * attrib_list); + EGLContext(EGLAPIENTRY *eglCreateContext) (EGLDisplay dpy, + EGLConfig config, + EGLContext share_list, + const EGLint * attrib_list); - EGLBoolean(*eglDestroyContext) (EGLDisplay dpy, EGLContext ctx); + EGLBoolean(EGLAPIENTRY *eglDestroyContext) (EGLDisplay dpy, EGLContext ctx); - EGLSurface(*eglCreateWindowSurface) (EGLDisplay dpy, - EGLConfig config, - NativeWindowType window, - const EGLint * attrib_list); - EGLBoolean(*eglDestroySurface) (EGLDisplay dpy, EGLSurface surface); + EGLSurface(EGLAPIENTRY *eglCreateWindowSurface) (EGLDisplay dpy, + EGLConfig config, + NativeWindowType window, + const EGLint * attrib_list); + EGLBoolean(EGLAPIENTRY *eglDestroySurface) (EGLDisplay dpy, EGLSurface surface); - EGLBoolean(*eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw, - EGLSurface read, EGLContext ctx); + EGLBoolean(EGLAPIENTRY *eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw, + EGLSurface read, EGLContext ctx); - EGLBoolean(*eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw); + EGLBoolean(EGLAPIENTRY *eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw); - EGLBoolean(*eglSwapInterval) (EGLDisplay dpy, EGLint interval); + EGLBoolean(EGLAPIENTRY *eglSwapInterval) (EGLDisplay dpy, EGLint interval); - const char *(*eglQueryString) (EGLDisplay dpy, EGLint name); + const char *(EGLAPIENTRY *eglQueryString) (EGLDisplay dpy, EGLint name); - EGLBoolean(*eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, - EGLint attribute, EGLint * value); + EGLBoolean(EGLAPIENTRY *eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint * value); - EGLBoolean(*eglWaitNative) (EGLint engine); + EGLBoolean(EGLAPIENTRY *eglWaitNative) (EGLint engine); - EGLBoolean(*eglWaitGL)(void); + EGLBoolean(EGLAPIENTRY *eglWaitGL)(void); } SDL_EGL_VideoData; /* OpenGLES functions */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 5c1c6d3f7..e255f4bbf 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -41,7 +41,7 @@ /* GL and GLES2 headers conflict on Linux 32 bits */ #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL -#include "SDL_opengles2.h" +#include "SDL_opengles2.h" #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */ #include "SDL_syswm.h" diff --git a/src/video/winrt/SDL_winrtegl.h b/src/video/winrt/SDL_winrtegl.h new file mode 100644 index 000000000..4ce55be96 --- /dev/null +++ b/src/video/winrt/SDL_winrtegl.h @@ -0,0 +1,166 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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_winrtegl_h +#define _SDL_winrtegl_h + +#include "SDL_hints.h" +#include "SDL_loadso.h" + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +/* Emulate various *nix functions that SDL_egl.c will call. + */ +#define dlsym SDL_LoadFunction +#define dlclose SDL_UnloadObject +#define dlopen(path, mode) ((path == NULL) ? NULL : SDL_LoadObject(path)) /* TODO, WinRT: create a separate function here, that sets dlerror on empty params */ +#define dlerror SDL_GetError +#define getenv SDL_GetHint +#define RTLD_LAZY 0 + + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* EGL Types */ +/* EGLint is defined in eglplatform.h */ +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef void *EGLConfig; +typedef void *EGLContext; +typedef void *EGLDisplay; +typedef void *EGLSurface; +typedef void *EGLClientBuffer; + +/* Platform-specific types */ +//typedef int EGLNativeDisplayType; +typedef int NativeDisplayType; +typedef void * NativeWindowType; + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY __stdcall +#endif + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef int EGLint; + +/* EGL Enumerants. Bitmasks and other exceptional cases aside, most + * enums are assigned unique values starting at 0x3000. + */ + +/* EGL aliases */ +#define EGL_FALSE 0 +#define EGL_TRUE 1 + +/* Out-of-band handle values */ +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) + +/* Config attributes */ +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_NONE 0x3038 /* Attrib list terminator */ +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */ +#define EGL_CONFORMANT 0x3042 + +/* Config attribute mask bits */ +#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */ + +#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */ + +/* CreateContext attributes */ +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 + + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_winrtegl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtopengles.cpp b/src/video/winrt/SDL_winrtopengles.cpp new file mode 100644 index 000000000..bbb73d7e0 --- /dev/null +++ b/src/video/winrt/SDL_winrtopengles.cpp @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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" + +// TODO: WinRT, make this file compile via C code + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +/* EGL implementation of SDL OpenGL support */ + +// TODO, WinRT: Try to include these here, or via something else (rather than redefining key parts of them) +//#include +//#include +//#include + +#include "SDL_winrtvideo_cpp.h" +extern "C" { +#include "SDL_winrtopengles.h" +} + +#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((NativeDisplayType) -3) + +extern "C" int +WINRT_GLES_LoadLibrary(_THIS, const char *path) { + return SDL_EGL_LoadLibrary(_this, path, EGL_D3D11_ONLY_DISPLAY_ANGLE); +} + +extern "C" { +SDL_EGL_CreateContext_impl(WINRT) +SDL_EGL_SwapWindow_impl(WINRT) +SDL_EGL_MakeCurrent_impl(WINRT) +} + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h new file mode 100644 index 000000000..5c52e0cb4 --- /dev/null +++ b/src/video/winrt/SDL_winrtopengles.h @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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_winrtopengles_h +#define _SDL_winrtopengles_h + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl.h" + +/* OpenGLES functions */ +#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute +#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WINRT_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); +extern void WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_winrtopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index c0b75c0eb..97358a966 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -42,6 +42,7 @@ extern "C" { #include "../../events/SDL_events_c.h" #include "../../render/SDL_sysrender.h" #include "SDL_syswm.h" +#include "SDL_winrtopengles.h" } #include "../../core/winrt/SDL_winrtapp_direct3d.h" @@ -111,6 +112,17 @@ WINRT_CreateDevice(int devindex) device->SetDisplayMode = WINRT_SetDisplayMode; device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; +#ifdef SDL_VIDEO_OPENGL_EGL + device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; + device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; + device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary; + device->GL_CreateContext = WINRT_GLES_CreateContext; + device->GL_MakeCurrent = WINRT_GLES_MakeCurrent; + device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval; + device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval; + device->GL_SwapWindow = WINRT_GLES_SwapWindow; + device->GL_DeleteContext = WINRT_GLES_DeleteContext; +#endif device->free = WINRT_DeleteDevice; WINRT_GlobalSDLVideoDevice = device; @@ -247,6 +259,22 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) data->coreWindow = CoreWindow::GetForCurrentThread(); } +#if SDL_VIDEO_OPENGL_EGL + /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */ + if (!(window->flags & SDL_WINDOW_OPENGL)) { + /* OpenGL ES 2 wasn't requested. Don't set up an EGL surface. */ + data->egl_surface = EGL_NO_SURFACE; + } else { + /* OpenGL ES 2 was reuqested. Set up an EGL surface. */ + IUnknown * nativeWindow = reinterpret_cast(data->coreWindow.Get()); + data->egl_surface = SDL_EGL_CreateSurface(_this, nativeWindow); + if (data->egl_surface == NULL) { + // TODO, WinRT: see if SDL_EGL_CreateSurface, or its callee(s), sets an error message. If so, attach it to the SDL error. + return SDL_SetError("SDL_EGL_CreateSurface failed"); + } + } +#endif + /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. */ @@ -259,6 +287,12 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_WINDOW_MAXIMIZED | SDL_WINDOW_INPUT_GRABBED; +#if SDL_VIDEO_OPENGL_EGL + if (data->egl_surface) { + window->flags |= SDL_WINDOW_OPENGL; + } +#endif + /* WinRT does not, as of this writing, appear to support app-adjustable window sizes. Set the window size to whatever the native WinRT CoreWindow is set at. diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index a36cc308d..f3900acfd 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -26,8 +26,14 @@ #endif /* SDL includes: */ +#include "SDL_video.h" #include "SDL_events.h" +extern "C" { +#include "../SDL_sysvideo.h" +#include "SDL_winrtegl.h" +} + /* The global, WinRT, SDL Window. For now, SDL/WinRT only supports one window (due to platform limitations of @@ -49,6 +55,9 @@ struct SDL_WindowData { SDL_Window *sdlWindow; Platform::Agile coreWindow; +#ifdef SDL_VIDEO_OPENGL_EGL + EGLSurface egl_surface; +#endif }; #endif // ifdef __cplusplus_winrt From 4f6b8b547b077ab36ec6a72b16c21706e3baaee7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 28 Nov 2013 21:15:05 -0500 Subject: [PATCH 225/264] WinRT: fixed bug: touch input coordinates weren't normalized [0..1] Thanks to Pierre-Yves for pointing this out and providing a fix! --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 8 +-- src/video/winrt/SDL_winrtevents_c.h | 8 ++- src/video/winrt/SDL_winrtpointerinput.cpp | 71 ++++++++++++++--------- 3 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index a5027fa4e..05a748727 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -495,7 +495,7 @@ WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); #endif WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); @@ -504,7 +504,7 @@ void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); #endif WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); @@ -513,7 +513,7 @@ void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); #endif WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); @@ -522,7 +522,7 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) { #if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position)); + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); #endif WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index ea09347ae..a6ae7a2c6 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -46,7 +46,13 @@ extern void WINRT_PumpEvents(_THIS); #ifdef __cplusplus_winrt /* Pointers (Mice, Touch, etc.) */ -extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition); +typedef enum { + NormalizeZeroToOne, + TransformToSDLWindowSize +} WINRT_CursorNormalizationType; +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, + Windows::Foundation::Point rawPosition, + WINRT_CursorNormalizationType normalization); extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index 9e64138a5..bb1a771f9 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -47,9 +47,14 @@ WINRT_InitTouch(_THIS) SDL_AddTouch(WINRT_TouchID, ""); } + +// // Applies necessary geometric transformations to raw cursor positions: +// Windows::Foundation::Point -WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition) +WINRT_TransformCursorPosition(SDL_Window * window, + Windows::Foundation::Point rawPosition, + WINRT_CursorNormalizationType normalization) { using namespace Windows::UI::Core; using namespace Windows::Graphics::Display; @@ -64,6 +69,8 @@ WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point ra // This might end up being the case as XAML support is extended. // For now, if there's no CoreWindow attached to the SDL_Window, // don't do any transforms. + + // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support return rawPosition; } @@ -73,33 +80,41 @@ WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point ra CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); Windows::Foundation::Point outputPosition; + // Compute coordinates normalized from 0..1. + // If the coordinates need to be sized to the SDL window, + // we'll do that after. #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; + outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; #else switch (DisplayProperties::CurrentOrientation) { case DisplayOrientations::Portrait: - outputPosition.X = rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; + outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; break; case DisplayOrientations::PortraitFlipped: - outputPosition.X = (float32)window->w - rawPosition.X * (((float32)window->w) / nativeWindow->Bounds.Width); - outputPosition.Y = (float32)window->h - rawPosition.Y * (((float32)window->h) / nativeWindow->Bounds.Height); + outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); + outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); break; case DisplayOrientations::Landscape: - outputPosition.X = rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); - outputPosition.Y = (float32)window->h - rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; + outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); break; case DisplayOrientations::LandscapeFlipped: - outputPosition.X = (float32)window->w - rawPosition.Y * (((float32)window->w) / nativeWindow->Bounds.Height); - outputPosition.Y = rawPosition.X * (((float32)window->h) / nativeWindow->Bounds.Width); + outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); + outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; break; default: break; } #endif + if (normalization == TransformToSDLWindowSize) { + outputPosition.X *= ((float32) window->w); + outputPosition.Y *= ((float32) window->h); + } + return outputPosition; } @@ -208,15 +223,17 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po return; } - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (!WINRT_IsTouchEvent(pointerPoint)) { + if ( ! WINRT_IsTouchEvent(pointerPoint)) { SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } else { + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); + if (!WINRT_LeftFingerDown) { if (button) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } @@ -227,8 +244,8 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, SDL_TRUE, - transformedPoint.X, - transformedPoint.Y, + normalizedPoint.X, + normalizedPoint.Y, pointerPoint->Properties->Pressure); } } @@ -240,20 +257,21 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo return; } - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); - if (!WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + if ( ! WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); } else if (pointerPoint->PointerId == WINRT_LeftFingerDown) { if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - SDL_SendMouseMotion(window, 0, 0, (int)transformedPoint.X, (int)transformedPoint.Y); + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); } SDL_SendTouchMotion( WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, - transformedPoint.X, - transformedPoint.Y, + normalizedPoint.X, + normalizedPoint.Y, pointerPoint->Properties->Pressure); } } @@ -264,12 +282,13 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P return; } - Windows::Foundation::Point transformedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position); Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); if (!WINRT_IsTouchEvent(pointerPoint)) { SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } else { + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { if (button) { SDL_SendMouseButton(window, 0, SDL_RELEASED, button); @@ -281,8 +300,8 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P WINRT_TouchID, (SDL_FingerID) pointerPoint->PointerId, SDL_FALSE, - transformedPoint.X, - transformedPoint.Y, + normalizedPoint.X, + normalizedPoint.Y, pointerPoint->Properties->Pressure); } } @@ -363,7 +382,7 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse // to SDL window coordinates. // const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize); SDL_SendMouseMotion( window, 0, From 446c3812675e298d1d3c249d313dae8046ee6dcf Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 28 Nov 2013 22:24:13 -0500 Subject: [PATCH 226/264] WinRT: implemented SDL_DetachThread() for WinRT --- src/thread/stdcpp/SDL_systhread.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index 02fcf76aa..6e043b417 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -130,6 +130,26 @@ SDL_SYS_WaitThread(SDL_Thread * thread) } } +extern "C" +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + if ( ! thread) { + return; + } + + try { + std::thread * cpp_thread = (std::thread *) thread->handle; + if (cpp_thread->joinable()) { + cpp_thread->detach(); + } + } catch (std::system_error &) { + // An error occurred when detaching the thread. SDL_DetachThread does not, + // however, seem to provide a means to report errors to its callers + // though! + } +} + extern "C" SDL_TLSData * SDL_SYS_GetTLSData() From 603365be1ed5293b6393bcf8d16e1ebba0d53018 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 28 Nov 2013 22:59:21 -0500 Subject: [PATCH 227/264] WinRT: got the SDL-official OpenGL ES 2 changes working, in an experimental state --- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 2 +- .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 6 +- include/SDL_egl.h | 7 + src/video/SDL_egl.c | 6 +- src/video/winrt/SDL_winrtegl.h | 166 ------------------ src/video/winrt/SDL_winrtopengles.h | 2 +- src/video/winrt/SDL_winrtvideo_cpp.h | 2 +- 7 files changed, 16 insertions(+), 175 deletions(-) delete mode 100644 src/video/winrt/SDL_winrtegl.h diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index a7ffb4d5f..8e9765fc6 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -217,6 +217,7 @@ + @@ -315,7 +316,6 @@ - diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index 82cbcb344..20f2f541c 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -629,12 +629,12 @@ Source Files - - Source Files - Header Files + + Header Files + diff --git a/include/SDL_egl.h b/include/SDL_egl.h index fc8fde4a6..5a1bc374b 100644 --- a/include/SDL_egl.h +++ b/include/SDL_egl.h @@ -391,9 +391,16 @@ typedef enum { #endif #include +#if __WINRT__ +#include +typedef IUnknown * EGLNativeWindowType; +typedef int EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +#else typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; +#endif #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index ce8f46221..733f202a2 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -41,7 +41,7 @@ #define DEFAULT_OGL_ES_PVR "libGLES_CM.so" #define DEFAULT_OGL_ES "libGLESv1_CM.so" -#elif SDL_VIDEO_DRIVER_WINDOWS +#elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT /* EGL AND OpenGL ES support via ANGLE */ #define DEFAULT_EGL "libEGL.dll" #define DEFAULT_OGL_ES2 "libGLESv2.dll" @@ -118,7 +118,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa { void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */ char *path = NULL; -#if SDL_VIDEO_DRIVER_WINDOWS +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT const char *d3dcompiler; #endif @@ -131,7 +131,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa return SDL_OutOfMemory(); } -#if SDL_VIDEO_DRIVER_WINDOWS +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER); if (!d3dcompiler) { /* By default we load the Vista+ compatible compiler */ diff --git a/src/video/winrt/SDL_winrtegl.h b/src/video/winrt/SDL_winrtegl.h deleted file mode 100644 index 4ce55be96..000000000 --- a/src/video/winrt/SDL_winrtegl.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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_winrtegl_h -#define _SDL_winrtegl_h - -#include "SDL_hints.h" -#include "SDL_loadso.h" - -#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL - -/* Emulate various *nix functions that SDL_egl.c will call. - */ -#define dlsym SDL_LoadFunction -#define dlclose SDL_UnloadObject -#define dlopen(path, mode) ((path == NULL) ? NULL : SDL_LoadObject(path)) /* TODO, WinRT: create a separate function here, that sets dlerror on empty params */ -#define dlerror SDL_GetError -#define getenv SDL_GetHint -#define RTLD_LAZY 0 - - -/* -** Copyright (c) 2007-2009 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* EGL Types */ -/* EGLint is defined in eglplatform.h */ -typedef unsigned int EGLBoolean; -typedef unsigned int EGLenum; -typedef void *EGLConfig; -typedef void *EGLContext; -typedef void *EGLDisplay; -typedef void *EGLSurface; -typedef void *EGLClientBuffer; - -/* Platform-specific types */ -//typedef int EGLNativeDisplayType; -typedef int NativeDisplayType; -typedef void * NativeWindowType; - -#ifndef EGLAPIENTRY -#define EGLAPIENTRY __stdcall -#endif - - -/* Define EGLint. This must be a signed integral type large enough to contain - * all legal attribute names and values passed into and out of EGL, whether - * their type is boolean, bitmask, enumerant (symbolic constant), integer, - * handle, or other. While in general a 32-bit integer will suffice, if - * handles are 64 bit types, then EGLint should be defined as a signed 64-bit - * integer type. - */ -typedef int EGLint; - -/* EGL Enumerants. Bitmasks and other exceptional cases aside, most - * enums are assigned unique values starting at 0x3000. - */ - -/* EGL aliases */ -#define EGL_FALSE 0 -#define EGL_TRUE 1 - -/* Out-of-band handle values */ -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_SURFACE ((EGLSurface)0) - -/* Config attributes */ -#define EGL_BUFFER_SIZE 0x3020 -#define EGL_ALPHA_SIZE 0x3021 -#define EGL_BLUE_SIZE 0x3022 -#define EGL_GREEN_SIZE 0x3023 -#define EGL_RED_SIZE 0x3024 -#define EGL_DEPTH_SIZE 0x3025 -#define EGL_STENCIL_SIZE 0x3026 -#define EGL_CONFIG_CAVEAT 0x3027 -#define EGL_CONFIG_ID 0x3028 -#define EGL_LEVEL 0x3029 -#define EGL_MAX_PBUFFER_HEIGHT 0x302A -#define EGL_MAX_PBUFFER_PIXELS 0x302B -#define EGL_MAX_PBUFFER_WIDTH 0x302C -#define EGL_NATIVE_RENDERABLE 0x302D -#define EGL_NATIVE_VISUAL_ID 0x302E -#define EGL_NATIVE_VISUAL_TYPE 0x302F -#define EGL_SAMPLES 0x3031 -#define EGL_SAMPLE_BUFFERS 0x3032 -#define EGL_SURFACE_TYPE 0x3033 -#define EGL_TRANSPARENT_TYPE 0x3034 -#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 -#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 -#define EGL_TRANSPARENT_RED_VALUE 0x3037 -#define EGL_NONE 0x3038 /* Attrib list terminator */ -#define EGL_BIND_TO_TEXTURE_RGB 0x3039 -#define EGL_BIND_TO_TEXTURE_RGBA 0x303A -#define EGL_MIN_SWAP_INTERVAL 0x303B -#define EGL_MAX_SWAP_INTERVAL 0x303C -#define EGL_LUMINANCE_SIZE 0x303D -#define EGL_ALPHA_MASK_SIZE 0x303E -#define EGL_COLOR_BUFFER_TYPE 0x303F -#define EGL_RENDERABLE_TYPE 0x3040 -#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */ -#define EGL_CONFORMANT 0x3042 - -/* Config attribute mask bits */ -#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */ -#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */ - -#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */ - -/* CreateContext attributes */ -#define EGL_CONTEXT_CLIENT_VERSION 0x3098 - - -#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ - -#endif /* _SDL_winrtegl_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h index 5c52e0cb4..4ac3cfe23 100644 --- a/src/video/winrt/SDL_winrtopengles.h +++ b/src/video/winrt/SDL_winrtopengles.h @@ -26,7 +26,7 @@ #if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL #include "../SDL_sysvideo.h" -#include "../SDL_egl.h" +#include "../SDL_egl_c.h" /* OpenGLES functions */ #define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index f3900acfd..15c731e24 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -31,7 +31,7 @@ extern "C" { #include "../SDL_sysvideo.h" -#include "SDL_winrtegl.h" +#include "../SDL_egl_c.h" } From a4f050087d781d552889550c6ec0f5acedc13a0f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 29 Nov 2013 00:19:46 -0500 Subject: [PATCH 228/264] WinRT: enable the OpenGL ES 2 SDL_Renderer backend, if and when OpenGL ES 2 support is compiled in --- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 4 ++++ VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters | 12 ++++++++++++ include/SDL_config_winrt.h | 4 ++++ src/render/opengles2/SDL_render_gles2.c | 8 ++++++++ 4 files changed, 28 insertions(+) diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index 8e9765fc6..43bbb1a59 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -104,6 +104,8 @@ true true + + @@ -284,6 +286,8 @@ + + diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index 20f2f541c..b3c0686b4 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -285,6 +285,12 @@ Source Files + + Source Files + + + Source Files + @@ -635,6 +641,12 @@ Header Files + + Source Files + + + Source Files + diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 210d1e660..de09fbce7 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -179,6 +179,10 @@ typedef unsigned int uintptr_t; /* Enable appropriate renderer(s) */ #define SDL_VIDEO_RENDER_D3D11 1 +#if SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + /* Enable system power support */ // TODO, WinRT: investigate system power support. The Win32-based APIs don't work on WinRT. #define SDL_POWER_DISABLED 1 diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 31a1598c0..2c0828a02 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1772,6 +1772,14 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) return NULL; } +#if __WINRT__ + /* DLudwig, 2013-11-29: ANGLE for WinRT doesn't seem to work unless VSync + * is turned on. Not doing so will freeze the screen's contents to that + * of the first drawn frame. + */ + flags |= SDL_RENDERER_PRESENTVSYNC; +#endif + if (flags & SDL_RENDERER_PRESENTVSYNC) { SDL_GL_SetSwapInterval(1); } else { From a21be44a15a9f280d5344512327ee9b4c07152fd Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 29 Nov 2013 00:21:56 -0500 Subject: [PATCH 229/264] WinRT: removed a now-complete TODO comment regarding Direct3D 11 --- include/SDL_config_winrt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index de09fbce7..3db8c9de3 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -175,7 +175,6 @@ typedef unsigned int uintptr_t; //#define SDL_VIDEO_OPENGL_EGL 1 #endif -// TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. /* Enable appropriate renderer(s) */ #define SDL_VIDEO_RENDER_D3D11 1 From 1df5dccd9ae6c2308dcdb0344b46622e14bddf28 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 10 Dec 2013 22:34:08 -0500 Subject: [PATCH 230/264] WinRT: fixed bug: SDL_RenderReadPixels didn't work with certain orientations of the physical display --- src/render/direct3d11/SDL_render_d3d11.cpp | 143 +++++++++++---------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 2c2d49a9c..6852af82f 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -630,12 +630,46 @@ D3D11_ConvertDipsToPixels(float dips) } #endif - #if WINAPI_FAMILY == WINAPI_FAMILY_APP // TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative; #endif +static DXGI_MODE_ROTATION +D3D11_GetRotationForOrientation(Windows::Graphics::Display::DisplayOrientations orientation) +{ + switch (orientation) + { +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // + // Windows Phone rotations + // + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_ROTATE90; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE180; +#else + // + // Non-Windows-Phone rotations (ex: Windows 8, Windows RT) + // + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE180; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE90; +#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + + default: + return DXGI_MODE_ROTATION_UNSPECIFIED; + } +} // Initialize all resources that change when the window's size changes. // TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32 @@ -811,31 +845,9 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) // Set the proper orientation for the swap chain, and generate the // 3D matrix transformation for rendering to the rotated swap chain. // - // To note, his operation is not necessary on Windows Phone, nor is it - // even supported there. It's only needed in Windows 8/RT. - 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(); - } - + // To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary + // on Windows Phone, nor is it supported there. It's only needed in Windows 8/RT. + DXGI_MODE_ROTATION rotation = D3D11_GetRotationForOrientation(data->orientation); result = data->swapChain->SetRotation(rotation); if (FAILED(result)) { WIN_SetErrorFromHRESULT(__FUNCTION__, result); @@ -1223,7 +1235,7 @@ D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; return 0; -} +} static int D3D11_UpdateViewport(SDL_Renderer * renderer) @@ -1237,50 +1249,24 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) return 0; } - switch (data->orientation) + // Make sure the SDL viewport gets rotated to that of the physical display's orientation. + // Keep in mind here that the Y-axis will be been inverted (from Direct3D's + // default coordinate system) so rotations will be done in the opposite + // direction of the DXGI_MODE_ROTATION enumeration. + switch (D3D11_GetRotationForOrientation(data->orientation)) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - // - // Windows Phone rotations - // - case DisplayOrientations::Landscape: - // 270-degree (-90 degree) Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); - break; - case DisplayOrientations::Portrait: - // 0-degree Z-rotation + case DXGI_MODE_ROTATION_IDENTITY: XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); break; - case DisplayOrientations::LandscapeFlipped: - // 90-degree Z-rotation + case DXGI_MODE_ROTATION_ROTATE270: XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); break; - case DisplayOrientations::PortraitFlipped: - // 180-degree Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI)); - break; -#else - // - // Non-Windows-Phone rotations (ex: Windows 8, Windows RT) - // - case DisplayOrientations::Landscape: - // 0-degree Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); - break; - case DisplayOrientations::Portrait: - // 90-degree Z-rotation - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); - break; - case DisplayOrientations::LandscapeFlipped: - // 180-degree Z-rotation + case DXGI_MODE_ROTATION_ROTATE180: XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI)); break; - case DisplayOrientations::PortraitFlipped: - // 270-degree (-90 degree) Z-rotation + case DXGI_MODE_ROTATION_ROTATE90: XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); break; -#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - default: SDL_SetError("An unknown DisplayOrientation is being used"); return -1; @@ -1314,6 +1300,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // for Windows Phone devices. // SDL_FRect orientationAlignedViewport; + #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP const bool swapDimensions = data->orientation == DisplayOrientations::Landscape || @@ -1830,10 +1817,34 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, // 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; + switch (D3D11_GetRotationForOrientation(data->orientation)) { + case DXGI_MODE_ROTATION_IDENTITY: + srcBox.left = rect->x; + srcBox.right = rect->x + rect->w; + srcBox.top = rect->y; + srcBox.bottom = rect->y + rect->h; + break; + case DXGI_MODE_ROTATION_ROTATE270: + srcBox.left = rect->y; + srcBox.right = rect->y + rect->h; + srcBox.top = renderer->viewport.w - rect->x - rect->w; + srcBox.bottom = renderer->viewport.w - rect->x; + break; + case DXGI_MODE_ROTATION_ROTATE180: + srcBox.left = renderer->viewport.w - rect->x - rect->w; + srcBox.right = renderer->viewport.w - rect->x; + srcBox.top = renderer->viewport.h - rect->y - rect->h; + srcBox.bottom = renderer->viewport.h - rect->y; + break; + case DXGI_MODE_ROTATION_ROTATE90: + srcBox.left = renderer->viewport.h - rect->y - rect->h; + srcBox.right = renderer->viewport.h - rect->y; + srcBox.top = rect->x; + srcBox.bottom = rect->x + rect->h; + break; + default: + return SDL_SetError("The physical display is in an unknown or unsupported orientation"); + } srcBox.front = 0; srcBox.back = 1; data->d3dContext->CopySubresourceRegion( From fcbc582b237bc7ce6b9aece198df4baab657b162 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 21 Dec 2013 10:08:11 -0500 Subject: [PATCH 231/264] WinRT: enabled OpenGL ES 2 support by default A copy of ANGLE/WinRT is still needed to run OpenGL content, but is not needed to compile SDL/WinRT. --- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 12 ++++++------ include/SDL_config_winrt.h | 7 ++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index 43bbb1a59..6a2dfb6ee 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -465,7 +465,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -479,7 +479,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -493,7 +493,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -507,7 +507,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -521,7 +521,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -535,7 +535,7 @@ NotUsing false - ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) + ..\..\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 3db8c9de3..b99520544 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -168,11 +168,8 @@ typedef unsigned int uintptr_t; /* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */ -/* Uncomment the following two #defines to enable experimental OpenGL ES 2 support - (via a WinRT port of the ANGLE library). -*/ -//#define SDL_VIDEO_OPENGL_ES2 1 -//#define SDL_VIDEO_OPENGL_EGL 1 +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 #endif /* Enable appropriate renderer(s) */ From f5ca4203fbfb36c0be3c8405a52452c80dd2a4d9 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 22 Dec 2013 21:13:35 -0500 Subject: [PATCH 232/264] WinRT: better rendering performance via D3D11_USAGE_DYNAMIC --- src/render/direct3d11/SDL_render_d3d11.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 6852af82f..37e355dbb 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1384,7 +1384,7 @@ D3D11_RenderClear(SDL_Renderer * renderer) static int D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, - const void * vertexData, unsigned int dataSizeInBytes) + const void * vertexData, size_t dataSizeInBytes) { D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; @@ -1397,10 +1397,20 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, } if (vertexBufferDesc.ByteWidth >= dataSizeInBytes) { - rendererData->d3dContext->UpdateSubresource(rendererData->vertexBuffer.Get(), 0, NULL, vertexData, dataSizeInBytes, 0); + D3D11_MAPPED_SUBRESOURCE mappedResource; + ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE)); + result = rendererData->d3dContext->Map(rendererData->vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__, result); + return -1; + } + memcpy(mappedResource.pData, vertexData, dataSizeInBytes); + rendererData->d3dContext->Unmap(rendererData->vertexBuffer.Get(), 0); } else { vertexBufferDesc.ByteWidth = dataSizeInBytes; + vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; D3D11_SUBRESOURCE_DATA vertexBufferData = {0}; vertexBufferData.pSysMem = vertexData; From 378af595bc48af51c2b69959afd148999a91442b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 24 Dec 2013 21:08:11 -0500 Subject: [PATCH 233/264] WinRT: bug fix: game-controller/joystick button-down events weren't getting sent --- src/video/winrt/SDL_winrtvideo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 97358a966..180528373 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -301,6 +301,12 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) */ window->w = _this->displays[0].current_mode.w; window->h = _this->displays[0].current_mode.h; + + /* For now, treat WinRT apps as if they always have focus. + TODO, WinRT: try tracking keyboard and mouse focus state with respect to snapped apps + */ + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); /* Make sure the WinRT app's IFramworkView can post events on behalf of SDL: From 90532fcb1ada2d16a34153719e8cb60ac64acae0 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 24 Dec 2013 21:28:31 -0500 Subject: [PATCH 234/264] WinRT: moved ill-performing XInput device-detection calls to a separate thread --- src/joystick/winrt/SDL_xinputjoystick.c | 348 +++++++++++++++--------- 1 file changed, 224 insertions(+), 124 deletions(-) diff --git a/src/joystick/winrt/SDL_xinputjoystick.c b/src/joystick/winrt/SDL_xinputjoystick.c index 6b3e59f0e..7c2853f29 100644 --- a/src/joystick/winrt/SDL_xinputjoystick.c +++ b/src/joystick/winrt/SDL_xinputjoystick.c @@ -38,16 +38,18 @@ #include "../SDL_joystick_c.h" #include "SDL_events.h" #include "../../events/SDL_events_c.h" +#include "SDL_timer.h" #include #include 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? + //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 detection-polling, or during backend-initialization)? + SDL_bool isDeviceConnectionEventPending; // was a device added, and is the associated add-event pending? + SDL_bool isDeviceRemovalEventPending; // was the device removed, and is the associated remove-event pending? }; /* Keep track of data on all XInput devices, regardless of whether or not @@ -55,6 +57,79 @@ struct joystick_hwdata { */ static struct joystick_hwdata g_XInputData[XUSER_MAX_COUNT]; +/* Device detection can be extremely costly performance-wise, in some cases. + In particular, if no devices are connected, calls to detect a single device, + via either XInputGetState() or XInputGetCapabilities(), can take upwards of + 20 ms on a 1st generation Surface RT, more if devices are detected across + all of of XInput's four device slots. WinRT and XInput do not appear to + have callback-based APIs to notify an app when a device is connected, at + least as of Windows 8.1. The synchronous XInput calls must be used. + + Once a device is connected, calling XInputGetState() is a much less costly + operation, with individual calls costing well under 1 ms, and often under + 0.1 ms [on a 1st gen Surface RT]. + + With XInput's performance limitations in mind, a separate device-detection + thread will be utilized (by SDL) to try to move costly XInput calls off the + main thread. Polling of active devices still, however, occurs on the main + thread. + */ +static SDL_Thread * g_DeviceDetectionThread = NULL; +static SDL_mutex * g_DeviceInfoLock = NULL; +static SDL_bool g_DeviceDetectionQuit = SDL_FALSE; + +/* Main function for the device-detection thread. + */ +static int +DeviceDetectionThreadMain(void * _data) +{ + DWORD result; + XINPUT_CAPABILITIES tempXInputCaps; + int i; + + while (1) { + /* See if the device-detection thread is being asked to shutdown. + */ + SDL_LockMutex(g_DeviceInfoLock); + if (g_DeviceDetectionQuit) { + SDL_UnlockMutex(g_DeviceInfoLock); + break; + } + SDL_UnlockMutex(g_DeviceInfoLock); + + /* Add a short delay to prevent the device-detection thread from eating + up too much CPU time: + */ + SDL_Delay(300); + + /* TODO, WinRT: try making the device-detection thread wakeup sooner from its CPU-preserving SDL_Delay, if the thread was asked to quit. + */ + + /* See if any new devices are connected. */ + for (i = 0; i < XUSER_MAX_COUNT; ++i) { + if (!g_XInputData[i].isDeviceConnected && + !g_XInputData[i].isDeviceConnectionEventPending && + !g_XInputData[i].isDeviceRemovalEventPending) + { + result = XInputGetCapabilities(i, 0, &tempXInputCaps); + if (result == ERROR_SUCCESS) { + /* Yes, a device is connected. Mark it as such. + Others will be told about this (via an + SDL_JOYDEVICEADDED event) in the next call to + SDL_SYS_JoystickDetect. + */ + SDL_LockMutex(g_DeviceInfoLock); + g_XInputData[i].isDeviceConnected = SDL_TRUE; + g_XInputData[i].isDeviceConnectionEventPending = SDL_TRUE; + SDL_UnlockMutex(g_DeviceInfoLock); + } + } + } + } + + return 0; +} + /* Function to scan the system for joysticks. * It should return 0, or -1 on an unrecoverable fatal error. */ @@ -76,6 +151,12 @@ SDL_SYS_JoystickInit(void) } } + /* Start up the device-detection thread. + */ + g_DeviceDetectionQuit = SDL_FALSE; + g_DeviceInfoLock = SDL_CreateMutex(); + g_DeviceDetectionThread = SDL_CreateThread(DeviceDetectionThreadMain, "SDL_joystick", NULL); + return (0); } @@ -87,11 +168,13 @@ int SDL_SYS_NumJoysticks() /* Iterate through each possible XInput device and see if something was connected (at joystick init, or during the last polling). */ + SDL_LockMutex(g_DeviceInfoLock); for (i = 0; i < XUSER_MAX_COUNT; ++i) { if (g_XInputData[i].isDeviceConnected) { ++joystickCount; } } + SDL_UnlockMutex(g_DeviceInfoLock); return joystickCount; } @@ -99,36 +182,28 @@ int SDL_SYS_NumJoysticks() 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. */ + SDL_LockMutex(g_DeviceInfoLock); 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 (g_XInputData[i].isDeviceConnectionEventPending) { #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); - } + 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 } +#endif + g_XInputData[i].isDeviceConnectionEventPending = SDL_FALSE; } else if (g_XInputData[i].isDeviceRemovalEventPending) { /* A device was previously marked as removed (by SDL_SYS_JoystickUpdate). Tell others about the device removal. @@ -137,19 +212,20 @@ void SDL_SYS_JoystickDetect() 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); - } + 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 +#endif } } + SDL_UnlockMutex(g_DeviceInfoLock); } SDL_bool SDL_SYS_JoystickNeedsPolling() @@ -276,31 +352,35 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) 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! */ + /* 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; + SDL_bool isDeviceConnected; + SDL_LockMutex(g_DeviceInfoLock); + isDeviceConnected = joystick->hwdata->isDeviceConnected; + SDL_UnlockMutex(g_DeviceInfoLock); + return 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 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. @@ -311,70 +391,76 @@ static int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) 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 + HRESULT result; + XINPUT_STATE prevXInputState; + + SDL_LockMutex(g_DeviceInfoLock); + + /* Before polling for new data, make note of the old data */ + 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 */ + } + SDL_UnlockMutex(g_DeviceInfoLock); + 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 + } + + SDL_UnlockMutex(g_DeviceInfoLock); } /* Function to close a joystick after use */ @@ -382,7 +468,9 @@ void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { /* Clear cached button data on the joystick */ + SDL_LockMutex(g_DeviceInfoLock); SDL_zero(joystick->hwdata->XInputState); + SDL_UnlockMutex(g_DeviceInfoLock); /* 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 @@ -395,6 +483,18 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick) void SDL_SYS_JoystickQuit(void) { + /* Tell the joystick detection thread to stop, then wait for it to finish */ + SDL_LockMutex(g_DeviceInfoLock); + g_DeviceDetectionQuit = SDL_TRUE; + SDL_UnlockMutex(g_DeviceInfoLock); + SDL_WaitThread(g_DeviceDetectionThread, NULL); + + /* Clean up device-detection stuff */ + SDL_DestroyMutex(g_DeviceInfoLock); + g_DeviceInfoLock = NULL; + g_DeviceDetectionThread = NULL; + g_DeviceDetectionQuit = SDL_FALSE; + return; } @@ -419,15 +519,15 @@ SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) 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; +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 */ From 326ecc4ed62e8d95cbdad7750753c6fb53f9a801 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 12:43:26 -0500 Subject: [PATCH 235/264] WinRT: made d3d11-spawned error messages include the function name of failed calls --- src/render/direct3d11/SDL_render_d3d11.cpp | 69 +++++++++++----------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 37e355dbb..ed3b9316d 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -282,7 +282,7 @@ D3D11_LoadPixelShader(SDL_Renderer * renderer, shaderOutput ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader", result); return result; } @@ -313,7 +313,7 @@ D3D11_CreateBlendMode(SDL_Renderer * renderer, blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; result = data->d3dDevice->CreateBlendState(&blendDesc, blendStateOutput); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBlendState", result); return result; } @@ -370,7 +370,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &context // Returns the device immediate context. ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result); return result; } @@ -378,12 +378,13 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) Microsoft::WRL::ComPtr d3dDevice1; result = device.As(&(data->d3dDevice)); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result); return result; } result = context.As(&data->d3dContext); if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", result); return result; } @@ -429,7 +430,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->vertexShader ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", result); return result; } @@ -451,7 +452,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->inputLayout ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result); return result; } @@ -480,7 +481,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->vertexShaderConstants ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result); return result; } @@ -512,7 +513,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->nearestPixelSampler ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result); return result; } @@ -522,7 +523,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->linearSampler ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result); return result; } @@ -543,7 +544,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) rasterDesc.SlopeScaledDepthBias = 0.0f; result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->mainRasterizer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState", result); return result; } @@ -686,7 +687,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) if (coreWindow) { result = coreWindow->get_Bounds(&nativeWindowBounds); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__", Get Window Bounds", result); + WIN_SetErrorFromHRESULT(__FUNCTION__", ICoreWindow::get_Bounds [get native-window bounds]", result); return result; } } else { @@ -735,7 +736,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) 0 ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::ResizeBuffers", result); return result; } } @@ -769,14 +770,14 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) ComPtr dxgiDevice; result = data->d3dDevice.As(&dxgiDevice); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1 to IDXGIDevice1", result); return result; } ComPtr dxgiAdapter; result = dxgiDevice->GetAdapter(&dxgiAdapter); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::GetAdapter", result); return result; } @@ -786,7 +787,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) &dxgiFactory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter::GetParent", result); return result; } @@ -797,7 +798,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) nullptr, &data->swapChain); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateSwapChainForComposition", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result); return result; } @@ -815,7 +816,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) IUnknown * coreWindowAsIUnknown = nullptr; result = coreWindow->QueryInterface(&coreWindowAsIUnknown); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CoreWindow to IUnknown", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow to IUnknown", result); return result; } @@ -827,7 +828,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) &data->swapChain ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", result); return result; } } @@ -836,7 +837,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) // ensures that the application will only render after each VSync, minimizing power consumption. result = dxgiDevice->SetMaximumFrameLatency(1); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::SetMaximumFrameLatency", result); return result; } } @@ -850,7 +851,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) DXGI_MODE_ROTATION rotation = D3D11_GetRotationForOrientation(data->orientation); result = data->swapChain->SetRotation(rotation); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation" , result); return result; } #endif @@ -863,7 +864,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) &backBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [back-buffer]", result); return result; } @@ -873,7 +874,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) &data->mainRenderTargetView ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result); return result; } @@ -896,7 +897,7 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) result = coreWindow->get_Bounds(&coreWindowBounds); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Get Window Bounds", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow::get_Bounds [get window bounds]", result); return result; } @@ -1037,7 +1038,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result); return -1; } @@ -1053,7 +1054,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) &textureData->mainTextureRenderTargetView); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result); return -1; } } @@ -1070,7 +1071,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result); return -1; } @@ -1157,7 +1158,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, NULL, &textureData->stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Create Staging Texture", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result); return -1; } @@ -1171,7 +1172,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, &textureMemory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Map Staging Texture", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result); textureData->stagingTexture = nullptr; return -1; } @@ -1401,7 +1402,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE)); result = rendererData->d3dContext->Map(rendererData->vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result); return -1; } memcpy(mappedResource.pData, vertexData, dataSizeInBytes); @@ -1423,7 +1424,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, &rendererData->vertexBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result); return -1; } } @@ -1802,7 +1803,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, &backBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Get Back Buffer", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result); return -1; } @@ -1821,7 +1822,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, NULL, &stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Create Staging Texture", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result); return -1; } @@ -1874,7 +1875,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 0, &textureMemory); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", Map Staging Texture to CPU Memory", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result); return -1; } @@ -1950,7 +1951,7 @@ D3D11_RenderPresent(SDL_Renderer * renderer) } else { - WIN_SetErrorFromHRESULT(__FUNCTION__, hr); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::DiscardView", hr); } } From 255cf99d66c0273131a61e15713a4eb1565d22f6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 12:47:39 -0500 Subject: [PATCH 236/264] WinRT: made d3d11-spawned error messages trickle down Some error messages had the potential to be overwritten/obscured. --- src/render/direct3d11/SDL_render_d3d11.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index ed3b9316d..109e71e3e 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -911,7 +911,7 @@ D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) data->d3dContext->Flush(); result = D3D11_CreateWindowSizeDependentResources(renderer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + /* D3D11_CreateWindowSizeDependentResources will set the SDL error */ return result; } } @@ -932,13 +932,13 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer) result = D3D11_CreateDeviceResources(renderer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + /* D3D11_CreateDeviceResources will set the SDL error */ return result; } result = D3D11_UpdateForWindowSizeChange(renderer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, result); + /* D3D11_UpdateForWindowSizeChange will set the SDL error */ return result; } @@ -1946,7 +1946,7 @@ D3D11_RenderPresent(SDL_Renderer * renderer) { hr = D3D11_HandleDeviceLost(renderer); if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__, hr); + /* D3D11_HandleDeviceLost will set the SDL error */ } } else From 5fac22c332c49915f5bd615be2b29e688b70e91f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 12:48:47 -0500 Subject: [PATCH 237/264] WinRT: minor d3d11 code cleanups --- src/render/direct3d11/SDL_render_d3d11.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 109e71e3e..c17326fb9 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -375,7 +375,6 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) } // Get the Direct3D 11.1 API device and context interfaces. - Microsoft::WRL::ComPtr d3dDevice1; result = device.As(&(data->d3dDevice)); if (FAILED(result)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result); @@ -767,7 +766,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) #endif swapChainDesc.Flags = 0; - ComPtr dxgiDevice; + ComPtr dxgiDevice; result = data->d3dDevice.As(&dxgiDevice); if (FAILED(result)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1 to IDXGIDevice1", result); From 1b770842fced9841acbab08fc1323b4c9dbb6dd7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 12:52:16 -0500 Subject: [PATCH 238/264] WinRT: utilized SDL_SetError's return value in the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index c17326fb9..9041a9dcd 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -973,9 +973,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 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", + return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", __FUNCTION__, texture->format); - return -1; } textureData = new D3D11_TextureData; @@ -1106,8 +1105,7 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, // 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; + return SDL_SetError(errorMessage.c_str()); } // Copy pixel data to the locked texture's memory: @@ -1135,8 +1133,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, HRESULT result = S_OK; if (textureData->stagingTexture) { - SDL_SetError("texture is already locked"); - return -1; + return SDL_SetError("texture is already locked"); } // Create a 'staging' texture, which will be used to write to a portion @@ -1228,8 +1225,7 @@ D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) if (!textureData->mainTextureRenderTargetView) { std::string errorMessage = string(__FUNCTION__) + ": specified texture is not a render target"; - SDL_SetError(errorMessage.c_str()); - return -1; + return SDL_SetError(errorMessage.c_str()); } rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; @@ -1268,8 +1264,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); break; default: - SDL_SetError("An unknown DisplayOrientation is being used"); - return -1; + return SDL_SetError("An unknown DisplayOrientation is being used"); } // @@ -1892,8 +1887,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, // 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; + return SDL_SetError(errorMessage.c_str()); } // Unmap the texture: From 788d61ec6baf1dbb537c6dd77b4aee940330c5a5 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 12:58:37 -0500 Subject: [PATCH 239/264] WinRT: removed an unnecessary use of std::string in the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 9041a9dcd..a97c407cf 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1224,8 +1224,7 @@ D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; if (!textureData->mainTextureRenderTargetView) { - std::string errorMessage = string(__FUNCTION__) + ": specified texture is not a render target"; - return SDL_SetError(errorMessage.c_str()); + return SDL_SetError(__FUNCTION__ ", specified texture is not a render target"); } rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; From bbd8e31737913782040a4822b21de4f73dd3ecc3 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 13:00:41 -0500 Subject: [PATCH 240/264] WinRT: simplified a potentially-common error message from D3D11_SetRenderTarget --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index a97c407cf..541fcdbcb 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1224,7 +1224,7 @@ D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; if (!textureData->mainTextureRenderTargetView) { - return SDL_SetError(__FUNCTION__ ", specified texture is not a render target"); + return SDL_SetError("specified texture is not a render target"); } rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; From 1f740f328bddf23dfa720b8932a8b6f310b21856 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 13:13:15 -0500 Subject: [PATCH 241/264] WinRT: moved contents of the d3d11 renderer's header file into its implementation file --- .../SDL/SDL-WinPhone_VS2012.vcxproj | 1 - .../SDL/SDL-WinPhone_VS2012.vcxproj.filters | 3 - VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 1 - .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 3 - src/render/direct3d11/SDL_render_d3d11.cpp | 69 ++++++++++++++- src/render/direct3d11/SDL_render_d3d11_cpp.h | 86 ------------------- 6 files changed, 67 insertions(+), 96 deletions(-) delete mode 100644 src/render/direct3d11/SDL_render_d3d11_cpp.h diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj index 882fe3b6c..0f185bec2 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj @@ -215,7 +215,6 @@ - diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters index f99bb9488..59296bf42 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters @@ -318,9 +318,6 @@ Source Files - - Source Files - Source Files diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index 6a2dfb6ee..f06787f78 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -284,7 +284,6 @@ - diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index b3c0686b4..bff9c9deb 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -599,9 +599,6 @@ Header Files - - Source Files - Header Files diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 541fcdbcb..f5a2d0f59 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -49,7 +49,10 @@ extern "C" { #include #include -#include "SDL_render_d3d11_cpp.h" +#include +#include +#include + using namespace DirectX; using namespace Microsoft::WRL; @@ -64,8 +67,70 @@ using namespace Windows::UI::Core; static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_MIP_POINT; static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR; -/* Direct3D 11.1 renderer implementation */ +/* Vertex shader, common values */ +struct SDL_VertexShaderConstants +{ + DirectX::XMFLOAT4X4 model; + DirectX::XMFLOAT4X4 view; + DirectX::XMFLOAT4X4 projection; +}; +/* Per-vertex data */ +struct VertexPositionColor +{ + DirectX::XMFLOAT3 pos; + DirectX::XMFLOAT2 tex; + DirectX::XMFLOAT4 color; +}; + +/* Per-texture data */ +typedef struct +{ + Microsoft::WRL::ComPtr mainTexture; + Microsoft::WRL::ComPtr mainTextureResourceView; + Microsoft::WRL::ComPtr mainTextureRenderTargetView; + SDL_PixelFormat * pixelFormat; + Microsoft::WRL::ComPtr stagingTexture; + DirectX::XMINT2 lockedTexturePosition; + D3D11_FILTER scaleMode; +} D3D11_TextureData; + +/* Private renderer data */ +typedef struct +{ + Microsoft::WRL::ComPtr d3dDevice; + Microsoft::WRL::ComPtr d3dContext; + Microsoft::WRL::ComPtr swapChain; + Microsoft::WRL::ComPtr mainRenderTargetView; + Microsoft::WRL::ComPtr currentOffscreenRenderTargetView; + Microsoft::WRL::ComPtr inputLayout; + Microsoft::WRL::ComPtr vertexBuffer; + Microsoft::WRL::ComPtr vertexShader; + Microsoft::WRL::ComPtr texturePixelShader; + Microsoft::WRL::ComPtr colorPixelShader; + Microsoft::WRL::ComPtr blendModeBlend; + Microsoft::WRL::ComPtr blendModeAdd; + Microsoft::WRL::ComPtr blendModeMod; + Microsoft::WRL::ComPtr nearestPixelSampler; + Microsoft::WRL::ComPtr linearSampler; + Microsoft::WRL::ComPtr mainRasterizer; + D3D_FEATURE_LEVEL featureLevel; + + // Vertex buffer constants: + SDL_VertexShaderConstants vertexShaderConstantsData; + Microsoft::WRL::ComPtr 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; + + +/* 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); diff --git a/src/render/direct3d11/SDL_render_d3d11_cpp.h b/src/render/direct3d11/SDL_render_d3d11_cpp.h deleted file mode 100644 index 6c8584683..000000000 --- a/src/render/direct3d11/SDL_render_d3d11_cpp.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 -#include -#include -#include - -struct SDL_VertexShaderConstants -{ - DirectX::XMFLOAT4X4 model; - DirectX::XMFLOAT4X4 view; - DirectX::XMFLOAT4X4 projection; -}; - -typedef struct -{ - Microsoft::WRL::ComPtr d3dDevice; - Microsoft::WRL::ComPtr d3dContext; - Microsoft::WRL::ComPtr swapChain; - Microsoft::WRL::ComPtr mainRenderTargetView; - Microsoft::WRL::ComPtr currentOffscreenRenderTargetView; - Microsoft::WRL::ComPtr inputLayout; - Microsoft::WRL::ComPtr vertexBuffer; - Microsoft::WRL::ComPtr vertexShader; - Microsoft::WRL::ComPtr texturePixelShader; - Microsoft::WRL::ComPtr colorPixelShader; - Microsoft::WRL::ComPtr blendModeBlend; - Microsoft::WRL::ComPtr blendModeAdd; - Microsoft::WRL::ComPtr blendModeMod; - Microsoft::WRL::ComPtr nearestPixelSampler; - Microsoft::WRL::ComPtr linearSampler; - Microsoft::WRL::ComPtr mainRasterizer; - D3D_FEATURE_LEVEL featureLevel; - - // Vertex buffer constants: - SDL_VertexShaderConstants vertexShaderConstantsData; - Microsoft::WRL::ComPtr 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 mainTexture; - Microsoft::WRL::ComPtr mainTextureResourceView; - Microsoft::WRL::ComPtr mainTextureRenderTargetView; - SDL_PixelFormat * pixelFormat; - Microsoft::WRL::ComPtr stagingTexture; - DirectX::XMINT2 lockedTexturePosition; - D3D11_FILTER scaleMode; -} D3D11_TextureData; - -struct VertexPositionColor -{ - DirectX::XMFLOAT3 pos; - DirectX::XMFLOAT2 tex; - DirectX::XMFLOAT4 color; -}; - -/* vi: set ts=4 sw=4 expandtab: */ From 79d7f0dee259ad709c43527b4cf7f411cee13364 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 14:17:49 -0500 Subject: [PATCH 242/264] WinRT: renamed d3d11-internal struct, SDL_VertexShaderConstants, to just VertexShaderConstants This is primarily to keep naming consistent with other shader-bound structs. --- src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl | 2 +- src/render/direct3d11/SDL_render_d3d11.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl index b5cac4fa9..c625c0970 100644 --- a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl +++ b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl @@ -1,7 +1,7 @@ #pragma pack_matrix( row_major ) -cbuffer SDL_VertexShaderConstants : register(b0) +cbuffer VertexShaderConstants : register(b0) { matrix model; matrix view; diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index f5a2d0f59..a98b5a6a6 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -68,7 +68,7 @@ static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_ static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR; /* Vertex shader, common values */ -struct SDL_VertexShaderConstants +struct VertexShaderConstants { DirectX::XMFLOAT4X4 model; DirectX::XMFLOAT4X4 view; @@ -117,7 +117,7 @@ typedef struct D3D_FEATURE_LEVEL featureLevel; // Vertex buffer constants: - SDL_VertexShaderConstants vertexShaderConstantsData; + VertexShaderConstants vertexShaderConstantsData; Microsoft::WRL::ComPtr vertexShaderConstants; // Cached renderer properties. @@ -538,7 +538,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // // Setup space to hold vertex shader constants: // - CD3D11_BUFFER_DESC constantBufferDesc(sizeof(SDL_VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER); + CD3D11_BUFFER_DESC constantBufferDesc(sizeof(VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER); result = data->d3dDevice->CreateBuffer( &constantBufferDesc, nullptr, From eb6020c6bcbd3cf9aeb15fae4da6cdf1bf5c778e Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 14:20:40 -0500 Subject: [PATCH 243/264] WinRT: added a TODO note regarding texture-[un]locking in the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index a98b5a6a6..56d3ba381 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1206,6 +1206,8 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, // 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. + // + // TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated D3D11_TEXTURE2D_DESC stagingTextureDesc; textureData->mainTexture->GetDesc(&stagingTextureDesc); stagingTextureDesc.Width = rect->w; From 0975ebfe9be9fef9197369b9179507cbbe971f8d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 14:42:38 -0500 Subject: [PATCH 244/264] WinRT: prevented a potential race condition in the XInput backend The race condition could've been triggered on device removal. --- src/joystick/winrt/SDL_xinputjoystick.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/joystick/winrt/SDL_xinputjoystick.c b/src/joystick/winrt/SDL_xinputjoystick.c index 7c2853f29..1bb91b272 100644 --- a/src/joystick/winrt/SDL_xinputjoystick.c +++ b/src/joystick/winrt/SDL_xinputjoystick.c @@ -106,25 +106,27 @@ DeviceDetectionThreadMain(void * _data) */ /* See if any new devices are connected. */ + SDL_LockMutex(g_DeviceInfoLock); for (i = 0; i < XUSER_MAX_COUNT; ++i) { if (!g_XInputData[i].isDeviceConnected && !g_XInputData[i].isDeviceConnectionEventPending && !g_XInputData[i].isDeviceRemovalEventPending) { + SDL_UnlockMutex(g_DeviceInfoLock); result = XInputGetCapabilities(i, 0, &tempXInputCaps); + SDL_LockMutex(g_DeviceInfoLock); if (result == ERROR_SUCCESS) { /* Yes, a device is connected. Mark it as such. Others will be told about this (via an SDL_JOYDEVICEADDED event) in the next call to SDL_SYS_JoystickDetect. */ - SDL_LockMutex(g_DeviceInfoLock); g_XInputData[i].isDeviceConnected = SDL_TRUE; g_XInputData[i].isDeviceConnectionEventPending = SDL_TRUE; - SDL_UnlockMutex(g_DeviceInfoLock); } } } + SDL_UnlockMutex(g_DeviceInfoLock); } return 0; From c836d9ffc2560e809e4e7263ee319bb5b30b94fe Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 21:39:48 -0500 Subject: [PATCH 245/264] WinRT: compiled the d3d11 renderer's shaders into SDL itself Previously, the shaders would get compiled separately, the output of which would need to be packaged into the app. This change should make SDL's dll be the only binary needed to include SDL in a WinRT app. --- .../SDL/SDL-WinPhone_VS2012.vcxproj | 20 - .../SDL/SDL-WinPhone_VS2012.vcxproj.filters | 14 - VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 42 -- .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 14 - .../SDL_D3D11_PixelShader_FixedColor.hlsl | 12 - .../SDL_D3D11_PixelShader_TextureColored.hlsl | 14 - .../SDL_D3D11_VertexShader_Default.hlsl | 41 -- src/render/direct3d11/SDL_render_d3d11.cpp | 492 +++++++++++++++--- 8 files changed, 413 insertions(+), 236 deletions(-) delete mode 100644 src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl delete mode 100644 src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl delete mode 100644 src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj index 0f185bec2..4eaeca36b 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj @@ -397,26 +397,6 @@ true - - - Pixel - Pixel - Pixel - Pixel - - - Pixel - Pixel - Pixel - Pixel - - - Vertex - Vertex - Vertex - Vertex - - diff --git a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters index 59296bf42..9535fe759 100644 --- a/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters +++ b/VisualC-WinPhone/SDL/SDL-WinPhone_VS2012.vcxproj.filters @@ -7,9 +7,6 @@ {abc3a7e6-f955-4cb5-8340-fae0f653e9c1} - - {fd67993e-5155-488b-9313-d1eb06a1b67e} - @@ -612,15 +609,4 @@ Source Files - - - GPU Shaders - - - GPU Shaders - - - GPU Shaders - - \ No newline at end of file diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index f06787f78..a63bbc8cd 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -324,48 +324,6 @@ - - - Pixel - Pixel - Pixel - Pixel - Pixel - Pixel - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - - - Pixel - Pixel - Pixel - Pixel - Pixel - Pixel - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - - - Vertex - Vertex - Vertex - Vertex - Vertex - Vertex - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - 4.0_level_9_1 - - {aeaea3a2-d4e6-45b1-8ec6-53d84287fc14} Win32Proj diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index bff9c9deb..21ec9bb9d 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -1,16 +1,5 @@  - - - GPU Shaders - - - GPU Shaders - - - GPU Shaders - - Source Files @@ -652,8 +641,5 @@ {ddf04d85-6a87-4c5a-bc52-869b38f45a61} - - {83ed1283-8234-4c77-99a8-ffcfd8ce7381} - \ No newline at end of file diff --git a/src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl b/src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl deleted file mode 100644 index 84de709f5..000000000 --- a/src/render/direct3d11/SDL_D3D11_PixelShader_FixedColor.hlsl +++ /dev/null @@ -1,12 +0,0 @@ - -struct PixelShaderInput -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD0; - float4 color : COLOR0; -}; - -float4 main(PixelShaderInput input) : SV_TARGET -{ - return input.color; -} diff --git a/src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl b/src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl deleted file mode 100644 index 503b4fdcb..000000000 --- a/src/render/direct3d11/SDL_D3D11_PixelShader_TextureColored.hlsl +++ /dev/null @@ -1,14 +0,0 @@ -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; -} diff --git a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl b/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl deleted file mode 100644 index c625c0970..000000000 --- a/src/render/direct3d11/SDL_D3D11_VertexShader_Default.hlsl +++ /dev/null @@ -1,41 +0,0 @@ - -#pragma pack_matrix( row_major ) - -cbuffer 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; -} diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 56d3ba381..f285a644a 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -130,6 +130,395 @@ typedef struct } D3D11_RenderData; +/* Direct3D 11.x shaders + + SDL's shaders are compiled into SDL itself, to simplify distribution. + + All Direct3D 11.x shaders were compiled with the following: + + fxc /E"main" /T "" /Fo"" "" + + Variables: + - : the type of shader. A table of utilized shader types is + listed below. + - : where to store compiled output + - : where to read shader source code from + + Shader types: + - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT + - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT + - ps_4_0_level_9_3: Pixel shader for Windows Phone 8 + - vs_4_0_level_9_3: Vertex shader for Windows Phone 8 + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define D3D11_USE_SHADER_MODEL_4_0_level_9_3 +#else +#define D3D11_USE_SHADER_MODEL_4_0_level_9_1 +#endif + +/* The texture-rendering pixel shader: + + --- D3D11_PixelShader_Textures.hlsl --- + 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; + } +*/ +#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) +static const DWORD D3D11_PixelShader_Textures[] = { + 0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001, + 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, + 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, + 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, + 0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, + 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, + 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, + 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, + 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, + 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, + 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, + 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, + 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, + 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, + 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, + 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, + 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 +}; +#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) +static const DWORD D3D11_PixelShader_Textures[] = { + 0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001, + 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, + 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, + 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, + 0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000, + 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, + 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, + 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, + 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, + 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, + 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, + 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, + 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, + 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, + 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, + 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, + 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 +}; +#else +#error "An appropriate 'textures' pixel shader is not defined" +#endif + +/* The color-only-rendering pixel shader: + + --- D3D11_PixelShader_Colors.hlsl --- + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + float4 main(PixelShaderInput input) : SV_TARGET + { + return input.color; + } +*/ +#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) +static const DWORD D3D11_PixelShader_Colors[] = { + 0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001, + 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, + 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, + 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, + 0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, + 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, + 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, + 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 +}; +#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) +static const DWORD D3D11_PixelShader_Colors[] = { + 0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001, + 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, + 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, + 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, + 0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, + 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, + 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, + 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, +}; +#else +#error "An appropriate 'colors' pixel shader is not defined." +#endif + +/* The sole vertex shader: + + --- D3D11_VertexShader.hlsl --- + #pragma pack_matrix( row_major ) + + cbuffer 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; + } +*/ +#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) +static const DWORD D3D11_VertexShader[] = { + 0x43425844, 0x3f31b022, 0x2ffad8b8, 0xd6c45cbd, 0xa7894c28, 0x00000001, + 0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494, + 0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200, + 0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0200, + 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, + 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, + 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, + 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, + 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, + 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, + 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001, + 0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009, + 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001, + 0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004, + 0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, + 0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, + 0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096, + 0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072, + 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, + 0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, + 0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, + 0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, + 0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, + 0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, + 0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, + 0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, + 0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, + 0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, + 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, + 0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, + 0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001, + 0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032, + 0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, + 0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46, + 0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000, + 0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036, + 0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2, + 0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, + 0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, + 0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400, + 0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865, + 0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003, + 0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c, + 0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000, + 0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, + 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, + 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003, + 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001, + 0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002, + 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, + 0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, + 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, +}; +#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) +static const DWORD D3D11_VertexShader[] = { + 0x43425844, 0xacfd840a, 0x6a6ae1e1, 0xc3649c43, 0x8bfc0816, 0x00000001, + 0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494, + 0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200, + 0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0201, + 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, + 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, + 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, + 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, + 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, + 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, + 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001, + 0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009, + 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001, + 0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004, + 0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, + 0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, + 0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096, + 0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072, + 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, + 0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, + 0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, + 0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, + 0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, + 0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, + 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, + 0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, + 0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, + 0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, + 0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, + 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, + 0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, + 0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, + 0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001, + 0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032, + 0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, + 0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46, + 0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000, + 0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036, + 0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2, + 0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, + 0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, + 0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400, + 0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865, + 0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003, + 0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080, + 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c, + 0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000, + 0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, + 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, + 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003, + 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001, + 0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002, + 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, + 0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, + 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f +}; +#else +#error "An appropriate vertex shader is not defined." +#endif + /* Direct3D 11.1 renderer implementation */ static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags); static void D3D11_WindowEvent(SDL_Renderer * renderer, @@ -294,66 +683,6 @@ D3D11_DestroyRenderer(SDL_Renderer * renderer) } } -static bool -D3D11_ReadFileContents(const wstring & fileName, vector & 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 & 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 - // TODO, WinRT: 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 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__ ", ID3D11Device1::CreatePixelShader", result); - return result; - } - - return S_OK; -} - static HRESULT D3D11_CreateBlendMode(SDL_Renderer * renderer, BOOL enableBlending, @@ -396,12 +725,12 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // Make sure Direct3D's debugging feature gets used, if the app requests it. - const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); - if (hint) { - if (*hint == '1') { + //const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); + //if (hint) { + // if (*hint == '1') { creationFlags |= D3D11_CREATE_DEVICE_DEBUG; - } - } + // } + //} // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. @@ -481,15 +810,9 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // // Load in SDL's one and only vertex shader: // - vector 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(), + D3D11_VertexShader, + sizeof(D3D11_VertexShader), nullptr, &data->vertexShader ); @@ -511,8 +834,8 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) result = data->d3dDevice->CreateInputLayout( vertexDesc, ARRAYSIZE(vertexDesc), - &fileData[0], - fileData.size(), + D3D11_VertexShader, + sizeof(D3D11_VertexShader), &data->inputLayout ); if (FAILED(result)) { @@ -523,15 +846,26 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) // // Load in SDL's pixel shaders // - result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_TextureColored.cso", &data->texturePixelShader); + + result = data->d3dDevice->CreatePixelShader( + D3D11_PixelShader_Textures, + sizeof(D3D11_PixelShader_Textures), + nullptr, + &data->texturePixelShader + ); if (FAILED(result)) { - // D3D11_LoadPixelShader will have aleady set the SDL error + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result); return result; } - result = D3D11_LoadPixelShader(renderer, L"SDL_D3D11_PixelShader_FixedColor.cso", &data->colorPixelShader); + result = data->d3dDevice->CreatePixelShader( + D3D11_PixelShader_Colors, + sizeof(D3D11_PixelShader_Colors), + nullptr, + &data->colorPixelShader + ); if (FAILED(result)) { - // D3D11_LoadPixelShader will have aleady set the SDL error + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result); return result; } From 481dfa1d54a8480950f99356517bbcbe09690a8c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 22:05:18 -0500 Subject: [PATCH 246/264] WinRT: made sure d3d11 debug mode doesn't get enabled by default D3D11 debug mode got inadvertently enabled, in all cases, via changeset c0e68f3. This change reverts that. --- src/render/direct3d11/SDL_render_d3d11.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index f285a644a..8e094bf0f 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -725,12 +725,12 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // Make sure Direct3D's debugging feature gets used, if the app requests it. - //const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); - //if (hint) { - // if (*hint == '1') { + const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); + if (hint) { + if (*hint == '1') { creationFlags |= D3D11_CREATE_DEVICE_DEBUG; - // } - //} + } + } // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. From 0dabf1d7512ef67024da42f51f5a1ebba858dcd7 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 22:27:58 -0500 Subject: [PATCH 247/264] WinRT: d3d11 compiled-shader code cleanup I'm surprised this code even compiled, before this change. It did, but regardless, here's a cleanup. --- src/render/direct3d11/SDL_render_d3d11.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 8e094bf0f..9651c6fa4 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -319,7 +319,7 @@ static const DWORD D3D11_PixelShader_Colors[] = { 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 }; #else #error "An appropriate 'colors' pixel shader is not defined." @@ -440,7 +440,7 @@ static const DWORD D3D11_VertexShader[] = { 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, - 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, + 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f }; #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) static const DWORD D3D11_VertexShader[] = { From ccae63527b976e3b630f202879fa7659a3994642 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 23:25:25 -0500 Subject: [PATCH 248/264] WinRT: removed a bit of dead d3d11 code --- src/render/direct3d11/SDL_render_d3d11.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 9651c6fa4..fd5d66289 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -601,15 +601,7 @@ SDLPixelFormatToDXGIFormat(Uint32 sdlFormat) 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) From 51e5bb14f4dce5da65faf2e0dc9bf54c62f76838 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 23:45:07 -0500 Subject: [PATCH 249/264] WinRT: minor rotation/orientation code cleanup in the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index fd5d66289..4942a6766 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -1062,6 +1062,18 @@ D3D11_GetRotationForOrientation(Windows::Graphics::Display::DisplayOrientations } } +static bool +D3D11_IsDisplayRotated90Degrees(Windows::Graphics::Display::DisplayOrientations orientation) +{ + switch (D3D11_GetRotationForOrientation(orientation)) { + case DXGI_MODE_ROTATION_ROTATE90: + case DXGI_MODE_ROTATION_ROTATE270: + return true; + default: + return false; + } +} + // Initialize all resources that change when the window's size changes. // TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32 HRESULT @@ -1108,9 +1120,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP const bool swapDimensions = false; #else - const bool swapDimensions = - data->orientation == DisplayOrientations::Portrait || - data->orientation == DisplayOrientations::PortraitFlipped; + const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); #endif data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth; data->renderTargetSize.y = swapDimensions ? windowWidth : windowHeight; @@ -1687,16 +1697,7 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // for Windows Phone devices. // SDL_FRect orientationAlignedViewport; - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - const bool swapDimensions = - data->orientation == DisplayOrientations::Landscape || - data->orientation == DisplayOrientations::LandscapeFlipped; -#else - const bool swapDimensions = - data->orientation == DisplayOrientations::Portrait || - data->orientation == DisplayOrientations::PortraitFlipped; -#endif + const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); if (swapDimensions) { orientationAlignedViewport.x = (float) renderer->viewport.y; orientationAlignedViewport.y = (float) renderer->viewport.x; From 32da5a850089591d395f9997b6d675701d5bdd5b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 25 Dec 2013 23:46:19 -0500 Subject: [PATCH 250/264] WinRT: corrected a minor error in an end-of-file comment --- src/render/direct3d11/SDL_render_d3d11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 4942a6766..12e0cc267 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -2341,6 +2341,6 @@ D3D11_RenderPresent(SDL_Renderer * renderer) } } -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ From a408c61485841fb2c61eb29bc6ecbd7c1a81c0a0 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 10:18:33 -0500 Subject: [PATCH 251/264] WinRT: implemented SDL_RenderSetClipRect for the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 112 +++++++++++++++------ 1 file changed, 79 insertions(+), 33 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 12e0cc267..15112403c 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -113,9 +113,13 @@ typedef struct Microsoft::WRL::ComPtr blendModeMod; Microsoft::WRL::ComPtr nearestPixelSampler; Microsoft::WRL::ComPtr linearSampler; - Microsoft::WRL::ComPtr mainRasterizer; D3D_FEATURE_LEVEL featureLevel; + // Rasterizers: + // If this list starts to get unwieldy, then consider using a map<> of them. + Microsoft::WRL::ComPtr mainRasterizer; + Microsoft::WRL::ComPtr clippedRasterizer; + // Vertex buffer constants: VertexShaderConstants vertexShaderConstantsData; Microsoft::WRL::ComPtr vertexShaderConstants; @@ -918,7 +922,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) } // - // Setup the Direct3D rasterizer + // Setup Direct3D rasterizer states // D3D11_RASTERIZER_DESC rasterDesc; memset(&rasterDesc, 0, sizeof(rasterDesc)); @@ -934,7 +938,14 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) rasterDesc.SlopeScaledDepthBias = 0.0f; result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->mainRasterizer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState", result); + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result); + return result; + } + + rasterDesc.ScissorEnable = true; + result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->clippedRasterizer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result); return result; } @@ -1074,6 +1085,42 @@ D3D11_IsDisplayRotated90Degrees(Windows::Graphics::Display::DisplayOrientations } } +static int +D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect) +{ + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + switch (D3D11_GetRotationForOrientation(data-> orientation)) { + case DXGI_MODE_ROTATION_IDENTITY: + outRect->left = sdlRect->x; + outRect->right = sdlRect->x + sdlRect->w; + outRect->top = sdlRect->y; + outRect->bottom = sdlRect->y + sdlRect->h; + break; + case DXGI_MODE_ROTATION_ROTATE270: + outRect->left = sdlRect->y; + outRect->right = sdlRect->y + sdlRect->h; + outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w; + outRect->bottom = renderer->viewport.w - sdlRect->x; + break; + case DXGI_MODE_ROTATION_ROTATE180: + outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w; + outRect->right = renderer->viewport.w - sdlRect->x; + outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h; + outRect->bottom = renderer->viewport.h - sdlRect->y; + break; + case DXGI_MODE_ROTATION_ROTATE90: + outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h; + outRect->right = renderer->viewport.h - sdlRect->y; + outRect->top = sdlRect->x; + outRect->bottom = sdlRect->x + sdlRect->h; + break; + default: + return SDL_SetError("The physical display is in an unknown or unsupported orientation"); + } + return 0; +} + + // Initialize all resources that change when the window's size changes. // TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32 HRESULT @@ -1738,7 +1785,20 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) static int D3D11_UpdateClipRect(SDL_Renderer * renderer) { - // TODO, WinRT: implement D3D11_UpdateClipRect + D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + const SDL_Rect *rect = &renderer->clip_rect; + + if (SDL_RectEmpty(rect)) { + data->d3dContext->RSSetScissorRects(0, 0); + } else { + D3D11_RECT scissorRect; + if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &scissorRect) != 0) { + /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */ + return -1; + } + data->d3dContext->RSSetScissorRects(1, &scissorRect); + } + return 0; } @@ -1893,7 +1953,11 @@ D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, 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()); + if (SDL_RectEmpty(&(renderer->clip_rect))) { + rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get()); + } else { + rendererData->d3dContext->RSSetState(rendererData->clippedRasterizer.Get()); + } rendererData->d3dContext->Draw(vertexCount, 0); } @@ -2214,35 +2278,17 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, } // Copy the desired portion of the back buffer to the staging texture: - D3D11_BOX srcBox; - switch (D3D11_GetRotationForOrientation(data->orientation)) { - case DXGI_MODE_ROTATION_IDENTITY: - srcBox.left = rect->x; - srcBox.right = rect->x + rect->w; - srcBox.top = rect->y; - srcBox.bottom = rect->y + rect->h; - break; - case DXGI_MODE_ROTATION_ROTATE270: - srcBox.left = rect->y; - srcBox.right = rect->y + rect->h; - srcBox.top = renderer->viewport.w - rect->x - rect->w; - srcBox.bottom = renderer->viewport.w - rect->x; - break; - case DXGI_MODE_ROTATION_ROTATE180: - srcBox.left = renderer->viewport.w - rect->x - rect->w; - srcBox.right = renderer->viewport.w - rect->x; - srcBox.top = renderer->viewport.h - rect->y - rect->h; - srcBox.bottom = renderer->viewport.h - rect->y; - break; - case DXGI_MODE_ROTATION_ROTATE90: - srcBox.left = renderer->viewport.h - rect->y - rect->h; - srcBox.right = renderer->viewport.h - rect->y; - srcBox.top = rect->x; - srcBox.bottom = rect->x + rect->h; - break; - default: - return SDL_SetError("The physical display is in an unknown or unsupported orientation"); + D3D11_RECT srcRect; + if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect) != 0) { + /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */ + return -1; } + + D3D11_BOX srcBox; + srcBox.left = srcRect.left; + srcBox.right = srcRect.right; + srcBox.top = srcRect.top; + srcBox.bottom = srcRect.bottom; srcBox.front = 0; srcBox.back = 1; data->d3dContext->CopySubresourceRegion( From fd6014b877dab983d8a0fcec577b36378ee1386c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 11:03:43 -0500 Subject: [PATCH 252/264] WinRT: simplified the d3d11 vertex shader a bit The projection and view matrices are now computed ahead of time, as they both get computed in the same spot, and typically not often. If this does, however, become a performance problem later on, this change can always be reverted. --- src/render/direct3d11/SDL_render_d3d11.cpp | 276 ++++++++++----------- 1 file changed, 133 insertions(+), 143 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 15112403c..497c56356 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -71,8 +71,7 @@ static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LIN struct VertexShaderConstants { DirectX::XMFLOAT4X4 model; - DirectX::XMFLOAT4X4 view; - DirectX::XMFLOAT4X4 projection; + DirectX::XMFLOAT4X4 projectionAndView; }; /* Per-vertex data */ @@ -153,6 +152,12 @@ typedef struct - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT - ps_4_0_level_9_3: Pixel shader for Windows Phone 8 - vs_4_0_level_9_3: Vertex shader for Windows Phone 8 + + + Shader object code was converted to a list of DWORDs via the following + *nix style command (available separately from Windows + MSVC): + + hexdump -v -e '6/4 "0x%08.8x, " "\n"' */ #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP #define D3D11_USE_SHADER_MODEL_4_0_level_9_3 @@ -337,8 +342,7 @@ static const DWORD D3D11_PixelShader_Colors[] = { cbuffer VertexShaderConstants : register(b0) { matrix model; - matrix view; - matrix projection; + matrix projectionAndView; }; struct VertexShaderInput @@ -362,8 +366,7 @@ static const DWORD D3D11_PixelShader_Colors[] = { // Transform the vertex position into projected space. pos = mul(pos, model); - pos = mul(pos, view); - pos = mul(pos, projection); + pos = mul(pos, projectionAndView); output.pos = pos; // Pass through texture coordinates and color values without transformation @@ -375,11 +378,11 @@ static const DWORD D3D11_PixelShader_Colors[] = { */ #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) static const DWORD D3D11_VertexShader[] = { - 0x43425844, 0x3f31b022, 0x2ffad8b8, 0xd6c45cbd, 0xa7894c28, 0x00000001, - 0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494, - 0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200, - 0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, - 0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0200, + 0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001, + 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, + 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, + 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200, 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, @@ -387,72 +390,62 @@ static const DWORD D3D11_VertexShader[] = { 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, - 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001, - 0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009, - 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001, - 0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004, - 0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, - 0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, - 0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096, - 0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072, - 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, - 0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, - 0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, - 0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, - 0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, - 0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, - 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, - 0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, - 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, - 0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, - 0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, - 0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, - 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, - 0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, - 0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, - 0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001, - 0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032, - 0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, - 0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, - 0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46, - 0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000, - 0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036, - 0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2, - 0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, - 0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000, - 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, + 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, + 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, + 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, + 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, + 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, + 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, + 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, + 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, + 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, + 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, + 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, + 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, + 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, - 0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400, - 0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865, - 0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003, - 0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c, - 0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000, - 0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, - 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, - 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003, - 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000, - 0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001, - 0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002, - 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, - 0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, - 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, - 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065, - 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, - 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, + 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, + 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, + 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, + 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, + 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, + 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, + 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, + 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, + 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, + 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f }; #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) static const DWORD D3D11_VertexShader[] = { - 0x43425844, 0xacfd840a, 0x6a6ae1e1, 0xc3649c43, 0x8bfc0816, 0x00000001, - 0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494, - 0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200, - 0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, - 0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0201, + 0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001, + 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, + 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, + 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201, 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, @@ -460,64 +453,54 @@ static const DWORD D3D11_VertexShader[] = { 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, - 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001, - 0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009, - 0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001, - 0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004, - 0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, - 0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, - 0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096, - 0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072, - 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, - 0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, - 0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, - 0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, - 0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, - 0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, - 0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, - 0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, - 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, - 0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, - 0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, - 0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, - 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, - 0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, - 0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, - 0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001, - 0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032, - 0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, - 0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001, - 0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46, - 0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000, - 0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036, - 0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2, - 0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, - 0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000, - 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, + 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, + 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, + 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, + 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, + 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, + 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, + 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, + 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, + 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, + 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, + 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, + 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, + 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, - 0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400, - 0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865, - 0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003, - 0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080, - 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c, - 0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000, - 0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, - 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, - 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003, - 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000, - 0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001, - 0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002, - 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, - 0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, - 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, - 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065, - 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, - 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, + 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, + 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, + 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, + 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, + 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, + 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, + 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, + 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, + 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, + 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f }; #else #error "An appropriate vertex shader is not defined." @@ -1698,19 +1681,20 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // Keep in mind here that the Y-axis will be been inverted (from Direct3D's // default coordinate system) so rotations will be done in the opposite // direction of the DXGI_MODE_ROTATION enumeration. + DirectX::XMMATRIX projection; switch (D3D11_GetRotationForOrientation(data->orientation)) { case DXGI_MODE_ROTATION_IDENTITY: - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity()); + projection = XMMatrixIdentity(); break; case DXGI_MODE_ROTATION_ROTATE270: - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2)); + projection = XMMatrixRotationZ(XM_PIDIV2); break; case DXGI_MODE_ROTATION_ROTATE180: - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI)); + projection = XMMatrixRotationZ(XM_PI); break; case DXGI_MODE_ROTATION_ROTATE90: - XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2)); + projection = XMMatrixRotationZ(-XM_PIDIV2); break; default: return SDL_SetError("An unknown DisplayOrientation is being used"); @@ -1721,16 +1705,22 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // float viewportWidth = (float) renderer->viewport.w; float viewportHeight = (float) renderer->viewport.h; - XMStoreFloat4x4(&data->vertexShaderConstantsData.view, + DirectX::XMMATRIX view = XMMatrixMultiply( + XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f), 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 + XMMatrixTranslation(-1, -1, 0), + XMMatrixRotationX(XM_PI) + )); + + // + // Combine the projection + view matrix together now, as both only get + // set here (as of this writing, on Dec 26, 2013). When done, store it + // for eventual transfer to the GPU. + // + XMStoreFloat4x4(&data->vertexShaderConstantsData.projectionAndView, + XMMatrixMultiply( + view, + projection)); // // Reset the model matrix From ad7caf326711d7c0f6ac8227aba1f18524f0d91b Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 11:04:35 -0500 Subject: [PATCH 253/264] WinRT: minor header file usage cleanup in the d3d11 renderer --- src/render/direct3d11/SDL_render_d3d11.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 497c56356..02f7f4f79 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -36,16 +36,12 @@ 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 #include #include From 64014dc3d8fda5af1d7f089899513a004cb54cf1 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 13:59:01 -0500 Subject: [PATCH 254/264] WinRT: fixed crash on ARM and x64 during OpenGL window init --- src/video/winrt/SDL_winrtvideo.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 180528373..900767fe9 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -266,8 +266,27 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) data->egl_surface = EGL_NO_SURFACE; } else { /* OpenGL ES 2 was reuqested. Set up an EGL surface. */ - IUnknown * nativeWindow = reinterpret_cast(data->coreWindow.Get()); - data->egl_surface = SDL_EGL_CreateSurface(_this, nativeWindow); + + /* HACK: ANGLE/WinRT currently uses non-pointer, C++ objects to represent + native windows. The object only contains a single pointer to a COM + interface pointer, which on x86 appears to be castable to the object + without apparant problems. On other platforms, notable ARM and x64, + doing so will cause a crash. To avoid this crash, we'll bypass + SDL's normal call to eglCreateWindowSurface, which is invoked from C + code, and call it here, where an appropriate C++ object may be + passed in. + */ + typedef EGLSurface (*eglCreateWindowSurfaceFunction)(EGLDisplay dpy, EGLConfig config, + Microsoft::WRL::ComPtr win, + const EGLint *attrib_list); + eglCreateWindowSurfaceFunction WINRT_eglCreateWindowSurface = + (eglCreateWindowSurfaceFunction) _this->egl_data->eglCreateWindowSurface; + + Microsoft::WRL::ComPtr nativeWindow = reinterpret_cast(data->coreWindow.Get()); + data->egl_surface = WINRT_eglCreateWindowSurface( + _this->egl_data->egl_display, + _this->egl_data->egl_config, + nativeWindow, NULL); if (data->egl_surface == NULL) { // TODO, WinRT: see if SDL_EGL_CreateSurface, or its callee(s), sets an error message. If so, attach it to the SDL error. return SDL_SetError("SDL_EGL_CreateSurface failed"); From 4472396559700896af2e1854b599c658c0f3112c Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 14:13:20 -0500 Subject: [PATCH 255/264] WinRT: took out some dead comments from SDL_winrtopengles.cpp --- src/video/winrt/SDL_winrtopengles.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/video/winrt/SDL_winrtopengles.cpp b/src/video/winrt/SDL_winrtopengles.cpp index bbb73d7e0..f6cdeaec6 100644 --- a/src/video/winrt/SDL_winrtopengles.cpp +++ b/src/video/winrt/SDL_winrtopengles.cpp @@ -26,11 +26,6 @@ /* EGL implementation of SDL OpenGL support */ -// TODO, WinRT: Try to include these here, or via something else (rather than redefining key parts of them) -//#include -//#include -//#include - #include "SDL_winrtvideo_cpp.h" extern "C" { #include "SDL_winrtopengles.h" From 5264f889eb91b9c92e92a2594ac733d49e18453f Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Thu, 26 Dec 2013 14:21:47 -0500 Subject: [PATCH 256/264] WinRT: minor error cleanup regarding OpenGL init --- src/video/winrt/SDL_winrtvideo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 900767fe9..ba1fd2f1e 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -288,8 +288,8 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) _this->egl_data->egl_config, nativeWindow, NULL); if (data->egl_surface == NULL) { - // TODO, WinRT: see if SDL_EGL_CreateSurface, or its callee(s), sets an error message. If so, attach it to the SDL error. - return SDL_SetError("SDL_EGL_CreateSurface failed"); + // TODO, WinRT: see if eglCreateWindowSurface, or its callee(s), sets an error message. If so, attach it to the SDL error. + return SDL_SetError("eglCreateWindowSurface failed"); } } #endif From 02d00dd07d229db858e5374e7b5a36d89f5122d4 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 30 Dec 2013 11:59:04 -0500 Subject: [PATCH 257/264] WinRT: d3d11 blend mode bug fixes The destination target's alpha wasn't getting set correctly in many cases. Among other problems, this prevented some alpha-blended textures from displaying correctly in Windows Phone 8's multitasking screen. The d3d11 renderer now uses the same blending settings found in the d3d9 renderer. --- src/render/direct3d11/SDL_render_d3d11.cpp | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 02f7f4f79..319b5c910 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -663,6 +663,8 @@ D3D11_CreateBlendMode(SDL_Renderer * renderer, BOOL enableBlending, D3D11_BLEND srcBlend, D3D11_BLEND destBlend, + D3D11_BLEND srcBlendAlpha, + D3D11_BLEND destBlendAlpha, ID3D11BlendState ** blendStateOutput) { D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; @@ -676,8 +678,8 @@ D3D11_CreateBlendMode(SDL_Renderer * renderer, 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].SrcBlendAlpha = srcBlendAlpha; + blendDesc.RenderTarget[0].DestBlendAlpha = destBlendAlpha; blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; result = data->d3dDevice->CreateBlendState(&blendDesc, blendStateOutput); @@ -934,8 +936,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) result = D3D11_CreateBlendMode( renderer, TRUE, - D3D11_BLEND_SRC_ALPHA, - D3D11_BLEND_INV_SRC_ALPHA, + D3D11_BLEND_SRC_ALPHA, /* srcBlend */ + D3D11_BLEND_INV_SRC_ALPHA, /* destBlend */ + D3D11_BLEND_ONE, /* srcBlendAlpha */ + D3D11_BLEND_INV_SRC_ALPHA, /* destBlendAlpha */ &data->blendModeBlend); if (FAILED(result)) { // D3D11_CreateBlendMode will set the SDL error, if it fails @@ -945,8 +949,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) result = D3D11_CreateBlendMode( renderer, TRUE, - D3D11_BLEND_SRC_ALPHA, - D3D11_BLEND_ONE, + D3D11_BLEND_SRC_ALPHA, /* srcBlend */ + D3D11_BLEND_ONE, /* destBlend */ + D3D11_BLEND_ZERO, /* srcBlendAlpha */ + D3D11_BLEND_ONE, /* destBlendAlpha */ &data->blendModeAdd); if (FAILED(result)) { // D3D11_CreateBlendMode will set the SDL error, if it fails @@ -956,8 +962,10 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) result = D3D11_CreateBlendMode( renderer, TRUE, - D3D11_BLEND_ZERO, - D3D11_BLEND_SRC_COLOR, + D3D11_BLEND_ZERO, /* srcBlend */ + D3D11_BLEND_SRC_COLOR, /* destBlend */ + D3D11_BLEND_ZERO, /* srcBlendAlpha */ + D3D11_BLEND_ONE, /* destBlendAlpha */ &data->blendModeMod); if (FAILED(result)) { // D3D11_CreateBlendMode will set the SDL error, if it fails From 4c397e686a22bc9721ab7a3df0612b5cad10dda6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Wed, 1 Jan 2014 16:05:37 -0500 Subject: [PATCH 258/264] WinRT: added a means to display a privacy policy link via the Settings charm This change is only relevant for Windows 8, 8.1, and RT apps, and only for those that are network-enabled. Such apps must feature a link to a privacy policy, which must be displayed via the Windows Settings charm. This is needed to pass Windows Store app-certification. Using SDL_SetHint, along with SDL_HINT_WINRT_PRIVACY_POLICY_URL and optionally SDL_HINT_WINRT_PRIVACY_POLICY_LABEL, will cause SDL/WinRT to create a link inside the Windows Settings charm, as invoked from within an SDL-based app. Network-enabled Windows Phone apps do not need to set this hint, and should provide some sort of in-app means to display their privacy policy. Microsoft does not appear to provide an OS-integrated means for displaying such on Windows Phone. --- include/SDL_hints.h | 47 ++++++++++++++++++++ src/core/winrt/SDL_winrtapp_direct3d.cpp | 55 ++++++++++++++++++++++++ src/core/winrt/SDL_winrtapp_direct3d.h | 7 +++ 3 files changed, 109 insertions(+) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 9ca009778..57dc8507b 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -331,6 +331,53 @@ extern "C" { */ #define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_HINT_WINRT_PRIVACY_POLICY_URL" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with it's label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init. + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL" + /** * \brief An enumeration of hint priorities */ diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 05a748727..cb095e2be 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -34,6 +34,7 @@ extern "C" { #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_windowevents_c.h" #include "../../render/SDL_sysrender.h" +#include "../windows/SDL_windows.h" } #include "../../video/winrt/SDL_winrtevents_c.h" @@ -314,6 +315,16 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->KeyUp += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) + // Make sure we know when a user has opened the app's settings pane. + // This is needed in order to display a privacy policy, which needs + // to be done for network-enabled apps, as per Windows Store requirements. + using namespace Windows::UI::ApplicationSettings; + SettingsPane::GetForCurrentView()->CommandsRequested += + ref new TypedEventHandler + (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); +#endif } void SDL_WinRTApp::Load(Platform::String^ entryPoint) @@ -352,6 +363,50 @@ void SDL_WinRTApp::Uninitialize() { } +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +void SDL_WinRTApp::OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args) +{ + using namespace Platform; + using namespace Windows::UI::ApplicationSettings; + using namespace Windows::UI::Popups; + + String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy + String ^privacyPolicyLabel = nullptr; // label/link text + const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately + wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion + + // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint): + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + // Convert the privacy policy's URL to UCS2: + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyURL = ref new String(tmpStr); + SDL_free(tmpStr); + + // Optionally retrieve custom label-text for the link. If this isn't + // available, a default value will be used instead. + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyLabel = ref new String(tmpStr); + SDL_free(tmpStr); + } else { + privacyPolicyLabel = ref new String(L"Privacy Policy"); + } + + // Register the link, along with a handler to be called if and when it is + // clicked: + auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel, + ref new UICommandInvokedHandler([=](IUICommand ^) { + Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); + })); + args->Request->ApplicationCommands->Append(cmd); + } +} +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP + void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { #if LOG_WINDOW_EVENTS==1 diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index 837afdca6..3aed74de1 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -22,6 +22,13 @@ internal: protected: // Event Handlers. + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) + void OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args); +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP + void OnOrientationChanged(Platform::Object^ sender); void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); void OnLogicalDpiChanged(Platform::Object^ sender); From 40b6f9290b67f1221fac16abd2d86c1312d4dc08 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sun, 26 Jan 2014 08:06:36 -0500 Subject: [PATCH 259/264] WinRT: simulate keyboard events on Windows Phone 8 back-button presses Pressing the hardware back button on a Windows Phone 8 device will now cause SDL to emit a pair of key-down and key-up events, with the SDL scancode, SDL_SCANCODE_AC_BACK. By default, if WinRT's native back-button-press events are not explicitly marked as 'handled', then Windows Phone will terminate the app. More details on Microsoft's reasoning behind this can be found on MSDN, at http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx To mark back-button-press events as 'handled', set SDL_HINT_WINRT_HANDLE_BACK_BUTTON to 1. Setting it to anything else will cause these events to not be marked as 'handled'. Due to limitations in Windows Phone's APIs, SDL will emit a virtual key-up event immediately after the back button's key-down event is registered. Unfortunately, Windows Phone 8 only allows one to register for back-button-press events, and not back-button-release events. --- include/SDL_hints.h | 9 ++++++++ src/core/winrt/SDL_winrtapp_direct3d.cpp | 26 ++++++++++++++++++++++++ src/core/winrt/SDL_winrtapp_direct3d.h | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 57dc8507b..abd148309 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -378,6 +378,15 @@ extern "C" { */ #define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL" +/** \brief If set to 1, back button press events on Windows Phone 8+ will be marked as handled. + * + * TODO, WinRT: document SDL_HINT_WINRT_HANDLE_BACK_BUTTON need and use + * For now, more details on why this is needed can be found at the + * beginning of the following web page: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_HINT_WINRT_HANDLE_BACK_BUTTON" + /** * \brief An enumeration of hint priorities */ diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index cb095e2be..3b712bf23 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -19,6 +19,10 @@ using namespace Windows::System; using namespace Windows::UI::Core; using namespace Windows::UI::Input; +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +using namespace Windows::Phone::UI::Input; +#endif + /* SDL includes */ extern "C" { @@ -31,6 +35,7 @@ extern "C" { #include "SDL_render.h" #include "../../video/SDL_sysvideo.h" //#include "../../SDL_hints_c.h" +#include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_windowevents_c.h" #include "../../render/SDL_sysrender.h" @@ -316,6 +321,11 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window) window->KeyUp += ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + HardwareButtons::BackPressed += + ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); +#endif + #if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) // Make sure we know when a user has opened the app's settings pane. // This is needed in order to display a privacy policy, which needs @@ -597,3 +607,19 @@ void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::C { WINRT_ProcessKeyUpEvent(args); } + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args) +{ + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK); + + const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON); + if (hint) { + if (*hint == '1') { + args->Handled = true; + } + } +} +#endif + diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index 3aed74de1..43f9ffb9d 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -45,6 +45,10 @@ protected: void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); +#endif + private: bool m_windowClosed; bool m_windowVisible; From 582a189bc460cb166a3d0220bdaa37a176c3e286 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 1 Mar 2014 16:08:16 -0500 Subject: [PATCH 260/264] WinRT: fixed a crash in SDL_Quit SDL was expected that each SDL_DisplayMode had a driverdata field that was SDL_malloc'ed, and was calling SDL_free on them. This change moves WinRT's driverdata content into a SDL_malloc'ed field. --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 25 +++++++-- src/video/winrt/SDL_winrtvideo.cpp | 67 +++++++++++++++++------- src/video/winrt/SDL_winrtvideo_cpp.h | 22 ++++++-- 3 files changed, 88 insertions(+), 26 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 3b712bf23..a649432d2 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -157,8 +157,15 @@ WINRT_ProcessWindowSizeChange() // 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. - SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow(); + SDL_DisplayMode resizedDisplayMode; + if (WINRT_CalcDisplayModeUsingNativeWindow(&resizedDisplayMode) != 0) { + return; + } + if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) { + if (resizedDisplayMode.driverdata) { + SDL_free(resizedDisplayMode.driverdata); + } return; } @@ -166,8 +173,14 @@ WINRT_ProcessWindowSizeChange() SDL_zero(oldDisplayMode); if (WINRT_GlobalSDLVideoDevice) { oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode; + if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode), &resizedDisplayMode) != 0) { + SDL_free(resizedDisplayMode.driverdata); + return; + } WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; - WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode; + if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) { + SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata); + } WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; } @@ -184,8 +197,8 @@ WINRT_ProcessWindowSizeChange() // Landscape to LandscapeFlipped, Portrait to PortraitFlipped, // or vice-versa on either of those two, lead to the Direct3D renderer // getting updated. - const DisplayOrientations oldOrientation = (DisplayOrientations) (unsigned int) oldDisplayMode.driverdata; - const DisplayOrientations newOrientation = (DisplayOrientations) (unsigned int) resizedDisplayMode.driverdata; + const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation; + const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)resizedDisplayMode.driverdata)->currentOrientation; if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) || (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) || @@ -212,6 +225,10 @@ WINRT_ProcessWindowSizeChange() } #endif } + + if (oldDisplayMode.driverdata) { + SDL_free(oldDisplayMode.driverdata); + } } SDL_WinRTApp::SDL_WinRTApp() : diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index ba1fd2f1e..66993916c 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -147,33 +147,42 @@ WINRT_VideoInit(_THIS) return 0; } -SDL_DisplayMode -WINRT_CalcDisplayModeUsingNativeWindow() +int +WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) { + SDL_DisplayModeData * driverdata; + using namespace Windows::Graphics::Display; - // Create an empty, zeroed-out display mode: - SDL_DisplayMode mode; - SDL_zero(mode); + // Initialize the mode to all zeros: + SDL_zerop(mode); // Go no further if a native window cannot be accessed. This can happen, // for example, if this function is called from certain threads, such as // the SDL/XAML thread. if (!CoreWindow::GetForCurrentThread()) { - return mode; + return SDL_SetError("SDL/WinRT display modes cannot be calculated outside of the main thread, such as in SDL's XAML thread"); } + // Create a driverdata field: + driverdata = (SDL_DisplayModeData *) SDL_malloc(sizeof(*driverdata)); + if (!driverdata) { + return SDL_OutOfMemory(); + } + SDL_zerop(driverdata); + // 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 = (void *) DisplayProperties::CurrentOrientation; + 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 = driverdata; + driverdata->currentOrientation = DisplayProperties::CurrentOrientation; // 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); + mode->w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch); + mode->h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // On Windows Phone, the native window's size is always in portrait, @@ -186,32 +195,52 @@ WINRT_CalcDisplayModeUsingNativeWindow() case DisplayOrientations::Landscape: case DisplayOrientations::LandscapeFlipped: { - const int tmp = mode.h; - mode.h = mode.w; - mode.w = tmp; + const int tmp = mode->h; + mode->h = mode->w; + mode->w = tmp; break; } default: break; } - - // Attach the mode to te #endif - return mode; + return 0; +} + +int +WINRT_DuplicateDisplayMode(SDL_DisplayMode * dest, const SDL_DisplayMode * src) +{ + SDL_DisplayModeData * driverdata; + driverdata = (SDL_DisplayModeData *) SDL_malloc(sizeof(*driverdata)); + if (!driverdata) { + return SDL_OutOfMemory(); + } + SDL_memcpy(driverdata, src->driverdata, sizeof(SDL_DisplayModeData)); + SDL_memcpy(dest, src, sizeof(SDL_DisplayMode)); + dest->driverdata = driverdata; + return 0; } int WINRT_InitModes(_THIS) { // Retrieve the display mode: - SDL_DisplayMode mode = WINRT_CalcDisplayModeUsingNativeWindow(); + SDL_DisplayMode mode, desktop_mode; + if (WINRT_CalcDisplayModeUsingNativeWindow(&mode) != 0) { + return -1; // If WINRT_CalcDisplayModeUsingNativeWindow fails, it'll already have set the SDL error + } + if (mode.w == 0 || mode.h == 0) { + SDL_free(mode.driverdata); return SDL_SetError("Unable to calculate the WinRT window/display's size"); } - if (SDL_AddBasicVideoDisplay(&mode) < 0) { + if (WINRT_DuplicateDisplayMode(&desktop_mode, &mode) != 0) { + return -1; + } + if (SDL_AddBasicVideoDisplay(&desktop_mode) < 0) { return -1; } diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index 15c731e24..0c2cb1154 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -44,9 +44,25 @@ extern SDL_Window * WINRT_GlobalSDLWindow; /* The global, WinRT, video device. */ extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; -/* Computes the current display mode for Plain Direct3D (non-XAML) apps */ -extern SDL_DisplayMode WINRT_CalcDisplayModeUsingNativeWindow(); - +/* Creates a display mode for Plain Direct3D (non-XAML) apps, using the lone, native window's settings. + + Pass in an allocated SDL_DisplayMode field to store the data in. + + This function will return 0 on success, -1 on failure. + + If this function succeeds, be sure to call SDL_free on the + SDL_DisplayMode's driverdata field. +*/ +extern int WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode); + +/* Duplicates a display mode, copying over driverdata as necessary */ +extern int WINRT_DuplicateDisplayMode(SDL_DisplayMode * dest, const SDL_DisplayMode * src); + +/* Display mode internals */ +typedef struct +{ + Windows::Graphics::Display::DisplayOrientations currentOrientation; +} SDL_DisplayModeData; #ifdef __cplusplus_winrt From 65f91d101f98c80bbcf308a598c2487bfdb1aa63 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 1 Mar 2014 16:37:30 -0500 Subject: [PATCH 261/264] WinRT: cleaned up some hard-to-read SDL_DisplayMode management code --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 56 ++++++++++++++---------- src/video/winrt/SDL_winrtvideo.cpp | 28 ++++++------ 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index a649432d2..d48430066 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -157,31 +157,39 @@ WINRT_ProcessWindowSizeChange() // 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. - SDL_DisplayMode resizedDisplayMode; - if (WINRT_CalcDisplayModeUsingNativeWindow(&resizedDisplayMode) != 0) { - return; - } - - if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) { - if (resizedDisplayMode.driverdata) { - SDL_free(resizedDisplayMode.driverdata); - } + SDL_DisplayMode newDisplayMode; + if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) { return; } + // Make note of the old display mode, and it's old driverdata. SDL_DisplayMode oldDisplayMode; SDL_zero(oldDisplayMode); if (WINRT_GlobalSDLVideoDevice) { oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode; - if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode), &resizedDisplayMode) != 0) { - SDL_free(resizedDisplayMode.driverdata); + } + + // Setup the new display mode in the appropriate spots. + if (WINRT_GlobalSDLVideoDevice) { + // Make a full copy of the display mode for display_modes[0], + // one with with a separately malloced 'driverdata' field. + // SDL_VideoQuit(), if called, will attempt to free the driverdata + // fields in 'desktop_mode' and each entry in the 'display_modes' + // array. + if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) { + // Free the previous mode's memory + SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata); + WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL; + } + if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) { + // Uh oh, something went wrong. A malloc call probably failed. + SDL_free(newDisplayMode.driverdata); return; } - WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode; - if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) { - SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata); - } - WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode; + + // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'. + WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode; } if (WINRT_GlobalSDLWindow) { @@ -189,8 +197,8 @@ WINRT_ProcessWindowSizeChange() SDL_SendWindowEvent( WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESIZED, - resizedDisplayMode.w, - resizedDisplayMode.h); + newDisplayMode.w, + newDisplayMode.h); #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // HACK: On Windows Phone, make sure that orientation changes from @@ -198,7 +206,7 @@ WINRT_ProcessWindowSizeChange() // or vice-versa on either of those two, lead to the Direct3D renderer // getting updated. const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation; - const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)resizedDisplayMode.driverdata)->currentOrientation; + const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation; if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) || (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) || @@ -213,21 +221,23 @@ WINRT_ProcessWindowSizeChange() // Make sure that the display/window size really didn't change. If // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and // the Direct3D 11.1 renderer picked it up, presumably. - if (oldDisplayMode.w == resizedDisplayMode.w && - oldDisplayMode.h == resizedDisplayMode.h) + if (oldDisplayMode.w == newDisplayMode.w && + oldDisplayMode.h == newDisplayMode.h) { SDL_SendWindowEvent( WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SIZE_CHANGED, - resizedDisplayMode.w, - resizedDisplayMode.h); + newDisplayMode.w, + newDisplayMode.h); } } #endif } + // Finally, free the 'driverdata' field of the old 'desktop_mode'. if (oldDisplayMode.driverdata) { SDL_free(oldDisplayMode.driverdata); + oldDisplayMode.driverdata = NULL; } } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 66993916c..d5f467960 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -154,9 +154,6 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) using namespace Windows::Graphics::Display; - // Initialize the mode to all zeros: - SDL_zerop(mode); - // Go no further if a native window cannot be accessed. This can happen, // for example, if this function is called from certain threads, such as // the SDL/XAML thread. @@ -164,6 +161,16 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) return SDL_SetError("SDL/WinRT display modes cannot be calculated outside of the main thread, such as in SDL's XAML thread"); } + // 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; + const int w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch); + const int h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch); + if (w == 0 || w == h) { + return SDL_SetError("Unable to calculate the WinRT window/display's size"); + } + // Create a driverdata field: driverdata = (SDL_DisplayModeData *) SDL_malloc(sizeof(*driverdata)); if (!driverdata) { @@ -172,18 +179,14 @@ WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode) SDL_zerop(driverdata); // Fill in most fields: + SDL_zerop(mode); mode->format = SDL_PIXELFORMAT_RGB888; mode->refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps) + mode->w = w; + mode->h = h; mode->driverdata = driverdata; driverdata->currentOrientation = DisplayProperties::CurrentOrientation; - // 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); - #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // On Windows Phone, the native window's size is always in portrait, // regardless of the device's orientation. This is in contrast to @@ -231,11 +234,6 @@ WINRT_InitModes(_THIS) if (WINRT_CalcDisplayModeUsingNativeWindow(&mode) != 0) { return -1; // If WINRT_CalcDisplayModeUsingNativeWindow fails, it'll already have set the SDL error } - - if (mode.w == 0 || mode.h == 0) { - SDL_free(mode.driverdata); - return SDL_SetError("Unable to calculate the WinRT window/display's size"); - } if (WINRT_DuplicateDisplayMode(&desktop_mode, &mode) != 0) { return -1; From e5e0e486fe87300f37e52d685063b8af5eb2901a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 4 Mar 2014 19:30:36 -0500 Subject: [PATCH 262/264] WinRT: emit SDL_APP_WILLENTER* and SDL_APP_DIDENTER* events --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index d48430066..ec9441ad9 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -35,6 +35,7 @@ extern "C" { #include "SDL_render.h" #include "../../video/SDL_sysvideo.h" //#include "../../SDL_hints_c.h" +#include "../../events/SDL_events_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_windowevents_c.h" @@ -547,12 +548,19 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently) SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); } + + SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); + SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); + deferral->Complete(); }); } void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) { + SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); + SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); + // 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. From 780830080bae43dc219980960b6618915395b19d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Tue, 4 Mar 2014 19:49:11 -0500 Subject: [PATCH 263/264] WinRT: emit SDL_APP_TERMINATING --- src/core/winrt/SDL_winrtapp_direct3d.cpp | 8 ++++++++ src/core/winrt/SDL_winrtapp_direct3d.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index ec9441ad9..3870d77ed 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -259,6 +259,9 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Resuming += ref new EventHandler(this, &SDL_WinRTApp::OnResuming); + CoreApplication::Exiting += + ref new EventHandler(this, &SDL_WinRTApp::OnExiting); + DisplayProperties::OrientationChanged += ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged); @@ -578,6 +581,11 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) } } +void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) +{ + SDL_SendAppEvent(SDL_APP_TERMINATING); +} + static void WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) { diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index 43f9ffb9d..fcf37a149 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -35,6 +35,7 @@ protected: 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 OnExiting(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); From 211b54deef93ad1b448ac6e89fdd6e5309ef9449 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 9 Mar 2014 11:06:11 -0700 Subject: [PATCH 264/264] Fixed line endings on WinRT source code --- include/SDL_config_winrt.h | 6 +- include/SDL_egl.h | 4 +- include/SDL_main.h | 2 +- include/SDL_platform.h | 336 +- include/SDL_system.h | 370 +- include/begin_code.h | 280 +- src/SDL_log.c | 878 +-- src/atomic/SDL_spinlock.c | 252 +- src/audio/xaudio2/SDL_xaudio2.c | 1086 +-- .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 138 +- src/audio/xaudio2/SDL_xaudio2_winrthelpers.h | 104 +- src/core/winrt/SDL_winrtapp_common.cpp | 30 +- src/core/winrt/SDL_winrtapp_common.h | 18 +- src/core/winrt/SDL_winrtapp_direct3d.cpp | 1326 ++-- src/core/winrt/SDL_winrtapp_direct3d.h | 116 +- src/file/SDL_rwops.c | 1530 ++-- src/filesystem/winrt/SDL_sysfilesystem.cpp | 308 +- src/joystick/SDL_gamecontroller.c | 2494 +++---- src/main/winrt/SDL_winrt_main_NonXAML.cpp | 112 +- src/render/direct3d11/SDL_render_d3d11.cpp | 3128 ++++---- src/thread/stdcpp/SDL_systhread.cpp | 22 +- src/timer/windows/SDL_systimer.c | 22 +- src/video/SDL_sysvideo.h | 802 +- src/video/SDL_video.c | 6586 ++++++++--------- src/video/winrt/SDL_winrtevents.cpp | 180 +- src/video/winrt/SDL_winrtevents_c.h | 6 +- src/video/winrt/SDL_winrtkeyboard.cpp | 600 +- src/video/winrt/SDL_winrtmouse.cpp | 332 +- src/video/winrt/SDL_winrtopengles.cpp | 100 +- src/video/winrt/SDL_winrtopengles.h | 96 +- src/video/winrt/SDL_winrtpointerinput.cpp | 706 +- src/video/winrt/SDL_winrtvideo.cpp | 18 +- src/video/winrt/SDL_winrtvideo_cpp.h | 50 +- test/loopwave.c | 288 +- test/testthread.c | 198 +- 35 files changed, 11262 insertions(+), 11262 deletions(-) diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index b99520544..2d9258132 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -166,9 +166,9 @@ typedef unsigned int uintptr_t; #define SDL_VIDEO_DRIVER_WINRT 1 #define SDL_VIDEO_DRIVER_DUMMY 1 -/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */ -#define SDL_VIDEO_OPENGL_ES2 1 +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */ +#define SDL_VIDEO_OPENGL_ES2 1 #define SDL_VIDEO_OPENGL_EGL 1 #endif diff --git a/include/SDL_egl.h b/include/SDL_egl.h index 5a1bc374b..ec6eb105c 100644 --- a/include/SDL_egl.h +++ b/include/SDL_egl.h @@ -393,8 +393,8 @@ typedef enum { #if __WINRT__ #include -typedef IUnknown * EGLNativeWindowType; -typedef int EGLNativeDisplayType; +typedef IUnknown * EGLNativeWindowType; +typedef int EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; #else typedef HDC EGLNativeDisplayType; diff --git a/include/SDL_main.h b/include/SDL_main.h index a8969810b..97ed0cf08 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -140,7 +140,7 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more * information on the failure. */ -extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel); +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel); #endif /* __WINRT__ */ diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 8cddb432d..333044775 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -1,168 +1,168 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ - -/** - * \file SDL_platform.h - * - * Try to get a standard set of platform defines. - */ - -#ifndef _SDL_platform_h -#define _SDL_platform_h - -#if defined(_AIX) -#undef __AIX__ -#define __AIX__ 1 -#endif -#if defined(__HAIKU__) -#undef __HAIKU__ -#define __HAIKU__ 1 -#endif -#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) -#undef __BSDI__ -#define __BSDI__ 1 -#endif -#if defined(_arch_dreamcast) -#undef __DREAMCAST__ -#define __DREAMCAST__ 1 -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) -#undef __FREEBSD__ -#define __FREEBSD__ 1 -#endif -#if defined(hpux) || defined(__hpux) || defined(__hpux__) -#undef __HPUX__ -#define __HPUX__ 1 -#endif -#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) -#undef __IRIX__ -#define __IRIX__ 1 -#endif -#if defined(linux) || defined(__linux) || defined(__linux__) -#undef __LINUX__ -#define __LINUX__ 1 -#endif -#if defined(ANDROID) -#undef __ANDROID__ -#undef __LINUX__ /* do we need to do this? */ -#define __ANDROID__ 1 -#endif - -#if defined(__APPLE__) -/* lets us know what version of Mac OS X we're compiling on */ -#include "AvailabilityMacros.h" -#include "TargetConditionals.h" -#if TARGET_OS_IPHONE -/* if compiling for iPhone */ -#undef __IPHONEOS__ -#define __IPHONEOS__ 1 -#undef __MACOSX__ -#else -/* if not compiling for iPhone */ -#undef __MACOSX__ -#define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 -# error SDL for Mac OS X only supports deploying on 10.5 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 -# error SDL for Mac OS X must be built with a 10.6 SDK or above. -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1060 */ -#endif /* TARGET_OS_IPHONE */ -#endif /* defined(__APPLE__) */ - -#if defined(__NetBSD__) -#undef __NETBSD__ -#define __NETBSD__ 1 -#endif -#if defined(__OpenBSD__) -#undef __OPENBSD__ -#define __OPENBSD__ 1 -#endif -#if defined(__OS2__) -#undef __OS2__ -#define __OS2__ 1 -#endif -#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) -#undef __OSF__ -#define __OSF__ 1 -#endif -#if defined(__QNXNTO__) -#undef __QNXNTO__ -#define __QNXNTO__ 1 -#endif -#if defined(riscos) || defined(__riscos) || defined(__riscos__) -#undef __RISCOS__ -#define __RISCOS__ 1 -#endif -#if defined(__SVR4) -#undef __SOLARIS__ -#define __SOLARIS__ 1 -#endif - -#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) -/* Try to find out if we're compiling for WinRT or non-WinRT */ -#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */ -#include -#endif /* _MSC_VER >= 1700 */ -/* Default to classic, Win32/Win64/Desktop compilation either if: - 1. the version of Windows is explicity set to a 'Desktop' (non-Metro) app - 2. the version of Windows cannot be determined via winapifamily.h - If neither is true, then see if we're compiling for WinRT. - */ -#if ! defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#undef __WINDOWS__ -#define __WINDOWS__ 1 -/* See if we're compiling for WinRT: */ -#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -#undef __WINRT__ -#define __WINRT__ 1 -#endif /* ! defined(WINAPI_FAMILY_PARTITION) */ -#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ - -#if defined(__WINDOWS__) -#undef __WIN32__ -#define __WIN32__ 1 -#endif -#if defined(__PSP__) -#undef __PSP__ -#define __PSP__ 1 -#endif - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Gets the name of the platform. - */ -extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include "close_code.h" - -#endif /* _SDL_platform_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/** + * \file SDL_platform.h + * + * Try to get a standard set of platform defines. + */ + +#ifndef _SDL_platform_h +#define _SDL_platform_h + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__HAIKU__) +#undef __HAIKU__ +#define __HAIKU__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if defined(linux) || defined(__linux) || defined(__linux__) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(ANDROID) +#undef __ANDROID__ +#undef __LINUX__ /* do we need to do this? */ +#define __ANDROID__ 1 +#endif + +#if defined(__APPLE__) +/* lets us know what version of Mac OS X we're compiling on */ +#include "AvailabilityMacros.h" +#include "TargetConditionals.h" +#if TARGET_OS_IPHONE +/* if compiling for iPhone */ +#undef __IPHONEOS__ +#define __IPHONEOS__ 1 +#undef __MACOSX__ +#else +/* if not compiling for iPhone */ +#undef __MACOSX__ +#define __MACOSX__ 1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +# error SDL for Mac OS X only supports deploying on 10.5 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */ +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 +# error SDL for Mac OS X must be built with a 10.6 SDK or above. +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1060 */ +#endif /* TARGET_OS_IPHONE */ +#endif /* defined(__APPLE__) */ + +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) +/* Try to find out if we're compiling for WinRT or non-WinRT */ +#if defined(_MSC_VER) && (_MSC_VER >= 1700) /* _MSC_VER==1700 for MSVC 2012 */ +#include +#endif /* _MSC_VER >= 1700 */ +/* Default to classic, Win32/Win64/Desktop compilation either if: + 1. the version of Windows is explicity set to a 'Desktop' (non-Metro) app + 2. the version of Windows cannot be determined via winapifamily.h + If neither is true, then see if we're compiling for WinRT. + */ +#if ! defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#undef __WINDOWS__ +#define __WINDOWS__ 1 +/* See if we're compiling for WinRT: */ +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#undef __WINRT__ +#define __WINRT__ 1 +#endif /* ! defined(WINAPI_FAMILY_PARTITION) */ +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + +#if defined(__WINDOWS__) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +#if defined(__PSP__) +#undef __PSP__ +#define __PSP__ 1 +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Gets the name of the platform. + */ +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_platform_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/SDL_system.h b/include/SDL_system.h index 5dc64cc94..fecbf1cfb 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -1,185 +1,185 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ - -/** - * \file SDL_system.h - * - * Include file for platform specific SDL API functions - */ - -#ifndef _SDL_system_h -#define _SDL_system_h - -#include "SDL_stdinc.h" -#include "SDL_keyboard.h" -#include "SDL_render.h" -#include "SDL_video.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - -/* Platform specific functions for Windows */ -#ifdef __WIN32__ - -/* Returns the D3D9 adapter index that matches the specified display index. - This adapter index can be passed to IDirect3D9::CreateDevice and controls - on which monitor a full screen application will appear. -*/ -extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); - -/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. - Once you are done using the device, you should release it to avoid a resource leak. - */ -typedef struct IDirect3DDevice9 IDirect3DDevice9; -extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); - -#endif /* __WIN32__ */ - - -/* Platform specific functions for iOS */ -#if defined(__IPHONEOS__) && __IPHONEOS__ - -extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); -extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); - -#endif /* __IPHONEOS__ */ - - -/* Platform specific functions for Android */ -#if defined(__ANDROID__) && __ANDROID__ - -/* Get the JNI environment for the current thread - This returns JNIEnv*, but the prototype is void* so we don't need jni.h - */ -extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(); - -/* Get the SDL Activity object for the application - This returns jobject, but the prototype is void* so we don't need jni.h - The jobject returned by SDL_AndroidGetActivity is a local reference. - It is the caller's responsibility to properly release it - (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef) - */ -extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(); - -/* See the official Android developer guide for more information: - http://developer.android.com/guide/topics/data/data-storage.html -*/ -#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 -#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 - -/* Get the path used for internal storage for this application. - This path is unique to your application and cannot be written to - by other applications. - */ -extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(); - -/* Get the current state of external storage, a bitmask of these values: - SDL_ANDROID_EXTERNAL_STORAGE_READ - SDL_ANDROID_EXTERNAL_STORAGE_WRITE - If external storage is currently unavailable, this will return 0. -*/ -extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(); - -/* Get the path used for external storage for this application. - This path is unique to your application, but is public and can be - written to by other applications. - */ -extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); - -#endif /* __ANDROID__ */ - -/* Platform specific functions for WinRT */ -#if defined(__WINRT__) && __WINRT__ - -/** - * \brief WinRT / 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 WinRT defined path on the local file system - * - * \note Documentation on most app-specific path types on WinRT - * 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 WinRT defined path on the local file system - * - * \note Documentation on most app-specific path types on WinRT - * 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 -} -#endif -#include "close_code.h" - -#endif /* _SDL_system_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef _SDL_system_h +#define _SDL_system_h + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#ifdef __WIN32__ + +/* Returns the D3D9 adapter index that matches the specified display index. + This adapter index can be passed to IDirect3D9::CreateDevice and controls + on which monitor a full screen application will appear. +*/ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. + Once you are done using the device, you should release it to avoid a resource leak. + */ +typedef struct IDirect3DDevice9 IDirect3DDevice9; +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +#endif /* __WIN32__ */ + + +/* Platform specific functions for iOS */ +#if defined(__IPHONEOS__) && __IPHONEOS__ + +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#if defined(__ANDROID__) && __ANDROID__ + +/* Get the JNI environment for the current thread + This returns JNIEnv*, but the prototype is void* so we don't need jni.h + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(); + +/* Get the SDL Activity object for the application + This returns jobject, but the prototype is void* so we don't need jni.h + The jobject returned by SDL_AndroidGetActivity is a local reference. + It is the caller's responsibility to properly release it + (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef) + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(); + +/* See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/* Get the path used for internal storage for this application. + This path is unique to your application and cannot be written to + by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(); + +/* Get the current state of external storage, a bitmask of these values: + SDL_ANDROID_EXTERNAL_STORAGE_READ + SDL_ANDROID_EXTERNAL_STORAGE_WRITE + If external storage is currently unavailable, this will return 0. +*/ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(); + +/* Get the path used for external storage for this application. + This path is unique to your application, but is public and can be + written to by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#if defined(__WINRT__) && __WINRT__ + +/** + * \brief WinRT / 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 WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * 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 WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * 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 +} +#endif +#include "close_code.h" + +#endif /* _SDL_system_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/begin_code.h b/include/begin_code.h index 1a5aa31bd..2651ee1b5 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -1,140 +1,140 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ - -/** - * \file begin_code.h - * - * This file sets things up for C dynamic library function definitions, - * static inlined functions, and structures aligned at 4-byte alignment. - * If you don't like ugly C preprocessor code, don't look at this file. :) - */ - -/* This shouldn't be nested -- included it around code only. */ -#ifdef _begin_code_h -#error Nested inclusion of begin_code.h -#endif -#define _begin_code_h - -#ifndef SDL_DEPRECATED -# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ -# define SDL_DEPRECATED __attribute__((deprecated)) -# else -# define SDL_DEPRECATED -# endif -#endif - -/* Some compilers use a special export keyword */ -#ifndef DECLSPEC -# if defined(__WIN32__) || defined(__WINRT__) -# ifdef __BORLANDC__ -# ifdef BUILD_SDL -# define DECLSPEC -# else -# define DECLSPEC __declspec(dllimport) -# endif -# else -# define DECLSPEC __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && __GNUC__ >= 4 -# define DECLSPEC __attribute__ ((visibility("default"))) -# elif defined(__GNUC__) && __GNUC__ >= 2 -# define DECLSPEC __declspec(dllexport) -# else -# define DECLSPEC -# endif -# endif -#endif - -/* By default SDL uses the C calling convention */ -#ifndef SDLCALL -#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) -#define SDLCALL __cdecl -#else -#define SDLCALL -#endif -#endif /* SDLCALL */ - -/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ -#ifdef __SYMBIAN32__ -#undef DECLSPEC -#define DECLSPEC -#endif /* __SYMBIAN32__ */ - -/* Force structure packing at 4 byte alignment. - This is necessary if the header is included in code which has structure - packing set to an alternate value, say for loading structures from disk. - The packing is reset to the previous value in close_code.h - */ -#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) -#ifdef _MSC_VER -#pragma warning(disable: 4103) -#endif -#ifdef __BORLANDC__ -#pragma nopackwarning -#endif -#ifdef _M_X64 -/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ -#pragma pack(push,8) -#else -#pragma pack(push,4) -#endif -#endif /* Compiler needs structure packing set */ - -#ifndef SDL_INLINE -#if defined(__GNUC__) -#define SDL_INLINE __inline__ -#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ - defined(__DMC__) || defined(__SC__) || \ - defined(__WATCOMC__) || defined(__LCC__) || \ - defined(__DECC) -#define SDL_INLINE __inline -#ifndef __inline__ -#define __inline__ __inline -#endif -#else -#define SDL_INLINE inline -#ifndef __inline__ -#define __inline__ inline -#endif -#endif -#endif /* SDL_INLINE not defined */ - -#ifndef SDL_FORCE_INLINE -#if defined(_MSC_VER) -#define SDL_FORCE_INLINE __forceinline -#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) -#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ -#else -#define SDL_FORCE_INLINE static SDL_INLINE -#endif -#endif /* SDL_FORCE_INLINE not defined */ - -/* Apparently this is needed by several Windows compilers */ -#if !defined(__MACH__) -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif /* NULL */ -#endif /* ! Mac OS X - breaks precompiled headers */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/** + * \file begin_code.h + * + * This file sets things up for C dynamic library function definitions, + * static inlined functions, and structures aligned at 4-byte alignment. + * If you don't like ugly C preprocessor code, don't look at this file. :) + */ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +#ifndef SDL_DEPRECATED +# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# define SDL_DEPRECATED __attribute__((deprecated)) +# else +# define SDL_DEPRECATED +# endif +#endif + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__WIN32__) || defined(__WINRT__) +# ifdef __BORLANDC__ +# ifdef BUILD_SDL +# define DECLSPEC +# else +# define DECLSPEC __declspec(dllimport) +# endif +# else +# define DECLSPEC __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# elif defined(__GNUC__) && __GNUC__ >= 2 +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) +#define SDLCALL __cdecl +#else +#define SDLCALL +#endif +#endif /* SDLCALL */ + +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ +#ifdef __SYMBIAN32__ +#undef DECLSPEC +#define DECLSPEC +#endif /* __SYMBIAN32__ */ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#ifdef _M_X64 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ +#pragma pack(push,8) +#else +#pragma pack(push,4) +#endif +#endif /* Compiler needs structure packing set */ + +#ifndef SDL_INLINE +#if defined(__GNUC__) +#define SDL_INLINE __inline__ +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) +#define SDL_INLINE __inline +#ifndef __inline__ +#define __inline__ __inline +#endif +#else +#define SDL_INLINE inline +#ifndef __inline__ +#define __inline__ inline +#endif +#endif +#endif /* SDL_INLINE not defined */ + +#ifndef SDL_FORCE_INLINE +#if defined(_MSC_VER) +#define SDL_FORCE_INLINE __forceinline +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ +#else +#define SDL_FORCE_INLINE static SDL_INLINE +#endif +#endif /* SDL_FORCE_INLINE not defined */ + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ diff --git a/src/SDL_log.c b/src/SDL_log.c index bc9f954fb..9a9be86a4 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -1,439 +1,439 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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 defined(__WIN32__) || defined(__WINRT__) -#include "core/windows/SDL_windows.h" -#endif - -/* Simple log messages in SDL */ - -#include "SDL_log.h" - -#if HAVE_STDIO_H -#include -#endif - -#if defined(__ANDROID__) -#include -#endif - -#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL -#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN -#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO -#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE - -/* Forward definition of error function */ -extern int SDL_SetError(const char *fmt, ...); - -typedef struct SDL_LogLevel -{ - int category; - SDL_LogPriority priority; - struct SDL_LogLevel *next; -} SDL_LogLevel; - -/* The default log output function */ -static void SDL_LogOutput(void *userdata, - int category, SDL_LogPriority priority, - const char *message); - -static SDL_LogLevel *SDL_loglevels; -static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY; -static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; -static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; -static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY; -static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput; -static void *SDL_log_userdata = NULL; - -static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = { - NULL, - "VERBOSE", - "DEBUG", - "INFO", - "WARN", - "ERROR", - "CRITICAL" -}; - -#ifdef __ANDROID__ -static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = { - "APP", - "ERROR", - "SYSTEM", - "AUDIO", - "VIDEO", - "RENDER", - "INPUT" -}; - -static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = { - ANDROID_LOG_UNKNOWN, - ANDROID_LOG_VERBOSE, - ANDROID_LOG_DEBUG, - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL -}; -#endif /* __ANDROID__ */ - - -void -SDL_LogSetAllPriority(SDL_LogPriority priority) -{ - SDL_LogLevel *entry; - - for (entry = SDL_loglevels; entry; entry = entry->next) { - entry->priority = priority; - } - SDL_default_priority = priority; - SDL_assert_priority = priority; - SDL_application_priority = priority; -} - -void -SDL_LogSetPriority(int category, SDL_LogPriority priority) -{ - SDL_LogLevel *entry; - - for (entry = SDL_loglevels; entry; entry = entry->next) { - if (entry->category == category) { - entry->priority = priority; - return; - } - } - - /* Create a new entry */ - entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry)); - if (entry) { - entry->category = category; - entry->priority = priority; - entry->next = SDL_loglevels; - SDL_loglevels = entry; - } -} - -SDL_LogPriority -SDL_LogGetPriority(int category) -{ - SDL_LogLevel *entry; - - for (entry = SDL_loglevels; entry; entry = entry->next) { - if (entry->category == category) { - return entry->priority; - } - } - - if (category == SDL_LOG_CATEGORY_TEST) { - return SDL_test_priority; - } else if (category == SDL_LOG_CATEGORY_APPLICATION) { - return SDL_application_priority; - } else if (category == SDL_LOG_CATEGORY_ASSERT) { - return SDL_assert_priority; - } else { - return SDL_default_priority; - } -} - -void -SDL_LogResetPriorities(void) -{ - SDL_LogLevel *entry; - - while (SDL_loglevels) { - entry = SDL_loglevels; - SDL_loglevels = entry->next; - SDL_free(entry); - } - - SDL_default_priority = DEFAULT_PRIORITY; - SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; - SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; - SDL_test_priority = DEFAULT_TEST_PRIORITY; -} - -void -SDL_Log(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); - va_end(ap); -} - -void -SDL_LogVerbose(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap); - va_end(ap); -} - -void -SDL_LogDebug(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap); - va_end(ap); -} - -void -SDL_LogInfo(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap); - va_end(ap); -} - -void -SDL_LogWarn(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap); - va_end(ap); -} - -void -SDL_LogError(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap); - va_end(ap); -} - -void -SDL_LogCritical(int category, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap); - va_end(ap); -} - -void -SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - SDL_LogMessageV(category, priority, fmt, ap); - va_end(ap); -} - -#ifdef __ANDROID__ -static const char * -GetCategoryPrefix(int category) -{ - if (category < SDL_LOG_CATEGORY_RESERVED1) { - return SDL_category_prefixes[category]; - } - if (category < SDL_LOG_CATEGORY_CUSTOM) { - return "RESERVED"; - } - return "CUSTOM"; -} -#endif /* __ANDROID__ */ - -void -SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) -{ - char *message; - size_t len; - - /* Nothing to do if we don't have an output function */ - if (!SDL_log_function) { - return; - } - - /* Make sure we don't exceed array bounds */ - if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) { - return; - } - - /* See if we want to do anything with this message */ - if (priority < SDL_LogGetPriority(category)) { - return; - } - - message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (!message) { - return; - } - - SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap); - - /* Chop off final endline. */ - len = SDL_strlen(message); - if ((len > 0) && (message[len-1] == '\n')) { - message[--len] = '\0'; - if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */ - message[--len] = '\0'; - } - } - - SDL_log_function(SDL_log_userdata, category, priority, message); - SDL_stack_free(message); -} - -#if defined(__WIN32__) -/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */ -static int consoleAttached = 0; - -/* Handle to stderr output of console. */ -static HANDLE stderrHandle = NULL; -#endif - -static void -SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, - const char *message) -{ -#if defined(__WIN32__) || defined(__WINRT__) - /* Way too many allocations here, urgh */ - /* Note: One can't call SDL_SetError here, since that function itself logs. */ - { - char *output; - size_t length; - LPTSTR tstr; - -#ifndef __WINRT__ - BOOL attachResult; - DWORD attachError; - unsigned long charsWritten; - - /* Maybe attach console and get stderr handle */ - if (consoleAttached == 0) { - attachResult = AttachConsole(ATTACH_PARENT_PROCESS); - if (!attachResult) { - attachError = GetLastError(); - if (attachError == ERROR_INVALID_HANDLE) { - OutputDebugString(TEXT("Parent process has no console\r\n")); - consoleAttached = -1; - } else if (attachError == ERROR_GEN_FAILURE) { - OutputDebugString(TEXT("Could not attach to console of parent process\r\n")); - consoleAttached = -1; - } else if (attachError == ERROR_ACCESS_DENIED) { - /* Already attached */ - consoleAttached = 1; - } else { - OutputDebugString(TEXT("Error attaching console\r\n")); - consoleAttached = -1; - } - } else { - /* Newly attached */ - consoleAttached = 1; - } - - if (consoleAttached == 1) { - stderrHandle = GetStdHandle(STD_ERROR_HANDLE); - } - } -#endif /* ifndef __WINRT__ */ - - length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1; - output = SDL_stack_alloc(char, length); - SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message); - tstr = WIN_UTF8ToString(output); - - /* Output to debugger */ - OutputDebugString(tstr); - -#ifndef __WINRT__ - /* Screen output to stderr, if console was attached. */ - if (consoleAttached == 1) { - if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) { - OutputDebugString(TEXT("Error calling WriteConsole\r\n")); - } - if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) { - OutputDebugString(TEXT("Insufficient heap memory to write message\r\n")); - } - } -#endif /* ifndef __WINRT__ */ - - SDL_free(tstr); - SDL_stack_free(output); - } -#elif defined(__ANDROID__) - { - char tag[32]; - - SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category)); - __android_log_write(SDL_android_priority[priority], tag, message); - } -#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) - /* Technically we don't need SDL_VIDEO_DRIVER_COCOA, but that's where this function is defined for now. - */ - extern void SDL_NSLog(const char *text); - { - char *text; - - text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (text) { - SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message); - SDL_NSLog(text); - SDL_stack_free(text); - return; - } - } -#elif defined(__PSP__) - { - FILE* pFile; - pFile = fopen ("SDL_Log.txt", "a"); - fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message); - fclose (pFile); - } -#endif -#if HAVE_STDIO_H - fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message); -#endif -} - -void -SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata) -{ - if (callback) { - *callback = SDL_log_function; - } - if (userdata) { - *userdata = SDL_log_userdata; - } -} - -void -SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata) -{ - SDL_log_function = callback; - SDL_log_userdata = userdata; -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 defined(__WIN32__) || defined(__WINRT__) +#include "core/windows/SDL_windows.h" +#endif + +/* Simple log messages in SDL */ + +#include "SDL_log.h" + +#if HAVE_STDIO_H +#include +#endif + +#if defined(__ANDROID__) +#include +#endif + +#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL +#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN +#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO +#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE + +/* Forward definition of error function */ +extern int SDL_SetError(const char *fmt, ...); + +typedef struct SDL_LogLevel +{ + int category; + SDL_LogPriority priority; + struct SDL_LogLevel *next; +} SDL_LogLevel; + +/* The default log output function */ +static void SDL_LogOutput(void *userdata, + int category, SDL_LogPriority priority, + const char *message); + +static SDL_LogLevel *SDL_loglevels; +static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY; +static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; +static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; +static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY; +static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput; +static void *SDL_log_userdata = NULL; + +static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = { + NULL, + "VERBOSE", + "DEBUG", + "INFO", + "WARN", + "ERROR", + "CRITICAL" +}; + +#ifdef __ANDROID__ +static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = { + "APP", + "ERROR", + "SYSTEM", + "AUDIO", + "VIDEO", + "RENDER", + "INPUT" +}; + +static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = { + ANDROID_LOG_UNKNOWN, + ANDROID_LOG_VERBOSE, + ANDROID_LOG_DEBUG, + ANDROID_LOG_INFO, + ANDROID_LOG_WARN, + ANDROID_LOG_ERROR, + ANDROID_LOG_FATAL +}; +#endif /* __ANDROID__ */ + + +void +SDL_LogSetAllPriority(SDL_LogPriority priority) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + entry->priority = priority; + } + SDL_default_priority = priority; + SDL_assert_priority = priority; + SDL_application_priority = priority; +} + +void +SDL_LogSetPriority(int category, SDL_LogPriority priority) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + if (entry->category == category) { + entry->priority = priority; + return; + } + } + + /* Create a new entry */ + entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry)); + if (entry) { + entry->category = category; + entry->priority = priority; + entry->next = SDL_loglevels; + SDL_loglevels = entry; + } +} + +SDL_LogPriority +SDL_LogGetPriority(int category) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + if (entry->category == category) { + return entry->priority; + } + } + + if (category == SDL_LOG_CATEGORY_TEST) { + return SDL_test_priority; + } else if (category == SDL_LOG_CATEGORY_APPLICATION) { + return SDL_application_priority; + } else if (category == SDL_LOG_CATEGORY_ASSERT) { + return SDL_assert_priority; + } else { + return SDL_default_priority; + } +} + +void +SDL_LogResetPriorities(void) +{ + SDL_LogLevel *entry; + + while (SDL_loglevels) { + entry = SDL_loglevels; + SDL_loglevels = entry->next; + SDL_free(entry); + } + + SDL_default_priority = DEFAULT_PRIORITY; + SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; + SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; + SDL_test_priority = DEFAULT_TEST_PRIORITY; +} + +void +SDL_Log(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); + va_end(ap); +} + +void +SDL_LogVerbose(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap); + va_end(ap); +} + +void +SDL_LogDebug(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap); + va_end(ap); +} + +void +SDL_LogInfo(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap); + va_end(ap); +} + +void +SDL_LogWarn(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap); + va_end(ap); +} + +void +SDL_LogError(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap); + va_end(ap); +} + +void +SDL_LogCritical(int category, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap); + va_end(ap); +} + +void +SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, priority, fmt, ap); + va_end(ap); +} + +#ifdef __ANDROID__ +static const char * +GetCategoryPrefix(int category) +{ + if (category < SDL_LOG_CATEGORY_RESERVED1) { + return SDL_category_prefixes[category]; + } + if (category < SDL_LOG_CATEGORY_CUSTOM) { + return "RESERVED"; + } + return "CUSTOM"; +} +#endif /* __ANDROID__ */ + +void +SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) +{ + char *message; + size_t len; + + /* Nothing to do if we don't have an output function */ + if (!SDL_log_function) { + return; + } + + /* Make sure we don't exceed array bounds */ + if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) { + return; + } + + /* See if we want to do anything with this message */ + if (priority < SDL_LogGetPriority(category)) { + return; + } + + message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); + if (!message) { + return; + } + + SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap); + + /* Chop off final endline. */ + len = SDL_strlen(message); + if ((len > 0) && (message[len-1] == '\n')) { + message[--len] = '\0'; + if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */ + message[--len] = '\0'; + } + } + + SDL_log_function(SDL_log_userdata, category, priority, message); + SDL_stack_free(message); +} + +#if defined(__WIN32__) +/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */ +static int consoleAttached = 0; + +/* Handle to stderr output of console. */ +static HANDLE stderrHandle = NULL; +#endif + +static void +SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, + const char *message) +{ +#if defined(__WIN32__) || defined(__WINRT__) + /* Way too many allocations here, urgh */ + /* Note: One can't call SDL_SetError here, since that function itself logs. */ + { + char *output; + size_t length; + LPTSTR tstr; + +#ifndef __WINRT__ + BOOL attachResult; + DWORD attachError; + unsigned long charsWritten; + + /* Maybe attach console and get stderr handle */ + if (consoleAttached == 0) { + attachResult = AttachConsole(ATTACH_PARENT_PROCESS); + if (!attachResult) { + attachError = GetLastError(); + if (attachError == ERROR_INVALID_HANDLE) { + OutputDebugString(TEXT("Parent process has no console\r\n")); + consoleAttached = -1; + } else if (attachError == ERROR_GEN_FAILURE) { + OutputDebugString(TEXT("Could not attach to console of parent process\r\n")); + consoleAttached = -1; + } else if (attachError == ERROR_ACCESS_DENIED) { + /* Already attached */ + consoleAttached = 1; + } else { + OutputDebugString(TEXT("Error attaching console\r\n")); + consoleAttached = -1; + } + } else { + /* Newly attached */ + consoleAttached = 1; + } + + if (consoleAttached == 1) { + stderrHandle = GetStdHandle(STD_ERROR_HANDLE); + } + } +#endif /* ifndef __WINRT__ */ + + length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1; + output = SDL_stack_alloc(char, length); + SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message); + tstr = WIN_UTF8ToString(output); + + /* Output to debugger */ + OutputDebugString(tstr); + +#ifndef __WINRT__ + /* Screen output to stderr, if console was attached. */ + if (consoleAttached == 1) { + if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) { + OutputDebugString(TEXT("Error calling WriteConsole\r\n")); + } + if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) { + OutputDebugString(TEXT("Insufficient heap memory to write message\r\n")); + } + } +#endif /* ifndef __WINRT__ */ + + SDL_free(tstr); + SDL_stack_free(output); + } +#elif defined(__ANDROID__) + { + char tag[32]; + + SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category)); + __android_log_write(SDL_android_priority[priority], tag, message); + } +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) + /* Technically we don't need SDL_VIDEO_DRIVER_COCOA, but that's where this function is defined for now. + */ + extern void SDL_NSLog(const char *text); + { + char *text; + + text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); + if (text) { + SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message); + SDL_NSLog(text); + SDL_stack_free(text); + return; + } + } +#elif defined(__PSP__) + { + FILE* pFile; + pFile = fopen ("SDL_Log.txt", "a"); + fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message); + fclose (pFile); + } +#endif +#if HAVE_STDIO_H + fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message); +#endif +} + +void +SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata) +{ + if (callback) { + *callback = SDL_log_function; + } + if (userdata) { + *userdata = SDL_log_userdata; + } +} + +void +SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata) +{ + SDL_log_function = callback; + SDL_log_userdata = userdata; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index ac78729c7..b533b33f5 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -1,126 +1,126 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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 defined(__WIN32__) || defined(__WINRT__) -#include "../core/windows/SDL_windows.h" -#endif - -#include "SDL_atomic.h" -#include "SDL_mutex.h" -#include "SDL_timer.h" - - -/* This function is where all the magic happens... */ -SDL_bool -SDL_AtomicTryLock(SDL_SpinLock *lock) -{ -#if SDL_ATOMIC_DISABLED - /* Terrible terrible damage */ - static SDL_mutex *_spinlock_mutex; - - if (!_spinlock_mutex) { - /* Race condition on first lock... */ - _spinlock_mutex = SDL_CreateMutex(); - } - SDL_LockMutex(_spinlock_mutex); - if (*lock == 0) { - *lock = 1; - SDL_UnlockMutex(_spinlock_mutex); - return SDL_TRUE; - } else { - SDL_UnlockMutex(_spinlock_mutex); - return SDL_FALSE; - } - -#elif defined(_MSC_VER) - SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); - return (InterlockedExchange((long*)lock, 1) == 0); - -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET - return (__sync_lock_test_and_set(lock, 1) == 0); - -#elif defined(__GNUC__) && defined(__arm__) && \ - (defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \ - defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \ - defined(__ARM_ARCH_5TEJ__)) - int result; - __asm__ __volatile__ ( - "swp %0, %1, [%2]\n" - : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory"); - return (result == 0); - -#elif defined(__GNUC__) && defined(__arm__) - int result; - __asm__ __volatile__ ( - "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" - : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); - return (result == 0); - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - int result; - __asm__ __volatile__( - "lock ; xchgl %0, (%1)\n" - : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory"); - return (result == 0); - -#elif defined(__MACOSX__) || defined(__IPHONEOS__) - /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */ - return OSAtomicCompareAndSwap32Barrier(0, 1, lock); - -#elif HAVE_PTHREAD_SPINLOCK - /* pthread instructions */ - return (pthread_spin_trylock(lock) == 0); - -#else -#error Please implement for your platform. - return SDL_FALSE; -#endif -} - -void -SDL_AtomicLock(SDL_SpinLock *lock) -{ - /* FIXME: Should we have an eventual timeout? */ - while (!SDL_AtomicTryLock(lock)) { - SDL_Delay(0); - } -} - -void -SDL_AtomicUnlock(SDL_SpinLock *lock) -{ -#if defined(_MSC_VER) - _ReadWriteBarrier(); - *lock = 0; - -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET - __sync_lock_release(lock); - -#elif HAVE_PTHREAD_SPINLOCK - pthread_spin_unlock(lock); - -#else - *lock = 0; -#endif -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 defined(__WIN32__) || defined(__WINRT__) +#include "../core/windows/SDL_windows.h" +#endif + +#include "SDL_atomic.h" +#include "SDL_mutex.h" +#include "SDL_timer.h" + + +/* This function is where all the magic happens... */ +SDL_bool +SDL_AtomicTryLock(SDL_SpinLock *lock) +{ +#if SDL_ATOMIC_DISABLED + /* Terrible terrible damage */ + static SDL_mutex *_spinlock_mutex; + + if (!_spinlock_mutex) { + /* Race condition on first lock... */ + _spinlock_mutex = SDL_CreateMutex(); + } + SDL_LockMutex(_spinlock_mutex); + if (*lock == 0) { + *lock = 1; + SDL_UnlockMutex(_spinlock_mutex); + return SDL_TRUE; + } else { + SDL_UnlockMutex(_spinlock_mutex); + return SDL_FALSE; + } + +#elif defined(_MSC_VER) + SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); + return (InterlockedExchange((long*)lock, 1) == 0); + +#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET + return (__sync_lock_test_and_set(lock, 1) == 0); + +#elif defined(__GNUC__) && defined(__arm__) && \ + (defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \ + defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_5TEJ__)) + int result; + __asm__ __volatile__ ( + "swp %0, %1, [%2]\n" + : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory"); + return (result == 0); + +#elif defined(__GNUC__) && defined(__arm__) + int result; + __asm__ __volatile__ ( + "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" + : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); + return (result == 0); + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + int result; + __asm__ __volatile__( + "lock ; xchgl %0, (%1)\n" + : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory"); + return (result == 0); + +#elif defined(__MACOSX__) || defined(__IPHONEOS__) + /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */ + return OSAtomicCompareAndSwap32Barrier(0, 1, lock); + +#elif HAVE_PTHREAD_SPINLOCK + /* pthread instructions */ + return (pthread_spin_trylock(lock) == 0); + +#else +#error Please implement for your platform. + return SDL_FALSE; +#endif +} + +void +SDL_AtomicLock(SDL_SpinLock *lock) +{ + /* FIXME: Should we have an eventual timeout? */ + while (!SDL_AtomicTryLock(lock)) { + SDL_Delay(0); + } +} + +void +SDL_AtomicUnlock(SDL_SpinLock *lock) +{ +#if defined(_MSC_VER) + _ReadWriteBarrier(); + *lock = 0; + +#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET + __sync_lock_release(lock); + +#elif HAVE_PTHREAD_SPINLOCK + pthread_spin_unlock(lock); + +#else + *lock = 0; +#endif +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index e4014f960..a6792c667 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -1,543 +1,543 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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 few 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 WinRT. 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 WinRT. - 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^)). (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 WinRT, the - string-based argument will be used. -*/ - -#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 -#elif defined(__WINRT__) -/* WinRT always has access to the .the XAudio 2 SDK */ -# define SDL_XAUDIO2_HAS_SDK -#else -/* XAudio2 exists as of the March 2008 DirectX SDK - The XAudio2 implementation available in the Windows 8 SDK targets Windows 8 and newer. - If you want to build SDL with XAudio2 support you should install the DirectX SDK. - */ -#include -#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 - -/* Check to see if we're compiling for XAudio 2.8, or higher. */ -#ifdef WINVER -#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */ -#define SDL_XAUDIO2_WIN8 1 -#endif -#endif - -/* The XAudio header file, when #include'd on WinRT, will only compile in C++ - files, but not C. A few preprocessor-based hacks are defined below in order - to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c. - */ -#ifdef __WINRT__ -#define uuid(x) -#define DX_BUILD -#endif - -#define INITGUID 1 -#include - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -#ifdef __WINRT__ -#include "SDL_xaudio2_winrthelpers.h" -#endif - -/* Fixes bug 1210 where some versions of gcc need named parameters */ -#ifdef __GNUC__ -#ifdef THIS -#undef THIS -#endif -#define THIS INTERFACE *p -#ifdef THIS_ -#undef THIS_ -#endif -#define THIS_ INTERFACE *p, -#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) {} - - -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); -#if SDL_XAUDIO2_WIN8 - IXAudio2SourceVoice_GetState(source, &state, 0); -#else - IXAudio2SourceVoice_GetState(source, &state); -#endif - while (state.BuffersQueued > 0) { - SDL_SemWait(this->hidden->semaphore); -#if SDL_XAUDIO2_WIN8 - IXAudio2SourceVoice_GetState(source, &state, 0); -#else - IXAudio2SourceVoice_GetState(source, &state); -#endif - } -} - - -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); - } - 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(SDL_XAUDIO2_WIN8) - LPCWSTR devId = NULL; -#else - UINT32 devId = 0; /* 0 == system default device. */ -#endif - - 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."); - } - - /* - 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__) - 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) { - devId = i; - 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. */ -#if SDL_XAUDIO2_WIN8 - result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, - XAUDIO2_DEFAULT_CHANNELS, - this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); -#else - result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, - XAUDIO2_DEFAULT_CHANNELS, - this->spec.freq, 0, devId, NULL); -#endif - 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 -} - -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 + + 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 few 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 WinRT. 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 WinRT. + 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^)). (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 WinRT, the + string-based argument will be used. +*/ + +#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 +#elif defined(__WINRT__) +/* WinRT always has access to the .the XAudio 2 SDK */ +# define SDL_XAUDIO2_HAS_SDK +#else +/* XAudio2 exists as of the March 2008 DirectX SDK + The XAudio2 implementation available in the Windows 8 SDK targets Windows 8 and newer. + If you want to build SDL with XAudio2 support you should install the DirectX SDK. + */ +#include +#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 + +/* Check to see if we're compiling for XAudio 2.8, or higher. */ +#ifdef WINVER +#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */ +#define SDL_XAUDIO2_WIN8 1 +#endif +#endif + +/* The XAudio header file, when #include'd on WinRT, will only compile in C++ + files, but not C. A few preprocessor-based hacks are defined below in order + to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c. + */ +#ifdef __WINRT__ +#define uuid(x) +#define DX_BUILD +#endif + +#define INITGUID 1 +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +#ifdef __WINRT__ +#include "SDL_xaudio2_winrthelpers.h" +#endif + +/* Fixes bug 1210 where some versions of gcc need named parameters */ +#ifdef __GNUC__ +#ifdef THIS +#undef THIS +#endif +#define THIS INTERFACE *p +#ifdef THIS_ +#undef THIS_ +#endif +#define THIS_ INTERFACE *p, +#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) {} + + +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); +#if SDL_XAUDIO2_WIN8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else + IXAudio2SourceVoice_GetState(source, &state); +#endif + while (state.BuffersQueued > 0) { + SDL_SemWait(this->hidden->semaphore); +#if SDL_XAUDIO2_WIN8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else + IXAudio2SourceVoice_GetState(source, &state); +#endif + } +} + + +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); + } + 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(SDL_XAUDIO2_WIN8) + LPCWSTR devId = NULL; +#else + UINT32 devId = 0; /* 0 == system default device. */ +#endif + + 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."); + } + + /* + 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__) + 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) { + devId = i; + 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. */ +#if SDL_XAUDIO2_WIN8 + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, + XAUDIO2_DEFAULT_CHANNELS, + this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); +#else + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, + XAUDIO2_DEFAULT_CHANNELS, + this->spec.freq, 0, devId, NULL); +#endif + 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 +} + +AudioBootStrap XAUDIO2_bootstrap = { + "xaudio2", "XAudio2", XAUDIO2_Init, 0 +}; + +#endif /* SDL_AUDIO_DRIVER_XAUDIO2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp index 9c0fe0ed7..b27ee59b6 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -1,69 +1,69 @@ - -#include -#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 - -extern "C" HRESULT __cdecl 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 -} - -extern "C" 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 -} + +#include +#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 + +extern "C" HRESULT __cdecl 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 +} + +extern "C" 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 +} diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h index ee5afcd45..0beaf8d1f 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h @@ -1,52 +1,52 @@ - -#pragma once - -// -// Re-implementation of methods removed from XAudio2 (in WinRT): -// - -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; - - -#ifdef __cplusplus -extern "C" { -#endif - -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount); -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details); - -#ifdef __cplusplus -} -#endif - - -// -// C-style macros to call XAudio2's methods in C++: -// -#ifdef __cplusplus -/* -#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)) -*/ -#endif // ifdef __cplusplus + +#pragma once + +// +// Re-implementation of methods removed from XAudio2 (in WinRT): +// + +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; + + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount); +HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details); + +#ifdef __cplusplus +} +#endif + + +// +// C-style macros to call XAudio2's methods in C++: +// +#ifdef __cplusplus +/* +#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)) +*/ +#endif // ifdef __cplusplus diff --git a/src/core/winrt/SDL_winrtapp_common.cpp b/src/core/winrt/SDL_winrtapp_common.cpp index 6699e6811..fb151f229 100644 --- a/src/core/winrt/SDL_winrtapp_common.cpp +++ b/src/core/winrt/SDL_winrtapp_common.cpp @@ -1,16 +1,16 @@ - -#include -#include "SDL_winrtapp_direct3d.h" -#include "SDL_winrtapp_xaml.h" - -int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; - + +#include +#include "SDL_winrtapp_direct3d.h" +#include "SDL_winrtapp_xaml.h" + +int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; + extern "C" DECLSPEC int -SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel) -{ - if (xamlBackgroundPanel) { - return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); - } else { - return SDL_WinRTInitNonXAMLApp(mainFunction); - } -} +SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel) +{ + if (xamlBackgroundPanel) { + return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); + } else { + return SDL_WinRTInitNonXAMLApp(mainFunction); + } +} diff --git a/src/core/winrt/SDL_winrtapp_common.h b/src/core/winrt/SDL_winrtapp_common.h index 503a785aa..d54a8ccdc 100644 --- a/src/core/winrt/SDL_winrtapp_common.h +++ b/src/core/winrt/SDL_winrtapp_common.h @@ -19,13 +19,13 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_config.h" - + #ifndef _SDL_winrtapp_common_h -#define _SDL_winrtapp_common_h - -/* A pointer to the app's C-style main() function (which is a different - function than the WinRT app's actual entry point). - */ -extern int (*WINRT_SDLAppEntryPoint)(int, char **); - -#endif // ifndef _SDL_winrtapp_common_h +#define _SDL_winrtapp_common_h + +/* A pointer to the app's C-style main() function (which is a different + function than the WinRT app's actual entry point). + */ +extern int (*WINRT_SDLAppEntryPoint)(int, char **); + +#endif // ifndef _SDL_winrtapp_common_h diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 3870d77ed..53c72bc4e 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -1,668 +1,668 @@ - -/* Standard C++11 includes */ -#include -#include -#include -using namespace std; - - -/* Windows includes */ -#include "ppltasks.h" -using namespace concurrency; -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; - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -using namespace Windows::Phone::UI::Input; -#endif - - -/* SDL includes */ -extern "C" { -#include "SDL_assert.h" -#include "SDL_events.h" -#include "SDL_hints.h" -#include "SDL_log.h" -#include "SDL_main.h" -#include "SDL_stdinc.h" -#include "SDL_render.h" -#include "../../video/SDL_sysvideo.h" -//#include "../../SDL_hints_c.h" -#include "../../events/SDL_events_c.h" -#include "../../events/SDL_keyboard_c.h" -#include "../../events/SDL_mouse_c.h" -#include "../../events/SDL_windowevents_c.h" -#include "../../render/SDL_sysrender.h" -#include "../windows/SDL_windows.h" -} - -#include "../../video/winrt/SDL_winrtevents_c.h" -#include "../../video/winrt/SDL_winrtvideo_cpp.h" -#include "SDL_winrtapp_common.h" -#include "SDL_winrtapp_direct3d.h" - - -// 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: record a reference to the global, WinRT '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; -} - -int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) -{ - WINRT_SDLAppEntryPoint = mainFunction; - auto direct3DApplicationSource = ref new SDLApplicationSource(); - CoreApplication::Run(direct3DApplicationSource); - return 0; -} - -static void WINRT_SetDisplayOrientationsPreference(void *userdata, 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; - if (newValue) { - 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 WinRT [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; -} - -static void -WINRT_ProcessWindowSizeChange() -{ - // Make the new window size be the one true fullscreen mode. - // This change was initially 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. - SDL_DisplayMode newDisplayMode; - if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) { - return; - } - - // Make note of the old display mode, and it's old driverdata. - SDL_DisplayMode oldDisplayMode; - SDL_zero(oldDisplayMode); - if (WINRT_GlobalSDLVideoDevice) { - oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode; - } - - // Setup the new display mode in the appropriate spots. - if (WINRT_GlobalSDLVideoDevice) { - // Make a full copy of the display mode for display_modes[0], - // one with with a separately malloced 'driverdata' field. - // SDL_VideoQuit(), if called, will attempt to free the driverdata - // fields in 'desktop_mode' and each entry in the 'display_modes' - // array. - if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) { - // Free the previous mode's memory - SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata); - WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL; - } - if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) { - // Uh oh, something went wrong. A malloc call probably failed. - SDL_free(newDisplayMode.driverdata); - return; - } - - // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'. - WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode; - WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode; - } - - if (WINRT_GlobalSDLWindow) { - // Send a window-resize event to the rest of SDL, and to apps: - SDL_SendWindowEvent( - WINRT_GlobalSDLWindow, - SDL_WINDOWEVENT_RESIZED, - newDisplayMode.w, - newDisplayMode.h); - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - // HACK: On Windows Phone, make sure that orientation changes from - // Landscape to LandscapeFlipped, Portrait to PortraitFlipped, - // or vice-versa on either of those two, lead to the Direct3D renderer - // getting updated. - const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation; - const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation; - - if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) || - (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) || - (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) || - (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait)) - { - // One of the reasons this event is getting sent out is because SDL - // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events - // if and when the event size doesn't change (and the Direct3D 11.1 - // renderer doesn't get the memo). - // - // Make sure that the display/window size really didn't change. If - // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and - // the Direct3D 11.1 renderer picked it up, presumably. - if (oldDisplayMode.w == newDisplayMode.w && - oldDisplayMode.h == newDisplayMode.h) - { - SDL_SendWindowEvent( - WINRT_GlobalSDLWindow, - SDL_WINDOWEVENT_SIZE_CHANGED, - newDisplayMode.w, - newDisplayMode.h); - } - } -#endif - } - - // Finally, free the 'driverdata' field of the old 'desktop_mode'. - if (oldDisplayMode.driverdata) { - SDL_free(oldDisplayMode.driverdata); - oldDisplayMode.driverdata = NULL; - } -} - -SDL_WinRTApp::SDL_WinRTApp() : - m_windowClosed(false), - m_windowVisible(true) -{ -} - -void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) -{ - applicationView->Activated += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnActivated); - - CoreApplication::Suspending += - ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); - - CoreApplication::Resuming += - ref new EventHandler(this, &SDL_WinRTApp::OnResuming); - - CoreApplication::Exiting += - ref new EventHandler(this, &SDL_WinRTApp::OnExiting); - - 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. - // - // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. - //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback) - SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); -} - -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 - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - // On Windows Phone, treat an orientation change as a change in window size. - // The native window's size doesn't seem to change, however SDL will simulate - // a window size change. - WINRT_ProcessWindowSizeChange(); -#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(this, &SDL_WinRTApp::OnWindowSizeChanged); - - window->VisibilityChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); - - window->Closed += - ref new TypedEventHandler(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(this, &SDL_WinRTApp::OnPointerPressed); - - window->PointerMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); - - window->PointerReleased += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); - - window->PointerWheelChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); - -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - // Retrieves relative-only mouse movements: - Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); -#endif - - window->KeyDown += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); - - window->KeyUp += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - HardwareButtons::BackPressed += - ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); -#endif - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) - // Make sure we know when a user has opened the app's settings pane. - // This is needed in order to display a privacy policy, which needs - // to be done for network-enabled apps, as per Windows Store requirements. - using namespace Windows::UI::ApplicationSettings; - SettingsPane::GetForCurrentView()->CommandsRequested += - ref new TypedEventHandler - (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); -#endif -} - -void SDL_WinRTApp::Load(Platform::String^ entryPoint) -{ -} - -void SDL_WinRTApp::Run() -{ - SDL_SetMainReady(); - if (WINRT_SDLAppEntryPoint) - { - // TODO, WinRT: pass the C-style main() a reasonably realistic - // representation of command line arguments. - int argc = 0; - char **argv = NULL; - WINRT_SDLAppEntryPoint(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() -{ -} - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP -void SDL_WinRTApp::OnSettingsPaneCommandsRequested( - Windows::UI::ApplicationSettings::SettingsPane ^p, - Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args) -{ - using namespace Platform; - using namespace Windows::UI::ApplicationSettings; - using namespace Windows::UI::Popups; - - String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy - String ^privacyPolicyLabel = nullptr; // label/link text - const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately - wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion - - // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint): - tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL); - if (tmpHintValue && tmpHintValue[0] != '\0') { - // Convert the privacy policy's URL to UCS2: - tmpStr = WIN_UTF8ToString(tmpHintValue); - privacyPolicyURL = ref new String(tmpStr); - SDL_free(tmpStr); - - // Optionally retrieve custom label-text for the link. If this isn't - // available, a default value will be used instead. - tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL); - if (tmpHintValue && tmpHintValue[0] != '\0') { - tmpStr = WIN_UTF8ToString(tmpHintValue); - privacyPolicyLabel = ref new String(tmpStr); - SDL_free(tmpStr); - } else { - privacyPolicyLabel = ref new String(L"Privacy Policy"); - } - - // Register the link, along with a handler to be called if and when it is - // clicked: - auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel, - ref new UICommandInvokedHandler([=](IUICommand ^) { - Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); - })); - args->Request->ApplicationCommands->Append(cmd); - } -} -#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP - -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, WINRT_GlobalSDLWindow?=%s\n", - __FUNCTION__, - args->Size.Width, args->Size.Height, - (int)DisplayProperties::CurrentOrientation, - (int)DisplayProperties::NativeOrientation, - (int)DisplayProperties::AutoRotationPreferences, - (WINRT_GlobalSDLWindow ? "yes" : "no")); -#endif - - WINRT_ProcessWindowSizeChange(); -} - -void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) -{ -#if LOG_WINDOW_EVENTS==1 - SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n", - __FUNCTION__, - (args->Visible ? "yes" : "no"), - (WINRT_GlobalSDLWindow ? "yes" : "no")); -#endif - - m_windowVisible = args->Visible; - if (WINRT_GlobalSDLWindow) { - SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid; - - if (args->Visible) { - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); - } else { - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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. - WINRT_GlobalSDLWindow->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; -} - -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 (WINRT_GlobalSDLWindow) - { - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently) - SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); - } - - SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); - SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); - - deferral->Complete(); - }); -} - -void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) -{ - SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); - SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); - - // 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 (WINRT_GlobalSDLWindow) - { - SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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); - } -} - -void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) -{ - SDL_SendAppEvent(SDL_APP_TERMINATING); -} - -static void -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) -{ - Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", - header, - pt->Position.X, pt->Position.Y, - transformedPoint.X, transformedPoint.Y, - pt->Properties->MouseWheelDelta, - pt->FrameId, - pt->PointerId, - WINRT_GetSDLButtonForPointerPoint(pt)); -} - -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); -#endif - - WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); -#endif - - WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); -#endif - - WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) -{ -#if LOG_POINTER_EVENTS - WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); -#endif - - WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); -} - -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) -{ - WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); -} - -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyDownEvent(args); -} - -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) -{ - WINRT_ProcessKeyUpEvent(args); -} - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args) -{ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK); - + +/* Standard C++11 includes */ +#include +#include +#include +using namespace std; + + +/* Windows includes */ +#include "ppltasks.h" +using namespace concurrency; +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; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +using namespace Windows::Phone::UI::Input; +#endif + + +/* SDL includes */ +extern "C" { +#include "SDL_assert.h" +#include "SDL_events.h" +#include "SDL_hints.h" +#include "SDL_log.h" +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_render.h" +#include "../../video/SDL_sysvideo.h" +//#include "../../SDL_hints_c.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../render/SDL_sysrender.h" +#include "../windows/SDL_windows.h" +} + +#include "../../video/winrt/SDL_winrtevents_c.h" +#include "../../video/winrt/SDL_winrtvideo_cpp.h" +#include "SDL_winrtapp_common.h" +#include "SDL_winrtapp_direct3d.h" + + +// 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: record a reference to the global, WinRT '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; +} + +int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) +{ + WINRT_SDLAppEntryPoint = mainFunction; + auto direct3DApplicationSource = ref new SDLApplicationSource(); + CoreApplication::Run(direct3DApplicationSource); + return 0; +} + +static void WINRT_SetDisplayOrientationsPreference(void *userdata, 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; + if (newValue) { + 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 WinRT [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; +} + +static void +WINRT_ProcessWindowSizeChange() +{ + // Make the new window size be the one true fullscreen mode. + // This change was initially 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. + SDL_DisplayMode newDisplayMode; + if (WINRT_CalcDisplayModeUsingNativeWindow(&newDisplayMode) != 0) { + return; + } + + // Make note of the old display mode, and it's old driverdata. + SDL_DisplayMode oldDisplayMode; + SDL_zero(oldDisplayMode); + if (WINRT_GlobalSDLVideoDevice) { + oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode; + } + + // Setup the new display mode in the appropriate spots. + if (WINRT_GlobalSDLVideoDevice) { + // Make a full copy of the display mode for display_modes[0], + // one with with a separately malloced 'driverdata' field. + // SDL_VideoQuit(), if called, will attempt to free the driverdata + // fields in 'desktop_mode' and each entry in the 'display_modes' + // array. + if (WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata) { + // Free the previous mode's memory + SDL_free(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata); + WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0].driverdata = NULL; + } + if (WINRT_DuplicateDisplayMode(&(WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0]), &newDisplayMode) != 0) { + // Uh oh, something went wrong. A malloc call probably failed. + SDL_free(newDisplayMode.driverdata); + return; + } + + // Install 'newDisplayMode' into 'current_mode' and 'desktop_mode'. + WINRT_GlobalSDLVideoDevice->displays[0].current_mode = newDisplayMode; + WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = newDisplayMode; + } + + if (WINRT_GlobalSDLWindow) { + // Send a window-resize event to the rest of SDL, and to apps: + SDL_SendWindowEvent( + WINRT_GlobalSDLWindow, + SDL_WINDOWEVENT_RESIZED, + newDisplayMode.w, + newDisplayMode.h); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // HACK: On Windows Phone, make sure that orientation changes from + // Landscape to LandscapeFlipped, Portrait to PortraitFlipped, + // or vice-versa on either of those two, lead to the Direct3D renderer + // getting updated. + const DisplayOrientations oldOrientation = ((SDL_DisplayModeData *)oldDisplayMode.driverdata)->currentOrientation; + const DisplayOrientations newOrientation = ((SDL_DisplayModeData *)newDisplayMode.driverdata)->currentOrientation; + + if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) || + (oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) || + (oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) || + (oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait)) + { + // One of the reasons this event is getting sent out is because SDL + // will ignore requests to send out SDL_WINDOWEVENT_RESIZED events + // if and when the event size doesn't change (and the Direct3D 11.1 + // renderer doesn't get the memo). + // + // Make sure that the display/window size really didn't change. If + // it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and + // the Direct3D 11.1 renderer picked it up, presumably. + if (oldDisplayMode.w == newDisplayMode.w && + oldDisplayMode.h == newDisplayMode.h) + { + SDL_SendWindowEvent( + WINRT_GlobalSDLWindow, + SDL_WINDOWEVENT_SIZE_CHANGED, + newDisplayMode.w, + newDisplayMode.h); + } + } +#endif + } + + // Finally, free the 'driverdata' field of the old 'desktop_mode'. + if (oldDisplayMode.driverdata) { + SDL_free(oldDisplayMode.driverdata); + oldDisplayMode.driverdata = NULL; + } +} + +SDL_WinRTApp::SDL_WinRTApp() : + m_windowClosed(false), + m_windowVisible(true) +{ +} + +void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) +{ + applicationView->Activated += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnActivated); + + CoreApplication::Suspending += + ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler(this, &SDL_WinRTApp::OnResuming); + + CoreApplication::Exiting += + ref new EventHandler(this, &SDL_WinRTApp::OnExiting); + + 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. + // + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. + //SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight Portrait PortraitUpsideDown"); // DavidL: this is no longer needed (for SDL_AddHintCallback) + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); +} + +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 + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // On Windows Phone, treat an orientation change as a change in window size. + // The native window's size doesn't seem to change, however SDL will simulate + // a window size change. + WINRT_ProcessWindowSizeChange(); +#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(this, &SDL_WinRTApp::OnWindowSizeChanged); + + window->VisibilityChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); + + window->Closed += + ref new TypedEventHandler(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(this, &SDL_WinRTApp::OnPointerPressed); + + window->PointerMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + + window->PointerReleased += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); + + window->PointerWheelChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + // Retrieves relative-only mouse movements: + Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); +#endif + + window->KeyDown += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); + + window->KeyUp += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + HardwareButtons::BackPressed += + ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); +#endif + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) + // Make sure we know when a user has opened the app's settings pane. + // This is needed in order to display a privacy policy, which needs + // to be done for network-enabled apps, as per Windows Store requirements. + using namespace Windows::UI::ApplicationSettings; + SettingsPane::GetForCurrentView()->CommandsRequested += + ref new TypedEventHandler + (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); +#endif +} + +void SDL_WinRTApp::Load(Platform::String^ entryPoint) +{ +} + +void SDL_WinRTApp::Run() +{ + SDL_SetMainReady(); + if (WINRT_SDLAppEntryPoint) + { + // TODO, WinRT: pass the C-style main() a reasonably realistic + // representation of command line arguments. + int argc = 0; + char **argv = NULL; + WINRT_SDLAppEntryPoint(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() +{ +} + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP +void SDL_WinRTApp::OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args) +{ + using namespace Platform; + using namespace Windows::UI::ApplicationSettings; + using namespace Windows::UI::Popups; + + String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy + String ^privacyPolicyLabel = nullptr; // label/link text + const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately + wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion + + // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint): + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + // Convert the privacy policy's URL to UCS2: + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyURL = ref new String(tmpStr); + SDL_free(tmpStr); + + // Optionally retrieve custom label-text for the link. If this isn't + // available, a default value will be used instead. + tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL); + if (tmpHintValue && tmpHintValue[0] != '\0') { + tmpStr = WIN_UTF8ToString(tmpHintValue); + privacyPolicyLabel = ref new String(tmpStr); + SDL_free(tmpStr); + } else { + privacyPolicyLabel = ref new String(L"Privacy Policy"); + } + + // Register the link, along with a handler to be called if and when it is + // clicked: + auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel, + ref new UICommandInvokedHandler([=](IUICommand ^) { + Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); + })); + args->Request->ApplicationCommands->Append(cmd); + } +} +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP + +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, WINRT_GlobalSDLWindow?=%s\n", + __FUNCTION__, + args->Size.Width, args->Size.Height, + (int)DisplayProperties::CurrentOrientation, + (int)DisplayProperties::NativeOrientation, + (int)DisplayProperties::AutoRotationPreferences, + (WINRT_GlobalSDLWindow ? "yes" : "no")); +#endif + + WINRT_ProcessWindowSizeChange(); +} + +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +{ +#if LOG_WINDOW_EVENTS==1 + SDL_Log("%s, visible?=%s, WINRT_GlobalSDLWindow?=%s\n", + __FUNCTION__, + (args->Visible ? "yes" : "no"), + (WINRT_GlobalSDLWindow ? "yes" : "no")); +#endif + + m_windowVisible = args->Visible; + if (WINRT_GlobalSDLWindow) { + SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid; + + if (args->Visible) { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0); + } else { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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. + WINRT_GlobalSDLWindow->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; +} + +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 (WINRT_GlobalSDLWindow) + { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); // TODO: see if SDL_WINDOWEVENT_SIZE_CHANGED should be getting triggered here (it is, currently) + SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0); + } + + SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); + SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); + + deferral->Complete(); + }); +} + +void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) +{ + SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); + SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); + + // 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 (WINRT_GlobalSDLWindow) + { + SDL_SendWindowEvent(WINRT_GlobalSDLWindow, 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); + } +} + +void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) +{ + SDL_SendAppEvent(SDL_APP_TERMINATING); +} + +static void +WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +{ + Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + WINRT_GetSDLButtonForPointerPoint(pt)); +} + +void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +{ +#if LOG_POINTER_EVENTS + WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); +#endif + + WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); +} + +void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) +{ + WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); +} + +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyDownEvent(args); +} + +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +{ + WINRT_ProcessKeyUpEvent(args); +} + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args) +{ + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK); + const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON); if (hint) { if (*hint == '1') { args->Handled = true; } - } -} -#endif - + } +} +#endif + diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index fcf37a149..07e4a8048 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -1,58 +1,58 @@ -#pragma once - -#include - -extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); - -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 - void PumpEvents(); - -protected: - // Event Handlers. - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) - void OnSettingsPaneCommandsRequested( - Windows::UI::ApplicationSettings::SettingsPane ^p, - Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args); -#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP - - 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 OnExiting(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); - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); -#endif - -private: - bool m_windowClosed; - bool m_windowVisible; -}; - -extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; +#pragma once + +#include + +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); + +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 + void PumpEvents(); + +protected: + // Event Handlers. + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP // for Windows 8/8.1/RT apps... (and not Phone apps) + void OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args); +#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP + + 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 OnExiting(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); + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); +#endif + +private: + bool m_windowClosed; + bool m_windowVisible; +}; + +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 73e9846aa..a5fe56a2d 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -1,765 +1,765 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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" - -#if defined(__WIN32__) -#include "../core/windows/SDL_windows.h" -#endif - - -/* 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 */ - -#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 */ - } - 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: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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" + +#if defined(__WIN32__) +#include "../core/windows/SDL_windows.h" +#endif + + +/* 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 */ + +#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 */ + } + 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: */ diff --git a/src/filesystem/winrt/SDL_sysfilesystem.cpp b/src/filesystem/winrt/SDL_sysfilesystem.cpp index 2e9f7e710..53dbaebe8 100644 --- a/src/filesystem/winrt/SDL_sysfilesystem.cpp +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -1,154 +1,154 @@ -/* TODO, WinRT: include copyright info in SDL_winrtpaths.cpp - TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all -*/ - -#include "SDL_config.h" - -#ifdef __WINRT__ - -extern "C" { -#include "SDL_filesystem.h" -#include "SDL_error.h" -#include "SDL_stdinc.h" -#include "SDL_system.h" -#include "../../core/windows/SDL_windows.h" -} - -#include -#include - -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 UTF8PathMap; - static UTF8PathMap utf8Paths; - - UTF8PathMap::iterator searchResult = utf8Paths.find(pathType); - if (searchResult != utf8Paths.end()) { - return searchResult->second.c_str(); - } - - const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType); - if (!ucs2Path) { - return NULL; - } - - char * utf8Path = WIN_StringToUTF8(ucs2Path); - utf8Paths[pathType] = utf8Path; - SDL_free(utf8Path); - return utf8Paths[pathType].c_str(); -} - -extern "C" char * -SDL_GetBasePath(void) -{ - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION); - size_t destPathLen; - char * destPath = NULL; - - if (!srcPath) { - SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); - return NULL; - } - - destPathLen = SDL_strlen(srcPath) + 2; - destPath = (char *) SDL_malloc(destPathLen); - if (!destPath) { - SDL_OutOfMemory(); - return NULL; - } - - SDL_snprintf(destPath, destPathLen, "%s\\", srcPath); - return destPath; -} - -extern "C" char * -SDL_GetPrefPath(const char *org, const char *app) -{ - /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and - * earlier is not available on WinRT or Windows Phone. WinRT provides - * a similar API, but SHGetFolderPath can't be called, at least not - * without violating Microsoft's app-store requirements. - */ - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */ - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER); -#else - /* A 'Roaming' folder is available on Windows 8 and 8.1. Use that. */ - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_ROAMING_FOLDER); -#endif - - size_t destPathLen; - char * destPath = NULL; - - if (!srcPath) { - SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); - return NULL; - } - - destPathLen = SDL_strlen(srcPath) + SDL_strlen(org) + SDL_strlen(app) + 4; - destPath = (char *) SDL_malloc(destPathLen); - if (!destPath) { - SDL_OutOfMemory(); - return NULL; - } - - SDL_snprintf(destPath, destPathLen, "%s\\%s\\%s\\", srcPath, org, app); - return destPath; -} - -#endif /* __WINRT__ */ +/* TODO, WinRT: include copyright info in SDL_winrtpaths.cpp + TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all +*/ + +#include "SDL_config.h" + +#ifdef __WINRT__ + +extern "C" { +#include "SDL_filesystem.h" +#include "SDL_error.h" +#include "SDL_stdinc.h" +#include "SDL_system.h" +#include "../../core/windows/SDL_windows.h" +} + +#include +#include + +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 UTF8PathMap; + static UTF8PathMap utf8Paths; + + UTF8PathMap::iterator searchResult = utf8Paths.find(pathType); + if (searchResult != utf8Paths.end()) { + return searchResult->second.c_str(); + } + + const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType); + if (!ucs2Path) { + return NULL; + } + + char * utf8Path = WIN_StringToUTF8(ucs2Path); + utf8Paths[pathType] = utf8Path; + SDL_free(utf8Path); + return utf8Paths[pathType].c_str(); +} + +extern "C" char * +SDL_GetBasePath(void) +{ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION); + size_t destPathLen; + char * destPath = NULL; + + if (!srcPath) { + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); + return NULL; + } + + destPathLen = SDL_strlen(srcPath) + 2; + destPath = (char *) SDL_malloc(destPathLen); + if (!destPath) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(destPath, destPathLen, "%s\\", srcPath); + return destPath; +} + +extern "C" char * +SDL_GetPrefPath(const char *org, const char *app) +{ + /* WinRT note: The 'SHGetFolderPath' API that is used in Windows 7 and + * earlier is not available on WinRT or Windows Phone. WinRT provides + * a similar API, but SHGetFolderPath can't be called, at least not + * without violating Microsoft's app-store requirements. + */ + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + /* A 'Roaming' folder is not available in Windows Phone 8, however a 'Local' folder is. */ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_LOCAL_FOLDER); +#else + /* A 'Roaming' folder is available on Windows 8 and 8.1. Use that. */ + const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_ROAMING_FOLDER); +#endif + + size_t destPathLen; + char * destPath = NULL; + + if (!srcPath) { + SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); + return NULL; + } + + destPathLen = SDL_strlen(srcPath) + SDL_strlen(org) + SDL_strlen(app) + 4; + destPath = (char *) SDL_malloc(destPathLen); + if (!destPath) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(destPath, destPathLen, "%s\\%s\\%s\\", srcPath, org, app); + return destPath; +} + +#endif /* __WINRT__ */ diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index f739c5706..f1f469c98 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -1,1247 +1,1247 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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); - } -} - -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] ) { - size_t 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 + + 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); + } +} + +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] ) { + size_t 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: */ diff --git a/src/main/winrt/SDL_winrt_main_NonXAML.cpp b/src/main/winrt/SDL_winrt_main_NonXAML.cpp index 19eb7b919..088cd6c32 100644 --- a/src/main/winrt/SDL_winrt_main_NonXAML.cpp +++ b/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -1,56 +1,56 @@ - -#include -#include - -/* At least one file in any SDL/WinRT app appears to require compilation - with C++/CX, otherwise a Windows Metadata file won't get created, and - an APPX0702 build error can appear shortly after linking. - - The following set of preprocessor code forces this file to be compiled - as C++/CX, which appears to cause Visual C++ 2012's build tools to - create this .winmd file, and will help allow builds of SDL/WinRT apps - to proceed without error. - - If other files in an app's project enable C++/CX compilation, then it might - be possible for SDL_winrt_main_NonXAML.cpp to be compiled without /ZW, - for Visual C++'s build tools to create a winmd file, and for the app to - build without APPX0702 errors. In this case, if - SDL_WINRT_METADATA_FILE_AVAILABLE is defined as a C/C++ macro, then - the #error (to force C++/CX compilation) will be disabled. - - Please note that /ZW can be specified on a file-by-file basis. To do this, - right click on the file in Visual C++, click Properties, then change the - setting through the dialog that comes up. -*/ -#ifndef SDL_WINRT_METADATA_FILE_AVAILABLE -#ifndef __cplusplus_winrt -#error SDL_winrt_main_NonXAML.cpp must be compiled with /ZW, otherwise build errors due to missing .winmd files can occur. -#endif -#endif - -/* Prevent MSVC++ from warning about threading models when defining our - custom WinMain. The threading model will instead be set via a direct - call to Windows::Foundation::Initialize (rather than via an attributed - function). - - To note, this warning (C4447) does not seem to come up unless this file - is compiled with C++/CX enabled (via the /ZW compiler flag). -*/ -#ifdef _MSC_VER -#pragma warning(disable:4447) -#endif - -/* Make sure the function to initialize the Windows Runtime gets linked in. */ -#ifdef _MSC_VER -#pragma comment(lib, "runtimeobject.lib") -#endif - -int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { - return 1; - } - - SDL_WinRTRunApp(SDL_main, NULL); - return 0; -} + +#include +#include + +/* At least one file in any SDL/WinRT app appears to require compilation + with C++/CX, otherwise a Windows Metadata file won't get created, and + an APPX0702 build error can appear shortly after linking. + + The following set of preprocessor code forces this file to be compiled + as C++/CX, which appears to cause Visual C++ 2012's build tools to + create this .winmd file, and will help allow builds of SDL/WinRT apps + to proceed without error. + + If other files in an app's project enable C++/CX compilation, then it might + be possible for SDL_winrt_main_NonXAML.cpp to be compiled without /ZW, + for Visual C++'s build tools to create a winmd file, and for the app to + build without APPX0702 errors. In this case, if + SDL_WINRT_METADATA_FILE_AVAILABLE is defined as a C/C++ macro, then + the #error (to force C++/CX compilation) will be disabled. + + Please note that /ZW can be specified on a file-by-file basis. To do this, + right click on the file in Visual C++, click Properties, then change the + setting through the dialog that comes up. +*/ +#ifndef SDL_WINRT_METADATA_FILE_AVAILABLE +#ifndef __cplusplus_winrt +#error SDL_winrt_main_NonXAML.cpp must be compiled with /ZW, otherwise build errors due to missing .winmd files can occur. +#endif +#endif + +/* Prevent MSVC++ from warning about threading models when defining our + custom WinMain. The threading model will instead be set via a direct + call to Windows::Foundation::Initialize (rather than via an attributed + function). + + To note, this warning (C4447) does not seem to come up unless this file + is compiled with C++/CX enabled (via the /ZW compiler flag). +*/ +#ifdef _MSC_VER +#pragma warning(disable:4447) +#endif + +/* Make sure the function to initialize the Windows Runtime gets linked in. */ +#ifdef _MSC_VER +#pragma comment(lib, "runtimeobject.lib") +#endif + +int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { + return 1; + } + + SDL_WinRTRunApp(SDL_main, NULL); + return 0; +} diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 319b5c910..58a7ede22 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -64,18 +64,18 @@ static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_ static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR; /* Vertex shader, common values */ -struct VertexShaderConstants -{ - DirectX::XMFLOAT4X4 model; - DirectX::XMFLOAT4X4 projectionAndView; +struct VertexShaderConstants +{ + DirectX::XMFLOAT4X4 model; + DirectX::XMFLOAT4X4 projectionAndView; }; /* Per-vertex data */ -struct VertexPositionColor -{ - DirectX::XMFLOAT3 pos; - DirectX::XMFLOAT2 tex; - DirectX::XMFLOAT4 color; +struct VertexPositionColor +{ + DirectX::XMFLOAT3 pos; + DirectX::XMFLOAT2 tex; + DirectX::XMFLOAT4 color; }; /* Per-texture data */ @@ -83,7 +83,7 @@ typedef struct { Microsoft::WRL::ComPtr mainTexture; Microsoft::WRL::ComPtr mainTextureResourceView; - Microsoft::WRL::ComPtr mainTextureRenderTargetView; + Microsoft::WRL::ComPtr mainTextureRenderTargetView; SDL_PixelFormat * pixelFormat; Microsoft::WRL::ComPtr stagingTexture; DirectX::XMINT2 lockedTexturePosition; @@ -94,18 +94,18 @@ typedef struct typedef struct { Microsoft::WRL::ComPtr d3dDevice; - Microsoft::WRL::ComPtr d3dContext; - Microsoft::WRL::ComPtr swapChain; - Microsoft::WRL::ComPtr mainRenderTargetView; - Microsoft::WRL::ComPtr currentOffscreenRenderTargetView; - Microsoft::WRL::ComPtr inputLayout; - Microsoft::WRL::ComPtr vertexBuffer; - Microsoft::WRL::ComPtr vertexShader; - Microsoft::WRL::ComPtr texturePixelShader; - Microsoft::WRL::ComPtr colorPixelShader; - Microsoft::WRL::ComPtr blendModeBlend; - Microsoft::WRL::ComPtr blendModeAdd; - Microsoft::WRL::ComPtr blendModeMod; + Microsoft::WRL::ComPtr d3dContext; + Microsoft::WRL::ComPtr swapChain; + Microsoft::WRL::ComPtr mainRenderTargetView; + Microsoft::WRL::ComPtr currentOffscreenRenderTargetView; + Microsoft::WRL::ComPtr inputLayout; + Microsoft::WRL::ComPtr vertexBuffer; + Microsoft::WRL::ComPtr vertexShader; + Microsoft::WRL::ComPtr texturePixelShader; + Microsoft::WRL::ComPtr colorPixelShader; + Microsoft::WRL::ComPtr blendModeBlend; + Microsoft::WRL::ComPtr blendModeAdd; + Microsoft::WRL::ComPtr blendModeMod; Microsoft::WRL::ComPtr nearestPixelSampler; Microsoft::WRL::ComPtr linearSampler; D3D_FEATURE_LEVEL featureLevel; @@ -120,11 +120,11 @@ typedef struct Microsoft::WRL::ComPtr vertexShaderConstants; // Cached renderer properties. - DirectX::XMFLOAT2 windowSizeInDIPs; + DirectX::XMFLOAT2 windowSizeInDIPs; DirectX::XMFLOAT2 renderTargetSize; Windows::Graphics::Display::DisplayOrientations orientation; - // Transform used for display orientation. + // Transform used for display orientation. DirectX::XMFLOAT4X4 orientationTransform3D; } D3D11_RenderData; @@ -134,123 +134,123 @@ typedef struct SDL's shaders are compiled into SDL itself, to simplify distribution. All Direct3D 11.x shaders were compiled with the following: - - fxc /E"main" /T "" /Fo"" "" - - Variables: - - : the type of shader. A table of utilized shader types is - listed below. - - : where to store compiled output - - : where to read shader source code from - - Shader types: - - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT - - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT - - ps_4_0_level_9_3: Pixel shader for Windows Phone 8 - - vs_4_0_level_9_3: Vertex shader for Windows Phone 8 - - - Shader object code was converted to a list of DWORDs via the following - *nix style command (available separately from Windows + MSVC): - - hexdump -v -e '6/4 "0x%08.8x, " "\n"' - */ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -#define D3D11_USE_SHADER_MODEL_4_0_level_9_3 -#else -#define D3D11_USE_SHADER_MODEL_4_0_level_9_1 -#endif - -/* The texture-rendering pixel shader: - - --- D3D11_PixelShader_Textures.hlsl --- - 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; - } -*/ -#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) -static const DWORD D3D11_PixelShader_Textures[] = { - 0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001, - 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, - 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, - 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, - 0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, - 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, - 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, - 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, - 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, - 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, - 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, - 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, - 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, - 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, - 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, - 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, - 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, - 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, - 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, - 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, - 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, - 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, - 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, - 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, - 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, - 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, - 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, - 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 + + fxc /E"main" /T "" /Fo"" "" + + Variables: + - : the type of shader. A table of utilized shader types is + listed below. + - : where to store compiled output + - : where to read shader source code from + + Shader types: + - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT + - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT + - ps_4_0_level_9_3: Pixel shader for Windows Phone 8 + - vs_4_0_level_9_3: Vertex shader for Windows Phone 8 + + + Shader object code was converted to a list of DWORDs via the following + *nix style command (available separately from Windows + MSVC): + + hexdump -v -e '6/4 "0x%08.8x, " "\n"' + */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define D3D11_USE_SHADER_MODEL_4_0_level_9_3 +#else +#define D3D11_USE_SHADER_MODEL_4_0_level_9_1 +#endif + +/* The texture-rendering pixel shader: + + --- D3D11_PixelShader_Textures.hlsl --- + 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; + } +*/ +#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) +static const DWORD D3D11_PixelShader_Textures[] = { + 0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001, + 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, + 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, + 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, + 0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000, + 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, + 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, + 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, + 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, + 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, + 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, + 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, + 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, + 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, + 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, + 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, + 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 }; #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) static const DWORD D3D11_PixelShader_Textures[] = { - 0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001, - 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, - 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, - 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, - 0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000, - 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, - 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, - 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, - 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, - 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, - 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, - 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, - 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, - 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, - 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, - 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, - 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, - 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, - 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, - 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, - 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, - 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, - 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, - 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, - 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, - 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, - 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, - 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001, + 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8, + 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200, + 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001, + 0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000, + 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800, + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000, + 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, + 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000, + 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062, + 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, + 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2, + 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000, + 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003, + 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8, + 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100, + 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005, + 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874, + 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263, + 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43, + 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 }; #else @@ -260,72 +260,72 @@ static const DWORD D3D11_PixelShader_Textures[] = { /* The color-only-rendering pixel shader: --- D3D11_PixelShader_Colors.hlsl --- - struct PixelShaderInput - { - float4 pos : SV_POSITION; - float2 tex : TEXCOORD0; - float4 color : COLOR0; - }; - - float4 main(PixelShaderInput input) : SV_TARGET - { - return input.color; - } -*/ + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + float4 main(PixelShaderInput input) : SV_TARGET + { + return input.color; + } +*/ #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) -static const DWORD D3D11_PixelShader_Colors[] = { - 0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001, - 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, - 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, - 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, - 0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, - 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, - 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, - 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, - 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, - 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, - 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, - 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, - 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, - 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, - 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, - 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, - 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, - 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 -}; -#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) -static const DWORD D3D11_PixelShader_Colors[] = { - 0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001, - 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, - 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, - 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, - 0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, - 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, - 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, - 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, - 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, - 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, - 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, - 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, - 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, - 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, - 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, - 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, - 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, - 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 -}; +static const DWORD D3D11_PixelShader_Colors[] = { + 0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001, + 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, + 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, + 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, + 0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, + 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, + 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, + 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 +}; +#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) +static const DWORD D3D11_PixelShader_Colors[] = { + 0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001, + 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140, + 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200, + 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000, + 0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001, + 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, + 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000, + 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d, + 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, + 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438, + 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, + 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, + 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000, + 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f, + 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054 +}; #else #error "An appropriate 'colors' pixel shader is not defined." #endif @@ -333,170 +333,170 @@ static const DWORD D3D11_PixelShader_Colors[] = { /* The sole vertex shader: --- D3D11_VertexShader.hlsl --- - #pragma pack_matrix( row_major ) - - cbuffer VertexShaderConstants : register(b0) - { - matrix model; - matrix projectionAndView; - }; - - 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, projectionAndView); - output.pos = pos; - - // Pass through texture coordinates and color values without transformation - output.tex = input.tex; - output.color = input.color; - - return output; - } + #pragma pack_matrix( row_major ) + + cbuffer VertexShaderConstants : register(b0) + { + matrix model; + matrix projectionAndView; + }; + + 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, projectionAndView); + output.pos = pos; + + // Pass through texture coordinates and color values without transformation + output.tex = input.tex; + output.color = input.color; + + return output; + } */ #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1) static const DWORD D3D11_VertexShader[] = { - 0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001, - 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, - 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, - 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, - 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200, - 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, - 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, - 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, - 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, - 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, - 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, - 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, - 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, - 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, - 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, - 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, - 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, - 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, - 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, - 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, - 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, - 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, - 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, - 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, - 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, - 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, - 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, - 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, - 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, - 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, - 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, - 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, - 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, - 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, - 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, - 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, - 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, - 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, - 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, - 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, - 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, - 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, - 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, - 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, - 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, - 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, - 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, - 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, - 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, - 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, - 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, - 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001, + 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, + 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, + 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200, + 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, + 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, + 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, + 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, + 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, + 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, + 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, + 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, + 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, + 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, + 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, + 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, + 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, + 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, + 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, + 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, + 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, + 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, + 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, + 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, + 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, + 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, + 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, + 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, + 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, + 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, + 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, + 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, + 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, + 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f }; #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3) static const DWORD D3D11_VertexShader[] = { - 0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001, - 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, - 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, - 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, - 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201, - 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, - 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, - 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, - 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, - 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, - 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, - 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, - 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, - 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, - 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, - 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, - 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, - 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, - 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, - 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, - 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, - 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, - 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, - 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, - 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, - 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, - 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, - 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, - 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, - 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, - 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, - 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, - 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, - 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, - 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, - 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, - 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, - 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, - 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, - 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, - 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, - 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, - 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, - 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, - 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, - 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, - 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, - 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, - 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, - 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, - 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, - 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, - 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, - 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, - 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f + 0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001, + 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0, + 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200, + 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000, + 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201, + 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001, + 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000, + 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000, + 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002, + 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000, + 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001, + 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004, + 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000, + 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000, + 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002, + 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059, + 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000, + 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002, + 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, + 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002, + 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, + 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003, + 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46, + 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006, + 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001, + 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46, + 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, + 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007, + 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046, + 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002, + 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000, + 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054, + 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174, + 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000, + 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4, + 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000, + 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077, + 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, + 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, + 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059, + 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062, + 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50, + 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f, + 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, + 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000, + 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f }; #else #error "An appropriate vertex shader is not defined." @@ -576,76 +576,76 @@ DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) { 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; - } + 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; + } } -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->UpdateClipRect = D3D11_UpdateClipRect; - 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; +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->UpdateClipRect = D3D11_UpdateClipRect; + 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 @@ -669,353 +669,353 @@ D3D11_CreateBlendMode(SDL_Renderer * renderer, { 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 = srcBlendAlpha; - blendDesc.RenderTarget[0].DestBlendAlpha = destBlendAlpha; - 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__ ", ID3D11Device1::CreateBlendState", result); - return result; - } - - return 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 = srcBlendAlpha; + blendDesc.RenderTarget[0].DestBlendAlpha = destBlendAlpha; + 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__ ", ID3D11Device1::CreateBlendState", 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; - - // Make sure Direct3D's debugging feature gets used, if the app requests it. +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; + + // Make sure Direct3D's debugging feature gets used, if the app requests it. const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); if (hint) { if (*hint == '1') { creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } - } - - // 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 device; - ComPtr 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__ ", D3D11CreateDevice", result); - return result; - } - - // Get the Direct3D 11.1 API device and context interfaces. - result = device.As(&(data->d3dDevice)); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result); - return result; - } - - result = context.As(&data->d3dContext); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", 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: - // - result = data->d3dDevice->CreateVertexShader( - D3D11_VertexShader, - sizeof(D3D11_VertexShader), - nullptr, - &data->vertexShader - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", 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), - D3D11_VertexShader, - sizeof(D3D11_VertexShader), - &data->inputLayout - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result); - return result; - } - - // - // Load in SDL's pixel shaders - // - - result = data->d3dDevice->CreatePixelShader( - D3D11_PixelShader_Textures, - sizeof(D3D11_PixelShader_Textures), - nullptr, - &data->texturePixelShader - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result); - return result; - } - - result = data->d3dDevice->CreatePixelShader( - D3D11_PixelShader_Colors, - sizeof(D3D11_PixelShader_Colors), - nullptr, - &data->colorPixelShader - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result); - return result; - } - - // - // Setup space to hold vertex shader constants: - // - CD3D11_BUFFER_DESC constantBufferDesc(sizeof(VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER); - result = data->d3dDevice->CreateBuffer( - &constantBufferDesc, - nullptr, - &data->vertexShaderConstants - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result); - return result; - } - - // - // Make sure that the vertex buffer, if already created, gets freed. - // It will be recreated later. - // - data->vertexBuffer = nullptr; - - // - // Create samplers to use when drawing textures: - // - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = SDL_D3D11_NEAREST_PIXEL_FILTER; - 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->nearestPixelSampler - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result); - return result; - } - - samplerDesc.Filter = SDL_D3D11_LINEAR_FILTER; - result = data->d3dDevice->CreateSamplerState( - &samplerDesc, - &data->linearSampler - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result); - return result; - } - - // - // Setup Direct3D rasterizer states - // - 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__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result); - return result; - } - - rasterDesc.ScissorEnable = true; - result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->clippedRasterizer); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result); - return result; - } - - // - // Create blending states: - // - result = D3D11_CreateBlendMode( - renderer, - TRUE, - D3D11_BLEND_SRC_ALPHA, /* srcBlend */ - D3D11_BLEND_INV_SRC_ALPHA, /* destBlend */ - D3D11_BLEND_ONE, /* srcBlendAlpha */ - D3D11_BLEND_INV_SRC_ALPHA, /* destBlendAlpha */ - &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, /* srcBlend */ - D3D11_BLEND_ONE, /* destBlend */ - D3D11_BLEND_ZERO, /* srcBlendAlpha */ - D3D11_BLEND_ONE, /* destBlendAlpha */ - &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, /* srcBlend */ - D3D11_BLEND_SRC_COLOR, /* destBlend */ - D3D11_BLEND_ZERO, /* srcBlendAlpha */ - D3D11_BLEND_ONE, /* destBlendAlpha */ - &data->blendModeMod); - if (FAILED(result)) { - // D3D11_CreateBlendMode will set the SDL error, if it fails - return result; - } - - // - // All done! - // - return S_OK; + } + + // 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 device; + ComPtr 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__ ", D3D11CreateDevice", result); + return result; + } + + // Get the Direct3D 11.1 API device and context interfaces. + result = device.As(&(data->d3dDevice)); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result); + return result; + } + + result = context.As(&data->d3dContext); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", 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: + // + result = data->d3dDevice->CreateVertexShader( + D3D11_VertexShader, + sizeof(D3D11_VertexShader), + nullptr, + &data->vertexShader + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", 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), + D3D11_VertexShader, + sizeof(D3D11_VertexShader), + &data->inputLayout + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result); + return result; + } + + // + // Load in SDL's pixel shaders + // + + result = data->d3dDevice->CreatePixelShader( + D3D11_PixelShader_Textures, + sizeof(D3D11_PixelShader_Textures), + nullptr, + &data->texturePixelShader + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result); + return result; + } + + result = data->d3dDevice->CreatePixelShader( + D3D11_PixelShader_Colors, + sizeof(D3D11_PixelShader_Colors), + nullptr, + &data->colorPixelShader + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result); + return result; + } + + // + // Setup space to hold vertex shader constants: + // + CD3D11_BUFFER_DESC constantBufferDesc(sizeof(VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER); + result = data->d3dDevice->CreateBuffer( + &constantBufferDesc, + nullptr, + &data->vertexShaderConstants + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result); + return result; + } + + // + // Make sure that the vertex buffer, if already created, gets freed. + // It will be recreated later. + // + data->vertexBuffer = nullptr; + + // + // Create samplers to use when drawing textures: + // + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = SDL_D3D11_NEAREST_PIXEL_FILTER; + 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->nearestPixelSampler + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result); + return result; + } + + samplerDesc.Filter = SDL_D3D11_LINEAR_FILTER; + result = data->d3dDevice->CreateSamplerState( + &samplerDesc, + &data->linearSampler + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result); + return result; + } + + // + // Setup Direct3D rasterizer states + // + 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__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result); + return result; + } + + rasterDesc.ScissorEnable = true; + result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->clippedRasterizer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result); + return result; + } + + // + // Create blending states: + // + result = D3D11_CreateBlendMode( + renderer, + TRUE, + D3D11_BLEND_SRC_ALPHA, /* srcBlend */ + D3D11_BLEND_INV_SRC_ALPHA, /* destBlend */ + D3D11_BLEND_ONE, /* srcBlendAlpha */ + D3D11_BLEND_INV_SRC_ALPHA, /* destBlendAlpha */ + &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, /* srcBlend */ + D3D11_BLEND_ONE, /* destBlend */ + D3D11_BLEND_ZERO, /* srcBlendAlpha */ + D3D11_BLEND_ONE, /* destBlendAlpha */ + &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, /* srcBlend */ + D3D11_BLEND_SRC_COLOR, /* destBlend */ + D3D11_BLEND_ZERO, /* srcBlendAlpha */ + D3D11_BLEND_ONE, /* destBlendAlpha */ + &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_WINRT) { - 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; + +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_WINRT) { + 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. +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 @@ -1033,27 +1033,27 @@ D3D11_GetRotationForOrientation(Windows::Graphics::Display::DisplayOrientations // // Windows Phone rotations // - case DisplayOrientations::Landscape: - return DXGI_MODE_ROTATION_ROTATE90; - case DisplayOrientations::Portrait: - return DXGI_MODE_ROTATION_IDENTITY; - case DisplayOrientations::LandscapeFlipped: - return DXGI_MODE_ROTATION_ROTATE270; - case DisplayOrientations::PortraitFlipped: - return DXGI_MODE_ROTATION_ROTATE180; + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_ROTATE90; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE180; #else // // Non-Windows-Phone rotations (ex: Windows 8, Windows RT) - // - case DisplayOrientations::Landscape: - return DXGI_MODE_ROTATION_IDENTITY; - case DisplayOrientations::Portrait: - return DXGI_MODE_ROTATION_ROTATE270; - case DisplayOrientations::LandscapeFlipped: - return DXGI_MODE_ROTATION_ROTATE180; - case DisplayOrientations::PortraitFlipped: - return DXGI_MODE_ROTATION_ROTATE90; -#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + // + case DisplayOrientations::Landscape: + return DXGI_MODE_ROTATION_IDENTITY; + case DisplayOrientations::Portrait: + return DXGI_MODE_ROTATION_ROTATE270; + case DisplayOrientations::LandscapeFlipped: + return DXGI_MODE_ROTATION_ROTATE180; + case DisplayOrientations::PortraitFlipped: + return DXGI_MODE_ROTATION_ROTATE90; +#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP default: return DXGI_MODE_ROTATION_UNSPECIFIED; @@ -1084,9 +1084,9 @@ D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec outRect->bottom = sdlRect->y + sdlRect->h; break; case DXGI_MODE_ROTATION_ROTATE270: - outRect->left = sdlRect->y; - outRect->right = sdlRect->y + sdlRect->h; - outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w; + outRect->left = sdlRect->y; + outRect->right = sdlRect->y + sdlRect->h; + outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w; outRect->bottom = renderer->viewport.w - sdlRect->x; break; case DXGI_MODE_ROTATION_ROTATE180: @@ -1098,7 +1098,7 @@ D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec case DXGI_MODE_ROTATION_ROTATE90: outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h; outRect->right = renderer->viewport.h - sdlRect->y; - outRect->top = sdlRect->x; + outRect->top = sdlRect->x; outRect->bottom = sdlRect->x + sdlRect->h; break; default: @@ -1110,24 +1110,24 @@ D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec // Initialize all resources that change when the window's size changes. // TODO, WinRT: 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 nativeWindowBounds; - if (coreWindow) { - result = coreWindow->get_Bounds(&nativeWindowBounds); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__", ICoreWindow::get_Bounds [get native-window bounds]", result); - return result; - } - } else { - // TODO, WinRT, XAML: clean up window-bounds code in D3D11_CreateWindowSizeDependentResources +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 nativeWindowBounds; + if (coreWindow) { + result = coreWindow->get_Bounds(&nativeWindowBounds); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__", ICoreWindow::get_Bounds [get native-window bounds]", result); + return result; + } + } else { + // TODO, WinRT, XAML: clean up window-bounds code in D3D11_CreateWindowSizeDependentResources SDL_DisplayMode displayMode; if (SDL_GetDesktopDisplayMode(0, &displayMode) < 0) { SDL_SetError(__FUNCTION__", Get Window Bounds (XAML): Unable to retrieve the native window's size"); @@ -1135,222 +1135,222 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) } nativeWindowBounds.Width = (FLOAT) displayMode.w; - nativeWindowBounds.Height = (FLOAT) displayMode.h; - } - - // TODO, WinRT, XAML: see if window/control sizes are in DIPs, or something else. If something else, then adjust renderer size tracking accordingly. - data->windowSizeInDIPs.x = nativeWindowBounds.Width; - data->windowSizeInDIPs.y = nativeWindowBounds.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; - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - const bool swapDimensions = false; -#else - const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); -#endif - 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(data->renderTargetSize.x), - static_cast(data->renderTargetSize.y), - DXGI_FORMAT_B8G8R8A8_UNORM, - 0 - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::ResizeBuffers", result); - return result; - } - } - else - { - const bool usingXAML = (coreWindow == nullptr); - - // Otherwise, create a new one using the same adapter as the existing Direct3D device. - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; - swapChainDesc.Width = static_cast(data->renderTargetSize.x); // Match the size of the window. - swapChainDesc.Height = static_cast(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 - if (usingXAML) { - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - } 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 dxgiDevice; - result = data->d3dDevice.As(&dxgiDevice); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1 to IDXGIDevice1", result); - return result; - } - - ComPtr dxgiAdapter; - result = dxgiDevice->GetAdapter(&dxgiAdapter); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::GetAdapter", result); - return result; - } - - ComPtr dxgiFactory; - result = dxgiAdapter->GetParent( - __uuidof(IDXGIFactory2), - &dxgiFactory - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter::GetParent", result); - return result; - } - - if (usingXAML) { - result = dxgiFactory->CreateSwapChainForComposition( - data->d3dDevice.Get(), - &swapChainDesc, - nullptr, - &data->swapChain); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result); - return result; - } - -#if WINAPI_FAMILY == WINAPI_FAMILY_APP - result = WINRT_GlobalSwapChainBackgroundPanelNative->SetSwapChain(data->swapChain.Get()); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result); - return result; - } -#else - SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone"); - return E_FAIL; -#endif - } else { - IUnknown * coreWindowAsIUnknown = nullptr; - result = coreWindow->QueryInterface(&coreWindowAsIUnknown); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow 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__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", 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__ ", IDXGIDevice1::SetMaximumFrameLatency", result); - return result; - } - } - -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - // Set the proper orientation for the swap chain, and generate the - // 3D matrix transformation for rendering to the rotated swap chain. - // - // To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary - // on Windows Phone, nor is it supported there. It's only needed in Windows 8/RT. - DXGI_MODE_ROTATION rotation = D3D11_GetRotationForOrientation(data->orientation); - result = data->swapChain->SetRotation(rotation); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation" , result); - return result; - } -#endif - - // Create a render target view of the swap chain back buffer. - ComPtr backBuffer; - result = data->swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [back-buffer]", result); - return result; - } - - result = data->d3dDevice->CreateRenderTargetView( - backBuffer.Get(), - nullptr, - &data->mainRenderTargetView - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result); - return result; - } - - if (D3D11_UpdateViewport(renderer) != 0) { - // D3D11_UpdateViewport will set the SDL error if it fails. - return E_FAIL; - } - - return S_OK; + nativeWindowBounds.Height = (FLOAT) displayMode.h; + } + + // TODO, WinRT, XAML: see if window/control sizes are in DIPs, or something else. If something else, then adjust renderer size tracking accordingly. + data->windowSizeInDIPs.x = nativeWindowBounds.Width; + data->windowSizeInDIPs.y = nativeWindowBounds.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; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + const bool swapDimensions = false; +#else + const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); +#endif + 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(data->renderTargetSize.x), + static_cast(data->renderTargetSize.y), + DXGI_FORMAT_B8G8R8A8_UNORM, + 0 + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::ResizeBuffers", result); + return result; + } + } + else + { + const bool usingXAML = (coreWindow == nullptr); + + // Otherwise, create a new one using the same adapter as the existing Direct3D device. + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; + swapChainDesc.Width = static_cast(data->renderTargetSize.x); // Match the size of the window. + swapChainDesc.Height = static_cast(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 + if (usingXAML) { + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + } 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 dxgiDevice; + result = data->d3dDevice.As(&dxgiDevice); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1 to IDXGIDevice1", result); + return result; + } + + ComPtr dxgiAdapter; + result = dxgiDevice->GetAdapter(&dxgiAdapter); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::GetAdapter", result); + return result; + } + + ComPtr dxgiFactory; + result = dxgiAdapter->GetParent( + __uuidof(IDXGIFactory2), + &dxgiFactory + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter::GetParent", result); + return result; + } + + if (usingXAML) { + result = dxgiFactory->CreateSwapChainForComposition( + data->d3dDevice.Get(), + &swapChainDesc, + nullptr, + &data->swapChain); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result); + return result; + } + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP + result = WINRT_GlobalSwapChainBackgroundPanelNative->SetSwapChain(data->swapChain.Get()); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result); + return result; + } +#else + SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone"); + return E_FAIL; +#endif + } else { + IUnknown * coreWindowAsIUnknown = nullptr; + result = coreWindow->QueryInterface(&coreWindowAsIUnknown); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow 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__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", 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__ ", IDXGIDevice1::SetMaximumFrameLatency", result); + return result; + } + } + +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + // Set the proper orientation for the swap chain, and generate the + // 3D matrix transformation for rendering to the rotated swap chain. + // + // To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary + // on Windows Phone, nor is it supported there. It's only needed in Windows 8/RT. + DXGI_MODE_ROTATION rotation = D3D11_GetRotationForOrientation(data->orientation); + result = data->swapChain->SetRotation(rotation); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation" , result); + return result; + } +#endif + + // Create a render target view of the swap chain back buffer. + ComPtr backBuffer; + result = data->swapChain->GetBuffer( + 0, + __uuidof(ID3D11Texture2D), + &backBuffer + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [back-buffer]", result); + return result; + } + + result = data->d3dDevice->CreateRenderTargetView( + backBuffer.Get(), + nullptr, + &data->mainRenderTargetView + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", 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__ ", ICoreWindow::get_Bounds [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)) { - /* D3D11_CreateWindowSizeDependentResources will set the SDL error */ - return result; - } - } - - return S_OK; +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__ ", ICoreWindow::get_Bounds [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)) { + /* D3D11_CreateWindowSizeDependentResources will set the SDL error */ + return result; + } + } + + return S_OK; } HRESULT @@ -1359,22 +1359,22 @@ 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)) { - /* D3D11_CreateDeviceResources will set the SDL error */ - return result; - } - - result = D3D11_UpdateForWindowSizeChange(renderer); - if (FAILED(result)) { - /* D3D11_UpdateForWindowSizeChange will set the SDL error */ - return result; - } + // 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)) { + /* D3D11_CreateDeviceResources will set the SDL error */ + return result; + } + + result = D3D11_UpdateForWindowSizeChange(renderer); + if (FAILED(result)) { + /* D3D11_UpdateForWindowSizeChange will set the SDL error */ + return result; + } return S_OK; } @@ -1382,140 +1382,140 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer) static void D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { - //D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; - - if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { - D3D11_UpdateForWindowSizeChange(renderer); + //D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { + D3D11_UpdateForWindowSizeChange(renderer); } } -static D3D11_FILTER -GetScaleQuality(void) -{ - const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); - if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) { - return SDL_D3D11_NEAREST_PIXEL_FILTER; - } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ { - return SDL_D3D11_LINEAR_FILTER; - } +static D3D11_FILTER +GetScaleQuality(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); + if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) { + return SDL_D3D11_NEAREST_PIXEL_FILTER; + } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ { + return SDL_D3D11_LINEAR_FILTER; + } } -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) { - return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", - __FUNCTION__, texture->format); - } - - textureData = new D3D11_TextureData; - if (!textureData) { - SDL_OutOfMemory(); - return -1; - } - textureData->pixelFormat = SDL_AllocFormat(texture->format); - textureData->lockedTexturePosition = XMINT2(0, 0); - textureData->scaleMode = GetScaleQuality(); - - 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 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__ ", ID3D11Device1::CreateTexture2D", 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__ ", ID3D11Device1::CreateRenderTargetView", 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__ "ID3D11Device1::CreateShaderResourceView", result); - return -1; - } - - return 0; +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) { + return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", + __FUNCTION__, texture->format); + } + + textureData = new D3D11_TextureData; + if (!textureData) { + SDL_OutOfMemory(); + return -1; + } + textureData->pixelFormat = SDL_AllocFormat(texture->format); + textureData->lockedTexturePosition = XMINT2(0, 0); + textureData->scaleMode = GetScaleQuality(); + + 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 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__ ", ID3D11Device1::CreateTexture2D", 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__ ", ID3D11Device1::CreateRenderTargetView", 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__ "ID3D11Device1::CreateShaderResourceView", result); + return -1; + } + + return 0; } static void D3D11_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; if (textureData) { if (textureData->pixelFormat) { @@ -1533,27 +1533,27 @@ 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(); - return SDL_SetError(errorMessage.c_str()); - } - - // 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); + // 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(); + return SDL_SetError(errorMessage.c_str()); + } + + // 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; @@ -1564,9 +1564,9 @@ 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; - + D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + HRESULT result = S_OK; + if (textureData->stagingTexture) { return SDL_SetError("texture is already locked"); } @@ -1596,18 +1596,18 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } // 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__ ", ID3D11DeviceContext1::Map [map staging texture]", result); - textureData->stagingTexture = nullptr; - return -1; + 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__ ", ID3D11DeviceContext1::Map [map staging texture]", result); + textureData->stagingTexture = nullptr; + return -1; } // Make note of where the staging texture will be written to (on a @@ -1649,24 +1649,24 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) } 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) { - return SDL_SetError("specified texture is not a render target"); - } - - rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; - - return 0; +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) { + return SDL_SetError("specified texture is not a render target"); + } + + rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView; + + return 0; } static int @@ -1686,34 +1686,34 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // default coordinate system) so rotations will be done in the opposite // direction of the DXGI_MODE_ROTATION enumeration. DirectX::XMMATRIX projection; - switch (D3D11_GetRotationForOrientation(data->orientation)) - { - case DXGI_MODE_ROTATION_IDENTITY: - projection = XMMatrixIdentity(); - break; - case DXGI_MODE_ROTATION_ROTATE270: - projection = XMMatrixRotationZ(XM_PIDIV2); - break; - case DXGI_MODE_ROTATION_ROTATE180: - projection = XMMatrixRotationZ(XM_PI); - break; - case DXGI_MODE_ROTATION_ROTATE90: - projection = XMMatrixRotationZ(-XM_PIDIV2); - break; - default: - return SDL_SetError("An unknown DisplayOrientation is being used"); + switch (D3D11_GetRotationForOrientation(data->orientation)) + { + case DXGI_MODE_ROTATION_IDENTITY: + projection = XMMatrixIdentity(); + break; + case DXGI_MODE_ROTATION_ROTATE270: + projection = XMMatrixRotationZ(XM_PIDIV2); + break; + case DXGI_MODE_ROTATION_ROTATE180: + projection = XMMatrixRotationZ(XM_PI); + break; + case DXGI_MODE_ROTATION_ROTATE90: + projection = XMMatrixRotationZ(-XM_PIDIV2); + break; + default: + return SDL_SetError("An unknown DisplayOrientation is being used"); } - // - // Update the view matrix - // - float viewportWidth = (float) renderer->viewport.w; - float viewportHeight = (float) renderer->viewport.h; - DirectX::XMMATRIX view = XMMatrixMultiply( - XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f), - XMMatrixMultiply( - XMMatrixTranslation(-1, -1, 0), - XMMatrixRotationX(XM_PI) + // + // Update the view matrix + // + float viewportWidth = (float) renderer->viewport.w; + float viewportHeight = (float) renderer->viewport.h; + DirectX::XMMATRIX view = XMMatrixMultiply( + XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f), + XMMatrixMultiply( + XMMatrixTranslation(-1, -1, 0), + XMMatrixRotationX(XM_PI) )); // @@ -1737,39 +1737,39 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) // a landscape mode, for all Windows 8/RT devices, or a portrait mode, // for Windows Phone devices. // - SDL_FRect orientationAlignedViewport; - const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); - 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; - } - // TODO, WinRT: 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; + SDL_FRect orientationAlignedViewport; + const bool swapDimensions = D3D11_IsDisplayRotated90Degrees(data->orientation); + 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; + } + // TODO, WinRT: 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, + 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 @@ -1796,32 +1796,32 @@ D3D11_UpdateClipRect(SDL_Renderer * renderer) return 0; } -static ComPtr & -D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer) -{ - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; - if (data->currentOffscreenRenderTargetView) { - return data->currentOffscreenRenderTargetView; - } else { - return data->mainRenderTargetView; - } +static ComPtr & +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_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 @@ -1839,45 +1839,45 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, } if (vertexBufferDesc.ByteWidth >= dataSizeInBytes) { - D3D11_MAPPED_SUBRESOURCE mappedResource; - ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE)); - result = rendererData->d3dContext->Map(rendererData->vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result); - return -1; - } - memcpy(mappedResource.pData, vertexData, dataSizeInBytes); - rendererData->d3dContext->Unmap(rendererData->vertexBuffer.Get(), 0); - } else { - vertexBufferDesc.ByteWidth = dataSizeInBytes; - vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; - vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - - 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__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result); - return -1; - } - } - - UINT stride = sizeof(VertexPositionColor); - UINT offset = 0; - rendererData->d3dContext->IASetVertexBuffers( - 0, - 1, - rendererData->vertexBuffer.GetAddressOf(), - &stride, - &offset + D3D11_MAPPED_SUBRESOURCE mappedResource; + ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE)); + result = rendererData->d3dContext->Map(rendererData->vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result); + return -1; + } + memcpy(mappedResource.pData, vertexData, dataSizeInBytes); + rendererData->d3dContext->Unmap(rendererData->vertexBuffer.Get(), 0); + } else { + vertexBufferDesc.ByteWidth = dataSizeInBytes; + vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + 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__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result); + return -1; + } + } + + UINT stride = sizeof(VertexPositionColor); + UINT offset = 0; + rendererData->d3dContext->IASetVertexBuffers( + 0, + 1, + rendererData->vertexBuffer.GetAddressOf(), + &stride, + &offset ); return 0; @@ -1888,32 +1888,32 @@ 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); + 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); + 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); + case SDL_BLENDMODE_MOD: + rendererData->d3dContext->OMSetBlendState(rendererData->blendModeMod.Get(), 0, 0xFFFFFFFF); break; case SDL_BLENDMODE_NONE: - rendererData->d3dContext->OMSetBlendState(NULL, 0, 0xFFFFFFFF); - break; - } -} + rendererData->d3dContext->OMSetBlendState(NULL, 0, 0xFFFFFFFF); + break; + } +} static void D3D11_SetPixelShader(SDL_Renderer * renderer, @@ -1921,10 +1921,10 @@ D3D11_SetPixelShader(SDL_Renderer * renderer, 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); + 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 @@ -1933,25 +1933,25 @@ D3D11_RenderFinishDrawOp(SDL_Renderer * renderer, 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()); - if (SDL_RectEmpty(&(renderer->clip_rect))) { - rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get()); - } else { - rendererData->d3dContext->RSSetState(rendererData->clippedRasterizer.Get()); - } + + 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()); + if (SDL_RectEmpty(&(renderer->clip_rect))) { + rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get()); + } else { + rendererData->d3dContext->RSSetState(rendererData->clippedRasterizer.Get()); + } rendererData->d3dContext->Draw(vertexCount, 0); } @@ -1968,25 +1968,25 @@ D3D11_RenderDrawPoints(SDL_Renderer * renderer, a = (float)(renderer->a / 255.0f); VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, count); - for (int i = 0; i < min(count, 128); ++i) { - const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; - vertices[i] = v; - } - - D3D11_RenderStartDrawOp(renderer); - D3D11_RenderSetBlendMode(renderer, renderer->blendMode); - if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { - SDL_stack_free(vertices); - return -1; - } - - D3D11_SetPixelShader( - renderer, - rendererData->colorPixelShader.Get(), - nullptr, - nullptr); - - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count); + for (int i = 0; i < min(count, 128); ++i) { + const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; + vertices[i] = v; + } + + D3D11_RenderStartDrawOp(renderer); + D3D11_RenderSetBlendMode(renderer, renderer->blendMode); + if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { + SDL_stack_free(vertices); + return -1; + } + + D3D11_SetPixelShader( + renderer, + rendererData->colorPixelShader.Get(), + nullptr, + nullptr); + + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count); SDL_stack_free(vertices); return 0; } @@ -2004,25 +2004,25 @@ D3D11_RenderDrawLines(SDL_Renderer * renderer, a = (float)(renderer->a / 255.0f); VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, count); - for (int i = 0; i < count; ++i) { - const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; - vertices[i] = v; - } - - D3D11_RenderStartDrawOp(renderer); - D3D11_RenderSetBlendMode(renderer, renderer->blendMode); - if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { - SDL_stack_free(vertices); - return -1; - } - - D3D11_SetPixelShader( - renderer, - rendererData->colorPixelShader.Get(), - nullptr, - nullptr); - - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count); + for (int i = 0; i < count; ++i) { + const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)}; + vertices[i] = v; + } + + D3D11_RenderStartDrawOp(renderer); + D3D11_RenderSetBlendMode(renderer, renderer->blendMode); + if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) { + SDL_stack_free(vertices); + return -1; + } + + D3D11_SetPixelShader( + renderer, + rendererData->colorPixelShader.Get(), + nullptr, + nullptr); + + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count); SDL_stack_free(vertices); return 0; } @@ -2052,40 +2052,40 @@ D3D11_RenderFillRects(SDL_Renderer * renderer, #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)); - } + 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; } @@ -2116,9 +2116,9 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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 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; @@ -2133,25 +2133,25 @@ D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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; - } - - ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); - D3D11_SetPixelShader( - renderer, - rendererData->texturePixelShader.Get(), - textureData->mainTextureResourceView.Get(), - textureSampler); - - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); + + 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; + } + + ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); + D3D11_SetPixelShader( + renderer, + rendererData->texturePixelShader.Get(), + textureData->mainTextureResourceView.Get(), + textureSampler); + + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); return 0; } @@ -2167,9 +2167,9 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, 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 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; @@ -2204,31 +2204,31 @@ D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, 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; - } - - ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); - D3D11_SetPixelShader( - renderer, - rendererData->texturePixelShader.Get(), - textureData->mainTextureResourceView.Get(), - textureSampler); - - D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); - - rendererData->vertexShaderConstantsData.model = oldModelMatrix; + 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; + } + + ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture); + D3D11_SetPixelShader( + renderer, + rendererData->texturePixelShader.Get(), + textureData->mainTextureResourceView.Get(), + textureSampler); + + D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor)); + + rendererData->vertexShaderConstantsData.model = oldModelMatrix; return 0; } @@ -2241,15 +2241,15 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, HRESULT result = S_OK; // Retrieve a pointer to the back buffer: - ComPtr backBuffer; - result = data->swapChain->GetBuffer( - 0, - __uuidof(ID3D11Texture2D), - &backBuffer - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result); - return -1; + ComPtr backBuffer; + result = data->swapChain->GetBuffer( + 0, + __uuidof(ID3D11Texture2D), + &backBuffer + ); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result); + return -1; } // Create a staging texture to copy the screen's data to: @@ -2308,29 +2308,29 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, // 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(); - return SDL_SetError(errorMessage.c_str()); - } - - // 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; + 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(); + return SDL_SetError(errorMessage.c_str()); + } + + // 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 @@ -2338,46 +2338,46 @@ 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, ¶meters); -#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)) { - /* D3D11_HandleDeviceLost will set the SDL error */ - } - } - else - { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::DiscardView", hr); +#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, ¶meters); +#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)) { + /* D3D11_HandleDeviceLost will set the SDL error */ + } + } + else + { + WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::DiscardView", hr); } } diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index 6e043b417..24df914c7 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -151,17 +151,17 @@ SDL_SYS_DetachThread(SDL_Thread * thread) } extern "C" -SDL_TLSData * -SDL_SYS_GetTLSData() -{ - return SDL_Generic_GetTLSData(); -} - -extern "C" -int -SDL_SYS_SetTLSData(SDL_TLSData *data) -{ - return SDL_Generic_SetTLSData(data); +SDL_TLSData * +SDL_SYS_GetTLSData() +{ + return SDL_Generic_GetTLSData(); +} + +extern "C" +int +SDL_SYS_SetTLSData(SDL_TLSData *data) +{ + return SDL_Generic_SetTLSData(data); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/windows/SDL_systimer.c b/src/timer/windows/SDL_systimer.c index a3055218c..4680d4aa7 100644 --- a/src/timer/windows/SDL_systimer.c +++ b/src/timer/windows/SDL_systimer.c @@ -170,17 +170,17 @@ SDL_GetPerformanceFrequency(void) return frequency.QuadPart; } -#ifdef __WINRT__ -static void -Sleep(DWORD timeout) -{ - static HANDLE mutex = 0; - if ( ! mutex ) - { - mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); - } - WaitForSingleObjectEx(mutex, timeout, FALSE); -} +#ifdef __WINRT__ +static void +Sleep(DWORD timeout) +{ + static HANDLE mutex = 0; + if ( ! mutex ) + { + mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); + } + WaitForSingleObjectEx(mutex, timeout, FALSE); +} #endif void diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 397942d55..a72fe1168 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -1,401 +1,401 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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_sysvideo_h -#define _SDL_sysvideo_h - -#include "SDL_messagebox.h" -#include "SDL_shape.h" -#include "SDL_thread.h" - -/* The SDL video driver */ - -typedef struct SDL_WindowShaper SDL_WindowShaper; -typedef struct SDL_ShapeDriver SDL_ShapeDriver; -typedef struct SDL_VideoDisplay SDL_VideoDisplay; -typedef struct SDL_VideoDevice SDL_VideoDevice; - -/* Define the SDL window-shaper structure */ -struct SDL_WindowShaper -{ - /* The window associated with the shaper */ - SDL_Window *window; - - /* The user's specified coordinates for the window, for once we give it a shape. */ - Uint32 userx,usery; - - /* The parameters for shape calculation. */ - SDL_WindowShapeMode mode; - - /* Has this window been assigned a shape? */ - SDL_bool hasshape; - - void *driverdata; -}; - -/* Define the SDL shape driver structure */ -struct SDL_ShapeDriver -{ - SDL_WindowShaper *(*CreateShaper)(SDL_Window * window); - int (*SetWindowShape)(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); - int (*ResizeWindowShape)(SDL_Window *window); -}; - -typedef struct SDL_WindowUserData -{ - char *name; - void *data; - struct SDL_WindowUserData *next; -} SDL_WindowUserData; - -/* Define the SDL window structure, corresponding to toplevel windows */ -struct SDL_Window -{ - const void *magic; - Uint32 id; - char *title; - SDL_Surface *icon; - int x, y; - int w, h; - int min_w, min_h; - int max_w, max_h; - Uint32 flags; - - /* Stored position and size for windowed mode */ - SDL_Rect windowed; - - SDL_DisplayMode fullscreen_mode; - - float brightness; - Uint16 *gamma; - Uint16 *saved_gamma; /* (just offset into gamma) */ - - SDL_Surface *surface; - SDL_bool surface_valid; - - SDL_WindowShaper *shaper; - - SDL_WindowUserData *data; - - void *driverdata; - - SDL_Window *prev; - SDL_Window *next; -}; -#define FULLSCREEN_VISIBLE(W) \ - (((W)->flags & SDL_WINDOW_FULLSCREEN) && \ - ((W)->flags & SDL_WINDOW_SHOWN) && \ - !((W)->flags & SDL_WINDOW_MINIMIZED)) - -/* - * Define the SDL display structure This corresponds to physical monitors - * attached to the system. - */ -struct SDL_VideoDisplay -{ - char *name; - int max_display_modes; - int num_display_modes; - SDL_DisplayMode *display_modes; - SDL_DisplayMode desktop_mode; - SDL_DisplayMode current_mode; - - SDL_Window *fullscreen_window; - - SDL_VideoDevice *device; - - void *driverdata; -}; - -/* Forward declaration */ -struct SDL_SysWMinfo; - -/* Define the SDL video driver structure */ -#define _THIS SDL_VideoDevice *_this - -struct SDL_VideoDevice -{ - /* * * */ - /* The name of this video driver */ - const char *name; - - /* * * */ - /* Initialization/Query functions */ - - /* - * Initialize the native video subsystem, filling in the list of - * displays for this driver, returning 0 or -1 if there's an error. - */ - int (*VideoInit) (_THIS); - - /* - * Reverse the effects VideoInit() -- called if VideoInit() fails or - * if the application is shutting down the video subsystem. - */ - void (*VideoQuit) (_THIS); - - /* * * */ - /* - * Display functions - */ - - /* - * Get the bounds of a display - */ - int (*GetDisplayBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); - - /* - * Get a list of the available display modes for a display. - */ - void (*GetDisplayModes) (_THIS, SDL_VideoDisplay * display); - - /* - * Setting the display mode is independent of creating windows, so - * when the display mode is changed, all existing windows should have - * their data updated accordingly, including the display surfaces - * associated with them. - */ - int (*SetDisplayMode) (_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); - - /* * * */ - /* - * Window functions - */ - int (*CreateWindow) (_THIS, SDL_Window * window); - int (*CreateWindowFrom) (_THIS, SDL_Window * window, const void *data); - void (*SetWindowTitle) (_THIS, SDL_Window * window); - void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon); - void (*SetWindowPosition) (_THIS, SDL_Window * window); - void (*SetWindowSize) (_THIS, SDL_Window * window); - void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); - void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); - void (*ShowWindow) (_THIS, SDL_Window * window); - void (*HideWindow) (_THIS, SDL_Window * window); - void (*RaiseWindow) (_THIS, SDL_Window * window); - void (*MaximizeWindow) (_THIS, SDL_Window * window); - void (*MinimizeWindow) (_THIS, SDL_Window * window); - void (*RestoreWindow) (_THIS, SDL_Window * window); - void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); - void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); - int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); - int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); - void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); - void (*DestroyWindow) (_THIS, SDL_Window * window); - int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); - int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); - void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); - void (*OnWindowEnter) (_THIS, SDL_Window * window); - - /* * * */ - /* - * Shaped-window functions - */ - SDL_ShapeDriver shape_driver; - - /* Get some platform dependent window information */ - SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window, - struct SDL_SysWMinfo * info); - - /* * * */ - /* - * OpenGL support - */ - int (*GL_LoadLibrary) (_THIS, const char *path); - void *(*GL_GetProcAddress) (_THIS, const char *proc); - void (*GL_UnloadLibrary) (_THIS); - SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window); - int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context); - void (*GL_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h); - int (*GL_SetSwapInterval) (_THIS, int interval); - int (*GL_GetSwapInterval) (_THIS); - void (*GL_SwapWindow) (_THIS, SDL_Window * window); - void (*GL_DeleteContext) (_THIS, SDL_GLContext context); - - /* * * */ - /* - * Event manager functions - */ - void (*PumpEvents) (_THIS); - - /* Suspend the screensaver */ - void (*SuspendScreenSaver) (_THIS); - - /* Text input */ - void (*StartTextInput) (_THIS); - void (*StopTextInput) (_THIS); - void (*SetTextInputRect) (_THIS, SDL_Rect *rect); - - /* Screen keyboard */ - SDL_bool (*HasScreenKeyboardSupport) (_THIS); - void (*ShowScreenKeyboard) (_THIS, SDL_Window *window); - void (*HideScreenKeyboard) (_THIS, SDL_Window *window); - SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window); - - /* Clipboard */ - int (*SetClipboardText) (_THIS, const char *text); - char * (*GetClipboardText) (_THIS); - SDL_bool (*HasClipboardText) (_THIS); - - /* MessageBox */ - int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid); - - /* * * */ - /* Data common to all drivers */ - SDL_bool suspend_screensaver; - int num_displays; - SDL_VideoDisplay *displays; - SDL_Window *windows; - Uint8 window_magic; - Uint32 next_object_id; - char * clipboard_text; - - /* * * */ - /* Data used by the GL drivers */ - struct - { - int red_size; - int green_size; - int blue_size; - int alpha_size; - int depth_size; - int buffer_size; - int stencil_size; - int double_buffer; - int accum_red_size; - int accum_green_size; - int accum_blue_size; - int accum_alpha_size; - int stereo; - int multisamplebuffers; - int multisamplesamples; - int accelerated; - int major_version; - int minor_version; - int flags; - int profile_mask; - int share_with_current_context; - int framebuffer_srgb_capable; - int retained_backing; - int driver_loaded; - char driver_path[256]; - void *dll_handle; - } gl_config; - - /* * * */ - /* Cache current GL context; don't call the OS when it hasn't changed. */ - /* We have the global pointers here so Cocoa continues to work the way - it always has, and the thread-local storage for the general case. - */ - SDL_Window *current_glwin; - SDL_GLContext current_glctx; - SDL_TLSID current_glwin_tls; - SDL_TLSID current_glctx_tls; - - /* * * */ - /* Data private to this driver */ - void *driverdata; - struct SDL_GLDriverData *gl_data; - -#if SDL_VIDEO_OPENGL_EGL - struct SDL_EGL_VideoData *egl_data; -#endif - -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - struct SDL_PrivateGLESData *gles_data; -#endif - - /* * * */ - /* The function used to dispose of this structure */ - void (*free) (_THIS); -}; - -typedef struct VideoBootStrap -{ - const char *name; - const char *desc; - int (*available) (void); - SDL_VideoDevice *(*create) (int devindex); -} VideoBootStrap; - -#if SDL_VIDEO_DRIVER_COCOA -extern VideoBootStrap COCOA_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_X11 -extern VideoBootStrap X11_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_DIRECTFB -extern VideoBootStrap DirectFB_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_WINDOWS -extern VideoBootStrap WINDOWS_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_WINRT -extern VideoBootStrap WINRT_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_HAIKU -extern VideoBootStrap HAIKU_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_PANDORA -extern VideoBootStrap PND_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_UIKIT -extern VideoBootStrap UIKIT_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_ANDROID -extern VideoBootStrap Android_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_PSP -extern VideoBootStrap PSP_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_RPI -extern VideoBootStrap RPI_bootstrap; -#endif -#if SDL_VIDEO_DRIVER_DUMMY -extern VideoBootStrap DUMMY_bootstrap; -#endif - -extern SDL_VideoDevice *SDL_GetVideoDevice(void); -extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); -extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display); -extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); -extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); -extern void *SDL_GetDisplayDriverData( int displayIndex ); - -extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); - -extern void SDL_OnWindowShown(SDL_Window * window); -extern void SDL_OnWindowHidden(SDL_Window * window); -extern void SDL_OnWindowResized(SDL_Window * window); -extern void SDL_OnWindowMinimized(SDL_Window * window); -extern void SDL_OnWindowRestored(SDL_Window * window); -extern void SDL_OnWindowEnter(SDL_Window * window); -extern void SDL_OnWindowLeave(SDL_Window * window); -extern void SDL_OnWindowFocusGained(SDL_Window * window); -extern void SDL_OnWindowFocusLost(SDL_Window * window); -extern void SDL_UpdateWindowGrab(SDL_Window * window); -extern SDL_Window * SDL_GetFocusWindow(void); - -extern SDL_bool SDL_ShouldAllowTopmost(void); - -#endif /* _SDL_sysvideo_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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_sysvideo_h +#define _SDL_sysvideo_h + +#include "SDL_messagebox.h" +#include "SDL_shape.h" +#include "SDL_thread.h" + +/* The SDL video driver */ + +typedef struct SDL_WindowShaper SDL_WindowShaper; +typedef struct SDL_ShapeDriver SDL_ShapeDriver; +typedef struct SDL_VideoDisplay SDL_VideoDisplay; +typedef struct SDL_VideoDevice SDL_VideoDevice; + +/* Define the SDL window-shaper structure */ +struct SDL_WindowShaper +{ + /* The window associated with the shaper */ + SDL_Window *window; + + /* The user's specified coordinates for the window, for once we give it a shape. */ + Uint32 userx,usery; + + /* The parameters for shape calculation. */ + SDL_WindowShapeMode mode; + + /* Has this window been assigned a shape? */ + SDL_bool hasshape; + + void *driverdata; +}; + +/* Define the SDL shape driver structure */ +struct SDL_ShapeDriver +{ + SDL_WindowShaper *(*CreateShaper)(SDL_Window * window); + int (*SetWindowShape)(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + int (*ResizeWindowShape)(SDL_Window *window); +}; + +typedef struct SDL_WindowUserData +{ + char *name; + void *data; + struct SDL_WindowUserData *next; +} SDL_WindowUserData; + +/* Define the SDL window structure, corresponding to toplevel windows */ +struct SDL_Window +{ + const void *magic; + Uint32 id; + char *title; + SDL_Surface *icon; + int x, y; + int w, h; + int min_w, min_h; + int max_w, max_h; + Uint32 flags; + + /* Stored position and size for windowed mode */ + SDL_Rect windowed; + + SDL_DisplayMode fullscreen_mode; + + float brightness; + Uint16 *gamma; + Uint16 *saved_gamma; /* (just offset into gamma) */ + + SDL_Surface *surface; + SDL_bool surface_valid; + + SDL_WindowShaper *shaper; + + SDL_WindowUserData *data; + + void *driverdata; + + SDL_Window *prev; + SDL_Window *next; +}; +#define FULLSCREEN_VISIBLE(W) \ + (((W)->flags & SDL_WINDOW_FULLSCREEN) && \ + ((W)->flags & SDL_WINDOW_SHOWN) && \ + !((W)->flags & SDL_WINDOW_MINIMIZED)) + +/* + * Define the SDL display structure This corresponds to physical monitors + * attached to the system. + */ +struct SDL_VideoDisplay +{ + char *name; + int max_display_modes; + int num_display_modes; + SDL_DisplayMode *display_modes; + SDL_DisplayMode desktop_mode; + SDL_DisplayMode current_mode; + + SDL_Window *fullscreen_window; + + SDL_VideoDevice *device; + + void *driverdata; +}; + +/* Forward declaration */ +struct SDL_SysWMinfo; + +/* Define the SDL video driver structure */ +#define _THIS SDL_VideoDevice *_this + +struct SDL_VideoDevice +{ + /* * * */ + /* The name of this video driver */ + const char *name; + + /* * * */ + /* Initialization/Query functions */ + + /* + * Initialize the native video subsystem, filling in the list of + * displays for this driver, returning 0 or -1 if there's an error. + */ + int (*VideoInit) (_THIS); + + /* + * Reverse the effects VideoInit() -- called if VideoInit() fails or + * if the application is shutting down the video subsystem. + */ + void (*VideoQuit) (_THIS); + + /* * * */ + /* + * Display functions + */ + + /* + * Get the bounds of a display + */ + int (*GetDisplayBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); + + /* + * Get a list of the available display modes for a display. + */ + void (*GetDisplayModes) (_THIS, SDL_VideoDisplay * display); + + /* + * Setting the display mode is independent of creating windows, so + * when the display mode is changed, all existing windows should have + * their data updated accordingly, including the display surfaces + * associated with them. + */ + int (*SetDisplayMode) (_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); + + /* * * */ + /* + * Window functions + */ + int (*CreateWindow) (_THIS, SDL_Window * window); + int (*CreateWindowFrom) (_THIS, SDL_Window * window, const void *data); + void (*SetWindowTitle) (_THIS, SDL_Window * window); + void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon); + void (*SetWindowPosition) (_THIS, SDL_Window * window); + void (*SetWindowSize) (_THIS, SDL_Window * window); + void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); + void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); + void (*ShowWindow) (_THIS, SDL_Window * window); + void (*HideWindow) (_THIS, SDL_Window * window); + void (*RaiseWindow) (_THIS, SDL_Window * window); + void (*MaximizeWindow) (_THIS, SDL_Window * window); + void (*MinimizeWindow) (_THIS, SDL_Window * window); + void (*RestoreWindow) (_THIS, SDL_Window * window); + void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); + void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); + int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); + int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); + void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void (*DestroyWindow) (_THIS, SDL_Window * window); + int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); + int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); + void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); + void (*OnWindowEnter) (_THIS, SDL_Window * window); + + /* * * */ + /* + * Shaped-window functions + */ + SDL_ShapeDriver shape_driver; + + /* Get some platform dependent window information */ + SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window, + struct SDL_SysWMinfo * info); + + /* * * */ + /* + * OpenGL support + */ + int (*GL_LoadLibrary) (_THIS, const char *path); + void *(*GL_GetProcAddress) (_THIS, const char *proc); + void (*GL_UnloadLibrary) (_THIS); + SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window); + int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context); + void (*GL_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h); + int (*GL_SetSwapInterval) (_THIS, int interval); + int (*GL_GetSwapInterval) (_THIS); + void (*GL_SwapWindow) (_THIS, SDL_Window * window); + void (*GL_DeleteContext) (_THIS, SDL_GLContext context); + + /* * * */ + /* + * Event manager functions + */ + void (*PumpEvents) (_THIS); + + /* Suspend the screensaver */ + void (*SuspendScreenSaver) (_THIS); + + /* Text input */ + void (*StartTextInput) (_THIS); + void (*StopTextInput) (_THIS); + void (*SetTextInputRect) (_THIS, SDL_Rect *rect); + + /* Screen keyboard */ + SDL_bool (*HasScreenKeyboardSupport) (_THIS); + void (*ShowScreenKeyboard) (_THIS, SDL_Window *window); + void (*HideScreenKeyboard) (_THIS, SDL_Window *window); + SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window); + + /* Clipboard */ + int (*SetClipboardText) (_THIS, const char *text); + char * (*GetClipboardText) (_THIS); + SDL_bool (*HasClipboardText) (_THIS); + + /* MessageBox */ + int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid); + + /* * * */ + /* Data common to all drivers */ + SDL_bool suspend_screensaver; + int num_displays; + SDL_VideoDisplay *displays; + SDL_Window *windows; + Uint8 window_magic; + Uint32 next_object_id; + char * clipboard_text; + + /* * * */ + /* Data used by the GL drivers */ + struct + { + int red_size; + int green_size; + int blue_size; + int alpha_size; + int depth_size; + int buffer_size; + int stencil_size; + int double_buffer; + int accum_red_size; + int accum_green_size; + int accum_blue_size; + int accum_alpha_size; + int stereo; + int multisamplebuffers; + int multisamplesamples; + int accelerated; + int major_version; + int minor_version; + int flags; + int profile_mask; + int share_with_current_context; + int framebuffer_srgb_capable; + int retained_backing; + int driver_loaded; + char driver_path[256]; + void *dll_handle; + } gl_config; + + /* * * */ + /* Cache current GL context; don't call the OS when it hasn't changed. */ + /* We have the global pointers here so Cocoa continues to work the way + it always has, and the thread-local storage for the general case. + */ + SDL_Window *current_glwin; + SDL_GLContext current_glctx; + SDL_TLSID current_glwin_tls; + SDL_TLSID current_glctx_tls; + + /* * * */ + /* Data private to this driver */ + void *driverdata; + struct SDL_GLDriverData *gl_data; + +#if SDL_VIDEO_OPENGL_EGL + struct SDL_EGL_VideoData *egl_data; +#endif + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + struct SDL_PrivateGLESData *gles_data; +#endif + + /* * * */ + /* The function used to dispose of this structure */ + void (*free) (_THIS); +}; + +typedef struct VideoBootStrap +{ + const char *name; + const char *desc; + int (*available) (void); + SDL_VideoDevice *(*create) (int devindex); +} VideoBootStrap; + +#if SDL_VIDEO_DRIVER_COCOA +extern VideoBootStrap COCOA_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_X11 +extern VideoBootStrap X11_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DIRECTFB +extern VideoBootStrap DirectFB_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_WINDOWS +extern VideoBootStrap WINDOWS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_WINRT +extern VideoBootStrap WINRT_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_HAIKU +extern VideoBootStrap HAIKU_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PANDORA +extern VideoBootStrap PND_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_UIKIT +extern VideoBootStrap UIKIT_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_ANDROID +extern VideoBootStrap Android_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PSP +extern VideoBootStrap PSP_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_RPI +extern VideoBootStrap RPI_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DUMMY +extern VideoBootStrap DUMMY_bootstrap; +#endif + +extern SDL_VideoDevice *SDL_GetVideoDevice(void); +extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); +extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display); +extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); +extern void *SDL_GetDisplayDriverData( int displayIndex ); + +extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); + +extern void SDL_OnWindowShown(SDL_Window * window); +extern void SDL_OnWindowHidden(SDL_Window * window); +extern void SDL_OnWindowResized(SDL_Window * window); +extern void SDL_OnWindowMinimized(SDL_Window * window); +extern void SDL_OnWindowRestored(SDL_Window * window); +extern void SDL_OnWindowEnter(SDL_Window * window); +extern void SDL_OnWindowLeave(SDL_Window * window); +extern void SDL_OnWindowFocusGained(SDL_Window * window); +extern void SDL_OnWindowFocusLost(SDL_Window * window); +extern void SDL_UpdateWindowGrab(SDL_Window * window); +extern SDL_Window * SDL_GetFocusWindow(void); + +extern SDL_bool SDL_ShouldAllowTopmost(void); + +#endif /* _SDL_sysvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index c265a77e6..a05914eaa 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1,3293 +1,3293 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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" - -/* The high-level video driver subsystem */ - -#include "SDL.h" -#include "SDL_video.h" -#include "SDL_sysvideo.h" -#include "SDL_blit.h" -#include "SDL_pixels_c.h" -#include "SDL_rect_c.h" -#include "../events/SDL_events_c.h" -#include "../timer/SDL_timer_c.h" - -#if SDL_VIDEO_OPENGL -#include "SDL_opengl.h" -#endif /* SDL_VIDEO_OPENGL */ - -#if SDL_VIDEO_OPENGL_ES -#include "SDL_opengles.h" -#endif /* SDL_VIDEO_OPENGL_ES */ - -/* GL and GLES2 headers conflict on Linux 32 bits */ -#if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL -#include "SDL_opengles2.h" -#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */ - -#include "SDL_syswm.h" - -/* On Windows, windows.h defines CreateWindow */ -#ifdef CreateWindow -#undef CreateWindow -#endif - -/* Available video drivers */ -static VideoBootStrap *bootstrap[] = { -#if SDL_VIDEO_DRIVER_COCOA - &COCOA_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_X11 - &X11_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_DIRECTFB - &DirectFB_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_WINDOWS - &WINDOWS_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_WINRT - &WINRT_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_HAIKU - &HAIKU_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_PANDORA - &PND_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_UIKIT - &UIKIT_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_ANDROID - &Android_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_PSP - &PSP_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_RPI - &RPI_bootstrap, -#endif -#if SDL_VIDEO_DRIVER_DUMMY - &DUMMY_bootstrap, -#endif - NULL -}; - -static SDL_VideoDevice *_this = NULL; - -#define CHECK_WINDOW_MAGIC(window, retval) \ - if (!_this) { \ - SDL_UninitializedVideo(); \ - return retval; \ - } \ - if (!window || window->magic != &_this->window_magic) { \ - SDL_SetError("Invalid window"); \ - return retval; \ - } - -#define CHECK_DISPLAY_INDEX(displayIndex, retval) \ - if (!_this) { \ - SDL_UninitializedVideo(); \ - return retval; \ - } \ - if (displayIndex < 0 || displayIndex >= _this->num_displays) { \ - SDL_SetError("displayIndex must be in the range 0 - %d", \ - _this->num_displays - 1); \ - return retval; \ - } - - -#ifdef __MACOSX__ -/* Support for Mac OS X fullscreen spaces */ -extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window); -extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state); -#endif - - -/* Support for framebuffer emulation using an accelerated renderer */ - -#define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" - -typedef struct { - SDL_Renderer *renderer; - SDL_Texture *texture; - void *pixels; - int pitch; - int bytes_per_pixel; -} SDL_WindowTextureData; - -static SDL_bool -ShouldUseTextureFramebuffer() -{ - const char *hint; - - /* If there's no native framebuffer support then there's no option */ - if (!_this->CreateWindowFramebuffer) { - return SDL_TRUE; - } - - /* If the user has specified a software renderer we can't use a - texture framebuffer, or renderer creation will go recursive. - */ - hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); - if (hint && SDL_strcasecmp(hint, "software") == 0) { - return SDL_FALSE; - } - - /* See if the user or application wants a specific behavior */ - hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - - /* Each platform has different performance characteristics */ -#if defined(__WIN32__) - /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. - */ - return SDL_FALSE; - -#elif defined(__MACOSX__) - /* Mac OS X uses OpenGL as the native fast path */ - return SDL_TRUE; - -#elif defined(__LINUX__) - /* Properly configured OpenGL drivers are faster than MIT-SHM */ -#if SDL_VIDEO_OPENGL - /* Ugh, find a way to cache this value! */ - { - SDL_Window *window; - SDL_GLContext context; - SDL_bool hasAcceleratedOpenGL = SDL_FALSE; - - window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN); - if (window) { - context = SDL_GL_CreateContext(window); - if (context) { - const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); - const char *vendor = NULL; - - glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); - if (glGetStringFunc) { - vendor = (const char *) glGetStringFunc(GL_VENDOR); - } - /* Add more vendors here at will... */ - if (vendor && - (SDL_strstr(vendor, "ATI Technologies") || - SDL_strstr(vendor, "NVIDIA"))) { - hasAcceleratedOpenGL = SDL_TRUE; - } - SDL_GL_DeleteContext(context); - } - SDL_DestroyWindow(window); - } - return hasAcceleratedOpenGL; - } -#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - /* Let's be optimistic about this! */ - return SDL_TRUE; -#else - return SDL_FALSE; -#endif - -#else - /* Play it safe, assume that if there is a framebuffer driver that it's - optimized for the current platform. - */ - return SDL_FALSE; -#endif -} - -static int -SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) -{ - SDL_WindowTextureData *data; - SDL_RendererInfo info; - Uint32 i; - - data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); - if (!data) { - SDL_Renderer *renderer = NULL; - SDL_RendererInfo info; - int i; - const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - - /* Check to see if there's a specific driver requested */ - if (hint && *hint != '0' && *hint != '1' && - SDL_strcasecmp(hint, "software") != 0) { - for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &info); - if (SDL_strcasecmp(info.name, hint) == 0) { - renderer = SDL_CreateRenderer(window, i, 0); - break; - } - } - } - - if (!renderer) { - for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &info); - if (SDL_strcmp(info.name, "software") != 0) { - renderer = SDL_CreateRenderer(window, i, 0); - if (renderer) { - break; - } - } - } - } - if (!renderer) { - return SDL_SetError("No hardware accelerated renderers available"); - } - - /* Create the data after we successfully create the renderer (bug #1116) */ - data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data)); - if (!data) { - SDL_DestroyRenderer(renderer); - return SDL_OutOfMemory(); - } - SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data); - - data->renderer = renderer; - } - - /* Free any old texture and pixel data */ - if (data->texture) { - SDL_DestroyTexture(data->texture); - data->texture = NULL; - } - SDL_free(data->pixels); - data->pixels = NULL; - - if (SDL_GetRendererInfo(data->renderer, &info) < 0) { - return -1; - } - - /* Find the first format without an alpha channel */ - *format = info.texture_formats[0]; - for (i = 0; i < info.num_texture_formats; ++i) { - if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && - !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { - *format = info.texture_formats[i]; - break; - } - } - - data->texture = SDL_CreateTexture(data->renderer, *format, - SDL_TEXTUREACCESS_STREAMING, - window->w, window->h); - if (!data->texture) { - return -1; - } - - /* Create framebuffer data */ - data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format); - data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3); - data->pixels = SDL_malloc(window->h * data->pitch); - if (!data->pixels) { - return SDL_OutOfMemory(); - } - - *pixels = data->pixels; - *pitch = data->pitch; - - /* Make sure we're not double-scaling the viewport */ - SDL_RenderSetViewport(data->renderer, NULL); - - return 0; -} - -static int -SDL_UpdateWindowTexture(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) -{ - SDL_WindowTextureData *data; - SDL_Rect rect; - void *src; - - data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); - if (!data || !data->texture) { - return SDL_SetError("No window texture data"); - } - - /* Update a single rect that contains subrects for best DMA performance */ - if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) { - src = (void *)((Uint8 *)data->pixels + - rect.y * data->pitch + - rect.x * data->bytes_per_pixel); - if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) { - return -1; - } - - if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) { - return -1; - } - - SDL_RenderPresent(data->renderer); - } - return 0; -} - -static void -SDL_DestroyWindowTexture(_THIS, SDL_Window * window) -{ - SDL_WindowTextureData *data; - - data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, NULL); - if (!data) { - return; - } - if (data->texture) { - SDL_DestroyTexture(data->texture); - } - if (data->renderer) { - SDL_DestroyRenderer(data->renderer); - } - SDL_free(data->pixels); - SDL_free(data); -} - - -static int -cmpmodes(const void *A, const void *B) -{ - const SDL_DisplayMode *a = (const SDL_DisplayMode *) A; - const SDL_DisplayMode *b = (const SDL_DisplayMode *) B; - if (a == b) { - return 0; - } else if (a->w != b->w) { - return b->w - a->w; - } else if (a->h != b->h) { - return b->h - a->h; - } else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) { - return SDL_BITSPERPIXEL(b->format) - SDL_BITSPERPIXEL(a->format); - } else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) { - return SDL_PIXELLAYOUT(b->format) - SDL_PIXELLAYOUT(a->format); - } else if (a->refresh_rate != b->refresh_rate) { - return b->refresh_rate - a->refresh_rate; - } - return 0; -} - -static int -SDL_UninitializedVideo() -{ - return SDL_SetError("Video subsystem has not been initialized"); -} - -int -SDL_GetNumVideoDrivers(void) -{ - return SDL_arraysize(bootstrap) - 1; -} - -const char * -SDL_GetVideoDriver(int index) -{ - if (index >= 0 && index < SDL_GetNumVideoDrivers()) { - return bootstrap[index]->name; - } - return NULL; -} - -/* - * Initialize the video and event subsystems -- determine native pixel format - */ -int -SDL_VideoInit(const char *driver_name) -{ - SDL_VideoDevice *video; - int index; - int i; - - /* Check to make sure we don't overwrite '_this' */ - if (_this != NULL) { - SDL_VideoQuit(); - } - -#if !SDL_TIMERS_DISABLED - SDL_InitTicks(); -#endif - - /* Start the event loop */ - if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || - SDL_KeyboardInit() < 0 || - SDL_MouseInit() < 0 || - SDL_TouchInit() < 0) { - return -1; - } - - /* Select the proper video driver */ - index = 0; - video = NULL; - if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_VIDEODRIVER"); - } - if (driver_name != NULL) { - for (i = 0; bootstrap[i]; ++i) { - if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) { - video = bootstrap[i]->create(index); - break; - } - } - } else { - for (i = 0; bootstrap[i]; ++i) { - if (bootstrap[i]->available()) { - video = bootstrap[i]->create(index); - if (video != NULL) { - break; - } - } - } - } - if (video == NULL) { - if (driver_name) { - return SDL_SetError("%s not available", driver_name); - } - return SDL_SetError("No available video device"); - } - _this = video; - _this->name = bootstrap[i]->name; - _this->next_object_id = 1; - - - /* Set some very sane GL defaults */ - _this->gl_config.driver_loaded = 0; - _this->gl_config.dll_handle = NULL; - _this->gl_config.red_size = 3; - _this->gl_config.green_size = 3; - _this->gl_config.blue_size = 2; - _this->gl_config.alpha_size = 0; - _this->gl_config.buffer_size = 0; - _this->gl_config.depth_size = 16; - _this->gl_config.stencil_size = 0; - _this->gl_config.double_buffer = 1; - _this->gl_config.accum_red_size = 0; - _this->gl_config.accum_green_size = 0; - _this->gl_config.accum_blue_size = 0; - _this->gl_config.accum_alpha_size = 0; - _this->gl_config.stereo = 0; - _this->gl_config.multisamplebuffers = 0; - _this->gl_config.multisamplesamples = 0; - _this->gl_config.retained_backing = 1; - _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ - _this->gl_config.profile_mask = 0; -#if SDL_VIDEO_OPENGL - _this->gl_config.major_version = 2; - _this->gl_config.minor_version = 1; -#elif SDL_VIDEO_OPENGL_ES2 - _this->gl_config.major_version = 2; - _this->gl_config.minor_version = 0; - _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; -#elif SDL_VIDEO_OPENGL_ES - _this->gl_config.major_version = 1; - _this->gl_config.minor_version = 1; - _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; -#endif - _this->gl_config.flags = 0; - - _this->gl_config.share_with_current_context = 0; - - _this->current_glwin_tls = SDL_TLSCreate(); - _this->current_glctx_tls = SDL_TLSCreate(); - - /* Initialize the video subsystem */ - if (_this->VideoInit(_this) < 0) { - SDL_VideoQuit(); - return -1; - } - - /* Make sure some displays were added */ - if (_this->num_displays == 0) { - SDL_VideoQuit(); - return SDL_SetError("The video driver did not add any displays"); - } - - /* Add the renderer framebuffer emulation if desired */ - if (ShouldUseTextureFramebuffer()) { - _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; - _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; - _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; - } - - /* If we don't use a screen keyboard, turn on text input by default, - otherwise programs that expect to get text events without enabling - UNICODE input won't get any events. - - Actually, come to think of it, you needed to call SDL_EnableUNICODE(1) - in SDL 1.2 before you got text input events. Hmm... - */ - if (!SDL_HasScreenKeyboardSupport()) { - SDL_StartTextInput(); - } - - /* We're ready to go! */ - return 0; -} - -const char * -SDL_GetCurrentVideoDriver() -{ - if (!_this) { - SDL_UninitializedVideo(); - return NULL; - } - return _this->name; -} - -SDL_VideoDevice * -SDL_GetVideoDevice(void) -{ - return _this; -} - -int -SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) -{ - SDL_VideoDisplay display; - - SDL_zero(display); - if (desktop_mode) { - display.desktop_mode = *desktop_mode; - } - display.current_mode = display.desktop_mode; - - return SDL_AddVideoDisplay(&display); -} - -int -SDL_AddVideoDisplay(const SDL_VideoDisplay * display) -{ - SDL_VideoDisplay *displays; - int index = -1; - - displays = - SDL_realloc(_this->displays, - (_this->num_displays + 1) * sizeof(*displays)); - if (displays) { - index = _this->num_displays++; - displays[index] = *display; - displays[index].device = _this; - _this->displays = displays; - - if (display->name) { - displays[index].name = SDL_strdup(display->name); - } else { - char name[32]; - - SDL_itoa(index, name, 10); - displays[index].name = SDL_strdup(name); - } - } else { - SDL_OutOfMemory(); - } - return index; -} - -int -SDL_GetNumVideoDisplays(void) -{ - if (!_this) { - SDL_UninitializedVideo(); - return 0; - } - return _this->num_displays; -} - -static int -SDL_GetIndexOfDisplay(SDL_VideoDisplay *display) -{ - int displayIndex; - - for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) { - if (display == &_this->displays[displayIndex]) { - return displayIndex; - } - } - - /* Couldn't find the display, just use index 0 */ - return 0; -} - -void * -SDL_GetDisplayDriverData( int displayIndex ) -{ - CHECK_DISPLAY_INDEX( displayIndex, NULL ); - - return _this->displays[displayIndex].driverdata; -} - -const char * -SDL_GetDisplayName(int displayIndex) -{ - CHECK_DISPLAY_INDEX(displayIndex, NULL); - - return _this->displays[displayIndex].name; -} - -int -SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect) -{ - CHECK_DISPLAY_INDEX(displayIndex, -1); - - if (rect) { - SDL_VideoDisplay *display = &_this->displays[displayIndex]; - - if (_this->GetDisplayBounds) { - if (_this->GetDisplayBounds(_this, display, rect) == 0) { - return 0; - } - } - - /* Assume that the displays are left to right */ - if (displayIndex == 0) { - rect->x = 0; - rect->y = 0; - } else { - SDL_GetDisplayBounds(displayIndex-1, rect); - rect->x += rect->w; - } - rect->w = display->current_mode.w; - rect->h = display->current_mode.h; - } - return 0; -} - -SDL_bool -SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) -{ - SDL_DisplayMode *modes; - int i, nmodes; - - /* Make sure we don't already have the mode in the list */ - modes = display->display_modes; - nmodes = display->num_display_modes; - for (i = 0; i < nmodes; ++i) { - if (cmpmodes(mode, &modes[i]) == 0) { - return SDL_FALSE; - } - } - - /* Go ahead and add the new mode */ - if (nmodes == display->max_display_modes) { - modes = - SDL_realloc(modes, - (display->max_display_modes + 32) * sizeof(*modes)); - if (!modes) { - return SDL_FALSE; - } - display->display_modes = modes; - display->max_display_modes += 32; - } - modes[nmodes] = *mode; - display->num_display_modes++; - - /* Re-sort video modes */ - SDL_qsort(display->display_modes, display->num_display_modes, - sizeof(SDL_DisplayMode), cmpmodes); - - return SDL_TRUE; -} - -static int -SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) -{ - if (!display->num_display_modes && _this->GetDisplayModes) { - _this->GetDisplayModes(_this, display); - SDL_qsort(display->display_modes, display->num_display_modes, - sizeof(SDL_DisplayMode), cmpmodes); - } - return display->num_display_modes; -} - -int -SDL_GetNumDisplayModes(int displayIndex) -{ - CHECK_DISPLAY_INDEX(displayIndex, -1); - - return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]); -} - -int -SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) -{ - SDL_VideoDisplay *display; - - CHECK_DISPLAY_INDEX(displayIndex, -1); - - display = &_this->displays[displayIndex]; - if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) { - return SDL_SetError("index must be in the range of 0 - %d", - SDL_GetNumDisplayModesForDisplay(display) - 1); - } - if (mode) { - *mode = display->display_modes[index]; - } - return 0; -} - -int -SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode) -{ - SDL_VideoDisplay *display; - - CHECK_DISPLAY_INDEX(displayIndex, -1); - - display = &_this->displays[displayIndex]; - if (mode) { - *mode = display->desktop_mode; - } - return 0; -} - -int -SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode) -{ - SDL_VideoDisplay *display; - - CHECK_DISPLAY_INDEX(displayIndex, -1); - - display = &_this->displays[displayIndex]; - if (mode) { - *mode = display->current_mode; - } - return 0; -} - -static SDL_DisplayMode * -SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, - const SDL_DisplayMode * mode, - SDL_DisplayMode * closest) -{ - Uint32 target_format; - int target_refresh_rate; - int i; - SDL_DisplayMode *current, *match; - - if (!mode || !closest) { - SDL_SetError("Missing desired mode or closest mode parameter"); - return NULL; - } - - /* Default to the desktop format */ - if (mode->format) { - target_format = mode->format; - } else { - target_format = display->desktop_mode.format; - } - - /* Default to the desktop refresh rate */ - if (mode->refresh_rate) { - target_refresh_rate = mode->refresh_rate; - } else { - target_refresh_rate = display->desktop_mode.refresh_rate; - } - - match = NULL; - for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) { - current = &display->display_modes[i]; - - if (current->w && (current->w < mode->w)) { - /* Out of sorted modes large enough here */ - break; - } - if (current->h && (current->h < mode->h)) { - if (current->w && (current->w == mode->w)) { - /* Out of sorted modes large enough here */ - break; - } - /* Wider, but not tall enough, due to a different - aspect ratio. This mode must be skipped, but closer - modes may still follow. */ - continue; - } - if (!match || current->w < match->w || current->h < match->h) { - match = current; - continue; - } - if (current->format != match->format) { - /* Sorted highest depth to lowest */ - if (current->format == target_format || - (SDL_BITSPERPIXEL(current->format) >= - SDL_BITSPERPIXEL(target_format) - && SDL_PIXELTYPE(current->format) == - SDL_PIXELTYPE(target_format))) { - match = current; - } - continue; - } - if (current->refresh_rate != match->refresh_rate) { - /* Sorted highest refresh to lowest */ - if (current->refresh_rate >= target_refresh_rate) { - match = current; - } - } - } - if (match) { - if (match->format) { - closest->format = match->format; - } else { - closest->format = mode->format; - } - if (match->w && match->h) { - closest->w = match->w; - closest->h = match->h; - } else { - closest->w = mode->w; - closest->h = mode->h; - } - if (match->refresh_rate) { - closest->refresh_rate = match->refresh_rate; - } else { - closest->refresh_rate = mode->refresh_rate; - } - closest->driverdata = match->driverdata; - - /* - * Pick some reasonable defaults if the app and driver don't - * care - */ - if (!closest->format) { - closest->format = SDL_PIXELFORMAT_RGB888; - } - if (!closest->w) { - closest->w = 640; - } - if (!closest->h) { - closest->h = 480; - } - return closest; - } - return NULL; -} - -SDL_DisplayMode * -SDL_GetClosestDisplayMode(int displayIndex, - const SDL_DisplayMode * mode, - SDL_DisplayMode * closest) -{ - SDL_VideoDisplay *display; - - CHECK_DISPLAY_INDEX(displayIndex, NULL); - - display = &_this->displays[displayIndex]; - return SDL_GetClosestDisplayModeForDisplay(display, mode, closest); -} - -static int -SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) -{ - SDL_DisplayMode display_mode; - SDL_DisplayMode current_mode; - - if (mode) { - display_mode = *mode; - - /* Default to the current mode */ - if (!display_mode.format) { - display_mode.format = display->current_mode.format; - } - if (!display_mode.w) { - display_mode.w = display->current_mode.w; - } - if (!display_mode.h) { - display_mode.h = display->current_mode.h; - } - if (!display_mode.refresh_rate) { - display_mode.refresh_rate = display->current_mode.refresh_rate; - } - - /* Get a good video mode, the closest one possible */ - if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) { - return SDL_SetError("No video mode large enough for %dx%d", - display_mode.w, display_mode.h); - } - } else { - display_mode = display->desktop_mode; - } - - /* See if there's anything left to do */ - current_mode = display->current_mode; - if (SDL_memcmp(&display_mode, ¤t_mode, sizeof(display_mode)) == 0) { - return 0; - } - - /* Actually change the display mode */ - if (!_this->SetDisplayMode) { - return SDL_SetError("Video driver doesn't support changing display mode"); - } - if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { - return -1; - } - display->current_mode = display_mode; - return 0; -} - -int -SDL_GetWindowDisplayIndex(SDL_Window * window) -{ - int displayIndex; - int i, dist; - int closest = -1; - int closest_dist = 0x7FFFFFFF; - SDL_Point center; - SDL_Point delta; - SDL_Rect rect; - - CHECK_WINDOW_MAGIC(window, -1); - - if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || - SDL_WINDOWPOS_ISCENTERED(window->x)) { - displayIndex = (window->x & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } - if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || - SDL_WINDOWPOS_ISCENTERED(window->y)) { - displayIndex = (window->y & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } - - /* Find the display containing the window */ - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - - if (display->fullscreen_window == window) { - return i; - } - } - center.x = window->x + window->w / 2; - center.y = window->y + window->h / 2; - for (i = 0; i < _this->num_displays; ++i) { - SDL_GetDisplayBounds(i, &rect); - if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { - return i; - } - - delta.x = center.x - (rect.x + rect.w / 2); - delta.y = center.y - (rect.y + rect.h / 2); - dist = (delta.x*delta.x + delta.y*delta.y); - if (dist < closest_dist) { - closest = i; - closest_dist = dist; - } - } - if (closest < 0) { - SDL_SetError("Couldn't find any displays"); - } - return closest; -} - -SDL_VideoDisplay * -SDL_GetDisplayForWindow(SDL_Window *window) -{ - int displayIndex = SDL_GetWindowDisplayIndex(window); - if (displayIndex >= 0) { - return &_this->displays[displayIndex]; - } else { - return NULL; - } -} - -int -SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (mode) { - window->fullscreen_mode = *mode; - } else { - SDL_zero(window->fullscreen_mode); - } - return 0; -} - -int -SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) -{ - SDL_DisplayMode fullscreen_mode; - SDL_VideoDisplay *display; - - if (!mode) { - return SDL_InvalidParamError("mode"); - } - - CHECK_WINDOW_MAGIC(window, -1); - - fullscreen_mode = window->fullscreen_mode; - if (!fullscreen_mode.w) { - fullscreen_mode.w = window->w; - } - if (!fullscreen_mode.h) { - fullscreen_mode.h = window->h; - } - - display = SDL_GetDisplayForWindow(window); - - /* if in desktop size mode, just return the size of the desktop */ - if ( ( window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP ) - { - fullscreen_mode = display->desktop_mode; - } - else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), - &fullscreen_mode, - &fullscreen_mode)) { - return SDL_SetError("Couldn't find display mode match"); - } - - if (mode) { - *mode = fullscreen_mode; - } - return 0; -} - -Uint32 -SDL_GetWindowPixelFormat(SDL_Window * window) -{ - SDL_VideoDisplay *display; - - CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN); - - display = SDL_GetDisplayForWindow(window); - return display->current_mode.format; -} - -static void -SDL_RestoreMousePosition(SDL_Window *window) -{ - int x, y; - - if (window == SDL_GetMouseFocus()) { - SDL_GetMouseState(&x, &y); - SDL_WarpMouseInWindow(window, x, y); - } -} - -static void -SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) -{ - SDL_VideoDisplay *display; - SDL_Window *other; - -#ifdef __MACOSX__ - if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) { - return; - } -#endif - - display = SDL_GetDisplayForWindow(window); - - if (fullscreen) { - /* Hide any other fullscreen windows */ - if (display->fullscreen_window && - display->fullscreen_window != window) { - SDL_MinimizeWindow(display->fullscreen_window); - } - } - - /* See if anything needs to be done now */ - if ((display->fullscreen_window == window) == fullscreen) { - return; - } - - /* See if there are any fullscreen windows */ - for (other = _this->windows; other; other = other->next) { - SDL_bool setDisplayMode = SDL_FALSE; - - if (other == window) { - setDisplayMode = fullscreen; - } else if (FULLSCREEN_VISIBLE(other) && - SDL_GetDisplayForWindow(other) == display) { - setDisplayMode = SDL_TRUE; - } - - if (setDisplayMode) { - SDL_DisplayMode fullscreen_mode; - - if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) { - SDL_bool resized = SDL_TRUE; - - if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) { - resized = SDL_FALSE; - } - - /* only do the mode change if we want exclusive fullscreen */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { - SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); - } else { - SDL_SetDisplayModeForDisplay(display, NULL); - } - - if (_this->SetWindowFullscreen) { - _this->SetWindowFullscreen(_this, other, display, SDL_TRUE); - } - display->fullscreen_window = other; - - /* Generate a mode change event here */ - if (resized) { - SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED, - fullscreen_mode.w, fullscreen_mode.h); - } else { - SDL_OnWindowResized(other); - } - - SDL_RestoreMousePosition(other); - return; - } - } - } - - /* Nope, restore the desktop mode */ - SDL_SetDisplayModeForDisplay(display, NULL); - - if (_this->SetWindowFullscreen) { - _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); - } - display->fullscreen_window = NULL; - - /* Generate a mode change event here */ - SDL_OnWindowResized(window); - - /* Restore the cursor position */ - SDL_RestoreMousePosition(window); -} - -#define CREATE_FLAGS \ - (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI) - -static void -SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) -{ - window->windowed.x = window->x; - window->windowed.y = window->y; - window->windowed.w = window->w; - window->windowed.h = window->h; - - if (flags & SDL_WINDOW_MAXIMIZED) { - SDL_MaximizeWindow(window); - } - if (flags & SDL_WINDOW_MINIMIZED) { - SDL_MinimizeWindow(window); - } - if (flags & SDL_WINDOW_FULLSCREEN) { - SDL_SetWindowFullscreen(window, flags); - } - if (flags & SDL_WINDOW_INPUT_GRABBED) { - SDL_SetWindowGrab(window, SDL_TRUE); - } - if (!(flags & SDL_WINDOW_HIDDEN)) { - SDL_ShowWindow(window); - } -} - -SDL_Window * -SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) -{ - SDL_Window *window; - const char *hint; - - if (!_this) { - /* Initialize the video system if needed */ - if (SDL_VideoInit(NULL) < 0) { - return NULL; - } - } - - /* Some platforms can't create zero-sized windows */ - if (w < 1) { - w = 1; - } - if (h < 1) { - h = 1; - } - - /* Some platforms have OpenGL enabled by default */ -#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ - flags |= SDL_WINDOW_OPENGL; -#endif - if (flags & SDL_WINDOW_OPENGL) { - if (!_this->GL_CreateContext) { - SDL_SetError("No OpenGL support in video driver"); - return NULL; - } - if (SDL_GL_LoadLibrary(NULL) < 0) { - return NULL; - } - } - - /* Unless the user has specified the high-DPI disabling hint, respect the - * SDL_WINDOW_ALLOW_HIGHDPI flag. - */ - if (flags & SDL_WINDOW_ALLOW_HIGHDPI) { - hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED); - if (hint && SDL_atoi(hint) > 0) { - flags &= ~SDL_WINDOW_ALLOW_HIGHDPI; - } - } - - window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); - if (!window) { - SDL_OutOfMemory(); - return NULL; - } - window->magic = &_this->window_magic; - window->id = _this->next_object_id++; - window->x = x; - window->y = y; - window->w = w; - window->h = h; - if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || - SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - int displayIndex; - SDL_Rect bounds; - - displayIndex = SDL_GetIndexOfDisplay(display); - SDL_GetDisplayBounds(displayIndex, &bounds); - if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { - window->x = bounds.x + (bounds.w - w) / 2; - } - if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { - window->y = bounds.y + (bounds.h - h) / 2; - } - } - window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); - window->brightness = 1.0f; - window->next = _this->windows; - - if (_this->windows) { - _this->windows->prev = window; - } - _this->windows = window; - - if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) { - SDL_DestroyWindow(window); - return NULL; - } - - if (title) { - SDL_SetWindowTitle(window, title); - } - SDL_FinishWindowCreation(window, flags); - - /* If the window was created fullscreen, make sure the mode code matches */ - SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)); - - return window; -} - -SDL_Window * -SDL_CreateWindowFrom(const void *data) -{ - SDL_Window *window; - - if (!_this) { - SDL_UninitializedVideo(); - return NULL; - } - window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); - if (!window) { - SDL_OutOfMemory(); - return NULL; - } - window->magic = &_this->window_magic; - window->id = _this->next_object_id++; - window->flags = SDL_WINDOW_FOREIGN; - window->brightness = 1.0f; - window->next = _this->windows; - if (_this->windows) { - _this->windows->prev = window; - } - _this->windows = window; - - if (!_this->CreateWindowFrom || - _this->CreateWindowFrom(_this, window, data) < 0) { - SDL_DestroyWindow(window); - return NULL; - } - return window; -} - -int -SDL_RecreateWindow(SDL_Window * window, Uint32 flags) -{ - char *title = window->title; - SDL_Surface *icon = window->icon; - - if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { - return SDL_SetError("No OpenGL support in video driver"); - } - - if (window->flags & SDL_WINDOW_FOREIGN) { - /* Can't destroy and re-create foreign windows, hrm */ - flags |= SDL_WINDOW_FOREIGN; - } else { - flags &= ~SDL_WINDOW_FOREIGN; - } - - /* Restore video mode, etc. */ - SDL_HideWindow(window); - - /* Tear down the old native window */ - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } - if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { - _this->DestroyWindow(_this, window); - } - - if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) { - if (flags & SDL_WINDOW_OPENGL) { - if (SDL_GL_LoadLibrary(NULL) < 0) { - return -1; - } - } else { - SDL_GL_UnloadLibrary(); - } - } - - window->title = NULL; - window->icon = NULL; - window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); - - if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) { - if (_this->CreateWindow(_this, window) < 0) { - if (flags & SDL_WINDOW_OPENGL) { - SDL_GL_UnloadLibrary(); - } - return -1; - } - } - - if (title) { - SDL_SetWindowTitle(window, title); - SDL_free(title); - } - if (icon) { - SDL_SetWindowIcon(window, icon); - SDL_FreeSurface(icon); - } - SDL_FinishWindowCreation(window, flags); - - return 0; -} - -Uint32 -SDL_GetWindowID(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, 0); - - return window->id; -} - -SDL_Window * -SDL_GetWindowFromID(Uint32 id) -{ - SDL_Window *window; - - if (!_this) { - return NULL; - } - for (window = _this->windows; window; window = window->next) { - if (window->id == id) { - return window; - } - } - return NULL; -} - -Uint32 -SDL_GetWindowFlags(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, 0); - - return window->flags; -} - -void -SDL_SetWindowTitle(SDL_Window * window, const char *title) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (title == window->title) { - return; - } - SDL_free(window->title); - if (title && *title) { - window->title = SDL_strdup(title); - } else { - window->title = NULL; - } - - if (_this->SetWindowTitle) { - _this->SetWindowTitle(_this, window); - } -} - -const char * -SDL_GetWindowTitle(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ""); - - return window->title ? window->title : ""; -} - -void -SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!icon) { - return; - } - - SDL_FreeSurface(window->icon); - - /* Convert the icon into ARGB8888 */ - window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0); - if (!window->icon) { - return; - } - - if (_this->SetWindowIcon) { - _this->SetWindowIcon(_this, window, window->icon); - } -} - -void* -SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) -{ - SDL_WindowUserData *prev, *data; - - CHECK_WINDOW_MAGIC(window, NULL); - - /* Input validation */ - if (name == NULL || name[0] == '\0') { - SDL_InvalidParamError("name"); - return NULL; - } - - /* See if the named data already exists */ - prev = NULL; - for (data = window->data; data; prev = data, data = data->next) { - if (data->name && SDL_strcmp(data->name, name) == 0) { - void *last_value = data->data; - - if (userdata) { - /* Set the new value */ - data->data = userdata; - } else { - /* Delete this value */ - if (prev) { - prev->next = data->next; - } else { - window->data = data->next; - } - SDL_free(data->name); - SDL_free(data); - } - return last_value; - } - } - - /* Add new data to the window */ - if (userdata) { - data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data)); - data->name = SDL_strdup(name); - data->data = userdata; - data->next = window->data; - window->data = data; - } - return NULL; -} - -void * -SDL_GetWindowData(SDL_Window * window, const char *name) -{ - SDL_WindowUserData *data; - - CHECK_WINDOW_MAGIC(window, NULL); - - /* Input validation */ - if (name == NULL || name[0] == '\0') { - SDL_InvalidParamError("name"); - return NULL; - } - - for (data = window->data; data; data = data->next) { - if (data->name && SDL_strcmp(data->name, name) == 0) { - return data->data; - } - } - return NULL; -} - -void -SDL_SetWindowPosition(SDL_Window * window, int x, int y) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - int displayIndex; - SDL_Rect bounds; - - displayIndex = SDL_GetIndexOfDisplay(display); - SDL_GetDisplayBounds(displayIndex, &bounds); - if (SDL_WINDOWPOS_ISCENTERED(x)) { - x = bounds.x + (bounds.w - window->w) / 2; - } - if (SDL_WINDOWPOS_ISCENTERED(y)) { - y = bounds.y + (bounds.h - window->h) / 2; - } - } - - if ((window->flags & SDL_WINDOW_FULLSCREEN)) { - if (!SDL_WINDOWPOS_ISUNDEFINED(x)) { - window->windowed.x = x; - } - if (!SDL_WINDOWPOS_ISUNDEFINED(y)) { - window->windowed.y = y; - } - } else { - if (!SDL_WINDOWPOS_ISUNDEFINED(x)) { - window->x = x; - } - if (!SDL_WINDOWPOS_ISUNDEFINED(y)) { - window->y = y; - } - - if (_this->SetWindowPosition) { - _this->SetWindowPosition(_this, window); - } - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); - } -} - -void -SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) -{ - CHECK_WINDOW_MAGIC(window, ); - - /* Fullscreen windows are always at their display's origin */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - if (x) { - *x = 0; - } - if (y) { - *y = 0; - } - } else { - if (x) { - *x = window->x; - } - if (y) { - *y = window->y; - } - } -} - -void -SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) -{ - CHECK_WINDOW_MAGIC(window, ); - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - const int want = (bordered != SDL_FALSE); /* normalize the flag. */ - const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0); - if ((want != have) && (_this->SetWindowBordered)) { - if (want) { - window->flags &= ~SDL_WINDOW_BORDERLESS; - } else { - window->flags |= SDL_WINDOW_BORDERLESS; - } - _this->SetWindowBordered(_this, window, (SDL_bool) want); - } - } -} - -void -SDL_SetWindowSize(SDL_Window * window, int w, int h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (w <= 0) { - SDL_InvalidParamError("w"); - return; - } - if (h <= 0) { - SDL_InvalidParamError("h"); - return; - } - - /* Make sure we don't exceed any window size limits */ - if (window->min_w && w < window->min_w) - { - w = window->min_w; - } - if (window->max_w && w > window->max_w) - { - w = window->max_w; - } - if (window->min_h && h < window->min_h) - { - h = window->min_h; - } - if (window->max_h && h > window->max_h) - { - h = window->max_h; - } - - /* FIXME: Should this change fullscreen modes? */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - window->windowed.w = w; - window->windowed.h = h; - } else { - window->w = w; - window->h = h; - if (_this->SetWindowSize) { - _this->SetWindowSize(_this, window); - } - if (window->w == w && window->h == h) { - /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */ - SDL_OnWindowResized(window); - } - } -} - -void -SDL_GetWindowSize(SDL_Window * window, int *w, int *h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (w) { - *w = window->w; - } - if (h) { - *h = window->h; - } -} - -void -SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (min_w <= 0) { - SDL_InvalidParamError("min_w"); - return; - } - if (min_h <= 0) { - SDL_InvalidParamError("min_h"); - return; - } - - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - window->min_w = min_w; - window->min_h = min_h; - if (_this->SetWindowMinimumSize) { - _this->SetWindowMinimumSize(_this, window); - } - /* Ensure that window is not smaller than minimal size */ - SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h)); - } -} - -void -SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (min_w) { - *min_w = window->min_w; - } - if (min_h) { - *min_h = window->min_h; - } -} - -void -SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (max_w <= 0) { - SDL_InvalidParamError("max_w"); - return; - } - if (max_h <= 0) { - SDL_InvalidParamError("max_h"); - return; - } - - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - window->max_w = max_w; - window->max_h = max_h; - if (_this->SetWindowMaximumSize) { - _this->SetWindowMaximumSize(_this, window); - } - /* Ensure that window is not larger than maximal size */ - SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h)); - } -} - -void -SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h) -{ - CHECK_WINDOW_MAGIC(window, ); - if (max_w) { - *max_w = window->max_w; - } - if (max_h) { - *max_h = window->max_h; - } -} - -void -SDL_ShowWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (window->flags & SDL_WINDOW_SHOWN) { - return; - } - - if (_this->ShowWindow) { - _this->ShowWindow(_this, window); - } - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); -} - -void -SDL_HideWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!(window->flags & SDL_WINDOW_SHOWN)) { - return; - } - - SDL_UpdateFullscreenMode(window, SDL_FALSE); - - if (_this->HideWindow) { - _this->HideWindow(_this, window); - } - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); -} - -void -SDL_RaiseWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!(window->flags & SDL_WINDOW_SHOWN)) { - return; - } - if (_this->RaiseWindow) { - _this->RaiseWindow(_this, window); - } -} - -void -SDL_MaximizeWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (window->flags & SDL_WINDOW_MAXIMIZED) { - return; - } - - /* !!! FIXME: should this check if the window is resizable? */ - - if (_this->MaximizeWindow) { - _this->MaximizeWindow(_this, window); - } -} - -void -SDL_MinimizeWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (window->flags & SDL_WINDOW_MINIMIZED) { - return; - } - - SDL_UpdateFullscreenMode(window, SDL_FALSE); - - if (_this->MinimizeWindow) { - _this->MinimizeWindow(_this, window); - } -} - -void -SDL_RestoreWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) { - return; - } - - if (_this->RestoreWindow) { - _this->RestoreWindow(_this, window); - } -} - -#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ) -int -SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) -{ - CHECK_WINDOW_MAGIC(window, -1); - - flags &= FULLSCREEN_MASK; - - if ( flags == (window->flags & FULLSCREEN_MASK) ) { - return 0; - } - - /* clear the previous flags and OR in the new ones */ - window->flags &= ~FULLSCREEN_MASK; - window->flags |= flags; - - SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)); - - return 0; -} - -static SDL_Surface * -SDL_CreateWindowFramebuffer(SDL_Window * window) -{ - Uint32 format; - void *pixels; - int pitch; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { - return NULL; - } - - if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { - return NULL; - } - - if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { - return NULL; - } - - return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask); -} - -SDL_Surface * -SDL_GetWindowSurface(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, NULL); - - if (!window->surface_valid) { - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - } - window->surface = SDL_CreateWindowFramebuffer(window); - if (window->surface) { - window->surface_valid = SDL_TRUE; - window->surface->flags |= SDL_DONTFREE; - } - } - return window->surface; -} - -int -SDL_UpdateWindowSurface(SDL_Window * window) -{ - SDL_Rect full_rect; - - CHECK_WINDOW_MAGIC(window, -1); - - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = window->w; - full_rect.h = window->h; - return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1); -} - -int -SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, - int numrects) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (!window->surface_valid) { - return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface"); - } - - return _this->UpdateWindowFramebuffer(_this, window, rects, numrects); -} - -int -SDL_SetWindowBrightness(SDL_Window * window, float brightness) -{ - Uint16 ramp[256]; - int status; - - CHECK_WINDOW_MAGIC(window, -1); - - SDL_CalculateGammaRamp(brightness, ramp); - status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp); - if (status == 0) { - window->brightness = brightness; - } - return status; -} - -float -SDL_GetWindowBrightness(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, 1.0f); - - return window->brightness; -} - -int -SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, - const Uint16 * green, - const Uint16 * blue) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (!_this->SetWindowGammaRamp) { - return SDL_Unsupported(); - } - - if (!window->gamma) { - if (SDL_GetWindowGammaRamp(window, NULL, NULL, NULL) < 0) { - return -1; - } - } - - if (red) { - SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16)); - } - if (green) { - SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16)); - } - if (blue) { - SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16)); - } - if (window->flags & SDL_WINDOW_INPUT_FOCUS) { - return _this->SetWindowGammaRamp(_this, window, window->gamma); - } else { - return 0; - } -} - -int -SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, - Uint16 * green, - Uint16 * blue) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (!window->gamma) { - int i; - - window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16)); - if (!window->gamma) { - return SDL_OutOfMemory(); - } - window->saved_gamma = window->gamma + 3*256; - - if (_this->GetWindowGammaRamp) { - if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) { - return -1; - } - } else { - /* Create an identity gamma ramp */ - for (i = 0; i < 256; ++i) { - Uint16 value = (Uint16)((i << 8) | i); - - window->gamma[0*256+i] = value; - window->gamma[1*256+i] = value; - window->gamma[2*256+i] = value; - } - } - SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16)); - } - - if (red) { - SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16)); - } - if (green) { - SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16)); - } - if (blue) { - SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16)); - } - return 0; -} - -void -SDL_UpdateWindowGrab(SDL_Window * window) -{ - if (_this->SetWindowGrab) { - SDL_bool grabbed; - if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - grabbed = SDL_TRUE; - } else { - grabbed = SDL_FALSE; - } - _this->SetWindowGrab(_this, window, grabbed); - } -} - -void -SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) { - return; - } - if (grabbed) { - window->flags |= SDL_WINDOW_INPUT_GRABBED; - } else { - window->flags &= ~SDL_WINDOW_INPUT_GRABBED; - } - SDL_UpdateWindowGrab(window); -} - -SDL_bool -SDL_GetWindowGrab(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, SDL_FALSE); - - return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0); -} - -void -SDL_OnWindowShown(SDL_Window * window) -{ - SDL_OnWindowRestored(window); -} - -void -SDL_OnWindowHidden(SDL_Window * window) -{ - SDL_UpdateFullscreenMode(window, SDL_FALSE); -} - -void -SDL_OnWindowResized(SDL_Window * window) -{ - window->surface_valid = SDL_FALSE; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); -} - -void -SDL_OnWindowMinimized(SDL_Window * window) -{ - SDL_UpdateFullscreenMode(window, SDL_FALSE); -} - -void -SDL_OnWindowRestored(SDL_Window * window) -{ - SDL_RaiseWindow(window); - - if (FULLSCREEN_VISIBLE(window)) { - SDL_UpdateFullscreenMode(window, SDL_TRUE); - } -} - -void -SDL_OnWindowEnter(SDL_Window * window) -{ - if (_this->OnWindowEnter) { - _this->OnWindowEnter(_this, window); - } -} - -void -SDL_OnWindowLeave(SDL_Window * window) -{ -} - -void -SDL_OnWindowFocusGained(SDL_Window * window) -{ - SDL_Mouse *mouse = SDL_GetMouse(); - - if (window->gamma && _this->SetWindowGammaRamp) { - _this->SetWindowGammaRamp(_this, window, window->gamma); - } - - if (mouse && mouse->relative_mode) { - SDL_SetMouseFocus(window); - SDL_WarpMouseInWindow(window, window->w/2, window->h/2); - } - - SDL_UpdateWindowGrab(window); -} - -static SDL_bool -ShouldMinimizeOnFocusLoss(SDL_Window * window) -{ - const char *hint; - - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - return SDL_FALSE; - } - -#ifdef __MACOSX__ - if (Cocoa_IsWindowInFullscreenSpace(window)) { - return SDL_FALSE; - } -#endif - - hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - - return SDL_TRUE; -} - -void -SDL_OnWindowFocusLost(SDL_Window * window) -{ - if (window->gamma && _this->SetWindowGammaRamp) { - _this->SetWindowGammaRamp(_this, window, window->saved_gamma); - } - - SDL_UpdateWindowGrab(window); - - if (ShouldMinimizeOnFocusLoss(window)) { - SDL_MinimizeWindow(window); - } -} - -SDL_Window * -SDL_GetFocusWindow(void) -{ - SDL_Window *window; - - if (!_this) { - return NULL; - } - for (window = _this->windows; window; window = window->next) { - if (window->flags & SDL_WINDOW_INPUT_FOCUS) { - return window; - } - } - return NULL; -} - -void -SDL_DestroyWindow(SDL_Window * window) -{ - SDL_VideoDisplay *display; - - CHECK_WINDOW_MAGIC(window, ); - - /* Restore video mode, etc. */ - SDL_HideWindow(window); - - /* Make sure this window no longer has focus */ - if (SDL_GetKeyboardFocus() == window) { - SDL_SetKeyboardFocus(NULL); - } - if (SDL_GetMouseFocus() == window) { - SDL_SetMouseFocus(NULL); - } - - /* make no context current if this is the current context window. */ - if (window->flags & SDL_WINDOW_OPENGL) { - if (_this->current_glwin == window) { - SDL_GL_MakeCurrent(window, NULL); - } - } - - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } - if (_this->DestroyWindow) { - _this->DestroyWindow(_this, window); - } - if (window->flags & SDL_WINDOW_OPENGL) { - SDL_GL_UnloadLibrary(); - } - - display = SDL_GetDisplayForWindow(window); - if (display->fullscreen_window == window) { - display->fullscreen_window = NULL; - } - - /* Now invalidate magic */ - window->magic = NULL; - - /* Free memory associated with the window */ - SDL_free(window->title); - SDL_FreeSurface(window->icon); - SDL_free(window->gamma); - while (window->data) { - SDL_WindowUserData *data = window->data; - - window->data = data->next; - SDL_free(data->name); - SDL_free(data); - } - - /* Unlink the window from the list */ - if (window->next) { - window->next->prev = window->prev; - } - if (window->prev) { - window->prev->next = window->next; - } else { - _this->windows = window->next; - } - - SDL_free(window); -} - -SDL_bool -SDL_IsScreenSaverEnabled() -{ - if (!_this) { - return SDL_TRUE; - } - return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE; -} - -void -SDL_EnableScreenSaver() -{ - if (!_this) { - return; - } - if (!_this->suspend_screensaver) { - return; - } - _this->suspend_screensaver = SDL_FALSE; - if (_this->SuspendScreenSaver) { - _this->SuspendScreenSaver(_this); - } -} - -void -SDL_DisableScreenSaver() -{ - if (!_this) { - return; - } - if (_this->suspend_screensaver) { - return; - } - _this->suspend_screensaver = SDL_TRUE; - if (_this->SuspendScreenSaver) { - _this->SuspendScreenSaver(_this); - } -} - -void -SDL_VideoQuit(void) -{ - int i, j; - - if (!_this) { - return; - } - - /* Halt event processing before doing anything else */ - SDL_TouchQuit(); - SDL_MouseQuit(); - SDL_KeyboardQuit(); - SDL_QuitSubSystem(SDL_INIT_EVENTS); - - SDL_EnableScreenSaver(); - - /* Clean up the system video */ - while (_this->windows) { - SDL_DestroyWindow(_this->windows); - } - _this->VideoQuit(_this); - - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - for (j = display->num_display_modes; j--;) { - SDL_free(display->display_modes[j].driverdata); - display->display_modes[j].driverdata = NULL; - } - SDL_free(display->display_modes); - display->display_modes = NULL; - SDL_free(display->desktop_mode.driverdata); - display->desktop_mode.driverdata = NULL; - SDL_free(display->driverdata); - display->driverdata = NULL; - } - if (_this->displays) { - for (i = 0; i < _this->num_displays; ++i) { - SDL_free(_this->displays[i].name); - } - SDL_free(_this->displays); - _this->displays = NULL; - _this->num_displays = 0; - } - SDL_free(_this->clipboard_text); - _this->clipboard_text = NULL; - _this->free(_this); - _this = NULL; -} - -int -SDL_GL_LoadLibrary(const char *path) -{ - int retval; - - if (!_this) { - return SDL_UninitializedVideo(); - } - if (_this->gl_config.driver_loaded) { - if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) { - return SDL_SetError("OpenGL library already loaded"); - } - retval = 0; - } else { - if (!_this->GL_LoadLibrary) { - return SDL_SetError("No dynamic GL support in video driver"); - } - retval = _this->GL_LoadLibrary(_this, path); - } - if (retval == 0) { - ++_this->gl_config.driver_loaded; - } else { - if (_this->GL_UnloadLibrary) { - _this->GL_UnloadLibrary(_this); - } - } - return (retval); -} - -void * -SDL_GL_GetProcAddress(const char *proc) -{ - void *func; - - if (!_this) { - SDL_UninitializedVideo(); - return NULL; - } - func = NULL; - if (_this->GL_GetProcAddress) { - if (_this->gl_config.driver_loaded) { - func = _this->GL_GetProcAddress(_this, proc); - } else { - SDL_SetError("No GL driver has been loaded"); - } - } else { - SDL_SetError("No dynamic GL support in video driver"); - } - return func; -} - -void -SDL_GL_UnloadLibrary(void) -{ - if (!_this) { - SDL_UninitializedVideo(); - return; - } - if (_this->gl_config.driver_loaded > 0) { - if (--_this->gl_config.driver_loaded > 0) { - return; - } - if (_this->GL_UnloadLibrary) { - _this->GL_UnloadLibrary(_this); - } - } -} - -static SDL_INLINE SDL_bool -isAtLeastGL3(const char *verstr) -{ - return ( verstr && (SDL_atoi(verstr) >= 3) ); -} - -SDL_bool -SDL_GL_ExtensionSupported(const char *extension) -{ -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); - const char *extensions; - const char *start; - const char *where, *terminator; - - /* Extension names should not have spaces. */ - where = SDL_strchr(extension, ' '); - if (where || *extension == '\0') { - return SDL_FALSE; - } - /* See if there's an environment variable override */ - start = SDL_getenv(extension); - if (start && *start == '0') { - return SDL_FALSE; - } - - /* Lookup the available extensions */ - - glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); - if (!glGetStringFunc) { - return SDL_FALSE; - } - - if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) { - const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint); - void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); - GLint num_exts = 0; - GLint i; - - glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi"); - glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); - if ((!glGetStringiFunc) || (!glGetIntegervFunc)) { - return SDL_FALSE; - } - - #ifndef GL_NUM_EXTENSIONS - #define GL_NUM_EXTENSIONS 0x821D - #endif - glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts); - for (i = 0; i < num_exts; i++) { - const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i); - if (SDL_strcmp(thisext, extension) == 0) { - return SDL_TRUE; - } - } - - return SDL_FALSE; - } - - /* Try the old way with glGetString(GL_EXTENSIONS) ... */ - - extensions = (const char *) glGetStringFunc(GL_EXTENSIONS); - if (!extensions) { - return SDL_FALSE; - } - /* - * It takes a bit of care to be fool-proof about parsing the OpenGL - * extensions string. Don't be fooled by sub-strings, etc. - */ - - start = extensions; - - for (;;) { - where = SDL_strstr(start, extension); - if (!where) - break; - - terminator = where + SDL_strlen(extension); - if (where == start || *(where - 1) == ' ') - if (*terminator == ' ' || *terminator == '\0') - return SDL_TRUE; - - start = terminator; - } - return SDL_FALSE; -#else - return SDL_FALSE; -#endif -} - -int -SDL_GL_SetAttribute(SDL_GLattr attr, int value) -{ -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - int retval; - - if (!_this) { - return SDL_UninitializedVideo(); - } - retval = 0; - switch (attr) { - case SDL_GL_RED_SIZE: - _this->gl_config.red_size = value; - break; - case SDL_GL_GREEN_SIZE: - _this->gl_config.green_size = value; - break; - case SDL_GL_BLUE_SIZE: - _this->gl_config.blue_size = value; - break; - case SDL_GL_ALPHA_SIZE: - _this->gl_config.alpha_size = value; - break; - case SDL_GL_DOUBLEBUFFER: - _this->gl_config.double_buffer = value; - break; - case SDL_GL_BUFFER_SIZE: - _this->gl_config.buffer_size = value; - break; - case SDL_GL_DEPTH_SIZE: - _this->gl_config.depth_size = value; - break; - case SDL_GL_STENCIL_SIZE: - _this->gl_config.stencil_size = value; - break; - case SDL_GL_ACCUM_RED_SIZE: - _this->gl_config.accum_red_size = value; - break; - case SDL_GL_ACCUM_GREEN_SIZE: - _this->gl_config.accum_green_size = value; - break; - case SDL_GL_ACCUM_BLUE_SIZE: - _this->gl_config.accum_blue_size = value; - break; - case SDL_GL_ACCUM_ALPHA_SIZE: - _this->gl_config.accum_alpha_size = value; - break; - case SDL_GL_STEREO: - _this->gl_config.stereo = value; - break; - case SDL_GL_MULTISAMPLEBUFFERS: - _this->gl_config.multisamplebuffers = value; - break; - case SDL_GL_MULTISAMPLESAMPLES: - _this->gl_config.multisamplesamples = value; - break; - case SDL_GL_ACCELERATED_VISUAL: - _this->gl_config.accelerated = value; - break; - case SDL_GL_RETAINED_BACKING: - _this->gl_config.retained_backing = value; - break; - case SDL_GL_CONTEXT_MAJOR_VERSION: - _this->gl_config.major_version = value; - break; - case SDL_GL_CONTEXT_MINOR_VERSION: - _this->gl_config.minor_version = value; - break; - case SDL_GL_CONTEXT_EGL: - /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */ - if (value != 0) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - } else { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); - }; - break; - case SDL_GL_CONTEXT_FLAGS: - if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG | - SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG | - SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG | - SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) { - retval = SDL_SetError("Unknown OpenGL context flag %d", value); - break; - } - _this->gl_config.flags = value; - break; - case SDL_GL_CONTEXT_PROFILE_MASK: - if( value != 0 && - value != SDL_GL_CONTEXT_PROFILE_CORE && - value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY && - value != SDL_GL_CONTEXT_PROFILE_ES ) { - retval = SDL_SetError("Unknown OpenGL context profile %d", value); - break; - } - _this->gl_config.profile_mask = value; - break; - case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: - _this->gl_config.share_with_current_context = value; - break; - case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: - _this->gl_config.framebuffer_srgb_capable = value; - break; - default: - retval = SDL_SetError("Unknown OpenGL attribute"); - break; - } - return retval; -#else - return SDL_Unsupported(); -#endif /* SDL_VIDEO_OPENGL */ -} - -int -SDL_GL_GetAttribute(SDL_GLattr attr, int *value) -{ -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); - GLenum(APIENTRY * glGetErrorFunc) (void); - GLenum attrib = 0; - GLenum error = 0; - - glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); - if (!glGetIntegervFunc) { - return -1; - } - - glGetErrorFunc = SDL_GL_GetProcAddress("glGetError"); - if (!glGetErrorFunc) { - return -1; - } - - /* Clear value in any case */ - *value = 0; - - switch (attr) { - case SDL_GL_RED_SIZE: - attrib = GL_RED_BITS; - break; - case SDL_GL_BLUE_SIZE: - attrib = GL_BLUE_BITS; - break; - case SDL_GL_GREEN_SIZE: - attrib = GL_GREEN_BITS; - break; - case SDL_GL_ALPHA_SIZE: - attrib = GL_ALPHA_BITS; - break; - case SDL_GL_DOUBLEBUFFER: -#if SDL_VIDEO_OPENGL - attrib = GL_DOUBLEBUFFER; - break; -#else - /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER */ - /* parameter which switches double buffer to single buffer. OpenGL ES */ - /* SDL driver must set proper value after initialization */ - *value = _this->gl_config.double_buffer; - return 0; -#endif - case SDL_GL_DEPTH_SIZE: - attrib = GL_DEPTH_BITS; - break; - case SDL_GL_STENCIL_SIZE: - attrib = GL_STENCIL_BITS; - break; -#if SDL_VIDEO_OPENGL - case SDL_GL_ACCUM_RED_SIZE: - attrib = GL_ACCUM_RED_BITS; - break; - case SDL_GL_ACCUM_GREEN_SIZE: - attrib = GL_ACCUM_GREEN_BITS; - break; - case SDL_GL_ACCUM_BLUE_SIZE: - attrib = GL_ACCUM_BLUE_BITS; - break; - case SDL_GL_ACCUM_ALPHA_SIZE: - attrib = GL_ACCUM_ALPHA_BITS; - break; - case SDL_GL_STEREO: - attrib = GL_STEREO; - break; -#else - case SDL_GL_ACCUM_RED_SIZE: - case SDL_GL_ACCUM_GREEN_SIZE: - case SDL_GL_ACCUM_BLUE_SIZE: - case SDL_GL_ACCUM_ALPHA_SIZE: - case SDL_GL_STEREO: - /* none of these are supported in OpenGL ES */ - *value = 0; - return 0; -#endif - case SDL_GL_MULTISAMPLEBUFFERS: -#if SDL_VIDEO_OPENGL - attrib = GL_SAMPLE_BUFFERS_ARB; -#else - attrib = GL_SAMPLE_BUFFERS; -#endif - break; - case SDL_GL_MULTISAMPLESAMPLES: -#if SDL_VIDEO_OPENGL - attrib = GL_SAMPLES_ARB; -#else - attrib = GL_SAMPLES; -#endif - break; - case SDL_GL_BUFFER_SIZE: - { - GLint bits = 0; - GLint component; - - /* - * there doesn't seem to be a single flag in OpenGL - * for this! - */ - glGetIntegervFunc(GL_RED_BITS, &component); - bits += component; - glGetIntegervFunc(GL_GREEN_BITS, &component); - bits += component; - glGetIntegervFunc(GL_BLUE_BITS, &component); - bits += component; - glGetIntegervFunc(GL_ALPHA_BITS, &component); - bits += component; - - *value = bits; - return 0; - } - case SDL_GL_ACCELERATED_VISUAL: - { - /* FIXME: How do we get this information? */ - *value = (_this->gl_config.accelerated != 0); - return 0; - } - case SDL_GL_RETAINED_BACKING: - { - *value = _this->gl_config.retained_backing; - return 0; - } - case SDL_GL_CONTEXT_MAJOR_VERSION: - { - *value = _this->gl_config.major_version; - return 0; - } - case SDL_GL_CONTEXT_MINOR_VERSION: - { - *value = _this->gl_config.minor_version; - return 0; - } - case SDL_GL_CONTEXT_EGL: - /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */ - { - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { - *value = 1; - } - else { - *value = 0; - } - return 0; - } - case SDL_GL_CONTEXT_FLAGS: - { - *value = _this->gl_config.flags; - return 0; - } - case SDL_GL_CONTEXT_PROFILE_MASK: - { - *value = _this->gl_config.profile_mask; - return 0; - } - case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: - { - *value = _this->gl_config.share_with_current_context; - return 0; - } - case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: - { - *value = _this->gl_config.framebuffer_srgb_capable; - return 0; - } - default: - return SDL_SetError("Unknown OpenGL attribute"); - } - - glGetIntegervFunc(attrib, (GLint *) value); - error = glGetErrorFunc(); - if (error != GL_NO_ERROR) { - if (error == GL_INVALID_ENUM) { - return SDL_SetError("OpenGL error: GL_INVALID_ENUM"); - } else if (error == GL_INVALID_VALUE) { - return SDL_SetError("OpenGL error: GL_INVALID_VALUE"); - } - return SDL_SetError("OpenGL error: %08X", error); - } - return 0; -#else - return SDL_Unsupported(); -#endif /* SDL_VIDEO_OPENGL */ -} - -SDL_GLContext -SDL_GL_CreateContext(SDL_Window * window) -{ - SDL_GLContext ctx = NULL; - CHECK_WINDOW_MAGIC(window, NULL); - - if (!(window->flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("The specified window isn't an OpenGL window"); - return NULL; - } - - ctx = _this->GL_CreateContext(_this, window); - - /* Creating a context is assumed to make it current in the SDL driver. */ - if (ctx) { - _this->current_glwin = window; - _this->current_glctx = ctx; - SDL_TLSSet(_this->current_glwin_tls, window, NULL); - SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); - } - return ctx; -} - -int -SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) -{ - int retval; - - if (window == SDL_GL_GetCurrentWindow() && - ctx == SDL_GL_GetCurrentContext()) { - /* We're already current. */ - return 0; - } - - if (!ctx) { - window = NULL; - } else { - CHECK_WINDOW_MAGIC(window, -1); - - if (!(window->flags & SDL_WINDOW_OPENGL)) { - return SDL_SetError("The specified window isn't an OpenGL window"); - } - } - - retval = _this->GL_MakeCurrent(_this, window, ctx); - if (retval == 0) { - _this->current_glwin = window; - _this->current_glctx = ctx; - SDL_TLSSet(_this->current_glwin_tls, window, NULL); - SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); - } - return retval; -} - -SDL_Window * -SDL_GL_GetCurrentWindow(void) -{ - if (!_this) { - SDL_UninitializedVideo(); - return NULL; - } - return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls); -} - -SDL_GLContext -SDL_GL_GetCurrentContext(void) -{ - if (!_this) { - SDL_UninitializedVideo(); - return NULL; - } - return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls); -} - -void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (_this->GL_GetDrawableSize) { - _this->GL_GetDrawableSize(_this, window, w, h); - } else { - SDL_GetWindowSize(window, w, h); - } -} - -int -SDL_GL_SetSwapInterval(int interval) -{ - if (!_this) { - return SDL_UninitializedVideo(); - } else if (SDL_GL_GetCurrentContext() == NULL) { - return SDL_SetError("No OpenGL context has been made current"); - } else if (_this->GL_SetSwapInterval) { - return _this->GL_SetSwapInterval(_this, interval); - } else { - return SDL_SetError("Setting the swap interval is not supported"); - } -} - -int -SDL_GL_GetSwapInterval(void) -{ - if (!_this) { - return 0; - } else if (SDL_GL_GetCurrentContext() == NULL) { - return 0; - } else if (_this->GL_GetSwapInterval) { - return _this->GL_GetSwapInterval(_this); - } else { - return 0; - } -} - -void -SDL_GL_SwapWindow(SDL_Window * window) -{ - CHECK_WINDOW_MAGIC(window, ); - - if (!(window->flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("The specified window isn't an OpenGL window"); - return; - } - - if (SDL_GL_GetCurrentWindow() != window) { - SDL_SetError("The specified window has not been made current"); - return; - } - - _this->GL_SwapWindow(_this, window); -} - -void -SDL_GL_DeleteContext(SDL_GLContext context) -{ - if (!_this || !context) { - return; - } - - if (SDL_GL_GetCurrentContext() == context) { - SDL_GL_MakeCurrent(NULL, NULL); - } - - _this->GL_DeleteContext(_this, context); -} - -#if 0 /* FIXME */ -/* - * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags - * & 2 for alpha channel. - */ -static void -CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) -{ - int x, y; - Uint32 colorkey; -#define SET_MASKBIT(icon, x, y, mask) \ - mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) - - colorkey = icon->format->colorkey; - switch (icon->format->BytesPerPixel) { - case 1: - { - Uint8 *pixels; - for (y = 0; y < icon->h; ++y) { - pixels = (Uint8 *) icon->pixels + y * icon->pitch; - for (x = 0; x < icon->w; ++x) { - if (*pixels++ == colorkey) { - SET_MASKBIT(icon, x, y, mask); - } - } - } - } - break; - - case 2: - { - Uint16 *pixels; - for (y = 0; y < icon->h; ++y) { - pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2; - for (x = 0; x < icon->w; ++x) { - if ((flags & 1) && *pixels == colorkey) { - SET_MASKBIT(icon, x, y, mask); - } else if ((flags & 2) - && (*pixels & icon->format->Amask) == 0) { - SET_MASKBIT(icon, x, y, mask); - } - pixels++; - } - } - } - break; - - case 4: - { - Uint32 *pixels; - for (y = 0; y < icon->h; ++y) { - pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4; - for (x = 0; x < icon->w; ++x) { - if ((flags & 1) && *pixels == colorkey) { - SET_MASKBIT(icon, x, y, mask); - } else if ((flags & 2) - && (*pixels & icon->format->Amask) == 0) { - SET_MASKBIT(icon, x, y, mask); - } - pixels++; - } - } - } - break; - } -} - -/* - * Sets the window manager icon for the display window. - */ -void -SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) -{ - if (icon && _this->SetIcon) { - /* Generate a mask if necessary, and create the icon! */ - if (mask == NULL) { - int mask_len = icon->h * (icon->w + 7) / 8; - int flags = 0; - mask = (Uint8 *) SDL_malloc(mask_len); - if (mask == NULL) { - return; - } - SDL_memset(mask, ~0, mask_len); - if (icon->flags & SDL_SRCCOLORKEY) - flags |= 1; - if (icon->flags & SDL_SRCALPHA) - flags |= 2; - if (flags) { - CreateMaskFromColorKeyOrAlpha(icon, mask, flags); - } - _this->SetIcon(_this, icon, mask); - SDL_free(mask); - } else { - _this->SetIcon(_this, icon, mask); - } - } -} -#endif - -SDL_bool -SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) -{ - CHECK_WINDOW_MAGIC(window, SDL_FALSE); - - if (!info) { - return SDL_FALSE; - } - info->subsystem = SDL_SYSWM_UNKNOWN; - - if (!_this->GetWindowWMInfo) { - return SDL_FALSE; - } - return (_this->GetWindowWMInfo(_this, window, info)); -} - -void -SDL_StartTextInput(void) -{ - SDL_Window *window; - - /* First, enable text events */ - SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); - SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); - - /* Then show the on-screen keyboard, if any */ - window = SDL_GetFocusWindow(); - if (window && _this && _this->ShowScreenKeyboard) { - _this->ShowScreenKeyboard(_this, window); - } - - /* Finally start the text input system */ - if (_this && _this->StartTextInput) { - _this->StartTextInput(_this); - } -} - -SDL_bool -SDL_IsTextInputActive(void) -{ - return (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE); -} - -void -SDL_StopTextInput(void) -{ - SDL_Window *window; - - /* Stop the text input system */ - if (_this && _this->StopTextInput) { - _this->StopTextInput(_this); - } - - /* Hide the on-screen keyboard, if any */ - window = SDL_GetFocusWindow(); - if (window && _this && _this->HideScreenKeyboard) { - _this->HideScreenKeyboard(_this, window); - } - - /* Finally disable text events */ - SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); - SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); -} - -void -SDL_SetTextInputRect(SDL_Rect *rect) -{ - if (_this && _this->SetTextInputRect) { - _this->SetTextInputRect(_this, rect); - } -} - -SDL_bool -SDL_HasScreenKeyboardSupport(void) -{ - if (_this && _this->HasScreenKeyboardSupport) { - return _this->HasScreenKeyboardSupport(_this); - } - return SDL_FALSE; -} - -SDL_bool -SDL_IsScreenKeyboardShown(SDL_Window *window) -{ - if (window && _this && _this->IsScreenKeyboardShown) { - return _this->IsScreenKeyboardShown(_this, window); - } - return SDL_FALSE; -} - -#if SDL_VIDEO_DRIVER_WINDOWS -#include "windows/SDL_windowsmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_COCOA -#include "cocoa/SDL_cocoamessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_UIKIT -#include "uikit/SDL_uikitmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_X11 -#include "x11/SDL_x11messagebox.h" -#endif - -static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) -{ - SDL_SysWMinfo info; - SDL_Window *window = messageboxdata->window; - - if (!window) { - return SDL_TRUE; - } - - SDL_VERSION(&info.version); - if (!SDL_GetWindowWMInfo(window, &info)) { - return SDL_TRUE; - } else { - return (info.subsystem == drivertype); - } -} - -int -SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) -{ - int dummybutton; - int retval = -1; - SDL_bool relative_mode; - int show_cursor_prev; - - if (!messageboxdata) { - return SDL_InvalidParamError("messageboxdata"); - } - - relative_mode = SDL_GetRelativeMouseMode(); - SDL_SetRelativeMouseMode(SDL_FALSE); - show_cursor_prev = SDL_ShowCursor(1); - - if (!buttonid) { - buttonid = &dummybutton; - } - - if (_this && _this->ShowMessageBox) { - retval = _this->ShowMessageBox(_this, messageboxdata, buttonid); - } - - /* It's completely fine to call this function before video is initialized */ -#if SDL_VIDEO_DRIVER_WINDOWS - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINDOWS) && - WIN_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_COCOA - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) && - Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_UIKIT - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) && - UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_X11 - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) && - X11_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif - if (retval == -1) { - SDL_SetError("No message system available"); - } - - SDL_ShowCursor(show_cursor_prev); - SDL_SetRelativeMouseMode(relative_mode); - - return retval; -} - -int -SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) -{ - SDL_MessageBoxData data; - SDL_MessageBoxButtonData button; - - SDL_zero(data); - data.flags = flags; - data.title = title; - data.message = message; - data.numbuttons = 1; - data.buttons = &button; - data.window = window; - - SDL_zero(button); - button.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; - button.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; - button.text = "OK"; - - return SDL_ShowMessageBox(&data, NULL); -} - -SDL_bool -SDL_ShouldAllowTopmost(void) -{ - const char *hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - return SDL_TRUE; -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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" + +/* The high-level video driver subsystem */ + +#include "SDL.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_rect_c.h" +#include "../events/SDL_events_c.h" +#include "../timer/SDL_timer_c.h" + +#if SDL_VIDEO_OPENGL +#include "SDL_opengl.h" +#endif /* SDL_VIDEO_OPENGL */ + +#if SDL_VIDEO_OPENGL_ES +#include "SDL_opengles.h" +#endif /* SDL_VIDEO_OPENGL_ES */ + +/* GL and GLES2 headers conflict on Linux 32 bits */ +#if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL +#include "SDL_opengles2.h" +#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */ + +#include "SDL_syswm.h" + +/* On Windows, windows.h defines CreateWindow */ +#ifdef CreateWindow +#undef CreateWindow +#endif + +/* Available video drivers */ +static VideoBootStrap *bootstrap[] = { +#if SDL_VIDEO_DRIVER_COCOA + &COCOA_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_X11 + &X11_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DIRECTFB + &DirectFB_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_WINDOWS + &WINDOWS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_WINRT + &WINRT_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_HAIKU + &HAIKU_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PANDORA + &PND_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_UIKIT + &UIKIT_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_ANDROID + &Android_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PSP + &PSP_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_RPI + &RPI_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DUMMY + &DUMMY_bootstrap, +#endif + NULL +}; + +static SDL_VideoDevice *_this = NULL; + +#define CHECK_WINDOW_MAGIC(window, retval) \ + if (!_this) { \ + SDL_UninitializedVideo(); \ + return retval; \ + } \ + if (!window || window->magic != &_this->window_magic) { \ + SDL_SetError("Invalid window"); \ + return retval; \ + } + +#define CHECK_DISPLAY_INDEX(displayIndex, retval) \ + if (!_this) { \ + SDL_UninitializedVideo(); \ + return retval; \ + } \ + if (displayIndex < 0 || displayIndex >= _this->num_displays) { \ + SDL_SetError("displayIndex must be in the range 0 - %d", \ + _this->num_displays - 1); \ + return retval; \ + } + + +#ifdef __MACOSX__ +/* Support for Mac OS X fullscreen spaces */ +extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window); +extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state); +#endif + + +/* Support for framebuffer emulation using an accelerated renderer */ + +#define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" + +typedef struct { + SDL_Renderer *renderer; + SDL_Texture *texture; + void *pixels; + int pitch; + int bytes_per_pixel; +} SDL_WindowTextureData; + +static SDL_bool +ShouldUseTextureFramebuffer() +{ + const char *hint; + + /* If there's no native framebuffer support then there's no option */ + if (!_this->CreateWindowFramebuffer) { + return SDL_TRUE; + } + + /* If the user has specified a software renderer we can't use a + texture framebuffer, or renderer creation will go recursive. + */ + hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); + if (hint && SDL_strcasecmp(hint, "software") == 0) { + return SDL_FALSE; + } + + /* See if the user or application wants a specific behavior */ + hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + if (hint) { + if (*hint == '0') { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } + + /* Each platform has different performance characteristics */ +#if defined(__WIN32__) + /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. + */ + return SDL_FALSE; + +#elif defined(__MACOSX__) + /* Mac OS X uses OpenGL as the native fast path */ + return SDL_TRUE; + +#elif defined(__LINUX__) + /* Properly configured OpenGL drivers are faster than MIT-SHM */ +#if SDL_VIDEO_OPENGL + /* Ugh, find a way to cache this value! */ + { + SDL_Window *window; + SDL_GLContext context; + SDL_bool hasAcceleratedOpenGL = SDL_FALSE; + + window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN); + if (window) { + context = SDL_GL_CreateContext(window); + if (context) { + const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); + const char *vendor = NULL; + + glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); + if (glGetStringFunc) { + vendor = (const char *) glGetStringFunc(GL_VENDOR); + } + /* Add more vendors here at will... */ + if (vendor && + (SDL_strstr(vendor, "ATI Technologies") || + SDL_strstr(vendor, "NVIDIA"))) { + hasAcceleratedOpenGL = SDL_TRUE; + } + SDL_GL_DeleteContext(context); + } + SDL_DestroyWindow(window); + } + return hasAcceleratedOpenGL; + } +#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + /* Let's be optimistic about this! */ + return SDL_TRUE; +#else + return SDL_FALSE; +#endif + +#else + /* Play it safe, assume that if there is a framebuffer driver that it's + optimized for the current platform. + */ + return SDL_FALSE; +#endif +} + +static int +SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_WindowTextureData *data; + SDL_RendererInfo info; + Uint32 i; + + data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); + if (!data) { + SDL_Renderer *renderer = NULL; + SDL_RendererInfo info; + int i; + const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + + /* Check to see if there's a specific driver requested */ + if (hint && *hint != '0' && *hint != '1' && + SDL_strcasecmp(hint, "software") != 0) { + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { + SDL_GetRenderDriverInfo(i, &info); + if (SDL_strcasecmp(info.name, hint) == 0) { + renderer = SDL_CreateRenderer(window, i, 0); + break; + } + } + } + + if (!renderer) { + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { + SDL_GetRenderDriverInfo(i, &info); + if (SDL_strcmp(info.name, "software") != 0) { + renderer = SDL_CreateRenderer(window, i, 0); + if (renderer) { + break; + } + } + } + } + if (!renderer) { + return SDL_SetError("No hardware accelerated renderers available"); + } + + /* Create the data after we successfully create the renderer (bug #1116) */ + data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_DestroyRenderer(renderer); + return SDL_OutOfMemory(); + } + SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data); + + data->renderer = renderer; + } + + /* Free any old texture and pixel data */ + if (data->texture) { + SDL_DestroyTexture(data->texture); + data->texture = NULL; + } + SDL_free(data->pixels); + data->pixels = NULL; + + if (SDL_GetRendererInfo(data->renderer, &info) < 0) { + return -1; + } + + /* Find the first format without an alpha channel */ + *format = info.texture_formats[0]; + for (i = 0; i < info.num_texture_formats; ++i) { + if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && + !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { + *format = info.texture_formats[i]; + break; + } + } + + data->texture = SDL_CreateTexture(data->renderer, *format, + SDL_TEXTUREACCESS_STREAMING, + window->w, window->h); + if (!data->texture) { + return -1; + } + + /* Create framebuffer data */ + data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format); + data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3); + data->pixels = SDL_malloc(window->h * data->pitch); + if (!data->pixels) { + return SDL_OutOfMemory(); + } + + *pixels = data->pixels; + *pitch = data->pitch; + + /* Make sure we're not double-scaling the viewport */ + SDL_RenderSetViewport(data->renderer, NULL); + + return 0; +} + +static int +SDL_UpdateWindowTexture(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + SDL_WindowTextureData *data; + SDL_Rect rect; + void *src; + + data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); + if (!data || !data->texture) { + return SDL_SetError("No window texture data"); + } + + /* Update a single rect that contains subrects for best DMA performance */ + if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) { + src = (void *)((Uint8 *)data->pixels + + rect.y * data->pitch + + rect.x * data->bytes_per_pixel); + if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) { + return -1; + } + + if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) { + return -1; + } + + SDL_RenderPresent(data->renderer); + } + return 0; +} + +static void +SDL_DestroyWindowTexture(_THIS, SDL_Window * window) +{ + SDL_WindowTextureData *data; + + data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, NULL); + if (!data) { + return; + } + if (data->texture) { + SDL_DestroyTexture(data->texture); + } + if (data->renderer) { + SDL_DestroyRenderer(data->renderer); + } + SDL_free(data->pixels); + SDL_free(data); +} + + +static int +cmpmodes(const void *A, const void *B) +{ + const SDL_DisplayMode *a = (const SDL_DisplayMode *) A; + const SDL_DisplayMode *b = (const SDL_DisplayMode *) B; + if (a == b) { + return 0; + } else if (a->w != b->w) { + return b->w - a->w; + } else if (a->h != b->h) { + return b->h - a->h; + } else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) { + return SDL_BITSPERPIXEL(b->format) - SDL_BITSPERPIXEL(a->format); + } else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) { + return SDL_PIXELLAYOUT(b->format) - SDL_PIXELLAYOUT(a->format); + } else if (a->refresh_rate != b->refresh_rate) { + return b->refresh_rate - a->refresh_rate; + } + return 0; +} + +static int +SDL_UninitializedVideo() +{ + return SDL_SetError("Video subsystem has not been initialized"); +} + +int +SDL_GetNumVideoDrivers(void) +{ + return SDL_arraysize(bootstrap) - 1; +} + +const char * +SDL_GetVideoDriver(int index) +{ + if (index >= 0 && index < SDL_GetNumVideoDrivers()) { + return bootstrap[index]->name; + } + return NULL; +} + +/* + * Initialize the video and event subsystems -- determine native pixel format + */ +int +SDL_VideoInit(const char *driver_name) +{ + SDL_VideoDevice *video; + int index; + int i; + + /* Check to make sure we don't overwrite '_this' */ + if (_this != NULL) { + SDL_VideoQuit(); + } + +#if !SDL_TIMERS_DISABLED + SDL_InitTicks(); +#endif + + /* Start the event loop */ + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || + SDL_KeyboardInit() < 0 || + SDL_MouseInit() < 0 || + SDL_TouchInit() < 0) { + return -1; + } + + /* Select the proper video driver */ + index = 0; + video = NULL; + if (driver_name == NULL) { + driver_name = SDL_getenv("SDL_VIDEODRIVER"); + } + if (driver_name != NULL) { + for (i = 0; bootstrap[i]; ++i) { + if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) { + video = bootstrap[i]->create(index); + break; + } + } + } else { + for (i = 0; bootstrap[i]; ++i) { + if (bootstrap[i]->available()) { + video = bootstrap[i]->create(index); + if (video != NULL) { + break; + } + } + } + } + if (video == NULL) { + if (driver_name) { + return SDL_SetError("%s not available", driver_name); + } + return SDL_SetError("No available video device"); + } + _this = video; + _this->name = bootstrap[i]->name; + _this->next_object_id = 1; + + + /* Set some very sane GL defaults */ + _this->gl_config.driver_loaded = 0; + _this->gl_config.dll_handle = NULL; + _this->gl_config.red_size = 3; + _this->gl_config.green_size = 3; + _this->gl_config.blue_size = 2; + _this->gl_config.alpha_size = 0; + _this->gl_config.buffer_size = 0; + _this->gl_config.depth_size = 16; + _this->gl_config.stencil_size = 0; + _this->gl_config.double_buffer = 1; + _this->gl_config.accum_red_size = 0; + _this->gl_config.accum_green_size = 0; + _this->gl_config.accum_blue_size = 0; + _this->gl_config.accum_alpha_size = 0; + _this->gl_config.stereo = 0; + _this->gl_config.multisamplebuffers = 0; + _this->gl_config.multisamplesamples = 0; + _this->gl_config.retained_backing = 1; + _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ + _this->gl_config.profile_mask = 0; +#if SDL_VIDEO_OPENGL + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 1; +#elif SDL_VIDEO_OPENGL_ES2 + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; +#elif SDL_VIDEO_OPENGL_ES + _this->gl_config.major_version = 1; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; +#endif + _this->gl_config.flags = 0; + + _this->gl_config.share_with_current_context = 0; + + _this->current_glwin_tls = SDL_TLSCreate(); + _this->current_glctx_tls = SDL_TLSCreate(); + + /* Initialize the video subsystem */ + if (_this->VideoInit(_this) < 0) { + SDL_VideoQuit(); + return -1; + } + + /* Make sure some displays were added */ + if (_this->num_displays == 0) { + SDL_VideoQuit(); + return SDL_SetError("The video driver did not add any displays"); + } + + /* Add the renderer framebuffer emulation if desired */ + if (ShouldUseTextureFramebuffer()) { + _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; + _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; + _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; + } + + /* If we don't use a screen keyboard, turn on text input by default, + otherwise programs that expect to get text events without enabling + UNICODE input won't get any events. + + Actually, come to think of it, you needed to call SDL_EnableUNICODE(1) + in SDL 1.2 before you got text input events. Hmm... + */ + if (!SDL_HasScreenKeyboardSupport()) { + SDL_StartTextInput(); + } + + /* We're ready to go! */ + return 0; +} + +const char * +SDL_GetCurrentVideoDriver() +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return _this->name; +} + +SDL_VideoDevice * +SDL_GetVideoDevice(void) +{ + return _this; +} + +int +SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) +{ + SDL_VideoDisplay display; + + SDL_zero(display); + if (desktop_mode) { + display.desktop_mode = *desktop_mode; + } + display.current_mode = display.desktop_mode; + + return SDL_AddVideoDisplay(&display); +} + +int +SDL_AddVideoDisplay(const SDL_VideoDisplay * display) +{ + SDL_VideoDisplay *displays; + int index = -1; + + displays = + SDL_realloc(_this->displays, + (_this->num_displays + 1) * sizeof(*displays)); + if (displays) { + index = _this->num_displays++; + displays[index] = *display; + displays[index].device = _this; + _this->displays = displays; + + if (display->name) { + displays[index].name = SDL_strdup(display->name); + } else { + char name[32]; + + SDL_itoa(index, name, 10); + displays[index].name = SDL_strdup(name); + } + } else { + SDL_OutOfMemory(); + } + return index; +} + +int +SDL_GetNumVideoDisplays(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return 0; + } + return _this->num_displays; +} + +static int +SDL_GetIndexOfDisplay(SDL_VideoDisplay *display) +{ + int displayIndex; + + for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) { + if (display == &_this->displays[displayIndex]) { + return displayIndex; + } + } + + /* Couldn't find the display, just use index 0 */ + return 0; +} + +void * +SDL_GetDisplayDriverData( int displayIndex ) +{ + CHECK_DISPLAY_INDEX( displayIndex, NULL ); + + return _this->displays[displayIndex].driverdata; +} + +const char * +SDL_GetDisplayName(int displayIndex) +{ + CHECK_DISPLAY_INDEX(displayIndex, NULL); + + return _this->displays[displayIndex].name; +} + +int +SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect) +{ + CHECK_DISPLAY_INDEX(displayIndex, -1); + + if (rect) { + SDL_VideoDisplay *display = &_this->displays[displayIndex]; + + if (_this->GetDisplayBounds) { + if (_this->GetDisplayBounds(_this, display, rect) == 0) { + return 0; + } + } + + /* Assume that the displays are left to right */ + if (displayIndex == 0) { + rect->x = 0; + rect->y = 0; + } else { + SDL_GetDisplayBounds(displayIndex-1, rect); + rect->x += rect->w; + } + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + } + return 0; +} + +SDL_bool +SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_DisplayMode *modes; + int i, nmodes; + + /* Make sure we don't already have the mode in the list */ + modes = display->display_modes; + nmodes = display->num_display_modes; + for (i = 0; i < nmodes; ++i) { + if (cmpmodes(mode, &modes[i]) == 0) { + return SDL_FALSE; + } + } + + /* Go ahead and add the new mode */ + if (nmodes == display->max_display_modes) { + modes = + SDL_realloc(modes, + (display->max_display_modes + 32) * sizeof(*modes)); + if (!modes) { + return SDL_FALSE; + } + display->display_modes = modes; + display->max_display_modes += 32; + } + modes[nmodes] = *mode; + display->num_display_modes++; + + /* Re-sort video modes */ + SDL_qsort(display->display_modes, display->num_display_modes, + sizeof(SDL_DisplayMode), cmpmodes); + + return SDL_TRUE; +} + +static int +SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) +{ + if (!display->num_display_modes && _this->GetDisplayModes) { + _this->GetDisplayModes(_this, display); + SDL_qsort(display->display_modes, display->num_display_modes, + sizeof(SDL_DisplayMode), cmpmodes); + } + return display->num_display_modes; +} + +int +SDL_GetNumDisplayModes(int displayIndex) +{ + CHECK_DISPLAY_INDEX(displayIndex, -1); + + return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]); +} + +int +SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) +{ + SDL_VideoDisplay *display; + + CHECK_DISPLAY_INDEX(displayIndex, -1); + + display = &_this->displays[displayIndex]; + if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) { + return SDL_SetError("index must be in the range of 0 - %d", + SDL_GetNumDisplayModesForDisplay(display) - 1); + } + if (mode) { + *mode = display->display_modes[index]; + } + return 0; +} + +int +SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode) +{ + SDL_VideoDisplay *display; + + CHECK_DISPLAY_INDEX(displayIndex, -1); + + display = &_this->displays[displayIndex]; + if (mode) { + *mode = display->desktop_mode; + } + return 0; +} + +int +SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode) +{ + SDL_VideoDisplay *display; + + CHECK_DISPLAY_INDEX(displayIndex, -1); + + display = &_this->displays[displayIndex]; + if (mode) { + *mode = display->current_mode; + } + return 0; +} + +static SDL_DisplayMode * +SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, + const SDL_DisplayMode * mode, + SDL_DisplayMode * closest) +{ + Uint32 target_format; + int target_refresh_rate; + int i; + SDL_DisplayMode *current, *match; + + if (!mode || !closest) { + SDL_SetError("Missing desired mode or closest mode parameter"); + return NULL; + } + + /* Default to the desktop format */ + if (mode->format) { + target_format = mode->format; + } else { + target_format = display->desktop_mode.format; + } + + /* Default to the desktop refresh rate */ + if (mode->refresh_rate) { + target_refresh_rate = mode->refresh_rate; + } else { + target_refresh_rate = display->desktop_mode.refresh_rate; + } + + match = NULL; + for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) { + current = &display->display_modes[i]; + + if (current->w && (current->w < mode->w)) { + /* Out of sorted modes large enough here */ + break; + } + if (current->h && (current->h < mode->h)) { + if (current->w && (current->w == mode->w)) { + /* Out of sorted modes large enough here */ + break; + } + /* Wider, but not tall enough, due to a different + aspect ratio. This mode must be skipped, but closer + modes may still follow. */ + continue; + } + if (!match || current->w < match->w || current->h < match->h) { + match = current; + continue; + } + if (current->format != match->format) { + /* Sorted highest depth to lowest */ + if (current->format == target_format || + (SDL_BITSPERPIXEL(current->format) >= + SDL_BITSPERPIXEL(target_format) + && SDL_PIXELTYPE(current->format) == + SDL_PIXELTYPE(target_format))) { + match = current; + } + continue; + } + if (current->refresh_rate != match->refresh_rate) { + /* Sorted highest refresh to lowest */ + if (current->refresh_rate >= target_refresh_rate) { + match = current; + } + } + } + if (match) { + if (match->format) { + closest->format = match->format; + } else { + closest->format = mode->format; + } + if (match->w && match->h) { + closest->w = match->w; + closest->h = match->h; + } else { + closest->w = mode->w; + closest->h = mode->h; + } + if (match->refresh_rate) { + closest->refresh_rate = match->refresh_rate; + } else { + closest->refresh_rate = mode->refresh_rate; + } + closest->driverdata = match->driverdata; + + /* + * Pick some reasonable defaults if the app and driver don't + * care + */ + if (!closest->format) { + closest->format = SDL_PIXELFORMAT_RGB888; + } + if (!closest->w) { + closest->w = 640; + } + if (!closest->h) { + closest->h = 480; + } + return closest; + } + return NULL; +} + +SDL_DisplayMode * +SDL_GetClosestDisplayMode(int displayIndex, + const SDL_DisplayMode * mode, + SDL_DisplayMode * closest) +{ + SDL_VideoDisplay *display; + + CHECK_DISPLAY_INDEX(displayIndex, NULL); + + display = &_this->displays[displayIndex]; + return SDL_GetClosestDisplayModeForDisplay(display, mode, closest); +} + +static int +SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_DisplayMode display_mode; + SDL_DisplayMode current_mode; + + if (mode) { + display_mode = *mode; + + /* Default to the current mode */ + if (!display_mode.format) { + display_mode.format = display->current_mode.format; + } + if (!display_mode.w) { + display_mode.w = display->current_mode.w; + } + if (!display_mode.h) { + display_mode.h = display->current_mode.h; + } + if (!display_mode.refresh_rate) { + display_mode.refresh_rate = display->current_mode.refresh_rate; + } + + /* Get a good video mode, the closest one possible */ + if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) { + return SDL_SetError("No video mode large enough for %dx%d", + display_mode.w, display_mode.h); + } + } else { + display_mode = display->desktop_mode; + } + + /* See if there's anything left to do */ + current_mode = display->current_mode; + if (SDL_memcmp(&display_mode, ¤t_mode, sizeof(display_mode)) == 0) { + return 0; + } + + /* Actually change the display mode */ + if (!_this->SetDisplayMode) { + return SDL_SetError("Video driver doesn't support changing display mode"); + } + if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { + return -1; + } + display->current_mode = display_mode; + return 0; +} + +int +SDL_GetWindowDisplayIndex(SDL_Window * window) +{ + int displayIndex; + int i, dist; + int closest = -1; + int closest_dist = 0x7FFFFFFF; + SDL_Point center; + SDL_Point delta; + SDL_Rect rect; + + CHECK_WINDOW_MAGIC(window, -1); + + if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || + SDL_WINDOWPOS_ISCENTERED(window->x)) { + displayIndex = (window->x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; + } + if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || + SDL_WINDOWPOS_ISCENTERED(window->y)) { + displayIndex = (window->y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; + } + + /* Find the display containing the window */ + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + + if (display->fullscreen_window == window) { + return i; + } + } + center.x = window->x + window->w / 2; + center.y = window->y + window->h / 2; + for (i = 0; i < _this->num_displays; ++i) { + SDL_GetDisplayBounds(i, &rect); + if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { + return i; + } + + delta.x = center.x - (rect.x + rect.w / 2); + delta.y = center.y - (rect.y + rect.h / 2); + dist = (delta.x*delta.x + delta.y*delta.y); + if (dist < closest_dist) { + closest = i; + closest_dist = dist; + } + } + if (closest < 0) { + SDL_SetError("Couldn't find any displays"); + } + return closest; +} + +SDL_VideoDisplay * +SDL_GetDisplayForWindow(SDL_Window *window) +{ + int displayIndex = SDL_GetWindowDisplayIndex(window); + if (displayIndex >= 0) { + return &_this->displays[displayIndex]; + } else { + return NULL; + } +} + +int +SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (mode) { + window->fullscreen_mode = *mode; + } else { + SDL_zero(window->fullscreen_mode); + } + return 0; +} + +int +SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) +{ + SDL_DisplayMode fullscreen_mode; + SDL_VideoDisplay *display; + + if (!mode) { + return SDL_InvalidParamError("mode"); + } + + CHECK_WINDOW_MAGIC(window, -1); + + fullscreen_mode = window->fullscreen_mode; + if (!fullscreen_mode.w) { + fullscreen_mode.w = window->w; + } + if (!fullscreen_mode.h) { + fullscreen_mode.h = window->h; + } + + display = SDL_GetDisplayForWindow(window); + + /* if in desktop size mode, just return the size of the desktop */ + if ( ( window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP ) + { + fullscreen_mode = display->desktop_mode; + } + else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), + &fullscreen_mode, + &fullscreen_mode)) { + return SDL_SetError("Couldn't find display mode match"); + } + + if (mode) { + *mode = fullscreen_mode; + } + return 0; +} + +Uint32 +SDL_GetWindowPixelFormat(SDL_Window * window) +{ + SDL_VideoDisplay *display; + + CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN); + + display = SDL_GetDisplayForWindow(window); + return display->current_mode.format; +} + +static void +SDL_RestoreMousePosition(SDL_Window *window) +{ + int x, y; + + if (window == SDL_GetMouseFocus()) { + SDL_GetMouseState(&x, &y); + SDL_WarpMouseInWindow(window, x, y); + } +} + +static void +SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) +{ + SDL_VideoDisplay *display; + SDL_Window *other; + +#ifdef __MACOSX__ + if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) { + return; + } +#endif + + display = SDL_GetDisplayForWindow(window); + + if (fullscreen) { + /* Hide any other fullscreen windows */ + if (display->fullscreen_window && + display->fullscreen_window != window) { + SDL_MinimizeWindow(display->fullscreen_window); + } + } + + /* See if anything needs to be done now */ + if ((display->fullscreen_window == window) == fullscreen) { + return; + } + + /* See if there are any fullscreen windows */ + for (other = _this->windows; other; other = other->next) { + SDL_bool setDisplayMode = SDL_FALSE; + + if (other == window) { + setDisplayMode = fullscreen; + } else if (FULLSCREEN_VISIBLE(other) && + SDL_GetDisplayForWindow(other) == display) { + setDisplayMode = SDL_TRUE; + } + + if (setDisplayMode) { + SDL_DisplayMode fullscreen_mode; + + if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) { + SDL_bool resized = SDL_TRUE; + + if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) { + resized = SDL_FALSE; + } + + /* only do the mode change if we want exclusive fullscreen */ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { + SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); + } else { + SDL_SetDisplayModeForDisplay(display, NULL); + } + + if (_this->SetWindowFullscreen) { + _this->SetWindowFullscreen(_this, other, display, SDL_TRUE); + } + display->fullscreen_window = other; + + /* Generate a mode change event here */ + if (resized) { + SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED, + fullscreen_mode.w, fullscreen_mode.h); + } else { + SDL_OnWindowResized(other); + } + + SDL_RestoreMousePosition(other); + return; + } + } + } + + /* Nope, restore the desktop mode */ + SDL_SetDisplayModeForDisplay(display, NULL); + + if (_this->SetWindowFullscreen) { + _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); + } + display->fullscreen_window = NULL; + + /* Generate a mode change event here */ + SDL_OnWindowResized(window); + + /* Restore the cursor position */ + SDL_RestoreMousePosition(window); +} + +#define CREATE_FLAGS \ + (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI) + +static void +SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) +{ + window->windowed.x = window->x; + window->windowed.y = window->y; + window->windowed.w = window->w; + window->windowed.h = window->h; + + if (flags & SDL_WINDOW_MAXIMIZED) { + SDL_MaximizeWindow(window); + } + if (flags & SDL_WINDOW_MINIMIZED) { + SDL_MinimizeWindow(window); + } + if (flags & SDL_WINDOW_FULLSCREEN) { + SDL_SetWindowFullscreen(window, flags); + } + if (flags & SDL_WINDOW_INPUT_GRABBED) { + SDL_SetWindowGrab(window, SDL_TRUE); + } + if (!(flags & SDL_WINDOW_HIDDEN)) { + SDL_ShowWindow(window); + } +} + +SDL_Window * +SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) +{ + SDL_Window *window; + const char *hint; + + if (!_this) { + /* Initialize the video system if needed */ + if (SDL_VideoInit(NULL) < 0) { + return NULL; + } + } + + /* Some platforms can't create zero-sized windows */ + if (w < 1) { + w = 1; + } + if (h < 1) { + h = 1; + } + + /* Some platforms have OpenGL enabled by default */ +#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ + flags |= SDL_WINDOW_OPENGL; +#endif + if (flags & SDL_WINDOW_OPENGL) { + if (!_this->GL_CreateContext) { + SDL_SetError("No OpenGL support in video driver"); + return NULL; + } + if (SDL_GL_LoadLibrary(NULL) < 0) { + return NULL; + } + } + + /* Unless the user has specified the high-DPI disabling hint, respect the + * SDL_WINDOW_ALLOW_HIGHDPI flag. + */ + if (flags & SDL_WINDOW_ALLOW_HIGHDPI) { + hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED); + if (hint && SDL_atoi(hint) > 0) { + flags &= ~SDL_WINDOW_ALLOW_HIGHDPI; + } + } + + window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); + if (!window) { + SDL_OutOfMemory(); + return NULL; + } + window->magic = &_this->window_magic; + window->id = _this->next_object_id++; + window->x = x; + window->y = y; + window->w = w; + window->h = h; + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || + SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + int displayIndex; + SDL_Rect bounds; + + displayIndex = SDL_GetIndexOfDisplay(display); + SDL_GetDisplayBounds(displayIndex, &bounds); + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + window->x = bounds.x + (bounds.w - w) / 2; + } + if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { + window->y = bounds.y + (bounds.h - h) / 2; + } + } + window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); + window->brightness = 1.0f; + window->next = _this->windows; + + if (_this->windows) { + _this->windows->prev = window; + } + _this->windows = window; + + if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) { + SDL_DestroyWindow(window); + return NULL; + } + + if (title) { + SDL_SetWindowTitle(window, title); + } + SDL_FinishWindowCreation(window, flags); + + /* If the window was created fullscreen, make sure the mode code matches */ + SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)); + + return window; +} + +SDL_Window * +SDL_CreateWindowFrom(const void *data) +{ + SDL_Window *window; + + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); + if (!window) { + SDL_OutOfMemory(); + return NULL; + } + window->magic = &_this->window_magic; + window->id = _this->next_object_id++; + window->flags = SDL_WINDOW_FOREIGN; + window->brightness = 1.0f; + window->next = _this->windows; + if (_this->windows) { + _this->windows->prev = window; + } + _this->windows = window; + + if (!_this->CreateWindowFrom || + _this->CreateWindowFrom(_this, window, data) < 0) { + SDL_DestroyWindow(window); + return NULL; + } + return window; +} + +int +SDL_RecreateWindow(SDL_Window * window, Uint32 flags) +{ + char *title = window->title; + SDL_Surface *icon = window->icon; + + if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { + return SDL_SetError("No OpenGL support in video driver"); + } + + if (window->flags & SDL_WINDOW_FOREIGN) { + /* Can't destroy and re-create foreign windows, hrm */ + flags |= SDL_WINDOW_FOREIGN; + } else { + flags &= ~SDL_WINDOW_FOREIGN; + } + + /* Restore video mode, etc. */ + SDL_HideWindow(window); + + /* Tear down the old native window */ + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + } + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } + if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { + _this->DestroyWindow(_this, window); + } + + if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) { + if (flags & SDL_WINDOW_OPENGL) { + if (SDL_GL_LoadLibrary(NULL) < 0) { + return -1; + } + } else { + SDL_GL_UnloadLibrary(); + } + } + + window->title = NULL; + window->icon = NULL; + window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); + + if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) { + if (_this->CreateWindow(_this, window) < 0) { + if (flags & SDL_WINDOW_OPENGL) { + SDL_GL_UnloadLibrary(); + } + return -1; + } + } + + if (title) { + SDL_SetWindowTitle(window, title); + SDL_free(title); + } + if (icon) { + SDL_SetWindowIcon(window, icon); + SDL_FreeSurface(icon); + } + SDL_FinishWindowCreation(window, flags); + + return 0; +} + +Uint32 +SDL_GetWindowID(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, 0); + + return window->id; +} + +SDL_Window * +SDL_GetWindowFromID(Uint32 id) +{ + SDL_Window *window; + + if (!_this) { + return NULL; + } + for (window = _this->windows; window; window = window->next) { + if (window->id == id) { + return window; + } + } + return NULL; +} + +Uint32 +SDL_GetWindowFlags(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, 0); + + return window->flags; +} + +void +SDL_SetWindowTitle(SDL_Window * window, const char *title) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (title == window->title) { + return; + } + SDL_free(window->title); + if (title && *title) { + window->title = SDL_strdup(title); + } else { + window->title = NULL; + } + + if (_this->SetWindowTitle) { + _this->SetWindowTitle(_this, window); + } +} + +const char * +SDL_GetWindowTitle(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ""); + + return window->title ? window->title : ""; +} + +void +SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!icon) { + return; + } + + SDL_FreeSurface(window->icon); + + /* Convert the icon into ARGB8888 */ + window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0); + if (!window->icon) { + return; + } + + if (_this->SetWindowIcon) { + _this->SetWindowIcon(_this, window, window->icon); + } +} + +void* +SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) +{ + SDL_WindowUserData *prev, *data; + + CHECK_WINDOW_MAGIC(window, NULL); + + /* Input validation */ + if (name == NULL || name[0] == '\0') { + SDL_InvalidParamError("name"); + return NULL; + } + + /* See if the named data already exists */ + prev = NULL; + for (data = window->data; data; prev = data, data = data->next) { + if (data->name && SDL_strcmp(data->name, name) == 0) { + void *last_value = data->data; + + if (userdata) { + /* Set the new value */ + data->data = userdata; + } else { + /* Delete this value */ + if (prev) { + prev->next = data->next; + } else { + window->data = data->next; + } + SDL_free(data->name); + SDL_free(data); + } + return last_value; + } + } + + /* Add new data to the window */ + if (userdata) { + data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data)); + data->name = SDL_strdup(name); + data->data = userdata; + data->next = window->data; + window->data = data; + } + return NULL; +} + +void * +SDL_GetWindowData(SDL_Window * window, const char *name) +{ + SDL_WindowUserData *data; + + CHECK_WINDOW_MAGIC(window, NULL); + + /* Input validation */ + if (name == NULL || name[0] == '\0') { + SDL_InvalidParamError("name"); + return NULL; + } + + for (data = window->data; data; data = data->next) { + if (data->name && SDL_strcmp(data->name, name) == 0) { + return data->data; + } + } + return NULL; +} + +void +SDL_SetWindowPosition(SDL_Window * window, int x, int y) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + int displayIndex; + SDL_Rect bounds; + + displayIndex = SDL_GetIndexOfDisplay(display); + SDL_GetDisplayBounds(displayIndex, &bounds); + if (SDL_WINDOWPOS_ISCENTERED(x)) { + x = bounds.x + (bounds.w - window->w) / 2; + } + if (SDL_WINDOWPOS_ISCENTERED(y)) { + y = bounds.y + (bounds.h - window->h) / 2; + } + } + + if ((window->flags & SDL_WINDOW_FULLSCREEN)) { + if (!SDL_WINDOWPOS_ISUNDEFINED(x)) { + window->windowed.x = x; + } + if (!SDL_WINDOWPOS_ISUNDEFINED(y)) { + window->windowed.y = y; + } + } else { + if (!SDL_WINDOWPOS_ISUNDEFINED(x)) { + window->x = x; + } + if (!SDL_WINDOWPOS_ISUNDEFINED(y)) { + window->y = y; + } + + if (_this->SetWindowPosition) { + _this->SetWindowPosition(_this, window); + } + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + } +} + +void +SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) +{ + CHECK_WINDOW_MAGIC(window, ); + + /* Fullscreen windows are always at their display's origin */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + if (x) { + *x = 0; + } + if (y) { + *y = 0; + } + } else { + if (x) { + *x = window->x; + } + if (y) { + *y = window->y; + } + } +} + +void +SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) +{ + CHECK_WINDOW_MAGIC(window, ); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (bordered != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0); + if ((want != have) && (_this->SetWindowBordered)) { + if (want) { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } else { + window->flags |= SDL_WINDOW_BORDERLESS; + } + _this->SetWindowBordered(_this, window, (SDL_bool) want); + } + } +} + +void +SDL_SetWindowSize(SDL_Window * window, int w, int h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (w <= 0) { + SDL_InvalidParamError("w"); + return; + } + if (h <= 0) { + SDL_InvalidParamError("h"); + return; + } + + /* Make sure we don't exceed any window size limits */ + if (window->min_w && w < window->min_w) + { + w = window->min_w; + } + if (window->max_w && w > window->max_w) + { + w = window->max_w; + } + if (window->min_h && h < window->min_h) + { + h = window->min_h; + } + if (window->max_h && h > window->max_h) + { + h = window->max_h; + } + + /* FIXME: Should this change fullscreen modes? */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + window->windowed.w = w; + window->windowed.h = h; + } else { + window->w = w; + window->h = h; + if (_this->SetWindowSize) { + _this->SetWindowSize(_this, window); + } + if (window->w == w && window->h == h) { + /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */ + SDL_OnWindowResized(window); + } + } +} + +void +SDL_GetWindowSize(SDL_Window * window, int *w, int *h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (w) { + *w = window->w; + } + if (h) { + *h = window->h; + } +} + +void +SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (min_w <= 0) { + SDL_InvalidParamError("min_w"); + return; + } + if (min_h <= 0) { + SDL_InvalidParamError("min_h"); + return; + } + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + window->min_w = min_w; + window->min_h = min_h; + if (_this->SetWindowMinimumSize) { + _this->SetWindowMinimumSize(_this, window); + } + /* Ensure that window is not smaller than minimal size */ + SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h)); + } +} + +void +SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (min_w) { + *min_w = window->min_w; + } + if (min_h) { + *min_h = window->min_h; + } +} + +void +SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (max_w <= 0) { + SDL_InvalidParamError("max_w"); + return; + } + if (max_h <= 0) { + SDL_InvalidParamError("max_h"); + return; + } + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + window->max_w = max_w; + window->max_h = max_h; + if (_this->SetWindowMaximumSize) { + _this->SetWindowMaximumSize(_this, window); + } + /* Ensure that window is not larger than maximal size */ + SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h)); + } +} + +void +SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h) +{ + CHECK_WINDOW_MAGIC(window, ); + if (max_w) { + *max_w = window->max_w; + } + if (max_h) { + *max_h = window->max_h; + } +} + +void +SDL_ShowWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (window->flags & SDL_WINDOW_SHOWN) { + return; + } + + if (_this->ShowWindow) { + _this->ShowWindow(_this, window); + } + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); +} + +void +SDL_HideWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & SDL_WINDOW_SHOWN)) { + return; + } + + SDL_UpdateFullscreenMode(window, SDL_FALSE); + + if (_this->HideWindow) { + _this->HideWindow(_this, window); + } + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); +} + +void +SDL_RaiseWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & SDL_WINDOW_SHOWN)) { + return; + } + if (_this->RaiseWindow) { + _this->RaiseWindow(_this, window); + } +} + +void +SDL_MaximizeWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (window->flags & SDL_WINDOW_MAXIMIZED) { + return; + } + + /* !!! FIXME: should this check if the window is resizable? */ + + if (_this->MaximizeWindow) { + _this->MaximizeWindow(_this, window); + } +} + +void +SDL_MinimizeWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (window->flags & SDL_WINDOW_MINIMIZED) { + return; + } + + SDL_UpdateFullscreenMode(window, SDL_FALSE); + + if (_this->MinimizeWindow) { + _this->MinimizeWindow(_this, window); + } +} + +void +SDL_RestoreWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) { + return; + } + + if (_this->RestoreWindow) { + _this->RestoreWindow(_this, window); + } +} + +#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ) +int +SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) +{ + CHECK_WINDOW_MAGIC(window, -1); + + flags &= FULLSCREEN_MASK; + + if ( flags == (window->flags & FULLSCREEN_MASK) ) { + return 0; + } + + /* clear the previous flags and OR in the new ones */ + window->flags &= ~FULLSCREEN_MASK; + window->flags |= flags; + + SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)); + + return 0; +} + +static SDL_Surface * +SDL_CreateWindowFramebuffer(SDL_Window * window) +{ + Uint32 format; + void *pixels; + int pitch; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { + return NULL; + } + + if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { + return NULL; + } + + if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + return NULL; + } + + return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask); +} + +SDL_Surface * +SDL_GetWindowSurface(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, NULL); + + if (!window->surface_valid) { + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + } + window->surface = SDL_CreateWindowFramebuffer(window); + if (window->surface) { + window->surface_valid = SDL_TRUE; + window->surface->flags |= SDL_DONTFREE; + } + } + return window->surface; +} + +int +SDL_UpdateWindowSurface(SDL_Window * window) +{ + SDL_Rect full_rect; + + CHECK_WINDOW_MAGIC(window, -1); + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = window->w; + full_rect.h = window->h; + return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1); +} + +int +SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, + int numrects) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (!window->surface_valid) { + return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface"); + } + + return _this->UpdateWindowFramebuffer(_this, window, rects, numrects); +} + +int +SDL_SetWindowBrightness(SDL_Window * window, float brightness) +{ + Uint16 ramp[256]; + int status; + + CHECK_WINDOW_MAGIC(window, -1); + + SDL_CalculateGammaRamp(brightness, ramp); + status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp); + if (status == 0) { + window->brightness = brightness; + } + return status; +} + +float +SDL_GetWindowBrightness(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, 1.0f); + + return window->brightness; +} + +int +SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, + const Uint16 * green, + const Uint16 * blue) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (!_this->SetWindowGammaRamp) { + return SDL_Unsupported(); + } + + if (!window->gamma) { + if (SDL_GetWindowGammaRamp(window, NULL, NULL, NULL) < 0) { + return -1; + } + } + + if (red) { + SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16)); + } + if (green) { + SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16)); + } + if (blue) { + SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16)); + } + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + return _this->SetWindowGammaRamp(_this, window, window->gamma); + } else { + return 0; + } +} + +int +SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, + Uint16 * green, + Uint16 * blue) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (!window->gamma) { + int i; + + window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16)); + if (!window->gamma) { + return SDL_OutOfMemory(); + } + window->saved_gamma = window->gamma + 3*256; + + if (_this->GetWindowGammaRamp) { + if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) { + return -1; + } + } else { + /* Create an identity gamma ramp */ + for (i = 0; i < 256; ++i) { + Uint16 value = (Uint16)((i << 8) | i); + + window->gamma[0*256+i] = value; + window->gamma[1*256+i] = value; + window->gamma[2*256+i] = value; + } + } + SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16)); + } + + if (red) { + SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16)); + } + if (green) { + SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16)); + } + if (blue) { + SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16)); + } + return 0; +} + +void +SDL_UpdateWindowGrab(SDL_Window * window) +{ + if (_this->SetWindowGrab) { + SDL_bool grabbed; + if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + grabbed = SDL_TRUE; + } else { + grabbed = SDL_FALSE; + } + _this->SetWindowGrab(_this, window, grabbed); + } +} + +void +SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) { + return; + } + if (grabbed) { + window->flags |= SDL_WINDOW_INPUT_GRABBED; + } else { + window->flags &= ~SDL_WINDOW_INPUT_GRABBED; + } + SDL_UpdateWindowGrab(window); +} + +SDL_bool +SDL_GetWindowGrab(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, SDL_FALSE); + + return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0); +} + +void +SDL_OnWindowShown(SDL_Window * window) +{ + SDL_OnWindowRestored(window); +} + +void +SDL_OnWindowHidden(SDL_Window * window) +{ + SDL_UpdateFullscreenMode(window, SDL_FALSE); +} + +void +SDL_OnWindowResized(SDL_Window * window) +{ + window->surface_valid = SDL_FALSE; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); +} + +void +SDL_OnWindowMinimized(SDL_Window * window) +{ + SDL_UpdateFullscreenMode(window, SDL_FALSE); +} + +void +SDL_OnWindowRestored(SDL_Window * window) +{ + SDL_RaiseWindow(window); + + if (FULLSCREEN_VISIBLE(window)) { + SDL_UpdateFullscreenMode(window, SDL_TRUE); + } +} + +void +SDL_OnWindowEnter(SDL_Window * window) +{ + if (_this->OnWindowEnter) { + _this->OnWindowEnter(_this, window); + } +} + +void +SDL_OnWindowLeave(SDL_Window * window) +{ +} + +void +SDL_OnWindowFocusGained(SDL_Window * window) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (window->gamma && _this->SetWindowGammaRamp) { + _this->SetWindowGammaRamp(_this, window, window->gamma); + } + + if (mouse && mouse->relative_mode) { + SDL_SetMouseFocus(window); + SDL_WarpMouseInWindow(window, window->w/2, window->h/2); + } + + SDL_UpdateWindowGrab(window); +} + +static SDL_bool +ShouldMinimizeOnFocusLoss(SDL_Window * window) +{ + const char *hint; + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + return SDL_FALSE; + } + +#ifdef __MACOSX__ + if (Cocoa_IsWindowInFullscreenSpace(window)) { + return SDL_FALSE; + } +#endif + + hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); + if (hint) { + if (*hint == '0') { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } + + return SDL_TRUE; +} + +void +SDL_OnWindowFocusLost(SDL_Window * window) +{ + if (window->gamma && _this->SetWindowGammaRamp) { + _this->SetWindowGammaRamp(_this, window, window->saved_gamma); + } + + SDL_UpdateWindowGrab(window); + + if (ShouldMinimizeOnFocusLoss(window)) { + SDL_MinimizeWindow(window); + } +} + +SDL_Window * +SDL_GetFocusWindow(void) +{ + SDL_Window *window; + + if (!_this) { + return NULL; + } + for (window = _this->windows; window; window = window->next) { + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + return window; + } + } + return NULL; +} + +void +SDL_DestroyWindow(SDL_Window * window) +{ + SDL_VideoDisplay *display; + + CHECK_WINDOW_MAGIC(window, ); + + /* Restore video mode, etc. */ + SDL_HideWindow(window); + + /* Make sure this window no longer has focus */ + if (SDL_GetKeyboardFocus() == window) { + SDL_SetKeyboardFocus(NULL); + } + if (SDL_GetMouseFocus() == window) { + SDL_SetMouseFocus(NULL); + } + + /* make no context current if this is the current context window. */ + if (window->flags & SDL_WINDOW_OPENGL) { + if (_this->current_glwin == window) { + SDL_GL_MakeCurrent(window, NULL); + } + } + + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + } + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } + if (_this->DestroyWindow) { + _this->DestroyWindow(_this, window); + } + if (window->flags & SDL_WINDOW_OPENGL) { + SDL_GL_UnloadLibrary(); + } + + display = SDL_GetDisplayForWindow(window); + if (display->fullscreen_window == window) { + display->fullscreen_window = NULL; + } + + /* Now invalidate magic */ + window->magic = NULL; + + /* Free memory associated with the window */ + SDL_free(window->title); + SDL_FreeSurface(window->icon); + SDL_free(window->gamma); + while (window->data) { + SDL_WindowUserData *data = window->data; + + window->data = data->next; + SDL_free(data->name); + SDL_free(data); + } + + /* Unlink the window from the list */ + if (window->next) { + window->next->prev = window->prev; + } + if (window->prev) { + window->prev->next = window->next; + } else { + _this->windows = window->next; + } + + SDL_free(window); +} + +SDL_bool +SDL_IsScreenSaverEnabled() +{ + if (!_this) { + return SDL_TRUE; + } + return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE; +} + +void +SDL_EnableScreenSaver() +{ + if (!_this) { + return; + } + if (!_this->suspend_screensaver) { + return; + } + _this->suspend_screensaver = SDL_FALSE; + if (_this->SuspendScreenSaver) { + _this->SuspendScreenSaver(_this); + } +} + +void +SDL_DisableScreenSaver() +{ + if (!_this) { + return; + } + if (_this->suspend_screensaver) { + return; + } + _this->suspend_screensaver = SDL_TRUE; + if (_this->SuspendScreenSaver) { + _this->SuspendScreenSaver(_this); + } +} + +void +SDL_VideoQuit(void) +{ + int i, j; + + if (!_this) { + return; + } + + /* Halt event processing before doing anything else */ + SDL_TouchQuit(); + SDL_MouseQuit(); + SDL_KeyboardQuit(); + SDL_QuitSubSystem(SDL_INIT_EVENTS); + + SDL_EnableScreenSaver(); + + /* Clean up the system video */ + while (_this->windows) { + SDL_DestroyWindow(_this->windows); + } + _this->VideoQuit(_this); + + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + for (j = display->num_display_modes; j--;) { + SDL_free(display->display_modes[j].driverdata); + display->display_modes[j].driverdata = NULL; + } + SDL_free(display->display_modes); + display->display_modes = NULL; + SDL_free(display->desktop_mode.driverdata); + display->desktop_mode.driverdata = NULL; + SDL_free(display->driverdata); + display->driverdata = NULL; + } + if (_this->displays) { + for (i = 0; i < _this->num_displays; ++i) { + SDL_free(_this->displays[i].name); + } + SDL_free(_this->displays); + _this->displays = NULL; + _this->num_displays = 0; + } + SDL_free(_this->clipboard_text); + _this->clipboard_text = NULL; + _this->free(_this); + _this = NULL; +} + +int +SDL_GL_LoadLibrary(const char *path) +{ + int retval; + + if (!_this) { + return SDL_UninitializedVideo(); + } + if (_this->gl_config.driver_loaded) { + if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) { + return SDL_SetError("OpenGL library already loaded"); + } + retval = 0; + } else { + if (!_this->GL_LoadLibrary) { + return SDL_SetError("No dynamic GL support in video driver"); + } + retval = _this->GL_LoadLibrary(_this, path); + } + if (retval == 0) { + ++_this->gl_config.driver_loaded; + } else { + if (_this->GL_UnloadLibrary) { + _this->GL_UnloadLibrary(_this); + } + } + return (retval); +} + +void * +SDL_GL_GetProcAddress(const char *proc) +{ + void *func; + + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + func = NULL; + if (_this->GL_GetProcAddress) { + if (_this->gl_config.driver_loaded) { + func = _this->GL_GetProcAddress(_this, proc); + } else { + SDL_SetError("No GL driver has been loaded"); + } + } else { + SDL_SetError("No dynamic GL support in video driver"); + } + return func; +} + +void +SDL_GL_UnloadLibrary(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return; + } + if (_this->gl_config.driver_loaded > 0) { + if (--_this->gl_config.driver_loaded > 0) { + return; + } + if (_this->GL_UnloadLibrary) { + _this->GL_UnloadLibrary(_this); + } + } +} + +static SDL_INLINE SDL_bool +isAtLeastGL3(const char *verstr) +{ + return ( verstr && (SDL_atoi(verstr) >= 3) ); +} + +SDL_bool +SDL_GL_ExtensionSupported(const char *extension) +{ +#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); + const char *extensions; + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = SDL_strchr(extension, ' '); + if (where || *extension == '\0') { + return SDL_FALSE; + } + /* See if there's an environment variable override */ + start = SDL_getenv(extension); + if (start && *start == '0') { + return SDL_FALSE; + } + + /* Lookup the available extensions */ + + glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); + if (!glGetStringFunc) { + return SDL_FALSE; + } + + if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) { + const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint); + void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); + GLint num_exts = 0; + GLint i; + + glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi"); + glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); + if ((!glGetStringiFunc) || (!glGetIntegervFunc)) { + return SDL_FALSE; + } + + #ifndef GL_NUM_EXTENSIONS + #define GL_NUM_EXTENSIONS 0x821D + #endif + glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts); + for (i = 0; i < num_exts; i++) { + const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i); + if (SDL_strcmp(thisext, extension) == 0) { + return SDL_TRUE; + } + } + + return SDL_FALSE; + } + + /* Try the old way with glGetString(GL_EXTENSIONS) ... */ + + extensions = (const char *) glGetStringFunc(GL_EXTENSIONS); + if (!extensions) { + return SDL_FALSE; + } + /* + * It takes a bit of care to be fool-proof about parsing the OpenGL + * extensions string. Don't be fooled by sub-strings, etc. + */ + + start = extensions; + + for (;;) { + where = SDL_strstr(start, extension); + if (!where) + break; + + terminator = where + SDL_strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return SDL_TRUE; + + start = terminator; + } + return SDL_FALSE; +#else + return SDL_FALSE; +#endif +} + +int +SDL_GL_SetAttribute(SDL_GLattr attr, int value) +{ +#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + int retval; + + if (!_this) { + return SDL_UninitializedVideo(); + } + retval = 0; + switch (attr) { + case SDL_GL_RED_SIZE: + _this->gl_config.red_size = value; + break; + case SDL_GL_GREEN_SIZE: + _this->gl_config.green_size = value; + break; + case SDL_GL_BLUE_SIZE: + _this->gl_config.blue_size = value; + break; + case SDL_GL_ALPHA_SIZE: + _this->gl_config.alpha_size = value; + break; + case SDL_GL_DOUBLEBUFFER: + _this->gl_config.double_buffer = value; + break; + case SDL_GL_BUFFER_SIZE: + _this->gl_config.buffer_size = value; + break; + case SDL_GL_DEPTH_SIZE: + _this->gl_config.depth_size = value; + break; + case SDL_GL_STENCIL_SIZE: + _this->gl_config.stencil_size = value; + break; + case SDL_GL_ACCUM_RED_SIZE: + _this->gl_config.accum_red_size = value; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + _this->gl_config.accum_green_size = value; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + _this->gl_config.accum_blue_size = value; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + _this->gl_config.accum_alpha_size = value; + break; + case SDL_GL_STEREO: + _this->gl_config.stereo = value; + break; + case SDL_GL_MULTISAMPLEBUFFERS: + _this->gl_config.multisamplebuffers = value; + break; + case SDL_GL_MULTISAMPLESAMPLES: + _this->gl_config.multisamplesamples = value; + break; + case SDL_GL_ACCELERATED_VISUAL: + _this->gl_config.accelerated = value; + break; + case SDL_GL_RETAINED_BACKING: + _this->gl_config.retained_backing = value; + break; + case SDL_GL_CONTEXT_MAJOR_VERSION: + _this->gl_config.major_version = value; + break; + case SDL_GL_CONTEXT_MINOR_VERSION: + _this->gl_config.minor_version = value; + break; + case SDL_GL_CONTEXT_EGL: + /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */ + if (value != 0) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + } else { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); + }; + break; + case SDL_GL_CONTEXT_FLAGS: + if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG | + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG | + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG | + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) { + retval = SDL_SetError("Unknown OpenGL context flag %d", value); + break; + } + _this->gl_config.flags = value; + break; + case SDL_GL_CONTEXT_PROFILE_MASK: + if( value != 0 && + value != SDL_GL_CONTEXT_PROFILE_CORE && + value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY && + value != SDL_GL_CONTEXT_PROFILE_ES ) { + retval = SDL_SetError("Unknown OpenGL context profile %d", value); + break; + } + _this->gl_config.profile_mask = value; + break; + case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: + _this->gl_config.share_with_current_context = value; + break; + case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: + _this->gl_config.framebuffer_srgb_capable = value; + break; + default: + retval = SDL_SetError("Unknown OpenGL attribute"); + break; + } + return retval; +#else + return SDL_Unsupported(); +#endif /* SDL_VIDEO_OPENGL */ +} + +int +SDL_GL_GetAttribute(SDL_GLattr attr, int *value) +{ +#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); + GLenum(APIENTRY * glGetErrorFunc) (void); + GLenum attrib = 0; + GLenum error = 0; + + glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); + if (!glGetIntegervFunc) { + return -1; + } + + glGetErrorFunc = SDL_GL_GetProcAddress("glGetError"); + if (!glGetErrorFunc) { + return -1; + } + + /* Clear value in any case */ + *value = 0; + + switch (attr) { + case SDL_GL_RED_SIZE: + attrib = GL_RED_BITS; + break; + case SDL_GL_BLUE_SIZE: + attrib = GL_BLUE_BITS; + break; + case SDL_GL_GREEN_SIZE: + attrib = GL_GREEN_BITS; + break; + case SDL_GL_ALPHA_SIZE: + attrib = GL_ALPHA_BITS; + break; + case SDL_GL_DOUBLEBUFFER: +#if SDL_VIDEO_OPENGL + attrib = GL_DOUBLEBUFFER; + break; +#else + /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER */ + /* parameter which switches double buffer to single buffer. OpenGL ES */ + /* SDL driver must set proper value after initialization */ + *value = _this->gl_config.double_buffer; + return 0; +#endif + case SDL_GL_DEPTH_SIZE: + attrib = GL_DEPTH_BITS; + break; + case SDL_GL_STENCIL_SIZE: + attrib = GL_STENCIL_BITS; + break; +#if SDL_VIDEO_OPENGL + case SDL_GL_ACCUM_RED_SIZE: + attrib = GL_ACCUM_RED_BITS; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + attrib = GL_ACCUM_GREEN_BITS; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + attrib = GL_ACCUM_BLUE_BITS; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + attrib = GL_ACCUM_ALPHA_BITS; + break; + case SDL_GL_STEREO: + attrib = GL_STEREO; + break; +#else + case SDL_GL_ACCUM_RED_SIZE: + case SDL_GL_ACCUM_GREEN_SIZE: + case SDL_GL_ACCUM_BLUE_SIZE: + case SDL_GL_ACCUM_ALPHA_SIZE: + case SDL_GL_STEREO: + /* none of these are supported in OpenGL ES */ + *value = 0; + return 0; +#endif + case SDL_GL_MULTISAMPLEBUFFERS: +#if SDL_VIDEO_OPENGL + attrib = GL_SAMPLE_BUFFERS_ARB; +#else + attrib = GL_SAMPLE_BUFFERS; +#endif + break; + case SDL_GL_MULTISAMPLESAMPLES: +#if SDL_VIDEO_OPENGL + attrib = GL_SAMPLES_ARB; +#else + attrib = GL_SAMPLES; +#endif + break; + case SDL_GL_BUFFER_SIZE: + { + GLint bits = 0; + GLint component; + + /* + * there doesn't seem to be a single flag in OpenGL + * for this! + */ + glGetIntegervFunc(GL_RED_BITS, &component); + bits += component; + glGetIntegervFunc(GL_GREEN_BITS, &component); + bits += component; + glGetIntegervFunc(GL_BLUE_BITS, &component); + bits += component; + glGetIntegervFunc(GL_ALPHA_BITS, &component); + bits += component; + + *value = bits; + return 0; + } + case SDL_GL_ACCELERATED_VISUAL: + { + /* FIXME: How do we get this information? */ + *value = (_this->gl_config.accelerated != 0); + return 0; + } + case SDL_GL_RETAINED_BACKING: + { + *value = _this->gl_config.retained_backing; + return 0; + } + case SDL_GL_CONTEXT_MAJOR_VERSION: + { + *value = _this->gl_config.major_version; + return 0; + } + case SDL_GL_CONTEXT_MINOR_VERSION: + { + *value = _this->gl_config.minor_version; + return 0; + } + case SDL_GL_CONTEXT_EGL: + /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */ + { + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { + *value = 1; + } + else { + *value = 0; + } + return 0; + } + case SDL_GL_CONTEXT_FLAGS: + { + *value = _this->gl_config.flags; + return 0; + } + case SDL_GL_CONTEXT_PROFILE_MASK: + { + *value = _this->gl_config.profile_mask; + return 0; + } + case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: + { + *value = _this->gl_config.share_with_current_context; + return 0; + } + case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: + { + *value = _this->gl_config.framebuffer_srgb_capable; + return 0; + } + default: + return SDL_SetError("Unknown OpenGL attribute"); + } + + glGetIntegervFunc(attrib, (GLint *) value); + error = glGetErrorFunc(); + if (error != GL_NO_ERROR) { + if (error == GL_INVALID_ENUM) { + return SDL_SetError("OpenGL error: GL_INVALID_ENUM"); + } else if (error == GL_INVALID_VALUE) { + return SDL_SetError("OpenGL error: GL_INVALID_VALUE"); + } + return SDL_SetError("OpenGL error: %08X", error); + } + return 0; +#else + return SDL_Unsupported(); +#endif /* SDL_VIDEO_OPENGL */ +} + +SDL_GLContext +SDL_GL_CreateContext(SDL_Window * window) +{ + SDL_GLContext ctx = NULL; + CHECK_WINDOW_MAGIC(window, NULL); + + if (!(window->flags & SDL_WINDOW_OPENGL)) { + SDL_SetError("The specified window isn't an OpenGL window"); + return NULL; + } + + ctx = _this->GL_CreateContext(_this, window); + + /* Creating a context is assumed to make it current in the SDL driver. */ + if (ctx) { + _this->current_glwin = window; + _this->current_glctx = ctx; + SDL_TLSSet(_this->current_glwin_tls, window, NULL); + SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); + } + return ctx; +} + +int +SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) +{ + int retval; + + if (window == SDL_GL_GetCurrentWindow() && + ctx == SDL_GL_GetCurrentContext()) { + /* We're already current. */ + return 0; + } + + if (!ctx) { + window = NULL; + } else { + CHECK_WINDOW_MAGIC(window, -1); + + if (!(window->flags & SDL_WINDOW_OPENGL)) { + return SDL_SetError("The specified window isn't an OpenGL window"); + } + } + + retval = _this->GL_MakeCurrent(_this, window, ctx); + if (retval == 0) { + _this->current_glwin = window; + _this->current_glctx = ctx; + SDL_TLSSet(_this->current_glwin_tls, window, NULL); + SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); + } + return retval; +} + +SDL_Window * +SDL_GL_GetCurrentWindow(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls); +} + +SDL_GLContext +SDL_GL_GetCurrentContext(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls); +} + +void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (_this->GL_GetDrawableSize) { + _this->GL_GetDrawableSize(_this, window, w, h); + } else { + SDL_GetWindowSize(window, w, h); + } +} + +int +SDL_GL_SetSwapInterval(int interval) +{ + if (!_this) { + return SDL_UninitializedVideo(); + } else if (SDL_GL_GetCurrentContext() == NULL) { + return SDL_SetError("No OpenGL context has been made current"); + } else if (_this->GL_SetSwapInterval) { + return _this->GL_SetSwapInterval(_this, interval); + } else { + return SDL_SetError("Setting the swap interval is not supported"); + } +} + +int +SDL_GL_GetSwapInterval(void) +{ + if (!_this) { + return 0; + } else if (SDL_GL_GetCurrentContext() == NULL) { + return 0; + } else if (_this->GL_GetSwapInterval) { + return _this->GL_GetSwapInterval(_this); + } else { + return 0; + } +} + +void +SDL_GL_SwapWindow(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!(window->flags & SDL_WINDOW_OPENGL)) { + SDL_SetError("The specified window isn't an OpenGL window"); + return; + } + + if (SDL_GL_GetCurrentWindow() != window) { + SDL_SetError("The specified window has not been made current"); + return; + } + + _this->GL_SwapWindow(_this, window); +} + +void +SDL_GL_DeleteContext(SDL_GLContext context) +{ + if (!_this || !context) { + return; + } + + if (SDL_GL_GetCurrentContext() == context) { + SDL_GL_MakeCurrent(NULL, NULL); + } + + _this->GL_DeleteContext(_this, context); +} + +#if 0 /* FIXME */ +/* + * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags + * & 2 for alpha channel. + */ +static void +CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) +{ + int x, y; + Uint32 colorkey; +#define SET_MASKBIT(icon, x, y, mask) \ + mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) + + colorkey = icon->format->colorkey; + switch (icon->format->BytesPerPixel) { + case 1: + { + Uint8 *pixels; + for (y = 0; y < icon->h; ++y) { + pixels = (Uint8 *) icon->pixels + y * icon->pitch; + for (x = 0; x < icon->w; ++x) { + if (*pixels++ == colorkey) { + SET_MASKBIT(icon, x, y, mask); + } + } + } + } + break; + + case 2: + { + Uint16 *pixels; + for (y = 0; y < icon->h; ++y) { + pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2; + for (x = 0; x < icon->w; ++x) { + if ((flags & 1) && *pixels == colorkey) { + SET_MASKBIT(icon, x, y, mask); + } else if ((flags & 2) + && (*pixels & icon->format->Amask) == 0) { + SET_MASKBIT(icon, x, y, mask); + } + pixels++; + } + } + } + break; + + case 4: + { + Uint32 *pixels; + for (y = 0; y < icon->h; ++y) { + pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4; + for (x = 0; x < icon->w; ++x) { + if ((flags & 1) && *pixels == colorkey) { + SET_MASKBIT(icon, x, y, mask); + } else if ((flags & 2) + && (*pixels & icon->format->Amask) == 0) { + SET_MASKBIT(icon, x, y, mask); + } + pixels++; + } + } + } + break; + } +} + +/* + * Sets the window manager icon for the display window. + */ +void +SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) +{ + if (icon && _this->SetIcon) { + /* Generate a mask if necessary, and create the icon! */ + if (mask == NULL) { + int mask_len = icon->h * (icon->w + 7) / 8; + int flags = 0; + mask = (Uint8 *) SDL_malloc(mask_len); + if (mask == NULL) { + return; + } + SDL_memset(mask, ~0, mask_len); + if (icon->flags & SDL_SRCCOLORKEY) + flags |= 1; + if (icon->flags & SDL_SRCALPHA) + flags |= 2; + if (flags) { + CreateMaskFromColorKeyOrAlpha(icon, mask, flags); + } + _this->SetIcon(_this, icon, mask); + SDL_free(mask); + } else { + _this->SetIcon(_this, icon, mask); + } + } +} +#endif + +SDL_bool +SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) +{ + CHECK_WINDOW_MAGIC(window, SDL_FALSE); + + if (!info) { + return SDL_FALSE; + } + info->subsystem = SDL_SYSWM_UNKNOWN; + + if (!_this->GetWindowWMInfo) { + return SDL_FALSE; + } + return (_this->GetWindowWMInfo(_this, window, info)); +} + +void +SDL_StartTextInput(void) +{ + SDL_Window *window; + + /* First, enable text events */ + SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); + SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); + + /* Then show the on-screen keyboard, if any */ + window = SDL_GetFocusWindow(); + if (window && _this && _this->ShowScreenKeyboard) { + _this->ShowScreenKeyboard(_this, window); + } + + /* Finally start the text input system */ + if (_this && _this->StartTextInput) { + _this->StartTextInput(_this); + } +} + +SDL_bool +SDL_IsTextInputActive(void) +{ + return (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE); +} + +void +SDL_StopTextInput(void) +{ + SDL_Window *window; + + /* Stop the text input system */ + if (_this && _this->StopTextInput) { + _this->StopTextInput(_this); + } + + /* Hide the on-screen keyboard, if any */ + window = SDL_GetFocusWindow(); + if (window && _this && _this->HideScreenKeyboard) { + _this->HideScreenKeyboard(_this, window); + } + + /* Finally disable text events */ + SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); + SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); +} + +void +SDL_SetTextInputRect(SDL_Rect *rect) +{ + if (_this && _this->SetTextInputRect) { + _this->SetTextInputRect(_this, rect); + } +} + +SDL_bool +SDL_HasScreenKeyboardSupport(void) +{ + if (_this && _this->HasScreenKeyboardSupport) { + return _this->HasScreenKeyboardSupport(_this); + } + return SDL_FALSE; +} + +SDL_bool +SDL_IsScreenKeyboardShown(SDL_Window *window) +{ + if (window && _this && _this->IsScreenKeyboardShown) { + return _this->IsScreenKeyboardShown(_this, window); + } + return SDL_FALSE; +} + +#if SDL_VIDEO_DRIVER_WINDOWS +#include "windows/SDL_windowsmessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_COCOA +#include "cocoa/SDL_cocoamessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_UIKIT +#include "uikit/SDL_uikitmessagebox.h" +#endif +#if SDL_VIDEO_DRIVER_X11 +#include "x11/SDL_x11messagebox.h" +#endif + +static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) +{ + SDL_SysWMinfo info; + SDL_Window *window = messageboxdata->window; + + if (!window) { + return SDL_TRUE; + } + + SDL_VERSION(&info.version); + if (!SDL_GetWindowWMInfo(window, &info)) { + return SDL_TRUE; + } else { + return (info.subsystem == drivertype); + } +} + +int +SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + int dummybutton; + int retval = -1; + SDL_bool relative_mode; + int show_cursor_prev; + + if (!messageboxdata) { + return SDL_InvalidParamError("messageboxdata"); + } + + relative_mode = SDL_GetRelativeMouseMode(); + SDL_SetRelativeMouseMode(SDL_FALSE); + show_cursor_prev = SDL_ShowCursor(1); + + if (!buttonid) { + buttonid = &dummybutton; + } + + if (_this && _this->ShowMessageBox) { + retval = _this->ShowMessageBox(_this, messageboxdata, buttonid); + } + + /* It's completely fine to call this function before video is initialized */ +#if SDL_VIDEO_DRIVER_WINDOWS + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINDOWS) && + WIN_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif +#if SDL_VIDEO_DRIVER_COCOA + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) && + Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif +#if SDL_VIDEO_DRIVER_UIKIT + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) && + UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif +#if SDL_VIDEO_DRIVER_X11 + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) && + X11_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif + if (retval == -1) { + SDL_SetError("No message system available"); + } + + SDL_ShowCursor(show_cursor_prev); + SDL_SetRelativeMouseMode(relative_mode); + + return retval; +} + +int +SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) +{ + SDL_MessageBoxData data; + SDL_MessageBoxButtonData button; + + SDL_zero(data); + data.flags = flags; + data.title = title; + data.message = message; + data.numbuttons = 1; + data.buttons = &button; + data.window = window; + + SDL_zero(button); + button.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; + button.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + button.text = "OK"; + + return SDL_ShowMessageBox(&data, NULL); +} + +SDL_bool +SDL_ShouldAllowTopmost(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST); + if (hint) { + if (*hint == '0') { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } + return SDL_TRUE; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index 021ad406c..112c3d494 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -22,15 +22,15 @@ #if SDL_VIDEO_DRIVER_WINRT -/* - * Windows includes: - */ -#include -using namespace Windows::UI::Core; -using Windows::UI::Core::CoreCursor; - -/* - * SDL includes: +/* + * Windows includes: + */ +#include +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: */ #include "SDL_winrtevents_c.h" #include "../../core/winrt/SDL_winrtapp_common.h" @@ -63,89 +63,89 @@ WINRT_PumpEvents(_THIS) /* XAML Thread management */ - -enum SDL_XAMLAppThreadState -{ - ThreadState_NotLaunched = 0, - ThreadState_Running, - ThreadState_Yielding + +enum SDL_XAMLAppThreadState +{ + ThreadState_NotLaunched = 0, + ThreadState_Running, + ThreadState_Yielding }; -static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched; -static SDL_Thread * _XAMLThread = nullptr; -static SDL_mutex * _mutex = nullptr; -static SDL_cond * _cond = nullptr; - -static void -WINRT_YieldXAMLThread() -{ - SDL_LockMutex(_mutex); - SDL_assert(_threadState == ThreadState_Running); - _threadState = ThreadState_Yielding; - SDL_UnlockMutex(_mutex); - - SDL_CondSignal(_cond); - - SDL_LockMutex(_mutex); - while (_threadState != ThreadState_Running) { - SDL_CondWait(_cond, _mutex); - } - SDL_UnlockMutex(_mutex); -} - -static int -WINRT_XAMLThreadMain(void * userdata) -{ - // TODO, WinRT: pass the C-style main() a reasonably realistic - // representation of command line arguments. - int argc = 0; - char **argv = NULL; - return WINRT_SDLAppEntryPoint(argc, argv); -} - -void -WINRT_CycleXAMLThread() -{ - switch (_threadState) { - case ThreadState_NotLaunched: - { - _cond = SDL_CreateCond(); - - _mutex = SDL_CreateMutex(); - _threadState = ThreadState_Running; - _XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr); - - SDL_LockMutex(_mutex); - while (_threadState != ThreadState_Yielding) { - SDL_CondWait(_cond, _mutex); - } - SDL_UnlockMutex(_mutex); - - break; - } - - case ThreadState_Running: - { - SDL_assert(false); - break; - } - - case ThreadState_Yielding: - { - SDL_LockMutex(_mutex); - SDL_assert(_threadState == ThreadState_Yielding); - _threadState = ThreadState_Running; - SDL_UnlockMutex(_mutex); - - SDL_CondSignal(_cond); - - SDL_LockMutex(_mutex); - while (_threadState != ThreadState_Yielding) { - SDL_CondWait(_cond, _mutex); - } - SDL_UnlockMutex(_mutex); - } - } +static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched; +static SDL_Thread * _XAMLThread = nullptr; +static SDL_mutex * _mutex = nullptr; +static SDL_cond * _cond = nullptr; + +static void +WINRT_YieldXAMLThread() +{ + SDL_LockMutex(_mutex); + SDL_assert(_threadState == ThreadState_Running); + _threadState = ThreadState_Yielding; + SDL_UnlockMutex(_mutex); + + SDL_CondSignal(_cond); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Running) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); +} + +static int +WINRT_XAMLThreadMain(void * userdata) +{ + // TODO, WinRT: pass the C-style main() a reasonably realistic + // representation of command line arguments. + int argc = 0; + char **argv = NULL; + return WINRT_SDLAppEntryPoint(argc, argv); +} + +void +WINRT_CycleXAMLThread() +{ + switch (_threadState) { + case ThreadState_NotLaunched: + { + _cond = SDL_CreateCond(); + + _mutex = SDL_CreateMutex(); + _threadState = ThreadState_Running; + _XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); + + break; + } + + case ThreadState_Running: + { + SDL_assert(false); + break; + } + + case ThreadState_Yielding: + { + SDL_LockMutex(_mutex); + SDL_assert(_threadState == ThreadState_Yielding); + _threadState = ThreadState_Running; + SDL_UnlockMutex(_mutex); + + SDL_CondSignal(_cond); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); + } + SDL_UnlockMutex(_mutex); + } + } } #endif /* SDL_VIDEO_DRIVER_WINRT */ diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index a6ae7a2c6..ba5105f3f 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -46,9 +46,9 @@ extern void WINRT_PumpEvents(_THIS); #ifdef __cplusplus_winrt /* Pointers (Mice, Touch, etc.) */ -typedef enum { - NormalizeZeroToOne, - TransformToSDLWindowSize +typedef enum { + NormalizeZeroToOne, + TransformToSDLWindowSize } WINRT_CursorNormalizationType; extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, Windows::Foundation::Point rawPosition, diff --git a/src/video/winrt/SDL_winrtkeyboard.cpp b/src/video/winrt/SDL_winrtkeyboard.cpp index a68b6d50c..cb5f57dd7 100644 --- a/src/video/winrt/SDL_winrtkeyboard.cpp +++ b/src/video/winrt/SDL_winrtkeyboard.cpp @@ -1,301 +1,301 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 - -/* Standard C++11 includes */ -#include - - -/* Windows-specific includes */ -#include -#include - - -/* SDL-specific includes */ -#include -#include "SDL_winrtevents_c.h" - -extern "C" { -#include "../../events/scancodes_windows.h" -#include "../../events/SDL_keyboard_c.h" -} - - -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 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 -WINRT_ProcessKeyDownEvent(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 -WINRT_ProcessKeyUpEvent(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); -} - -#endif // SDL_VIDEO_DRIVER_WINRT + +#if SDL_VIDEO_DRIVER_WINRT + +/* Standard C++11 includes */ +#include + + +/* Windows-specific includes */ +#include +#include + + +/* SDL-specific includes */ +#include +#include "SDL_winrtevents_c.h" + +extern "C" { +#include "../../events/scancodes_windows.h" +#include "../../events/SDL_keyboard_c.h" +} + + +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 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 +WINRT_ProcessKeyDownEvent(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 +WINRT_ProcessKeyUpEvent(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); +} + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index c2605e47f..3e896f7f0 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -1,166 +1,166 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2012 Sam Lantinga - - 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 - -/* - * Windows includes: - */ -#include -using namespace Windows::UI::Core; -using Windows::UI::Core::CoreCursor; - -/* - * SDL includes: - */ -extern "C" { -#include "SDL_assert.h" -#include "../../events/SDL_mouse_c.h" -#include "../../events/SDL_touch_c.h" -#include "../SDL_sysvideo.h" -#include "SDL_events.h" -#include "SDL_log.h" -} - -#include "../../core/winrt/SDL_winrtapp_direct3d.h" -#include "SDL_winrtvideo_cpp.h" -#include "SDL_winrtmouse_c.h" - - -extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; - - -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) -{ - // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled. - if ( ! CoreWindow::GetForCurrentThread()) { - return 0; - } - - 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) -{ - WINRT_UsingRelativeMouseMode = enabled; - return 0; -} - -void -WINRT_InitMouse(_THIS) -{ - SDL_Mouse *mouse = SDL_GetMouse(); - - /* DLudwig, Dec 3, 2012: WinRT 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: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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 + +/* + * Windows includes: + */ +#include +using namespace Windows::UI::Core; +using Windows::UI::Core::CoreCursor; + +/* + * SDL includes: + */ +extern "C" { +#include "SDL_assert.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +#include "../SDL_sysvideo.h" +#include "SDL_events.h" +#include "SDL_log.h" +} + +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "SDL_winrtvideo_cpp.h" +#include "SDL_winrtmouse_c.h" + + +extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; + + +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) +{ + // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled. + if ( ! CoreWindow::GetForCurrentThread()) { + return 0; + } + + 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) +{ + WINRT_UsingRelativeMouseMode = enabled; + return 0; +} + +void +WINRT_InitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + /* DLudwig, Dec 3, 2012: WinRT 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: */ diff --git a/src/video/winrt/SDL_winrtopengles.cpp b/src/video/winrt/SDL_winrtopengles.cpp index f6cdeaec6..1229eb9bf 100644 --- a/src/video/winrt/SDL_winrtopengles.cpp +++ b/src/video/winrt/SDL_winrtopengles.cpp @@ -1,50 +1,50 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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" - -// TODO: WinRT, make this file compile via C code - -#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL - -/* EGL implementation of SDL OpenGL support */ - -#include "SDL_winrtvideo_cpp.h" -extern "C" { -#include "SDL_winrtopengles.h" -} - -#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((NativeDisplayType) -3) - -extern "C" int -WINRT_GLES_LoadLibrary(_THIS, const char *path) { - return SDL_EGL_LoadLibrary(_this, path, EGL_D3D11_ONLY_DISPLAY_ANGLE); -} - -extern "C" { -SDL_EGL_CreateContext_impl(WINRT) -SDL_EGL_SwapWindow_impl(WINRT) -SDL_EGL_MakeCurrent_impl(WINRT) -} - -#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ - -/* vi: set ts=4 sw=4 expandtab: */ - +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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" + +// TODO: WinRT, make this file compile via C code + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +/* EGL implementation of SDL OpenGL support */ + +#include "SDL_winrtvideo_cpp.h" +extern "C" { +#include "SDL_winrtopengles.h" +} + +#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((NativeDisplayType) -3) + +extern "C" int +WINRT_GLES_LoadLibrary(_THIS, const char *path) { + return SDL_EGL_LoadLibrary(_this, path, EGL_D3D11_ONLY_DISPLAY_ANGLE); +} + +extern "C" { +SDL_EGL_CreateContext_impl(WINRT) +SDL_EGL_SwapWindow_impl(WINRT) +SDL_EGL_MakeCurrent_impl(WINRT) +} + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h index 4ac3cfe23..193e0333f 100644 --- a/src/video/winrt/SDL_winrtopengles.h +++ b/src/video/winrt/SDL_winrtopengles.h @@ -1,48 +1,48 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2013 Sam Lantinga - - 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_winrtopengles_h -#define _SDL_winrtopengles_h - -#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL - -#include "../SDL_sysvideo.h" -#include "../SDL_egl_c.h" - -/* OpenGLES functions */ -#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute -#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress -#define WINRT_GLES_UnloadLibrary SDL_EGL_UnloadLibrary -#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval -#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext - -extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); -extern void WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); - -#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ - -#endif /* _SDL_winrtopengles_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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_winrtopengles_h +#define _SDL_winrtopengles_h + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +/* OpenGLES functions */ +#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute +#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WINRT_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); +extern void WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_winrtopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index bb1a771f9..13dd5b621 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -17,7 +17,7 @@ 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 @@ -32,363 +32,363 @@ extern "C" { #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" -#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_mouse_c.h" #include "../../events/SDL_touch_c.h" } - -/* File-specific globals: */ -static SDL_TouchID WINRT_TouchID = 1; -static unsigned int WINRT_LeftFingerDown = 0; - - -void -WINRT_InitTouch(_THIS) -{ - SDL_AddTouch(WINRT_TouchID, ""); -} - - -// -// Applies necessary geometric transformations to raw cursor positions: -// -Windows::Foundation::Point -WINRT_TransformCursorPosition(SDL_Window * window, - Windows::Foundation::Point rawPosition, - WINRT_CursorNormalizationType normalization) -{ - using namespace Windows::UI::Core; - using namespace Windows::Graphics::Display; - - if (!window) { - return rawPosition; - } - - SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; - if (windowData->coreWindow == nullptr) { - // For some reason, the window isn't associated with a CoreWindow. - // This might end up being the case as XAML support is extended. - // For now, if there's no CoreWindow attached to the SDL_Window, - // don't do any transforms. - - // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support - return rawPosition; - } - - // The CoreWindow can only be accessed on certain thread(s). - SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); - - CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); - Windows::Foundation::Point outputPosition; - - // Compute coordinates normalized from 0..1. - // If the coordinates need to be sized to the SDL window, - // we'll do that after. -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; - outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; -#else - switch (DisplayProperties::CurrentOrientation) - { - case DisplayOrientations::Portrait: - outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; - outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; - break; - case DisplayOrientations::PortraitFlipped: - outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); - outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); - break; - case DisplayOrientations::Landscape: - outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; - outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); - break; - case DisplayOrientations::LandscapeFlipped: - outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); - outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; - break; - default: - break; - } -#endif - - if (normalization == TransformToSDLWindowSize) { - outputPosition.X *= ((float32) window->w); - outputPosition.Y *= ((float32) window->h); - } - - return outputPosition; -} - -static inline int -_lround(float arg) -{ - if (arg >= 0.0f) { - return (int)floor(arg + 0.5f); - } else { - return (int)ceil(arg - 0.5f); - } -} - -Uint8 -WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) -{ - using namespace Windows::UI::Input; - -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return SDL_BUTTON_LEFT; -#else - 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; - } -#endif - - return 0; -} - -//const char * -//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) -//{ -// using namespace Windows::UI::Input; -// -// 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 bool -WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) -{ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return true; -#else - using namespace Windows::Devices::Input; - switch (pointerPoint->PointerDevice->PointerDeviceType) { - case PointerDeviceType::Touch: - case PointerDeviceType::Pen: - return true; - default: - return false; - } -#endif -} - -void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - - if ( ! WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); - } else { - Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); - Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); - - if (!WINRT_LeftFingerDown) { - if (button) { - SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); - } - - WINRT_LeftFingerDown = pointerPoint->PointerId; - } - - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_TRUE, - normalizedPoint.X, - normalizedPoint.Y, - pointerPoint->Properties->Pressure); - } + +/* File-specific globals: */ +static SDL_TouchID WINRT_TouchID = 1; +static unsigned int WINRT_LeftFingerDown = 0; + + +void +WINRT_InitTouch(_THIS) +{ + SDL_AddTouch(WINRT_TouchID, ""); } - -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window || WINRT_UsingRelativeMouseMode) { - return; - } - - Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); - Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); - - if ( ! WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); - } else if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - if (pointerPoint->PointerId == WINRT_LeftFingerDown) { - SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); - } - - SDL_SendTouchMotion( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - normalizedPoint.X, - normalizedPoint.Y, - pointerPoint->Properties->Pressure); - } -} - -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - - if (!WINRT_IsTouchEvent(pointerPoint)) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - } else { - Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); - - if (WINRT_LeftFingerDown == pointerPoint->PointerId) { - if (button) { - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - } - WINRT_LeftFingerDown = 0; - } - - SDL_SendTouch( - WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, - SDL_FALSE, - normalizedPoint.X, - normalizedPoint.Y, - pointerPoint->Properties->Pressure); - } -} -void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) -{ - if (!window) { - return; - } - - // FIXME: This may need to accumulate deltas up to WHEEL_DELTA - short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; - SDL_SendMouseWheel(window, 0, 0, motion); -} -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) -{ - if (!window || !WINRT_UsingRelativeMouseMode) { - return; - } - - // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); - const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize); - SDL_SendMouseMotion( - window, - 0, - 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); +// +// Applies necessary geometric transformations to raw cursor positions: +// +Windows::Foundation::Point +WINRT_TransformCursorPosition(SDL_Window * window, + Windows::Foundation::Point rawPosition, + WINRT_CursorNormalizationType normalization) +{ + using namespace Windows::UI::Core; + using namespace Windows::Graphics::Display; + + if (!window) { + return rawPosition; + } + + SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; + if (windowData->coreWindow == nullptr) { + // For some reason, the window isn't associated with a CoreWindow. + // This might end up being the case as XAML support is extended. + // For now, if there's no CoreWindow attached to the SDL_Window, + // don't do any transforms. + + // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support + return rawPosition; + } + + // The CoreWindow can only be accessed on certain thread(s). + SDL_assert(CoreWindow::GetForCurrentThread() != nullptr); + + CoreWindow ^ nativeWindow = windowData->coreWindow.Get(); + Windows::Foundation::Point outputPosition; + + // Compute coordinates normalized from 0..1. + // If the coordinates need to be sized to the SDL window, + // we'll do that after. +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; + outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; +#else + switch (DisplayProperties::CurrentOrientation) + { + case DisplayOrientations::Portrait: + outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; + outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; + break; + case DisplayOrientations::PortraitFlipped: + outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); + outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::Landscape: + outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; + outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); + break; + case DisplayOrientations::LandscapeFlipped: + outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); + outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; + break; + default: + break; + } +#endif + + if (normalization == TransformToSDLWindowSize) { + outputPosition.X *= ((float32) window->w); + outputPosition.Y *= ((float32) window->h); + } + + return outputPosition; +} + +static inline int +_lround(float arg) +{ + if (arg >= 0.0f) { + return (int)floor(arg + 0.5f); + } else { + return (int)ceil(arg - 0.5f); + } +} + +Uint8 +WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +{ + using namespace Windows::UI::Input; + +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return SDL_BUTTON_LEFT; +#else + 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; + } +#endif + + return 0; +} + +//const char * +//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) +//{ +// using namespace Windows::UI::Input; +// +// 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 bool +WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + return true; +#else + using namespace Windows::Devices::Input; + switch (pointerPoint->PointerDevice->PointerDeviceType) { + case PointerDeviceType::Touch: + case PointerDeviceType::Pen: + return true; + default: + return false; + } +#endif +} + +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + + if ( ! WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } else { + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); + + if (!WINRT_LeftFingerDown) { + if (button) { + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + } + + WINRT_LeftFingerDown = pointerPoint->PointerId; + } + + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_TRUE, + normalizedPoint.X, + normalizedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void +WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window || WINRT_UsingRelativeMouseMode) { + return; + } + + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); + + if ( ! WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); + } else if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + if (pointerPoint->PointerId == WINRT_LeftFingerDown) { + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); + } + + SDL_SendTouchMotion( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + normalizedPoint.X, + normalizedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); + + if (!WINRT_IsTouchEvent(pointerPoint)) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } else { + Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); + + if (WINRT_LeftFingerDown == pointerPoint->PointerId) { + if (button) { + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + } + WINRT_LeftFingerDown = 0; + } + + SDL_SendTouch( + WINRT_TouchID, + (SDL_FingerID) pointerPoint->PointerId, + SDL_FALSE, + normalizedPoint.X, + normalizedPoint.Y, + pointerPoint->Properties->Pressure); + } +} + +void +WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +{ + if (!window) { + return; + } + + // FIXME: This may need to accumulate deltas up to WHEEL_DELTA + short motion = pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, motion); +} + +void +WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +{ + if (!window || !WINRT_UsingRelativeMouseMode) { + return; + } + + // 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 WinRT 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 Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y); + const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize); + SDL_SendMouseMotion( + window, + 0, + 1, + _lround(mouseDeltaInSDLWindowCoords.X), + _lround(mouseDeltaInSDLWindowCoords.Y)); } #endif // SDL_VIDEO_DRIVER_WINRT diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index d5f467960..30dffcf08 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -113,14 +113,14 @@ WINRT_CreateDevice(int devindex) device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; #ifdef SDL_VIDEO_OPENGL_EGL - device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; - device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; - device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary; - device->GL_CreateContext = WINRT_GLES_CreateContext; - device->GL_MakeCurrent = WINRT_GLES_MakeCurrent; - device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval; - device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval; - device->GL_SwapWindow = WINRT_GLES_SwapWindow; + device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; + device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; + device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary; + device->GL_CreateContext = WINRT_GLES_CreateContext; + device->GL_MakeCurrent = WINRT_GLES_MakeCurrent; + device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval; + device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval; + device->GL_SwapWindow = WINRT_GLES_SwapWindow; device->GL_DeleteContext = WINRT_GLES_DeleteContext; #endif device->free = WINRT_DeleteDevice; @@ -351,7 +351,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) /* For now, treat WinRT apps as if they always have focus. TODO, WinRT: try tracking keyboard and mouse focus state with respect to snapped apps */ - SDL_SetMouseFocus(window); + SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); /* Make sure the WinRT app's IFramworkView can post events on diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index 0c2cb1154..0a8de6455 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -44,36 +44,36 @@ extern SDL_Window * WINRT_GlobalSDLWindow; /* The global, WinRT, video device. */ extern SDL_VideoDevice * WINRT_GlobalSDLVideoDevice; -/* Creates a display mode for Plain Direct3D (non-XAML) apps, using the lone, native window's settings. - - Pass in an allocated SDL_DisplayMode field to store the data in. - - This function will return 0 on success, -1 on failure. - - If this function succeeds, be sure to call SDL_free on the - SDL_DisplayMode's driverdata field. -*/ -extern int WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode); - -/* Duplicates a display mode, copying over driverdata as necessary */ -extern int WINRT_DuplicateDisplayMode(SDL_DisplayMode * dest, const SDL_DisplayMode * src); - -/* Display mode internals */ -typedef struct -{ - Windows::Graphics::Display::DisplayOrientations currentOrientation; +/* Creates a display mode for Plain Direct3D (non-XAML) apps, using the lone, native window's settings. + + Pass in an allocated SDL_DisplayMode field to store the data in. + + This function will return 0 on success, -1 on failure. + + If this function succeeds, be sure to call SDL_free on the + SDL_DisplayMode's driverdata field. +*/ +extern int WINRT_CalcDisplayModeUsingNativeWindow(SDL_DisplayMode * mode); + +/* Duplicates a display mode, copying over driverdata as necessary */ +extern int WINRT_DuplicateDisplayMode(SDL_DisplayMode * dest, const SDL_DisplayMode * src); + +/* Display mode internals */ +typedef struct +{ + Windows::Graphics::Display::DisplayOrientations currentOrientation; } SDL_DisplayModeData; #ifdef __cplusplus_winrt /* Internal window data */ -struct SDL_WindowData -{ - SDL_Window *sdlWindow; - Platform::Agile coreWindow; -#ifdef SDL_VIDEO_OPENGL_EGL - EGLSurface egl_surface; -#endif +struct SDL_WindowData +{ + SDL_Window *sdlWindow; + Platform::Agile coreWindow; +#ifdef SDL_VIDEO_OPENGL_EGL + EGLSurface egl_surface; +#endif }; #endif // ifdef __cplusplus_winrt diff --git a/test/loopwave.c b/test/loopwave.c index 403d16c53..210465a2b 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -1,144 +1,144 @@ -/* - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ - -/* Program to load a wave file and loop playing it using SDL sound */ - -/* loopwaves.c is much more robust in handling WAVE files -- - This is only for simple WAVEs -*/ -#include "SDL_config.h" - -#include -#include - -#if HAVE_SIGNAL_H -#include -#endif - -#include "SDL.h" -#include "SDL_audio.h" - -struct -{ - SDL_AudioSpec spec; - Uint8 *sound; /* Pointer to wave data */ - Uint32 soundlen; /* Length of wave data */ - int soundpos; /* Current play position */ -} wave; - - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - - -void SDLCALL -fillerup(void *unused, Uint8 * stream, int len) -{ - Uint8 *waveptr; - int waveleft; - - /* Set up the pointers */ - waveptr = wave.sound + wave.soundpos; - waveleft = wave.soundlen - wave.soundpos; - - /* Go! */ - while (waveleft <= len) { - SDL_memcpy(stream, waveptr, waveleft); - stream += waveleft; - len -= waveleft; - waveptr = wave.sound; - waveleft = wave.soundlen; - wave.soundpos = 0; - } - SDL_memcpy(stream, waveptr, len); - wave.soundpos += len; -} - -static int done = 0; -void -poked(int sig) -{ - done = 1; -} - -int -main(int argc, char *argv[]) -{ - int i; - char filename[4096]; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_AUDIO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - 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(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], SDL_GetError()); - quit(1); - } - - wave.spec.callback = fillerup; -#if HAVE_SIGNAL_H - /* Set the signals */ -#ifdef SIGHUP - signal(SIGHUP, poked); -#endif - signal(SIGINT, poked); -#ifdef SIGQUIT - signal(SIGQUIT, poked); -#endif - signal(SIGTERM, poked); -#endif /* HAVE_SIGNAL_H */ - - /* Show the list of available drivers */ - SDL_Log("Available audio drivers:"); - for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { - SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); - } - - /* Initialize fillerup() variables */ - if (SDL_OpenAudio(&wave.spec, NULL) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); - SDL_FreeWAV(wave.sound); - quit(2); - } - - SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - - /* Let the audio run */ - SDL_PauseAudio(0); - while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) - SDL_Delay(1000); - - /* Clean up on signal */ - SDL_CloseAudio(); - SDL_FreeWAV(wave.sound); - SDL_Quit(); - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/* Program to load a wave file and loop playing it using SDL sound */ + +/* loopwaves.c is much more robust in handling WAVE files -- + This is only for simple WAVEs +*/ +#include "SDL_config.h" + +#include +#include + +#if HAVE_SIGNAL_H +#include +#endif + +#include "SDL.h" +#include "SDL_audio.h" + +struct +{ + SDL_AudioSpec spec; + Uint8 *sound; /* Pointer to wave data */ + Uint32 soundlen; /* Length of wave data */ + int soundpos; /* Current play position */ +} wave; + + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_Quit(); + exit(rc); +} + + +void SDLCALL +fillerup(void *unused, Uint8 * stream, int len) +{ + Uint8 *waveptr; + int waveleft; + + /* Set up the pointers */ + waveptr = wave.sound + wave.soundpos; + waveleft = wave.soundlen - wave.soundpos; + + /* Go! */ + while (waveleft <= len) { + SDL_memcpy(stream, waveptr, waveleft); + stream += waveleft; + len -= waveleft; + waveptr = wave.sound; + waveleft = wave.soundlen; + wave.soundpos = 0; + } + SDL_memcpy(stream, waveptr, len); + wave.soundpos += len; +} + +static int done = 0; +void +poked(int sig) +{ + done = 1; +} + +int +main(int argc, char *argv[]) +{ + int i; + char filename[4096]; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Load the SDL library */ + if (SDL_Init(SDL_INIT_AUDIO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return (1); + } + + 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(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], SDL_GetError()); + quit(1); + } + + wave.spec.callback = fillerup; +#if HAVE_SIGNAL_H + /* Set the signals */ +#ifdef SIGHUP + signal(SIGHUP, poked); +#endif + signal(SIGINT, poked); +#ifdef SIGQUIT + signal(SIGQUIT, poked); +#endif + signal(SIGTERM, poked); +#endif /* HAVE_SIGNAL_H */ + + /* Show the list of available drivers */ + SDL_Log("Available audio drivers:"); + for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { + SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); + } + + /* Initialize fillerup() variables */ + if (SDL_OpenAudio(&wave.spec, NULL) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); + SDL_FreeWAV(wave.sound); + quit(2); + } + + SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); + + /* Let the audio run */ + SDL_PauseAudio(0); + while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) + SDL_Delay(1000); + + /* Clean up on signal */ + SDL_CloseAudio(); + SDL_FreeWAV(wave.sound); + SDL_Quit(); + return (0); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/test/testthread.c b/test/testthread.c index c5ce2d5a8..ed9f1f182 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -1,99 +1,99 @@ -/* - Copyright (C) 1997-2013 Sam Lantinga - - 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. -*/ - -/* Simple test of the SDL threading code */ - -#include -#include -#include - -#include "SDL.h" -#include "SDL_thread.h" - -static SDL_TLSID tls; -static int alive = 0; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -int SDLCALL -ThreadFunc(void *data) -{ - SDL_TLSSet(tls, "baby thread", NULL); - SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n", - (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls)); - while (alive) { - SDL_Log("Thread '%s' is alive!\n", (char *) data); - SDL_Delay(1 * 1000); - } - SDL_Log("Thread '%s' exiting!\n", (char *) data); - return (0); -} - -static void -killed(int sig) -{ - SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); - SDL_Delay(5 * 1000); - alive = 0; - quit(0); -} - -int -main(int argc, char *argv[]) -{ - SDL_Thread *thread; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - tls = SDL_TLSCreate(); - SDL_assert(tls); - SDL_TLSSet(tls, "main thread", NULL); - SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); - - alive = 1; - thread = SDL_CreateThread(ThreadFunc, "One", "#1"); - if (thread == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - SDL_Delay(5 * 1000); - SDL_Log("Waiting for thread #1\n"); - alive = 0; - SDL_WaitThread(thread, NULL); - - SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); - - alive = 1; - signal(SIGTERM, killed); - thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); - if (thread == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - raise(SIGTERM); - - SDL_Quit(); /* Never reached */ - return (0); /* Never reached */ -} +/* + Copyright (C) 1997-2013 Sam Lantinga + + 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. +*/ + +/* Simple test of the SDL threading code */ + +#include +#include +#include + +#include "SDL.h" +#include "SDL_thread.h" + +static SDL_TLSID tls; +static int alive = 0; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_Quit(); + exit(rc); +} + +int SDLCALL +ThreadFunc(void *data) +{ + SDL_TLSSet(tls, "baby thread", NULL); + SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n", + (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls)); + while (alive) { + SDL_Log("Thread '%s' is alive!\n", (char *) data); + SDL_Delay(1 * 1000); + } + SDL_Log("Thread '%s' exiting!\n", (char *) data); + return (0); +} + +static void +killed(int sig) +{ + SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); + SDL_Delay(5 * 1000); + alive = 0; + quit(0); +} + +int +main(int argc, char *argv[]) +{ + SDL_Thread *thread; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Load the SDL library */ + if (SDL_Init(0) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return (1); + } + + tls = SDL_TLSCreate(); + SDL_assert(tls); + SDL_TLSSet(tls, "main thread", NULL); + SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); + + alive = 1; + thread = SDL_CreateThread(ThreadFunc, "One", "#1"); + if (thread == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); + quit(1); + } + SDL_Delay(5 * 1000); + SDL_Log("Waiting for thread #1\n"); + alive = 0; + SDL_WaitThread(thread, NULL); + + SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); + + alive = 1; + signal(SIGTERM, killed); + thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); + if (thread == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); + quit(1); + } + raise(SIGTERM); + + SDL_Quit(); /* Never reached */ + return (0); /* Never reached */ +}