24 constexpr std::uint32_t
TextColour = 0x00FAFAFAU;
27 const data::LanguageCatalog& catalog, std::uint32_t
id)
30 if (!
text)
return std::unexpected(
text.error().detail);
37 std::string_view
pattern, std::string_view playerName)
40 for (std::size_t
i = 0;
i <
pattern.size(); ++
i)
53 [[
nodiscard]] std::expected<std::string, std::string> squareName(
54 const data::LanguageCatalog& catalog,
int city,
58 return std::unexpected(
59 "Future/Immunity square index is out of range");
61 city =
static_cast<int>(
catalog.language()) - 2;
63 42U *
static_cast<std::uint32_t
>(std::max(city, 0)) +
64 static_cast<std::uint32_t
>(square);
66 if (!
text)
return std::unexpected(
text.error().detail);
68 return std::unexpected(
69 "Future/Immunity square name is missing from LANG");
70 if (!(**text)->empty() && (**text)->front() == u
'*')
74 if (!
text)
return std::unexpected(
text.error().detail);
76 return std::unexpected(
77 "Future/Immunity base square name is missing from LANG");
85 data::LegacyBitmapRGBA8&
image, fonts::Runtime&
font,
86 std::string_view
text,
int x,
int y)
88 if (
text.empty())
return {};
97 data::LegacyBitmapRGBA8&
image, fonts::Runtime&
font,
107 data::LegacyBitmapRGBA8&
image, fonts::Runtime&
font,
113 {0, 0,
static_cast<std::uint32_t
>(
width),
114 static_cast<std::uint32_t
>(
height)});
121 struct RestoreFont
final
139 if (!visible_)
return {};
142 *surface_, FutureImmunityTextPriority, false}))
143 return std::unexpected(
144 "Future/Immunity text stop queue is full");
151 return std::unexpected(
152 "Future/Immunity text player is out of range");
154 return std::unexpected(
155 "Future/Immunity text font runtime is unavailable");
157 const auto resources =
playback.resources();
158 const auto language = resources ? resources->language() :
nullptr;
159 if (!language || !language->catalog)
160 return std::unexpected(
161 "Future/Immunity text has no language catalog");
163 playback.commands().pendingCount() >=
165 return std::unexpected(
166 "Future/Immunity text start queue is full");
168 const auto& catalog = *language->catalog;
174 if (!property)
return std::unexpected(property.error());
176 if (!
hits)
return std::unexpected(
hits.error());
180 if (!playerName)
return std::unexpected(playerName.error().detail);
183 std::array<std::string, 10> names{};
185 const auto first =
static_cast<std::size_t
>(
186 std::max(
state.scrollIndex, 0));
187 for (std::size_t
row = 0;
row < names.size(); ++
row)
191 const auto name = squareName(
192 catalog, city, resources->context().board,
194 if (!
name)
return std::unexpected(
name.error());
202 std::to_string(
static_cast<int>(
state.kind)) +
':' +
203 std::to_string(
state.player) +
':' +
204 std::to_string(
state.scrollIndex) +
':' + title +
':' +
205 *
property +
':' + *
hits;
206 for (std::size_t
row = 0;
row < names.size(); ++
row)
215 !contentKey_ || *contentKey_ !=
key;
218 return std::unexpected(
"sequence command queue cannot fit text redraw");
224 return std::unexpected(
restored.error().detail);
237 if (
auto result =
print(
244 return std::unexpected(
hitsMetrics.error().detail);
256 return std::unexpected(
lines.error().detail);
259 return std::unexpected(
lineMetrics.error().detail);
263 for (std::size_t
i = 0;
266 if (
auto result =
print(
274 for (std::size_t
row = 0;
row < names.size(); ++
row)
276 if (names[
row].empty())
break;
277 const int y = 60 +
static_cast<int>(
row) * 15;
283 if (
auto result =
print(
296 const auto updated =
playback.runtimeBitmaps().update(
297 *surface_, std::move(
image));
298 if (!updated)
return updated;
299 contentKey_ = std::move(
key);
313 if (!program)
return std::unexpected(program.error().detail);
315 *program, FutureImmunityTextPriority, {},
319 return std::unexpected(
320 "Future/Immunity text start queue is full");
std::deque< Bytes > output
static constexpr std::size_t Capacity
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > rawBitmap(data::DataId id, data::LegacyDataType sourceType, DescriptionLimits limits={})
std::expected< void, std::string > sync(const FutureImmunityState &state, const rules::GameState &gameState, display::Screen2D desiredView, int city, fonts::Runtime *fontRuntime, engine::SequencePlayback &playback)
std::expected< void, std::string > blitStraightRGBA8(LegacyBitmapRGBA8 &destination, const LegacyBitmapRGBA8 &source, std::int32_t destinationX, std::int32_t destinationY, BitmapBlitMode mode)
std::expected< std::string, Error > transcodeUtf8(std::u16string_view text)
std::vector< ObjectSpec > catalog(bool europe)
constexpr std::size_t SquareCount
constexpr PlayerNumber MaxPlayers
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
constexpr std::uint16_t FutureImmunityTextPriority
constexpr Rect FutureImmunityPopupRect
std::vector< std::uint8_t > pixels