Hide menu pictures only inside the menu frames
The hidden-texture list stayed active in a game; a game texture made at the address of a freed menu picture was skipped (rendering glitches in-game). Hiding now applies only while the main menu's frame or the in-game options draw over the menu background. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
db87e276bf
commit
c4aacbcdd2
2 files changed
+20
-4
No files matched your search
+17
-2
@@ -409,10 +409,22 @@ DrawPrimitiveFn g_drawPrimitive = nullptr;
|
||||
DrawIndexedPrimitiveFn g_drawIndexedPrimitive = nullptr;
|
||||
|
||||
// Textures not drawn (SetHiddenTextures): the surface bound to stage 0 is
|
||||
// tracked per thread (each thread draws with its own device calls).
|
||||
// tracked per thread (each thread draws with its own device calls). Only
|
||||
// inside a frame drawn over the menu background (g_hidingPictures: the main
|
||||
// menu's, the options' in a game): the list keeps surfaces the cache may
|
||||
// have freed since, and a game texture made at the same address was skipped
|
||||
// in the world view (user, 2026-10-21: "rendering glitches ingame").
|
||||
constexpr int kHiddenTextureMax = 64;
|
||||
std::atomic<void*> g_hiddenTextures[kHiddenTextureMax] = {};
|
||||
thread_local void* g_boundTexture = nullptr;
|
||||
thread_local int g_hidingPictures = 0;
|
||||
|
||||
struct HidingPictures {
|
||||
HidingPictures() { ++g_hidingPictures; }
|
||||
~HidingPictures() { --g_hidingPictures; }
|
||||
HidingPictures(const HidingPictures&) = delete;
|
||||
HidingPictures& operator=(const HidingPictures&) = delete;
|
||||
};
|
||||
|
||||
using SetTextureFn = HRESULT(__stdcall*)(void* device, DWORD stage, void* surface);
|
||||
SetTextureFn g_setTexture = nullptr;
|
||||
@@ -425,7 +437,7 @@ HRESULT __stdcall SetTextureTracked(void* device, DWORD stage, void* surface) {
|
||||
}
|
||||
|
||||
bool BoundTextureHidden() {
|
||||
if (!g_boundTexture) {
|
||||
if (!g_boundTexture || g_hidingPictures == 0) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& hidden : g_hiddenTextures) {
|
||||
@@ -521,9 +533,11 @@ public:
|
||||
Viewport7 frame = {static_cast<DWORD>(dx), 0, kLayoutWidth, 768, previous_.minZ, previous_.maxZ};
|
||||
device_ = device;
|
||||
g_setViewport(device, &frame);
|
||||
++g_hidingPictures;
|
||||
}
|
||||
~FrameScope() {
|
||||
if (device_) {
|
||||
--g_hidingPictures;
|
||||
g_setViewport(device_, &previous_);
|
||||
}
|
||||
}
|
||||
@@ -872,6 +886,7 @@ int RenderMenuFrame(void* device, bool framed, int (*body)(void* context), void*
|
||||
const int width = mods::widescreen::RenderWidth();
|
||||
const int dx = framed && width > kLayoutWidth ? (width - kLayoutWidth) / 2 : 0;
|
||||
g_menuFrameDx = dx;
|
||||
HidingPictures hiding;
|
||||
Viewport7 previous;
|
||||
auto getViewport =
|
||||
device ? reinterpret_cast<GetViewportFn>((*static_cast<void***>(device))[kVtableGetViewport]) : nullptr;
|
||||
|
||||
+3
-2
@@ -48,8 +48,9 @@ int HandleCanvas(void* event, int (*body)(void* context), void* context);
|
||||
int RenderMenuFrame(void* device, bool framed, int (*body)(void* context), void* context);
|
||||
int MenuFrameOffsetX();
|
||||
|
||||
// Quads drawn with one of these textures (Direct3D surfaces) are left out,
|
||||
// on every thread, until the list changes (at most 64).
|
||||
// Quads drawn with one of these textures (Direct3D surfaces) are left out
|
||||
// inside the frames drawn over the menu background (RenderMenuFrame, the
|
||||
// in-game options), until the list changes (at most 64).
|
||||
void SetHiddenTextures(void* const* surfaces, int count);
|
||||
|
||||
} // namespace mods::hud
|
||||
Reference in new issue
Block a user