37 LayerModeConverter layer_mode_converter{format_, diag_, tile_printer_, extrinsic_transparency};
38 MetatileDecompiler metatile_decompiler{format_, diag_, tile_printer_, extrinsic_transparency};
43 layer_mode_converter.triple_layerize(
tileset.porymap_component()),
44 std::unique_ptr<Tileset>,
45 std::format(
"Failed to triple-layerize Porymap component for tileset '{}'.",
tileset.name()));
53 auto new_porymap_component = std::make_unique<PorymapTilesetComponent>(
tileset.porymap_component());
55 auto new_porytiles_component = std::make_unique<PorytilesTilesetComponent>();
57 for (
const auto &palette :
tileset.porytiles_component().palettes()) {
59 if (palette.has_value()) {
60 new_porytiles_component->set_palette(i, palette.value());
71 const auto &porymap_attributes =
tileset.porymap_component().metatile_attributes_bin();
72 for (std::size_t metatile_id = 0; metatile_id < porymap_attributes.size(); metatile_id++) {
73 new_porytiles_component->insert_attribute(
76 porymap_attributes[metatile_id],
78 tileset.porytiles_component().get_attribute(metatile_id)));
86 new_porymap_component->metatiles_bin(tilemap_entries);
88 if (
const auto &porymap_animations =
tileset.porymap_component().anims(); !porymap_animations.empty()) {
91 std::set<PixelTile<Rgba32>> inter_anim_canonical_tiles;
93 AnimDecompiler anim_decompiler{config_, diag_, tile_printer_, palette_printer_};
95 for (
const auto &index_pixel_anim : porymap_animations | std::views::values) {
99 anim_decompiler.decompile_animation(
100 tileset.name(), index_pixel_anim, inter_anim_canonical_tiles, *new_porymap_component),
101 std::unique_ptr<Tileset>,
103 "Failed to decompile animation '{}'.",
FormatParam{index_pixel_anim.name(), Style::bold}));
109 if (rgba_anim.has_key_frame()) {
110 for (
const auto &t : rgba_anim.key_frame().tiles()) {
113 inter_anim_canonical_tiles.insert(base);
117 new_porytiles_component->add_anim(std::move(rgba_anim));
122 for (
const auto &key : per_anim_overrides.value() | std::views::keys) {
123 if (!porymap_animations.contains(key)) {
125 "unused-animation-config",
127 "Animation config for '{}' does not match any animation in tileset '{}'.",
135 new_porymap_component->metatiles_bin(
tileset.porymap_component().metatiles_bin());
140 metatile_decompiler.decompile_metatiles(
141 tilemap_entries, new_porymap_component->tiles_png(),
tileset.porymap_component().palettes()),
142 std::unique_ptr<Tileset>,
143 std::format(
"Failed to decompile Porymap component for tileset '{}'.",
tileset.name()));
147 constexpr std::size_t metatiles_per_row = 8;
151 metatileizer.demetatileize(metatiles, metatiles_per_row),
152 std::unique_ptr<Tileset>,
154 "Failed to demetatileize metatiles for tileset '{}'.",
FormatParam{tileset.name(), Style::bold}));
156 auto &[bottom_image, middle_image, top_image] = layer_images;
159 new_porytiles_component->bottom(bottom_image);
160 new_porytiles_component->middle(middle_image);
161 new_porytiles_component->top(top_image);
164 std::make_unique<Tileset>(
tileset.name(), std::move(new_porytiles_component), std::move(new_porymap_component));
#define PT_TRY_ASSIGN_CHAIN_ERR(var, expr, return_type,...)
Unwraps a ChainableResult, chaining a new error message on failure.
Decompiles indexed animation tiles to RGBA format.
A PixelTile representation that stores the canonical (lexicographically minimal) orientation among al...
A result type that maintains a chainable sequence of errors for debugging and error reporting.
An 8x8 tile backed by literal-array-based per-pixel storage of an arbitrary pixel type.
ChainableResult< std::unique_ptr< Tileset > > decompile(const Tileset &tileset) const
static const Style bold
Bold text formatting.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > ¶ms) const
Formats a string with styled parameters using fmtlib syntax.
A complete tileset containing both Porytiles and Porymap components.
const TextFormatter & formatter() const
virtual void warning(const std::string &tag, const std::vector< std::string > &lines) const =0
Display a tagged warning message.
@ canonical
Export tiles in canonical form without applying flip transformations.
MetatileAttribute merge_prior_layer_type_pin(MetatileAttribute fresh_from_bin, PriorPinColumnState prior_state, const std::optional< MetatileAttribute > &prior_attribute)
Applies the decompile/import round-trip rules to one metatile's layer_type pin.
PriorPinColumnState
What an attributes.csv (if any) said about a role's pin column when this component was loaded.
@ tileset
Configuration scoped to a specific tileset.
#define PT_UNWRAP_TILESET_CONFIG_PTR(ptr, config, tileset_name, return_type)
Unwraps a tileset-scoped config value via pointer access, returning early if the value is not availab...