SDL: gdk: Add support for building with OpenGL on Xbox

From 3ebfb1546947883dc1cda0805df61933a027a678 Mon Sep 17 00:00:00 2001
From: Caleb Cornett <[EMAIL REDACTED]>
Date: Mon, 19 Dec 2022 17:22:23 -0500
Subject: [PATCH] gdk: Add support for building with OpenGL on Xbox

---
 include/build_config/SDL_build_config_xbox.h | 17 +++++---
 src/video/windows/SDL_windowsopengl.c        | 35 ++++++++++++++-
 src/video/windows/SDL_windowsopengl.h        | 45 ++++++++++++++++++++
 src/video/windows/SDL_windowsvideo.h         |  2 +-
 src/video/windows/SDL_windowswindow.c        |  4 +-
 5 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/include/build_config/SDL_build_config_xbox.h b/include/build_config/SDL_build_config_xbox.h
index 31faf65ccfd0..3db6b365cd89 100644
--- a/include/build_config/SDL_build_config_xbox.h
+++ b/include/build_config/SDL_build_config_xbox.h
@@ -204,16 +204,21 @@
 #define SDL_VIDEO_DRIVER_DUMMY  1
 #define SDL_VIDEO_DRIVER_WINDOWS    1
 
-/* #ifndef SDL_VIDEO_RENDER_D3D
-#define SDL_VIDEO_RENDER_D3D    1
-#endif*/
-#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H)
-#define SDL_VIDEO_RENDER_D3D11  1
-#endif
 #if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H)
 #define SDL_VIDEO_RENDER_D3D12  1
 #endif
 
+/* Enable OpenGL support */
+#ifndef SDL_VIDEO_OPENGL
+#define SDL_VIDEO_OPENGL    1
+#endif
+#ifndef SDL_VIDEO_OPENGL_WGL
+#define SDL_VIDEO_OPENGL_WGL    1
+#endif
+#ifndef SDL_VIDEO_RENDER_OGL
+#define SDL_VIDEO_RENDER_OGL    1
+#endif
+
 /* Enable system power support */
 /*#define SDL_POWER_WINDOWS 1*/
 #define SDL_POWER_HARDWIRED 1
diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c
index 6226a754becc..a85b300af92a 100644
--- a/src/video/windows/SDL_windowsopengl.c
+++ b/src/video/windows/SDL_windowsopengl.c
@@ -20,7 +20,7 @@
 */
 #include "SDL_internal.h"
 
-#if SDL_VIDEO_DRIVER_WINDOWS && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
+#if SDL_VIDEO_DRIVER_WINDOWS
 
 #include "SDL_windowsvideo.h"
 #include "SDL_windowsopengles.h"
@@ -95,6 +95,16 @@ typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC,
                                                            const int
                                                                *attribList);
 
+#if __XBOXONE__ || __XBOXSERIES__
+#define GetDC(hwnd)          (HDC) hwnd
+#define ReleaseDC(hwnd, hdc) 1
+#define SwapBuffers          _this->gl_data->wglSwapBuffers
+#define DescribePixelFormat  _this->gl_data->wglDescribePixelFormat
+#define ChoosePixelFormat    _this->gl_data->wglChoosePixelFormat
+#define GetPixelFormat       _this->gl_data->wglGetPixelFormat
+#define SetPixelFormat       _this->gl_data->wglSetPixelFormat
+#endif
+
 int WIN_GL_LoadLibrary(_THIS, const char *path)
 {
     void *handle;
@@ -133,10 +143,31 @@ int WIN_GL_LoadLibrary(_THIS, const char *path)
         SDL_LoadFunction(handle, "wglShareLists");
     /* *INDENT-ON* */ /* clang-format on */
 
+#if __XBOXONE__ || __XBOXSERIES__
+    _this->gl_data->wglSwapBuffers = (BOOL(WINAPI *)(HDC))
+        SDL_LoadFunction(handle, "wglSwapBuffers");
+    _this->gl_data->wglDescribePixelFormat = (int(WINAPI *)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR))
+        SDL_LoadFunction(handle, "wglDescribePixelFormat");
+    _this->gl_data->wglChoosePixelFormat = (int(WINAPI *)(HDC, const PIXELFORMATDESCRIPTOR *))
+        SDL_LoadFunction(handle, "wglChoosePixelFormat");
+    _this->gl_data->wglSetPixelFormat = (BOOL(WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *))
+        SDL_LoadFunction(handle, "wglSetPixelFormat");
+    _this->gl_data->wglGetPixelFormat = (int(WINAPI *)(HDC hdc))
+        SDL_LoadFunction(handle, "wglGetPixelFormat");
+#endif
+
     if (!_this->gl_data->wglGetProcAddress ||
         !_this->gl_data->wglCreateContext ||
         !_this->gl_data->wglDeleteContext ||
-        !_this->gl_data->wglMakeCurrent) {
+        !_this->gl_data->wglMakeCurrent
+#if __XBOXONE__ || __XBOXSERIES__
+        || !_this->gl_data->wglSwapBuffers ||
+        !_this->gl_data->wglDescribePixelFormat ||
+        !_this->gl_data->wglChoosePixelFormat ||
+        !_this->gl_data->wglGetPixelFormat ||
+        !_this->gl_data->wglSetPixelFormat
+#endif
+    ) {
         return SDL_SetError("Could not retrieve OpenGL functions");
     }
 
