#include #include #include #include #include #include #include #include #include #include namespace { template void hookVtable(const CompatPtr& intf); void hookDirectDraw(CompatPtr dd) { hookVtable(dd); hookVtable(dd); hookVtable(dd); hookVtable(dd); } void hookDirectDrawClipper(CompatRef dd) { CompatPtr clipper; HRESULT result = dd->CreateClipper(&dd, 0, &clipper.getRef(), nullptr); if (SUCCEEDED(result)) { DDraw::DirectDrawClipper::hookVtable(clipper.get()->lpVtbl); } else { Compat::Log() << "ERROR: Failed to create a DirectDraw clipper for hooking: " << result; } } void hookDirectDrawPalette(CompatRef dd) { PALETTEENTRY paletteEntries[2] = {}; CompatPtr palette; HRESULT result = dd->CreatePalette(&dd, DDPCAPS_1BIT, paletteEntries, &palette.getRef(), nullptr); if (SUCCEEDED(result)) { DDraw::DirectDrawPalette::hookVtable(palette.get()->lpVtbl); } else { Compat::Log() << "ERROR: Failed to create a DirectDraw palette for hooking: " << result; } } void hookDirectDrawSurface(CompatRef dd) { DDSURFACEDESC2 desc = {}; desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; desc.dwWidth = 1; desc.dwHeight = 1; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; CompatPtr surface; HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); if (SUCCEEDED(result)) { DDraw::DirectDrawSurface::s_origVtable = *surface.get()->lpVtbl; hookVtable(surface); hookVtable(surface); hookVtable(surface); hookVtable(surface); hookVtable(surface); hookVtable(surface); } else { Compat::Log() << "ERROR: Failed to create a DirectDraw surface for hooking: " << result; } } template void hookVtable(const CompatPtr& intf) { if (intf) { CompatVtable>::hookVtable(intf.get()->lpVtbl); } } } namespace DDraw { void installHooks(CompatPtr dd7) { RealPrimarySurface::init(); Win32::Registry::unsetValue( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\DirectDraw", "EmulationOnly"); Win32::Registry::unsetValue( HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Microsoft\\DirectDraw", "EmulationOnly"); hookDirectDraw(dd7); hookDirectDrawClipper(*dd7); hookDirectDrawPalette(*dd7); hookDirectDrawSurface(*dd7); } }