From 75f8cbf953093bc539af67c77d18263767bb3474 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Sun, 31 Mar 2019 21:15:45 +0200
Subject: draft API for OpenGL shito in libui

---
 src/libui_sdl/libui/ui.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index b100c08..a81aa70 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -599,6 +599,17 @@ _UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar
 
 _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout);
 
+
+// OpenGL support
+// TODO for later: allow using OpenGL inside a uiWindow or uiArea
+
+typedef struct uiGLContext uiGLContext;
+
+_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c);
+_UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
+_UI_EXTERN void *uiGLGetProcAddress(const char* proc);
+
+
 _UI_ENUM(uiModifiers) {
 	uiModifierCtrl = 1 << 0,
 	uiModifierAlt = 1 << 1,
-- 
cgit v1.2.3


From b48fe5909bd9314c271f1cb729c9aa79d88a26f3 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Sun, 31 Mar 2019 21:54:14 +0200
Subject: * add some GL base to libui (only for Windows for now) * make the
 Codeblocks project a bit less braindead (don't repeat libraries for each
 build target)

---
 CMakeLists.txt           | 2 ++
 melonDS.cbp              | 1 +
 src/libui_sdl/libui/ui.h | 2 +-
 3 files changed, 4 insertions(+), 1 deletion(-)

(limited to 'src/libui_sdl/libui')

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8abe112..a333766 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -138,6 +138,7 @@ elseif (WIN32)
         src/libui_sdl/libui/windows/fontbutton.cpp
         src/libui_sdl/libui/windows/fontdialog.cpp
         src/libui_sdl/libui/windows/form.cpp
+	src/libui_sdl/libui/windows/gl.cpp
         src/libui_sdl/libui/windows/graphemes.cpp
         src/libui_sdl/libui/windows/grid.cpp
         src/libui_sdl/libui/windows/group.cpp
@@ -172,6 +173,7 @@ elseif (WIN32)
     LINK_LIBRARIES("usp10")
     LINK_LIBRARIES("ws2_32")
     LINK_LIBRARIES("uxtheme")
+    LINK_LIBRARIES("opengl32")
 endif (UNIX)
 
 find_package(SDL2 REQUIRED)
diff --git a/melonDS.cbp b/melonDS.cbp
index fc5f8df..9f105fc 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -222,6 +222,7 @@
 		<Unit filename="src/libui_sdl/libui/windows/fontbutton.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/fontdialog.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/form.cpp" />
+		<Unit filename="src/libui_sdl/libui/windows/gl.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/graphemes.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/grid.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/group.cpp" />
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index a81aa70..381b85b 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -601,11 +601,11 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou
 
 
 // OpenGL support
-// TODO for later: allow using OpenGL inside a uiWindow or uiArea
 
 typedef struct uiGLContext uiGLContext;
 
 _UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c);
+_UI_EXTERN void uiGLFreeContext(uiGLContext* ctx);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
 
-- 
cgit v1.2.3


From f1628b98de5dcef702ca57ee363407d715d5b36e Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Sun, 31 Mar 2019 21:54:42 +0200
Subject: adding that file might be good, too

---
 src/libui_sdl/libui/windows/gl.cpp | 66 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 src/libui_sdl/libui/windows/gl.cpp

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
new file mode 100644
index 0000000..fe21ae4
--- /dev/null
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -0,0 +1,66 @@
+// 31 march 2019
+#include "uipriv_windows.hpp"
+
+struct uiGLContext
+{
+    uiControl* c;
+
+    HWND hwnd;
+    HDC dc;
+    HGLRC rc;
+};
+
+
+uiGLContext* uiGLNewContext(uiControl* c)
+{
+    uiGLContext* ctx;
+
+    ctx = uiNew(uiGLContext);
+
+    ctx->c = c;
+    if (c)
+    {
+        ctx->hwnd = (HWND)c->Handle(c); // welp
+    }
+    else
+    {
+        // windowless context
+        ctx->hwnd = GetDesktopWindow();
+    }
+
+    PIXELFORMATDESCRIPTOR pfd;
+    memset(&pfd, 0, sizeof(pfd));
+    pfd.nSize = sizeof(pfd);
+    pfd.nVersion = 1;
+    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = 24;
+    pfd.cAlphaBits = 8;
+    pfd.cDepthBits = 24;
+    pfd.cStencilBits = 8;
+    pfd.iLayerType = PFD_MAIN_PLANE;
+
+    ctx->dc = GetDC(ctx->hwnd);
+
+    int pixelformat = ChoosePixelFormat(ctx->dc, &pfd);
+    SetPixelFormat(ctx->dc, pixelformat, &pfd);
+
+    ctx->rc = wglCreateContext(ctx->dc);
+}
+
+void uiGLFreeContext(uiGLContext* ctx)
+{
+    wglDeleteContext(ctx->rc);
+    ReleaseDC(ctx->hwnd, ctx->dc);
+    uiFree(ctx);
+}
+
+void uiGLMakeContextCurrent(uiGLContext* ctx)
+{
+    wglMakeCurrent(ctx->dc, ctx->rc);
+}
+
+void *uiGLGetProcAddress(const char* proc)
+{
+    return (void*)wglGetProcAddress(proc);
+}
-- 
cgit v1.2.3


From f8751bd1fb83e85e2eb4e91b9c4b032ef0c18cdd Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Mon, 1 Apr 2019 02:51:31 +0200
Subject: first attempt at things

(also fix softrenderer reset)
---
 melonDS.cbp                        |  68 ++++++------------
 src/GPU3D.cpp                      |  20 ++++--
 src/GPU3D.h                        |  14 ++++
 src/GPU3D_OpenGL43.cpp             | 138 +++++++++++++++++++++++++++++++++++++
 src/GPU3D_Soft.cpp                 |   6 +-
 src/Platform.h                     |   2 +
 src/libui_sdl/Platform.cpp         |   7 ++
 src/libui_sdl/libui/ui.h           |   2 +-
 src/libui_sdl/libui/windows/gl.cpp |  69 ++++++++++++++++++-
 src/libui_sdl/main.cpp             |  11 +++
 10 files changed, 275 insertions(+), 62 deletions(-)
 create mode 100644 src/GPU3D_OpenGL43.cpp

(limited to 'src/libui_sdl/libui')

diff --git a/melonDS.cbp b/melonDS.cbp
index 9f105fc..0ba8653 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -19,22 +19,6 @@
 				</Compiler>
 				<Linker>
 					<Add option="-m64" />
-					<Add library="SDL2" />
-					<Add library="shell32" />
-					<Add library="comctl32" />
-					<Add library="comdlg32" />
-					<Add library="advapi32" />
-					<Add library="wsock32" />
-					<Add library="oleacc" />
-					<Add library="ole32" />
-					<Add library="usp10" />
-					<Add library="gdi32" />
-					<Add library="d2d1" />
-					<Add library="dwrite" />
-					<Add library="uxtheme" />
-					<Add library="iphlpapi" />
-					<Add library="user32" />
-					<Add library="ws2_32" />
 				</Linker>
 			</Target>
 			<Target title="Release Windows">
@@ -51,22 +35,6 @@
 				<Linker>
 					<Add option="-s" />
 					<Add option="-m64" />
-					<Add library="SDL2" />
-					<Add library="shell32" />
-					<Add library="comctl32" />
-					<Add library="comdlg32" />
-					<Add library="advapi32" />
-					<Add library="wsock32" />
-					<Add library="oleacc" />
-					<Add library="ole32" />
-					<Add library="usp10" />
-					<Add library="gdi32" />
-					<Add library="d2d1" />
-					<Add library="dwrite" />
-					<Add library="uxtheme" />
-					<Add library="iphlpapi" />
-					<Add library="user32" />
-					<Add library="ws2_32" />
 				</Linker>
 			</Target>
 			<Target title="DebugFast Windows">
@@ -82,22 +50,6 @@
 				</Compiler>
 				<Linker>
 					<Add option="-m64" />
-					<Add library="SDL2" />
-					<Add library="shell32" />
-					<Add library="comctl32" />
-					<Add library="comdlg32" />
-					<Add library="advapi32" />
-					<Add library="wsock32" />
-					<Add library="oleacc" />
-					<Add library="ole32" />
-					<Add library="usp10" />
-					<Add library="gdi32" />
-					<Add library="d2d1" />
-					<Add library="dwrite" />
-					<Add library="uxtheme" />
-					<Add library="iphlpapi" />
-					<Add library="user32" />
-					<Add library="ws2_32" />
 				</Linker>
 			</Target>
 		</Build>
@@ -107,6 +59,25 @@
 			<Add option="-pipe" />
 			<Add directory="src" />
 		</Compiler>
+		<Linker>
+			<Add library="SDL2" />
+			<Add library="shell32" />
+			<Add library="comctl32" />
+			<Add library="comdlg32" />
+			<Add library="advapi32" />
+			<Add library="wsock32" />
+			<Add library="oleacc" />
+			<Add library="ole32" />
+			<Add library="usp10" />
+			<Add library="gdi32" />
+			<Add library="d2d1" />
+			<Add library="dwrite" />
+			<Add library="uxtheme" />
+			<Add library="iphlpapi" />
+			<Add library="user32" />
+			<Add library="ws2_32" />
+			<Add library="opengl32" />
+		</Linker>
 		<Unit filename="melon.rc">
 			<Option compilerVar="WINDRES" />
 		</Unit>
@@ -135,6 +106,7 @@
 		<Unit filename="src/GPU2D.h" />
 		<Unit filename="src/GPU3D.cpp" />
 		<Unit filename="src/GPU3D.h" />
+		<Unit filename="src/GPU3D_OpenGL43.cpp" />
 		<Unit filename="src/GPU3D_Soft.cpp" />
 		<Unit filename="src/NDS.cpp" />
 		<Unit filename="src/NDS.h" />
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index 802c9cd..b4211f0 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -275,14 +275,16 @@ bool Init()
 
     CmdStallQueue = new FIFO<CmdFIFOEntry>(64);
 
-    if (!SoftRenderer::Init()) return false;
+    //if (!SoftRenderer::Init()) return false;
+    if (!GLRenderer43::Init()) return false;
 
     return true;
 }
 
 void DeInit()
 {
-    SoftRenderer::DeInit();
+    //SoftRenderer::DeInit();
+    GLRenderer43::DeInit();
 
     delete CmdFIFO;
     delete CmdPIPE;
@@ -382,7 +384,8 @@ void Reset()
     FlushAttributes = 0;
 
     ResetRenderingState();
-    SoftRenderer::Reset();
+    //SoftRenderer::Reset();
+    GLRenderer43::Reset();
 }
 
 void DoSavestate(Savestate* file)
@@ -2331,7 +2334,7 @@ void CheckFIFODMA()
 
 void VCount144()
 {
-    SoftRenderer::VCount144();
+    //SoftRenderer::VCount144();
 }
 
 
@@ -2413,17 +2416,20 @@ void VBlank()
 
 void VCount215()
 {
-    SoftRenderer::RenderFrame();
+    //SoftRenderer::RenderFrame();
+    GLRenderer43::RenderFrame();
 }
 
 void RequestLine(int line)
 {
-    return SoftRenderer::RequestLine(line);
+    //return SoftRenderer::RequestLine(line);
+    return GLRenderer43::RequestLine(line);
 }
 
 u32* GetLine(int line)
 {
-    return SoftRenderer::GetLine(line);
+    //return SoftRenderer::GetLine(line);
+    return GLRenderer43::GetLine(line);
 }
 
 
diff --git a/src/GPU3D.h b/src/GPU3D.h
index 279494a..f300da8 100644
--- a/src/GPU3D.h
+++ b/src/GPU3D.h
@@ -132,6 +132,20 @@ u32* GetLine(int line);
 
 }
 
+namespace GLRenderer43
+{
+
+bool Init();
+void DeInit();
+void Reset();
+
+void VCount144();
+void RenderFrame();
+void RequestLine(int line);
+u32* GetLine(int line);
+
+}
+
 }
 
 #endif
diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp
new file mode 100644
index 0000000..acb1436
--- /dev/null
+++ b/src/GPU3D_OpenGL43.cpp
@@ -0,0 +1,138 @@
+/*
+    Copyright 2016-2019 Arisotura
+
+    This file is part of melonDS.
+
+    melonDS is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include <stdio.h>
+#include <string.h>
+#include "NDS.h"
+#include "GPU.h"
+#include "Platform.h"
+
+namespace GPU3D
+{
+namespace GLRenderer43
+{
+
+PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
+PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
+PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
+
+
+GLuint FramebufferID;
+u8 Framebuffer[256*192*4];
+u8 CurLine[256*4];
+
+
+bool InitGLExtensions()
+{
+#define LOADPROC(type, name)  \
+    name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \
+    if (!name) return false;
+
+    LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers);
+    LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer);
+    LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture);
+
+#undef LOADPROC
+    return true;
+}
+
+bool Init()
+{
+    if (!InitGLExtensions()) return false;
+
+    u8* test_tex = new u8[256*192*4];
+    u8* ptr = test_tex;
+    for (int y = 0; y < 192; y++)
+    {
+        for (int x = 0; x < 256; x++)
+        {
+            if ((x & 0x10) ^ (y & 0x10))
+            {
+                *ptr++ = 0x00;
+                *ptr++ = 0x00;
+                *ptr++ = 0x3F;
+                *ptr++ = 0x1F;
+            }
+            else
+            {
+                *ptr++ = 0;
+                *ptr++ = y>>2;
+                *ptr++ = 0x3F;
+                *ptr++ = 0x1F;
+            }
+        }
+    }
+
+    glGenFramebuffers(1, &FramebufferID);
+    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID);
+
+    GLuint frametex;
+    glGenTextures(1, &frametex);
+    glBindTexture(GL_TEXTURE_2D, frametex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, test_tex);
+    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frametex, 0);
+
+    return true;
+}
+
+void DeInit()
+{
+    //
+}
+
+void Reset()
+{
+    //
+}
+
+
+void VCount144()
+{
+}
+
+void RenderFrame()
+{
+    //
+}
+
+void RequestLine(int line)
+{
+    //
+}
+
+u32* GetLine(int line)
+{
+    if (line == 0)
+    {
+        glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID);
+        glReadBuffer(GL_COLOR_ATTACHMENT0);
+        glReadPixels(0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer);
+    }
+
+    return (u32*)&Framebuffer[256*4 * line];
+}
+
+}
+}
diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp
index 29b46e1..8d18a35 100644
--- a/src/GPU3D_Soft.cpp
+++ b/src/GPU3D_Soft.cpp
@@ -129,9 +129,9 @@ void DeInit()
 
 void Reset()
 {
-    memset(ColorBuffer, 0, 256*192 * 4);
-    memset(DepthBuffer, 0, 256*192 * 4);
-    memset(AttrBuffer, 0, 256*192 * 4);
+    memset(ColorBuffer, 0, BufferSize * 2 * 4);
+    memset(DepthBuffer, 0, BufferSize * 2 * 4);
+    memset(AttrBuffer, 0, BufferSize * 2 * 4);
 
     PrevIsShadowMask = false;
 
diff --git a/src/Platform.h b/src/Platform.h
index df3335b..ca6971e 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -68,6 +68,8 @@ void Semaphore_Reset(void* sema);
 void Semaphore_Wait(void* sema);
 void Semaphore_Post(void* sema);
 
+void* GL_GetProcAddress(const char* proc);
+
 // local multiplayer comm interface
 // packet type: DS-style TX header (12 bytes) + original 802.11 frame
 bool MP_Init();
diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp
index 6ebe8c3..e3035b3 100644
--- a/src/libui_sdl/Platform.cpp
+++ b/src/libui_sdl/Platform.cpp
@@ -24,6 +24,7 @@
 #include "PlatformConfig.h"
 #include "LAN_Socket.h"
 #include "LAN_PCap.h"
+#include "libui/ui.h"
 #include <string>
 
 #ifdef __WIN32__
@@ -302,6 +303,12 @@ void Semaphore_Post(void* sema)
 }
 
 
+void* GL_GetProcAddress(const char* proc)
+{
+    return uiGLGetProcAddress(proc);
+}
+
+
 bool MP_Init()
 {
     int opt_true = 1;
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index 381b85b..dd1c786 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -604,7 +604,7 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou
 
 typedef struct uiGLContext uiGLContext;
 
-_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c);
+_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor);
 _UI_EXTERN void uiGLFreeContext(uiGLContext* ctx);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index fe21ae4..eb7d33d 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -1,6 +1,9 @@
 // 31 march 2019
 #include "uipriv_windows.hpp"
 
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
 struct uiGLContext
 {
     uiControl* c;
@@ -11,9 +14,10 @@ struct uiGLContext
 };
 
 
-uiGLContext* uiGLNewContext(uiControl* c)
+uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor)
 {
     uiGLContext* ctx;
+    BOOL res;
 
     ctx = uiNew(uiGLContext);
 
@@ -25,7 +29,10 @@ uiGLContext* uiGLNewContext(uiControl* c)
     else
     {
         // windowless context
-        ctx->hwnd = GetDesktopWindow();
+        //ctx->hwnd = GetDesktopWindow();
+        // nope.
+        uiFree(ctx);
+        return NULL;
     }
 
     PIXELFORMATDESCRIPTOR pfd;
@@ -41,15 +48,71 @@ uiGLContext* uiGLNewContext(uiControl* c)
     pfd.iLayerType = PFD_MAIN_PLANE;
 
     ctx->dc = GetDC(ctx->hwnd);
+    if (!ctx->dc)
+    {
+        uiFree(ctx);
+        return NULL;
+    }
 
     int pixelformat = ChoosePixelFormat(ctx->dc, &pfd);
-    SetPixelFormat(ctx->dc, pixelformat, &pfd);
+    res = SetPixelFormat(ctx->dc, pixelformat, &pfd);
+    if (!res)
+    {
+        ReleaseDC(ctx->hwnd, ctx->dc);
+        uiFree(ctx);
+        return NULL;
+    }
 
     ctx->rc = wglCreateContext(ctx->dc);
+    if (!ctx->rc)
+    {
+        ReleaseDC(ctx->hwnd, ctx->dc);
+        uiFree(ctx);
+        return NULL;
+    }
+
+    wglMakeCurrent(ctx->dc, ctx->rc);
+
+    if (vermajor >= 3)
+    {
+        HGLRC (*wglCreateContextAttribsARB)(HDC,HGLRC,const int*);
+        HGLRC rc_better = NULL;
+
+        wglCreateContextAttribsARB = (HGLRC(*)(HDC,HGLRC,const int*))wglGetProcAddress("wglCreateContextAttribsARB");
+        if (wglCreateContextAttribsARB)
+        {
+            int attribs[15];
+            int i = 0;
+
+            attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
+            attribs[i++] = vermajor;
+            attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB;
+            attribs[i++] = verminor;
+
+            attribs[i] = 0;
+            rc_better = wglCreateContextAttribsARB(ctx->dc, NULL, attribs);
+        }
+
+        wglMakeCurrent(NULL, NULL);
+        wglDeleteContext(ctx->rc);
+
+        if (!rc_better)
+        {
+            ReleaseDC(ctx->hwnd, ctx->dc);
+            uiFree(ctx);
+            return NULL;
+        }
+
+        ctx->rc = rc_better;
+        wglMakeCurrent(ctx->dc, ctx->rc);
+    }
+
+    return ctx;
 }
 
 void uiGLFreeContext(uiGLContext* ctx)
 {
+    wglMakeCurrent(NULL, NULL);
     wglDeleteContext(ctx->rc);
     ReleaseDC(ctx->hwnd, ctx->dc);
     uiFree(ctx);
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 566b346..d892912 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -392,6 +392,14 @@ void FeedMicInput()
 
 int EmuThreadFunc(void* burp)
 {
+    // TODO: fail gracefully, support older OpenGL, etc
+    uiGLContext* glctx = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw
+    uiGLMakeContextCurrent(glctx);
+
+    void* testor = uiGLGetProcAddress("glUseProgram");
+    void* testor2 = uiGLGetProcAddress("glBindFramebuffer");
+    printf("OPENGL: %p %p\n", testor, testor2);
+
     NDS::Init();
 
     MainScreenPos[0] = 0;
@@ -616,6 +624,8 @@ int EmuThreadFunc(void* burp)
     NDS::DeInit();
     Platform::LAN_DeInit();
 
+    uiGLFreeContext(glctx);
+
     return 44203;
 }
 
@@ -1652,6 +1662,7 @@ void ApplyNewSettings(int type)
 
     if (type == 0) // general emu settings
     {
+        // TODO!! REMOVE ME
         GPU3D::SoftRenderer::SetupRenderThread();
     }
     else if (type == 1) // wifi settings
-- 
cgit v1.2.3


From 1f13d9ce80c0cd5e94ba883ff6bb30c95d48a48a Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Mon, 1 Apr 2019 04:50:48 +0200
Subject: * move GL init to main thread * fix potential bug causing the screen
 bitmap to be created twice

---
 src/GPU3D_OpenGL43.cpp                |  2 +-
 src/libui_sdl/libui/windows/alloc.cpp |  2 +-
 src/libui_sdl/libui/windows/gl.cpp    |  9 ++++++++-
 src/libui_sdl/main.cpp                | 29 +++++++++++++++++------------
 4 files changed, 27 insertions(+), 15 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp
index 58539fa..ea8bbd7 100644
--- a/src/GPU3D_OpenGL43.cpp
+++ b/src/GPU3D_OpenGL43.cpp
@@ -53,7 +53,7 @@ bool InitGLExtensions()
 {
 #define LOADPROC(type, name)  \
     name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \
-    if (!name) return false;
+    if (!name) { printf("OpenGL: " #name " not found\n"); return false; }
 
     LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers);
     LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers);
diff --git a/src/libui_sdl/libui/windows/alloc.cpp b/src/libui_sdl/libui/windows/alloc.cpp
index cf6bd2e..e29d60e 100644
--- a/src/libui_sdl/libui/windows/alloc.cpp
+++ b/src/libui_sdl/libui/windows/alloc.cpp
@@ -32,7 +32,7 @@ void *uiAlloc(size_t size, const char *type)
 {
 	byteArray *out;
 
-	out = new byteArray(size, 0);
+	out = new byteArray(size, 0);//printf("alloc %s at %08X\n", type, rawBytes(out));
 	heap[rawBytes(out)] = out;
 	types[out] = type;
 	return rawBytes(out);
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index eb7d33d..beccb79 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -120,7 +120,14 @@ void uiGLFreeContext(uiGLContext* ctx)
 
 void uiGLMakeContextCurrent(uiGLContext* ctx)
 {
-    wglMakeCurrent(ctx->dc, ctx->rc);
+    if (ctx == NULL)
+    {
+        wglMakeCurrent(NULL, NULL);
+        return;
+    }
+
+    if (wglGetCurrentContext() == ctx->rc) return;
+    int res = wglMakeCurrent(ctx->dc, ctx->rc);
 }
 
 void *uiGLGetProcAddress(const char* proc)
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index d892912..2705560 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -60,6 +60,7 @@ char* EmuDirectory;
 
 uiWindow* MainWindow;
 uiArea* MainDrawArea;
+uiGLContext* GLContext;
 
 int WindowWidth, WindowHeight;
 
@@ -392,14 +393,7 @@ void FeedMicInput()
 
 int EmuThreadFunc(void* burp)
 {
-    // TODO: fail gracefully, support older OpenGL, etc
-    uiGLContext* glctx = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw
-    uiGLMakeContextCurrent(glctx);
-
-    void* testor = uiGLGetProcAddress("glUseProgram");
-    void* testor2 = uiGLGetProcAddress("glBindFramebuffer");
-    printf("OPENGL: %p %p\n", testor, testor2);
-
+    uiGLMakeContextCurrent(GLContext);
     NDS::Init();
 
     MainScreenPos[0] = 0;
@@ -407,7 +401,6 @@ int EmuThreadFunc(void* burp)
     MainScreenPos[2] = 0;
     AutoScreenSizing = 0;
 
-    ScreenDrawInited = false;
     Touching = false;
     KeyInputMask = 0xFFF;
     HotkeyMask = 0;
@@ -440,6 +433,8 @@ int EmuThreadFunc(void* burp)
         {
             EmuStatus = 1;
 
+            uiGLMakeContextCurrent(GLContext);
+
             SDL_JoystickUpdate();
 
             if (Joystick)
@@ -624,8 +619,6 @@ int EmuThreadFunc(void* burp)
     NDS::DeInit();
     Platform::LAN_DeInit();
 
-    uiGLFreeContext(glctx);
-
     return 44203;
 }
 
@@ -634,8 +627,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
 {
     if (!ScreenDrawInited)
     {
-        ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384);
         ScreenDrawInited = true;
+        ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384);
     }
 
     if (!ScreenBitmap) return;
@@ -1981,6 +1974,7 @@ int main(int argc, char** argv)
     areahandler.KeyEvent = OnAreaKeyEvent;
     areahandler.Resize = OnAreaResize;
 
+    ScreenDrawInited = false;
     MainDrawArea = uiNewArea(&areahandler);
     uiWindowSetChild(MainWindow, uiControl(MainDrawArea));
     uiControlSetMinSize(uiControl(MainDrawArea), 256, 384);
@@ -2011,6 +2005,15 @@ int main(int argc, char** argv)
 
     OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]);
 
+    // TODO: fail gracefully, support older OpenGL, etc
+    GLContext = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw
+    uiGLMakeContextCurrent(GLContext);
+
+    void* testor = uiGLGetProcAddress("glUseProgram");
+    void* testor2 = uiGLGetProcAddress("glBindFramebuffer");
+    printf("OPENGL: %p %p\n", testor, testor2);
+    uiGLMakeContextCurrent(NULL);
+
     SDL_AudioSpec whatIwant, whatIget;
     memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
     whatIwant.freq = 47340;
@@ -2092,6 +2095,8 @@ int main(int argc, char** argv)
 
     if (MicWavBuffer) delete[] MicWavBuffer;
 
+    uiGLFreeContext(GLContext);
+
     Config::ScreenRotation = ScreenRotation;
     Config::ScreenGap = ScreenGap;
     Config::ScreenLayout = ScreenLayout;
-- 
cgit v1.2.3


From 4bf75a8d8ee1a5adae7dd1deb571ef943d874ce7 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Mon, 1 Apr 2019 04:52:03 +0200
Subject: glörg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/libui_sdl/libui/windows/alloc.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/windows/alloc.cpp b/src/libui_sdl/libui/windows/alloc.cpp
index e29d60e..cf6bd2e 100644
--- a/src/libui_sdl/libui/windows/alloc.cpp
+++ b/src/libui_sdl/libui/windows/alloc.cpp
@@ -32,7 +32,7 @@ void *uiAlloc(size_t size, const char *type)
 {
 	byteArray *out;
 
-	out = new byteArray(size, 0);//printf("alloc %s at %08X\n", type, rawBytes(out));
+	out = new byteArray(size, 0);
 	heap[rawBytes(out)] = out;
 	types[out] = type;
 	return rawBytes(out);
-- 
cgit v1.2.3


From a89366cb5a1106152374c9e91ebef96149db76cc Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Wed, 15 May 2019 16:43:56 +0200
Subject: begin butchering uiArea

---
 src/libui_sdl/DlgInputConfig.cpp           |  2 +-
 src/libui_sdl/libui/ui.h                   |  3 ++-
 src/libui_sdl/libui/windows/area.cpp       | 23 +++++++++++++++++++----
 src/libui_sdl/libui/windows/area.hpp       |  6 +++++-
 src/libui_sdl/libui/windows/areadraw.cpp   | 27 ++++++++++++++++++++-------
 src/libui_sdl/libui/windows/areaevents.cpp |  2 +-
 src/libui_sdl/libui/windows/areautil.cpp   | 21 ++++++++++++++++++---
 src/libui_sdl/libui/windows/gl.cpp         |  5 +++++
 src/libui_sdl/main.cpp                     |  6 ++++--
 9 files changed, 75 insertions(+), 20 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp
index 513bd90..4c464f1 100644
--- a/src/libui_sdl/DlgInputConfig.cpp
+++ b/src/libui_sdl/DlgInputConfig.cpp
@@ -432,7 +432,7 @@ void Open(int type)
         uiLabel* dummy = uiNewLabel("");
         uiBoxAppend(in_ctrl, uiControl(dummy), 1);
 
-        dlg->keypresscatcher = uiNewArea(&dlg->areahandler);
+        dlg->keypresscatcher = uiNewArea(&dlg->areahandler, 0);
         uiControl(dlg->keypresscatcher)->UserData = dlg;
         uiBoxAppend(in_ctrl, uiControl(dlg->keypresscatcher), 0);
 
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index dd1c786..2641f30 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -341,7 +341,7 @@ _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, doub
 _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a);
 _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);
 _UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b);
-_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah);
+_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah, int opengl);
 _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);
 
 struct uiAreaDrawParams {
@@ -608,6 +608,7 @@ _UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor)
 _UI_EXTERN void uiGLFreeContext(uiGLContext* ctx);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
+_UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx);
 
 
 _UI_ENUM(uiModifiers) {
diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp
index 2185f25..99c843e 100644
--- a/src/libui_sdl/libui/windows/area.cpp
+++ b/src/libui_sdl/libui/windows/area.cpp
@@ -25,8 +25,11 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
 	}
 
 	// always recreate the render target if necessary
-	if (a->rt == NULL)
-		a->rt = makeHWNDRenderTarget(a->hwnd);
+	if (!a->openGL)
+    {
+        if (a->rt == NULL)
+            a->rt = makeHWNDRenderTarget(a->hwnd);
+    }
 
 	if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE)
 		return lResult;
@@ -34,12 +37,14 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
 	if (uMsg == WM_WINDOWPOSCHANGED) {
 		if ((wp->flags & SWP_NOSIZE) != 0)
 			return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+        a->width = -1;
+        a->height = -1;
 		uiWindowsEnsureGetClientRect(a->hwnd, &client);
 		areaDrawOnResize(a, &client);
 		areaScrollOnResize(a, &client);
 		{
 		    double w, h;
-		    loadAreaSize(a, a->rt, &w, &h);
+		    loadAreaSize(a, &w, &h);
 		    a->ah->Resize(a->ah, a, (int)w, (int)h);
 		}
 		return 0;
@@ -176,12 +181,15 @@ void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b)
 }
 
 
-uiArea *uiNewArea(uiAreaHandler *ah)
+uiArea *uiNewArea(uiAreaHandler *ah, int opengl)
 {
 	uiArea *a;
 
 	uiWindowsNewControl(uiArea, a);
 
+	a->width = -1;
+	a->height = -1;
+
 	a->ah = ah;
 	a->scrolling = FALSE;
 	clickCounterReset(&(a->cc));
@@ -195,6 +203,8 @@ uiArea *uiNewArea(uiAreaHandler *ah)
 
     uiAreaSetBackgroundColor(a, -1, -1, -1);
 
+    a->openGL = opengl;
+
 	return a;
 }
 
@@ -204,6 +214,9 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
 
 	uiWindowsNewControl(uiArea, a);
 
+	a->width = -1;
+	a->height = -1;
+
 	a->ah = ah;
 	a->scrolling = TRUE;
 	a->scrollWidth = width;
@@ -219,6 +232,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
 
     uiAreaSetBackgroundColor(a, -1, -1, -1);
 
+    a->openGL = 0; // TODO, eventually???
+
 	// set initial scrolling parameters
 	areaUpdateScroll(a);
 
diff --git a/src/libui_sdl/libui/windows/area.hpp b/src/libui_sdl/libui/windows/area.hpp
index add62dd..f8abd4f 100644
--- a/src/libui_sdl/libui/windows/area.hpp
+++ b/src/libui_sdl/libui/windows/area.hpp
@@ -10,6 +10,8 @@ struct uiArea {
 	HWND hwnd;
 	uiAreaHandler *ah;
 
+	int width, height;
+
 	BOOL scrolling;
 	int scrollWidth;
 	int scrollHeight;
@@ -26,6 +28,8 @@ struct uiArea {
 
 	int bgR, bgG, bgB;
 
+	int openGL;
+
 	ID2D1HwndRenderTarget *rt;
 };
 
@@ -42,6 +46,6 @@ extern void areaUpdateScroll(uiArea *a);
 extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
 
 // areautil.cpp
-extern void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height);
+extern void loadAreaSize(uiArea *a, double *width, double *height);
 extern void pixelsToDIP(uiArea *a, double *x, double *y);
 extern void dipToPixels(uiArea *a, double *x, double *y);
diff --git a/src/libui_sdl/libui/windows/areadraw.cpp b/src/libui_sdl/libui/windows/areadraw.cpp
index a9ad477..6b4845a 100644
--- a/src/libui_sdl/libui/windows/areadraw.cpp
+++ b/src/libui_sdl/libui/windows/areadraw.cpp
@@ -6,6 +6,13 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)
 {
 	uiAreaHandler *ah = a->ah;
 	uiAreaDrawParams dp;
+
+	if (a->openGL)
+    {
+        (*(ah->Draw))(ah, a, &dp);
+        return S_OK;
+    }
+
 	COLORREF bgcolorref;
 	D2D1_COLOR_F bgcolor;
 	D2D1_MATRIX_3X2_F scrollTransform;
@@ -13,7 +20,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)
 	// no need to save or restore the graphics state to reset transformations;  it's handled by resetTarget() in draw.c, called during the following
 	dp.Context = newContext(rt);
 
-	loadAreaSize(a, rt, &(dp.AreaWidth), &(dp.AreaHeight));
+	loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight));
 
 	dp.ClipX = clip->left;
 	dp.ClipY = clip->top;
@@ -113,6 +120,9 @@ static void onWM_PAINT(uiArea *a)
 
 static void onWM_PRINTCLIENT(uiArea *a, HDC dc)
 {
+    // TODO????
+    if (a->openGL) return;
+
 	ID2D1DCRenderTarget *rt;
 	RECT client;
 	HRESULT hr;
@@ -143,13 +153,16 @@ BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lRe
 // TODO only if the render target wasn't just created?
 void areaDrawOnResize(uiArea *a, RECT *newClient)
 {
-	D2D1_SIZE_U size;
+    if (!a->openGL)
+    {
+        D2D1_SIZE_U size;
 
-	size.width = newClient->right - newClient->left;
-	size.height = newClient->bottom - newClient->top;
-	// don't track the error; we'll get that in EndDraw()
-	// see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx
-	a->rt->Resize(&size);
+        size.width = newClient->right - newClient->left;
+        size.height = newClient->bottom - newClient->top;
+        // don't track the error; we'll get that in EndDraw()
+        // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx
+        a->rt->Resize(&size);
+    }
 
 	// according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572)
 	// we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore
diff --git a/src/libui_sdl/libui/windows/areaevents.cpp b/src/libui_sdl/libui/windows/areaevents.cpp
index 3ff7a47..46d6ab9 100644
--- a/src/libui_sdl/libui/windows/areaevents.cpp
+++ b/src/libui_sdl/libui/windows/areaevents.cpp
@@ -109,7 +109,7 @@ static void areaMouseEvent(uiArea *a, int down, int  up, WPARAM wParam, LPARAM l
 		me.Y += a->vscrollpos;
 	}
 
-	loadAreaSize(a, NULL, &(me.AreaWidth), &(me.AreaHeight));
+	loadAreaSize(a, &(me.AreaWidth), &(me.AreaHeight));
 
 	me.Down = down;
 	me.Up = up;
diff --git a/src/libui_sdl/libui/windows/areautil.cpp b/src/libui_sdl/libui/windows/areautil.cpp
index 212ea42..ea13221 100644
--- a/src/libui_sdl/libui/windows/areautil.cpp
+++ b/src/libui_sdl/libui/windows/areautil.cpp
@@ -2,20 +2,35 @@
 #include "uipriv_windows.hpp"
 #include "area.hpp"
 
-void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height)
+// TODO: make those int rather than double
+void loadAreaSize(uiArea *a, double *width, double *height)
 {
 	D2D1_SIZE_F size;
 
+	if (a->width != -1)
+    {
+        *width = (double)a->width;
+        *height = (double)a->height;
+        return;
+    }
+
 	*width = 0;
 	*height = 0;
 	if (!a->scrolling) {
-		if (rt == NULL)
+		/*if (rt == NULL)
 			rt = a->rt;
 		size = realGetSize(rt);
 		*width = size.width;
 		*height = size.height;
-		dipToPixels(a, width, height);
+		dipToPixels(a, width, height);*/
+		RECT rect;
+        GetWindowRect(a->hwnd, &rect);
+        *width = (double)(rect.right - rect.left);
+        *height = (double)(rect.bottom - rect.top);
 	}
