diff options
| author | Arisotura <thetotalworm@gmail.com> | 2019-05-25 20:42:27 +0200 | 
|---|---|---|
| committer | Arisotura <thetotalworm@gmail.com> | 2019-05-25 20:42:27 +0200 | 
| commit | 94f5ecb64714c3a4026bebe4f81a99ca4dba0362 (patch) | |
| tree | cfc88ac94ce13bb1332aadde9f15c6eb4e61aee5 /src/libui_sdl/main.cpp | |
| parent | 63e42bf90fa9d78c92123dcbc9c2b8ca5bb5e3ba (diff) | |
| parent | 9ed1dda9ca18e571fc6613885ac944bbb938cd9a (diff) | |
Merge branch 'blackmagic'
BAHAHAHHAHAHAHAAHAHAHAHHH
HARK HARK HARK HARK HA-*~
Diffstat (limited to 'src/libui_sdl/main.cpp')
| -rw-r--r-- | src/libui_sdl/main.cpp | 756 | 
1 files changed, 588 insertions, 168 deletions
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 3eea39c..c086bbf 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -24,12 +24,16 @@  #include <SDL2/SDL.h>  #include "libui/ui.h" +#include "../OpenGLSupport.h" +#include "main_shaders.h" +  #include "../types.h"  #include "../version.h"  #include "PlatformConfig.h"  #include "DlgEmuSettings.h"  #include "DlgInputConfig.h" +#include "DlgVideoSettings.h"  #include "DlgAudioSettings.h"  #include "DlgWifiSettings.h" @@ -60,6 +64,10 @@ char* EmuDirectory;  uiWindow* MainWindow;  uiArea* MainDrawArea; +uiAreaHandler MainDrawAreaHandler; + +const u32 kGLVersions[] = {uiGLVersion(3,1), 0}; +uiGLContext* GLContext;  int WindowWidth, WindowHeight; @@ -81,6 +89,9 @@ uiMenuItem* MenuItem_ScreenGap[6];  uiMenuItem* MenuItem_ScreenLayout[3];  uiMenuItem* MenuItem_ScreenSizing[4]; +uiMenuItem* MenuItem_ScreenFilter; +uiMenuItem* MenuItem_LimitFPS; +  SDL_Thread* EmuThread;  int EmuRunning;  volatile int EmuStatus; @@ -92,9 +103,27 @@ char PrevSRAMPath[1024]; // for savestate 'undo load'  bool SavestateLoaded; +bool Screen_UseGL; +  bool ScreenDrawInited = false; -uiDrawBitmap* ScreenBitmap = NULL; -u32 ScreenBuffer[256*384]; +uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; + +GLuint GL_ScreenShader[3]; +GLuint GL_ScreenShaderAccel[3]; +struct +{ +    float uScreenSize[2]; +    u32 u3DScale; +    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 GL_3DScale;  int ScreenGap = 0;  int ScreenLayout = 0; @@ -135,7 +164,262 @@ void LoadState(int slot);  void UndoStateLoad();  void GetSavestateName(int slot, char* filename, int len); +void CreateMainWindow(bool opengl); +void DestroyMainWindow(); +void RecreateMainWindow(bool opengl); + + + +bool GLScreen_InitShader(GLuint* shader, const char* fs) +{ +    if (!OpenGL_BuildShaderProgram(kScreenVS, fs, shader, "ScreenShader")) +        return false; + +    GLuint uni_id; + +    uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); +    glUniformBlockBinding(shader[2], uni_id, 16); + +    glUseProgram(shader[2]); +    uni_id = glGetUniformLocation(shader[2], "ScreenTex"); +    glUniform1i(uni_id, 0); +    uni_id = glGetUniformLocation(shader[2], "_3DTex"); +    glUniform1i(uni_id, 1); + +    glBindAttribLocation(shader[2], 0, "vPosition"); +    glBindAttribLocation(shader[2], 1, "vTexcoord"); +    glBindFragDataLocation(shader[2], 0, "oColor"); + +    return true; +} + +bool GLScreen_Init() +{ +    if (!OpenGL_Init()) +        return false; + +    if (!GLScreen_InitShader(GL_ScreenShader, kScreenFS)) +        return false; +    if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel)) +        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); + +    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, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + +    GL_ScreenSizeDirty = true; + +    return true; +} + +void GLScreen_DeInit() +{ +    glDeleteTextures(1, &GL_ScreenTexture); + +    glDeleteVertexArrays(1, &GL_ScreenVertexArrayID); +    glDeleteBuffers(1, &GL_ScreenVertexBufferID); + +    OpenGL_DeleteShaderProgram(GL_ScreenShader); +    OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel); +} + +void GLScreen_DrawScreen() +{ +    if (GL_ScreenSizeDirty) +    { +        GL_ScreenSizeDirty = false; + +        GL_ShaderConfig.uScreenSize[0] = WindowWidth; +        GL_ShaderConfig.uScreenSize[1] = WindowHeight; +        GL_ShaderConfig.u3DScale = GL_3DScale; + +        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; + +        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; + +        scwidth = 256; +        scheight = 192; + +        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); + +        x0 = BottomScreenRect.X; +        y0 = BottomScreenRect.Y; +        x1 = BottomScreenRect.X + BottomScreenRect.Width; +        y1 = BottomScreenRect.Y + BottomScreenRect.Height; + +        scwidth = 256; +        scheight = 192; + +        switch (ScreenRotation) +        { +        case 0: +            s0 = 0; t0 = 192; +            s1 = scwidth; t1 = 192; +            s2 = 0; t2 = 192+scheight; +            s3 = scwidth; t3 = 192+scheight; +            break; + +        case 1: +            s0 = 0; t0 = 192+scheight; +            s1 = 0; t1 = 192; +            s2 = scwidth; t2 = 192+scheight; +            s3 = scwidth; t3 = 192; +            break; + +        case 2: +            s0 = scwidth; t0 = 192+scheight; +            s1 = 0; t1 = 192+scheight; +            s2 = scwidth; t2 = 192; +            s3 = 0; t3 = 192; +            break; + +        case 3: +            s0 = scwidth; t0 = 192; +            s1 = scwidth; t1 = 192+scheight; +            s2 = 0; t2 = 192; +            s3 = 0; t3 = 192+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_STENCIL_TEST); +    glDisable(GL_BLEND); +    glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + +    glViewport(0, 0, WindowWidth, WindowHeight); + +    if (GPU3D::Renderer == 0) +        OpenGL_UseShaderProgram(GL_ScreenShader); +    else +        OpenGL_UseShaderProgram(GL_ScreenShaderAccel); + +    glBindFramebuffer(GL_FRAMEBUFFER, 0); +    glClearColor(0, 0, 0, 1); +    glClear(GL_COLOR_BUFFER_BIT); + +    int frontbuf = GPU::FrontBuffer; +    glActiveTexture(GL_TEXTURE0); +    glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); + +    if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) +    { +        if (GPU3D::Renderer == 0) +        { +            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA_INTEGER, +                            GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); +            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA_INTEGER, +                            GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); +        } +        else +        { +            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, +                            GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); +            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, +                            GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); +        } +    } + +    glActiveTexture(GL_TEXTURE1); +    if (GPU3D::Renderer != 0) +        GPU3D::GLRenderer::SetupAccelFrame(); + +    glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); +    glBindVertexArray(GL_ScreenVertexArrayID); +    glDrawArrays(GL_TRIANGLES, 0, 4*3); + +    glFlush(); +    uiGLSwapBuffers(GLContext); +}  void MicLoadWav(char* name)  { @@ -399,7 +683,18 @@ int EmuThreadFunc(void* burp)      MainScreenPos[2] = 0;      AutoScreenSizing = 0; -    ScreenDrawInited = false; +    if (Screen_UseGL) +    { +        uiGLMakeContextCurrent(GLContext); +        GPU3D::InitRenderer(true); +        uiGLMakeContextCurrent(NULL); +    } +    else +    { +        GPU3D::InitRenderer(false); +        GPU::SetDisplaySettings(false); +    } +      Touching = false;      KeyInputMask = 0xFFF;      HotkeyMask = 0; @@ -513,10 +808,7 @@ int EmuThreadFunc(void* burp)              // microphone input              FeedMicInput(); -            // emulate -            u32 nlines = NDS::RunFrame(); - -            if (EmuRunning == 0) break; +            if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);              // auto screen layout              { @@ -547,13 +839,16 @@ int EmuThreadFunc(void* burp)                  }              } -            memcpy(ScreenBuffer, GPU::Framebuffer, 256*384*4); +            // emulate +            u32 nlines = NDS::RunFrame(); + +            if (EmuRunning == 0) break; + +            if (Screen_UseGL) GLScreen_DrawScreen();              uiAreaQueueRedrawAll(MainDrawArea);              // framerate limiter based off SDL2_gfx -            float framerate; -            if (nlines == 263) framerate = 1000.0f / 60.0f; -            else               framerate = ((1000.0f * nlines) / 263.0f) / 60.0f; +            float framerate = (1000.0f * nlines) / (60.0f * 263.0f);              fpslimitcount++;              u32 curtick = SDL_GetTicks(); @@ -602,9 +897,16 @@ int EmuThreadFunc(void* burp)              if (EmuRunning == 2)              { +                if (Screen_UseGL) +                { +                    uiGLMakeContextCurrent(GLContext); +                    GLScreen_DrawScreen(); +                }                  uiAreaQueueRedrawAll(MainDrawArea);              } +            if (Screen_UseGL) uiGLMakeContextCurrent(NULL); +              EmuStatus = EmuRunning;              SDL_Delay(100); @@ -618,6 +920,8 @@ int EmuThreadFunc(void* burp)      NDS::DeInit();      Platform::LAN_DeInit(); +    if (Screen_UseGL) GLScreen_DeInit(); +      return 44203;  } @@ -626,25 +930,32 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)  {      if (!ScreenDrawInited)      { -        ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384); +        if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); +        if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); +          ScreenDrawInited = true; +        ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192); +        ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192);      } -    if (!ScreenBitmap) return; +    int frontbuf = GPU::FrontBuffer; +    if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; +    if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) return;      uiRect top = {0, 0, 256, 192}; -    uiRect bot = {0, 192, 256, 192}; +    uiRect bot = {0, 0, 256, 192}; -    uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); +    uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); +    uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]);      uiDrawSave(params->Context);      uiDrawTransform(params->Context, &TopScreenTrans); -    uiDrawBitmapDraw(params->Context, ScreenBitmap, &top, &TopScreenRect, Config::ScreenFilter==1); +    uiDrawBitmapDraw(params->Context, ScreenBitmap[0], &top, &TopScreenRect, Config::ScreenFilter==1);      uiDrawRestore(params->Context);      uiDrawSave(params->Context);      uiDrawTransform(params->Context, &BottomScreenTrans); -    uiDrawBitmapDraw(params->Context, ScreenBitmap, &bot, &BottomScreenRect, Config::ScreenFilter==1); +    uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1);      uiDrawRestore(params->Context);  } @@ -804,7 +1115,7 @@ void SetupScreenRects(int width, int height)      else          sizemode = ScreenSizing; -    int screenW, screenH; +    int screenW, screenH, gap;      if (sideways)      {          screenW = 192; @@ -816,6 +1127,8 @@ void SetupScreenRects(int width, int height)          screenH = 192;      } +    gap = ScreenGap; +      uiRect *topscreen, *bottomscreen;      if (ScreenRotation == 1 || ScreenRotation == 2)      { @@ -835,7 +1148,7 @@ void SetupScreenRects(int width, int height)          int heightreq;          int startX = 0; -        width -= ScreenGap; +        width -= gap;          if (sizemode == 0) // even          { @@ -873,7 +1186,7 @@ void SetupScreenRects(int width, int height)          topscreen->X = startX;          topscreen->Y = ((height - heightreq) / 2) + (heightreq - topscreen->Height); -        bottomscreen->X = topscreen->X + topscreen->Width + ScreenGap; +        bottomscreen->X = topscreen->X + topscreen->Width + gap;          if (sizemode == 1)          { @@ -894,7 +1207,7 @@ void SetupScreenRects(int width, int height)          int widthreq;          int startY = 0; -        height -= ScreenGap; +        height -= gap;          if (sizemode == 0) // even          { @@ -932,7 +1245,7 @@ void SetupScreenRects(int width, int height)          topscreen->Y = startY;          topscreen->X = (width - topscreen->Width) / 2; -        bottomscreen->Y = topscreen->Y + topscreen->Height + ScreenGap; +        bottomscreen->Y = topscreen->Y + topscreen->Height + gap;          if (sizemode == 1)          { @@ -1002,6 +1315,8 @@ void SetupScreenRects(int width, int height)          }          break;      } + +    GL_ScreenSizeDirty = true;  }  void SetMinSize(int w, int h) @@ -1092,7 +1407,6 @@ void Stop(bool internal)      uiMenuItemDisable(MenuItem_Stop);      uiMenuItemSetChecked(MenuItem_Pause, 0); -    memset(ScreenBuffer, 0, 256*384*4);      uiAreaQueueRedrawAll(MainDrawArea);      SDL_PauseAudioDevice(AudioDevice, 1); @@ -1364,7 +1678,7 @@ void OnCloseByMenu(uiMenuItem* item, uiWindow* window, void* blarg)      EmuRunning = 3;      while (EmuStatus != 3); -    uiControlDestroy(uiControl(window)); +    DestroyMainWindow();      uiQuit();  } @@ -1485,6 +1799,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(); @@ -1506,26 +1825,31 @@ void EnsureProperMinSize()  {      bool isHori = (ScreenRotation == 1 || ScreenRotation == 3); +    int w0 = 256; +    int h0 = 192; +    int w1 = 256; +    int h1 = 192; +      if (ScreenLayout == 0) // natural      {          if (isHori) -            SetMinSize(384+ScreenGap, 256); +            SetMinSize(h0+ScreenGap+h1, std::max(w0,w1));          else -            SetMinSize(256, 384+ScreenGap); +            SetMinSize(std::max(w0,w1), h0+ScreenGap+h1);      }      else if (ScreenLayout == 1) // vertical      {          if (isHori) -            SetMinSize(192, 512+ScreenGap); +            SetMinSize(std::max(h0,h1), w0+ScreenGap+w1);          else -            SetMinSize(256, 384+ScreenGap); +            SetMinSize(std::max(w0,w1), h0+ScreenGap+h1);      }      else // horizontal      {          if (isHori) -            SetMinSize(384+ScreenGap, 256); +            SetMinSize(h0+ScreenGap+h1, std::max(w0,w1));          else -            SetMinSize(512+ScreenGap, 192); +            SetMinSize(w0+ScreenGap+w1, std::max(h0,h1));      }  } @@ -1537,6 +1861,8 @@ void OnSetScreenSize(uiMenuItem* item, uiWindow* window, void* param)      int w = 256*factor;      int h = 192*factor; +    // FIXME +      if (ScreenLayout == 0) // natural      {          if (isHori) @@ -1646,15 +1972,20 @@ void OnSetLimitFPS(uiMenuItem* item, uiWindow* window, void* blarg)  void ApplyNewSettings(int type)  { -    if (!RunningSomething) return; +    if (!RunningSomething && type != 2) return;      int prevstatus = EmuRunning; -    EmuRunning = 2; -    while (EmuStatus != 2); +    EmuRunning = 3; +    while (EmuStatus != 3); -    if (type == 0) // general emu settings +    if (type == 0) // 3D renderer settings      { -        GPU3D::SoftRenderer::SetupRenderThread(); +        if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); +        GPU3D::UpdateRendererConfig(); +        if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + +        GL_3DScale = Config::GL_ScaleFactor; // dorp +        GL_ScreenSizeDirty = true;      }      else if (type == 1) // wifi settings      { @@ -1667,112 +1998,44 @@ void ApplyNewSettings(int type)          Platform::LAN_DeInit();          Platform::LAN_Init();      } - -    EmuRunning = prevstatus; -} - - -int main(int argc, char** argv) -{ -    srand(time(NULL)); - -    printf("melonDS " MELONDS_VERSION "\n"); -    printf(MELONDS_URL "\n"); - -    if (argc > 0 && strlen(argv[0]) > 0) +    else if (type == 2) // video output method      { -        int len = strlen(argv[0]); -        while (len > 0) -        { -            if (argv[0][len] == '/') break; -            if (argv[0][len] == '\\') break; -            len--; -        } -        if (len > 0) -        { -            EmuDirectory = new char[len+1]; -            strncpy(EmuDirectory, argv[0], len); -            EmuDirectory[len] = '\0'; -        } -        else +        bool usegl = Config::ScreenUseGL || (Config::_3DRenderer != 0); +        if (usegl != Screen_UseGL)          { -            EmuDirectory = new char[2]; -            strcpy(EmuDirectory, "."); -        } -    } -    else -    { -        EmuDirectory = new char[2]; -        strcpy(EmuDirectory, "."); -    } - -    // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl -    SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); +            Screen_UseGL = usegl; -    if (SDL_Init(SDL_INIT_HAPTIC) < 0) -    { -        printf("SDL couldn't init rumble\n"); -    } -    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) -    { -        printf("SDL shat itself :(\n"); -        return 1; -    } +            if (RunningSomething) +            { +                if (usegl) uiGLMakeContextCurrent(GLContext); +                GPU3D::DeInitRenderer(); +                if (usegl) uiGLMakeContextCurrent(NULL); +            } -    SDL_JoystickEventState(SDL_ENABLE); +            RecreateMainWindow(usegl); -    uiInitOptions ui_opt; -    memset(&ui_opt, 0, sizeof(uiInitOptions)); -    const char* ui_err = uiInit(&ui_opt); -    if (ui_err != NULL) -    { -        printf("libui shat itself :( %s\n", ui_err); -        uiFreeInitError(ui_err); -        return 1; +            if (RunningSomething) +            { +                if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); +                GPU3D::InitRenderer(Screen_UseGL); +                if (Screen_UseGL) uiGLMakeContextCurrent(NULL); +            } +        }      } - -    Config::Load(); - -    if      (Config::AudioVolume < 0)   Config::AudioVolume = 0; -    else if (Config::AudioVolume > 256) Config::AudioVolume = 256; - -    if (!Platform::LocalFileExists("bios7.bin") || -        !Platform::LocalFileExists("bios9.bin") || -        !Platform::LocalFileExists("firmware.bin")) +    else if (type == 3) // 3D renderer      { -        uiMsgBoxError( -            NULL, -            "BIOS/Firmware not found", -            "One or more of the following required files don't exist or couldn't be accessed:\n\n" -            "bios7.bin -- ARM7 BIOS\n" -            "bios9.bin -- ARM9 BIOS\n" -            "firmware.bin -- firmware image\n\n" -            "Dump the files from your DS and place them in the directory you run melonDS from.\n" -            "Make sure that the files can be accessed."); - -        uiUninit(); -        SDL_Quit(); -        return 0; +        if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); +        GPU3D::DeInitRenderer(); +        GPU3D::InitRenderer(Screen_UseGL); +        if (Screen_UseGL) uiGLMakeContextCurrent(NULL);      } -    { -        FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); -        if (f) -        { -            u32 data; -            fread(&data, 4, 1, f); -            fclose(f); +    EmuRunning = prevstatus; +} -            if ((data >> 24) == 0) // old CRC-based list -            { -                uiMsgBoxError(NULL, -                              "Your version of romlist.bin is outdated.", -                              "Save memory type detection will not work correctly.\n\n" -                              "You should use the latest version of romlist.bin (provided in melonDS release packages)."); -            } -        } -    } +void CreateMainWindowMenu() +{      uiMenu* menu;      uiMenuItem* menuitem; @@ -1847,6 +2110,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"); @@ -1928,24 +2193,18 @@ int main(int argc, char** argv)          uiMenuAppendSubmenu(menu, submenu);      } -    menuitem = uiMenuAppendCheckItem(menu, "Screen filtering"); -    uiMenuItemOnClicked(menuitem, OnSetScreenFiltering, NULL); -    uiMenuItemSetChecked(menuitem, Config::ScreenFilter==1); - -    menuitem = uiMenuAppendCheckItem(menu, "Limit framerate"); -    uiMenuItemOnClicked(menuitem, OnSetLimitFPS, NULL); -    uiMenuItemSetChecked(menuitem, Config::LimitFPS==1); +    MenuItem_ScreenFilter = uiMenuAppendCheckItem(menu, "Screen filtering"); +    uiMenuItemOnClicked(MenuItem_ScreenFilter, OnSetScreenFiltering, NULL); +    MenuItem_LimitFPS = uiMenuAppendCheckItem(menu, "Limit framerate"); +    uiMenuItemOnClicked(MenuItem_LimitFPS, OnSetLimitFPS, NULL); +} -    int w = Config::WindowWidth; -    int h = Config::WindowHeight; -    //if (w < 256) w = 256; -    //if (h < 384) h = 384; - -    WindowWidth = w; -    WindowHeight = h; - -    MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); +void CreateMainWindow(bool opengl) +{ +    MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, +                             WindowWidth, WindowHeight, +                             Config::WindowMaximized, 1, 1);      uiWindowOnClosing(MainWindow, OnCloseWindow, NULL);      uiWindowSetDropTarget(MainWindow, 1); @@ -1954,28 +2213,182 @@ int main(int argc, char** argv)      uiWindowOnGetFocus(MainWindow, OnGetFocus, NULL);      uiWindowOnLoseFocus(MainWindow, OnLoseFocus, NULL); -    //uiMenuItemDisable(MenuItem_SaveState); -    //uiMenuItemDisable(MenuItem_LoadState); -    for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_SaveStateSlot[i]); -    for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_LoadStateSlot[i]); -    uiMenuItemDisable(MenuItem_UndoStateLoad); - -    uiMenuItemDisable(MenuItem_Pause); -    uiMenuItemDisable(MenuItem_Reset); -    uiMenuItemDisable(MenuItem_Stop); +    ScreenDrawInited = false; +    bool opengl_good = opengl; -    uiAreaHandler areahandler; -    areahandler.Draw = OnAreaDraw; -    areahandler.MouseEvent = OnAreaMouseEvent; -    areahandler.MouseCrossed = OnAreaMouseCrossed; -    areahandler.DragBroken = OnAreaDragBroken; -    areahandler.KeyEvent = OnAreaKeyEvent; -    areahandler.Resize = OnAreaResize; +    if (!opengl) MainDrawArea = uiNewArea(&MainDrawAreaHandler); +    else         MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); -    MainDrawArea = uiNewArea(&areahandler);      uiWindowSetChild(MainWindow, uiControl(MainDrawArea));      uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); -    uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? +    uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + +    uiControlShow(uiControl(MainWindow)); +    uiControlSetFocus(uiControl(MainDrawArea)); + +    if (opengl_good) +    { +        GLContext = uiAreaGetGLContext(MainDrawArea); +        if (!GLContext) opengl_good = false; +    } +    if (opengl_good) +    { +        uiGLMakeContextCurrent(GLContext); +        if (!GLScreen_Init()) opengl_good = false; +        uiGLMakeContextCurrent(NULL); +    } + +    if (opengl && !opengl_good) +    { +        printf("OpenGL: initialization failed\n"); +        RecreateMainWindow(false); +        Screen_UseGL = false; +    } +} + +void DestroyMainWindow() +{ +    uiControlDestroy(uiControl(MainWindow)); + +    if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); +    if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); + +    ScreenBitmap[0] = NULL; +    ScreenBitmap[1] = NULL; +} + +void RecreateMainWindow(bool opengl) +{ +    int winX, winY, maxi; +    uiWindowPosition(MainWindow, &winX, &winY); +    maxi = uiWindowMaximized(MainWindow); +    DestroyMainWindow(); +    CreateMainWindow(opengl); +    uiWindowSetPosition(MainWindow, winX, winY); +    uiWindowSetMaximized(MainWindow, maxi); +} + + +int main(int argc, char** argv) +{ +    srand(time(NULL)); + +    printf("melonDS " MELONDS_VERSION "\n"); +    printf(MELONDS_URL "\n"); + +    if (argc > 0 && strlen(argv[0]) > 0) +    { +        int len = strlen(argv[0]); +        while (len > 0) +        { +            if (argv[0][len] == '/') break; +            if (argv[0][len] == '\\') break; +            len--; +        } +        if (len > 0) +        { +            EmuDirectory = new char[len+1]; +            strncpy(EmuDirectory, argv[0], len); +            EmuDirectory[len] = '\0'; +        } +        else +        { +            EmuDirectory = new char[2]; +            strcpy(EmuDirectory, "."); +        } +    } +    else +    { +        EmuDirectory = new char[2]; +        strcpy(EmuDirectory, "."); +    } + +    // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl +    SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + +    if (SDL_Init(SDL_INIT_HAPTIC) < 0) +    { +        printf("SDL couldn't init rumble\n"); +    } +    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) +    { +        printf("SDL shat itself :(\n"); +        return 1; +    } + +    SDL_JoystickEventState(SDL_ENABLE); + +    uiInitOptions ui_opt; +    memset(&ui_opt, 0, sizeof(uiInitOptions)); +    const char* ui_err = uiInit(&ui_opt); +    if (ui_err != NULL) +    { +        printf("libui shat itself :( %s\n", ui_err); +        uiFreeInitError(ui_err); +        return 1; +    } + +    Config::Load(); + +    if      (Config::AudioVolume < 0)   Config::AudioVolume = 0; +    else if (Config::AudioVolume > 256) Config::AudioVolume = 256; + +    if (!Platform::LocalFileExists("bios7.bin") || +        !Platform::LocalFileExists("bios9.bin") || +        !Platform::LocalFileExists("firmware.bin")) +    { +        uiMsgBoxError( +            NULL, +            "BIOS/Firmware not found", +            "One or more of the following required files don't exist or couldn't be accessed:\n\n" +            "bios7.bin -- ARM7 BIOS\n" +            "bios9.bin -- ARM9 BIOS\n" +            "firmware.bin -- firmware image\n\n" +            "Dump the files from your DS and place them in the directory you run melonDS from.\n" +            "Make sure that the files can be accessed."); + +        uiUninit(); +        SDL_Quit(); +        return 0; +    } + +    { +        FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); +        if (f) +        { +            u32 data; +            fread(&data, 4, 1, f); +            fclose(f); + +            if ((data >> 24) == 0) // old CRC-based list +            { +                uiMsgBoxError(NULL, +                              "Your version of romlist.bin is outdated.", +                              "Save memory type detection will not work correctly.\n\n" +                              "You should use the latest version of romlist.bin (provided in melonDS release packages)."); +            } +        } +    } + +    CreateMainWindowMenu(); + +    MainDrawAreaHandler.Draw = OnAreaDraw; +    MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent; +    MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed; +    MainDrawAreaHandler.DragBroken = OnAreaDragBroken; +    MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent; +    MainDrawAreaHandler.Resize = OnAreaResize; + +    WindowWidth = Config::WindowWidth; +    WindowHeight = Config::WindowHeight; + +    Screen_UseGL = Config::ScreenUseGL || (Config::_3DRenderer != 0); + +    GL_3DScale = Config::GL_ScaleFactor; +    if      (GL_3DScale < 1) GL_3DScale = 1; +    else if (GL_3DScale > 8) GL_3DScale = 8; + +    CreateMainWindow(Screen_UseGL);      ScreenRotation = Config::ScreenRotation;      ScreenGap = Config::ScreenGap; @@ -1988,6 +2401,14 @@ int main(int argc, char** argv)      SANITIZE(ScreenSizing, 0, 3);  #undef SANITIZE +    for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_SaveStateSlot[i]); +    for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_LoadStateSlot[i]); +    uiMenuItemDisable(MenuItem_UndoStateLoad); + +    uiMenuItemDisable(MenuItem_Pause); +    uiMenuItemDisable(MenuItem_Reset); +    uiMenuItemDisable(MenuItem_Stop); +      uiMenuItemSetChecked(MenuItem_SavestateSRAMReloc, Config::SavestateRelocSRAM?1:0);      uiMenuItemSetChecked(MenuItem_ScreenRot[ScreenRotation], 1); @@ -2002,6 +2423,9 @@ int main(int argc, char** argv)      OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); +    uiMenuItemSetChecked(MenuItem_ScreenFilter, Config::ScreenFilter==1); +    uiMenuItemSetChecked(MenuItem_LimitFPS, Config::LimitFPS==1); +      SDL_AudioSpec whatIwant, whatIget;      memset(&whatIwant, 0, sizeof(SDL_AudioSpec));      whatIwant.freq = 47340; @@ -2070,8 +2494,6 @@ int main(int argc, char** argv)          }      } -    uiControlShow(uiControl(MainWindow)); -    uiControlSetFocus(uiControl(MainDrawArea));      uiMain();      EmuRunning = 0; @@ -2090,8 +2512,6 @@ int main(int argc, char** argv)      Config::Save(); -    if (ScreenBitmap) uiDrawFreeBitmap(ScreenBitmap); -      uiUninit();      SDL_Quit();      delete[] EmuDirectory;  |