1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Moved display mode operations to CompatDisplayMode

This commit is contained in:
narzoul 2016-05-22 11:09:44 +02:00
parent cf08f10162
commit c4ea2541a9
14 changed files with 213 additions and 173 deletions

View File

@ -1,6 +1,7 @@
#include "CompatActivateAppHandler.h" #include "CompatActivateAppHandler.h"
#include "CompatDirectDraw.h" #include "CompatDirectDraw.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatDisplayMode.h"
#include "CompatGdi.h" #include "CompatGdi.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
@ -32,11 +33,8 @@ namespace
} }
dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, g_fullScreenCooperativeFlags); dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, g_fullScreenCooperativeFlags);
if (CompatPrimarySurface::isDisplayModeChanged) auto dm = CompatDisplayMode::getDisplayMode(dd);
{ dd->SetDisplayMode(&dd, dm.width, dm.height, 32, dm.refreshRate, dm.flags);
const CompatPrimarySurface::DisplayMode& dm = CompatPrimarySurface::displayMode;
dd->SetDisplayMode(&dd, dm.width, dm.height, 32, dm.refreshRate, 0);
}
auto primary(CompatPrimarySurface::getPrimary()); auto primary(CompatPrimarySurface::getPrimary());
if (primary && SUCCEEDED(primary->Restore(primary))) if (primary && SUCCEEDED(primary->Restore(primary)))
@ -48,10 +46,7 @@ namespace
void deactivateApp(CompatRef<IDirectDraw7> dd) void deactivateApp(CompatRef<IDirectDraw7> dd)
{ {
if (CompatPrimarySurface::isDisplayModeChanged) dd->RestoreDisplayMode(&dd);
{
dd->RestoreDisplayMode(&dd);
}
dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, DDSCL_NORMAL); dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, DDSCL_NORMAL);
if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES)) if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES))

View File