+
+	a->width = (int)*width;
+	a->height = (int)*height;
 }
 
 void pixelsToDIP(uiArea *a, double *x, double *y)
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index beccb79..67eaeda 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -134,3 +134,8 @@ void *uiGLGetProcAddress(const char* proc)
 {
     return (void*)wglGetProcAddress(proc);
 }
+
+void uiGLSwapBuffers(uiGLContext* ctx)
+{
+    SwapBuffers(ctx->dc);
+}
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 6fcb1ae..b39f493 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -568,6 +568,7 @@ int EmuThreadFunc(void* burp)
             if (EmuRunning == 0) break;
 
             uiAreaQueueRedrawAll(MainDrawArea);
+            //uiGLSwapBuffers(GLContext);
 
             // framerate limiter based off SDL2_gfx
             float framerate;
@@ -619,7 +620,8 @@ int EmuThreadFunc(void* burp)
 
             if (EmuRunning == 2)
             {
-                uiAreaQueueRedrawAll(MainDrawArea);
+                //uiAreaQueueRedrawAll(MainDrawArea);
+                //uiGLSwapBuffers(GLContext);
             }
 
             EmuStatus = EmuRunning;
@@ -2061,7 +2063,7 @@ int main(int argc, char** argv)
     areahandler.Resize = OnAreaResize;
 
     ScreenDrawInited = false;
-    MainDrawArea = uiNewArea(&areahandler);
+    MainDrawArea = uiNewArea(&areahandler, 0);
     uiWindowSetChild(MainWindow, uiControl(MainDrawArea));
     uiControlSetMinSize(uiControl(MainDrawArea), 256, 384);
     uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable?
-- 
cgit v1.2.3


From 256b8cb69c751f43a7766eafc6f8798eefa3217e Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Wed, 15 May 2019 19:49:21 +0200
Subject: botch GL support.

---
 melonDS.cbp                              |   2 +
 src/GPU3D_OpenGL43.cpp                   | 124 +------------------------------
 src/OpenGLSupport.cpp                    |  30 ++++++++
 src/OpenGLSupport.h                      | 112 ++++++++++++++++++++++++++++
 src/libui_sdl/libui/windows/areadraw.cpp |   2 +-
 5 files changed, 147 insertions(+), 123 deletions(-)
 create mode 100644 src/OpenGLSupport.cpp
 create mode 100644 src/OpenGLSupport.h

(limited to 'src/libui_sdl/libui')

diff --git a/melonDS.cbp b/melonDS.cbp
index b396861..4634513 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -112,6 +112,8 @@
 		<Unit filename="src/NDS.h" />
 		<Unit filename="src/NDSCart.cpp" />
 		<Unit filename="src/NDSCart.h" />
+		<Unit filename="src/OpenGLSupport.cpp" />
+		<Unit filename="src/OpenGLSupport.h" />
 		<Unit filename="src/Platform.h" />
 		<Unit filename="src/RTC.cpp" />
 		<Unit filename="src/RTC.h" />
diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp
index 57a80f1..3a2a3f1 100644
--- a/src/GPU3D_OpenGL43.cpp
+++ b/src/GPU3D_OpenGL43.cpp
@@ -16,77 +16,17 @@
     with melonDS. If not, see http://www.gnu.org/licenses/.
 */
 
-#include <GL/gl.h>
-#include <GL/glext.h>
-
 #include <stdio.h>
 #include <string.h>
 #include "NDS.h"
 #include "GPU.h"
-#include "Platform.h"
+#include "OpenGLSupport.h"
 
 namespace GPU3D
 {
 namespace GLRenderer43
 {
 
-PFNGLGENFRAMEBUFFERSPROC        glGenFramebuffers;
-PFNGLDELETEFRAMEBUFFERSPROC     glDeleteFramebuffers;
-PFNGLBINDFRAMEBUFFERPROC        glBindFramebuffer;
-PFNGLFRAMEBUFFERTEXTUREPROC     glFramebufferTexture;
-PFNGLBLITFRAMEBUFFERPROC        glBlitFramebuffer;
-
-PFNGLGENBUFFERSPROC             glGenBuffers;
-PFNGLDELETEBUFFERSPROC          glDeleteBuffers;
-PFNGLBINDBUFFERPROC             glBindBuffer;
-PFNGLMAPBUFFERPROC              glMapBuffer;
-PFNGLMAPBUFFERRANGEPROC         glMapBufferRange;
-PFNGLUNMAPBUFFERPROC            glUnmapBuffer;
-PFNGLBUFFERDATAPROC             glBufferData;
-PFNGLBUFFERSUBDATAPROC          glBufferSubData;
-PFNGLBINDBUFFERBASEPROC         glBindBufferBase;
-
-PFNGLGENVERTEXARRAYSPROC            glGenVertexArrays;
-PFNGLDELETEVERTEXARRAYSPROC         glDeleteVertexArrays;
-PFNGLBINDVERTEXARRAYPROC            glBindVertexArray;
-PFNGLENABLEVERTEXATTRIBARRAYPROC    glEnableVertexAttribArray;
-PFNGLDISABLEVERTEXATTRIBARRAYPROC   glDisableVertexAttribArray;
-PFNGLVERTEXATTRIBPOINTERPROC        glVertexAttribPointer;
-PFNGLVERTEXATTRIBIPOINTERPROC       glVertexAttribIPointer;
-
-PFNGLCREATESHADERPROC           glCreateShader;
-PFNGLSHADERSOURCEPROC           glShaderSource;
-PFNGLCOMPILESHADERPROC          glCompileShader;
-PFNGLCREATEPROGRAMPROC          glCreateProgram;
-PFNGLATTACHSHADERPROC           glAttachShader;
-PFNGLLINKPROGRAMPROC            glLinkProgram;
-PFNGLUSEPROGRAMPROC             glUseProgram;
-PFNGLGETSHADERIVPROC            glGetShaderiv;
-PFNGLGETSHADERINFOLOGPROC       glGetShaderInfoLog;
-PFNGLGETPROGRAMIVPROC           glGetProgramiv;
-PFNGLGETPROGRAMINFOLOGPROC      glGetProgramInfoLog;
-PFNGLDELETESHADERPROC           glDeleteShader;
-PFNGLDELETEPROGRAMPROC          glDeleteProgram;
-
-PFNGLUNIFORM1UIPROC             glUniform1ui;
-PFNGLUNIFORM4UIPROC             glUniform4ui;
-PFNGLUNIFORMBLOCKBINDINGPROC    glUniformBlockBinding;
-
-PFNGLACTIVETEXTUREPROC          glActiveTexture;
-PFNGLBINDIMAGETEXTUREPROC       glBindImageTexture;
-
-PFNGLDRAWBUFFERSPROC            glDrawBuffers;
-
-PFNGLBLENDFUNCSEPARATEIPROC      glBlendFuncSeparatei;
-PFNGLBLENDEQUATIONSEPARATEIPROC  glBlendEquationSeparatei;
-
-PFNGLCOLORMASKIPROC             glColorMaski;
-
-PFNGLMEMORYBARRIERPROC          glMemoryBarrier;
-
-PFNGLGETSTRINGIPROC             glGetStringi;
-
-
 // GL version requirements
 // * explicit uniform location: 4.3 (or extension)
 // * texelFetch: 3.0 (GLSL 1.30)     (3.2/1.50 for MS)
@@ -792,67 +732,7 @@ bool ChunkedRendering = false;
 
 bool InitGLExtensions()
 {
-#define LOADPROC(type, name)  \
-    name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \
-    if (!name) { printf("OpenGL: " #name " not found\n"); return false; }
-
-    LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers);
-    LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers);
-    LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer);
-    LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture);
-    LOADPROC(GLBLITFRAMEBUFFER, glBlitFramebuffer);
-
-    LOADPROC(GLGENBUFFERS, glGenBuffers);
-    LOADPROC(GLDELETEBUFFERS, glDeleteBuffers);
-    LOADPROC(GLBINDBUFFER, glBindBuffer);
-    LOADPROC(GLMAPBUFFER, glMapBuffer);
-    LOADPROC(GLMAPBUFFERRANGE, glMapBufferRange);
-    LOADPROC(GLUNMAPBUFFER, glUnmapBuffer);
-    LOADPROC(GLBUFFERDATA, glBufferData);
-    LOADPROC(GLBUFFERSUBDATA, glBufferSubData);
-    LOADPROC(GLBINDBUFFERBASE, glBindBufferBase);
-
-    LOADPROC(GLGENVERTEXARRAYS, glGenVertexArrays);
-    LOADPROC(GLDELETEVERTEXARRAYS, glDeleteVertexArrays);
-    LOADPROC(GLBINDVERTEXARRAY, glBindVertexArray);
-    LOADPROC(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray);
-    LOADPROC(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray);
-    LOADPROC(GLVERTEXATTRIBPOINTER, glVertexAttribPointer);
-    LOADPROC(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer);
-
-    LOADPROC(GLCREATESHADER, glCreateShader);
-    LOADPROC(GLSHADERSOURCE, glShaderSource);
-    LOADPROC(GLCOMPILESHADER, glCompileShader);
-    LOADPROC(GLCREATEPROGRAM, glCreateProgram);
-    LOADPROC(GLATTACHSHADER, glAttachShader);
-    LOADPROC(GLLINKPROGRAM, glLinkProgram);
-    LOADPROC(GLUSEPROGRAM, glUseProgram);
-    LOADPROC(GLGETSHADERIV, glGetShaderiv);
-    LOADPROC(GLGETSHADERINFOLOG, glGetShaderInfoLog);
-    LOADPROC(GLGETPROGRAMIV, glGetProgramiv);
-    LOADPROC(GLGETPROGRAMINFOLOG, glGetProgramInfoLog);
-    LOADPROC(GLDELETESHADER, glDeleteShader);
-    LOADPROC(GLDELETEPROGRAM, glDeleteProgram);
-
-    LOADPROC(GLUNIFORM1UI, glUniform1ui);
-    LOADPROC(GLUNIFORM4UI, glUniform4ui);
-    LOADPROC(GLUNIFORMBLOCKBINDING, glUniformBlockBinding);
-
-    LOADPROC(GLACTIVETEXTURE, glActiveTexture);
-    LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture);
-
-    LOADPROC(GLDRAWBUFFERS, glDrawBuffers);
-
-    LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei);
-    LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei);
-
-    LOADPROC(GLCOLORMASKI, glColorMaski);
-
-    LOADPROC(GLMEMORYBARRIER, glMemoryBarrier);
-
-    LOADPROC(GLGETSTRINGI, glGetStringi);
-
-#undef LOADPROC
+    if (!OpenGL_Init()) return false;
     return true;
 }
 
diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp
new file mode 100644
index 0000000..c22fd1c
--- /dev/null
+++ b/src/OpenGLSupport.cpp
@@ -0,0 +1,30 @@
+/*
+    Copyright 2016-2019 Arisotura
+
+    This file is part of melonDS.
+
+    melonDS is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "OpenGLSupport.h"
+
+
+DO_PROCLIST(DECLPROC);
+
+
+bool OpenGL_Init()
+{
+    DO_PROCLIST(LOADPROC);
+
+    return true;
+}
diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h
new file mode 100644
index 0000000..10ba1e5
--- /dev/null
+++ b/src/OpenGLSupport.h
@@ -0,0 +1,112 @@
+/*
+    Copyright 2016-2019 Arisotura
+
+    This file is part of melonDS.
+
+    melonDS is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef OPENGLSUPPORT_H
+#define OPENGLSUPPORT_H
+
+#include <stdio.h>
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include "Platform.h"
+
+
+// here, have some macro magic
+// we at the melonDS company really love macro magic
+// also, suggestion to the fine folks who write the OpenGL headers:
+// pls make the type names follow the same capitalization as their
+// matching function names, so this is more convenient to deal with
+
+#define DECLPROC(type, name)  \
+    PFN##type##PROC name ;
+
+#define DECLPROC_EXT(type, name)  \
+    extern PFN##type##PROC name ;
+
+#define LOADPROC(type, name)  \
+    name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \
+    if (!name) { printf("OpenGL: " #name " not found\n"); return false; }
+
+
+// if you need more OpenGL functions, add them to the macronator here
+// TODO: handle conditionally loading certain functions for different GL versions
+
+#define DO_PROCLIST(func) \
+    func(GLGENFRAMEBUFFERS, glGenFramebuffers); \
+    func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \
+    func(GLBINDFRAMEBUFFER, glBindFramebuffer); \
+    func(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); \
+    func(GLBLITFRAMEBUFFER, glBlitFramebuffer); \
+     \
+    func(GLGENBUFFERS, glGenBuffers); \
+    func(GLDELETEBUFFERS, glDeleteBuffers); \
+    func(GLBINDBUFFER, glBindBuffer); \
+    func(GLMAPBUFFER, glMapBuffer); \
+    func(GLMAPBUFFERRANGE, glMapBufferRange); \
+    func(GLUNMAPBUFFER, glUnmapBuffer); \
+    func(GLBUFFERDATA, glBufferData); \
+    func(GLBUFFERSUBDATA, glBufferSubData); \
+    func(GLBINDBUFFERBASE, glBindBufferBase); \
+     \
+    func(GLGENVERTEXARRAYS, glGenVertexArrays); \
+    func(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); \
+    func(GLBINDVERTEXARRAY, glBindVertexArray); \
+    func(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); \
+    func(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); \
+    func(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); \
+    func(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); \
+     \
+    func(GLCREATESHADER, glCreateShader); \
+    func(GLSHADERSOURCE, glShaderSource); \
+    func(GLCOMPILESHADER, glCompileShader); \
+    func(GLCREATEPROGRAM, glCreateProgram); \
+    func(GLATTACHSHADER, glAttachShader); \
+    func(GLLINKPROGRAM, glLinkProgram); \
+    func(GLUSEPROGRAM, glUseProgram); \
+    func(GLGETSHADERIV, glGetShaderiv); \
+    func(GLGETSHADERINFOLOG, glGetShaderInfoLog); \
+    func(GLGETPROGRAMIV, glGetProgramiv); \
+    func(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); \
+    func(GLDELETESHADER, glDeleteShader); \
+    func(GLDELETEPROGRAM, glDeleteProgram); \
+     \
+    func(GLUNIFORM1UI, glUniform1ui); \
+    func(GLUNIFORM4UI, glUniform4ui); \
+    func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \
+     \
+    func(GLACTIVETEXTURE, glActiveTexture); \
+    func(GLBINDIMAGETEXTURE, glBindImageTexture); \
+     \
+    func(GLDRAWBUFFERS, glDrawBuffers); \
+     \
+    func(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); \
+    func(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); \
+     \
+    func(GLCOLORMASKI, glColorMaski); \
+     \
+    func(GLMEMORYBARRIER, glMemoryBarrier); \
+     \
+    func(GLGETSTRINGI, glGetStringi); \
+
+
+DO_PROCLIST(DECLPROC_EXT);
+
+
+bool OpenGL_Init();
+
+#endif // OPENGLSUPPORT_H
diff --git a/src/libui_sdl/libui/windows/areadraw.cpp b/src/libui_sdl/libui/windows/areadraw.cpp
index 6b4845a..f369255 100644
--- a/src/libui_sdl/libui/windows/areadraw.cpp
+++ b/src/libui_sdl/libui/windows/areadraw.cpp
@@ -9,7 +9,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip)
 
 	if (a->openGL)
     {
-        (*(ah->Draw))(ah, a, &dp);
+        //(*(ah->Draw))(ah, a, &dp);
         return S_OK;
     }
 
-- 
cgit v1.2.3


From f2725791d8c3b5f00ddc830691ed556b48f2f508 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Thu, 16 May 2019 00:30:55 +0200
Subject: preliminary, shitty, code for drawing the main window with OpenGL

---
 melonDS.cbp                        |   1 +
 src/GPU3D_OpenGL43.cpp             |   7 +-
 src/OpenGLSupport.cpp              |  85 ++++++++++++++
 src/OpenGLSupport.h                |   4 +
 src/libui_sdl/libui/windows/gl.cpp |   2 +-
 src/libui_sdl/main.cpp             | 227 ++++++++++++++++++++++++++++++++++++-
 src/libui_sdl/main_shaders.h       |  72 ++++++++++++
 7 files changed, 392 insertions(+), 6 deletions(-)
 create mode 100644 src/libui_sdl/main_shaders.h

(limited to 'src/libui_sdl/libui')

diff --git a/melonDS.cbp b/melonDS.cbp
index 4634513..ff01ebf 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -230,6 +230,7 @@
 		<Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" />
 		<Unit filename="src/libui_sdl/libui/windows/winutil.cpp" />
 		<Unit filename="src/libui_sdl/main.cpp" />
+		<Unit filename="src/libui_sdl/main_shaders.h" />
 		<Unit filename="src/pcap/bluetooth.h" />
 		<Unit filename="src/pcap/bpf.h" />
 		<Unit filename="src/pcap/can_socketcan.h" />
diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp
index 3a2a3f1..b3e0856 100644
--- a/src/GPU3D_OpenGL43.cpp
+++ b/src/GPU3D_OpenGL43.cpp
@@ -732,7 +732,8 @@ bool ChunkedRendering = false;
 
 bool InitGLExtensions()
 {
-    if (!OpenGL_Init()) return false;
+    // TODO move this elsewhere!!
+    //if (!OpenGL_Init()) return false;
     return true;
 }
 
@@ -1385,7 +1386,7 @@ void VCount144()
 }
 
 void RenderFrame()
-{
+{return;
     ShaderConfig.uScreenSize[0] = ScreenW;
     ShaderConfig.uScreenSize[1] = ScreenH;
     ShaderConfig.uDispCnt = RenderDispCnt;
@@ -1544,7 +1545,7 @@ void RenderFrame()
 u32* GetLine(int line)
 {
     int stride = 256 << (ScaleFactor*2);
-
+return &Framebuffer[stride * line];
     if (!ChunkedRendering)
     {
         if (line == 0)
diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp
index c22fd1c..81a008b 100644
--- a/src/OpenGLSupport.cpp
+++ b/src/OpenGLSupport.cpp
@@ -28,3 +28,88 @@ bool OpenGL_Init()
 
     return true;
 }
+
+bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name)
+{
+    int len;
+    int res;
+
+    ids[0] = glCreateShader(GL_VERTEX_SHADER);
+    len = strlen(vs);
+    glShaderSource(ids[0], 1, &vs, &len);
+    glCompileShader(ids[0]);
+
+    glGetShaderiv(ids[0], GL_COMPILE_STATUS, &res);
+    if (res != GL_TRUE)
+    {
+        glGetShaderiv(ids[0], GL_INFO_LOG_LENGTH, &res);
+        if (res < 1) res = 1024;
+        char* log = new char[res+1];
+        glGetShaderInfoLog(ids[0], res+1, NULL, log);
+        printf("OpenGL: failed to compile vertex shader %s: %s\n", name, log);
+        printf("shader source:\n--\n%s\n--\n", vs);
+        delete[] log;
+
+        glDeleteShader(ids[0]);
+
+        return false;
+    }
+
+    ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
+    len = strlen(fs);
+    glShaderSource(ids[1], 1, &fs, &len);
+    glCompileShader(ids[1]);
+
+    glGetShaderiv(ids[1], GL_COMPILE_STATUS, &res);
+    if (res != GL_TRUE)
+    {
+        glGetShaderiv(ids[1], GL_INFO_LOG_LENGTH, &res);
+        if (res < 1) res = 1024;
+        char* log = new char[res+1];
+        glGetShaderInfoLog(ids[1], res+1, NULL, log);
+        printf("OpenGL: failed to compile fragment shader %s: %s\n", name, log);
+        //printf("shader source:\n--\n%s\n--\n", fs);
+        delete[] log;
+
+        glDeleteShader(ids[0]);
+        glDeleteShader(ids[1]);
+
+        return false;
+    }
+
+    ids[2] = glCreateProgram();
+    glAttachShader(ids[2], ids[0]);
+    glAttachShader(ids[2], ids[1]);
+    glLinkProgram(ids[2]);
+
+    glGetProgramiv(ids[2], GL_LINK_STATUS, &res);
+    if (res != GL_TRUE)
+    {
+        glGetProgramiv(ids[2], GL_INFO_LOG_LENGTH, &res);
+        if (res < 1) res = 1024;
+        char* log = new char[res+1];
+        glGetProgramInfoLog(ids[2], res+1, NULL, log);
+        printf("OpenGL: failed to link program %s: %s\n", name, log);
+        delete[] log;
+
+        glDeleteShader(ids[0]);
+        glDeleteShader(ids[1]);
+        glDeleteProgram(ids[2]);
+
+        return false;
+    }
+
+    return true;
+}
+
+void OpenGL_DeleteShaderProgram(GLuint* ids)
+{
+    glDeleteShader(ids[0]);
+    glDeleteShader(ids[1]);
+    glDeleteProgram(ids[2]);
+}
+
+void OpenGL_UseShaderProgram(GLuint* ids)
+{
+    glUseProgram(ids[2]);
+}
diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h
index 10ba1e5..2cee741 100644
--- a/src/OpenGLSupport.h
+++ b/src/OpenGLSupport.h
@@ -109,4 +109,8 @@ DO_PROCLIST(DECLPROC_EXT);
 
 bool OpenGL_Init();
 
+bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name);
+void OpenGL_DeleteShaderProgram(GLuint* ids);
+void OpenGL_UseShaderProgram(GLuint* ids);
+
 #endif // OPENGLSUPPORT_H
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index 67eaeda..832a2e5 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -39,7 +39,7 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor)
     memset(&pfd, 0, sizeof(pfd));
     pfd.nSize = sizeof(pfd);
     pfd.nVersion = 1;
-    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
     pfd.iPixelType = PFD_TYPE_RGBA;
     pfd.cColorBits = 24;
     pfd.cAlphaBits = 8;
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index b39f493..23e6617 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -24,6 +24,9 @@
 #include <SDL2/SDL.h>
 #include "libui/ui.h"
 
+#include "../OpenGLSupport.h"
+#include "main_shaders.h"
+
 #include "../types.h"
 #include "../version.h"
 #include "PlatformConfig.h"
@@ -97,6 +100,19 @@ bool SavestateLoaded;
 bool ScreenDrawInited = false;
 uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL};
 
+GLuint GL_ScreenShader[3];
+struct
+{
+    float uScreenSize[2];
+    u32 uFilterMode;
+
+} GL_ShaderConfig;
+GLuint GL_ShaderConfigUBO;
+GLuint GL_ScreenVertexArrayID, GL_ScreenVertexBufferID;
+float GL_ScreenVertices[2 * 3*2 * 4]; // position/texcoord
+GLuint GL_ScreenTexture;
+bool GL_ScreenSizeDirty;
+
 int ScreenScale[3];
 int ScreenScaleMode;
 
@@ -141,6 +157,204 @@ void GetSavestateName(int slot, char* filename, int len);
 
 
 
+bool GLDrawing_Init()
+{
+    if (!OpenGL_Init())
+        return false;
+
+    if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader"))
+        return false;
+
+    memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
+
+    glGenBuffers(1, &GL_ShaderConfigUBO);
+    glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW);
+    glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO);
+    glUniformBlockBinding(GL_ScreenShader[2], 0, 16);
+
+    glGenBuffers(1, &GL_ScreenVertexBufferID);
+    glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(GL_ScreenVertices), NULL, GL_STATIC_DRAW);
+
+    glGenVertexArrays(1, &GL_ScreenVertexArrayID);
+    glBindVertexArray(GL_ScreenVertexArrayID);
+    glEnableVertexAttribArray(0); // position
+    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0));
+    glEnableVertexAttribArray(1); // texcoord
+    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4));
+
+    glGenTextures(1, &GL_ScreenTexture);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL);
+
+    GL_ScreenSizeDirty = true;
+
+    return true;
+}
+
+void GLDrawing_DeInit()
+{
+    glDeleteTextures(1, &GL_ScreenTexture);
+
+    glDeleteVertexArrays(1, &GL_ScreenVertexArrayID);
+    glDeleteBuffers(1, &GL_ScreenVertexBufferID);
+
+    OpenGL_DeleteShaderProgram(GL_ScreenShader);
+}
+
+void GLDrawing_DrawScreen()
+{
+    if (GL_ScreenSizeDirty)
+    {
+        GL_ScreenSizeDirty = false;
+
+        GL_ShaderConfig.uScreenSize[0] = WindowWidth;
+        GL_ShaderConfig.uScreenSize[1] = WindowHeight;
+
+        glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO);
+        void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
+        if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig));
+        glUnmapBuffer(GL_UNIFORM_BUFFER);
+
+        float scwidth, scheight;
+        scwidth = 512;
+        scheight = 384;
+
+        float x0, y0, x1, y1;
+        float s0, s1, s2, s3;
+        float t0, t1, t2, t3;
+
+#define SETVERTEX(i, x, y, s, t) \
+    GL_ScreenVertices[4*(i) + 0] = x; \
+    GL_ScreenVertices[4*(i) + 1] = y; \
+    GL_ScreenVertices[4*(i) + 2] = s; \
+    GL_ScreenVertices[4*(i) + 3] = t;
+
+        x0 = TopScreenRect.X;
+        y0 = TopScreenRect.Y;
+        x1 = TopScreenRect.X + TopScreenRect.Width;
+        y1 = TopScreenRect.Y + TopScreenRect.Height;
+
+        switch (ScreenRotation)
+        {
+        case 0:
+            s0 = 0; t0 = 0;
+            s1 = scwidth; t1 = 0;
+            s2 = 0; t2 = scheight;
+            s3 = scwidth; t3 = scheight;
+            break;
+
+        case 1:
+            s0 = 0; t0 = scheight;
+            s1 = 0; t1 = 0;
+            s2 = scwidth; t2 = scheight;
+            s3 = scwidth; t3 = 0;
+            break;
+
+        case 2:
+            s0 = scwidth; t0 = scheight;
+            s1 = 0; t1 = scheight;
+            s2 = scwidth; t2 = 0;
+            s3 = 0; t3 = 0;
+            break;
+
+        case 3:
+            s0 = scwidth; t0 = 0;
+            s1 = scwidth; t1 = scheight;
+            s2 = 0; t2 = 0;
+            s3 = 0; t3 = scheight;
+            break;
+        }
+
+        SETVERTEX(0, x0, y0, s0, t0);
+        SETVERTEX(1, x1, y1, s3, t3);
+        SETVERTEX(2, x1, y0, s1, t1);
+        SETVERTEX(3, x0, y0, s0, t0);
+        SETVERTEX(4, x0, y1, s2, t2);
+        SETVERTEX(5, x1, y1, s3, t3);
+
+        // TODO: adjust scwidth/scheight
+
+        x0 = BottomScreenRect.X;
+        y0 = BottomScreenRect.Y;
+        x1 = BottomScreenRect.X + BottomScreenRect.Width;
+        y1 = BottomScreenRect.Y + BottomScreenRect.Height;
+
+        switch (ScreenRotation)
+        {
+        case 0:
+            s0 = 0; t0 = 768;
+            s1 = scwidth; t1 = 768;
+            s2 = 0; t2 = 768+scheight;
+            s3 = scwidth; t3 = 768+scheight;
+            break;
+
+        case 1:
+            s0 = 0; t0 = 768+scheight;
+            s1 = 0; t1 = 768;
+            s2 = scwidth; t2 = 768+scheight;
+            s3 = scwidth; t3 = 768;
+            break;
+
+        case 2:
+            s0 = scwidth; t0 = 768+scheight;
+            s1 = 0; t1 = 768+scheight;
+            s2 = scwidth; t2 = 768;
+            s3 = 0; t3 = 768;
+            break;
+
+        case 3:
+            s0 = scwidth; t0 = 768;
+            s1 = scwidth; t1 = 768+scheight;
+            s2 = 0; t2 = 768;
+            s3 = 0; t3 = 768+scheight;
+            break;
+        }
+
+        SETVERTEX(6, x0, y0, s0, t0);
+        SETVERTEX(7, x1, y1, s3, t3);
+        SETVERTEX(8, x1, y0, s1, t1);
+        SETVERTEX(9, x0, y0, s0, t0);
+        SETVERTEX(10, x0, y1, s2, t2);
+        SETVERTEX(11, x1, y1, s3, t3);
+
+#undef SETVERTEX
+
+        glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
+        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices);
+    }
+
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_BLEND);
+
+    glViewport(0, 0, WindowWidth, WindowHeight);
+
+    OpenGL_UseShaderProgram(GL_ScreenShader);
+
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    glClearColor(0, 1, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    int frontbuf = GPU::FrontBuffer;
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 512, 384, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 512, 384, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
+
+    glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
+    glBindVertexArray(GL_ScreenVertexArrayID);
+    glDrawArrays(GL_TRIANGLES, 0, 4*3);
+
+    uiGLSwapBuffers(GLContext);
+    uiAreaQueueRedrawAll(MainDrawArea);
+}
+
 void MicLoadWav(char* name)
 {
     SDL_AudioSpec format;
@@ -397,6 +611,8 @@ void FeedMicInput()
 int EmuThreadFunc(void* burp)
 {
     uiGLMakeContextCurrent(GLContext);
+    GLDrawing_Init();
+
     NDS::Init();
 
     MainScreenPos[0] = 0;
@@ -567,7 +783,9 @@ int EmuThreadFunc(void* burp)
 
             if (EmuRunning == 0) break;
 
-            uiAreaQueueRedrawAll(MainDrawArea);
+            GLDrawing_DrawScreen();
+
+            //uiAreaQueueRedrawAll(MainDrawArea);
             //uiGLSwapBuffers(GLContext);
 
             // framerate limiter based off SDL2_gfx
@@ -622,6 +840,7 @@ int EmuThreadFunc(void* burp)
             {
                 //uiAreaQueueRedrawAll(MainDrawArea);
                 //uiGLSwapBuffers(GLContext);
+                GLDrawing_DrawScreen();
             }
 
             EmuStatus = EmuRunning;
@@ -637,6 +856,8 @@ int EmuThreadFunc(void* burp)
     NDS::DeInit();
     Platform::LAN_DeInit();
 
+    GLDrawing_DeInit();
+
     return 44203;
 }
 
@@ -1058,6 +1279,8 @@ void SetupScreenRects(int width, int height)
         }
         break;
     }
+
+    GL_ScreenSizeDirty = true;
 }
 
 void SetMinSize(int w, int h)
@@ -2063,7 +2286,7 @@ int main(int argc, char** argv)
     areahandler.Resize = OnAreaResize;
 
     ScreenDrawInited = false;
-    MainDrawArea = uiNewArea(&areahandler, 0);
+    MainDrawArea = uiNewArea(&areahandler, 1);
     uiWindowSetChild(MainWindow, uiControl(MainDrawArea));
     uiControlSetMinSize(uiControl(MainDrawArea), 256, 384);
     uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable?
diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h
new file mode 100644
index 0000000..dcf79d9
--- /dev/null
+++ b/src/libui_sdl/main_shaders.h
@@ -0,0 +1,72 @@
+/*
+    Copyright 2016-2019 Arisotura
+
+    This file is part of melonDS.
+
+    melonDS is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef MAIN_SHADERS_H
+#define MAIN_SHADERS_H
+
+const char* kScreenVS = R"(#version 420
+
+layout(std140, binding=0) uniform uConfig
+{
+    vec2 uScreenSize;
+    uint uFilterMode;
+};
+
+layout(location=0) in vec2 vPosition;
+layout(location=1) in vec2 vTexcoord;
+
+smooth out vec2 fTexcoord;
+
+void main()
+{
+    vec4 fpos;
+    fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0;
+    fpos.y *= -1;
+    fpos.z = 0.0;
+    fpos.w = 1.0;
+
+    gl_Position = fpos;
+    fTexcoord = vTexcoord;
+}
+)";
+
+const char* kScreenFS = R"(#version 420
+
+layout(std140, binding=0) uniform uConfig
+{
+    vec2 uScreenSize;
+    uint uFilterMode;
+};
+
+layout(binding=0) uniform usampler2D ScreenTex;
+
+smooth in vec2 fTexcoord;
+
+layout(location=0) out vec4 oColor;
+
+void main()
+{
+    uvec4 pixel = texelFetch(ScreenTex, ivec2(fTexcoord), 0);
+
+    // TODO: filters
+
+    oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0);
+}
+)";
+
+#endif // MAIN_SHADERS_H
-- 
cgit v1.2.3


From c835b24f07a317ea435b742ec2fae12dc619c01b Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Tue, 21 May 2019 14:53:22 +0200
Subject: modify libui GL support so that it will be compatible with GTK

---
 melonDS.cbp                          |  4 +--
 src/libui_sdl/DlgInputConfig.cpp     |  2 +-
 src/libui_sdl/libui/ui.h             | 11 +++++--
 src/libui_sdl/libui/windows/area.cpp | 56 ++++++++++++++++++++++++++++++++++--
 src/libui_sdl/libui/windows/area.hpp |  5 ++++
 src/libui_sdl/libui/windows/gl.cpp   | 33 ++++++++++-----------
 src/libui_sdl/main.cpp               | 37 ++++++++++--------------
 7 files changed, 101 insertions(+), 47 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/melonDS.cbp b/melonDS.cbp
index 0bdac7f..bb4d8c7 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -106,8 +106,8 @@
 		<Unit filename="src/GPU2D.h" />
 		<Unit filename="src/GPU3D.cpp" />
 		<Unit filename="src/GPU3D.h" />
-		<Unit filename="src/GPU3D_OpenGL43.cpp" />
-		<Unit filename="src/GPU3D_OpenGL43_shaders.h" />
+		<Unit filename="src/GPU3D_OpenGL.cpp" />
+		<Unit filename="src/GPU3D_OpenGL_shaders.h" />
 		<Unit filename="src/GPU3D_Soft.cpp" />
 		<Unit filename="src/NDS.cpp" />
 		<Unit filename="src/NDS.h" />
diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp
index 4c464f1..513bd90 100644
--- a/src/libui_sdl/DlgInputConfig.cpp
+++ b/src/libui_sdl/DlgInputConfig.cpp
@@ -432,7 +432,7 @@ void Open(int type)
         uiLabel* dummy = uiNewLabel("");
         uiBoxAppend(in_ctrl, uiControl(dummy), 1);
 
-        dlg->keypresscatcher = uiNewArea(&dlg->areahandler, 0);
+        dlg->keypresscatcher = uiNewArea(&dlg->areahandler);
         uiControl(dlg->keypresscatcher)->UserData = dlg;
         uiBoxAppend(in_ctrl, uiControl(dlg->keypresscatcher), 0);
 
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index 2641f30..09092a1 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -326,6 +326,10 @@ _UI_ENUM(uiWindowResizeEdge) {
 	// TODO way to bring up the system menu instead?
 };
 
+#define uiGLVersion(major, minor)  ((major) | ((minor)<<16))
+#define uiGLVerMajor(ver)          ((ver) & 0xFFFF)
+#define uiGLVerMinor(ver)          ((ver) >> 16)
+
 #define uiArea(this) ((uiArea *) (this))
 // TODO give a better name
 // TODO document the types of width and height
@@ -341,7 +345,8 @@ _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, doub
 _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a);
 _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);
 _UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b);
-_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah, int opengl);
+_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah);
+_UI_EXTERN uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions);
 _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);
 
 struct uiAreaDrawParams {
@@ -604,9 +609,9 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou
 
 typedef struct uiGLContext uiGLContext;
 
-_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor);
-_UI_EXTERN void uiGLFreeContext(uiGLContext* ctx);
+_UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
+_UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
 _UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx);
 
diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp
index 99c843e..72d5145 100644
--- a/src/libui_sdl/libui/windows/area.cpp
+++ b/src/libui_sdl/libui/windows/area.cpp
@@ -61,7 +61,15 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
 
 // control implementation
 
-uiWindowsControlAllDefaults(uiArea)
+uiWindowsControlAllDefaultsExceptDestroy(uiArea)
+
+static void uiAreaDestroy(uiControl *c)
+{
+    uiArea* a = uiArea(c);
+    if (a->openGL && a->glcontext) freeGLContext(a->glcontext);
+    uiWindowsEnsureDestroyWindow(a->hwnd);
+    uiFreeControl(c);
+}
 
 static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height)
 {
@@ -181,7 +189,7 @@ void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b)
 }
 
 
-uiArea *uiNewArea(uiAreaHandler *ah, int opengl)
+uiArea *uiNewArea(uiAreaHandler *ah)
 {
 	uiArea *a;
 
@@ -203,7 +211,49 @@ uiArea *uiNewArea(uiAreaHandler *ah, int opengl)
 
     uiAreaSetBackgroundColor(a, -1, -1, -1);
 
-    a->openGL = opengl;
+    a->openGL = 0;
+
+	return a;
+}
+
+uiGLContext *uiAreaGetGLContext(uiArea* a)
+{
+    if (!a->openGL) userbug("trying to get GL context from non-GL area");
+
+    return a->glcontext;
+}
+
+uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
+{
+	uiArea *a;
+
+	uiWindowsNewControl(uiArea, a);
+
+	a->width = -1;
+	a->height = -1;
+
+	a->ah = ah;
+	a->scrolling = FALSE;
+	clickCounterReset(&(a->cc));
+
+	// a->hwnd is assigned in areaWndProc()
+	uiWindowsEnsureCreateControlHWND(0,
+		areaClass, L"",
+		0,
+		hInstance, a,
+		FALSE);
+
+    uiAreaSetBackgroundColor(a, -1, -1, -1);
+
+    a->openGL = 1;
+
+    for (int i = 0; req_versions[i]; i++)
+    {
+        int major = uiGLVerMajor(req_versions[i]);
+        int minor = uiGLVerMinor(req_versions[i]);
+        a->glcontext = createGLContext(a, major, minor);
+        if (a->glcontext) break;
+    }
 
 	return a;
 }
diff --git a/src/libui_sdl/libui/windows/area.hpp b/src/libui_sdl/libui/windows/area.hpp
index f8abd4f..cfc45a4 100644
--- a/src/libui_sdl/libui/windows/area.hpp
+++ b/src/libui_sdl/libui/windows/area.hpp
@@ -29,6 +29,7 @@ struct uiArea {
 	int bgR, bgG, bgB;
 
 	int openGL;
+	uiGLContext* glcontext;
 
 	ID2D1HwndRenderTarget *rt;
 };
@@ -49,3 +50,7 @@ extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRE
 extern void loadAreaSize(uiArea *a, double *width, double *height);
 extern void pixelsToDIP(uiArea *a, double *x, double *y);
 extern void dipToPixels(uiArea *a, double *x, double *y);
+
+// gl.cpp
+extern uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor);
+extern void freeGLContext(uiGLContext* c);
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index 832a2e5..1e3732c 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -1,39 +1,31 @@
 // 31 march 2019
 #include "uipriv_windows.hpp"
+#include "area.hpp"
 
 #include <GL/gl.h>
 #include <GL/wglext.h>
 
 struct uiGLContext
 {
-    uiControl* c;
+    uiArea* a;
 
     HWND hwnd;
     HDC dc;
     HGLRC rc;
+
+    unsigned int version;
 };
 
 
-uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor)
+uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor)
 {
     uiGLContext* ctx;
     BOOL res;
 
     ctx = uiNew(uiGLContext);
 
-    ctx->c = c;
-    if (c)
-    {
-        ctx->hwnd = (HWND)c->Handle(c); // welp
-    }
-    else
-    {
-        // windowless context
-        //ctx->hwnd = GetDesktopWindow();
-        // nope.
-        uiFree(ctx);
-        return NULL;
-    }
+    ctx->a = a;
+    ctx->hwnd = a->hwnd;
 
     PIXELFORMATDESCRIPTOR pfd;
     memset(&pfd, 0, sizeof(pfd));
@@ -103,6 +95,7 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor)
             return NULL;
         }
 
+        ctx->version = uiGLVersion(vermajor, verminor);
         ctx->rc = rc_better;
         wglMakeCurrent(ctx->dc, ctx->rc);
     }
@@ -110,8 +103,9 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor)
     return ctx;
 }
 
-void uiGLFreeContext(uiGLContext* ctx)
+void freeGLContext(uiGLContext* ctx)
 {
+    if (ctx == NULL) return;
     wglMakeCurrent(NULL, NULL);
     wglDeleteContext(ctx->rc);
     ReleaseDC(ctx->hwnd, ctx->dc);
@@ -130,6 +124,12 @@ void uiGLMakeContextCurrent(uiGLContext* ctx)
     int res = wglMakeCurrent(ctx->dc, ctx->rc);
 }
 
+unsigned int uiGLGetVersion(uiGLContext* ctx)
+{
+    if (ctx == NULL) return 0;
+    return ctx->version;
+}
+
 void *uiGLGetProcAddress(const char* proc)
 {
     return (void*)wglGetProcAddress(proc);
@@ -137,5 +137,6 @@ void *uiGLGetProcAddress(const char* proc)
 
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
+    if (ctx == NULL) return;
     SwapBuffers(ctx->dc);
 }
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index c68f323..b499da7 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -64,6 +64,9 @@ char* EmuDirectory;
 
 uiWindow* MainWindow;
 uiArea* MainDrawArea;
+uiAreaHandler MainDrawAreaHandler;
+
+const u32 kGLVersions[] = {uiGLVersion(3,1), 0};
 uiGLContext* GLContext;
 
 int WindowWidth, WindowHeight;
@@ -1792,7 +1795,7 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg)
 {
     DlgInputConfig::Open(1);
 }
-uiAreaHandler eeareahandler;
+
 void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg)
 {
     //DlgVideoSettings::Open();
@@ -1805,25 +1808,17 @@ void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg)
     GPU3D::GLRenderer::DeInit();
     GLDrawing_DeInit();
     uiGLMakeContextCurrent(NULL);
-    uiGLFreeContext(GLContext);
 
     uiWindowSetChild(MainWindow, NULL);
     uiControlDestroy(uiControl(MainDrawArea));
 
 
-    eeareahandler.Draw = OnAreaDraw;
-    eeareahandler.MouseEvent = OnAreaMouseEvent;
-    eeareahandler.MouseCrossed = OnAreaMouseCrossed;
-    eeareahandler.DragBroken = OnAreaDragBroken;
-    eeareahandler.KeyEvent = OnAreaKeyEvent;
-    eeareahandler.Resize = OnAreaResize;
-
-    MainDrawArea = uiNewArea(&eeareahandler, 1);
+    MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions);
     uiWindowSetChild(MainWindow, uiControl(MainDrawArea));
     uiControlSetMinSize(uiControl(MainDrawArea), 256, 384);
     uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0);
     //uiControlShow(uiControl(MainDrawArea));
-    GLContext = uiGLNewContext(uiControl(MainDrawArea), 3, 1);
+    GLContext = uiAreaGetGLContext(MainDrawArea);
 
     uiGLMakeContextCurrent(GLContext);
     GLDrawing_Init();
@@ -2343,16 +2338,16 @@ int main(int argc, char** argv)
     uiMenuItemDisable(MenuItem_Reset);
     uiMenuItemDisable(MenuItem_Stop);
 
-    uiAreaHandler areahandler;
-    areahandler.Draw = OnAreaDraw;
-    areahandler.MouseEvent = OnAreaMouseEvent;
-    areahandler.MouseCrossed = OnAreaMouseCrossed;
-    areahandler.DragBroken = OnAreaDragBroken;
-    areahandler.KeyEvent = OnAreaKeyEvent;
-    areahandler.Resize = OnAreaResize;
+    MainDrawAreaHandler.Draw = OnAreaDraw;
+    MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent;
+    MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed;
+    MainDrawAreaHandler.DragBroken = OnAreaDragBroken;
+    MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent;
+    MainDrawAreaHandler.Resize = OnAreaResize;
 
     ScreenDrawInited = false;
-    MainDrawArea = uiNewArea(&areahandler, 1);
+    //MainDrawArea = uiNewArea(&MainDrawAreaHandler);
+    MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions);
     uiWindowSetChild(MainWindow, uiControl(MainDrawArea));
     uiControlSetMinSize(uiControl(MainDrawArea), 256, 384);
     uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable?
@@ -2383,7 +2378,7 @@ int main(int argc, char** argv)
     OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]);
 
     // TODO: fail gracefully, support older OpenGL, etc
-    GLContext = uiGLNewContext(uiControl(MainDrawArea), 3, 1); // haw haw haw
+    GLContext = uiAreaGetGLContext(MainDrawArea);
     uiGLMakeContextCurrent(GLContext);
 
     void* testor = uiGLGetProcAddress("glUseProgram");
@@ -2472,8 +2467,6 @@ int main(int argc, char** argv)
 
     if (MicWavBuffer) delete[] MicWavBuffer;
 
-    uiGLFreeContext(GLContext);
-
     Config::ScreenRotation = ScreenRotation;
     Config::ScreenGap = ScreenGap;
     Config::ScreenLayout = ScreenLayout;
-- 
cgit v1.2.3


From e5236f0cdec4f3a29a8748f65ca49fee3fb54c03 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Thu, 23 May 2019 22:50:46 +0200
Subject: add API for getting/setting window size

bahahahaaa
---
 src/libui_sdl/libui/ui.h               |  2 ++
 src/libui_sdl/libui/windows/window.cpp | 15 +++++++++++++++
 src/libui_sdl/main.cpp                 |  3 +++
 3 files changed, 20 insertions(+)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index 09092a1..5b163af 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -108,6 +108,8 @@ typedef struct uiWindow uiWindow;
 #define uiWindow(this) ((uiWindow *) (this))
 _UI_EXTERN char *uiWindowTitle(uiWindow *w);
 _UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title);
+_UI_EXTERN void uiWindowPosition(uiWindow *w, int *x, int *y);
+_UI_EXTERN void uiWindowSetPosition(uiWindow *w, int x, int y);
 _UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height);
 _UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height);
 _UI_EXTERN int uiWindowMinimized(uiWindow *w);
diff --git a/src/libui_sdl/libui/windows/window.cpp b/src/libui_sdl/libui/windows/window.cpp
index f52e2f6..18d1171 100644
--- a/src/libui_sdl/libui/windows/window.cpp
+++ b/src/libui_sdl/libui/windows/window.cpp
@@ -363,6 +363,21 @@ static void windowMonitorRect(HWND hwnd, RECT *r)
 	*r = mi.rcMonitor;
 }
 
+void uiWindowPosition(uiWindow *w, int *x, int *y)
+{
+    RECT rect;
+    if (GetWindowRect(w->hwnd, &rect) == 0)
+        logLastError(L"error getting window position");
+    *x = rect.left;
+    *y = rect.top;
+}
+
+void uiWindowSetPosition(uiWindow *w, int x, int y)
+{
+    if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0)
+        logLastError(L"error moving window");
+}
+
 void uiWindowContentSize(uiWindow *w, int *width, int *height)
 {
 	RECT r;
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 9f92595..1f41bbe 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -1859,9 +1859,12 @@ void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg)
     EmuRunning = 3;
     while (EmuStatus != 3);
 
+    int winX, winY;
+    uiWindowPosition(MainWindow, &winX, &winY);
     uiControlDestroy(uiControl(window));
 
     zarg();
+    uiWindowSetPosition(MainWindow, winX, winY);
 
     EmuRunning = zerp;
 }
-- 
cgit v1.2.3


From 38f61a24fcdf5a78cbabc9184f55ded3b496f1d4 Mon Sep 17 00:00:00 2001
From: PoroCYon <pcy@national.shitposting.agency>
Date: Sun, 26 May 2019 00:38:24 +0200
Subject: 'port' libui GL stuff to Linux

Only implemented the functions needed by melonDS, and only tested using
a very recent mesa+libglvnd+nouveau. Will most likely bork using
proprietary nvidia or old(er) drivers (see gl.c)
---
 src/libui_sdl/libui/unix/CMakeLists.txt |  1 +
 src/libui_sdl/libui/unix/area.c         | 41 ++++++++++++++++++++++++++++
 src/libui_sdl/libui/unix/gl.c           | 47 +++++++++++++++++++++++++++++++++
 src/libui_sdl/libui/unix/uipriv_unix.h  |  6 ++++-
 src/libui_sdl/libui/unix/window.c       | 18 +++++++++++++
 5 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 src/libui_sdl/libui/unix/gl.c

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt
index 9300bcb..ec9ab75 100644
--- a/src/libui_sdl/libui/unix/CMakeLists.txt
+++ b/src/libui_sdl/libui/unix/CMakeLists.txt
@@ -43,6 +43,7 @@ list(APPEND _LIBUI_SOURCES
 	unix/text.c
 	unix/util.c
 	unix/window.c
+	unix/gl.c
 )
 set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
 
diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index 2da9bab..e518ae5 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -38,7 +38,10 @@ struct uiArea {
 
 	GtkWidget *areaWidget;
 	GtkDrawingArea *drawingArea;
+	GtkGLArea *glArea;
 	areaWidget *area;
+
+	GdkGLContext *glContext;
 	
 	int bgR, bgG, bgB;
 
@@ -730,6 +733,44 @@ uiArea *uiNewArea(uiAreaHandler *ah)
 	return a;
 }
 
+uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
+{
+	uiArea *a;
+
+	uiUnixNewControl(uiArea, a);
+
+	a->ah = ah;
+	a->scrolling = FALSE;
+
+	GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
+	GdkGLContext* ctx = NULL;
+
+	for (int i = 0; req_versions[i] && !ctx; i++) {
+		int major = uiGLVerMajor(req_versions[i]);
+		int minor = uiGLVerMinor(req_versions[i]);
+		gtk_gl_area_set_required_version(gla, major, minor);
+		ctx = createGLContext(gla, major, minor);
+	}
+
+	a->glContext = ctx;
+	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area",
+				a, NULL));
+	a->glArea = gla;
+	a->area = areaWidget(a->areaWidget);
+
+	a->widget = a->areaWidget;
+
+	uiAreaSetBackgroundColor(a, -1, -1, -1);
+
+	return a;
+}
+
+uiGLContext *uiAreaGetGLContext(uiArea* a)
+{
+	if (!a) return NULL;
+	return a->glContext;
+}
+
 uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
 {
 	uiArea *a;
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
new file mode 100644
index 0000000..da41437
--- /dev/null
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -0,0 +1,47 @@
+// 26 may 2019
+#include "uipriv_unix.h"
+
+/*
+ *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed
+
+(melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget'
+ */
+
+struct uiGLContext {
+	GtkGLArea *gla;
+	GdkGLContext *gctx;
+	int vermaj, vermin;
+};
+
+uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min)
+{
+	uiGLContext *ret = uiAlloc(sizeof(uiGLContext), "uiGLContext");
+	ret->gla = gla;
+	ret->gctx = gtk_gl_area_get_context(gla);
+	ret->vermaj = maj; ret->vermin = min;
+	return ret;
+}
+
+void uiGLSwapBuffers(uiGLContext* ctx)
+{
+	if (!ctx) return;
+	gtk_gl_area_attach_buffers(ctx->gla);
+}
+
+void uiGLMakeContextCurrent(uiGLContext* ctx)
+{
+	if (!ctx) return;
+	gtk_gl_area_make_current(ctx->gla);
+}
+void *uiGLGetProcAddress(const char* proc)
+{
+	// this *will* break for older systems that don't have libglvnd!
+	// TODO: use a real solution
+	return dlsym(NULL /* RTLD_DEFAULT */, proc);
+}
+unsigned int uiGLGetVersion(uiGLContext* ctx)
+{
+	if (!ctx) return 0;
+	return uiGLVersion(ctx->vermaj, ctx->vermin);
+}
+
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
index 33ff1e3..42d5d76 100644
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ b/src/libui_sdl/libui/unix/uipriv_unix.h
@@ -5,7 +5,7 @@
 #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10
 #include <gtk/gtk.h>
 #include <math.h>
