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

Added DesktopResolution setting

This commit is contained in:
narzoul 2023-01-07 23:14:38 +01:00
parent defdfafe20
commit 0b7f4589f2
13 changed files with 135 additions and 24 deletions

View File

@ -8,6 +8,7 @@
#include <Config/Settings/CpuAffinityRotation.h>
#include <Config/Settings/DepthFormat.h>
#include <Config/Settings/DesktopColorDepth.h>
#include <Config/Settings/DesktopResolution.h>
#include <Config/Settings/DisplayAspectRatio.h>
#include <Config/Settings/DisplayFilter.h>
#include <Config/Settings/DisplayRefreshRate.h>
@ -51,6 +52,7 @@ namespace Config
Settings::DepthFormat depthFormat;
Settings::DisplayAspectRatio displayAspectRatio;
Settings::DesktopColorDepth desktopColorDepth;
Settings::DesktopResolution desktopResolution;
Settings::DisplayFilter displayFilter;
Settings::DisplayRefreshRate displayRefreshRate;
Settings::DisplayResolution displayResolution;

View File

@ -0,0 +1,38 @@
#include <Config/Settings/DesktopResolution.h>
namespace Config
{
namespace Settings
{
DesktopResolution::DesktopResolution()
: MappedSetting("DesktopResolution", "desktop", { {"desktop", DESKTOP} })
{
}
std::string DesktopResolution::getValueStr() const
{
try
{
return MappedSetting::getValueStr();
}
catch (const ParsingError&)
{
return std::to_string(m_value.cx) + 'x' + std::to_string(m_value.cy);
}
}
void DesktopResolution::setValue(const std::string& value)
{
try
{
MappedSetting::setValue(value);
}
catch (const ParsingError&)
{
m_value = Parser::parseResolution(value);
}
}
const SIZE DesktopResolution::DESKTOP = { 0, 0 };
}
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <Windows.h>
#include <Common/Comparison.h>
#include <Config/MappedSetting.h>
namespace Config
{
namespace Settings
{
class DesktopResolution : public MappedSetting<SIZE>
{
public:
static const SIZE DESKTOP;
DesktopResolution();
protected:
std::string getValueStr() const override;
void setValue(const std::string& value) override;
};
}
extern Settings::DesktopResolution desktopResolution;
}

View File

@ -16,6 +16,7 @@
#include <D3dDdi/DeviceFuncs.h>
#include <D3dDdi/FormatInfo.h>
#include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/SurfaceRepository.h>
#include <Win32/DisplayMode.h>
namespace
@ -422,6 +423,7 @@ namespace D3dDdi
if (adapter.second.m_luid == luid)
{
adapter.second.m_repository = repository;
SurfaceRepository::get(adapter.second).setRepository(repository);
}
}
}

View File