@ -1,7 +1,7 @@
#include "CompatActivateAppHandler.h" #include "CompatActivateAppHandler.h"
#include "CompatDirectDraw.h" #include "CompatDirectDraw.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatPrimarySurface.h" #include "CompatDisplayMode.h"
#include "CompatPtr.h" #include "CompatPtr.h"
#include "CompatRef.h" #include "CompatRef.h"
#include "IReleaseNotifier.h" #include "IReleaseNotifier.h"
@ -47,18 +47,6 @@ namespace
return tagSurface; return tagSurface;
} }
template <typename TSurfaceDesc>
HRESULT PASCAL enumDisplayModesCallback(
TSurfaceDesc* lpDDSurfaceDesc,
LPVOID lpContext)
{
if (lpDDSurfaceDesc)
{
*static_cast<DDPIXELFORMAT*>(lpContext) = lpDDSurfaceDesc->ddpfPixelFormat;
}
return DDENUMRET_CANCEL;
}
bool isFullScreenDirectDraw(void* dd) bool isFullScreenDirectDraw(void* dd)
{ {
return dd && g_fullScreenDirectDraw && return dd && g_fullScreenDirectDraw &&
@ -72,64 +60,6 @@ namespace
g_fullScreenTagSurface = nullptr; g_fullScreenTagSurface = nullptr;
} }
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
DWORD dwRefreshRate, DWORD dwFlags)
{
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = dwWidth;
desc.dwHeight = dwHeight;
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
desc.ddpfPixelFormat.dwRGBBitCount = dwBPP;
switch (dwBPP)
{
case 1: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1; break;
case 2: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED2; break;
case 4: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED4; break;
case 8: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; break;
}
DDPIXELFORMAT pf = {};
if (dwBPP > 8)
{
if (FAILED(dd->EnumDisplayModes(&dd, 0, &desc, &pf, &enumDisplayModesCallback)) ||
0 == pf.dwSize)
{
Compat::Log() << "Failed to find the requested display mode: " <<
dwWidth << "x" << dwHeight << "x" << dwBPP;
return DDERR_INVALIDMODE;
}
}
else
{
pf = desc.ddpfPixelFormat;
}
HRESULT result = dd->SetDisplayMode(&dd, dwWidth, dwHeight, 32, dwRefreshRate, dwFlags);
if (SUCCEEDED(result))
{
CompatPrimarySurface::displayMode.width = dwWidth;
CompatPrimarySurface::displayMode.height = dwHeight;
CompatPrimarySurface::displayMode.pixelFormat = pf;
CompatPrimarySurface::displayMode.refreshRate = dwRefreshRate;
CompatPrimarySurface::isDisplayModeChanged = true;
}
else
{
Compat::Log() << "Failed to set the display mode to " << dwWidth << "x" << dwHeight << "x32";
}
return result;
}
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP)
{
return setDisplayMode(dd, dwWidth, dwHeight, dwBPP, 0, 0);
}
void setFullScreenDirectDraw(CompatRef<IDirectDraw> dd) void setFullScreenDirectDraw(CompatRef<IDirectDraw> dd)
{ {
g_fullScreenTagSurface.release(); g_fullScreenTagSurface.release();
@ -186,16 +116,19 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::CreateSurface(
} }
else else
{ {
if (CompatPrimarySurface::displayMode.pixelFormat.dwSize != 0 && if (lpDDSurfaceDesc &&
!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) && !(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) && (lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) &&
(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) && (lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) &&
!((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) && !((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) &&
(lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALPHA | DDSCAPS_ZBUFFER)))) (lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALPHA | DDSCAPS_ZBUFFER))))
{ {
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
auto dm = CompatDisplayMode::getDisplayMode(*dd);
TSurfaceDesc desc = *lpDDSurfaceDesc; TSurfaceDesc desc = *lpDDSurfaceDesc;
desc.dwFlags |= DDSD_PIXELFORMAT; desc.dwFlags |= DDSD_PIXELFORMAT;
desc.ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat; desc.ddpfPixelFormat = dm.pixelFormat;
result = s_origVtable.CreateSurface(This, &desc, lplpDDSurface, pUnkOuter); result = s_origVtable.CreateSurface(This, &desc, lplpDDSurface, pUnkOuter);
} }
else else
@ -215,14 +148,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::CreateSurface(
template <typename TDirectDraw> template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This) HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
{ {
HRESULT result = s_origVtable.RestoreDisplayMode(This); CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
if (SUCCEEDED(result)) return CompatDisplayMode::restoreDisplayMode(*dd);
{
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(*dd);
CompatPrimarySurface::isDisplayModeChanged = false;
}
return result;
} }
template <typename TDirectDraw> template <typename TDirectDraw>
@ -262,7 +189,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetDisplayMode(
Params... params) Params... params)
{ {
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This)); CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
return setDisplayMode(*dd, dwWidth, dwHeight, dwBPP, params...); return CompatDisplayMode::setDisplayMode(*dd, dwWidth, dwHeight, dwBPP, params...);
} }
template <> const IID& CompatDirectDraw<IDirectDraw>::s_iid = IID_IDirectDraw; template <> const IID& CompatDirectDraw<IDirectDraw>::s_iid = IID_IDirectDraw;

View File