-#include <dlfcn.h>		// see drawtext.c
+#include <dlfcn.h>		// see drawtext.c, gl.c
 #include <langinfo.h>
 #include <string.h>
 #include <stdlib.h>
@@ -63,3 +63,7 @@ extern GtkCellRenderer *newCellRendererButton(void);
 extern void loadFutures(void);
 extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha);
 extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name);
+
+// gl.c
+extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min);
+
diff --git a/src/libui_sdl/libui/unix/window.c b/src/libui_sdl/libui/unix/window.c
index 7da1134..6d5e2de 100644
--- a/src/libui_sdl/libui/unix/window.c
+++ b/src/libui_sdl/libui/unix/window.c
@@ -102,6 +102,23 @@ static void uiWindowDestroy(uiControl *c)
 	uiFreeControl(uiControl(w));
 }
 
+void uiWindowSetPosition(uiWindow *w, int x, int y)
+{
+	if (!w) return;
+
+	gtk_window_move(w->window, x, y);
+}
+
+void uiWindowPosition(uiWindow *w, int *x, int *y)
+{
+	if (!w) return;
+
+	int xx, yy;
+	gtk_window_get_position(w->window, &xx, &yy);
+	if (x) *x = xx;
+	if (y) *y = yy;
+}
+
 uiUnixControlDefaultHandle(uiWindow)
 
 uiControl *uiWindowParent(uiControl *c)
@@ -442,3 +459,4 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int maximized, i
 
 	return w;
 }
+
-- 
cgit v1.2.3


From ebad773a3881f31ab668cc0cbea89cc34f5cd2b7 Mon Sep 17 00:00:00 2001
From: PoroCYon <pcy@national.shitposting.agency>
Date: Sun, 26 May 2019 00:46:35 +0200
Subject: apply tgsm's changes (see PR #411 )

---
 src/CMakeLists.txt                         | 2 +-
 src/libui_sdl/libui/windows/CMakeLists.txt | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 72ae4bf..702edf5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,7 +28,7 @@ add_library(core STATIC
 )
 
 if (WIN32)
-	target_link_libraries(core ole32 comctl32 ws2_32)
+	target_link_libraries(core ole32 comctl32 ws2_32 opengl32)
 else()
 	target_link_libraries(core OpenGL)
 endif()
diff --git a/src/libui_sdl/libui/windows/CMakeLists.txt b/src/libui_sdl/libui/windows/CMakeLists.txt
index 4695eb4..9d5313a 100644
--- a/src/libui_sdl/libui/windows/CMakeLists.txt
+++ b/src/libui_sdl/libui/windows/CMakeLists.txt
@@ -29,6 +29,7 @@ list(APPEND _LIBUI_SOURCES
 	windows/fontbutton.cpp
 	windows/fontdialog.cpp
 	windows/form.cpp
+	windows/gl.cpp
 	windows/graphemes.cpp
 	windows/grid.cpp
 	windows/group.cpp
-- 
cgit v1.2.3


From 891ab9fd3c91042d5097f38107cccfb47511e5e5 Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Tue, 28 May 2019 19:48:59 +0200
Subject: Linux: start getting somewhere with the whole OpenGL shito

---
 CMakeLists.txt                  |   5 +-
 src/CMakeLists.txt              |   7 +-
 src/OpenGLSupport.cpp           |   1 -
 src/OpenGLSupport.h             |   1 +
 src/libui_sdl/CMakeLists.txt    |   2 +-
 src/libui_sdl/libui/ui.h        |   2 +
 src/libui_sdl/libui/unix/area.c |  83 ++++++---
 src/libui_sdl/libui/unix/gl.c   | 391 +++++++++++++++++++++++++++++++++++++++-
 src/libui_sdl/main.cpp          |  46 +++--
 9 files changed, 489 insertions(+), 49 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9aa96ad..c127af5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,9 +21,12 @@ else()
 endif()
 
 if(ENABLE_LTO)
-	add_compile_options(-flto)
+	add_compile_options(-O2 -flto)
 endif()
 
+add_compile_options(-fno-pic)
+add_link_options(-no-pie)
+
 option(BUILD_LIBUI "Build libui frontend" ON)
 option(BUILD_SDL "Build SDL2 frontend" OFF)
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 702edf5..d096c02 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,22 +13,21 @@ add_library(core STATIC
 	GPU.cpp
 	GPU2D.cpp
 	GPU3D.cpp
+	GPU3D_OpenGL.cpp
 	GPU3D_Soft.cpp
 	NDS.cpp
 	NDSCart.cpp
+	OpenGLSupport.cpp
 	RTC.cpp
 	Savestate.cpp
 	SPI.cpp
 	SPU.cpp
 	Wifi.cpp
 	WifiAP.cpp
-	# opengl backend stuff
-	GPU3D_OpenGL.cpp
-	OpenGLSupport.cpp
 )
 
 if (WIN32)
 	target_link_libraries(core ole32 comctl32 ws2_32 opengl32)
 else()
-	target_link_libraries(core OpenGL)
+	target_link_libraries(core GL)
 endif()
diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp
index bb9e180..11fd629 100644
--- a/src/OpenGLSupport.cpp
+++ b/src/OpenGLSupport.cpp
@@ -18,7 +18,6 @@
 
 #include "OpenGLSupport.h"
 
-#include <cstring>
 
 
 DO_PROCLIST(DECLPROC);
diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h
index 3f21a4c..239ae95 100644
--- a/src/OpenGLSupport.h
+++ b/src/OpenGLSupport.h
@@ -20,6 +20,7 @@
 #define OPENGLSUPPORT_H
 
 #include <stdio.h>
+#include <string.h>
 #include <GL/gl.h>
 #include <GL/glext.h>
 
diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt
index 0b7545b..61e0981 100644
--- a/src/libui_sdl/CMakeLists.txt
+++ b/src/libui_sdl/CMakeLists.txt
@@ -47,7 +47,7 @@ if (UNIX)
 				--generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml")
 
 	if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
-		target_link_libraries(melonDS dl)
+		target_link_libraries(melonDS dl X11)
 	endif ()
 
 	target_sources(melonDS PUBLIC melon_grc.c)
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index d2e9960..0c89d90 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -615,6 +615,8 @@ _UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
 _UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
+_UI_EXTERN int uiGLGetFramebuffer(uiGLContext* ctx);
+_UI_EXTERN float uiGLGetFramebufferScale(uiGLContext* ctx);
 _UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx);
 
 
diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index e518ae5..bf92ddf 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -28,6 +28,8 @@ struct areaWidgetClass {
 	GtkDrawingAreaClass parent_class;
 };
 
+typedef struct uiGLContext uiGLContext;
+
 struct uiArea {
 	uiUnixControl c;
 	GtkWidget *widget;		// either swidget or areaWidget depending on whether it is scrolling
@@ -41,7 +43,8 @@ struct uiArea {
 	GtkGLArea *glArea;
 	areaWidget *area;
 
-	GdkGLContext *glContext;
+    gboolean opengl;
+	uiGLContext *glContext;
 	
 	int bgR, bgG, bgB;
 
@@ -125,6 +128,8 @@ static void loadAreaSize(uiArea *a, double *width, double *height)
 	}
 }
 
+void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
+
 static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 {
 	areaWidget *aw = areaWidget(w);
@@ -136,21 +141,28 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 
 	loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight));
 
-	cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1);
-	dp.ClipX = clipX0;
-	dp.ClipY = clipY0;
-	dp.ClipWidth = clipX1 - clipX0;
-	dp.ClipHeight = clipY1 - clipY0;
-	
-	if (a->bgR != -1)
+    if (!a->opengl)
+    {
+	    cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1);
+	    dp.ClipX = clipX0;
+	    dp.ClipY = clipY0;
+	    dp.ClipWidth = clipX1 - clipX0;
+	    dp.ClipHeight = clipY1 - clipY0;
+	    
+	    if (a->bgR != -1)
+	    {
+	        cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0);
+	        cairo_paint(cr);
+	    }
+
+	    // no need to save or restore the graphics state to reset transformations; GTK+ does that for us
+	    (*(a->ah->Draw))(a->ah, a, &dp);
+	}
+	else
 	{
-	    cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0);
-	    cairo_paint(cr);
+	    areaDrawGL(w, &dp, cr, a->glContext);
 	}
 
-	// no need to save or restore the graphics state to reset transformations; GTK+ does that for us
-	(*(a->ah->Draw))(a->ah, a, &dp);
-
 	freeContext(dp.Context);
 	return FALSE;
 }
@@ -714,11 +726,12 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge)
 uiArea *uiNewArea(uiAreaHandler *ah)
 {
 	uiArea *a;
-
+printf("create regular area\n");
 	uiUnixNewControl(uiArea, a);
 
 	a->ah = ah;
 	a->scrolling = FALSE;
+	a->opengl = FALSE;
 
 	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
 		"libui-area", a,
@@ -733,35 +746,54 @@ uiArea *uiNewArea(uiAreaHandler *ah)
 	return a;
 }
 
+uiGLContext* FARTOMATIC(int major, int minor);
+void databotte(GtkWidget* gla, uiGLContext* ctx);
+void majoricc(GtkWidget* widget, gpointer data)
+{
+    printf("ACTUALLY CREATE CONTEXT\n");
+    
+    uiArea* a = (uiArea*)data;
+    uiGLContext* ctx = a->glContext;
+    
+    databotte(a->widget, ctx);
+}
+
 uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
 {
 	uiArea *a;
-
+printf("create glarea\n");
 	uiUnixNewControl(uiArea, a);
 
 	a->ah = ah;
 	a->scrolling = FALSE;
+	a->opengl = TRUE;
 
-	GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
-	GdkGLContext* ctx = NULL;
-
+	//GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
+	uiGLContext* ctx = NULL;
+printf("create sdfsf\n");
 	for (int i = 0; req_versions[i] && !ctx; i++) {
 		int major = uiGLVerMajor(req_versions[i]);
 		int minor = uiGLVerMinor(req_versions[i]);
-		gtk_gl_area_set_required_version(gla, major, minor);
-		ctx = createGLContext(gla, major, minor);
+		//gtk_gl_area_set_required_version(gla, major, minor);
+		//ctx = createGLContext(gla, major, minor);
+		ctx = FARTOMATIC(major, minor);
 	}
-
+printf("create jfghjjgh: %p\n", ctx);
 	a->glContext = ctx;
-	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area",
-				a, NULL));
-	a->glArea = gla;
+	//a->areaWidget = GTK_WIDGET(gla);
+	//a->glArea = gla;
+	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
+		"libui-area", a,
+		NULL));
 	a->area = areaWidget(a->areaWidget);
 
 	a->widget = a->areaWidget;
+	
+	g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a);
 
 	uiAreaSetBackgroundColor(a, -1, -1, -1);
-
+	//printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
+printf("create qssssq\n");
 	return a;
 }
 
@@ -781,6 +813,7 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
 	a->scrolling = TRUE;
 	a->scrollWidth = width;
 	a->scrollHeight = height;
