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) --- melonDS.cbp | 1 + 1 file changed, 1 insertion(+) (limited to 'melonDS.cbp') 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" /> -- 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 'melonDS.cbp') 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 b730bb890207d206505c338178fd49d244cd554d Mon Sep 17 00:00:00 2001 From: Arisotura <thetotalworm@gmail.com> Date: Sat, 11 May 2019 15:36:42 +0200 Subject: welp --- melonDS.cbp | 2 + src/libui_sdl/DlgVideoSettings.cpp | 150 +++++++++++++++++++++++++++++++++++++ src/libui_sdl/DlgVideoSettings.h | 29 +++++++ src/libui_sdl/main.cpp | 8 ++ 4 files changed, 189 insertions(+) create mode 100644 src/libui_sdl/DlgVideoSettings.cpp create mode 100644 src/libui_sdl/DlgVideoSettings.h (limited to 'melonDS.cbp') diff --git a/melonDS.cbp b/melonDS.cbp index 0ba8653..b396861 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -131,6 +131,8 @@ <Unit filename="src/libui_sdl/DlgEmuSettings.h" /> <Unit filename="src/libui_sdl/DlgInputConfig.cpp" /> <Unit filename="src/libui_sdl/DlgInputConfig.h" /> + <Unit filename="src/libui_sdl/DlgVideoSettings.cpp" /> + <Unit filename="src/libui_sdl/DlgVideoSettings.h" /> <Unit filename="src/libui_sdl/DlgWifiSettings.cpp" /> <Unit filename="src/libui_sdl/DlgWifiSettings.h" /> <Unit filename="src/libui_sdl/LAN_PCap.cpp" /> diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp new file mode 100644 index 0000000..f27a80b --- /dev/null +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -0,0 +1,150 @@ +/* + 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 <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libui/ui.h" + +#include "../types.h" +#include "PlatformConfig.h" + +#include "DlgVideoSettings.h" + + +// + + +namespace DlgVideoSettings +{ + +bool opened; +uiWindow* win; + +// + + +int OnCloseWindow(uiWindow* window, void* blarg) +{ + opened = false; + return 1; +} + +// + +void OnCancel(uiButton* btn, void* blarg) +{ + // restore old settings here + + uiControlDestroy(uiControl(win)); + opened = false; +} + +void OnOk(uiButton* btn, void* blarg) +{ + // set config entries here + + Config::Save(); + + uiControlDestroy(uiControl(win)); + opened = false; +} + +void Open() +{ + if (opened) + { + uiControlSetFocus(uiControl(win)); + return; + } + + opened = true; + win = uiNewWindow("Video settings - melonDS", 400, 100, 0, 0, 0); + uiWindowSetMargined(win, 1); + uiWindowOnClosing(win, OnCloseWindow, NULL); + + uiBox* top = uiNewVerticalBox(); + uiWindowSetChild(win, uiControl(top)); + uiBoxSetPadded(top, 1); + + /*{ + uiGroup* grp = uiNewGroup("Audio output"); + uiBoxAppend(top, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); + + uiLabel* label_vol = uiNewLabel("Volume:"); + uiBoxAppend(in_ctrl, uiControl(label_vol), 0); + + slVolume = uiNewSlider(0, 256); + uiSliderOnChanged(slVolume, OnVolumeChanged, NULL); + uiBoxAppend(in_ctrl, uiControl(slVolume), 0); + } + + { + uiGroup* grp = uiNewGroup("Microphone input"); + uiBoxAppend(top, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); + + rbMicInputType = uiNewRadioButtons(); + uiRadioButtonsAppend(rbMicInputType, "None"); + uiRadioButtonsAppend(rbMicInputType, "Microphone"); + uiRadioButtonsAppend(rbMicInputType, "White noise"); + uiRadioButtonsAppend(rbMicInputType, "WAV file:"); + uiBoxAppend(in_ctrl, uiControl(rbMicInputType), 0); + + uiBox* path_box = uiNewHorizontalBox(); + uiBoxAppend(in_ctrl, uiControl(path_box), 0); + + txMicWavPath = uiNewEntry(); + uiBoxAppend(path_box, uiControl(txMicWavPath), 1); + + uiButton* path_browse = uiNewButton("..."); + uiButtonOnClicked(path_browse, OnMicWavBrowse, NULL); + uiBoxAppend(path_box, uiControl(path_browse), 0); + }*/ + + { + uiBox* in_ctrl = uiNewHorizontalBox(); + uiBoxSetPadded(in_ctrl, 1); + uiBoxAppend(top, uiControl(in_ctrl), 0); + + uiLabel* dummy = uiNewLabel(""); + uiBoxAppend(in_ctrl, uiControl(dummy), 1); + + uiButton* btncancel = uiNewButton("Cancel"); + uiButtonOnClicked(btncancel, OnCancel, NULL); + uiBoxAppend(in_ctrl, uiControl(btncancel), 0); + + uiButton* btnok = uiNewButton("Ok"); + uiButtonOnClicked(btnok, OnOk, NULL); + uiBoxAppend(in_ctrl, uiControl(btnok), 0); + } + + // + + uiControlShow(uiControl(win)); +} + +} diff --git a/src/libui_sdl/DlgVideoSettings.h b/src/libui_sdl/DlgVideoSettings.h new file mode 100644 index 0000000..cd3d1b1 --- /dev/null +++ b/src/libui_sdl/DlgVideoSettings.h @@ -0,0 +1,29 @@ +/* + 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 DLGVIDEOSETTINGS_H +#define DLGVIDEOSETTINGS_H + +namespace DlgVideoSettings +{ + +void Open(); + +} + +#endif // DLGVIDEOSETTINGS_H diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b3fce3f..a8a5ceb 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -30,6 +30,7 @@ #include "DlgEmuSettings.h" #include "DlgInputConfig.h" +#include "DlgVideoSettings.h" #include "DlgAudioSettings.h" #include "DlgWifiSettings.h" @@ -1502,6 +1503,11 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) DlgInputConfig::Open(1); } +void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) +{ + DlgVideoSettings::Open(); +} + void OnOpenAudioSettings(uiMenuItem* item, uiWindow* window, void* blarg) { DlgAudioSettings::Open(); @@ -1865,6 +1871,8 @@ int main(int argc, char** argv) uiMenuItemOnClicked(menuitem, OnOpenInputConfig, NULL); menuitem = uiMenuAppendItem(menu, "Hotkey config"); uiMenuItemOnClicked(menuitem, OnOpenHotkeyConfig, NULL); + menuitem = uiMenuAppendItem(menu, "Video settings"); + uiMenuItemOnClicked(menuitem, OnOpenVideoSettings, NULL); menuitem = uiMenuAppendItem(menu, "Audio settings"); uiMenuItemOnClicked(menuitem, OnOpenAudioSettings, NULL); menuitem = uiMenuAppendItem(menu, "Wifi settings"); -- 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 'melonDS.cbp') 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 'melonDS.cbp') 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 c81bcccadc9ac8394ba8d4a836d7c954dd528751 Mon Sep 17 00:00:00 2001 From: Arisotura <thetotalworm@gmail.com> Date: Thu, 16 May 2019 16:27:45 +0200 Subject: BAHAHAHAHAHAHAHAA --- melonDS.cbp | 1 + src/GPU.cpp | 40 +-- src/GPU.h | 2 +- src/GPU2D.cpp | 169 +++++++----- src/GPU2D.h | 4 +- src/GPU3D.cpp | 4 +- src/GPU3D.h | 9 +- src/GPU3D_OpenGL43.cpp | 641 +----------------------------------------- src/GPU3D_OpenGL43_shaders.h | 645 +++++++++++++++++++++++++++++++++++++++++++ src/GPU3D_Soft.cpp | 7 +- src/libui_sdl/main.cpp | 19 +- 11 files changed, 813 insertions(+), 728 deletions(-) create mode 100644 src/GPU3D_OpenGL43_shaders.h (limited to 'melonDS.cbp') diff --git a/melonDS.cbp b/melonDS.cbp index ff01ebf..0bdac7f 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -107,6 +107,7 @@ <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_Soft.cpp" /> <Unit filename="src/NDS.cpp" /> <Unit filename="src/NDS.h" /> diff --git a/src/GPU.cpp b/src/GPU.cpp index f4e9fd4..1d073f5 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; int FBScale[2]; +bool Accelerated; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -88,9 +89,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - FBScale[0] = -1; FBScale[1] = -1; - //SetFramebufferScale(1); - SetFramebufferScale(1, 1); + FBScale[0] = -1; FBScale[1] = -1; Accelerated = false; + SetDisplaySettings(0, 0, false); return true; } @@ -247,13 +247,15 @@ void AssignFramebuffers() } } -void SetFramebufferScale(int top, int bottom) -{ - if (top != FBScale[0]) +void SetDisplaySettings(int topscale, int bottomscale, bool accel) +{accel=true; + if (topscale != FBScale[0] || accel != Accelerated) { - FBScale[0] = top; + FBScale[0] = accel ? 0 : topscale; - int fbsize = (256 * 192) << (FBScale[0] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; @@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetScale(FBScale[0]); - GPU3D::SetScale(FBScale[0]); + GPU2D_A->SetDisplaySettings(FBScale[0], accel); + GPU3D::SetDisplaySettings(topscale, accel); } else { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetScale(FBScale[0]); + GPU2D_B->SetDisplaySettings(FBScale[0], accel); } } - if (bottom != FBScale[1]) + if (bottomscale != FBScale[1] || accel != Accelerated) { - FBScale[1] = bottom; + FBScale[1] = accel ? 0 : bottomscale; - int fbsize = (256 * 192) << (FBScale[1] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; @@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetScale(FBScale[1]); + GPU2D_B->SetDisplaySettings(FBScale[1], accel); } else { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetScale(FBScale[1]); - GPU3D::SetScale(FBScale[1]); + GPU2D_A->SetDisplaySettings(FBScale[1], accel); + GPU3D::SetDisplaySettings(bottomscale, accel); } } + + Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index 2e47fc4..cfa8d7d 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int top, int bottom); +void SetDisplaySettings(int topscale, int bottomscale, bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 3a99964..34c17ff 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,7 +82,6 @@ GPU2D::GPU2D(u32 num) { Num = num; - SetScale(0); } GPU2D::~GPU2D() @@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetScale(int scale) +void GPU2D::SetDisplaySettings(int scale, bool accel) { + if (accel) scale = 0; + Accelerated = accel; + LineScale = scale; LineStride = 256 << (scale*2); - if (scale == 1) DrawPixel = DrawPixel_2x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else if (scale == 1) DrawPixel = DrawPixel_2x; else if (scale == 2) DrawPixel = DrawPixel_4x; else DrawPixel = DrawPixel_1x; } @@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[LineStride * line]; + int stride = Accelerated ? (256*3) : LineStride; + u32* dst = &Framebuffer[stride * line]; int n3dline = line; line = GPU::VCount; @@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0) + if (Num == 0 && !Accelerated) _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics @@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line) case 0: // screen off { for (int i = 0; i < LineStride; i++) - dst[i] = 0xFF3F3F3F; + dst[i] = 0x003F3F3F; } break; case 1: // regular display { - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < stride; i+=2) *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } + if (Accelerated) return; + // master brightness if (dispmode != 0) { @@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + // TODO: handle 3D in accelerated mode!! + u32* srcA; if (CaptureCnt & (1<<24)) srcA = _3DLine; @@ -1272,88 +1280,91 @@ void GPU2D::DrawScanline_Mode1(u32 line) // color special effects // can likely be optimized - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - - for (int i = 0; i < LineStride; i++) + if (!Accelerated) { - int j = (i >> LineScale) & 0xFF; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + for (int i = 0; i < LineStride; i++) + { + int j = (i >> LineScale) & 0xFF; - u32 coloreffect, eva, evb; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 coloreffect, eva, evb; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - coloreffect = 1; + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; - if (flag1 & 0x40) + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D layer blending + + BGOBJLine[i] = ColorBlend5(val1, val2); + continue; } else { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending - - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) - { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { - coloreffect = 1; - eva = EVA; - evb = EVB; + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else coloreffect = 0; } - else - coloreffect = 0; - } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; + switch (coloreffect) + { + case 0: + BGOBJLine[i] = val1; + break; - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; + case 1: + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); + break; - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + case 2: + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); + break; - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } } } @@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) *(u64*)(dst+3072+2) = val; } +void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + *(dst+512) = *(dst+256); + *(dst+256) = *dst; + *dst = r | (g << 8) | (b << 16) | flag; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D() iend -= (xoff & 0xFF); } - if (LineScale == 1) + if (Accelerated) + { + for (; i < iend; i++) + { + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+512] = BGOBJLine[i+256]; + BGOBJLine[i+256] = BGOBJLine[i]; + BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + } + } + else if (LineScale == 1) { for (; i < iend; i++) { diff --git a/src/GPU2D.h b/src/GPU2D.h index aca1f7e..fc420a5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetScale(int scale); + void SetDisplaySettings(int scale, bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +71,7 @@ private: u32 LineStride; u32 LineScale; + bool Accelerated; u32 BGOBJLine[1024*4 * 2]; u32* _3DLine; @@ -136,6 +137,7 @@ private: static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); static void DrawPixel_4x(u32* dst, u16 color, u32 flag); + static void DrawPixel_Accel(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 8c0588d..61629a7 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { - GLRenderer43::SetScale(scale); + GLRenderer43::SetDisplaySettings(scale, accel); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 68bc696..2fe5bee 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,7 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void ExecuteCommand(); @@ -110,6 +110,7 @@ void VCount144(); void VBlank(); void VCount215(); u32* GetLine(int line); +void SetupAccelFrame(); void WriteToGXFIFO(u32 val); @@ -127,13 +128,14 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } @@ -144,11 +146,12 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index e76db7f..6db9a18 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -21,6 +21,7 @@ #include "NDS.h" #include "GPU.h" #include "OpenGLSupport.h" +#include "GPU3D_OpenGL43_shaders.h" namespace GPU3D { @@ -33,631 +34,6 @@ namespace GLRenderer43 // * UBO: 3.1 // * glMemoryBarrier: 4.2 -// TODO: consider other way to handle uniforms (UBO?) - -#define kShaderHeader "#version 430" - - -const char* kClearVS = kShaderHeader R"( - -layout(location=0) in vec2 vPosition; - -layout(location=1) uniform uint uDepth; - -void main() -{ - float fdepth = (float(uDepth) / 8388608.0) - 1.0; - gl_Position = vec4(vPosition, fdepth, 1.0); -} -)"; - -const char* kClearFS = kShaderHeader R"( - -layout(location=0) uniform uvec4 uColor; -layout(location=2) uniform uint uOpaquePolyID; -layout(location=3) uniform uint uFogFlag; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -void main() -{ - oColor = vec4(uColor).bgra / 31.0; - oAttr.r = 0; - oAttr.g = uOpaquePolyID; - oAttr.b = 0; -} -)"; - - -const char* kRenderVSCommon = R"( - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - -smooth out vec4 fColor; -smooth out vec2 fTexcoord; -flat out uvec3 fPolygonAttr; -)"; - -const char* kRenderFSCommon = R"( - -layout(binding=0) uniform usampler2D TexMem; -layout(binding=1) uniform sampler2D TexPalMem; - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -smooth in vec4 fColor; -smooth in vec2 fTexcoord; -flat in uvec3 fPolygonAttr; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -int TexcoordWrap(int c, int maxc, uint mode) -{ - if ((mode & (1<<0)) != 0) - { - if ((mode & (1<<2)) != 0 && (c & maxc) != 0) - return (maxc-1) - (c & (maxc-1)); - else - return (c & (maxc-1)); - } - else - return clamp(c, 0, maxc-1); -} - -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; - - addr.y = (addr.y << 2) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - - int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); - if (addr.x >= 0x40000) slot1addr += 0x10000; - - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); - - addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); - palinfo >>= 14; - - if (val == 0) - { - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 1) - { - addr.y++; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 2) - { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - addr.y += 2; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - } - else - { - if (palinfo == 2) - { - addr.y += 3; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } - } -} - -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - addr.x++; - uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; -} - -vec4 TextureLookup_Nearest(vec2 st) -{ - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(ivec2(st), tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - uint type = (attr >> 26) & 0x7; - if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); - else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); - else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); - else return TextureFetch_Direct (vramaddr, st_full, wrapmode); -} - -vec4 TextureLookup_Linear(vec2 texcoord) -{ - ivec2 intpart = ivec2(texcoord); - vec2 fracpart = fract(texcoord); - - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(intpart, tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - vec4 A, B, C, D; - uint type = (attr >> 26) & 0x7; - if (type == 5) - { - A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); - B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 2) - { - A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 3) - { - A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 4) - { - A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 1) - { - A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); - B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 6) - { - A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); - B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else - { - A = TextureFetch_Direct(vramaddr, st_full , wrapmode); - B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - - float fx = fracpart.x; - vec4 AB; - if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) - AB = vec4(0); - else - { - //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) - // fx = step(0.5, fx); - - AB = mix(A, B, fx); - } - - fx = fracpart.x; - vec4 CD; - if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) - CD = vec4(0); - else - { - //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) - // fx = step(0.5, fx); - - CD = mix(C, D, fx); - } - - fx = fracpart.y; - vec4 ret; - if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) - ret = vec4(0); - else - { - //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) - // fx = step(0.5, fx); - - ret = mix(AB, CD, fx); - } - - return ret; -} - -vec4 FinalColor() -{ - vec4 col; - vec4 vcol = fColor; - uint blendmode = (fPolygonAttr.x >> 4) & 0x3; - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) == 0) - { - // toon - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - vcol.rgb = tooncolor; - } - else - { - // highlight - vcol.rgb = vcol.rrr; - } - } - - if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) - { - // no texture - col = vcol; - } - else - { - vec4 tcol = TextureLookup_Nearest(fTexcoord); - //vec4 tcol = TextureLookup_Linear(fTexcoord); - - if ((blendmode & 1) != 0) - { - // decal - col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); - col.a = vcol.a; - } - else - { - // modulate - col = vcol * tcol; - } - } - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) != 0) - { - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - col.rgb = min(col.rgb + tooncolor, 1.0); - } - } - - return col.bgra; -} -)"; - - -const char* kRenderVS_Z = R"( - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xyz *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - -const char* kRenderVS_W = R"( - -smooth out float fZ; - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fZ = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xy *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - - -const char* kRenderFS_ZO = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; -} -)"; - -const char* kRenderFS_WO = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZT = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; -} -)"; - -const char* kRenderFS_WT = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZSM = R"( - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; -} -)"; - -const char* kRenderFS_WSM = R"( - -smooth in float fZ; - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; -} -)"; - -const char* kRenderFS_WS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; - gl_FragDepth = fZ; -} -)"; - enum { @@ -721,6 +97,7 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; +bool Accelerated; int ScreenW, ScreenH; GLuint FramebufferTex[4]; @@ -968,9 +345,10 @@ void Reset() // } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { ScaleFactor = scale; + Accelerated = accel; // TODO: antialiasing setting ScreenW = 256 << scale; @@ -986,10 +364,12 @@ void SetScale(int scale) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[ScreenW*ScreenH]; + if (accel) Framebuffer = new u32[256*192]; + else Framebuffer = new u32[ScreenW*ScreenH]; } @@ -1533,5 +913,10 @@ u32* GetLine(int line) return &Framebuffer[stride * line]; } +void SetupAccelFrame() +{ + // +} + } } diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h new file mode 100644 index 0000000..8a69566 --- /dev/null +++ b/src/GPU3D_OpenGL43_shaders.h @@ -0,0 +1,645 @@ +/* + 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 GPU3D_OPENGL43_SHADERS_H +#define GPU3D_OPENGL43_SHADERS_H + +#define kShaderHeader "#version 430" + + +const char* kClearVS = kShaderHeader R"( + +layout(location=0) in vec2 vPosition; + +layout(location=1) uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +layout(location=0) uniform uvec4 uColor; +layout(location=2) uniform uint uOpaquePolyID; +layout(location=3) uniform uint uFogFlag; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +void main() +{ + oColor = vec4(uColor).bgra / 31.0; + oAttr.r = 0; + oAttr.g = uOpaquePolyID; + oAttr.b = 0; +} +)"; + + +const char* kRenderVSCommon = R"( + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out uvec3 fPolygonAttr; +)"; + +const char* kRenderFSCommon = R"( + +layout(binding=0) uniform usampler2D TexMem; +layout(binding=1) uniform sampler2D TexPalMem; + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in uvec3 fPolygonAttr; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +int TexcoordWrap(int c, int maxc, uint mode) +{ + if ((mode & (1<<0)) != 0) + { + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); + else + return (c & (maxc-1)); + } + else + return clamp(c, 0, maxc-1); +} + +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; + + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); + + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } +} + +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + +vec4 FinalColor() +{ + vec4 col; + vec4 vcol = fColor; + uint blendmode = (fPolygonAttr.x >> 4) & 0x3; + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); + + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } + } + + return col.bgra; +} +)"; + + +const char* kRenderVS_Z = R"( + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xyz *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + +const char* kRenderVS_W = R"( + +smooth out float fZ; + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_ZO = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; +} +)"; + +const char* kRenderFS_WO = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZSM = R"( + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; +} +)"; + +const char* kRenderFS_WSM = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; + gl_FragDepth = fZ; +} +)"; + +#endif // GPU3D_OPENGL43_SHADERS_H diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index ac5cd93..20283d3 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,7 +138,7 @@ void Reset() SetupRenderThread(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); } @@ -2122,5 +2122,10 @@ u32* GetLine(int line) return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset]; } +void SetupAccelFrame() +{ + // TODO +} + } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 47f5f13..b77d67f 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -240,8 +240,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256 << ScreenScale[0]; - scheight = 192 << ScreenScale[0]; + scwidth = 256;// << ScreenScale[0]; + scheight = 192;// << ScreenScale[0]; switch (ScreenRotation) { @@ -286,8 +286,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256 << ScreenScale[1]; - scheight = 192 << ScreenScale[1]; + scwidth = 256;// << ScreenScale[1]; + scheight = 192;// << ScreenScale[1]; switch (ScreenRotation) { @@ -349,9 +349,13 @@ void GLDrawing_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER, + /*glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<<ScreenScale[1], 192<<ScreenScale[1], GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);*/ + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -633,7 +637,8 @@ int EmuThreadFunc(void* burp) ScreenScale[0] = ScreenScale[2]; ScreenScale[1] = ScreenScale[2]; - int lastscale[2] = {-1, -1}; + int lastscale[2] = {ScreenScale[0], ScreenScale[1]}; + GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); Touching = false; KeyInputMask = 0xFFF; @@ -782,7 +787,7 @@ int EmuThreadFunc(void* burp) if (ScreenScale[0] != lastscale[0] || ScreenScale[1] != lastscale[1]) { - GPU::SetFramebufferScale(ScreenScale[0], ScreenScale[1]); + GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); ScreenDrawInited = false; } -- 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 'melonDS.cbp') 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 3e760a2e34990e9f0e416550091783a7d6695e60 Mon Sep 17 00:00:00 2001 From: Arisotura <thetotalworm@gmail.com> Date: Fri, 31 May 2019 22:03:59 +0200 Subject: add LTO to Release build under Codeblocks --- melonDS.cbp | 1 + 1 file changed, 1 insertion(+) (limited to 'melonDS.cbp') diff --git a/melonDS.cbp b/melonDS.cbp index bb4d8c7..b517353 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -30,6 +30,7 @@ <Compiler> <Add option="-O3" /> <Add option="-m64" /> + <Add option="-flto" /> <Add option="-D_FILE_OFFSET_BITS=64" /> </Compiler> <Linker> -- cgit v1.2.3 From 6de19645f8fdd309cdf9f53d846b70f45ed66e62 Mon Sep 17 00:00:00 2001 From: Arisotura <thetotalworm@gmail.com> Date: Sun, 2 Jun 2019 14:57:59 +0200 Subject: fix potential crash when running the software renderer (oops) --- melonDS.cbp | 2 ++ src/GPU2D.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'melonDS.cbp') diff --git a/melonDS.cbp b/melonDS.cbp index b517353..3003b84 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -143,6 +143,8 @@ <Unit filename="src/libui_sdl/LAN_PCap.h" /> <Unit filename="src/libui_sdl/LAN_Socket.cpp" /> <Unit filename="src/libui_sdl/LAN_Socket.h" /> + <Unit filename="src/libui_sdl/OSD.cpp" /> + <Unit filename="src/libui_sdl/OSD.h" /> <Unit filename="src/libui_sdl/Platform.cpp" /> <Unit filename="src/libui_sdl/PlatformConfig.cpp" /> <Unit filename="src/libui_sdl/PlatformConfig.h" /> diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 212372c..c51b252 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -882,10 +882,12 @@ void GPU2D::VBlankEnd() OBJMosaicY = 0; OBJMosaicYMax = OBJMosaicSize[1]; - // TODO: make optional - if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + if (GPU3D::Renderer != 0) { - GPU3D::GLRenderer::PrepareCaptureFrame(); + if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + GPU3D::GLRenderer::PrepareCaptureFrame(); + } } } -- cgit v1.2.3 From 0aca7a68281150f1f0ec9f596f838dccdae55b72 Mon Sep 17 00:00:00 2001 From: Arisotura <thetotalworm@gmail.com> Date: Sun, 2 Jun 2019 15:29:37 +0200 Subject: I guess adding font.h can't hurt --- melonDS.cbp | 1 + 1 file changed, 1 insertion(+) (limited to 'melonDS.cbp') diff --git a/melonDS.cbp b/melonDS.cbp index 3003b84..0af2f4a 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -148,6 +148,7 @@ <Unit filename="src/libui_sdl/Platform.cpp" /> <Unit filename="src/libui_sdl/PlatformConfig.cpp" /> <Unit filename="src/libui_sdl/PlatformConfig.h" /> + <Unit filename="src/libui_sdl/font.h" /> <Unit filename="src/libui_sdl/libui/common/areaevents.c"> <Option compilerVar="CC" /> </Unit> -- cgit v1.2.3