diff --git a/docs/hud.md b/docs/hud.md index 70534a9..4a0fe3d 100644 --- a/docs/hud.md +++ b/docs/hud.md @@ -52,3 +52,9 @@ sample a position ~400 px off now and then (jerky hold-to-move). Every user of the cursor goes through the accessor `0x6550f0`, so inside a moved window it returns a thread-local copy instead (with its own CRITICAL_SECTION at +0x24; copying and writing back hold the real object's lock). + +## Full-screen layers + +A primitive drawn inside a moved window that covers the whole 1024x768 layout +(e.g. the dimming behind the exit confirmation) is stretched across the render +width instead of shifted. diff --git a/src/mods/hud.cpp b/src/mods/hud.cpp index 4a3b86b..552e084 100644 --- a/src/mods/hud.cpp +++ b/src/mods/hud.cpp @@ -20,6 +20,7 @@ // [hud] // Enabled=1 +#include #include #include #include @@ -324,6 +325,8 @@ size_t VertexSize(DWORD fvf) { } // Returns vertices shifted by g_offsetX, or the input when nothing to do. +// Primitives covering the whole 1024x768 layout (e.g. the dimming behind +// modal dialogs) are stretched across the render width instead. void* ShiftVertices(DWORD fvf, void* vertices, DWORD count) { if (g_offsetX == 0 || (fvf & kFvfPositionMask) != kFvfXyzRhw || !vertices || count == 0) { return vertices; @@ -331,9 +334,19 @@ void* ShiftVertices(DWORD fvf, void* vertices, DWORD count) { thread_local std::vector buffer; const size_t stride = VertexSize(fvf); buffer.assign(static_cast(vertices), static_cast(vertices) + stride * count); + float minX = 1e9f, maxX = -1e9f, minY = 1e9f, maxY = -1e9f; + for (DWORD i = 0; i < count; ++i) { + const auto* position = reinterpret_cast(buffer.data() + stride * i); + minX = std::min(minX, position[0]); + maxX = std::max(maxX, position[0]); + minY = std::min(minY, position[1]); + maxY = std::max(maxY, position[1]); + } + const bool fullLayout = minX <= 0.5f && maxX >= kLayoutWidth - 0.5f && minY <= 0.5f && maxY >= 767.5f; + const float scale = static_cast(mods::widescreen::RenderWidth()) / kLayoutWidth; for (DWORD i = 0; i < count; ++i) { auto* x = reinterpret_cast(buffer.data() + stride * i); - *x += static_cast(g_offsetX); + *x = fullLayout ? *x * scale : *x + static_cast(g_offsetX); } return buffer.data(); }