+	a->opengl = FALSE;
 
 	a->swidget = gtk_scrolled_window_new(NULL, NULL);
 	a->scontainer = GTK_CONTAINER(a->swidget);
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index da41437..3504d3a 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -1,6 +1,12 @@
 // 26 may 2019
 #include "uipriv_unix.h"
 
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+extern GThread* gtkthread;
+
 /*
  *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed
 
@@ -9,32 +15,409 @@
 
 struct uiGLContext {
 	GtkGLArea *gla;
+	GtkWidget* widget;
+	GdkWindow* window;
 	GdkGLContext *gctx;
+	
+	Display* xdisp;
+	GLXPixmap glxpm;
+	GLXContext glxctx;
 	int vermaj, vermin;
+	
+	int width, height;
+	int scale;
+	GLuint renderbuffer[2];
+	GLuint framebuffer;
 };
 
+static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers;
+static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers;
+static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer;
+static PFNGLRENDERBUFFERSTORAGEPROC _glRenderbufferStorage;
+static PFNGLGETRENDERBUFFERPARAMETERIVPROC _glGetRenderbufferParameteriv;
+
+static PFNGLGENRENDERBUFFERSPROC _glGenFramebuffers;
+static PFNGLDELETERENDERBUFFERSPROC _glDeleteFramebuffers;
+static PFNGLBINDRENDERBUFFERPROC _glBindFramebuffer;
+static PFNGLFRAMEBUFFERTEXTUREPROC _glFramebufferTexture;
+static PFNGLFRAMEBUFFERRENDERBUFFERPROC _glFramebufferRenderbuffer;
+static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus;
+
+static int _procsLoaded = 0;
+
+static void _loadGLProcs()
+{
+    if (_procsLoaded) return;
+    
+    _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)uiGLGetProcAddress("glGenRenderbuffers");
+    _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)uiGLGetProcAddress("glDeleteRenderbuffers");
+    _glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)uiGLGetProcAddress("glBindRenderbuffer");
+    _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)uiGLGetProcAddress("glRenderbufferStorage");
+    _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)uiGLGetProcAddress("glGetRenderbufferParameteriv");
+    
+    _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)uiGLGetProcAddress("glGenFramebuffers");
+    _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)uiGLGetProcAddress("glDeleteFramebuffers");
+    _glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)uiGLGetProcAddress("glBindFramebuffer");
+    _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)uiGLGetProcAddress("glFramebufferTexture");
+    _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)uiGLGetProcAddress("glFramebufferRenderbuffer");
+    _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus");
+    
+    _procsLoaded = 1;
+}
+
+Display* derp;
+
 uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min)
 {
-	uiGLContext *ret = uiAlloc(sizeof(uiGLContext), "uiGLContext");
+    printf("barp\n");
+	uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext");
+	
+	// herp
+	ret->gla = gla;
+	ret->gctx = NULL;
+	//while (!ret->gctx)
+	/*{
+	gtk_widget_realize(GTK_WIDGET(gla));
+	printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
 	ret->gla = gla;
 	ret->gctx = gtk_gl_area_get_context(gla);
+	printf("context: %p\n", ret->gctx);
+	}*/
+	
+	
+	
+	/*
+	GtkAllocation allocation;
+    GdkWindow *window;
+    Display *display;
+    int id;
+
+    window = gtk_widget_get_window(widget);
+    display = gdk_x11_display_get_xdisplay(gdk_window_get_display(window));
+    id = gdk_x11_window_get_xid(window);
+
+    if (glXMakeCurrent(display, id, context) == TRUE) {*/
+    
+    
+    /*GdkWindow* window;
+    Display* disp;
+    
+    window = gtk_widget_get_window(GTK_WIDGET(gla));
+    display = */
+	
+	
+	
 	ret->vermaj = maj; ret->vermin = min;
 	return ret;
 }
 
+static void areaAllocRenderbuffer(uiGLContext* glctx);
+
+void databotte(GtkWidget* widget, uiGLContext* ctx)
+{
+    /*printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
+	ctx->gctx = gtk_gl_area_get_context(gla);
+	printf("context: %p\n", ctx->gctx);*/
+	
+	printf("DATABOTTE\n");
+	
+	GdkWindow* gdkwin = gtk_widget_get_window(widget);
+	printf("window=%p\n", gdkwin);
+	
+	GError* err = NULL;
+	GdkGLContext* glctx = gdk_window_create_gl_context(gdkwin, &err);
+	if (err != NULL)
+	{
+	    printf("CONTEXT SHAT ITSELF\n");
+	    return;
+	}
+	
+	gdk_gl_context_set_use_es(glctx, FALSE);
+	gdk_gl_context_set_required_version(glctx, 3, 2);
+	
+	gdk_gl_context_realize(glctx, &err);
+	if (err != NULL)
+	{
+	    printf("CONTEXT REALIZE SHAT ITSELF\n");
+	    return;
+	}
+	
+	GtkAllocation allocation;
+	gtk_widget_get_allocation(widget, &allocation);
+	int window_scale = gdk_window_get_scale_factor(gdkwin);
+	ctx->width = allocation.width;
+	ctx->height = allocation.height;
+	ctx->scale = window_scale;
+	
+	gdk_gl_context_make_current(glctx);
+	_loadGLProcs();
+	areaAllocRenderbuffer(ctx);
+	
+	ctx->widget = widget;
+	ctx->window = gdkwin;
+	ctx->gctx = glctx;
+}
+
+static void areaAllocRenderbuffer(uiGLContext* glctx)
+{
+    _glGenRenderbuffers(2, &glctx->renderbuffer[0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height);
+    //glGenTextures(2, &glctx->renderbuffer[0]);
+    _glGenFramebuffers(1, &glctx->framebuffer);printf("ylarg1 %04X\n", glGetError());
+    printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx);
+    /*glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[0]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    
+    glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[1]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);*/
+    
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg1 %04X\n", glGetError());
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg1 %04X\n", glGetError());
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
+    
+    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer);printf("ylarg2 %04X\n", glGetError());
+    /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0);
+    _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg3 %04X\n", glGetError());
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg4 %04X\n", glGetError());
+    //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]);
+    
+    if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+    printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    
+    int alpha_size;
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);
+    _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size);
+    printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size);
+}
+
+static void areaRellocRenderbuffer(uiGLContext* glctx)
+{
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
+}
+
+void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx)
+{
+    int window_scale = gdk_window_get_scale_factor(glctx->window);
+    
+    if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale)
+    {
+        glctx->width = dp->AreaWidth;
+        glctx->height = dp->AreaHeight;
+        glctx->scale = window_scale;
+        areaRellocRenderbuffer(glctx);
+    }
+    
+    gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), 
+                           glctx->renderbuffer[0], GL_RENDERBUFFER, 
+                           1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
+}
+
+uiGLContext* FARTOMATIC(int major, int minor)
+{
+    uiGLContext *_ret = uiNew(uiGLContext);
+    _ret->vermaj = major;
+    _ret->vermin = minor;
+    _ret->width = -1;
+    _ret->height = -1;
+    _ret->renderbuffer[0] = 0;
+    _ret->renderbuffer[1] = 0;
+    _ret->framebuffer = 0;
+    
+    return _ret;
+    
+    Display* disp;
+    XVisualInfo* vizir;
+    GLXFBConfig *cfg;
+    Pixmap pm;
+    GLXPixmap glxpm;
+    GLXContext ctx;
+    
+    disp = XOpenDisplay(NULL);
+    derp = disp;
+    
+    int kaa, baa;
+    glXQueryVersion(disp, &kaa, &baa);
+    printf("GL VERSION: %d.%d\n", kaa, baa);
+    
+    const int sbAttrib[] = { GLX_RGBA,
+                            GLX_RED_SIZE, 1,
+                            GLX_GREEN_SIZE, 1,
+                            GLX_BLUE_SIZE, 1,
+                            None };
+   const int dbAttrib[] = { GLX_RGBA,
+                            GLX_RED_SIZE, 1,
+                            GLX_GREEN_SIZE, 1,
+                            GLX_BLUE_SIZE, 1,
+                            GLX_DOUBLEBUFFER,
+                            None };
+                            
+    int scrnum = DefaultScreen( disp );
+   Window root = RootWindow( disp, scrnum );
+
+   vizir = glXChooseVisual( disp, scrnum, (int *) sbAttrib );
+   if (!vizir) {
+      vizir = glXChooseVisual( disp, scrnum, (int *) dbAttrib );
+      if (!vizir) {
+         printf("Error: couldn't get an RGB visual\n");
+         return NULL;
+      }
+   }
+   
+    const int fb_attr[] = { 
+      GLX_RENDER_TYPE,    GLX_RGBA_BIT,
+      GLX_DRAWABLE_TYPE,  GLX_PBUFFER_BIT,
+      GLX_X_VISUAL_TYPE,  GLX_TRUE_COLOR,
+      GLX_DOUBLEBUFFER,   True,
+      GLX_X_RENDERABLE,   True,
+      GLX_RED_SIZE,       8,
+      GLX_GREEN_SIZE,     8,
+      GLX_BLUE_SIZE,      8,
+      GLX_ALPHA_SIZE,     8,
+      GLX_DEPTH_SIZE,     24,
+      GLX_STENCIL_SIZE,   8,
+      None 
+    };
+    int configs;
+    cfg = glXChooseFBConfig(disp, scrnum, (int *)&fb_attr, &configs);
+
+    if (!cfg)
+    {
+        printf("NO GOOD FBCONFIG\n");
+        return NULL;
+    }
+   
+    /*ctx = glXCreateContext( disp, vizir, NULL, True );
+    if (!ctx)
+    {
+        printf("Error: glXCreateContext failed\n");
+        return NULL;
+    }*/
+
+    PFNGLXCREATECONTEXTATTRIBSARBPROC createctx;
+    createctx = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB("glXCreateContextAttribsARB");
+    if (!createctx)
+    {
+        printf("bad shito\n");
+        return NULL;
+    }
+   
+    const int ctx_attr[] = 
+    {
+            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,//major,
+            GLX_CONTEXT_MINOR_VERSION_ARB, 2,//minor,
+            None
+    };
+    
+    ctx = glXCreateContextAttribsARB(disp, cfg[0], 0, True, ctx_attr);
+    if (!ctx)
+    {
+        printf("FAILED TO CREATE FANCYPANTS GL CONTEXT\n");
+        return NULL;
+    }
+   
+   //printf("CONTEXT GOOD. Direct rendering: %s\n", glXIsDirect(disp, ctx) ? "Yes" : "No");
+   
+    printf("blorp: %d\n", vizir->depth);
+    pm = XCreatePixmap(disp, root, 256, 384, vizir->depth);
+    if (!pm) printf("PIXMAP SHAT ITSELF\n");
+    else printf("PIXMAP GOOD\n");
+    
+    glxpm = glXCreateGLXPixmap(disp, vizir, pm);
+    if (!glxpm) printf("GLXPIXMAP SHAT ITSELF\n");
+    else printf("GLXPIXMAP GOOD\n");
+    
+    uiGLContext *ret = uiNew(uiGLContext);
+    printf("CREATE CTX: %p, %p\n", ret, g_thread_self());
+    ret->xdisp = disp;
+    ret->glxpm = glxpm;
+    ret->glxctx = ctx;
+    
+    return ret;
+}
+
+int uiGLGetFramebuffer(uiGLContext* ctx)
+{
+    return ctx->framebuffer;
+}
+
+float uiGLGetFramebufferScale(uiGLContext* ctx)
+{
+    return (float)ctx->scale;
+}
+
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
 	if (!ctx) return;
-	gtk_gl_area_attach_buffers(ctx->gla);
+	//gtk_gl_area_attach_buffers(ctx->gla);
+}
+
+static volatile int _ctxset_done;
+
+gboolean _threadsafe_ctxset(gpointer data)
+{
+    uiGLContext* ctx = (uiGLContext*)data;
+    gtk_gl_area_make_current(ctx->gla);
+    _ctxset_done = 1;
+    return FALSE;
 }
 
 void uiGLMakeContextCurrent(uiGLContext* ctx)
 {
-	if (!ctx) return;
-	gtk_gl_area_make_current(ctx->gla);
+	//if (!ctx) return;
+	/*if (g_thread_self() != gtkthread)
+	{
+	    _ctxset_done = 0;
+	    g_idle_add(_threadsafe_ctxset, ctx);
+	    while (!_ctxset_done);
+	}
+	else*/
+	//gtk_gl_area_make_current(ctx->gla);
+	/*printf("MAKE CONTEXT CURRENT %p, %p\n", ctx, g_thread_self());
+	if (!ctx)
+	{
+	    // BLERUGEHZFZF
+	    glXMakeCurrent(derp, None, NULL);
+	    return;
+	}
+	Bool ret = True;
+	if (glXGetCurrentContext() != ctx->glxctx)
+	{printf("DZJSKFLD\n");
+	    ret = glXMakeCurrent(ctx->xdisp, ctx->glxpm, ctx->glxctx);
+	    //glXMakeContextCurrent(ctx->xdisp, ctx->glxpm, ctx->glxpm, ctx->glxctx);
+	}
+	printf("WE MAED IT CURRENT: %d\n", ret);*/
+	
+	printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL);
+	if (!ctx)
+	{
+	    gdk_gl_context_clear_current();
+	    return;
+	}
+	//gtk_gl_area_make_current(ctx->gla);
+	gdk_gl_context_make_current(ctx->gctx);
+	GdkGLContext* burp = gdk_gl_context_get_current();
+	//gtk_gl_area_attach_buffers(ctx->gla);
+	//printf("burp = %p / %p\n", burp, ctx->gctx);
 }
 void *uiGLGetProcAddress(const char* proc)
 {
+printf("get: %s - ", proc);
+void* a = dlsym(NULL, proc);
+void* b = glXGetProcAddress(proc);
+void* c = glXGetProcAddressARB(proc);
+printf("%p / %p / %p\n", a, b, c);
+return c;
 	// this *will* break for older systems that don't have libglvnd!
 	// TODO: use a real solution
 	return dlsym(NULL /* RTLD_DEFAULT */, proc);
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 0c7aacd..e2686f9 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -194,9 +194,16 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs)
 }
 
 bool GLScreen_Init()
-{
+{printf("BEGINNING GL SHITO\n");
     if (!OpenGL_Init())
         return false;
+        
+    printf("GL INIT: %p, %p\n", glGenFramebuffers, glCreateShader);
+    
+    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
+    const GLubyte* version = glGetString(GL_VERSION); // version as a string
+    printf("OpenGL: renderer: %s\n", renderer);
+    printf("OpenGL: version: %s\n", version);
 
     if (!GLScreen_InitShader(GL_ScreenShader, kScreenFS))
         return false;
@@ -204,7 +211,7 @@ bool GLScreen_Init()
         return false;
 
     memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
-
+printf("morp0\n");
     glGenBuffers(1, &GL_ShaderConfigUBO);
     glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO);
     glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW);
@@ -213,14 +220,14 @@ bool GLScreen_Init()
     glGenBuffers(1, &GL_ScreenVertexBufferID);
     glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GL_ScreenVertices), NULL, GL_STATIC_DRAW);
-
+printf("morp1\n");
     glGenVertexArrays(1, &GL_ScreenVertexArrayID);
     glBindVertexArray(GL_ScreenVertexArrayID);
     glEnableVertexAttribArray(0); // position
     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0));
     glEnableVertexAttribArray(1); // texcoord
     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4));
-
+printf("morp2\n");
     glGenTextures(1, &GL_ScreenTexture);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
@@ -231,7 +238,7 @@ bool GLScreen_Init()
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL);
 
     GL_ScreenSizeDirty = true;
-
+printf("morp3\n");
     return true;
 }
 
@@ -248,6 +255,8 @@ void GLScreen_DeInit()
 
 void GLScreen_DrawScreen()
 {
+    float scale = uiGLGetFramebufferScale(GLContext);
+    
     if (GL_ScreenSizeDirty)
     {
         GL_ScreenSizeDirty = false;
@@ -370,23 +379,26 @@ void GLScreen_DrawScreen()
         glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices);
     }
-
+    printf("rarp4 %04X\n", glGetError());
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_STENCIL_TEST);
     glDisable(GL_BLEND);
     glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+printf("rarp2 %04X\n", glGetError());
 
-    glViewport(0, 0, WindowWidth, WindowHeight);
+    glViewport(0, 0, WindowWidth*scale, WindowHeight*scale);
+    printf("draw screen: viewport=%d/%d\n", WindowWidth, WindowHeight);
 
     if (GPU3D::Renderer == 0)
         OpenGL_UseShaderProgram(GL_ScreenShader);
     else
         OpenGL_UseShaderProgram(GL_ScreenShaderAccel);
-
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glClearColor(0, 0, 0, 1);
+printf("rarp3 %04X\n", glGetError());
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
+    printf("rarp8 %04X\n", glGetError());
+    glClearColor(0, 0, 1, 1);
     glClear(GL_COLOR_BUFFER_BIT);
-
+printf("rarp5 %04X\n", glGetError());
     int frontbuf = GPU::FrontBuffer;
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
@@ -412,15 +424,21 @@ void GLScreen_DrawScreen()
     glActiveTexture(GL_TEXTURE1);
     if (GPU3D::Renderer != 0)
         GPU3D::GLRenderer::SetupAccelFrame();
-
+printf("rarp6 %04X\n", glGetError());
     glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
     glBindVertexArray(GL_ScreenVertexArrayID);
     glDrawArrays(GL_TRIANGLES, 0, 4*3);
-
+printf("rarp7 %04X\n", glGetError());
     glFlush();
     uiGLSwapBuffers(GLContext);
 }
 
+void norp(void* data)
+{
+    uiGLMakeContextCurrent(GLContext);
+    GLScreen_DrawScreen();
+}
+
 void MicLoadWav(char* name)
 {
     SDL_AudioSpec format;
@@ -901,6 +919,8 @@ int EmuThreadFunc(void* burp)
                 {
                     uiGLMakeContextCurrent(GLContext);
                     GLScreen_DrawScreen();
+                    //uiGLMakeContextCurrent(NULL);
+                    //uiQueueMain(norp, NULL);
                 }
                 uiAreaQueueRedrawAll(MainDrawArea);
             }
-- 
cgit v1.2.3


From ce9d728fb6fe97a36eba5294a793f0d451c8fd6d Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Thu, 30 May 2019 17:29:41 +0200
Subject: fix cleanup of libui objects when closing melonDS fixes to Cmake
 shito attempt shit

---
 src/libui_sdl/CMakeLists.txt            |   5 +-
 src/libui_sdl/libui/ui.h                |   2 +
 src/libui_sdl/libui/unix/CMakeLists.txt |   1 +
 src/libui_sdl/libui/unix/area.c         |  67 ++++++++---
 src/libui_sdl/libui/unix/gl.c           | 201 ++++++++++++++++++++++++++++----
 src/libui_sdl/libui/unix/main.c         |  31 +++++
 src/libui_sdl/libui/unix/uipriv_unix.h  |  20 +++-
 src/libui_sdl/main.cpp                  |  31 +++--
 8 files changed, 304 insertions(+), 54 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt
index 61e0981..e9a54e2 100644
--- a/src/libui_sdl/CMakeLists.txt
+++ b/src/libui_sdl/CMakeLists.txt
@@ -9,9 +9,8 @@ SET(SOURCES_LIBUI
 	DlgAudioSettings.cpp
 	DlgEmuSettings.cpp
 	DlgInputConfig.cpp
-	DlgWifiSettings.cpp
-	# opengl backend stuff
 	DlgVideoSettings.cpp
+	DlgWifiSettings.cpp
 )
 
 option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON)
@@ -47,7 +46,7 @@ if (UNIX)
 				--generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml")
 
 	if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
-		target_link_libraries(melonDS dl X11)
+		target_link_libraries(melonDS dl)
 	endif ()
 
 	target_sources(melonDS PUBLIC melon_grc.c)
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index 0c89d90..47da54b 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -613,6 +613,8 @@ typedef struct uiGLContext uiGLContext;
 
 _UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a);
 _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx);
+_UI_EXTERN void uiGLBegin(uiGLContext* ctx);
+_UI_EXTERN void uiGLEnd(uiGLContext* ctx);
 _UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx);
 _UI_EXTERN void *uiGLGetProcAddress(const char* proc);
 _UI_EXTERN int uiGLGetFramebuffer(uiGLContext* ctx);
diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt
index ec9ab75..c69081e 100644
--- a/src/libui_sdl/libui/unix/CMakeLists.txt
+++ b/src/libui_sdl/libui/unix/CMakeLists.txt
@@ -63,6 +63,7 @@ macro(_handle_static)
 	set(_oname libui-combined.o)
 	add_custom_command(
 		OUTPUT ${_oname}
+		DEPENDS ${_LIBUINAME}
 		COMMAND
 			ld -r --whole-archive ${_aname} -o ${_oname}
 		COMMAND
diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index bf92ddf..62a4cb0 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -3,18 +3,6 @@
 
 extern GThread* gtkthread;
 
-// notes:
-// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
-#define areaWidgetType (areaWidget_get_type())
-#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget))
-#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType))
-#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass))
-#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget))
-#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass))
-
-typedef struct areaWidget areaWidget;
-typedef struct areaWidgetClass areaWidgetClass;
-
 struct areaWidget {
 	GtkDrawingArea parent_instance;
 	uiArea *a;
@@ -45,6 +33,7 @@ struct uiArea {
 
     gboolean opengl;
 	uiGLContext *glContext;
+	gboolean drawreq;
 	
 	int bgR, bgG, bgB;
 
@@ -63,6 +52,21 @@ struct uiArea {
 
 G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA)
 
+int boub(GtkWidget* w) { return isAreaWidget(w); }
+void baba(GtkWidget* w)
+{
+    if (!isAreaWidget(w)) return;
+    
+    areaWidget *aw = areaWidget(w);
+	uiArea *a = aw->a;
+	if (!a->opengl) return;
+	
+	GdkGLContext* oldctx = gdk_gl_context_get_current();
+	uiGLMakeContextCurrent(a->glContext);
+	glFinish();
+	gdk_gl_context_make_current(oldctx);
+}
+
 static void areaWidget_init(areaWidget *aw)
 {
 	// for events
@@ -130,6 +134,22 @@ static void loadAreaSize(uiArea *a, double *width, double *height)
 
 void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
 
+void areaPreRedraw(areaWidget* widget)
+{
+    uiArea* a = widget->a;
+    if (!a->opengl) return;
+    
+    areaPreRedrawGL(a->glContext);
+}
+
+void areaPostRedraw(areaWidget* widget)
+{
+    uiArea* a = widget->a;
+    if (!a->opengl) return;
+    
+    areaPostRedrawGL(a->glContext);
+}
+
 static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 {
 	areaWidget *aw = areaWidget(w);
@@ -161,6 +181,8 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 	else
 	{
 	    areaDrawGL(w, &dp, cr, a->glContext);
+	    //if (a->drawreq) uiGLEnd(a->glContext);
+	    a->drawreq = FALSE;
 	}
 
 	freeContext(dp.Context);
@@ -613,7 +635,15 @@ static void areaWidget_class_init(areaWidgetClass *class)
 
 // control implementation
 
-uiUnixControlAllDefaults(uiArea)
+uiUnixControlAllDefaultsExceptDestroy(uiArea)
+
+static void uiAreaDestroy(uiControl *c)
+{
+    uiArea* a = uiArea(c);
+    if (a->opengl && a->glContext) freeGLContext(a->glContext);
+    g_object_unref(uiArea(c)->widget);
+    uiFreeControl(c);
+}
 
 void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b)
 {
@@ -634,6 +664,8 @@ void uiAreaSetSize(uiArea *a, int width, int height)
 gboolean _threadsaferefresh(gpointer data)
 {
     uiArea* a = (uiArea*)data;
+    a->drawreq = TRUE;
+    //if (a->opengl) uiGLBegin(a->glContext);
     gtk_widget_queue_draw(a->areaWidget);
     return FALSE;
 }
@@ -644,7 +676,11 @@ void uiAreaQueueRedrawAll(uiArea *a)
     if (g_thread_self() != gtkthread)
         g_idle_add(_threadsaferefresh, a);
     else
+    {
+        a->drawreq = TRUE;
+        //if (a->opengl) uiGLBegin(a->glContext);
 	    gtk_widget_queue_draw(a->areaWidget);
+	}
 }
 
 void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height)
@@ -767,10 +803,12 @@ printf("create glarea\n");
 	a->ah = ah;
 	a->scrolling = FALSE;
 	a->opengl = TRUE;
+	a->drawreq = FALSE;
 
 	//GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
 	uiGLContext* ctx = NULL;
 printf("create sdfsf\n");
+    // TODO: move this elsewhere!! so we can actually try all possible versions
 	for (int i = 0; req_versions[i] && !ctx; i++) {
 		int major = uiGLVerMajor(req_versions[i]);
 		int minor = uiGLVerMinor(req_versions[i]);
@@ -792,8 +830,7 @@ printf("create jfghjjgh: %p\n", ctx);
 	g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a);
 
 	uiAreaSetBackgroundColor(a, -1, -1, -1);
-	//printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
-printf("create qssssq\n");
+
 	return a;
 }
 
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index 3504d3a..3861cda 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -6,12 +6,35 @@
 #include <GL/glx.h>
 
 extern GThread* gtkthread;
+extern GMutex glmutex;
 
 /*
  *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed
 
 (melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget'
  */
+ 
+// MISERABLE LITTLE PILE OF HACKS
+#define HAX_GDK_GL_CONTEXT_CLASS(klass)	    (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass))
+#define HAX_GDK_IS_GL_CONTEXT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
+#define HAX_GDK_GL_CONTEXT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass))
+
+typedef struct _HAX_GdkGLContextClass       HAX_GdkGLContextClass;
+
+struct _HAX_GdkGLContextClass
+{
+  GObjectClass parent_class;
+
+  gboolean (* realize) (GdkGLContext *context,
+                        GError **error);
+
+  void (* end_frame)    (GdkGLContext *context,
+                         cairo_region_t *painted,
+                         cairo_region_t *damage);
+  gboolean (* texture_from_surface) (GdkGLContext    *context,
+                                     cairo_surface_t *surface,
+                                     cairo_region_t  *region);
+};
 
 struct uiGLContext {
 	GtkGLArea *gla;
@@ -19,6 +42,11 @@ struct uiGLContext {
 	GdkWindow* window;
 	GdkGLContext *gctx;
 	
+	GMutex mutex;
+	GLsync sync;
+	GLsync sync2;
+	int zog;
+	
 	Display* xdisp;
 	GLXPixmap glxpm;
 	GLXContext glxctx;
@@ -26,8 +54,8 @@ struct uiGLContext {
 	
 	int width, height;
 	int scale;
-	GLuint renderbuffer[2];
-	GLuint framebuffer;
+	GLuint renderbuffer[2][2];
+	GLuint framebuffer[2];
 };
 
 static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers;
@@ -45,7 +73,16 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus;
 
 static int _procsLoaded = 0;
 
-static void _loadGLProcs()
+static void (*vniorp)(GdkGLContext*, cairo_region_t*, cairo_region_t*);
+
+static void class_hax(GdkGLContext* glctx, cairo_region_t* painted, cairo_region_t* damage)
+{
+    //printf("END FRAME HIJACK\n");
+    //glClearColor(0, 1, 0, 1);
+    vniorp(glctx, painted, damage);
+}
+
+static void _loadGLProcs(GdkGLContext* glctx)
 {
     if (_procsLoaded) return;
     
@@ -63,17 +100,25 @@ static void _loadGLProcs()
     _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus");
     
     _procsLoaded = 1;
+    
+    HAX_GdkGLContextClass* class = HAX_GDK_GL_CONTEXT_GET_CLASS(glctx);
+    printf("HAX class = %p\n", class);
+    printf("class end_frame = %p\n", class->end_frame);
+    vniorp = class->end_frame;
+    class->end_frame = class_hax;
 }
 
 Display* derp;
 
-uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min)
+int nswaps = 0;
+
+uiGLContext *createGLContext(GtkWidget* widget, int maj, int min)
 {
     printf("barp\n");
 	uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext");
 	
 	// herp
-	ret->gla = gla;
+	ret->gla = widget;
 	ret->gctx = NULL;
 	//while (!ret->gctx)
 	/*{
@@ -111,6 +156,14 @@ uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min)
 	return ret;
 }
 
+void freeGLContext(uiGLContext* glctx)
+{
+    if (glctx == NULL) return;
+    gdk_gl_context_clear_current();
+    g_object_unref(glctx->gctx);
+    uiFree(glctx);
+}
+
 static void areaAllocRenderbuffer(uiGLContext* glctx);
 
 void databotte(GtkWidget* widget, uiGLContext* ctx)
@@ -150,7 +203,7 @@ void databotte(GtkWidget* widget, uiGLContext* ctx)
 	ctx->scale = window_scale;
 	
 	gdk_gl_context_make_current(glctx);
-	_loadGLProcs();
+	_loadGLProcs(glctx);
 	areaAllocRenderbuffer(ctx);
 	
 	ctx->widget = widget;
@@ -160,10 +213,10 @@ void databotte(GtkWidget* widget, uiGLContext* ctx)
 
 static void areaAllocRenderbuffer(uiGLContext* glctx)
 {
-    _glGenRenderbuffers(2, &glctx->renderbuffer[0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height);
+    _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height);
     //glGenTextures(2, &glctx->renderbuffer[0]);
-    _glGenFramebuffers(1, &glctx->framebuffer);printf("ylarg1 %04X\n", glGetError());
-    printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx);
+    _glGenFramebuffers(2, &glctx->framebuffer[0]);printf("ylarg1 %04X\n", glGetError());
+    printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer[0]:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx);
     /*glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[0]);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -176,37 +229,91 @@ static void areaAllocRenderbuffer(uiGLContext* glctx)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);*/
     
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg1 %04X\n", glGetError());
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg1 %04X\n", glGetError());
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg1 %04X\n", glGetError());
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
+    
+    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);printf("ylarg2 %04X\n", glGetError());
+    /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0);
+    _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg3 %04X\n", glGetError());
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg4 %04X\n", glGetError());
+    //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]);
+    
+    
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg1 %04X\n", glGetError());
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg1 %04X\n", glGetError());
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg1 %04X\n", glGetError());
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
     
-    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer);printf("ylarg2 %04X\n", glGetError());
+    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);printf("ylarg2 %04X\n", glGetError());
     /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0);
     _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0]);printf("ylarg3 %04X\n", glGetError());
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg4 %04X\n", glGetError());
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg3 %04X\n", glGetError());
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg4 %04X\n", glGetError());
     //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]);
     
     if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
     printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
     
     int alpha_size;
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
     _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size);
     printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size);
 }
 
 static void areaRellocRenderbuffer(uiGLContext* glctx)
 {
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
 }
 