@ -22,9 +22,8 @@ namespace
namespace D3dDdi
{
SurfaceRepository::SurfaceRepository(const Adapter& adapter)
: m_adapter(adapter)
, m_cursor(nullptr)
SurfaceRepository::SurfaceRepository()
: m_cursor(nullptr)
, m_cursorSize{}
, m_cursorHotspot{}
{
@ -33,8 +32,7 @@ namespace D3dDdi
CompatPtr<IDirectDrawSurface7> SurfaceRepository::createSurface(
DWORD width, DWORD height, D3DDDIFORMAT format, DWORD caps, UINT surfaceCount)
{
auto dd(m_adapter.getRepository());
if (!dd)
if (!m_dd)
{
LOG_ONCE("ERROR: no DirectDraw repository available");
return nullptr;
@ -65,7 +63,7 @@ namespace D3dDdi
DDraw::SuppressResourceFormatLogs suppressResourceFormatLogs;
s_inCreateSurface = true;
HRESULT result = dd.get()->lpVtbl->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
HRESULT result = m_dd.get()->lpVtbl->CreateSurface(m_dd, &desc, &surface.getRef(), nullptr);
s_inCreateSurface = false;
D3dDdi::Resource::setFormatOverride(D3DDDIFMT_UNKNOWN);
if (FAILED(result))
@ -83,12 +81,7 @@ namespace D3dDdi
SurfaceRepository& SurfaceRepository::get(const Adapter& adapter)
{
auto it = g_repositories.find(adapter.getLuid());
if (it != g_repositories.end())
{
return it->second;
}
return g_repositories.emplace(adapter.getLuid(), SurfaceRepository(adapter)).first->second;
return g_repositories[adapter.getLuid()];
}
SurfaceRepository::Cursor SurfaceRepository::getCursor(HCURSOR cursor)

View File

@ -35,6 +35,8 @@ namespace D3dDdi
D3DDDIFORMAT format = D3DDDIFMT_UNKNOWN;
};
SurfaceRepository();
Cursor getCursor(HCURSOR cursor);
Resource* getLogicalXorTexture();
Resource* getPaletteTexture();
@ -47,14 +49,13 @@ namespace D3dDdi
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1);
const Surface& getTempTexture(DWORD width, DWORD height, D3DDDIFORMAT format);
void release(Surface& surface);
void setRepository(CompatWeakPtr<IDirectDraw7> dd) { m_dd = dd; }
static SurfaceRepository& get(const Adapter& adapter);
static bool inCreateSurface() { return s_inCreateSurface; }
static void enableSurfaceCheck(bool enable);
private:
SurfaceRepository(const Adapter& adapter);
CompatPtr<IDirectDrawSurface7> createSurface(DWORD width, DWORD height,
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount);
bool getCursorImage(Surface& surface, HCURSOR cursor, DWORD width, DWORD height, UINT flags);
@ -63,7 +64,7 @@ namespace D3dDdi
bool hasAlpha(CompatRef<IDirectDrawSurface7> surface);
bool isLost(Surface& surface);
const Adapter& m_adapter;
CompatWeakPtr<IDirectDraw7> m_dd;
HCURSOR m_cursor;
SIZE m_cursorSize;
POINT m_cursorHotspot;

View File

@ -142,6 +142,7 @@ namespace
{
return FALSE;
}
DDraw::DirectDraw::onCreate(lpGUID, *dd);
if (FAILED(dd.get()->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL)))
{
@ -160,7 +161,8 @@ namespace
void createDefaultPrimary()
{
if (g_defaultPrimary ? SUCCEEDED(g_defaultPrimary->IsLost(g_defaultPrimary)) : g_frontBuffer)
if (!Dll::g_isHooked ||
(g_defaultPrimary ? SUCCEEDED(g_defaultPrimary->IsLost(g_defaultPrimary)) : g_frontBuffer))
{
return;
}

View File

@ -170,6 +170,7 @@
<ClInclude Include="Config\Settings\CpuAffinityRotation.h" />
<ClInclude Include="Config\Settings\DepthFormat.h" />
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
<ClInclude Include="Config\Settings\DesktopResolution.h" />
<ClInclude Include="Config\Settings\DisplayAspectRatio.h" />
<ClInclude Include="Config\Settings\DisplayFilter.h" />
<ClInclude Include="Config\Settings\DisplayRefreshRate.h" />
@ -332,6 +333,7 @@
<ClCompile Include="Config\Setting.cpp" />
<ClCompile Include="Config\Settings\Antialiasing.cpp" />
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
<ClCompile Include="Config\Settings\DesktopResolution.cpp" />
<ClCompile Include="Config\Settings\DisplayAspectRatio.cpp" />
<ClCompile Include="Config\Settings\DisplayFilter.cpp" />
<ClCompile Include="Config\Settings\DisplayRefreshRate.cpp" />

View File

@ -657,6 +657,9 @@
<ClInclude Include="Common\Vector.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
<ClInclude Include="Config\Settings\DesktopResolution.h">
<Filter>Header Files\Config\Settings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -1037,6 +1040,9 @@
<ClCompile Include="Config\Settings\DisplayAspectRatio.cpp">
<Filter>Source Files\Config\Settings</Filter>
</ClCompile>
<ClCompile Include="Config\Settings\DesktopResolution.cpp">
<Filter>Source Files\Config\Settings</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DDrawCompat.rc">

View File

@ -10,6 +10,7 @@ namespace Dll
HMODULE g_origDciman32Module = nullptr;
Procs g_origProcs = {};
Procs g_jmpTargetProcs = {};
bool g_isHooked = false;
HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority, unsigned initFlags)
{

View File

@ -80,6 +80,7 @@ namespace Dll
extern HMODULE g_origDciman32Module;
extern Procs g_origProcs;
extern Procs g_jmpTargetProcs;
extern bool g_isHooked;
}
#undef ADD_FARPROC_MEMBER

View File

@ -10,6 +10,7 @@
#include <Common/Path.h>
#include <Common/Time.h>
#include <Config/Parser.h>
#include <Config/Settings/DesktopResolution.h>
#include <Config/Settings/DpiAwareness.h>
#include <Config/Settings/FullscreenMode.h>
#include <D3dDdi/Hooks.h>
@ -51,7 +52,7 @@ namespace
template <FARPROC(Dll::Procs::* origFunc), typename OrigFuncPtrType, typename FirstParam, typename... Params>
HRESULT WINAPI directDrawFunc(FirstParam firstParam, Params... params)
{
LOG_FUNC(getFuncName<origFunc>(), params...);
LOG_FUNC(getFuncName<origFunc>(), firstParam, params...);
installHooks();
if constexpr (&Dll::Procs::DirectDrawCreate == origFunc || &Dll::Procs::DirectDrawCreateEx == origFunc)
{
@ -70,8 +71,7 @@ namespace
void installHooks()
{
static bool isAlreadyInstalled = false;
if (!isAlreadyInstalled)
if (!Dll::g_isHooked)
{
DDraw::SuppressResourceFormatLogs suppressResourceFormatLogs;
LOG_INFO << "Installing display mode hooks";
@ -121,10 +121,16 @@ namespace
Compat::closeDbgEng();
Gdi::GuiThread::start();
LOG_INFO << "Finished installing hooks";
isAlreadyInstalled = true;
Dll::g_isHooked = true;
}
}
unsigned WINAPI installHooksThreadProc(LPVOID /*lpParameter*/)
{
installHooks();
return 0;
}
bool isOtherDDrawWrapperLoaded()
{
const auto currentDllPath(Compat::getModulePath(Dll::g_currentModule));
@ -308,6 +314,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
CALL_ORIG_PROC(SetAppCompatData)(disableMaxWindowedMode, 0);
}
if (Config::Settings::DesktopResolution::DESKTOP != Config::desktopResolution.get())
{
Dll::createThread(&installHooksThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
}
LOG_INFO << "DDrawCompat loaded successfully";
}
else if (fdwReason == DLL_PROCESS_DETACH)

View File

@ -11,6 +11,7 @@
#include <Common/Hook.h>
#include <Common/ScopedSrwLock.h>
#include <Config/Settings/DesktopColorDepth.h>
#include <Config/Settings/DesktopResolution.h>
#include <Config/Settings/DisplayRefreshRate.h>
#include <Config/Settings/DisplayResolution.h>
#include <Config/Settings/SupportedResolutions.h>
@ -109,6 +110,27 @@ namespace
LONG changeDisplaySettingsEx(const Char* lpszDeviceName, typename DevMode<Char>* lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
{
DDraw::ScopedThreadLock lock;
auto desktopResolution = Config::desktopResolution.get();
if (!lpDevMode && 0 == dwflags && Config::Settings::DesktopResolution::DESKTOP != desktopResolution)
{
auto mi = Win32::DisplayMode::getMonitorInfo(getDeviceName(lpszDeviceName));
if (0 == mi.rcMonitor.left && 0 == mi.rcMonitor.top)
{
DevMode<Char> dm = {};
dm.dmSize = sizeof(dm);
enumDisplaySettingsEx(lpszDeviceName, ENUM_REGISTRY_SETTINGS, &dm, 0);
dm.dmBitsPerPel = g_desktopBpp;
dm.dmPelsWidth = desktopResolution.cx;
dm.dmPelsHeight = desktopResolution.cy;
if (DISP_CHANGE_SUCCESSFUL == changeDisplaySettingsEx(lpszDeviceName, &dm, nullptr, 0, nullptr))
{
return DISP_CHANGE_SUCCESSFUL;
}
}
}
DevMode<Char> targetDevMode = {};
SIZE emulatedResolution = {};
if (lpDevMode)
@ -781,13 +803,12 @@ namespace Win32
void installHooks()
{
DEVMODEA dm = {};
dm.dmSize = sizeof(dm);
EnumDisplaySettingsEx(nullptr, ENUM_CURRENT_SETTINGS, &dm, 0);
g_desktopBpp = Config::desktopColorDepth.get();
if (Config::Settings::DesktopColorDepth::INITIAL == g_desktopBpp)
{
DEVMODEA dm = {};
dm.dmSize = sizeof(dm);
EnumDisplaySettingsEx(nullptr, ENUM_CURRENT_SETTINGS, &dm, 0);
g_desktopBpp = dm.dmBitsPerPel;
}
g_emulatedDisplayMode.bpp = g_desktopBpp;
@ -804,6 +825,11 @@ namespace Win32
HOOK_FUNCTION(user32, GetMonitorInfoW, getMonitorInfoW);
disableDwm8And16BitMitigation();
if (Config::Settings::DesktopResolution::DESKTOP != Config::desktopResolution.get())
{
changeDisplaySettingsExA(nullptr, nullptr, nullptr, 0, nullptr);
}
}
}
}