diff --git a/desmume/src/frontend/windows/DeSmuME.vcxproj b/desmume/src/frontend/windows/DeSmuME.vcxproj
index 794d7106f..e7d3a7aed 100644
--- a/desmume/src/frontend/windows/DeSmuME.vcxproj
+++ b/desmume/src/frontend/windows/DeSmuME.vcxproj
@@ -284,6 +284,7 @@
+
@@ -582,6 +583,7 @@
+
diff --git a/desmume/src/frontend/windows/DeSmuME.vcxproj.filters b/desmume/src/frontend/windows/DeSmuME.vcxproj.filters
index 4047bb282..c6188bf59 100644
--- a/desmume/src/frontend/windows/DeSmuME.vcxproj.filters
+++ b/desmume/src/frontend/windows/DeSmuME.vcxproj.filters
@@ -921,6 +921,9 @@
utils\colorspacehandler
+
+ frontend\Windows
+
@@ -1610,6 +1613,9 @@
utils\colorspacehandler
+
+ frontend\Windows
+
diff --git a/desmume/src/frontend/windows/ddraw.cpp b/desmume/src/frontend/windows/ddraw.cpp
new file mode 100644
index 000000000..afbdb58b9
--- /dev/null
+++ b/desmume/src/frontend/windows/ddraw.cpp
@@ -0,0 +1,185 @@
+/*
+Copyright (C) 2018 DeSmuME team
+
+This file 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 2 of the License, or
+(at your option) any later version.
+
+This file 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 the this software. If not, see .
+*/
+
+#include "ddraw.h"
+
+#include "directx/ddraw.h"
+#include "GPU.h"
+#include "types.h"
+
+const char *DDerrors[] = {
+ "no errors",
+ "Unable to initialize DirectDraw",
+ "Unable to set DirectDraw Cooperative Level",
+ "Unable to create DirectDraw primary surface",
+ "Unable to set DirectDraw clipper" };
+
+DDRAW::DDRAW() :
+ handle(NULL), clip(NULL)
+{
+ surface.primary = NULL;
+ surface.back = NULL;
+ memset(&surfDesc, 0, sizeof(surfDesc));
+ memset(&surfDescBack, 0, sizeof(surfDescBack));
+}
+
+u32 DDRAW::create(HWND hwnd)
+{
+ if (handle) return 0;
+
+ if (FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&handle, IID_IDirectDraw7, NULL)))
+ return 1;
+
+ if (FAILED(handle->SetCooperativeLevel(hwnd, DDSCL_NORMAL)))
+ return 2;
+
+ createSurfaces(hwnd);
+
+ return 0;
+}
+
+bool DDRAW::release()
+{
+ if (!handle) return true;
+
+ if (clip != NULL) clip->Release();
+ if (surface.back != NULL) surface.back->Release();
+ if (surface.primary != NULL) surface.primary->Release();
+
+ if (FAILED(handle->Release())) return false;
+ return true;
+}
+
+bool DDRAW::createBackSurface(int width, int height)
+{
+ if (surface.back) { surface.back->Release(); surface.back = NULL; }
+
+ memset(&surfDescBack, 0, sizeof(surfDescBack));
+ surfDescBack.dwSize = sizeof(surfDescBack);
+ surfDescBack.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+ surfDescBack.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+
+ if (systemMemory)
+ surfDescBack.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
+ else
+ surfDescBack.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+
+
+ surfDescBack.dwWidth = width;
+ surfDescBack.dwHeight = height;
+
+ if (FAILED(handle->CreateSurface(&surfDescBack, &surface.back, NULL))) return false;
+
+ return true;
+}
+
+bool DDRAW::createSurfaces(HWND hwnd)
+{
+ if (!handle) return true;
+
+ if (clip) { clip->Release(); clip = NULL; }
+ if (surface.primary) { surface.primary->Release(); surface.primary = NULL; }
+
+
+ // primary
+ memset(&surfDesc, 0, sizeof(surfDesc));
+ surfDesc.dwSize = sizeof(surfDesc);
+ surfDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ surfDesc.dwFlags = DDSD_CAPS;
+ if (FAILED(handle->CreateSurface(&surfDesc, &surface.primary, NULL)))
+ return false;
+
+ //default doesnt matter much, itll get adjusted later
+ if (!createBackSurface(GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2))
+ return false;
+
+ if (FAILED(handle->CreateClipper(0, &clip, NULL))) return false;
+ if (FAILED(clip->SetHWnd(0, hwnd))) return false;
+ if (FAILED(surface.primary->SetClipper(clip))) return false;
+
+ return true;
+}
+
+bool DDRAW::lock()
+{
+ if (!handle) return true;
+ if (!surface.back) return false;
+ memset(&surfDescBack, 0, sizeof(surfDescBack));
+ surfDescBack.dwSize = sizeof(surfDescBack);
+ surfDescBack.dwFlags = DDSD_ALL;
+
+ HRESULT res = surface.back->Lock(NULL, &surfDescBack, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
+ if (FAILED(res))
+ {
+ //INFO("DDraw failed: Lock %i\n", res);
+ if (res == DDERR_SURFACELOST)
+ {
+ res = surface.back->Restore();
+ if (FAILED(res)) return false;
+ }
+ }
+ return true;
+}
+
+bool DDRAW::unlock()
+{
+ if (!handle) return true;
+ if (!surface.back) return false;
+ if (FAILED(surface.back->Unlock((LPRECT)surfDescBack.lpSurface))) return false;
+ return true;
+}
+
+bool DDRAW::OK()
+{
+ if (!handle) return false;
+ if (!surface.primary) return false;
+ if (!surface.back) return false;
+ return true;
+}
+
+bool DDRAW::blt(LPRECT dst, LPRECT src)
+{
+ if (!handle) return true;
+ if (!surface.primary) return false;
+ if (!surface.back) return false;
+
+ if (vSync)
+ {
+ //this seems to block the whole process. this destroys the display thread and will easily block the emulator to 30fps.
+ //IDirectDraw7_WaitForVerticalBlank(handle,DDWAITVB_BLOCKBEGIN,0);
+
+ for (;;)
+ {
+ BOOL vblank;
+ IDirectDraw7_GetVerticalBlankStatus(handle, &vblank);
+ if (vblank) break;
+ //must be a greedy loop since vblank is small relative to 1msec minimum Sleep() resolution.
+ }
+ }
+
+ HRESULT res = surface.primary->Blt(dst, surface.back, src, DDBLT_WAIT, 0);
+ if (FAILED(res))
+ {
+ //INFO("DDraw failed: Blt %i\n", res);
+ if (res == DDERR_SURFACELOST)
+ {
+ res = surface.primary->Restore();
+ if (FAILED(res)) return false;
+ }
+ }
+ return true;
+}
diff --git a/desmume/src/frontend/windows/ddraw.h b/desmume/src/frontend/windows/ddraw.h
new file mode 100644
index 000000000..ca7df272c
--- /dev/null
+++ b/desmume/src/frontend/windows/ddraw.h
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 2018 DeSmuME team
+
+This file 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 2 of the License, or
+(at your option) any later version.
+
+This file 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 the this software. If not, see .
+*/
+
+#ifndef _DDRAW_H_
+#define _DDRAW_H_
+
+#include "types.h"
+#include "directx/ddraw.h"
+
+extern const char *DDerrors[];
+
+struct DDRAW
+{
+ DDRAW();
+
+ u32 create(HWND hwnd);
+ bool release();
+ bool createSurfaces(HWND hwnd);
+ bool createBackSurface(int width, int height);
+ bool lock();
+ bool unlock();
+ bool blt(LPRECT dst, LPRECT src);
+ bool OK();
+
+ LPDIRECTDRAW7 handle;
+ struct
+ {
+ LPDIRECTDRAWSURFACE7 primary;
+ LPDIRECTDRAWSURFACE7 back;
+ } surface;
+
+ DDSURFACEDESC2 surfDesc;
+ DDSURFACEDESC2 surfDescBack;
+ LPDIRECTDRAWCLIPPER clip;
+
+ bool systemMemory = false;
+ bool vSync = false;
+};
+
+#endif
\ No newline at end of file
diff --git a/desmume/src/frontend/windows/main.cpp b/desmume/src/frontend/windows/main.cpp
index 606e8c150..036b75c51 100755
--- a/desmume/src/frontend/windows/main.cpp
+++ b/desmume/src/frontend/windows/main.cpp
@@ -91,6 +91,7 @@
#include "frontend/modules/ImageOut.h"
#include "winutil.h"
#include "ogl.h"
+#include "ddraw.h"
//tools and dialogs
#include "pathsettings.h"
@@ -340,43 +341,7 @@ Lock::Lock() : m_cs(&win_execute_sync) { EnterCriticalSection(m_cs); }
Lock::Lock(CRITICAL_SECTION& cs) : m_cs(&cs) { EnterCriticalSection(m_cs); }
Lock::~Lock() { LeaveCriticalSection(m_cs); }
-//====================== DirectDraw
-const char *DDerrors[] = { "no errors",
- "Unable to initialize DirectDraw",
- "Unable to set DirectDraw Cooperative Level",
- "Unable to create DirectDraw primary surface",
- "Unable to set DirectDraw clipper"};
-struct DDRAW
-{
- DDRAW():
- handle(NULL), clip(NULL)
- {
- surface.primary = NULL;
- surface.back = NULL;
- memset(&surfDesc, 0, sizeof(surfDesc));
- memset(&surfDescBack, 0, sizeof(surfDescBack));
- }
-
- u32 create(HWND hwnd);
- bool release();
- bool createSurfaces(HWND hwnd);
- bool createBackSurface(int width, int height);
- bool lock();
- bool unlock();
- bool blt(LPRECT dst, LPRECT src);
- bool OK();
-
- LPDIRECTDRAW7 handle;
- struct
- {
- LPDIRECTDRAWSURFACE7 primary;
- LPDIRECTDRAWSURFACE7 back;
- } surface;
-
- DDSURFACEDESC2 surfDesc;
- DDSURFACEDESC2 surfDescBack;
- LPDIRECTDRAWCLIPPER clip;
-} ddraw;
+DDRAW ddraw;
//===================== Input vars
#define WM_CUSTKEYDOWN (WM_USER+50)
@@ -7821,161 +7786,6 @@ void WIN_InstallGBACartridge()
GBACartridge_SRAMPath = Path::GetFileNameWithoutExt(win32_GBA_cfgRomPath) + "." + GBA_SRAM_FILE_EXT;
}
-// ================================================================= DDraw
-u32 DDRAW::create(HWND hwnd)
-{
- if (handle) return 0;
-
- if (FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&handle, IID_IDirectDraw7, NULL)))
- return 1;
-
- if (FAILED(handle->SetCooperativeLevel(hwnd, DDSCL_NORMAL)))
- return 2;
-
- createSurfaces(hwnd);
-
- return 0;
-}
-
-bool DDRAW::release()
-{
- if (!handle) return true;
-
- if (clip != NULL) clip->Release();
- if (surface.back != NULL) surface.back->Release();
- if (surface.primary != NULL) surface.primary->Release();
-
- if (FAILED(handle->Release())) return false;
- return true;
-}
-
-bool DDRAW::createBackSurface(int width, int height)
-{
- if (surface.back) { surface.back->Release(); surface.back = NULL; }
-
- bool hw = (GetStyle()&DWS_DDRAW_HW)!=0;
- bool sw = (GetStyle()&DWS_DDRAW_SW)!=0;
-
- if(!hw && !sw) return true;
-
- memset(&surfDescBack, 0, sizeof(surfDescBack));
- surfDescBack.dwSize = sizeof(surfDescBack);
- surfDescBack.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- surfDescBack.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
-
- if(sw)
- surfDescBack.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
- else
- surfDescBack.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
-
-
- surfDescBack.dwWidth = width;
- surfDescBack.dwHeight = height;
-
- if (FAILED(handle->CreateSurface(&surfDescBack, &surface.back, NULL))) return false;
-
- return true;
-}
-
-bool DDRAW::createSurfaces(HWND hwnd)
-{
- if (!handle) return true;
-
- if (clip) { clip->Release(); clip = NULL; }
- if (surface.primary) { surface.primary->Release(); surface.primary = NULL; }
-
-
- // primary
- memset(&surfDesc, 0, sizeof(surfDesc));
- surfDesc.dwSize = sizeof(surfDesc);
- surfDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- surfDesc.dwFlags = DDSD_CAPS;
- if (FAILED(handle->CreateSurface(&surfDesc, &surface.primary, NULL)))
- return false;
-
- //default doesnt matter much, itll get adjusted later
- if(!createBackSurface(GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2))
- return false;
-
- if (FAILED(handle->CreateClipper(0, &clip, NULL))) return false;
- if (FAILED(clip->SetHWnd(0, hwnd))) return false;
- if (FAILED(surface.primary->SetClipper(clip))) return false;
-
- backbuffer_invalidate = false;
-
- return true;
-}
-
-bool DDRAW::lock()
-{
- if (!handle) return true;
- if (!surface.back) return false;
- memset(&surfDescBack, 0, sizeof(surfDescBack));
- surfDescBack.dwSize = sizeof(surfDescBack);
- surfDescBack.dwFlags = DDSD_ALL;
-
- HRESULT res = surface.back->Lock(NULL, &surfDescBack, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
- if (FAILED(res))
- {
- //INFO("DDraw failed: Lock %i\n", res);
- if (res == DDERR_SURFACELOST)
- {
- res = surface.back->Restore();
- if (FAILED(res)) return false;
- }
- }
- return true;
-}
-
-bool DDRAW::unlock()
-{
- if (!handle) return true;
- if (!surface.back) return false;
- if (FAILED(surface.back->Unlock((LPRECT)surfDescBack.lpSurface))) return false;
- return true;
-}
-
-bool DDRAW::OK()
-{
- if (!handle) return false;
- if (!surface.primary) return false;
- if (!surface.back) return false;
- return true;
-}
-
-bool DDRAW::blt(LPRECT dst, LPRECT src)
-{
- if (!handle) return true;
- if (!surface.primary) return false;
- if (!surface.back) return false;
-
- if(GetStyle()&DWS_VSYNC)
- {
- //this seems to block the whole process. this destroys the display thread and will easily block the emulator to 30fps.
- //IDirectDraw7_WaitForVerticalBlank(handle,DDWAITVB_BLOCKBEGIN,0);
-
- for(;;)
- {
- BOOL vblank;
- IDirectDraw7_GetVerticalBlankStatus(handle,&vblank);
- if(vblank) break;
- //must be a greedy loop since vblank is small relative to 1msec minimum Sleep() resolution.
- }
- }
-
- HRESULT res = surface.primary->Blt(dst, surface.back, src, DDBLT_WAIT, 0);
- if (FAILED(res))
- {
- //INFO("DDraw failed: Blt %i\n", res);
- if (res == DDERR_SURFACELOST)
- {
- res = surface.primary->Restore();
- if (FAILED(res)) return false;
- }
- }
- return true;
-}
-
void SetStyle(u32 dws)
{
//pokefan's suggestion, there are a number of ways we could do this.
@@ -8004,4 +7814,6 @@ void SetStyle(u32 dws)
SetWindowPos(MainWindow->getHWnd(), insertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
gldisplay.setvsync(!!(GetStyle()&DWS_VSYNC));
+ ddraw.vSync = GetStyle()&DWS_VSYNC;
+ ddraw.systemMemory = GetStyle()&DWS_DDRAW_SW;
}