65 if(!
font || !
font->ready())
return std::unexpected(
"Trade partner chooser font unavailable");
66 const auto resources=
playback.resources();
67 if(!resources || !resources->language() || !resources->language()->catalog)
68 return std::unexpected(
"Trade partner chooser LANG unavailable");
71 if(resources_!=resources){bitmaps_.
clear();key_.clear();resources_=resources;}
72 const auto title16=resources->language()->catalog->message(2015);
75 if(!title)
return std::unexpected(title.error().detail);
77 std::vector<Row> rows;std::ostringstream
signature;
82 if(game.
players[player].token>10)
return std::unexpected(
"Trade partner token outside retail catalog");
84 if(!
name)
return std::unexpected(
name.error().detail);
89 if(rows.empty())
return std::unexpected(
"Trade partner chooser has no eligible players");
93 const auto load=[&](
data::DataId id)->std::expected<std::shared_ptr<const data::BitmapRuntimeAsset>,std::string>
95 const auto metadata=resources->data().metadata(
id);
const auto bytes=resources->data().load(
id);
97 if(!
bytes)
return std::unexpected(
bytes.error().detail);
99 if(!asset)
return std::unexpected(asset.error().detail);
return *asset;
101 const auto paper=load(0x0003058F);
102 if(!
paper)
return std::unexpected(
paper.error());
103 if((*paper)->image.width!=188 || (*paper)->image.height!=209)
104 return std::unexpected(
"Trade partner chooser template must be188x209");
105 const unsigned scale=
modern?3:1;
109 const auto dst=(std::size_t(
y)*
image.width+
x)*4;
116 {
const auto src=(std::size_t(
y)*188+
x)*4;
for(
unsigned c=0;
c<4;++
c)
image.pixels[
dst+
c]=(*paper)->image.pixels[
src+
c]; }
118 const auto text=[&](std::string_view
value,
int x,
int y,
bool center)->std::expected<void,std::string>
122 if(!
raster)
return std::unexpected(
raster.error().detail);
125 if(!center &&
clipped.width>116*scale)
133 if(!blit)
return std::unexpected(blit.error());
return {};
136 for(
const auto&
row:rows)
140 const auto token=load(0x000201C0+
row.token);
if(!
token)
return std::unexpected(
token.error());
141 const auto&
source=(*token)->image;
143 return std::unexpected(
"Trade partner token dimensions invalid");
144 if(
modern && tokenImages_)
146 std::shared_ptr<const data::LegacyBitmapRGBA8>
thumbnail;
147 try {
thumbnail=tokenImages_(
static_cast<std::uint8_t
>(
row.token)); }
154 if(!blit)
return std::unexpected(blit.error());
159 std::vector<std::uint8_t>(
source.pixels.size()*scale*scale)};
166 if(!blit)
return std::unexpected(blit.error());
170 {
const auto id=
playback.runtimeBitmaps().create(188,209,
true);
if(!
id)
return std::unexpected(
id.
error());surface_=*
id;
created=
true; }
171 const auto updated=
playback.runtimeBitmaps().update(surface_,std::move(
image),
172 modern?std::optional<std::array<float,4>>{{0,0,188,209}}:std::nullopt,
modern);
179 if(!started)
return started;visible_=
true;
LegacyBitmapMetadata metadata
std::vector< std::byte > bytes
std::expected< void, std::string > sync(const State &state, const rules::GameState &game, display::Screen2D view, fonts::Runtime *font, engine::SequencePlayback &playback, bool modernPresentation=false)
std::expected< void, std::string > blitStraightRGBA8(LegacyBitmapRGBA8 &destination, const LegacyBitmapRGBA8 &source, std::int32_t destinationX, std::int32_t destinationY, BitmapBlitMode mode)