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:
khallaandClaude Opus 5.5 committed 2026-10-21 00:41:12 +02:00
1 parent c4aacbcdd2
commit 0ef3cf4bbd
6 files changed
+68 -25

No files matched your search

+19 -16
View File
@@ -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);
}