Characters: 16:9 "Spielen" screen, autosave interval option
- Shared screen kit (mods/screen, docs/screens.md): a 1365x768 canvas centred in the render width on our own dark background, the game's frames and buttons; the main menu renders full width while it is shown. - The load window (cUI_Savegame) is replaced by the Spielen screen: character list, hero panel, campaign x difficulty grid, save/autosave choice, rename/delete/reset/new character dialogs. - Migrated characters without a shared hero load their hero's world first, then start the new world. - Options, Allgemein: autosave interval (Aus/5/10/15/30 minutes). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
732d9c2abb
commit
34a119433a
16 files changed
+1391
-468
No files matched your search
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
// 16:9 menu screens (request of 2026-10-20, docs/screens.md): a screen of our
|
||||
// own replaces a full-screen window of the game's (its render and mouse
|
||||
// handling), laid out on a 1365x768 canvas (1920x1080 in UI units), centred in
|
||||
// the render width; wider screens only get more background at the sides. The
|
||||
// look is the game's: its frames and buttons on a dark background of ours.
|
||||
//
|
||||
// A screen hooks its window's render and event methods and calls Render /
|
||||
// Handle with a body that draws / handles in canvas coordinates with the
|
||||
// helpers below.
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "game/ui/text.h"
|
||||
#include "mods/hud.h"
|
||||
|
||||
namespace mods::screen {
|
||||
|
||||
using game::UiRect;
|
||||
|
||||
constexpr int kWidth = hud::kCanvasWidth;
|
||||
constexpr int kHeight = hud::kCanvasHeight;
|
||||
|
||||
// Spacing: the game's frames reach about 0x20 beyond their rects, buttons
|
||||
// about 0x21 (measured on the options window).
|
||||
constexpr int kFrameOrnament = 0x20;
|
||||
// The frames are made of pieces of 64: other sizes leave gaps (the game's
|
||||
// frames are 384x128, 384x64; screenshot 2026-10-20).
|
||||
constexpr int kFrameStep = 64;
|
||||
constexpr int kButtonOrnament = 0x21;
|
||||
constexpr int kMargin = kFrameOrnament + 16; // canvas edge to a panel's rect
|
||||
constexpr int kPanelGap = 96; // between two panels' rects, as the options window's columns
|
||||
constexpr int kPanelPadding = 16; // panel rect to its content
|
||||
|
||||
constexpr uint16_t kFont = 1;
|
||||
constexpr uint32_t kTextColour = 0xffe6d6aa; // as the options' texts
|
||||
constexpr uint32_t kHeadingColour = 0xfff0c060; // as the options' headings
|
||||
constexpr uint32_t kDimColour = 0xff8c8474;
|
||||
constexpr uint32_t kRowColour = 0x40302418;
|
||||
constexpr uint32_t kRowHoverColour = 0x80403020;
|
||||
constexpr uint32_t kRowSelectedColour = 0xc0604818;
|
||||
|
||||
// Draws the screen of `window`: the background across the whole render
|
||||
// target, then body(context) in canvas coordinates. While `window` is shown
|
||||
// the main menu thread renders the full width (widescreen::SetWideMenuScreen).
|
||||
int Render(void* window, void* device, int (*body)(void* context), void* context);
|
||||
// Runs body(context) with the event's mouse position in canvas coordinates.
|
||||
int Handle(void* event, int (*body)(void* context), void* context);
|
||||
|
||||
void Fill(void* device, const UiRect& rect, uint32_t colour);
|
||||
// One line of text in `rect`, centred vertically (game::kTextCenter /
|
||||
// kTextRight for horizontal alignment).
|
||||
void Text(void* device, const UiRect& rect, const std::wstring& text, uint32_t colour, uint32_t flags = 0);
|
||||
|
||||
UiRect Inset(const UiRect& rect, int by);
|
||||
|
||||
// A panel: a dark backdrop with the game's frame around `rect` (made anew when
|
||||
// the rect changes) and an optional heading at its top.
|
||||
class Panel {
|
||||
public:
|
||||
explicit Panel(const char* name) : name_(name) {}
|
||||
// The content area below the heading.
|
||||
UiRect Draw(void* device, const UiRect& rect, const std::wstring& heading = {});
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
UiRect rect_ = {};
|
||||
uint8_t* frame_ = nullptr;
|
||||
};
|
||||
|
||||
// A button of the game's (look and sounds of `model`, a button of the
|
||||
// window), made on first use.
|
||||
class Button {
|
||||
public:
|
||||
Button(const char* name, std::wstring caption) : name_(name), caption_(std::move(caption)) {}
|
||||
void Draw(void* device, const uint8_t* model, const UiRect& rect);
|
||||
// Passes the event to the button (pressed look, sound); true for a left
|
||||
// click on it. Only for buttons drawn this frame.
|
||||
bool Clicked(void* event);
|
||||
void SetCaption(const std::wstring& caption);
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
std::wstring caption_;
|
||||
uint32_t captionId_ = 0;
|
||||
uint8_t* control_ = nullptr;
|
||||
UiRect rect_ = {};
|
||||
unsigned drawnFrame_ = 0;
|
||||
};
|
||||
|
||||
// Height of the model's buttons (as the window made them).
|
||||
int16_t ButtonHeight(const uint8_t* model);
|
||||
|
||||
// Two clicks on the same thing within the system's double-click time.
|
||||
class DoubleClick {
|
||||
public:
|
||||
bool Click(int target);
|
||||
|
||||
private:
|
||||
int last_ = -1;
|
||||
unsigned long at_ = 0;
|
||||
};
|
||||
|
||||
} // namespace mods::screen
|
||||
Reference in new issue
Block a user