+void areaPreRedrawGL(uiGLContext* glctx)
+{
+    g_mutex_lock(&glctx->mutex);
+    
+    /*gdk_gl_context_make_current(glctx->gctx);
+    //glClientWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED);
+    glDeleteSync(glctx->sync);
+    glFinish();
+    gdk_gl_context_clear_current();*/
+    /*GdkGLContext* oldctx = gdk_gl_context_get_current();
+    gdk_gl_context_make_current(glctx->gctx);
+    printf("[%p] PRE DRAW\n", gdk_gl_context_get_current());
+    
+    gdk_gl_context_make_current(oldctx);*/
+    //glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT);
+    //glWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED);
+    /*int ret = glClientWaitSync(glctx->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50);
+    printf("PRE-DRAW: SYNC %p, %04X, %04X\n", glctx->sync, ret, glGetError());
+    glDeleteSync(glctx->sync);
+    glctx->sync = NULL;*/
+    //glFlush();
+    if (nswaps > 1) printf("MISSED %d FRAMES\n", nswaps-1);
+    nswaps = 0;
+    //glctx->zog ^= 1;
+}
+
+void areaPostRedrawGL(uiGLContext* glctx)
+{
+    //glctx->sync2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+    //glFlush();
+    //printf("[%p] POST DRAW\n", gdk_gl_context_get_current());
+    g_mutex_unlock(&glctx->mutex);
+}
+
 void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx)
 {
+    //uiGLBegin(glctx);
+    
     int window_scale = gdk_window_get_scale_factor(glctx->window);
     
     if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale)
@@ -218,8 +325,10 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex
     }
     
     gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), 
-                           glctx->renderbuffer[0], GL_RENDERBUFFER, 
+                           glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, 
                            1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
+                           
+    //uiGLEnd(glctx);
 }
 
 uiGLContext* FARTOMATIC(int major, int minor)
@@ -229,9 +338,15 @@ uiGLContext* FARTOMATIC(int major, int minor)
     _ret->vermin = minor;
     _ret->width = -1;
     _ret->height = -1;
-    _ret->renderbuffer[0] = 0;
-    _ret->renderbuffer[1] = 0;
-    _ret->framebuffer = 0;
+    _ret->renderbuffer[0][0] = 0;
+    _ret->renderbuffer[0][1] = 0;
+    _ret->framebuffer[0] = 0;
+    _ret->renderbuffer[1][0] = 0;
+    _ret->renderbuffer[1][1] = 0;
+    _ret->framebuffer[1] = 0;
+    _ret->zog = 0;
+    
+    g_mutex_init(&_ret->mutex);
     
     return _ret;
     
@@ -348,7 +463,7 @@ uiGLContext* FARTOMATIC(int major, int minor)
 
 int uiGLGetFramebuffer(uiGLContext* ctx)
 {
-    return ctx->framebuffer;
+    return ctx->framebuffer[ctx->zog];// ? 0:1];
 }
 
 float uiGLGetFramebufferScale(uiGLContext* ctx)
@@ -358,8 +473,18 @@ float uiGLGetFramebufferScale(uiGLContext* ctx)
 
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
-	if (!ctx) return;
-	//gtk_gl_area_attach_buffers(ctx->gla);
+    /*ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+    //gdk_gl_context_clear_current();
+    glWaitSync(ctx->sync, 0, GL_TIMEOUT_IGNORED);
+    glDeleteSync(ctx->sync);*/
+    /*printf("[%p] SWAPBUFFERS\n", gdk_gl_context_get_current());
+    glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT);
+    glFinish();*/
+    //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+    //glFlush();
+    //printf("SWAP: SYNC=%p\n", ctx->sync);
+    //glFinish();
+    nswaps++;
 }
 
 static volatile int _ctxset_done;
@@ -398,7 +523,7 @@ void uiGLMakeContextCurrent(uiGLContext* ctx)
 	}
 	printf("WE MAED IT CURRENT: %d\n", ret);*/
 	
-	printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL);
+	//printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL);
 	if (!ctx)
 	{
 	    gdk_gl_context_clear_current();
@@ -410,6 +535,32 @@ void uiGLMakeContextCurrent(uiGLContext* ctx)
 	//gtk_gl_area_attach_buffers(ctx->gla);
 	//printf("burp = %p / %p\n", burp, ctx->gctx);
 }
+
+void uiGLBegin(uiGLContext* ctx)
+{
+    //g_mutex_lock(&ctx->mutex);
+    if (g_thread_self() != gtkthread)
+    {
+        g_mutex_lock(&glmutex);
+        
+        //int ret = glClientWaitSync(ctx->sync2, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50);
+        //printf("GLBEGIN: SYNC %p, %04X, %04X\n", ctx->sync2, ret, glGetError());
+        //glDeleteSync(ctx->sync2);
+    }
+}
+
+void uiGLEnd(uiGLContext* ctx)
+{
+    //g_mutex_unlock(&ctx->mutex);
+    if (g_thread_self() != gtkthread)
+    {
+        g_mutex_unlock(&glmutex);
+        
+        //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+        //glFlush();
+    }
+}
+
 void *uiGLGetProcAddress(const char* proc)
 {
 printf("get: %s - ", proc);
diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c
index 409b659..66bd335 100644
--- a/src/libui_sdl/libui/unix/main.c
+++ b/src/libui_sdl/libui/unix/main.c
@@ -6,6 +6,33 @@ uiInitOptions options;
 // kind of a hack
 GThread* gtkthread;
 
+GMutex glmutex;
+int boub(GtkWidget* w);
+void baba(GtkWidget* w);
+
+static void _eventfilter(GdkEvent* evt, gpointer data)
+{
+    if (evt->type == GDK_EXPOSE)
+    {
+        GtkWidget* widget = gtk_get_event_widget(evt);
+        if (isAreaWidget(widget))
+        {
+            areaWidget* area = areaWidget(widget);
+            areaPreRedraw(area);
+            gtk_main_do_event(evt);
+            areaPostRedraw(area);
+            return;
+        }
+    }
+    
+    gtk_main_do_event(evt);
+}
+
+static void _eventfilterdestroy(gpointer data)
+{
+    printf("DELET\n");
+}
+
 const char *uiInit(uiInitOptions *o)
 {
 	GError *err = NULL;
@@ -31,6 +58,10 @@ const char *uiInit(uiInitOptions *o)
 	
 	gtk_window_set_default_icon_list(iconlist);
 	
+	g_mutex_init(&glmutex);
+	
+	gdk_event_handler_set(_eventfilter, NULL, _eventfilterdestroy);
+	
 	return NULL;
 }
 
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
index 42d5d76..7a7b208 100644
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ b/src/libui_sdl/libui/unix/uipriv_unix.h
@@ -65,5 +65,23 @@ extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha);
 extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name);
 
 // gl.c
-extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min);
+extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min);
+extern void freeGLContext(uiGLContext* glctx);
+extern void areaPreRedrawGL(uiGLContext* glctx);
+extern void areaPostRedrawGL(uiGLContext* glctx);
+
+// notes:
+// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
+#define areaWidgetType (areaWidget_get_type())
+#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget))
+#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType))
+#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass))
+#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget))
+#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass))
+
+typedef struct areaWidget areaWidget;
+typedef struct areaWidgetClass areaWidgetClass;
+
+extern void areaPreRedraw(areaWidget* widget);
+extern void areaPostRedraw(areaWidget* widget);
 
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index e2686f9..fa6a2b5 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -379,26 +379,24 @@ void GLScreen_DrawScreen()
         glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices);
     }
-    printf("rarp4 %04X\n", glGetError());
+
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_STENCIL_TEST);
     glDisable(GL_BLEND);
     glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-printf("rarp2 %04X\n", glGetError());
 
     glViewport(0, 0, WindowWidth*scale, WindowHeight*scale);
-    printf("draw screen: viewport=%d/%d\n", WindowWidth, WindowHeight);
 
     if (GPU3D::Renderer == 0)
         OpenGL_UseShaderProgram(GL_ScreenShader);
     else
         OpenGL_UseShaderProgram(GL_ScreenShaderAccel);
-printf("rarp3 %04X\n", glGetError());
+
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
-    printf("rarp8 %04X\n", glGetError());
+
     glClearColor(0, 0, 1, 1);
     glClear(GL_COLOR_BUFFER_BIT);
-printf("rarp5 %04X\n", glGetError());
+
     int frontbuf = GPU::FrontBuffer;
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
@@ -424,11 +422,11 @@ printf("rarp5 %04X\n", glGetError());
     glActiveTexture(GL_TEXTURE1);
     if (GPU3D::Renderer != 0)
         GPU3D::GLRenderer::SetupAccelFrame();
-printf("rarp6 %04X\n", glGetError());
+
     glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
     glBindVertexArray(GL_ScreenVertexArrayID);
     glDrawArrays(GL_TRIANGLES, 0, 4*3);
-printf("rarp7 %04X\n", glGetError());
+
     glFlush();
     uiGLSwapBuffers(GLContext);
 }
@@ -826,7 +824,11 @@ int EmuThreadFunc(void* burp)
             // microphone input
             FeedMicInput();
 
-            if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);
+            if (Screen_UseGL)
+            {
+                uiGLBegin(GLContext);
+                uiGLMakeContextCurrent(GLContext);
+            }
 
             // auto screen layout
             {
@@ -862,7 +864,11 @@ int EmuThreadFunc(void* burp)
 
             if (EmuRunning == 0) break;
 
-            if (Screen_UseGL) GLScreen_DrawScreen();
+            if (Screen_UseGL)
+            {
+                GLScreen_DrawScreen();
+                uiGLEnd(GLContext);
+            }
             uiAreaQueueRedrawAll(MainDrawArea);
 
             // framerate limiter based off SDL2_gfx
@@ -917,8 +923,10 @@ int EmuThreadFunc(void* burp)
             {
                 if (Screen_UseGL)
                 {
+                    uiGLBegin(GLContext);
                     uiGLMakeContextCurrent(GLContext);
                     GLScreen_DrawScreen();
+                    uiGLEnd(GLContext);
                     //uiGLMakeContextCurrent(NULL);
                     //uiQueueMain(norp, NULL);
                 }
@@ -2537,6 +2545,9 @@ int main(int argc, char** argv)
     if (MicDevice)   SDL_CloseAudioDevice(MicDevice);
 
     if (MicWavBuffer) delete[] MicWavBuffer;
+    
+    if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]);
+    if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]);
 
     Config::ScreenRotation = ScreenRotation;
     Config::ScreenGap = ScreenGap;
-- 
cgit v1.2.3


From 27d451d07a398a79cedef8040dfb6a612672b06c Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Fri, 31 May 2019 01:46:47 +0200
Subject: clean up code, attempt at shit

---
 src/libui_sdl/libui/unix/area.c        |  61 ++---
 src/libui_sdl/libui/unix/gl.c          | 399 ++++-----------------------------
 src/libui_sdl/libui/unix/uipriv_unix.h |   1 +
 src/libui_sdl/main.cpp                 |   2 +-
 4 files changed, 67 insertions(+), 396 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index 62a4cb0..62fe512 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -28,12 +28,11 @@ struct uiArea {
 
 	GtkWidget *areaWidget;
 	GtkDrawingArea *drawingArea;
-	GtkGLArea *glArea;
 	areaWidget *area;
 
     gboolean opengl;
 	uiGLContext *glContext;
-	gboolean drawreq;
+	unsigned int* req_versions;
 	
 	int bgR, bgG, bgB;
 
@@ -132,8 +131,6 @@ static void loadAreaSize(uiArea *a, double *width, double *height)
 	}
 }
 
-void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
-
 void areaPreRedraw(areaWidget* widget)
 {
     uiArea* a = widget->a;
@@ -181,8 +178,6 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 	else
 	{
 	    areaDrawGL(w, &dp, cr, a->glContext);
-	    //if (a->drawreq) uiGLEnd(a->glContext);
-	    a->drawreq = FALSE;
 	}
 
 	freeContext(dp.Context);
@@ -664,8 +659,6 @@ void uiAreaSetSize(uiArea *a, int width, int height)
 gboolean _threadsaferefresh(gpointer data)
 {
     uiArea* a = (uiArea*)data;
-    a->drawreq = TRUE;
-    //if (a->opengl) uiGLBegin(a->glContext);
     gtk_widget_queue_draw(a->areaWidget);
     return FALSE;
 }
@@ -676,11 +669,7 @@ void uiAreaQueueRedrawAll(uiArea *a)
     if (g_thread_self() != gtkthread)
         g_idle_add(_threadsaferefresh, a);
     else
-    {
-        a->drawreq = TRUE;
-        //if (a->opengl) uiGLBegin(a->glContext);
 	    gtk_widget_queue_draw(a->areaWidget);
-	}
 }
 
 void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height)
@@ -762,7 +751,7 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge)
 uiArea *uiNewArea(uiAreaHandler *ah)
 {
 	uiArea *a;
-printf("create regular area\n");
+
 	uiUnixNewControl(uiArea, a);
 
 	a->ah = ah;
@@ -782,44 +771,38 @@ printf("create regular area\n");
 	return a;
 }
 
-uiGLContext* FARTOMATIC(int major, int minor);
-void databotte(GtkWidget* gla, uiGLContext* ctx);
-void majoricc(GtkWidget* widget, gpointer data)
+void _areaCreateGLContext(GtkWidget* widget, gpointer data)
 {
-    printf("ACTUALLY CREATE CONTEXT\n");
-    
     uiArea* a = (uiArea*)data;
-    uiGLContext* ctx = a->glContext;
     
-    databotte(a->widget, ctx);
+    uiGLContext* ctx = NULL;
+    for (int i = 0; a->req_versions[i] && !ctx; i++) 
+    {
+		int major = uiGLVerMajor(a->req_versions[i]);
+		int minor = uiGLVerMinor(a->req_versions[i]);
+		
+		// we cannot support any version older than 3.2 via GDK
+		if ((major < 3) || (major == 3 && minor < 2))
+		    break;
+
+		ctx = createGLContext(widget, major, minor);
+	}
+	
+    a->glContext = ctx;
 }
 
 uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
 {
 	uiArea *a;
-printf("create glarea\n");
+
 	uiUnixNewControl(uiArea, a);
 
 	a->ah = ah;
 	a->scrolling = FALSE;
 	a->opengl = TRUE;
-	a->drawreq = FALSE;
-
-	//GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new();
-	uiGLContext* ctx = NULL;
-printf("create sdfsf\n");
-    // TODO: move this elsewhere!! so we can actually try all possible versions
-	for (int i = 0; req_versions[i] && !ctx; i++) {
-		int major = uiGLVerMajor(req_versions[i]);
-		int minor = uiGLVerMinor(req_versions[i]);
-		//gtk_gl_area_set_required_version(gla, major, minor);
-		//ctx = createGLContext(gla, major, minor);
-		ctx = FARTOMATIC(major, minor);
-	}
-printf("create jfghjjgh: %p\n", ctx);
-	a->glContext = ctx;
-	//a->areaWidget = GTK_WIDGET(gla);
-	//a->glArea = gla;
+	
+	a->glContext = NULL;
+	a->req_versions = req_versions;
 	a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
 		"libui-area", a,
 		NULL));
@@ -827,7 +810,7 @@ printf("create jfghjjgh: %p\n", ctx);
 
 	a->widget = a->areaWidget;
 	
-	g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a);
+	g_signal_connect(a->widget, "realize", G_CALLBACK(_areaCreateGLContext), a);
 
 	uiAreaSetBackgroundColor(a, -1, -1, -1);
 
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index 3861cda..ab29abb 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -1,63 +1,29 @@
 // 26 may 2019
 #include "uipriv_unix.h"
 
-#include <X11/Xlib.h>
 #include <GL/gl.h>
-#include <GL/glx.h>
 
 extern GThread* gtkthread;
-extern GMutex glmutex;
 
-/*
- *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed
-
-(melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget'
- */
- 
-// MISERABLE LITTLE PILE OF HACKS
-#define HAX_GDK_GL_CONTEXT_CLASS(klass)	    (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass))
-#define HAX_GDK_IS_GL_CONTEXT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
-#define HAX_GDK_GL_CONTEXT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass))
-
-typedef struct _HAX_GdkGLContextClass       HAX_GdkGLContextClass;
-
-struct _HAX_GdkGLContextClass
+struct uiGLContext 
 {
-  GObjectClass parent_class;
-
-  gboolean (* realize) (GdkGLContext *context,
-                        GError **error);
-
-  void (* end_frame)    (GdkGLContext *context,
-                         cairo_region_t *painted,
-                         cairo_region_t *damage);
-  gboolean (* texture_from_surface) (GdkGLContext    *context,
-                                     cairo_surface_t *surface,
-                                     cairo_region_t  *region);
-};
-
-struct uiGLContext {
-	GtkGLArea *gla;
 	GtkWidget* widget;
 	GdkWindow* window;
+	
 	GdkGLContext *gctx;
+	int vermaj, vermin;
 	
 	GMutex mutex;
-	GLsync sync;
-	GLsync sync2;
-	int zog;
-	
-	Display* xdisp;
-	GLXPixmap glxpm;
-	GLXContext glxctx;
-	int vermaj, vermin;
 	
 	int width, height;
 	int scale;
 	GLuint renderbuffer[2][2];
 	GLuint framebuffer[2];
+	int backbuffer;
 };
 
+static void areaAllocRenderbuffer(uiGLContext* glctx);
+
 static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers;
 static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers;
 static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer;
@@ -73,15 +39,6 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus;
 
 static int _procsLoaded = 0;
 
-static void (*vniorp)(GdkGLContext*, cairo_region_t*, cairo_region_t*);
-
-static void class_hax(GdkGLContext* glctx, cairo_region_t* painted, cairo_region_t* damage)
-{
-    //printf("END FRAME HIJACK\n");
-    //glClearColor(0, 1, 0, 1);
-    vniorp(glctx, painted, damage);
-}
-
 static void _loadGLProcs(GdkGLContext* glctx)
 {
     if (_procsLoaded) return;
@@ -100,101 +57,31 @@ static void _loadGLProcs(GdkGLContext* glctx)
     _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus");
     
     _procsLoaded = 1;
-    
-    HAX_GdkGLContextClass* class = HAX_GDK_GL_CONTEXT_GET_CLASS(glctx);
-    printf("HAX class = %p\n", class);
-    printf("class end_frame = %p\n", class->end_frame);
-    vniorp = class->end_frame;
-    class->end_frame = class_hax;
 }
 
