Shared chest, menu after a game, dialogs over 16:9 screens
- Shared chest: emptied and not saved from the moment a save game is read until it reloads; a hero saved inside a load wrote the new world's objects (stale ids) as the chest's items. - Main menu after a game: shown 16:9 screens are tracked on the menu thread only and expire after 2 frames; a destroyed in-game window kept the menu unframed (old pictures, frame at the left). - Dialogs over a 16:9 screen in the main menu are centred, their dimming covers the screen. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c4aacbcdd2
commit
0ef3cf4bbd
6 files changed
+68
-25
No files matched your search
+19
-16
@@ -4,8 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <windows.h>
|
||||
@@ -46,15 +45,22 @@ constexpr int kHeadingHeight = 30;
|
||||
// frames).
|
||||
std::atomic<unsigned> g_frame{1};
|
||||
|
||||
// The windows whose screen is shown: the main menu's frame is not drawn
|
||||
// centred while any is (the screen draws itself across the width).
|
||||
std::mutex g_shownLock;
|
||||
std::set<const void*> g_shown;
|
||||
// The windows whose screen is shown on the menu thread, with the menu frame
|
||||
// they were last drawn in: the main menu's frame is not drawn centred while
|
||||
// any is (the screen draws itself across the width). Entries not drawn for
|
||||
// kShownFrames frames are dropped: the UI is rebuilt when a game starts or
|
||||
// ends, and a window destroyed while shown kept the menu from being framed
|
||||
// (user, 2026-10-21: "the old main menu is rendering again"). Menu thread only.
|
||||
constexpr unsigned kShownFrames = 2;
|
||||
unsigned g_menuFrame = 0;
|
||||
std::map<const void*, unsigned> g_shown;
|
||||
|
||||
void NoteShown(const void* window, bool shown) {
|
||||
std::lock_guard guard(g_shownLock);
|
||||
if (!widescreen::IsMenuThread()) {
|
||||
return;
|
||||
}
|
||||
if (shown) {
|
||||
g_shown.insert(window);
|
||||
g_shown[window] = g_menuFrame;
|
||||
} else {
|
||||
g_shown.erase(window);
|
||||
}
|
||||
@@ -91,11 +97,6 @@ void HidePictures() {
|
||||
hud::SetHiddenTextures(surfaces.data(), static_cast<int>(surfaces.size()));
|
||||
}
|
||||
|
||||
bool ShownAny() {
|
||||
std::lock_guard guard(g_shownLock);
|
||||
return !g_shown.empty();
|
||||
}
|
||||
|
||||
// The game's logo top left (user, 2026-10-21: "the bright blueish one"),
|
||||
// kLogoMargin from the edges: FX_SACREDLOGO.TGA, the emblem (horns around a
|
||||
// ring of runes) glowing blue on black, no alpha, added onto the background as
|
||||
@@ -134,8 +135,10 @@ void DrawRockWall(void* device, float width, float height) {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool AnyShown() {
|
||||
return ShownAny();
|
||||
bool BeginMenuFrame() {
|
||||
++g_menuFrame;
|
||||
std::erase_if(g_shown, [](const auto& entry) { return g_menuFrame - entry.second > kShownFrames; });
|
||||
return !g_shown.empty();
|
||||
}
|
||||
|
||||
void DrawBackground(void* device) {
|
||||
@@ -261,7 +264,7 @@ uint32_t __fastcall UiManager_Render(void* self, void* edx, uint32_t argument) {
|
||||
}
|
||||
auto* driver = *reinterpret_cast<DxDriver7**>(addr::g_dxDriver);
|
||||
void* device = driver ? driver->device : nullptr;
|
||||
const bool framed = !screen::AnyShown();
|
||||
const bool framed = !screen::BeginMenuFrame();
|
||||
if (framed && device) {
|
||||
screen::DrawBackground(device);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user