@ -3,6 +3,7 @@
#include "CompatDirectDraw.h" #include "CompatDirectDraw.h"
#include "CompatDirectDrawPalette.h" #include "CompatDirectDrawPalette.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatDisplayMode.h"
#include "CompatGdi.h" #include "CompatGdi.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
@ -178,28 +179,20 @@ HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
TSurface*& compatSurface) TSurface*& compatSurface)
{ {
if (0 == CompatPrimarySurface::displayMode.pixelFormat.dwSize)
{
CompatPtr<IDirectDraw7> dd7(Compat::queryInterface<IDirectDraw7>(&dd));
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(*dd7);
}
HRESULT result = RealPrimarySurface::create(dd); HRESULT result = RealPrimarySurface::create(dd);
if (FAILED(result)) if (FAILED(result))
{ {
return result; return result;
} }
CompatPrimarySurface::width = CompatPrimarySurface::displayMode.width; CompatPtr<IDirectDraw7> dd7(Compat::queryInterface<IDirectDraw7>(&dd));
CompatPrimarySurface::height = CompatPrimarySurface::displayMode.height; const auto& dm = CompatDisplayMode::getDisplayMode(*dd7);
CompatPrimarySurface::pixelFormat = CompatPrimarySurface::displayMode.pixelFormat;
compatDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; compatDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
compatDesc.dwWidth = CompatPrimarySurface::width; compatDesc.dwWidth = dm.width;
compatDesc.dwHeight = CompatPrimarySurface::height; compatDesc.dwHeight = dm.height;
compatDesc.ddsCaps.dwCaps ^= DDSCAPS_PRIMARYSURFACE; compatDesc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE;
compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
compatDesc.ddpfPixelFormat = CompatPrimarySurface::pixelFormat; compatDesc.ddpfPixelFormat = dm.pixelFormat;
result = dd->CreateSurface(&dd, &compatDesc, &compatSurface, nullptr); result = dd->CreateSurface(&dd, &compatDesc, &compatSurface, nullptr);
if (FAILED(result)) if (FAILED(result))

View File

@ -0,0 +1,117 @@
#include "CompatDisplayMode.h"
namespace
{
CompatDisplayMode::DisplayMode g_emulatedDisplayMode = {};
template <typename TSurfaceDesc>
HRESULT PASCAL enumDisplayModesCallback(
TSurfaceDesc* lpDDSurfaceDesc,
LPVOID lpContext)
{
if (lpDDSurfaceDesc)
{
*static_cast<DDPIXELFORMAT*>(lpContext) = lpDDSurfaceDesc->ddpfPixelFormat;
}
return DDENUMRET_CANCEL;
}
DDPIXELFORMAT getDisplayModePixelFormat(
CompatRef<IDirectDraw7> dd, DWORD width, DWORD height, DWORD bpp)
{
DDSURFACEDESC2 desc = {};
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
desc.ddpfPixelFormat.dwRGBBitCount = bpp;
if (bpp <= 8)
{
switch (bpp)
{
case 1: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1; break;
case 2: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED2; break;
case 4: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED4; break;
case 8: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; break;
default: return DDPIXELFORMAT();
}
return desc.ddpfPixelFormat;
}
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = width;
desc.dwHeight = height;
DDPIXELFORMAT pf = {};
if (FAILED(dd->EnumDisplayModes(&dd, 0, &desc, &pf, &enumDisplayModesCallback)) ||
0 == pf.dwSize)
{
Compat::Log() << "Failed to find the requested display mode: " <<
width << "x" << height << "x" << bpp;
}
return pf;
}
}
namespace CompatDisplayMode
{
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd)
{
if (0 == g_emulatedDisplayMode.width)
{
g_emulatedDisplayMode = getRealDisplayMode(dd);
}
return g_emulatedDisplayMode;
}
DisplayMode getRealDisplayMode(CompatRef<IDirectDraw7> dd)
{
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
dd->GetDisplayMode(&dd, &desc);
DisplayMode dm = {};
dm.width = desc.dwWidth;
dm.height = desc.dwHeight;
dm.pixelFormat = desc.ddpfPixelFormat;
dm.refreshRate = desc.dwRefreshRate;
return dm;
}
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd)
{
const HRESULT result = dd->RestoreDisplayMode(&dd);
if (SUCCEEDED(result))
{
ZeroMemory(&g_emulatedDisplayMode, sizeof(g_emulatedDisplayMode));
}
return result;
}
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
{
DDPIXELFORMAT pf = getDisplayModePixelFormat(dd, width, height, bpp);
if (0 == pf.dwSize)
{
return DDERR_INVALIDMODE;
}
const HRESULT result = dd->SetDisplayMode(&dd, width, height, 32, refreshRate, flags);
if (FAILED(result))
{
Compat::Log() << "Failed to set the display mode to " << width << "x" << height <<
"x" << bpp << " (" << std::hex << result << std::dec << ')';
return result;
}
g_emulatedDisplayMode.width = width;
g_emulatedDisplayMode.height = height;
g_emulatedDisplayMode.pixelFormat = pf;
g_emulatedDisplayMode.refreshRate = refreshRate;
g_emulatedDisplayMode.flags = flags;
return DD_OK;
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#define CINTERFACE
#include <ddraw.h>
#include "CompatRef.h"
namespace CompatDisplayMode
{
struct DisplayMode
{
DWORD width;
DWORD height;
DDPIXELFORMAT pixelFormat;
DWORD refreshRate;
DWORD flags;
};
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd);
DisplayMode getRealDisplayMode(CompatRef<IDirectDraw7> dd);
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd);
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate = 0, DWORD flags = 0);
};