-Display* derp;
-
-int nswaps = 0;
-
 uiGLContext *createGLContext(GtkWidget* widget, int maj, int min)
 {
-    printf("barp\n");
-	uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext");
-	
-	// herp
-	ret->gla = widget;
-	ret->gctx = NULL;
-	//while (!ret->gctx)
-	/*{
-	gtk_widget_realize(GTK_WIDGET(gla));
-	printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
-	ret->gla = gla;
-	ret->gctx = gtk_gl_area_get_context(gla);
-	printf("context: %p\n", ret->gctx);
-	}*/
-	
-	
-	
-	/*
-	GtkAllocation allocation;
-    GdkWindow *window;
-    Display *display;
-    int id;
-
-    window = gtk_widget_get_window(widget);
-    display = gdk_x11_display_get_xdisplay(gdk_window_get_display(window));
-    id = gdk_x11_window_get_xid(window);
+    GdkWindow* gdkwin = gtk_widget_get_window(widget);
 
-    if (glXMakeCurrent(display, id, context) == TRUE) {*/
-    
-    
-    /*GdkWindow* window;
-    Display* disp;
-    
-    window = gtk_widget_get_window(GTK_WIDGET(gla));
-    display = */
-	
-	
-	
-	ret->vermaj = maj; ret->vermin = min;
-	return ret;
-}
-
-void freeGLContext(uiGLContext* glctx)
-{
-    if (glctx == NULL) return;
-    gdk_gl_context_clear_current();
-    g_object_unref(glctx->gctx);
-    uiFree(glctx);
-}
-
-static void areaAllocRenderbuffer(uiGLContext* glctx);
-
-void databotte(GtkWidget* widget, uiGLContext* ctx)
-{
-    /*printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla)));
-	ctx->gctx = gtk_gl_area_get_context(gla);
-	printf("context: %p\n", ctx->gctx);*/
-	
-	printf("DATABOTTE\n");
-	
-	GdkWindow* gdkwin = gtk_widget_get_window(widget);
-	printf("window=%p\n", gdkwin);
-	
 	GError* err = NULL;
-	GdkGLContext* glctx = gdk_window_create_gl_context(gdkwin, &err);
-	if (err != NULL)
+	GdkGLContext* gctx = gdk_window_create_gl_context(gdkwin, &err);
+	if (err != NULL || gctx == NULL)
 	{
-	    printf("CONTEXT SHAT ITSELF\n");
-	    return;
+	    return NULL;
 	}
 	
-	gdk_gl_context_set_use_es(glctx, FALSE);
-	gdk_gl_context_set_required_version(glctx, 3, 2);
+	// TODO: make the set_use_es call conditional (#ifdef or smth) for older versions of gdk?
+	gdk_gl_context_set_use_es(gctx, FALSE);
+	gdk_gl_context_set_required_version(gctx, maj, min);
 	
-	gdk_gl_context_realize(glctx, &err);
-	if (err != NULL)
+	gboolean res = gdk_gl_context_realize(gctx, &err);
+	if (err != NULL || res == FALSE)
 	{
-	    printf("CONTEXT REALIZE SHAT ITSELF\n");
-	    return;
+	    return NULL;
 	}
 	
+	uiGLContext* ctx = uiNew(uiGLContext);
+	
 	GtkAllocation allocation;
 	gtk_widget_get_allocation(widget, &allocation);
 	int window_scale = gdk_window_get_scale_factor(gdkwin);
@@ -202,13 +89,26 @@ void databotte(GtkWidget* widget, uiGLContext* ctx)
 	ctx->height = allocation.height;
 	ctx->scale = window_scale;
 	
-	gdk_gl_context_make_current(glctx);
-	_loadGLProcs(glctx);
+	gdk_gl_context_make_current(gctx);
+	_loadGLProcs(gctx);
 	areaAllocRenderbuffer(ctx);
+	ctx->backbuffer = 0;
+	
+	g_mutex_init(&ctx->mutex);
 	
 	ctx->widget = widget;
 	ctx->window = gdkwin;
-	ctx->gctx = glctx;
+	ctx->gctx = gctx;
+	
+    return ctx;
+}
+
+void freeGLContext(uiGLContext* glctx)
+{
+    if (glctx == NULL) return;
+    gdk_gl_context_clear_current();
+    g_object_unref(glctx->gctx);
+    uiFree(glctx);
 }
 
 static void areaAllocRenderbuffer(uiGLContext* glctx)
@@ -279,41 +179,16 @@ static void areaRellocRenderbuffer(uiGLContext* glctx)
 void areaPreRedrawGL(uiGLContext* glctx)
 {
     g_mutex_lock(&glctx->mutex);
-    
-    /*gdk_gl_context_make_current(glctx->gctx);
-    //glClientWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED);
-    glDeleteSync(glctx->sync);
-    glFinish();
-    gdk_gl_context_clear_current();*/
-    /*GdkGLContext* oldctx = gdk_gl_context_get_current();
-    gdk_gl_context_make_current(glctx->gctx);
-    printf("[%p] PRE DRAW\n", gdk_gl_context_get_current());
-    
-    gdk_gl_context_make_current(oldctx);*/
-    //glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT);
-    //glWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED);
-    /*int ret = glClientWaitSync(glctx->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50);
-    printf("PRE-DRAW: SYNC %p, %04X, %04X\n", glctx->sync, ret, glGetError());
-    glDeleteSync(glctx->sync);
-    glctx->sync = NULL;*/
-    //glFlush();
-    if (nswaps > 1) printf("MISSED %d FRAMES\n", nswaps-1);
-    nswaps = 0;
-    //glctx->zog ^= 1;
+    glctx->backbuffer = glctx->backbuffer ? 0 : 1;
 }
 
 void areaPostRedrawGL(uiGLContext* glctx)
 {
-    //glctx->sync2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-    //glFlush();
-    //printf("[%p] POST DRAW\n", gdk_gl_context_get_current());
     g_mutex_unlock(&glctx->mutex);
 }
 
 void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx)
 {
-    //uiGLBegin(glctx);
-    
     int window_scale = gdk_window_get_scale_factor(glctx->window);
     
     if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale)
@@ -325,145 +200,13 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex
     }
     
     gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), 
-                           glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, 
+                           glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, 
                            1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
-                           
-    //uiGLEnd(glctx);
-}
-
-uiGLContext* FARTOMATIC(int major, int minor)
-{
-    uiGLContext *_ret = uiNew(uiGLContext);
-    _ret->vermaj = major;
-    _ret->vermin = minor;
-    _ret->width = -1;
-    _ret->height = -1;
-    _ret->renderbuffer[0][0] = 0;
-    _ret->renderbuffer[0][1] = 0;
-    _ret->framebuffer[0] = 0;
-    _ret->renderbuffer[1][0] = 0;
-    _ret->renderbuffer[1][1] = 0;
-    _ret->framebuffer[1] = 0;
-    _ret->zog = 0;
-    
-    g_mutex_init(&_ret->mutex);
-    
-    return _ret;
-    
-    Display* disp;
-    XVisualInfo* vizir;
-    GLXFBConfig *cfg;
-    Pixmap pm;
-    GLXPixmap glxpm;
-    GLXContext ctx;
-    
-    disp = XOpenDisplay(NULL);
-    derp = disp;
-    
-    int kaa, baa;
-    glXQueryVersion(disp, &kaa, &baa);
-    printf("GL VERSION: %d.%d\n", kaa, baa);
-    
-    const int sbAttrib[] = { GLX_RGBA,
-                            GLX_RED_SIZE, 1,
-                            GLX_GREEN_SIZE, 1,
-                            GLX_BLUE_SIZE, 1,
-                            None };
-   const int dbAttrib[] = { GLX_RGBA,
-                            GLX_RED_SIZE, 1,
-                            GLX_GREEN_SIZE, 1,
-                            GLX_BLUE_SIZE, 1,
-                            GLX_DOUBLEBUFFER,
-                            None };
-                            
-    int scrnum = DefaultScreen( disp );
-   Window root = RootWindow( disp, scrnum );
-
-   vizir = glXChooseVisual( disp, scrnum, (int *) sbAttrib );
-   if (!vizir) {
-      vizir = glXChooseVisual( disp, scrnum, (int *) dbAttrib );
-      if (!vizir) {
-         printf("Error: couldn't get an RGB visual\n");
-         return NULL;
-      }
-   }
-   
-    const int fb_attr[] = { 
-      GLX_RENDER_TYPE,    GLX_RGBA_BIT,
-      GLX_DRAWABLE_TYPE,  GLX_PBUFFER_BIT,
-      GLX_X_VISUAL_TYPE,  GLX_TRUE_COLOR,
-      GLX_DOUBLEBUFFER,   True,
-      GLX_X_RENDERABLE,   True,
-      GLX_RED_SIZE,       8,
-      GLX_GREEN_SIZE,     8,
-      GLX_BLUE_SIZE,      8,
-      GLX_ALPHA_SIZE,     8,
-      GLX_DEPTH_SIZE,     24,
-      GLX_STENCIL_SIZE,   8,
-      None 
-    };
-    int configs;
-    cfg = glXChooseFBConfig(disp, scrnum, (int *)&fb_attr, &configs);
-
-    if (!cfg)
-    {
-        printf("NO GOOD FBCONFIG\n");
-        return NULL;
-    }
-   
-    /*ctx = glXCreateContext( disp, vizir, NULL, True );
-    if (!ctx)
-    {
-        printf("Error: glXCreateContext failed\n");
-        return NULL;
-    }*/
-
-    PFNGLXCREATECONTEXTATTRIBSARBPROC createctx;
-    createctx = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB("glXCreateContextAttribsARB");
-    if (!createctx)
-    {
-        printf("bad shito\n");
-        return NULL;
-    }
-   
-    const int ctx_attr[] = 
-    {
-            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,//major,
-            GLX_CONTEXT_MINOR_VERSION_ARB, 2,//minor,
-            None
-    };
-    
-    ctx = glXCreateContextAttribsARB(disp, cfg[0], 0, True, ctx_attr);
-    if (!ctx)
-    {
-        printf("FAILED TO CREATE FANCYPANTS GL CONTEXT\n");
-        return NULL;
-    }
-   
-   //printf("CONTEXT GOOD. Direct rendering: %s\n", glXIsDirect(disp, ctx) ? "Yes" : "No");
-   
-    printf("blorp: %d\n", vizir->depth);
-    pm = XCreatePixmap(disp, root, 256, 384, vizir->depth);
-    if (!pm) printf("PIXMAP SHAT ITSELF\n");
-    else printf("PIXMAP GOOD\n");
-    
-    glxpm = glXCreateGLXPixmap(disp, vizir, pm);
-    if (!glxpm) printf("GLXPIXMAP SHAT ITSELF\n");
-    else printf("GLXPIXMAP GOOD\n");
-    
-    uiGLContext *ret = uiNew(uiGLContext);
-    printf("CREATE CTX: %p, %p\n", ret, g_thread_self());
-    ret->xdisp = disp;
-    ret->glxpm = glxpm;
-    ret->glxctx = ctx;
-    
-    return ret;
 }
 
 int uiGLGetFramebuffer(uiGLContext* ctx)
 {
-    return ctx->framebuffer[ctx->zog];// ? 0:1];
+    return ctx->framebuffer[ctx->backbuffer];// ? 0 : 1];
 }
 
 float uiGLGetFramebufferScale(uiGLContext* ctx)
@@ -473,91 +216,35 @@ float uiGLGetFramebufferScale(uiGLContext* ctx)
 
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
-    /*ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-    //gdk_gl_context_clear_current();
-    glWaitSync(ctx->sync, 0, GL_TIMEOUT_IGNORED);
-    glDeleteSync(ctx->sync);*/
-    /*printf("[%p] SWAPBUFFERS\n", gdk_gl_context_get_current());
-    glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT);
-    glFinish();*/
-    //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-    //glFlush();
-    //printf("SWAP: SYNC=%p\n", ctx->sync);
+    // nothing to do here, GTK will take care of this
     //glFinish();
-    nswaps++;
-}
-
-static volatile int _ctxset_done;
-
-gboolean _threadsafe_ctxset(gpointer data)
-{
-    uiGLContext* ctx = (uiGLContext*)data;
-    gtk_gl_area_make_current(ctx->gla);
-    _ctxset_done = 1;
-    return FALSE;
 }
 
 void uiGLMakeContextCurrent(uiGLContext* ctx)
 {
-	//if (!ctx) return;
-	/*if (g_thread_self() != gtkthread)
-	{
-	    _ctxset_done = 0;
-	    g_idle_add(_threadsafe_ctxset, ctx);
-	    while (!_ctxset_done);
-	}
-	else*/
-	//gtk_gl_area_make_current(ctx->gla);
-	/*printf("MAKE CONTEXT CURRENT %p, %p\n", ctx, g_thread_self());
-	if (!ctx)
-	{
-	    // BLERUGEHZFZF
-	    glXMakeCurrent(derp, None, NULL);
-	    return;
-	}
-	Bool ret = True;
-	if (glXGetCurrentContext() != ctx->glxctx)
-	{printf("DZJSKFLD\n");
-	    ret = glXMakeCurrent(ctx->xdisp, ctx->glxpm, ctx->glxctx);
-	    //glXMakeContextCurrent(ctx->xdisp, ctx->glxpm, ctx->glxpm, ctx->glxctx);
-	}
-	printf("WE MAED IT CURRENT: %d\n", ret);*/
-	
-	//printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL);
 	if (!ctx)
 	{
 	    gdk_gl_context_clear_current();
 	    return;
 	}
-	//gtk_gl_area_make_current(ctx->gla);
+
+    if (ctx->gctx == gdk_gl_context_get_current()) return;
 	gdk_gl_context_make_current(ctx->gctx);
-	GdkGLContext* burp = gdk_gl_context_get_current();
-	//gtk_gl_area_attach_buffers(ctx->gla);
-	//printf("burp = %p / %p\n", burp, ctx->gctx);
 }
 
 void uiGLBegin(uiGLContext* ctx)
 {
-    //g_mutex_lock(&ctx->mutex);
     if (g_thread_self() != gtkthread)
     {
-        g_mutex_lock(&glmutex);
-        
-        //int ret = glClientWaitSync(ctx->sync2, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50);
-        //printf("GLBEGIN: SYNC %p, %04X, %04X\n", ctx->sync2, ret, glGetError());
-        //glDeleteSync(ctx->sync2);
+        g_mutex_lock(&ctx->mutex);
     }
 }
 
 void uiGLEnd(uiGLContext* ctx)
 {
-    //g_mutex_unlock(&ctx->mutex);
     if (g_thread_self() != gtkthread)
     {
-        g_mutex_unlock(&glmutex);
-        
-        //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-        //glFlush();
+        g_mutex_unlock(&ctx->mutex);
     }
 }
 
@@ -568,7 +255,7 @@ void* a = dlsym(NULL, proc);
 void* b = glXGetProcAddress(proc);
 void* c = glXGetProcAddressARB(proc);
 printf("%p / %p / %p\n", a, b, c);
-return c;
+return a;
 	// this *will* break for older systems that don't have libglvnd!
 	// TODO: use a real solution
 	return dlsym(NULL /* RTLD_DEFAULT */, proc);
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
index 7a7b208..6f14091 100644
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ b/src/libui_sdl/libui/unix/uipriv_unix.h
@@ -68,6 +68,7 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path,
 extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min);
 extern void freeGLContext(uiGLContext* glctx);
 extern void areaPreRedrawGL(uiGLContext* glctx);
+extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
 extern void areaPostRedrawGL(uiGLContext* glctx);
 
 // notes:
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index fa6a2b5..a686cb4 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -66,7 +66,7 @@ uiWindow* MainWindow;
 uiArea* MainDrawArea;
 uiAreaHandler MainDrawAreaHandler;
 
-const u32 kGLVersions[] = {uiGLVersion(3,1), 0};
+const u32 kGLVersions[] = {uiGLVersion(3,2), uiGLVersion(3,1), 0};
 uiGLContext* GLContext;
 
 int WindowWidth, WindowHeight;
-- 
cgit v1.2.3


From 3ef00f8fa628dbc0d04c045d8736044afc929d97 Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Fri, 31 May 2019 02:21:41 +0200
Subject: attempt at fixing THE FLICKERING without making everything shitty.
 also, clean up code

---
 src/libui_sdl/libui/unix/gl.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index ab29abb..dbb30fa 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -3,6 +3,8 @@
 
 #include <GL/gl.h>
 
+void* glXGetProcAddressARB(const GLubyte* name);
+
 extern GThread* gtkthread;
 
 struct uiGLContext 
@@ -179,7 +181,6 @@ static void areaRellocRenderbuffer(uiGLContext* glctx)
 void areaPreRedrawGL(uiGLContext* glctx)
 {
     g_mutex_lock(&glctx->mutex);
-    glctx->backbuffer = glctx->backbuffer ? 0 : 1;
 }
 
 void areaPostRedrawGL(uiGLContext* glctx)
@@ -206,7 +207,7 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex
 
 int uiGLGetFramebuffer(uiGLContext* ctx)
 {
-    return ctx->framebuffer[ctx->backbuffer];// ? 0 : 1];
+    return ctx->framebuffer[ctx->backbuffer];
 }
 
 float uiGLGetFramebufferScale(uiGLContext* ctx)
@@ -216,8 +217,7 @@ float uiGLGetFramebufferScale(uiGLContext* ctx)
 
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
-    // nothing to do here, GTK will take care of this
-    //glFinish();
+    ctx->backbuffer = ctx->backbuffer ? 0 : 1;
 }
 
 void uiGLMakeContextCurrent(uiGLContext* ctx)
@@ -250,15 +250,15 @@ void uiGLEnd(uiGLContext* ctx)
 
 void *uiGLGetProcAddress(const char* proc)
 {
-printf("get: %s - ", proc);
-void* a = dlsym(NULL, proc);
-void* b = glXGetProcAddress(proc);
-void* c = glXGetProcAddressARB(proc);
-printf("%p / %p / %p\n", a, b, c);
-return a;
-	// this *will* break for older systems that don't have libglvnd!
-	// TODO: use a real solution
-	return dlsym(NULL /* RTLD_DEFAULT */, proc);
+	// TODO: consider using epoxy or something funny
+	
+	void* ptr = dlsym(NULL /* RTLD_DEFAULT */, proc);
+	if (ptr) return ptr;
+	
+	ptr = glXGetProcAddressARB((const GLubyte*)proc);
+	if (ptr) return ptr;
+	
+	return NULL;
 }
 unsigned int uiGLGetVersion(uiGLContext* ctx)
 {
-- 
cgit v1.2.3


From c49dec1acdf2b90cb53364efa4ed525259c387d9 Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Fri, 31 May 2019 03:00:53 +0200
Subject: try to fix fog consecutively to the Intel fix. still not perfect for
 whatever reason

also clean up more code
---
 src/GPU3D_OpenGL.cpp          |  7 +----
 src/GPU3D_OpenGL_shaders.h    | 26 ++++++++--------
 src/libui_sdl/libui/unix/gl.c | 71 +++++++++++++++----------------------------
 src/libui_sdl/main.cpp        | 15 +++++----
 4 files changed, 46 insertions(+), 73 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp
index 1b35fca..db2617c 100644
--- a/src/GPU3D_OpenGL.cpp
+++ b/src/GPU3D_OpenGL.cpp
@@ -187,12 +187,7 @@ void SetupDefaultTexParams(GLuint tex)
 bool Init()
 {
     GLint uni_id;
-
-    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
-    const GLubyte* version = glGetString(GL_VERSION); // version as a string
-    printf("OpenGL: renderer: %s\n", renderer);
-    printf("OpenGL: version: %s\n", version);
-
+    
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_STENCIL_TEST);
 
diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h
index a1aa95a..b12dc61 100644
--- a/src/GPU3D_OpenGL_shaders.h
+++ b/src/GPU3D_OpenGL_shaders.h
@@ -42,14 +42,14 @@ uniform uint uOpaquePolyID;
 uniform uint uFogFlag;
 
 out vec4 oColor;
-out uvec3 oAttr;
+out vec3 oAttr;
 
 void main()
 {
     oColor = vec4(uColor).bgra / 31.0;
-    oAttr.r = uOpaquePolyID;
-    oAttr.g = uint(0);
-    oAttr.b = uFogFlag;
+    oAttr.r = float(uOpaquePolyID) / 63.0;
+    oAttr.g = 0;
+    oAttr.b = float(uFogFlag);
 }
 )";
 
@@ -69,7 +69,7 @@ void main()
 const char* kFinalPassFS = kShaderHeader R"(
 
 uniform sampler2D DepthBuffer;
-uniform usampler2D AttrBuffer;
+uniform sampler2D AttrBuffer;
 
 layout(std140) uniform uConfig
 {
@@ -122,7 +122,7 @@ void main()
 
     vec4 ret = vec4(0,0,0,0);
     vec4 depth = texelFetch(DepthBuffer, coord, 0);
-    ivec4 attr = ivec4(texelFetch(AttrBuffer, coord, 0));
+    vec4 attr = texelFetch(AttrBuffer, coord, 0);
 
     if (attr.b != 0) ret = CalculateFog(depth.r);
 
@@ -178,7 +178,7 @@ smooth in vec2 fTexcoord;
 flat in ivec3 fPolygonAttr;
 
 out vec4 oColor;
-out uvec3 oAttr;
+out vec3 oAttr;
 
 int TexcoordWrap(int c, int maxc, int mode)
 {
@@ -618,8 +618,8 @@ void main()
     if (col.a < 30.5/31) discard;
 
     oColor = col;
-    oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F);
-    oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1);
+    oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0;
+    oAttr.b = float((fPolygonAttr.x >> 15) & 0x1);
 }
 )";
 
@@ -633,8 +633,8 @@ void main()
     if (col.a < 30.5/31) discard;
 
     oColor = col;
-    oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F);
-    oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1);
+    oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0;
+    oAttr.b = float((fPolygonAttr.x >> 15) & 0x1);
     gl_FragDepth = fZ;
 }
 )";
@@ -648,7 +648,7 @@ void main()
     if (col.a >= 30.5/31) discard;
 
     oColor = col;
-    oAttr.b = uint(0);
+    oAttr.b = 0;
 }
 )";
 
@@ -663,7 +663,7 @@ void main()
     if (col.a >= 30.5/31) discard;
 
     oColor = col;
-    oAttr.b = uint(0);
+    oAttr.b = 0;
     gl_FragDepth = fZ;
 }
 )";
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index dbb30fa..0511639 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -115,67 +115,46 @@ void freeGLContext(uiGLContext* glctx)
 
 static void areaAllocRenderbuffer(uiGLContext* glctx)
 {
-    _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height);
-    //glGenTextures(2, &glctx->renderbuffer[0]);
-    _glGenFramebuffers(2, &glctx->framebuffer[0]);printf("ylarg1 %04X\n", glGetError());
-    printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer[0]:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx);
-    /*glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[0]);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    // TODO: create textures as a fallback if GL_RGB renderbuffer isn't supported?
+    // they say GL implementations aren't required to support a GL_RGB renderbuffer
+    // however, a GL_RGBA one would cause gdk_cairo_draw_from_gl() to fall back to glReadPixels()
     
-    glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[1]);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);*/
-    
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg1 %04X\n", glGetError());
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg1 %04X\n", glGetError());
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
-    
-    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);printf("ylarg2 %04X\n", glGetError());
-    /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0);
-    _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg3 %04X\n", glGetError());
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg4 %04X\n", glGetError());
-    //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]);
+    _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);
+    _glGenFramebuffers(2, &glctx->framebuffer[0]);
     
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
+    //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
     
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg1 %04X\n", glGetError());
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg1 %04X\n", glGetError());
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError());
+    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
     
-    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);printf("ylarg2 %04X\n", glGetError());
-    /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0);
-    _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg3 %04X\n", glGetError());
-    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg4 %04X\n", glGetError());
-    //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]);
+    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
+    _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
+    //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
     
-    if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
-    printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
+    _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
     
-    int alpha_size;
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
-    _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size);
-    printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size);
+    //if (_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+    //    printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
 }
 
 static void areaRellocRenderbuffer(uiGLContext* glctx)
 {
     _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
+    //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
     
     _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
-    _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
-    _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
+    //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
+    //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
 }
 
 void areaPreRedrawGL(uiGLContext* glctx)
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index a686cb4..986a809 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -194,12 +194,11 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs)
 }
 
 bool GLScreen_Init()
-{printf("BEGINNING GL SHITO\n");
+{
+    // TODO: consider using epoxy?
     if (!OpenGL_Init())
         return false;
         
-    printf("GL INIT: %p, %p\n", glGenFramebuffers, glCreateShader);
-    
     const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
     const GLubyte* version = glGetString(GL_VERSION); // version as a string
     printf("OpenGL: renderer: %s\n", renderer);
@@ -211,7 +210,7 @@ bool GLScreen_Init()
         return false;
 
     memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
-printf("morp0\n");
+
     glGenBuffers(1, &GL_ShaderConfigUBO);
     glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO);
     glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW);
@@ -220,14 +219,14 @@ printf("morp0\n");
     glGenBuffers(1, &GL_ScreenVertexBufferID);
     glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GL_ScreenVertices), NULL, GL_STATIC_DRAW);
-printf("morp1\n");
+
     glGenVertexArrays(1, &GL_ScreenVertexArrayID);
     glBindVertexArray(GL_ScreenVertexArrayID);
     glEnableVertexAttribArray(0); // position
     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0));
     glEnableVertexAttribArray(1); // texcoord
     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4));
-printf("morp2\n");
+
     glGenTextures(1, &GL_ScreenTexture);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
@@ -238,7 +237,7 @@ printf("morp2\n");
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL);
 
     GL_ScreenSizeDirty = true;
-printf("morp3\n");
+
     return true;
 }
 
@@ -394,7 +393,7 @@ void GLScreen_DrawScreen()
 
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
 
-    glClearColor(0, 0, 1, 1);
+    glClearColor(0, 0, 0, 1);
     glClear(GL_COLOR_BUFFER_BIT);
 
     int frontbuf = GPU::FrontBuffer;
-- 
cgit v1.2.3


From 464b1169165b2e4d866c033e4c3288c9742539a8 Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Fri, 31 May 2019 04:15:37 +0200
Subject: fix the whole mutex shito

fixes potential crash when resizing window
---
 src/libui_sdl/libui/unix/area.c        | 28 ++++++++++++----------------
 src/libui_sdl/libui/unix/gl.c          | 33 +++++++++++----------------------
 src/libui_sdl/libui/unix/main.c        | 17 +++++------------
 src/libui_sdl/libui/unix/uipriv_unix.h | 17 -----------------
 src/libui_sdl/main.cpp                 |  6 ------
 5 files changed, 28 insertions(+), 73 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
index 62fe512..5734b4b 100644
--- a/src/libui_sdl/libui/unix/area.c
+++ b/src/libui_sdl/libui/unix/area.c
@@ -3,6 +3,18 @@
 
 extern GThread* gtkthread;
 
