From 4c83ec19e91b74e03810a5358a590509ca241b87 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Mon, 13 Aug 2018 11:08:59 -0500 Subject: [PATCH] Move DirectDraw code to its own .h and .cpp files. --- desmume/src/frontend/windows/DeSmuME.vcxproj | 2 + .../frontend/windows/DeSmuME.vcxproj.filters | 6 + desmume/src/frontend/windows/ddraw.cpp | 185 +++++++++++++++++ desmume/src/frontend/windows/ddraw.h | 54 +++++ desmume/src/frontend/windows/main.cpp | 196 +----------------- 5 files changed, 251 insertions(+), 192 deletions(-) create mode 100644 desmume/src/frontend/windows/ddraw.cpp create mode 100644 desmume/src/frontend/windows/ddraw.h 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; }