View File

@ -55,12 +55,8 @@ namespace
CompatPtr<IDirectDrawSurface7> createGdiSurface() CompatPtr<IDirectDrawSurface7> createGdiSurface()
{ {
DDSURFACEDESC2 desc = {}; DDSURFACEDESC2 desc = CompatPrimarySurface::getDesc();
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH | DDSD_LPSURFACE; desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH | DDSD_LPSURFACE;
desc.dwWidth = CompatPrimarySurface::width;
desc.dwHeight = CompatPrimarySurface::height;
desc.ddpfPixelFormat = CompatPrimarySurface::pixelFormat;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
desc.lPitch = g_pitch; desc.lPitch = g_pitch;
desc.lpSurface = g_surfaceMemory; desc.lpSurface = g_surfaceMemory;
@ -74,7 +70,7 @@ namespace
return nullptr; return nullptr;
} }
if (CompatPrimarySurface::pixelFormat.dwRGBBitCount <= 8) if (desc.ddpfPixelFormat.dwRGBBitCount <= 8)
{ {
surface->SetPalette(surface, g_palette); surface->SetPalette(surface, g_palette);
} }

View File

@ -96,7 +96,7 @@ namespace CompatGdi
{ {
flags |= DC_ACTIVE; flags |= DC_ACTIVE;
} }
if (CompatPrimarySurface::pixelFormat.dwRGBBitCount > 8) if (CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8)
{ {
flags |= DC_GRADIENT; flags |= DC_GRADIENT;
} }

View File

