diff --git a/DDrawCompat/DDraw/PaletteConverter.cpp b/DDrawCompat/DDraw/PaletteConverter.cpp deleted file mode 100644 index 0ecc5e4..0000000 --- a/DDrawCompat/DDraw/PaletteConverter.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#include "Common/CompatPtr.h" -#include "Common/Hook.h" -#include "Common/ScopedCriticalSection.h" -#include "DDraw/DisplayMode.h" -#include "DDraw/PaletteConverter.h" -#include "DDraw/RealPrimarySurface.h" -#include "DDraw/Repository.h" -#include "DDraw/Surfaces/PrimarySurface.h" -#include "DDraw/Types.h" - -namespace -{ - HDC g_dc = nullptr; - HGDIOBJ g_oldBitmap = nullptr; - CompatWeakPtr g_surface; - - void convertPaletteEntriesToRgbQuad(RGBQUAD* entries, DWORD count) - { - for (DWORD i = 0; i < count; ++i) - { - entries[i].rgbReserved = 0; - std::swap(entries[i].rgbRed, entries[i].rgbBlue); - } - } - - HBITMAP createDibSection(const DDSURFACEDESC2& dm, void*& bits) - { - struct PalettizedBitmapInfo - { - BITMAPINFOHEADER header; - PALETTEENTRY colors[256]; - }; - - PalettizedBitmapInfo bmi = {}; - bmi.header.biSize = sizeof(bmi.header); - bmi.header.biWidth = dm.dwWidth; - bmi.header.biHeight = -static_cast(dm.dwHeight); - bmi.header.biPlanes = 1; - bmi.header.biBitCount = static_cast(dm.ddpfPixelFormat.dwRGBBitCount); - bmi.header.biCompression = BI_RGB; - - return CreateDIBSection(nullptr, reinterpret_cast(&bmi), - DIB_RGB_COLORS, &bits, nullptr, 0); - } - - CompatPtr createSurface(const DDSURFACEDESC2& dm, void* bits) - { - DDSURFACEDESC2 desc = {}; - desc.dwSize = sizeof(desc); - desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | - DDSD_PITCH | DDSD_LPSURFACE; - desc.dwWidth = dm.dwWidth; - desc.dwHeight = dm.dwHeight; - desc.ddpfPixelFormat = dm.ddpfPixelFormat; - desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - desc.lPitch = (dm.dwWidth * dm.ddpfPixelFormat.dwRGBBitCount / 8 + 3) & ~3; - desc.lpSurface = bits; - - auto dd(DDraw::Repository::getDirectDraw()); - CompatPtr surface; - dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr); - return surface; - } -} - -namespace DDraw -{ - namespace PaletteConverter - { - bool create() - { - auto dd(Repository::getDirectDraw()); - auto dm(DisplayMode::getDisplayMode(*dd)); - DDSURFACEDESC2 realDm = {}; - realDm.dwSize = sizeof(realDm); - dd->GetDisplayMode(dd, &realDm); - if (dm.ddpfPixelFormat.dwRGBBitCount > 8 && - realDm.ddpfPixelFormat.dwRGBBitCount > 8) - { - return true; - } - - void* bits = nullptr; - HBITMAP dib = createDibSection(dm, bits); - if (!dib) - { - Compat::Log() << "Failed to create the palette converter DIB section"; - return false; - } - - CompatPtr surface(createSurface(dm, bits)); - if (!surface) - { - Compat::Log() << "Failed to create the palette converter surface"; - DeleteObject(dib); - return false; - } - - HDC dc = CALL_ORIG_FUNC(CreateCompatibleDC)(nullptr); - if (!dc) - { - Compat::Log() << "Failed to create the palette converter DC"; - DeleteObject(dib); - return false; - } - - g_oldBitmap = SelectObject(dc, dib); - g_dc = dc; - g_surface = surface.detach(); - return true; - } - - HDC getDc() - { - return g_dc; - } - - CompatWeakPtr getSurface() - { - return g_surface; - } - - void release() - { - if (!g_surface) - { - return; - } - - g_surface.release(); - - DeleteObject(SelectObject(g_dc, g_oldBitmap)); - DeleteDC(g_dc); - g_dc = nullptr; - } - - void setClipper(CompatWeakPtr clipper) - { - if (g_surface) - { - HRESULT result = g_surface->SetClipper(g_surface, clipper); - if (FAILED(result)) - { - LOG_ONCE("Failed to set a clipper on the palette converter surface: " << result); - } - } - } - - void updatePalette(DWORD startingEntry, DWORD count) - { - if (g_dc && PrimarySurface::s_palette) - { - RGBQUAD entries[256] = {}; - std::memcpy(entries, &PrimarySurface::s_paletteEntries[startingEntry], - count * sizeof(PALETTEENTRY)); - convertPaletteEntriesToRgbQuad(entries, count); - SetDIBColorTable(g_dc, startingEntry, count, entries); - } - } - }; -} diff --git a/DDrawCompat/DDraw/PaletteConverter.h b/DDrawCompat/DDraw/PaletteConverter.h deleted file mode 100644 index 999c55b..0000000 --- a/DDrawCompat/DDraw/PaletteConverter.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#define CINTERFACE - -#include - -#include "Common/CompatWeakPtr.h" - -namespace DDraw -{ - namespace PaletteConverter - { - bool create(); - HDC getDc(); - CompatWeakPtr getSurface(); - void release(); - void setClipper(CompatWeakPtr clipper); - void updatePalette(DWORD startingEntry, DWORD count); - } -} diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index f699743..ee8d310 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -5,8 +5,8 @@ #include "Common/Time.h" #include "Config/Config.h" #include "DDraw/DirectDrawSurface.h" +#include "DDraw/DisplayMode.h" #include "DDraw/IReleaseNotifier.h" -#include "DDraw/PaletteConverter.h" #include "DDraw/RealPrimarySurface.h" #include "DDraw/ScopedThreadLock.h" #include "DDraw/Surfaces/PrimarySurface.h" @@ -21,6 +21,7 @@ namespace CompatWeakPtr g_frontBuffer; CompatWeakPtr g_backBuffer; + CompatWeakPtr g_paletteConverter; CompatWeakPtr g_clipper; DDSURFACEDESC2 g_surfaceDesc = {}; DDraw::IReleaseNotifier g_releaseNotifier(onRelease); @@ -49,22 +50,26 @@ namespace auto primary(DDraw::PrimarySurface::getPrimary()); if (DDraw::PrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8) { - auto paletteConverter(DDraw::PaletteConverter::getSurface()); - paletteConverter->Blt(paletteConverter, &g_updateRect, - primary, &g_updateRect, DDBLT_WAIT, nullptr); + HDC paletteConverterDc = nullptr; + g_paletteConverter->GetDC(g_paletteConverter, &paletteConverterDc); + HDC primaryDc = nullptr; + primary->GetDC(primary, &primaryDc); - HDC destDc = nullptr; - dest->GetDC(&dest, &destDc); - result = TRUE == CALL_ORIG_FUNC(BitBlt)(destDc, g_updateRect.left, g_updateRect.top, - g_updateRect.right - g_updateRect.left, g_updateRect.bottom - g_updateRect.top, - DDraw::PaletteConverter::getDc(), g_updateRect.left, g_updateRect.top, SRCCOPY); - dest->ReleaseDC(&dest, destDc); - - if (&dest == g_frontBuffer) + if (paletteConverterDc && primaryDc) { - // Force the screen to be updated. It won't refresh from BitBlt alone. - RECT r = { 0, 0, 1, 1 }; - g_frontBuffer->BltFast(g_frontBuffer, 0, 0, g_frontBuffer, &r, DDBLTFAST_WAIT); + result = TRUE == CALL_ORIG_FUNC(BitBlt)(paletteConverterDc, + g_updateRect.left, g_updateRect.top, + g_updateRect.right - g_updateRect.left, g_updateRect.bottom - g_updateRect.top, + primaryDc, g_updateRect.left, g_updateRect.top, SRCCOPY); + } + + primary->ReleaseDC(primary, primaryDc); + g_paletteConverter->ReleaseDC(g_paletteConverter, paletteConverterDc); + + if (result) + { + result = SUCCEEDED(dest->Blt(&dest, &g_updateRect, + g_paletteConverter, &g_updateRect, DDBLT_WAIT, nullptr)); } } else @@ -78,7 +83,40 @@ namespace SetRectEmpty(&g_updateRect); } - Compat::LogLeave("RealPrimarySurface::compatBlt", dest); + Compat::LogLeave("RealPrimarySurface::compatBlt", dest) << result; + return result; + } + + template + HRESULT createPaletteConverter(CompatRef dd) + { + auto dd7(CompatPtr::from(&dd)); + auto dm = DDraw::DisplayMode::getDisplayMode(*dd7); + if (dm.ddpfPixelFormat.dwRGBBitCount > 8) + { + return DD_OK; + } + + typename DDraw::Types::TSurfaceDesc desc = {}; + desc.dwSize = sizeof(desc); + desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS; + desc.dwWidth = dm.dwWidth; + desc.dwHeight = dm.dwHeight; + desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); + desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + desc.ddpfPixelFormat.dwRGBBitCount = 32; + desc.ddpfPixelFormat.dwRBitMask = 0x00FF0000; + desc.ddpfPixelFormat.dwGBitMask = 0x0000FF00; + desc.ddpfPixelFormat.dwBBitMask = 0x000000FF; + desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + + CompatPtr::TCreatedSurface> paletteConverter; + HRESULT result = dd->CreateSurface(&dd, &desc, &paletteConverter.getRef(), nullptr); + if (SUCCEEDED(result)) + { + g_paletteConverter = Compat::queryInterface(paletteConverter.get()); + } + return result; } @@ -91,11 +129,6 @@ namespace HRESULT init(CompatPtr surface) { - if (!DDraw::PaletteConverter::create()) - { - return DDERR_GENERIC; - } - DDSURFACEDESC2 desc = {}; desc.dwSize = sizeof(desc); surface->GetSurfaceDesc(surface, &desc); @@ -152,7 +185,7 @@ namespace g_backBuffer = nullptr; g_clipper = nullptr; g_isFullScreen = false; - DDraw::PaletteConverter::release(); + g_paletteConverter.release(); ZeroMemory(&g_surfaceDesc, sizeof(g_surfaceDesc)); @@ -209,6 +242,13 @@ namespace DDraw template HRESULT RealPrimarySurface::create(CompatRef dd) { + HRESULT result = createPaletteConverter(dd); + if (FAILED(result)) + { + Compat::Log() << "Failed to create the palette converter surface: " << Compat::hex(result); + return result; + } + typename Types::TSurfaceDesc desc = {}; desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; @@ -216,7 +256,7 @@ namespace DDraw desc.dwBackBufferCount = 1; CompatPtr::TCreatedSurface> surface; - HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); + result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); bool isFlippable = true; if (DDERR_NOEXCLUSIVEMODE == result) @@ -230,7 +270,8 @@ namespace DDraw if (FAILED(result)) { - Compat::Log() << "Failed to create the real primary surface"; + Compat::Log() << "Failed to create the real primary surface: " << Compat::hex(result); + g_paletteConverter.release(); return result; } @@ -343,7 +384,6 @@ namespace DDraw LOG_ONCE("Failed to set clipper on the real primary surface: " << result); return; } - PaletteConverter::setClipper(clipper); g_clipper = clipper; } @@ -375,7 +415,6 @@ namespace DDraw void RealPrimarySurface::updatePalette(DWORD startingEntry, DWORD count) { - PaletteConverter::updatePalette(startingEntry, count); Gdi::updatePalette(startingEntry, count); if (PrimarySurface::s_palette) { diff --git a/DDrawCompat/DDraw/Surfaces/Surface.cpp b/DDrawCompat/DDraw/Surfaces/Surface.cpp index ee688f8..fe9f38e 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.cpp +++ b/DDrawCompat/DDraw/Surfaces/Surface.cpp @@ -26,10 +26,15 @@ namespace pf = dm.ddpfPixelFormat; } + if ((pf.dwFlags & DDPF_RGB) && pf.dwRGBBitCount <= 8) + { + caps &= ~(DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM); + caps |= DDSCAPS_SYSTEMMEMORY; + } + if (!(caps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_OVERLAY | DDSCAPS_TEXTURE | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER))) { - flags |= DDSD_CAPS; caps |= DDSCAPS_OFFSCREENPLAIN; } } diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index d990e1f..8eedd19 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -184,7 +184,6 @@ - @@ -247,7 +246,6 @@ - diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 2173d79..1f21a04 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -123,9 +123,6 @@ Header Files\DDraw - - Header Files\DDraw - Header Files\DDraw @@ -344,9 +341,6 @@ Source Files\DDraw - - Source Files\DDraw - Source Files\DDraw diff --git a/DDrawCompat/Gdi/Gdi.cpp b/DDrawCompat/Gdi/Gdi.cpp index 3546dd5..750e771 100644 --- a/DDrawCompat/Gdi/Gdi.cpp +++ b/DDrawCompat/Gdi/Gdi.cpp @@ -1,7 +1,6 @@ #include #include "Common/ScopedCriticalSection.h" -#include "DDraw/PaletteConverter.h" #include "DDraw/RealPrimarySurface.h" #include "DDraw/Surfaces/PrimarySurface.h" #include "Dll/Procs.h"