mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
67 lines
1.6 KiB
C++
67 lines
1.6 KiB
C++
#include <cstring>
|
|
#include <deque>
|
|
|
|
#include <Common/CompatVtable.h>
|
|
#include <Common/Time.h>
|
|
#include <DDraw/DirectDrawPalette.h>
|
|
#include <DDraw/ScopedThreadLock.h>
|
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
|
#include <DDraw/Visitors/DirectDrawPaletteVtblVisitor.h>
|
|
|
|
namespace
|
|
{
|
|
HRESULT STDMETHODCALLTYPE SetEntries(
|
|
IDirectDrawPalette* This, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
|
|
{
|
|
if (This == DDraw::PrimarySurface::s_palette)
|
|
{
|
|
DDraw::DirectDrawPalette::waitForNextUpdate();
|
|
}
|
|
|
|
HRESULT result = getOrigVtable(This).SetEntries(
|
|
This, dwFlags, dwStartingEntry, dwCount, lpEntries);
|
|
if (SUCCEEDED(result) && This == DDraw::PrimarySurface::s_palette)
|
|
{
|
|
DDraw::PrimarySurface::updatePalette();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
constexpr void setCompatVtable(IDirectDrawPaletteVtbl& vtable)
|
|
{
|
|
vtable.SetEntries = &SetEntries;
|
|
}
|
|
}
|
|
|
|
namespace DDraw
|
|
{
|
|
namespace DirectDrawPalette
|
|
{
|
|
void waitForNextUpdate()
|
|
{
|
|
static std::deque<long long> updatesInLastMs;
|
|
|
|
const long long qpcNow = Time::queryPerformanceCounter();
|
|
const long long qpcLastMsBegin = qpcNow - Time::g_qpcFrequency / 1000;
|
|
while (!updatesInLastMs.empty() && qpcLastMsBegin - updatesInLastMs.front() > 0)
|
|
{
|
|
updatesInLastMs.pop_front();
|
|
}
|
|
|
|
const unsigned maxPaletteUpdatesPerMs = 5;
|
|
if (updatesInLastMs.size() >= maxPaletteUpdatesPerMs)
|
|
{
|
|
Sleep(1);
|
|
updatesInLastMs.clear();
|
|
}
|
|
|
|
updatesInLastMs.push_back(Time::queryPerformanceCounter());
|
|
}
|
|
|
|
void hookVtable(const IDirectDrawPaletteVtbl& vtable)
|
|
{
|
|
CompatVtable<IDirectDrawPaletteVtbl>::hookVtable<ScopedThreadLock>(vtable);
|
|
}
|
|
}
|
|
}
|