+// notes:
+// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
+#define areaWidgetType (areaWidget_get_type())
+#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget))
+#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType))
+#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass))
+#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget))
+#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass))
+
+typedef struct areaWidget areaWidget;
+typedef struct areaWidgetClass areaWidgetClass;
+
 struct areaWidget {
 	GtkDrawingArea parent_instance;
 	uiArea *a;
@@ -131,22 +143,6 @@ static void loadAreaSize(uiArea *a, double *width, double *height)
 	}
 }
 
-void areaPreRedraw(areaWidget* widget)
-{
-    uiArea* a = widget->a;
-    if (!a->opengl) return;
-    
-    areaPreRedrawGL(a->glContext);
-}
-
-void areaPostRedraw(areaWidget* widget)
-{
-    uiArea* a = widget->a;
-    if (!a->opengl) return;
-    
-    areaPostRedrawGL(a->glContext);
-}
-
 static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
 {
 	areaWidget *aw = areaWidget(w);
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index 0511639..6965969 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -6,6 +6,7 @@
 void* glXGetProcAddressARB(const GLubyte* name);
 
 extern GThread* gtkthread;
+extern GMutex glmutex;
 
 struct uiGLContext 
 {
@@ -15,8 +16,6 @@ struct uiGLContext
 	GdkGLContext *gctx;
 	int vermaj, vermin;
 	
-	GMutex mutex;
-	
 	int width, height;
 	int scale;
 	GLuint renderbuffer[2][2];
@@ -96,8 +95,6 @@ uiGLContext *createGLContext(GtkWidget* widget, int maj, int min)
 	areaAllocRenderbuffer(ctx);
 	ctx->backbuffer = 0;
 	
-	g_mutex_init(&ctx->mutex);
-	
 	ctx->widget = widget;
 	ctx->window = gdkwin;
 	ctx->gctx = gctx;
@@ -144,7 +141,7 @@ static void areaAllocRenderbuffer(uiGLContext* glctx)
     //    printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
 }
 
-static void areaRellocRenderbuffer(uiGLContext* glctx)
+static void areaReallocRenderbuffer(uiGLContext* glctx)
 {
     _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
     _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
@@ -157,16 +154,6 @@ static void areaRellocRenderbuffer(uiGLContext* glctx)
     //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
 }
 
-void areaPreRedrawGL(uiGLContext* glctx)
-{
-    g_mutex_lock(&glctx->mutex);
-}
-
-void areaPostRedrawGL(uiGLContext* glctx)
-{
-    g_mutex_unlock(&glctx->mutex);
-}
-
 void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx)
 {
     int window_scale = gdk_window_get_scale_factor(glctx->window);
@@ -176,12 +163,14 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex
         glctx->width = dp->AreaWidth;
         glctx->height = dp->AreaHeight;
         glctx->scale = window_scale;
-        areaRellocRenderbuffer(glctx);
+        areaReallocRenderbuffer(glctx);
+    }
+    else
+    {
+        gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), 
+                               glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, 
+                               1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
     }
-    
-    gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), 
-                           glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, 
-                           1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
 }
 
 int uiGLGetFramebuffer(uiGLContext* ctx)
@@ -215,7 +204,7 @@ void uiGLBegin(uiGLContext* ctx)
 {
     if (g_thread_self() != gtkthread)
     {
-        g_mutex_lock(&ctx->mutex);
+        g_mutex_lock(&glmutex);
     }
 }
 
@@ -223,7 +212,7 @@ void uiGLEnd(uiGLContext* ctx)
 {
     if (g_thread_self() != gtkthread)
     {
-        g_mutex_unlock(&ctx->mutex);
+        g_mutex_unlock(&glmutex);
     }
 }
 
diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c
index 66bd335..516bd76 100644
--- a/src/libui_sdl/libui/unix/main.c
+++ b/src/libui_sdl/libui/unix/main.c
@@ -5,24 +5,16 @@ uiInitOptions options;
 
 // kind of a hack
 GThread* gtkthread;
-
 GMutex glmutex;
-int boub(GtkWidget* w);
-void baba(GtkWidget* w);
 
 static void _eventfilter(GdkEvent* evt, gpointer data)
 {
     if (evt->type == GDK_EXPOSE)
     {
-        GtkWidget* widget = gtk_get_event_widget(evt);
-        if (isAreaWidget(widget))
-        {
-            areaWidget* area = areaWidget(widget);
-            areaPreRedraw(area);
-            gtk_main_do_event(evt);
-            areaPostRedraw(area);
-            return;
-        }
+        g_mutex_lock(&glmutex);
+        gtk_main_do_event(evt);
+        g_mutex_unlock(&glmutex);
+        return;
     }
     
     gtk_main_do_event(evt);
@@ -48,6 +40,7 @@ const char *uiInit(uiInitOptions *o)
 	loadFutures();
 	
 	gtkthread = g_thread_self();
+	g_mutex_init(&glmutex);
 	
 	GList* iconlist = NULL;
 	iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_16x16.png", NULL));
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
index 6f14091..9b77188 100644
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ b/src/libui_sdl/libui/unix/uipriv_unix.h
@@ -67,22 +67,5 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path,
 // gl.c
 extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min);
 extern void freeGLContext(uiGLContext* glctx);
-extern void areaPreRedrawGL(uiGLContext* glctx);
 extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
-extern void areaPostRedrawGL(uiGLContext* glctx);
-
-// notes:
-// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
-#define areaWidgetType (areaWidget_get_type())
-#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget))
-#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType))
-#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass))
-#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget))
-#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass))
-
-typedef struct areaWidget areaWidget;
-typedef struct areaWidgetClass areaWidgetClass;
-
-extern void areaPreRedraw(areaWidget* widget);
-extern void areaPostRedraw(areaWidget* widget);
 
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 74d3fc9..6cc6c50 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -430,12 +430,6 @@ void GLScreen_DrawScreen()
     uiGLSwapBuffers(GLContext);
 }
 
-void norp(void* data)
-{
-    uiGLMakeContextCurrent(GLContext);
-    GLScreen_DrawScreen();
-}
-
 void MicLoadWav(char* name)
 {
     SDL_AudioSpec format;
-- 
cgit v1.2.3


From f6814e02c02a0ad68af107e7605c08ee47de79f4 Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Fri, 31 May 2019 21:37:30 +0200
Subject: * add needed libui functions under Windows, even if they don't do a
 whole lot * fix ass-stupid fog bug

---
 src/GPU3D_OpenGL.cpp               |  5 +----
 src/GPU3D_OpenGL_shaders.h         |  9 +++++++--
 src/libui_sdl/libui/windows/gl.cpp | 19 +++++++++++++++++++
 3 files changed, 27 insertions(+), 6 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp
index db2617c..95243d1 100644
--- a/src/GPU3D_OpenGL.cpp
+++ b/src/GPU3D_OpenGL.cpp
@@ -187,7 +187,7 @@ void SetupDefaultTexParams(GLuint tex)
 bool Init()
 {
     GLint uni_id;
-    
+
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_STENCIL_TEST);
 
@@ -1043,9 +1043,6 @@ void RenderFrame()
         {
             if (RenderPolygonRAM[i]->Degenerate) continue;
 
-            // zog.
-            //if (RenderPolygonRAM[i]->YBottom <= 96 || RenderPolygonRAM[i]->YTop >= 144) continue;
-
             SetupPolygon(&PolygonList[npolys], RenderPolygonRAM[i]);
             if (firsttrans < 0 && RenderPolygonRAM[i]->Translucent)
                 firsttrans = npolys;
diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h
index b12dc61..4c5b82e 100644
--- a/src/GPU3D_OpenGL_shaders.h
+++ b/src/GPU3D_OpenGL_shaders.h
@@ -42,7 +42,7 @@ uniform uint uOpaquePolyID;
 uniform uint uFogFlag;
 
 out vec4 oColor;
-out vec3 oAttr;
+out vec4 oAttr;
 
 void main()
 {
@@ -50,6 +50,7 @@ void main()
     oAttr.r = float(uOpaquePolyID) / 63.0;
     oAttr.g = 0;
     oAttr.b = float(uFogFlag);
+    oAttr.a = 1;
 }
 )";
 
@@ -178,7 +179,7 @@ smooth in vec2 fTexcoord;
 flat in ivec3 fPolygonAttr;
 
 out vec4 oColor;
-out vec3 oAttr;
+out vec4 oAttr;
 
 int TexcoordWrap(int c, int maxc, int mode)
 {
@@ -620,6 +621,7 @@ void main()
     oColor = col;
     oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0;
     oAttr.b = float((fPolygonAttr.x >> 15) & 0x1);
+    oAttr.a = 1;
 }
 )";
 
@@ -635,6 +637,7 @@ void main()
     oColor = col;
     oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0;
     oAttr.b = float((fPolygonAttr.x >> 15) & 0x1);
+    oAttr.a = 1;
     gl_FragDepth = fZ;
 }
 )";
@@ -649,6 +652,7 @@ void main()
 
     oColor = col;
     oAttr.b = 0;
+    oAttr.a = 1;
 }
 )";
 
@@ -664,6 +668,7 @@ void main()
 
     oColor = col;
     oAttr.b = 0;
+    oAttr.a = 1;
     gl_FragDepth = fZ;
 }
 )";
diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp
index 1e3732c..c621721 100644
--- a/src/libui_sdl/libui/windows/gl.cpp
+++ b/src/libui_sdl/libui/windows/gl.cpp
@@ -135,8 +135,27 @@ void *uiGLGetProcAddress(const char* proc)
     return (void*)wglGetProcAddress(proc);
 }
 
+void uiGLBegin(uiGLContext* ctx)
+{
+}
+
+void uiGLEnd(uiGLContext* ctx)
+{
+}
+
 void uiGLSwapBuffers(uiGLContext* ctx)
 {
     if (ctx == NULL) return;
     SwapBuffers(ctx->dc);
 }
+
+int uiGLGetFramebuffer(uiGLContext* ctx)
+{
+    return 0;
+}
+
+float uiGLGetFramebufferScale(uiGLContext* ctx)
+{
+    // TODO
+    return 1;
+}
-- 
cgit v1.2.3


From b9529e83619f1e2b725ea86508b546d72e072a0c Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Sat, 1 Jun 2019 00:27:54 +0200
Subject: Linux: fix uiGLGetProcAddress()

---
 src/CMakeLists.txt            |  2 +-
 src/libui_sdl/libui/unix/gl.c | 13 +++++++++----
 2 files changed, 10 insertions(+), 5 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d096c02..a1110f1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -29,5 +29,5 @@ add_library(core STATIC
 if (WIN32)
 	target_link_libraries(core ole32 comctl32 ws2_32 opengl32)
 else()
-	target_link_libraries(core GL)
+	target_link_libraries(core GL EGL)
 endif()
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index 6965969..4a180ef 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -2,8 +2,8 @@
 #include "uipriv_unix.h"
 
 #include <GL/gl.h>
-
-void* glXGetProcAddressARB(const GLubyte* name);
+#include <GL/glx.h>
+#include <EGL/egl.h>
 
 extern GThread* gtkthread;
 extern GMutex glmutex;
@@ -220,10 +220,15 @@ void *uiGLGetProcAddress(const char* proc)
 {
 	// TODO: consider using epoxy or something funny
 	
-	void* ptr = dlsym(NULL /* RTLD_DEFAULT */, proc);
+	void* ptr;
+
+	ptr = glXGetProcAddressARB((const GLubyte*)proc);
+	if (ptr) return ptr;
+	
+	ptr = eglGetProcAddress(proc);
 	if (ptr) return ptr;
 	
-	ptr = glXGetProcAddressARB((const GLubyte*)proc);
+	ptr = dlsym(NULL /* RTLD_DEFAULT */, proc);
 	if (ptr) return ptr;
 	
 	return NULL;
-- 
cgit v1.2.3


From 6f5e45ef2cb451249bf160141fccc0f2a0262357 Mon Sep 17 00:00:00 2001
From: StapleButter <thetotalworm@gmail.com>
Date: Thu, 30 May 2019 23:16:56 +0200
Subject: also, properly delete glarea framebuffers on exit

---
 src/libui_sdl/libui/unix/gl.c | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
index 4a180ef..e1665ee 100644
--- a/src/libui_sdl/libui/unix/gl.c
+++ b/src/libui_sdl/libui/unix/gl.c
@@ -105,6 +105,11 @@ uiGLContext *createGLContext(GtkWidget* widget, int maj, int min)
 void freeGLContext(uiGLContext* glctx)
 {
     if (glctx == NULL) return;
+    
+    gdk_gl_context_make_current(glctx->gctx);
+    _glDeleteRenderbuffers(4, &glctx->renderbuffer[0][0]);
+    _glDeleteFramebuffers(2, &glctx->framebuffer[0]);
+    
     gdk_gl_context_clear_current();
     g_object_unref(glctx->gctx);
     uiFree(glctx);
-- 
cgit v1.2.3


From 4a4415fc2ec067fb79881e17e14953b69ef80e0c Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Mon, 3 Jun 2019 15:00:49 +0200
Subject: more work on OSD

---
 src/libui_sdl/OSD.cpp                | 132 +++++++++++++++++++++++++----------
 src/libui_sdl/OSD.h                  |   9 ++-
 src/libui_sdl/libui/ui.h             |   2 +-
 src/libui_sdl/libui/unix/draw.c      |   4 +-
 src/libui_sdl/libui/windows/draw.cpp |   5 +-
 src/libui_sdl/main.cpp               |  39 ++++++++---
 6 files changed, 133 insertions(+), 58 deletions(-)

(limited to 'src/libui_sdl/libui')

diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp
index bce14c1..a13ff44 100644
--- a/src/libui_sdl/OSD.cpp
+++ b/src/libui_sdl/OSD.cpp
@@ -18,14 +18,14 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <queue>
+#include <deque>
 #include <SDL2/SDL.h>
 #include "../types.h"
-#include "OSD.h"
 
 #include "libui/ui.h"
 #include "../OpenGLSupport.h"
 
+#include "OSD.h"
 #include "font.h"
 
 extern int WindowWidth, WindowHeight;
@@ -38,6 +38,9 @@ const u32 kOSDMargin = 6;
 typedef struct
 {
     Uint32 Timestamp;
+    char Text[256];
+    u32 Color;
+
     u32 Width, Height;
     u32* Bitmap;
 
@@ -49,15 +52,28 @@ typedef struct
 
 } Item;
 
-std::queue<Item*> CurrentItems;
+std::deque<Item*> ItemQueue;
 
 
-bool Init()
+bool Init(bool opengl)
 {
+    return true;
 }
 
-void DeInit()
+void DeInit(bool opengl)
 {
+    for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
+    {
+        Item* item = *it;
+
+        if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
+        if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
+        if (item->Bitmap) delete[] item->Bitmap;
+
+        delete item;
+
+        ItemQueue.erase(it);
+    }
 }
 
 
@@ -142,7 +158,7 @@ u32 RainbowColor(u32 inc)
 {
     // inspired from Acmlmboard
 
-    if      (inc < 100) return 0xFFFF9BFF + (inc << 8);
+    if      (inc < 100) return 0xFFFF9B9B + (inc << 8);
     else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16);
     else if (inc < 300) return 0xFF9BFF9B + (inc-200);
     else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8);
@@ -156,10 +172,10 @@ void RenderText(u32 color, const char* text, Item* item)
     int breaks[64];
 
     bool rainbow = (color == 0);
-    u32 rainbowinc = rand() % 600;
+    u32 rainbowinc = (text[0] * 17) % 600;
 
     color |= 0xFF000000;
-    const u32 shadow = 0xC0000000;
+    const u32 shadow = 0xFE000000;
 
     LayoutText(text, &w, &h, breaks);
 
@@ -257,49 +273,89 @@ void RenderText(u32 color, const char* text, Item* item)
     }
 }
 
-void test(u32* berp)
+
+void AddMessage(u32 color, const char* text)
 {
-    Item barp;
-    RenderText(0x000000, "This is a test of OSD, it can display really long messages, like thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis. Also, pancakes are the best thing ever.", &barp);
+    Item* item = new Item;
+
+    item->Timestamp = SDL_GetTicks();
+    strncpy(item->Text, text, 255); item->Text[255] = '\0';
+    item->Color = color;
+    item->Bitmap = NULL;
 
-    for (int y = 0; y < barp.Height; y++)
+    item->DrawBitmapLoaded = false;
+    item->GLTextureLoaded = false;
+
+    ItemQueue.push_back(item);
+}
+
+void WindowResized(bool opengl)
+{
+    /*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
     {
-        for (int x = 0; x < barp.Width; x++)
-        {
-            u32 src = barp.Bitmap[(y*barp.Width)+x];
-            u32 dst = berp[((y+6)*256)+x+6];
+        Item* item = *it;
 
-            u32 sR = (src >> 16) & 0xFF;
-            u32 sG = (src >>  8) & 0xFF;
-            u32 sB = (src      ) & 0xFF;
-            u32 sA = (src >> 24) & 0xFF;
+        if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
+        //if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
 
-            u32 dR = (dst >> 16) & 0xFF;
-            u32 dG = (dst >>  8) & 0xFF;
-            u32 dB = (dst      ) & 0xFF;
+        item->DrawBitmapLoaded = false;
+        item->GLTextureLoaded = false;
 
-            dR = ((sR * sA) + (dR * (255-sA))) >> 8;
-            dG = ((sG * sA) + (dG * (255-sA))) >> 8;
-            dB = ((sB * sA) + (dB * (255-sA))) >> 8;
+        if (item->Bitmap) delete[] item->Bitmap;
 
-            dst = (dR << 16) | (dG << 8) | dB;
+        it++;
+    }*/
+}
+
+void Update(bool opengl, uiAreaDrawParams* params)
+{
+    Uint32 tick_now = SDL_GetTicks();
+    Uint32 tick_min = tick_now - 2500;
+    u32 y = kOSDMargin;
+
+    for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
+    {
+        Item* item = *it;
 
-            berp[((y+6)*256)+x+6] = dst | 0xFF000000;
+        if (item->Timestamp < tick_min)
+        {
+            if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
+            if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
+            if (item->Bitmap) delete[] item->Bitmap;
+
+            delete item;
+
+            ItemQueue.erase(it);
+            continue;
         }
-    }
 
-    delete[] barp.Bitmap;
-}
+        if (!item->Bitmap)
+        {
+            RenderText(item->Color, item->Text, item);
+        }
+
+        if (opengl)
+        {
+            //
+        }
+        else
+        {
+            if (!item->DrawBitmapLoaded)
+            {
+                item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1);
+                uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap);
+                item->DrawBitmapLoaded = true;
+            }
 
+            uiRect rc_src = {0, 0, item->Width, item->Height};
+            uiRect rc_dst = {kOSDMargin, y, item->Width, item->Height};
 
-void AddMessage(u32 color, const char* text)
-{
-    //
-}
+            uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0);
+        }
 
-void Update(bool opengl)
-{
-    //
+        y += item->Height;
+        it++;
+    }
 }
 
 }
diff --git a/src/libui_sdl/OSD.h b/src/libui_sdl/OSD.h
index ed38490..afe403f 100644
--- a/src/libui_sdl/OSD.h
+++ b/src/libui_sdl/OSD.h
@@ -22,14 +22,13 @@
 namespace OSD
 {
 
-bool Init();
-void DeInit();
-
-void test(u32* berp);
+bool Init(bool opengl);
+void DeInit(bool opengl);
 
 void AddMessage(u32 color, const char* text);
 
-void Update(bool opengl);
+void WindowResized(bool opengl);
+void Update(bool opengl, uiAreaDrawParams* params);
 
 }
 
diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h
index 47da54b..e15c127 100644
--- a/src/libui_sdl/libui/ui.h
+++ b/src/libui_sdl/libui/ui.h
@@ -516,7 +516,7 @@ _UI_EXTERN void uiDrawSave(uiDrawContext *c);
 _UI_EXTERN void uiDrawRestore(uiDrawContext *c);
 
 // bitmap API
-_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height);
+_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha);
 _UI_EXTERN void uiDrawBitmapUpdate(uiDrawBitmap* bmp, const void* data);
 _UI_EXTERN void uiDrawBitmapDraw(uiDrawContext* c, uiDrawBitmap* bmp, uiRect* srcrect, uiRect* dstrect, int filter);
 _UI_EXTERN void uiDrawFreeBitmap(uiDrawBitmap* bmp);
diff --git a/src/libui_sdl/libui/unix/draw.c b/src/libui_sdl/libui/unix/draw.c
index e55397e..5befcd3 100644
--- a/src/libui_sdl/libui/unix/draw.c
+++ b/src/libui_sdl/libui/unix/draw.c
@@ -143,13 +143,13 @@ void uiDrawRestore(uiDrawContext *c)
 
 // bitmap API
 
-uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
+uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha)
 {
     uiDrawBitmap* bmp;
     
     bmp = uiNew(uiDrawBitmap);
     
-    bmp->bmp = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+    bmp->bmp = cairo_image_surface_create(alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
     if (cairo_surface_status(bmp->bmp) != CAIRO_STATUS_SUCCESS)
 		implbug("error creating bitmap: %s",
 			cairo_status_to_string(cairo_surface_status(bmp->bmp)));
diff --git a/src/libui_sdl/libui/windows/draw.cpp b/src/libui_sdl/libui/windows/draw.cpp
index 11a777d..9a815b9 100644
--- a/src/libui_sdl/libui/windows/draw.cpp
+++ b/src/libui_sdl/libui/windows/draw.cpp
@@ -522,7 +522,7 @@ void uiDrawRestore(uiDrawContext *c)
 
 // bitmap API
 
-uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
+uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha)
 {
     uiDrawBitmap* bmp;
     HRESULT hr;
@@ -532,7 +532,8 @@ uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
     D2D1_BITMAP_PROPERTIES bp2 = D2D1::BitmapProperties();
     bp2.dpiX = 0;
     bp2.dpiY = 0;
-    bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
+    bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
+                                        alpha ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE);
 
     //c->rt->BeginDraw();
 
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 73666cd..5407403 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -434,6 +434,8 @@ void GLScreen_DrawScreen()
         glDrawArrays(GL_TRIANGLES, 0, 4*3);
     }
 
+    OSD::Update(true, NULL);
+
     glFlush();
     uiGLSwapBuffers(GLContext);
 }
@@ -948,7 +950,15 @@ int EmuThreadFunc(void* burp)
     NDS::DeInit();
     Platform::LAN_DeInit();
 
-    if (Screen_UseGL) GLScreen_DeInit();
+    if (Screen_UseGL)
+    {
+        uiGLMakeContextCurrent(GLContext);
+        OSD::DeInit(true);
+        GLScreen_DeInit();
+        uiGLMakeContextCurrent(NULL);
+    }
+    else
+        OSD::DeInit(false);
 
     return 44203;
 }
@@ -962,8 +972,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
         if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]);
 
         ScreenDrawInited = true;
-        ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192);
-        ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192);
+        ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192, 0);
+        ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192, 0);
     }
 
     int frontbuf = GPU::FrontBuffer;
@@ -973,8 +983,6 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
     uiRect top = {0, 0, 256, 192};
     uiRect bot = {0, 0, 256, 192};
 
-    //OSD::test(GPU::Framebuffer[frontbuf][0]);
-
     uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]);
     uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]);
 
@@ -987,6 +995,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
     uiDrawTransform(params->Context, &BottomScreenTrans);
     uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1);
     uiDrawRestore(params->Context);
+
+    OSD::Update(false, params);
 }
 
 void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* evt)
@@ -1118,7 +1128,8 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
             MicCommand |= 1;
 
         if (evt->Scancode == 0x57) // F11
-            NDS::debug(0);
+            OSD::AddMessage(0, "OSD test");
+            //NDS::debug(0);
     }
 
     return 1;
@@ -1374,15 +1385,17 @@ void OnAreaResize(uiAreaHandler* handler, uiArea* area, int width, int height)
     WindowWidth = width;
     WindowHeight = height;
 
-    int max = uiWindowMaximized(MainWindow);
-    int min = uiWindowMinimized(MainWindow);
+    int ismax = uiWindowMaximized(MainWindow);
+    int ismin = uiWindowMinimized(MainWindow);
 
-    Config::WindowMaximized = max;
-    if (!max && !min)
+    Config::WindowMaximized = ismax;
+    if (!ismax && !ismin)
     {
         Config::WindowWidth = width;
         Config::WindowHeight = height;
     }
+
+    OSD::WindowResized(Screen_UseGL);
 }
 
 
@@ -2061,6 +2074,10 @@ void ApplyNewSettings(int type)
                 if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
             }
 
+            if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);
+            OSD::DeInit(Screen_UseGL);
+            if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
+
             Screen_UseGL = usegl;
             RecreateMainWindow(usegl);
 
@@ -2294,6 +2311,8 @@ void CreateMainWindow(bool opengl)
         RecreateMainWindow(false);
         Screen_UseGL = false;
     }
+
+    OSD::Init(opengl);
 }
 
 void DestroyMainWindow()
-- 
cgit v1.2.3