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

Simplified 8/16 bit display mode emulation

This commit is contained in:
narzoul 2019-01-12 16:55:53 +01:00
parent 26f8742dc2
commit d817c4bfb3
8 changed files with 17 additions and 173 deletions

View File

@ -187,6 +187,11 @@ namespace D3dDdi
}
}
if (data.Flags.Primary)
{
data.Format = D3DDDIFMT_X8R8G8B8;
}
HRESULT result = origCreateResource(m_device, &data);
if (SUCCEEDED(result) && data.Flags.RenderTarget && !data.Flags.Primary && isVidMemPool(data.Pool))
{

View File

@ -5,26 +5,6 @@
#include "DDraw/Surfaces/PrimarySurface.h"
#include "Win32/DisplayMode.h"
namespace
{
template <typename TDirectDraw>
HRESULT setDisplayMode(TDirectDraw* This, DWORD width, DWORD height, DWORD bpp)
{
return DDraw::DirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode(This, width, height, bpp);
}
template <typename TDirectDraw>
HRESULT setDisplayMode(TDirectDraw* This, DWORD width, DWORD height, DWORD bpp,
DWORD refreshRate, DWORD flags)
{
Win32::DisplayMode::setDDrawBpp(bpp);
HRESULT result = DDraw::DirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode(
This, width, height, 32, refreshRate, flags);
Win32::DisplayMode::setDDrawBpp(0);
return result;
}
}
namespace DDraw
{
template <typename TDirectDraw>
@ -42,7 +22,7 @@ namespace DDraw
{
DDSURFACEDESC2 dm = {};
dm.dwSize = sizeof(dm);
dd.get().lpVtbl->GetDisplayMode(&dd, &dm);
dd->GetDisplayMode(&dd, &dm);
return dm;
}
@ -97,10 +77,8 @@ namespace DDraw
{
vtable.CreateSurface = &CreateSurface;
vtable.FlipToGDISurface = &FlipToGDISurface;
vtable.GetDisplayMode = &GetDisplayMode;
vtable.GetGDISurface = &GetGDISurface;
vtable.SetCooperativeLevel = &SetCooperativeLevel;
vtable.SetDisplayMode = &SetDisplayMode;
vtable.WaitForVerticalBlank = &WaitForVerticalBlank;
}
@ -132,18 +110,6 @@ namespace DDraw
return PrimarySurface::flipToGdiSurface();
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
{
HRESULT result = s_origVtable.GetDisplayMode(This, lpDDSurfaceDesc);
if (SUCCEEDED(result) && lpDDSurfaceDesc)
{
lpDDSurfaceDesc->ddpfPixelFormat = getRgbPixelFormat(Win32::DisplayMode::getBpp());
}
return result;
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetGDISurface(
TDirectDraw* /*This*/, TSurface** lplpGDIDDSSurface)
@ -182,18 +148,6 @@ namespace DDraw
return result;
}
template <typename TDirectDraw>
template <typename... Params>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetDisplayMode(
TDirectDraw* This,
DWORD dwWidth,
DWORD dwHeight,
DWORD dwBPP,
Params... params)
{
return setDisplayMode(This, dwWidth, dwHeight, dwBPP, params...);
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::WaitForVerticalBlank(
TDirectDraw* This, DWORD dwFlags, HANDLE hEvent)

View File

@ -32,19 +32,9 @@ namespace DDraw
IUnknown* pUnkOuter);
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
static HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID);
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
template <typename... Params>
static HRESULT STDMETHODCALLTYPE SetDisplayMode(
TDirectDraw* This,
DWORD dwWidth,
DWORD dwHeight,
DWORD dwBPP,
Params... params);
static HRESULT STDMETHODCALLTYPE WaitForVerticalBlank(TDirectDraw* This, DWORD dwFlags, HANDLE hEvent);
};
}

View File

