Move DirectDraw code to its own .h and .cpp files.

This commit is contained in:
SuuperW 2018-08-13 11:08:59 -05:00
parent 4357ba8f47
commit 4c83ec19e9
5 changed files with 251 additions and 192 deletions

View File

@ -284,6 +284,7 @@
<ClCompile Include="colorctrl.cpp" /> <ClCompile Include="colorctrl.cpp" />
<ClCompile Include="console.cpp" /> <ClCompile Include="console.cpp" />
<ClCompile Include="CWindow.cpp" /> <ClCompile Include="CWindow.cpp" />
<ClCompile Include="ddraw.cpp" />
<ClCompile Include="FEX_Interface.cpp" /> <ClCompile Include="FEX_Interface.cpp" />
<ClCompile Include="File_Extractor\7z_C\7zAlloc.c" /> <ClCompile Include="File_Extractor\7z_C\7zAlloc.c" />
<ClCompile Include="File_Extractor\7z_C\7zBuf.c" /> <ClCompile Include="File_Extractor\7z_C\7zBuf.c" />
@ -582,6 +583,7 @@
<ClInclude Include="colorctrl.h" /> <ClInclude Include="colorctrl.h" />
<ClInclude Include="console.h" /> <ClInclude Include="console.h" />
<ClInclude Include="CWindow.h" /> <ClInclude Include="CWindow.h" />
<ClInclude Include="ddraw.h" />
<ClInclude Include="FEX_Interface.h" /> <ClInclude Include="FEX_Interface.h" />
<ClInclude Include="File_Extractor\7z_C\7z.h" /> <ClInclude Include="File_Extractor\7z_C\7z.h" />
<ClInclude Include="File_Extractor\7z_C\7zAlloc.h" /> <ClInclude Include="File_Extractor\7z_C\7zAlloc.h" />

View File

@ -921,6 +921,9 @@
<ClCompile Include="..\..\utils\colorspacehandler\colorspacehandler_AltiVec.cpp"> <ClCompile Include="..\..\utils\colorspacehandler\colorspacehandler_AltiVec.cpp">
<Filter>utils\colorspacehandler</Filter> <Filter>utils\colorspacehandler</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ddraw.cpp">
<Filter>frontend\Windows</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\utils\guid.h"> <ClInclude Include="..\..\utils\guid.h">
@ -1610,6 +1613,9 @@
<ClInclude Include="..\..\utils\colorspacehandler\colorspacehandler_SSE2.h"> <ClInclude Include="..\..\utils\colorspacehandler\colorspacehandler_SSE2.h">
<Filter>utils\colorspacehandler</Filter> <Filter>utils\colorspacehandler</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ddraw.h">
<Filter>frontend\Windows</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="bitmap1.bmp"> <None Include="bitmap1.bmp">

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -91,6 +91,7 @@
#include "frontend/modules/ImageOut.h" #include "frontend/modules/ImageOut.h"
#include "winutil.h" #include "winutil.h"
#include "ogl.h" #include "ogl.h"
#include "ddraw.h"
//tools and dialogs //tools and dialogs
#include "pathsettings.h" #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(CRITICAL_SECTION& cs) : m_cs(&cs) { EnterCriticalSection(m_cs); }
Lock::~Lock() { LeaveCriticalSection(m_cs); } Lock::~Lock() { LeaveCriticalSection(m_cs); }
//====================== DirectDraw DDRAW ddraw;
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;
//===================== Input vars //===================== Input vars
#define WM_CUSTKEYDOWN (WM_USER+50) #define WM_CUSTKEYDOWN (WM_USER+50)
@ -7821,161 +7786,6 @@ void WIN_InstallGBACartridge()
GBACartridge_SRAMPath = Path::GetFileNameWithoutExt(win32_GBA_cfgRomPath) + "." + GBA_SRAM_FILE_EXT; 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) void SetStyle(u32 dws)
{ {
//pokefan's suggestion, there are a number of ways we could do this. //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); SetWindowPos(MainWindow->getHWnd(), insertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
gldisplay.setvsync(!!(GetStyle()&DWS_VSYNC)); gldisplay.setvsync(!!(GetStyle()&DWS_VSYNC));
ddraw.vSync = GetStyle()&DWS_VSYNC;
ddraw.systemMemory = GetStyle()&DWS_DDRAW_SW;
} }