@ -1,6 +1,7 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include "CompatDisplayMode.h"
#include "CompatPaletteConverter.h" #include "CompatPaletteConverter.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
@ -25,7 +26,7 @@ namespace
} }
} }
HBITMAP createDibSection(const DDSURFACEDESC2& primaryDesc, void*& bits) HBITMAP createDibSection(const CompatDisplayMode::DisplayMode& dm, void*& bits)
{ {
struct PalettizedBitmapInfo struct PalettizedBitmapInfo
{ {
@ -35,28 +36,27 @@ namespace
PalettizedBitmapInfo bmi = {}; PalettizedBitmapInfo bmi = {};
bmi.header.biSize = sizeof(bmi.header); bmi.header.biSize = sizeof(bmi.header);
bmi.header.biWidth = primaryDesc.dwWidth; bmi.header.biWidth = dm.width;
bmi.header.biHeight = -static_cast<LONG>(primaryDesc.dwHeight); bmi.header.biHeight = -static_cast<LONG>(dm.height);
bmi.header.biPlanes = 1; bmi.header.biPlanes = 1;
bmi.header.biBitCount = 8; bmi.header.biBitCount = static_cast<WORD>(dm.pixelFormat.dwRGBBitCount);
bmi.header.biCompression = BI_RGB; bmi.header.biCompression = BI_RGB;
bmi.header.biClrUsed = 256;
return CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&bmi), return CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&bmi),
DIB_RGB_COLORS, &bits, nullptr, 0); DIB_RGB_COLORS, &bits, nullptr, 0);
} }
CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& primaryDesc, void* bits) CompatPtr<IDirectDrawSurface7> createSurface(const CompatDisplayMode::DisplayMode& dm, void* bits)
{ {
DDSURFACEDESC2 desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
DDSD_PITCH | DDSD_LPSURFACE; DDSD_PITCH | DDSD_LPSURFACE;
desc.dwWidth = primaryDesc.dwWidth; desc.dwWidth = dm.width;
desc.dwHeight = primaryDesc.dwHeight; desc.dwHeight = dm.height;
desc.ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat; desc.ddpfPixelFormat = dm.pixelFormat;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
desc.lPitch = (primaryDesc.dwWidth + 3) & ~3; desc.lPitch = (dm.width * dm.pixelFormat.dwRGBBitCount / 8 + 3) & ~3;
desc.lpSurface = bits; desc.lpSurface = bits;
auto dd(DDrawRepository::getDirectDraw()); auto dd(DDrawRepository::getDirectDraw());
@ -68,23 +68,25 @@ namespace
namespace CompatPaletteConverter namespace CompatPaletteConverter
{ {
bool create(const DDSURFACEDESC2& primaryDesc) bool create()
{ {
if (CompatPrimarySurface::displayMode.pixelFormat.dwRGBBitCount > 8 && auto dd(DDrawRepository::getDirectDraw());
primaryDesc.ddpfPixelFormat.dwRGBBitCount > 8) auto dm(CompatDisplayMode::getDisplayMode(*dd));
if (dm.pixelFormat.dwRGBBitCount > 8 &&
CompatDisplayMode::getRealDisplayMode(*dd).pixelFormat.dwRGBBitCount > 8)
{ {
return true; return true;
} }
void* bits = nullptr; void* bits = nullptr;
HBITMAP dib = createDibSection(primaryDesc, bits); HBITMAP dib = createDibSection(dm, bits);
if (!dib) if (!dib)
{ {
Compat::Log() << "Failed to create the palette converter DIB section"; Compat::Log() << "Failed to create the palette converter DIB section";
return false; return false;
} }
CompatPtr<IDirectDrawSurface7> surface(createSurface(primaryDesc, bits)); CompatPtr<IDirectDrawSurface7> surface(createSurface(dm, bits));
if (!surface) if (!surface)
{ {
Compat::Log() << "Failed to create the palette converter surface"; Compat::Log() << "Failed to create the palette converter surface";

View File

@ -8,7 +8,7 @@
namespace CompatPaletteConverter namespace CompatPaletteConverter
{ {
bool create(const DDSURFACEDESC2& primaryDesc); bool create();
HDC getDc(); HDC getDc();
CompatWeakPtr<IDirectDrawSurface7> getSurface(); CompatWeakPtr<IDirectDrawSurface7> getSurface();
void release(); void release();

View File

@ -9,8 +9,12 @@
namespace namespace
{ {
void onRelease();
DDSURFACEDESC2 g_primarySurfaceDesc = {};
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr; CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
std::vector<void*> g_primarySurfacePtrs; std::vector<void*> g_primarySurfacePtrs;
IReleaseNotifier g_releaseNotifier(onRelease);
void onRelease() void onRelease()
{ {
@ -19,10 +23,8 @@ namespace
g_primarySurfacePtrs.clear(); g_primarySurfacePtrs.clear();
g_primarySurface = nullptr; g_primarySurface = nullptr;
CompatPrimarySurface::palette = nullptr; CompatPrimarySurface::palette = nullptr;
CompatPrimarySurface::width = 0;
CompatPrimarySurface::height = 0;
ZeroMemory(&CompatPrimarySurface::paletteEntries, sizeof(CompatPrimarySurface::paletteEntries)); ZeroMemory(&CompatPrimarySurface::paletteEntries, sizeof(CompatPrimarySurface::paletteEntries));
ZeroMemory(&CompatPrimarySurface::pixelFormat, sizeof(CompatPrimarySurface::pixelFormat)); ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
RealPrimarySurface::release(); RealPrimarySurface::release();
@ -32,17 +34,9 @@ namespace
namespace CompatPrimarySurface namespace CompatPrimarySurface
{ {
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd) const DDSURFACEDESC2& getDesc()
{ {
DisplayMode dm = {}; return g_primarySurfaceDesc;
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
dd->GetDisplayMode(&dd, &desc);
dm.width = desc.dwWidth;
dm.height = desc.dwHeight;
dm.pixelFormat = desc.ddpfPixelFormat;
dm.refreshRate = desc.dwRefreshRate;
return dm;
} }
CompatPtr<IDirectDrawSurface7> getPrimary() CompatPtr<IDirectDrawSurface7> getPrimary()
@ -66,6 +60,10 @@ namespace CompatPrimarySurface
CompatPtr<IDirectDrawSurface> surfacePtr(Compat::queryInterface<IDirectDrawSurface>(&surface)); CompatPtr<IDirectDrawSurface> surfacePtr(Compat::queryInterface<IDirectDrawSurface>(&surface));
g_primarySurface = surfacePtr; g_primarySurface = surfacePtr;
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc);
surface->GetSurfaceDesc(&surface, &g_primarySurfaceDesc);
g_primarySurfacePtrs.clear(); g_primarySurfacePtrs.clear();
g_primarySurfacePtrs.push_back(&surface); g_primarySurfacePtrs.push_back(&surface);
g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface4>(surfacePtr)); g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface4>(surfacePtr));
@ -73,17 +71,11 @@ namespace CompatPrimarySurface
g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface2>(surfacePtr)); g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface2>(surfacePtr));
g_primarySurfacePtrs.push_back(surfacePtr); g_primarySurfacePtrs.push_back(surfacePtr);
IReleaseNotifier* releaseNotifierPtr = &releaseNotifier; IReleaseNotifier* releaseNotifierPtr = &g_releaseNotifier;
surface->SetPrivateData(&surface, IID_IReleaseNotifier, surface->SetPrivateData(&surface, IID_IReleaseNotifier,
releaseNotifierPtr, sizeof(releaseNotifierPtr), DDSPD_IUNKNOWNPOINTER); releaseNotifierPtr, sizeof(releaseNotifierPtr), DDSPD_IUNKNOWNPOINTER);
} }
DisplayMode displayMode = {};
bool isDisplayModeChanged = false;
CompatWeakPtr<IDirectDrawPalette> palette; CompatWeakPtr<IDirectDrawPalette> palette;
PALETTEENTRY paletteEntries[256] = {}; PALETTEENTRY paletteEntries[256] = {};
LONG width = 0;
LONG height = 0;
DDPIXELFORMAT pixelFormat = {};
IReleaseNotifier releaseNotifier(onRelease);
} }

View File

@ -11,26 +11,11 @@ class IReleaseNotifier;
namespace CompatPrimarySurface namespace CompatPrimarySurface
{ {
struct DisplayMode const DDSURFACEDESC2& getDesc();
{
LONG width;
LONG height;
DDPIXELFORMAT pixelFormat;
DWORD refreshRate;
};
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd);
CompatPtr<IDirectDrawSurface7> getPrimary(); CompatPtr<IDirectDrawSurface7> getPrimary();
bool isPrimary(void* surface); bool isPrimary(void* surface);
void setPrimary(CompatRef<IDirectDrawSurface7> surface); void setPrimary(CompatRef<IDirectDrawSurface7> surface);
extern DisplayMode displayMode;
extern bool isDisplayModeChanged;
extern CompatWeakPtr<IDirectDrawPalette> palette; extern CompatWeakPtr<IDirectDrawPalette> palette;
extern PALETTEENTRY paletteEntries[256]; extern PALETTEENTRY paletteEntries[256];
extern LONG width;
extern LONG height;
extern DDPIXELFORMAT pixelFormat;
extern IReleaseNotifier releaseNotifier;
} }

View File

@ -146,6 +146,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="CompatActivateAppHandler.h" /> <ClInclude Include="CompatActivateAppHandler.h" />
<ClInclude Include="CompatDirectDrawPalette.h" /> <ClInclude Include="CompatDirectDrawPalette.h" />
<ClInclude Include="CompatDisplayMode.h" />
<ClInclude Include="CompatGdi.h" /> <ClInclude Include="CompatGdi.h" />
<ClInclude Include="CompatGdiCaret.h" /> <ClInclude Include="CompatGdiCaret.h" />
<ClInclude Include="CompatGdiDc.h" /> <ClInclude Include="CompatGdiDc.h" />
@ -187,6 +188,7 @@
<ClCompile Include="CompatDirectDraw.cpp" /> <ClCompile Include="CompatDirectDraw.cpp" />
<ClCompile Include="CompatDirectDrawPalette.cpp" /> <ClCompile Include="CompatDirectDrawPalette.cpp" />
<ClCompile Include="CompatDirectDrawSurface.cpp" /> <ClCompile Include="CompatDirectDrawSurface.cpp" />
<ClCompile Include="CompatDisplayMode.cpp" />
<ClCompile Include="CompatGdi.cpp" /> <ClCompile Include="CompatGdi.cpp" />
<ClCompile Include="CompatGdiCaret.cpp" /> <ClCompile Include="CompatGdiCaret.cpp" />
<ClCompile Include="CompatGdiDcCache.cpp" /> <ClCompile Include="CompatGdiDcCache.cpp" />

View File

@ -126,6 +126,9 @@
<ClInclude Include="CompatRef.h"> <ClInclude Include="CompatRef.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CompatDisplayMode.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="DllMain.cpp"> <ClCompile Include="DllMain.cpp">
@ -206,6 +209,9 @@
<ClCompile Include="CompatActivateAppHandler.cpp"> <ClCompile Include="CompatActivateAppHandler.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CompatDisplayMode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="DDrawCompat.def"> <None Include="DDrawCompat.def">

View File

@ -48,7 +48,7 @@ namespace
bool result = false; bool result = false;
auto primary(CompatPrimarySurface::getPrimary()); auto primary(CompatPrimarySurface::getPrimary());
if (CompatPrimarySurface::pixelFormat.dwRGBBitCount <= 8) if (CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8)
{ {
auto paletteConverter(CompatPaletteConverter::getSurface()); auto paletteConverter(CompatPaletteConverter::getSurface());
paletteConverter->Blt(paletteConverter, &g_updateRect, paletteConverter->Blt(paletteConverter, &g_updateRect,
@ -92,17 +92,17 @@ namespace
HRESULT init(CompatPtr<IDirectDrawSurface7> surface) HRESULT init(CompatPtr<IDirectDrawSurface7> surface)
{ {
DDSURFACEDESC2 desc = {}; if (!CompatPaletteConverter::create())
desc.dwSize = sizeof(desc);
surface->GetSurfaceDesc(surface, &desc);
if (!CompatPaletteConverter::create(desc))
{ {
return DDERR_GENERIC; return DDERR_GENERIC;
} }
CompatPtr<IDirectDrawSurface7> backBuffer; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
surface->GetSurfaceDesc(surface, &desc);
const bool isFlippable = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_FLIP); const bool isFlippable = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_FLIP);
CompatPtr<IDirectDrawSurface7> backBuffer;
if (isFlippable) if (isFlippable)
{ {
DDSCAPS2 backBufferCaps = {}; DDSCAPS2 backBufferCaps = {};
@ -294,8 +294,8 @@ void RealPrimarySurface::invalidate(const RECT* rect)
} }
else else
{ {
SetRect(&g_updateRect, 0, 0, auto primaryDesc = CompatPrimarySurface::getDesc();
CompatPrimarySurface::displayMode.width, CompatPrimarySurface::displayMode.height); SetRect(&g_updateRect, 0, 0, primaryDesc.dwWidth, primaryDesc.dwHeight);
} }
} }