@ -13,18 +13,12 @@ DEFINE_GUID(IID_CompatSurfacePrivateData,
namespace
{
void fixSurfaceDesc(DWORD& flags, DWORD& caps, DDPIXELFORMAT& pf)
void fixSurfaceDesc(DWORD& flags, DWORD& caps)
{
if ((flags & DDSD_WIDTH) &&
(flags & DDSD_HEIGHT) &&
!(caps & (DDSCAPS_ALPHA | DDSCAPS_ZBUFFER)))
{
if (!(flags & DDSD_PIXELFORMAT))
{
flags |= DDSD_PIXELFORMAT;
pf = DDraw::getRgbPixelFormat(Win32::DisplayMode::getBpp());
}
if (!(caps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_OVERLAY | DDSCAPS_TEXTURE |
DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)))
{
@ -129,7 +123,7 @@ namespace DDraw
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
HRESULT Surface::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
{
fixSurfaceDesc(desc.dwFlags, desc.ddsCaps.dwCaps, desc.ddpfPixelFormat);
fixSurfaceDesc(desc.dwFlags, desc.ddsCaps.dwCaps);
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
if (SUCCEEDED(result))

View File

@ -41,7 +41,7 @@ namespace
Compat::Log() << "Installing Direct3D driver hooks";
D3dDdi::installHooks(g_origDDrawModule);
Compat::Log() << "Installing display mode hooks";
Win32::DisplayMode::installHooks(g_origDDrawModule);
Win32::DisplayMode::installHooks();
Gdi::VirtualScreen::init();
CompatPtr<IDirectDraw> dd;

View File

@ -184,7 +184,8 @@ namespace Gdi
static auto prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1;
const auto currentDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness();
if (currentDisplaySettingsUniqueness == prevDisplaySettingsUniqueness)
const auto bpp = Win32::DisplayMode::getBpp();
if (currentDisplaySettingsUniqueness == prevDisplaySettingsUniqueness && bpp == g_bpp)
{
return LOG_RESULT(false);
}
@ -195,7 +196,7 @@ namespace Gdi
EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast<LPARAM>(&g_region));
GetRgnBox(g_region, &g_bounds);
g_bpp = Win32::DisplayMode::getBpp();
g_bpp = bpp;
g_width = g_bounds.right - g_bounds.left;
g_height = g_bounds.bottom - g_bounds.top;
g_pitch = (g_width * g_bpp / 8 + 3) & ~3;

View File

@ -6,6 +6,7 @@
#include "DDraw/DirectDraw.h"
#include "DDraw/ScopedThreadLock.h"
#include "Gdi/Gdi.h"
#include "Gdi/VirtualScreen.h"
#include "Win32/DisplayMode.h"
BOOL WINAPI DWM8And16Bit_IsShimApplied_CallOut() { return FALSE; };
@ -32,7 +33,6 @@ namespace
DWORD g_origBpp = 0;
DWORD g_currentBpp = 0;
DWORD g_lastBpp = 0;
DWORD g_ddrawBpp = 0;
BOOL WINAPI enumDisplaySettingsExA(
LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode, DWORD dwFlags);
@ -94,6 +94,8 @@ namespace
SetEvent(dwmDxFullScreenTransitionEvent);
CloseHandle(dwmDxFullScreenTransitionEvent);
}
Gdi::VirtualScreen::update();
}
return result;
@ -119,85 +121,6 @@ namespace
lpszDeviceName, lpDevMode, hwnd, dwflags, lParam));
}
template <typename CStr, typename DevMode, typename ChangeDisplaySettingsExFunc>
LONG ddrawChangeDisplaySettingsEx(
ChangeDisplaySettingsExFunc changeDisplaySettingsEx,
CStr lpszDeviceName, DevMode* lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
{
if (lpDevMode && 0 != lpDevMode->dmBitsPerPel)
{
lpDevMode->dmBitsPerPel = (0 != g_ddrawBpp) ? g_ddrawBpp : g_lastBpp;
}
return changeDisplaySettingsEx(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
}
LONG WINAPI ddrawChangeDisplaySettingsA(
DEVMODEA* lpDevMode, DWORD dwflags)
{
return ddrawChangeDisplaySettingsEx(&changeDisplaySettingsExA,
nullptr, lpDevMode, nullptr, dwflags, nullptr);
}
LONG WINAPI ddrawChangeDisplaySettingsW(
DEVMODEW* lpDevMode, DWORD dwflags)
{
return ddrawChangeDisplaySettingsEx(&changeDisplaySettingsExW,
nullptr, lpDevMode, nullptr, dwflags, nullptr);
}
LONG WINAPI ddrawChangeDisplaySettingsExA(
LPCSTR lpszDeviceName, DEVMODEA* lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
{
return ddrawChangeDisplaySettingsEx(&changeDisplaySettingsExA,
lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
}
LONG WINAPI ddrawChangeDisplaySettingsExW(
LPCWSTR lpszDeviceName, DEVMODEW* lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
{
return ddrawChangeDisplaySettingsEx(&changeDisplaySettingsExW,
lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
}
template <typename CStr, typename DevMode, typename EnumDisplaySettingsExFunc>
BOOL WINAPI ddrawEnumDisplaySettingsEx(
EnumDisplaySettingsExFunc origEnumDisplaySettingsEx,
EnumDisplaySettingsExFunc enumDisplaySettingsEx,
CStr lpszDeviceName, DWORD iModeNum, DevMode* lpDevMode, DWORD dwFlags)
{
if (ENUM_CURRENT_SETTINGS == iModeNum)
{
return origEnumDisplaySettingsEx(lpszDeviceName, iModeNum, lpDevMode, dwFlags);
}
return enumDisplaySettingsEx(lpszDeviceName, iModeNum, lpDevMode, dwFlags);
}
BOOL WINAPI ddrawEnumDisplaySettingsA(LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode)
{
return ddrawEnumDisplaySettingsEx(CALL_ORIG_FUNC(EnumDisplaySettingsExA), &enumDisplaySettingsExA,
lpszDeviceName, iModeNum, lpDevMode, 0);
}
BOOL WINAPI ddrawEnumDisplaySettingsW(LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode)
{
return ddrawEnumDisplaySettingsEx(CALL_ORIG_FUNC(EnumDisplaySettingsExW), &enumDisplaySettingsExW,
lpszDeviceName, iModeNum, lpDevMode, 0);
}
BOOL WINAPI ddrawEnumDisplaySettingsExA(
LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode, DWORD dwFlags)
{
return ddrawEnumDisplaySettingsEx(CALL_ORIG_FUNC(EnumDisplaySettingsExA), &enumDisplaySettingsExA,
lpszDeviceName, iModeNum, lpDevMode, dwFlags);
}
BOOL WINAPI ddrawEnumDisplaySettingsExW(
LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode, DWORD dwFlags)
{
return ddrawEnumDisplaySettingsEx(CALL_ORIG_FUNC(EnumDisplaySettingsExW), &enumDisplaySettingsExW,
lpszDeviceName, iModeNum, lpDevMode, dwFlags);
}
BOOL WINAPI dwm8And16BitIsShimAppliedCallOut()
{
return FALSE;
@ -304,17 +227,12 @@ namespace Win32
return ddQueryDisplaySettingsUniqueness();
}
void setDDrawBpp(DWORD bpp)
{
g_ddrawBpp = bpp;
}
void disableDwm8And16BitMitigation()
{
HOOK_FUNCTION(apphelp, DWM8And16Bit_IsShimApplied_CallOut, dwm8And16BitIsShimAppliedCallOut);
}
void installHooks(HMODULE origDDrawModule)
void installHooks()
{
DEVMODEA devMode = {};
devMode.dmSize = sizeof(devMode);
@ -334,23 +252,6 @@ namespace Win32
HOOK_FUNCTION(user32, EnumDisplaySettingsExA, enumDisplaySettingsExA);
HOOK_FUNCTION(user32, EnumDisplaySettingsExW, enumDisplaySettingsExW);
HOOK_FUNCTION(gdi32, GetDeviceCaps, getDeviceCaps);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "ChangeDisplaySettingsA",
&ddrawChangeDisplaySettingsA);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "ChangeDisplaySettingsW",
&ddrawChangeDisplaySettingsW);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "ChangeDisplaySettingsExA",
&ddrawChangeDisplaySettingsExA);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "ChangeDisplaySettingsExW",
&ddrawChangeDisplaySettingsExW);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsA",
&ddrawEnumDisplaySettingsA);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsW",
&ddrawEnumDisplaySettingsW);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsExA",
&ddrawEnumDisplaySettingsExA);
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsExW",
&ddrawEnumDisplaySettingsExW);
}
}
}

View File

@ -10,9 +10,8 @@ namespace Win32
{
DWORD getBpp();
ULONG queryDisplaySettingsUniqueness();
void setDDrawBpp(DWORD bpp);
void disableDwm8And16BitMitigation();
void installHooks(HMODULE origDDrawModule);
void installHooks();
}
}