diff --git a/src/video/windows/SDL_windowsopengl.h b/src/video/windows/SDL_windowsopengl.h
index 143e13f89f26..9268f8d2bcc5 100644
--- a/src/video/windows/SDL_windowsopengl.h
+++ b/src/video/windows/SDL_windowsopengl.h
@@ -25,6 +25,38 @@
 
 #if SDL_VIDEO_OPENGL_WGL
 
+#if __XBOXONE__ || __XBOXSERIES__
+typedef struct tagPIXELFORMATDESCRIPTOR
+{
+    WORD nSize;
+    WORD nVersion;
+    DWORD dwFlags;
+    BYTE iPixelType;
+    BYTE cColorBits;
+    BYTE cRedBits;
+    BYTE cRedShift;
+    BYTE cGreenBits;
+    BYTE cGreenShift;
+    BYTE cBlueBits;
+    BYTE cBlueShift;
+    BYTE cAlphaBits;
+    BYTE cAlphaShift;
+    BYTE cAccumBits;
+    BYTE cAccumRedBits;
+    BYTE cAccumGreenBits;
+    BYTE cAccumBlueBits;
+    BYTE cAccumAlphaBits;
+    BYTE cDepthBits;
+    BYTE cStencilBits;
+    BYTE cAuxBuffers;
+    BYTE iLayerType;
+    BYTE bReserved;
+    DWORD dwLayerMask;
+    DWORD dwVisibleMask;
+    DWORD dwDamageMask;
+} PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR;
+#endif
+
 struct SDL_GLDriverData
 {
     SDL_bool HAS_WGL_ARB_pixel_format;
@@ -53,6 +85,19 @@ struct SDL_GLDriverData
     BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
     BOOL (WINAPI *wglSwapIntervalEXT)(int interval);
     int (WINAPI *wglGetSwapIntervalEXT)(void);
+#if __XBOXONE__ || __XBOXSERIES__
+    BOOL (WINAPI *wglSwapBuffers)(HDC hdc);
+    int (WINAPI *wglDescribePixelFormat)(HDC hdc,
+                                         int iPixelFormat,
+                                         UINT nBytes,
+                                         LPPIXELFORMATDESCRIPTOR ppfd);
+    int (WINAPI *wglChoosePixelFormat)(HDC hdc,
+                                       const PIXELFORMATDESCRIPTOR *ppfd);
+    BOOL (WINAPI *wglSetPixelFormat)(HDC hdc,
+                                     int format,
+                                     const PIXELFORMATDESCRIPTOR *ppfd);
+    int (WINAPI *wglGetPixelFormat)(HDC hdc);
+#endif
     /* *INDENT-ON* */ /* clang-format on */
 };
 
diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h
index e47663f6b310..e94b198b8c41 100644
--- a/src/video/windows/SDL_windowsvideo.h
+++ b/src/video/windows/SDL_windowsvideo.h
@@ -41,12 +41,12 @@
 
 #include "SDL_windowsclipboard.h"
 #include "SDL_windowsevents.h"
+#include "SDL_windowsopengl.h"
 
 #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
 #include "SDL_windowskeyboard.h"
 #include "SDL_windowsmodes.h"
 #include "SDL_windowsmouse.h"
-#include "SDL_windowsopengl.h"
 #include "SDL_windowsopengles.h"
 #endif
 
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 8a4feb50439c..0f44abc07cd9 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -290,7 +290,9 @@ static int SetupWindowData(_THIS, SDL_Window *window, HWND hwnd, HWND parent, SD
     data->window = window;
     data->hwnd = hwnd;
     data->parent = parent;
-#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
+#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
+    data->hdc = (HDC) data->hwnd;
+#else
     data->hdc = GetDC(hwnd);
 #endif
     data->hinstance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);