mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Handle resolution scaling in windowed mode
This commit is contained in:
parent
96ad1d6ab6
commit
fc16184256
@ -1038,19 +1038,22 @@ namespace D3dDdi
|
||||
{
|
||||
if (srcResource->m_lockResource)
|
||||
{
|
||||
if (srcResource->m_lockData[0].isSysMemUpToDate &&
|
||||
if (srcResource->m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate &&
|
||||
!srcResource->m_fixedData.Flags.RenderTarget)
|
||||
{
|
||||
srcResource->m_lockData[0].isVidMemUpToDate = false;
|
||||
srcResource->m_lockData[data.SrcSubResourceIndex].isVidMemUpToDate = false;
|
||||
}
|
||||
|
||||
srcResource = &srcResource->prepareForGpuRead(0);
|
||||
srcResource = &srcResource->prepareForGpuRead(data.SrcSubResourceIndex);
|
||||
}
|
||||
|
||||
LONG srcWidth = srcResource->m_fixedData.pSurfList[0].Width;
|
||||
LONG srcHeight = srcResource->m_fixedData.pSurfList[0].Height;
|
||||
LONG srcWidth = srcResource->m_fixedData.pSurfList[data.SrcSubResourceIndex].Width;
|
||||
LONG srcHeight = srcResource->m_fixedData.pSurfList[data.SrcSubResourceIndex].Height;
|
||||
data.SrcRect = { 0, 0, srcWidth, srcHeight };
|
||||
data.DstRect = g_presentationRect;
|
||||
if (!IsRectEmpty(&g_presentationRect))
|
||||
{
|
||||
data.DstRect = g_presentationRect;
|
||||
}
|
||||
|
||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
||||
const auto& rtSurface = repo.getTempRenderTarget(srcWidth, srcHeight);
|
||||
@ -1078,14 +1081,18 @@ namespace D3dDdi
|
||||
pal[i].rgbGreen = entries[i].peGreen;
|
||||
pal[i].rgbBlue = entries[i].peBlue;
|
||||
}
|
||||
m_device.getShaderBlitter().palettizedBlt(*rt, rtIndex, rtRect, *srcResource, data.SrcRect, pal);
|
||||
m_device.getShaderBlitter().palettizedBlt(
|
||||
*rt, rtIndex, rtRect, *srcResource, data.SrcSubResourceIndex, data.SrcRect, pal);
|
||||
}
|
||||
else
|
||||
{
|
||||
copySubResourceRegion(*rt, rtIndex, rtRect, *srcResource, 0, data.SrcRect);
|
||||
copySubResourceRegion(*rt, rtIndex, rtRect, *srcResource, data.SrcSubResourceIndex, data.SrcRect);
|
||||
}
|
||||
|
||||
presentLayeredWindows(*rt, rtIndex, rtRect);
|
||||
if (!IsRectEmpty(&g_presentationRect))
|
||||
{
|
||||
presentLayeredWindows(*rt, rtIndex, rtRect);
|
||||
}
|
||||
|
||||
const auto cursorInfo = Gdi::Cursor::getEmulatedCursorInfo();
|
||||
const bool isCursorEmulated = cursorInfo.flags == CURSOR_SHOWING && cursorInfo.hCursor;
|
||||
|
@ -45,6 +45,7 @@ namespace D3dDdi
|
||||
void prepareForCpuWrite(UINT subResourceIndex);
|
||||
Resource& prepareForGpuRead(UINT subResourceIndex);
|
||||
void prepareForGpuWrite(UINT subResourceIndex);
|
||||
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
|
||||
void scaleRect(RECT& rect);
|
||||
void setAsGdiResource(bool isGdiResource);
|
||||
void setAsPrimary();
|
||||
@ -106,7 +107,6 @@ namespace D3dDdi
|
||||
void loadSysMemResource(UINT subResourceIndex);
|
||||
void loadVidMemResource(UINT subResourceIndex);
|
||||
void notifyLock(UINT subResourceIndex);
|
||||
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
|
||||
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect);
|
||||
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource);
|
||||
|
||||
|
@ -317,10 +317,11 @@ namespace D3dDdi
|
||||
}
|
||||
|
||||
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, RGBQUAD palette[256])
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, RGBQUAD palette[256])
|
||||
{
|
||||
LOG_FUNC("ShaderBlitter::palettizedBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||
static_cast<HANDLE>(srcResource), srcRect, Compat::array(reinterpret_cast<void**>(palette), 256));
|
||||
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect,
|
||||
Compat::array(reinterpret_cast<void**>(palette), 256));
|
||||
|
||||
auto paletteTexture(SurfaceRepository::get(m_device.getAdapter()).getPaletteTexture());
|
||||
if (!paletteTexture)
|
||||
@ -344,7 +345,8 @@ namespace D3dDdi
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
|
||||
setTempTextureStage(1, *paletteTexture, srcRect, D3DTEXF_POINT);
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psPaletteLookup.get(), D3DTEXF_POINT);
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||
m_psPaletteLookup.get(), D3DTEXF_POINT);
|
||||
}
|
||||
|
||||
void ShaderBlitter::resetGammaRamp()
|
||||
|
@ -34,7 +34,7 @@ namespace D3dDdi
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||
const Resource& lockRefResource);
|
||||
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, RGBQUAD palette[256]);
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, RGBQUAD palette[256]);
|
||||
void textureBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||
UINT filter, const UINT* srcColorKey = nullptr, const BYTE* alpha = nullptr,
|
||||
|
@ -9,12 +9,16 @@
|
||||
#include <Config/Config.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <D3dDdi/SurfaceRepository.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
#include <DDraw/IReleaseNotifier.h>
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
#include <DDraw/ScopedThreadLock.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <DDraw/Surfaces/TagSurface.h>
|
||||
#include <DDraw/Types.h>
|
||||
#include <Gdi/Caret.h>
|
||||
#include <Gdi/Cursor.h>
|
||||
@ -34,6 +38,7 @@ namespace
|
||||
void onRelease();
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_windowedBackBuffer;
|
||||
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
||||
RECT g_monitorRect = {};
|
||||
DDSURFACEDESC2 g_surfaceDesc = {};
|
||||
@ -65,7 +70,24 @@ namespace
|
||||
{
|
||||
if (!g_isFullscreen)
|
||||
{
|
||||
Gdi::Window::present(*g_frontBuffer, src, *g_clipper);
|
||||
{
|
||||
D3dDdi::ScopedCriticalSection lock;
|
||||
auto srcResource = D3dDdi::Device::findResource(
|
||||
DDraw::DirectDrawSurface::getDriverResourceHandle(src.get()));
|
||||
auto bbResource = D3dDdi::Device::findResource(
|
||||
DDraw::DirectDrawSurface::getDriverResourceHandle(*g_windowedBackBuffer));
|
||||
|
||||
D3DDDIARG_BLT blt = {};
|
||||
blt.hSrcResource = *srcResource;
|
||||
blt.SrcSubResourceIndex = DDraw::DirectDrawSurface::getSubResourceIndex(src.get());
|
||||
blt.SrcRect = DDraw::PrimarySurface::getMonitorRect();
|
||||
blt.hDstResource = *bbResource;
|
||||
blt.DstSubResourceIndex = 0;
|
||||
blt.DstRect = g_monitorRect;
|
||||
bbResource->presentationBlt(blt, srcResource);
|
||||
}
|
||||
|
||||
Gdi::Window::present(*g_frontBuffer, *g_windowedBackBuffer, *g_clipper);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -76,6 +98,48 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createWindowedBackBuffer(DDRAWI_DIRECTDRAW_LCL* ddLcl, DWORD width, DWORD height)
|
||||
{
|
||||
if (!ddLcl)
|
||||
{
|
||||
LOG_INFO << "ERROR: createWindowedBackBuffer: ddLcl is null";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto tagSurface = DDraw::TagSurface::get(ddLcl);
|
||||
if (!tagSurface)
|
||||
{
|
||||
LOG_INFO << "ERROR: createWindowedBackBuffer: TagSurface not found";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto resource = DDraw::DirectDrawSurface::getDriverResourceHandle(*tagSurface->getDDS());
|
||||
if (!resource)
|
||||
{
|
||||
LOG_INFO << "ERROR: createWindowedBackBuffer: driver resource handle not found";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto device = D3dDdi::Device::findDeviceByResource(resource);
|
||||
if (!device)
|
||||
{
|
||||
LOG_INFO << "ERROR: createWindowedBackBuffer: device not found";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& repo = D3dDdi::SurfaceRepository::get(device->getAdapter());
|
||||
D3dDdi::SurfaceRepository::Surface surface = {};
|
||||
repo.getSurface(surface, width, height, DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
||||
if (!surface.surface)
|
||||
{
|
||||
LOG_INFO << "ERROR: createWindowedBackBuffer: surface creation failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return surface.surface;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> getBackBuffer()
|
||||
{
|
||||
DDSCAPS2 caps = {};
|
||||
@ -133,6 +197,7 @@ namespace
|
||||
|
||||
g_frontBuffer = nullptr;
|
||||
g_lastFlipSurface = nullptr;
|
||||
g_windowedBackBuffer.release();
|
||||
g_clipper.release();
|
||||
g_isFullscreen = false;
|
||||
g_surfaceDesc = {};
|
||||
@ -164,6 +229,11 @@ namespace
|
||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(D3dDdi::KernelModeThunks::getVsyncCounter() + 1);
|
||||
}
|
||||
|
||||
if (g_windowedBackBuffer)
|
||||
{
|
||||
g_windowedBackBuffer->Restore(g_windowedBackBuffer);
|
||||
}
|
||||
|
||||
Compat::ScopedCriticalSection lock(g_presentCs);
|
||||
g_isUpdatePending = false;
|
||||
g_isUpdateReady = false;
|
||||
@ -204,11 +274,7 @@ namespace
|
||||
|
||||
Gdi::Region excludeRegion(DDraw::PrimarySurface::getMonitorRect());
|
||||
Gdi::Window::present(excludeRegion);
|
||||
|
||||
auto palette(Gdi::Palette::getHardwarePalette());
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(palette.data());
|
||||
bltToPrimaryChain(*src);
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(nullptr);
|
||||
}
|
||||
|
||||
void updateNow(CompatWeakPtr<IDirectDrawSurface7> src)
|
||||
@ -282,6 +348,17 @@ namespace DDraw
|
||||
return result;
|
||||
}
|
||||
|
||||
if (0 == desc.dwBackBufferCount)
|
||||
{
|
||||
g_windowedBackBuffer = createWindowedBackBuffer(DDraw::DirectDraw::getInt(dd.get()).lpLcl,
|
||||
g_monitorRect.right - g_monitorRect.left, g_monitorRect.bottom - g_monitorRect.top).detach();
|
||||
if (!g_windowedBackBuffer)
|
||||
{
|
||||
g_monitorRect = {};
|
||||
return DDERR_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
g_frontBuffer = CompatPtr<IDirectDrawSurface7>::from(surface.get()).detach();
|
||||
g_frontBuffer->SetPrivateData(g_frontBuffer, IID_IReleaseNotifier,
|
||||
&g_releaseNotifier, sizeof(&g_releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
|
@ -67,14 +67,24 @@ namespace DDraw
|
||||
}
|
||||
}
|
||||
|
||||
TagSurface* TagSurface::get(CompatRef<IDirectDraw> dd)
|
||||
TagSurface* TagSurface::get(DDRAWI_DIRECTDRAW_LCL* ddLcl)
|
||||
{
|
||||
auto ddLcl = DDraw::DirectDraw::getInt(dd.get()).lpLcl;
|
||||
auto it = g_ddObjects.find(ddLcl);
|
||||
if (it != g_ddObjects.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TagSurface* TagSurface::get(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
auto ddLcl = DDraw::DirectDraw::getInt(dd.get()).lpLcl;
|
||||
auto tagSurface = get(ddLcl);
|
||||
if (tagSurface)
|
||||
{
|
||||
return tagSurface;
|
||||
}
|
||||
|
||||
if (FAILED(create(dd)))
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ namespace DDraw
|
||||
TagSurface(DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl);
|
||||
virtual ~TagSurface() override;
|
||||
|
||||
static TagSurface* get(DDRAWI_DIRECTDRAW_LCL* ddLcl);
|
||||
static TagSurface* get(CompatRef<IDirectDraw> dd);
|
||||
static TagSurface* findFullscreenWindow(HWND hwnd);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user