Maps in widened views: TAB overlay in place, M map across the full width
- hud: shift SetViewport/Clear with moved windows (TAB overview map) - megamap: view constants patched to the render width (clip, scroll limit, edge scrolling, centre, dark band, zoomed view and its markers); frame stretched to the screen edges, zoom controls and their click area centred - hud: Anchor::Screen windows are drawn and clicked unshifted but still own the event scope - autotest waits for log markers instead of fixed delays (~18 s per run) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a7f8496b2b
commit
c6c5530709
9 files changed
+327
-18
No files matched your search
+55
-7
@@ -45,13 +45,14 @@ thread_local int g_offsetX = 0;
|
||||
thread_local bool g_eventShifted = false;
|
||||
|
||||
|
||||
enum class Anchor { Center, Right };
|
||||
// Screen: laid out across the whole render width by its mod (drawn unshifted).
|
||||
enum class Anchor { Center, Right, Screen };
|
||||
|
||||
int OffsetFor(Anchor anchor) {
|
||||
static const bool enabled = re::ConfigInt("hud", "Enabled", 1) != 0;
|
||||
const int width = mods::widescreen::RenderWidth();
|
||||
if (!enabled || width <= kLayoutWidth || mods::widescreen::IsClassicFrame() ||
|
||||
mods::widescreen::MenuIsShowing()) {
|
||||
mods::widescreen::MenuIsShowing() || anchor == Anchor::Screen) {
|
||||
return 0;
|
||||
}
|
||||
return anchor == Anchor::Center ? (width - kLayoutWidth) / 2 : width - kLayoutWidth;
|
||||
@@ -283,11 +284,12 @@ int MouseEventXOffsets(void* event, int (&offsets)[2]) {
|
||||
}
|
||||
}
|
||||
|
||||
// RAII: shift the mouse position by -dx for the scope (outermost window only).
|
||||
// RAII: shift the mouse position by -dx for the scope (outermost window only;
|
||||
// one with dx 0, e.g. Anchor::Screen, still keeps its children from shifting).
|
||||
class EventOffset {
|
||||
public:
|
||||
EventOffset(void* event, int dx) : cursor_(dx) {
|
||||
if (dx == 0 || g_eventShifted) {
|
||||
EventOffset(void* event, int dx) : outermost_(!g_eventShifted), cursor_(outermost_ ? dx : 0) {
|
||||
if (!outermost_) {
|
||||
return;
|
||||
}
|
||||
int offsets[2];
|
||||
@@ -309,6 +311,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool outermost_;
|
||||
int count_ = 0;
|
||||
int32_t* x_[2] = {};
|
||||
int32_t original_[2] = {};
|
||||
@@ -387,6 +390,45 @@ HRESULT __stdcall DrawIndexedPrimitiveShifted(void* device, DWORD type, DWORD fv
|
||||
indexCount, flags);
|
||||
}
|
||||
|
||||
// Viewports and cleared rectangles in screen space (the overview map, TAB,
|
||||
// sets a viewport at its frame, 162,120 700x525, and draws the map inside with
|
||||
// its own projection): moved like the vertices while a window draws.
|
||||
struct Viewport7 {
|
||||
DWORD x, y, width, height;
|
||||
float minZ, maxZ;
|
||||
};
|
||||
struct Rect7 {
|
||||
LONG x1, y1, x2, y2;
|
||||
};
|
||||
using SetViewportFn = HRESULT(__stdcall*)(void* device, Viewport7* viewport);
|
||||
using ClearFn = HRESULT(__stdcall*)(void* device, DWORD count, Rect7* rects, DWORD flags, DWORD color, float z,
|
||||
DWORD stencil);
|
||||
SetViewportFn g_setViewport = nullptr;
|
||||
ClearFn g_clear = nullptr;
|
||||
|
||||
HRESULT __stdcall SetViewportShifted(void* device, Viewport7* viewport) {
|
||||
if (g_offsetX == 0 || !viewport) {
|
||||
return g_setViewport(device, viewport);
|
||||
}
|
||||
Viewport7 shifted = *viewport;
|
||||
shifted.x = static_cast<DWORD>(static_cast<int>(shifted.x) + g_offsetX);
|
||||
return g_setViewport(device, &shifted);
|
||||
}
|
||||
|
||||
HRESULT __stdcall ClearShifted(void* device, DWORD count, Rect7* rects, DWORD flags, DWORD color, float z,
|
||||
DWORD stencil) {
|
||||
if (g_offsetX == 0 || count == 0 || !rects) {
|
||||
return g_clear(device, count, rects, flags, color, z, stencil);
|
||||
}
|
||||
thread_local std::vector<Rect7> shifted;
|
||||
shifted.assign(rects, rects + count);
|
||||
for (Rect7& r : shifted) {
|
||||
r.x1 += g_offsetX;
|
||||
r.x2 += g_offsetX;
|
||||
}
|
||||
return g_clear(device, count, shifted.data(), flags, color, z, stencil);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int CursorOffsetX() {
|
||||
@@ -414,6 +456,12 @@ void OnDevice(void* device) {
|
||||
g_drawIndexedPrimitive = reinterpret_cast<DrawIndexedPrimitiveFn>(vtable[26]);
|
||||
re::AttachRuntimeHook("D3D7 DrawIndexedPrimitive", reinterpret_cast<void**>(&g_drawIndexedPrimitive),
|
||||
reinterpret_cast<void*>(&DrawIndexedPrimitiveShifted));
|
||||
// Clear 10, SetViewport 13.
|
||||
g_clear = reinterpret_cast<ClearFn>(vtable[10]);
|
||||
re::AttachRuntimeHook("D3D7 Clear", reinterpret_cast<void**>(&g_clear), reinterpret_cast<void*>(&ClearShifted));
|
||||
g_setViewport = reinterpret_cast<SetViewportFn>(vtable[13]);
|
||||
re::AttachRuntimeHook("D3D7 SetViewport", reinterpret_cast<void**>(&g_setViewport),
|
||||
reinterpret_cast<void*>(&SetViewportShifted));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,8 +593,8 @@ HUD_EVENT(0x006c5f40, UiInventory_HandleEvent, Anchor::Center)
|
||||
HUD_RENDER(0x006c6140, UiInventory_Render, Anchor::Center)
|
||||
HUD_EVENT(0x006c70e0, UiOverviewMap_HandleEvent, Anchor::Center)
|
||||
HUD_RENDER(0x006c69d0, UiOverviewMap_Render, Anchor::Center)
|
||||
HUD_EVENT(0x006c7ec0, UiMegamap_HandleEvent, Anchor::Center)
|
||||
HUD_RENDER(0x006c9ce0, UiMegamap_Render, Anchor::Center)
|
||||
HUD_EVENT(0x006c7ec0, UiMegamap_HandleEvent, Anchor::Screen)
|
||||
HUD_RENDER(0x006c9ce0, UiMegamap_Render, Anchor::Screen) // laid out by mods/megamap.cpp
|
||||
HUD_EVENT(0x006d1080, UiMaster_HandleEvent, Anchor::Center)
|
||||
HUD_RENDER(0x006d0f00, UiMaster_Render, Anchor::Center)
|
||||
HUD_EVENT(0x006d2450, UiMasterCombo_HandleEvent, Anchor::Center)
|
||||
|
||||
Reference in new issue
Block a user