32 const std::filesystem::path &project_root,
37 auto image_result = loader.
load_from_file((project_root / src_key.
key()).string());
38 if (!image_result.has_value()) {
39 switch (image_result.error().type()) {
40 case ImageLoadError::Type::file_not_found:
41 case ImageLoadError::Type::unsupported_channel_count:
42 case ImageLoadError::Type::other_load_error:
47 panic(
"unhandled ImageLoadError type");
58 const std::filesystem::path &project_root,
62 panic(std::format(
"invalid pal index {}: out of range", index));
70 "Failed to load palette file.");
97template <SupportsTransparency PixelType,
typename LoaderType,
typename ComponentGetter>
101 const std::filesystem::path &project_root,
102 const std::string &anim_name,
103 const std::string &frame_name,
104 const LoaderType &loader,
105 ComponentGetter component_getter,
106 std::string_view error_context)
109 const auto png_path = project_root / src_key.
key();
112 load_animation_frame_from_png<PixelType>(png_path, frame_name, loader),
114 "{}: failed to load {}",
119 auto &component = component_getter(dest);
120 if (!component.has_anim(anim_name)) {
122 component.add_anim(std::move(anim));
125 auto &anim = component.anims().at(anim_name);
127 if (frame_name ==
"key") {
129 anim.
key_frame(std::move(load_result.frame));
133 anim.put_frame(frame_name, std::move(load_result.frame));
137 auto params = anim.params();
138 if (params.width_tiles() == 0 && params.height_tiles() == 0) {
139 params.width_tiles(load_result.width_tiles);
140 params.height_tiles(load_result.height_tiles);
141 anim.params(std::move(params));
158 for (
auto &entry : entries) {
168 const auto path = project_root_ / src_key.
key();
174 "Failed to read metatile_attributes.bin.");
175 for (
auto &attr : attributes) {
193 panic(std::format(
"invalid pal index {}: out of range", index));
203 const std::string &anim_name,
205 const std::vector<std::pair<std::string, ArtifactKey>> &frame_keys)
const
209 for (
const auto &[frame_name, frame_key] : frame_keys) {
211 (import_anim_frame_impl<IndexPixel>(
217 *png_indexed_loader_,
219 "Porymap animation frame")),
224 std::filesystem::path params_path = project_root_ / params_key.
key();
225 if (!std::filesystem::exists(params_path)) {
231 const std::string callback_func =
"InitTilesetAnim_PorytilesManaged_" + tileset_cased.to_pascal_case();
238 "{}: Failed to parse animation parameters.",
244 auto existing_params = anim.params();
248 new_params.width_tiles(existing_params.width_tiles());
249 new_params.height_tiles(existing_params.height_tiles());
251 anim.params(std::move(new_params));
303 for (
const auto &[metatile_id, attribute] : attributes) {
312 PT_TRY_CALL_PASS_ERR(import_porytiles_palette(dest, src_key, index, project_root_, *pal_loader_),
void);
318 const std::string &anim_name,
320 const std::optional<ArtifactKey> &key_frame_key,
321 const std::vector<std::pair<std::string, ArtifactKey>> &frame_keys)
const
327 anim_json_parser_->
parse((project_root_ / params_key.
key()).string()),
329 "{}: Failed to parse animation parameters.",
334 if (it == parsed_anim_params.end()) {
336 "{}: Animation '{}' not found in animation parameters file.",
341 const auto ¶ms = it->second;
349 if (key_frame_key.has_value()) {
351 (import_anim_frame_impl<Rgba32>(
353 key_frame_key.value(),
359 "Porytiles animation frame")),
364 for (
const auto &[frame_name, frame_key] : frame_keys) {
366 (import_anim_frame_impl<Rgba32>(
374 "Porytiles animation frame")),
384 const auto json_path = project_root_ / params_key.
key();
390 "{}: Failed to parse primary animation references.",
393 if (parsed_refs.empty()) {
397 std::map<std::string, std::vector<AnimOverrideEntry>> converted;
398 for (
auto &[cased_name, entries] : parsed_refs) {
399 converted[cased_name.to_snake_case()] = std::move(entries);
Shared helper for loading animation frames from PNG files.
#define PT_TRY_ASSIGN_CHAIN_ERR(var, expr, return_type,...)
Unwraps a ChainableResult, chaining a new error message on failure.
#define PT_TRY_CALL_PASS_ERR(expr, return_type)
Unwraps a void ChainableResult, passing through the error chain with an empty FormattableError when t...
#define PT_TRY_ASSIGN_PASS_ERR(var, expr, return_type)
Unwraps a ChainableResult, passing through the error chain with an empty FormattableError when types ...
ChainableResult< std::map< DynamicCasedName, AnimParams > > parse_from_callback(const std::filesystem::path &c_file_path, const std::string &callback_func_name, const DynamicCasedName &tileset_cased_name, bool porytiles_managed) const
Parses animation parameters by following the callback chain.
ChainableResult< std::map< DynamicCasedName, std::vector< AnimOverrideEntry > > > parse_primary_references(const std::filesystem::path &json_path) const
Parses the primary_references section from an anim.json file.
ChainableResult< std::map< DynamicCasedName, AnimParams > > parse(const std::filesystem::path &json_path) const
Parses an anim.json file into a map of animation parameters.
A complete tileset animation with name, configuration, and frame data.
const AnimFrame< PixelType > & key_frame() const
Returns the key frame of this animation.
A type-safe wrapper for artifact keys.
const std::string & key() const
ChainableResult< std::map< std::size_t, MetatileAttribute > > load(const std::filesystem::path &path) const
Loads metatile attributes from a CSV file.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A smart string wrapper that preserves word structure for lossless case format conversion.
A service interface that loads a fixed-length Palette from a given file.
virtual ChainableResult< Palette< Rgba32, pal::max_size > > load_with_wildcards(const std::filesystem::path &path) const =0
A template for two-dimensional images with arbitrarily typed pixel values.
An image loader that reads PNG files to create an Image with an Rgba32 pixel type.
ChainableResult< std::unique_ptr< Image< Rgba32 > >, ImageLoadError > load_from_file(const std::filesystem::path &path) const
const std::map< std::string, Animation< IndexPixel > > & anims() const
void push_back_tilemap_entry(TilemapEntry entry)
Add a TilemapEntry to the end of the entry vector.
void set_pal(std::size_t pal_index, Palette< Rgba32, pal::max_size > pal)
void push_back_attribute(MetatileAttribute attribute)
Add a MetatileAttribute to the end of the attribute vector.
const Image< IndexPixel > & tiles_png() const
const Image< Rgba32 > & bottom() const
void set_pal(std::size_t pal_index, Palette< Rgba32, pal::max_size > pal)
const Image< Rgba32 > & middle() const
const Image< Rgba32 > & top() const
void insert_attribute(std::size_t metatile_id, MetatileAttribute attribute)
Insert a MetatileAttribute to the end of the attribute vector.
void add_anim(Animation< Rgba32 > anim)
const std::map< std::string, std::vector< AnimOverrideEntry > > & primary_anim_overrides() const
ChainableResult< void > read_metatile_attributes_bin(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_top_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porytiles_pal_n(Tileset &dest, const ArtifactKey &src_key, std::size_t index) const override
ChainableResult< void > read_porymap_pal_n(Tileset &dest, const ArtifactKey &src_key, std::size_t index) const override
ChainableResult< void > read_attributes_csv(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_middle_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porytiles_anim(Tileset &dest, const std::string &anim_name, const ArtifactKey ¶ms_key, const std::optional< ArtifactKey > &key_frame_key, const std::vector< std::pair< std::string, ArtifactKey > > &frame_keys) const override
ChainableResult< void > read_bottom_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porymap_anim(Tileset &dest, const std::string &anim_name, const ArtifactKey ¶ms_key, const std::vector< std::pair< std::string, ArtifactKey > > &frame_keys) const override
ChainableResult< void > read_porytiles_primary_anim_references(Tileset &dest, const ArtifactKey ¶ms_key) const override
ChainableResult< void > read_tiles_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_metatiles_bin(Tileset &dest, const ArtifactKey &src_key) const override
static const Style bold
Bold text formatting.
A complete tileset containing both Porytiles and Porymap components.
const PorytilesTilesetComponent & porytiles_component() const
const PorymapTilesetComponent & porymap_component() const
const std::string & name() const
constexpr std::size_t bytes_per_attr_firered
constexpr std::size_t num_pals
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
ChainableResult< std::vector< MetatileAttribute > > parse_firered_metatile_attributes(const std::filesystem::path &path)
Parses a metatile_attributes.bin file for FireRed format.
ChainableResult< Palette< Rgba32, pal::max_size > > load_porymap_palette(const std::filesystem::path &path, const FilePalLoader &loader)
Loads a Porymap palette file (e.g., 00.pal).
ChainableResult< std::vector< MetatileAttribute > > parse_emerald_metatile_attributes(const std::filesystem::path &path)
Parses a metatile_attributes.bin file for Emerald format.
DynamicCasedName extract_tileset_cased_name(const std::string &tileset_name)
Extracts the tileset short name and wraps it in a DynamicCasedName.
ChainableResult< std::vector< TilemapEntry > > parse_metatiles_bin(const std::filesystem::path &path)
Parses a metatiles.bin file into TilemapEntry objects.
ChainableResult< std::unique_ptr< Image< IndexPixel > > > load_indexed_png(const std::filesystem::path &path, const PngIndexedImageLoader &loader)
Loads an indexed PNG file (e.g., tiles.png).
Utility functions for string manipulation and formatting.