29 if (!image_result.has_value()) {
30 switch (image_result.error().type()) {
34 case ImageLoadError::Type::file_not_found:
37 case ImageLoadError::Type::unsupported_channel_count:
38 case ImageLoadError::Type::other_load_error: {
39 const auto error_msg = fmt::format(
"failed to load layer image: {}", src_key.
key());
43 panic(
"unhandled ImageLoadError type");
52 std::ifstream metatiles_bin{src_key.
key(), std::ios::binary};
53 const std::vector<unsigned char> data_buf{std::istreambuf_iterator(metatiles_bin), {}};
55 if (data_buf.size() % 2 != 0) {
56 return FormattableError{
"metatiles.bin size is not a multiple of 2 bytes, probably corrupted"};
59 for (
unsigned int byte_index = 0; byte_index < data_buf.size(); byte_index += 2) {
61 const std::uint16_t lower_byte = data_buf.at(byte_index);
62 const std::uint16_t upper_byte = data_buf.at(byte_index + 1);
63 const std::uint16_t entry_bits = (upper_byte << 8) | lower_byte;
82 entry.hflip((entry_bits >> 10) & 0x0001);
83 entry.vflip((entry_bits >> 11) & 0x0001);
84 entry.pal_index((entry_bits >> 12) & 0x000F);
94 std::ifstream metatile_attr_bin{src_key.
key(), std::ios::binary};
95 const std::vector<unsigned char> data_buf{std::istreambuf_iterator(metatile_attr_bin), {}};
99 "metatile_attributes.bin size is not a multiple of {} bytes, probably corrupted",
104 for (std::size_t metatile_index = 0; metatile_index < metatile_count; metatile_index++) {
107 std::uint16_t attribute = (byte1 << 8) | byte0;
110 if (!layer_type_result.has_value()) {
115 MetatileAttribute metatile_attribute{layer_type_result.value(),
static_cast<std::uint16_t
>(attribute & 0x00FF)};
124 std::ifstream metatile_attr_bin{src_key.
key(), std::ios::binary};
125 const std::vector<unsigned char> data_buf{std::istreambuf_iterator(metatile_attr_bin), {}};
129 "metatile_attributes.bin size is not a multiple of {} bytes, probably corrupted",
134 for (std::size_t metatile_index = 0; metatile_index < metatile_count; metatile_index++) {
139 std::uint32_t attribute = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0;
153 if (!image_result.has_value()) {
154 return FormattableError{fmt::format(
"failed to load tiles.png: {}", image_result.error())};
163 if (index < 0 || index >= 16) {
164 panic(fmt::format(
"invalid pal index {}: out of range", index));
167 const auto pal_result = loader.
load(src_key.
key());
168 if (!pal_result.has_value()) {
169 return FormattableError{fmt::format(
"failed to load: {}", pal_result.error())};
183 switch (artifact.
type()) {
186 const auto result = import_layer_png(
190 if (!result.has_value()) {
196 const auto result = import_layer_png(
200 if (!result.has_value()) {
206 const auto result = import_layer_png(
210 if (!result.has_value()) {
216 panic(
"TODO: implement");
218 panic(
"TODO: implement");
220 panic(
"TODO: implement");
224 const auto result = import_metatiles_bin(dest, src_key);
225 if (!result.has_value()) {
232 const auto result = import_emerald_metatile_attributes(dest, src_key);
233 if (!result.has_value()) {
235 FormattableError{fmt::format(
"could not import metatile_attributes.bin")}, result};
241 const auto result = import_tiles_png(dest, src_key, *png_indexed_loader_);
242 if (!result.has_value()) {
248 panic(
"TODO: implement");
250 if (!artifact.
index().has_value()) {
251 panic(
"took TilesetArtifact::Type::pal_n branch but missing pal index");
253 const auto result = import_palette(dest, src_key, artifact.
index().value(), *pal_loader_);
254 if (!result.has_value()) {
263 panic(
"unhandled TilesetArtifact::Type");
A type-safe wrapper for artifact keys.
const std::string & key() const
Gets the underlying string value.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A service interface that loads a Palette from a given file.
virtual Result< Palette< Rgba32 > > load(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 index pixel type.
Result< std::unique_ptr< Image< IndexPixel > > > load_from_file(const std::filesystem::path &path) const
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
void push_back_tilemap_entry(TilemapEntry entry)
Add a TilemapEntry to the end of the entry vector.
void set_pal(Palette< Rgba32 > pal, unsigned int pal_index)
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 > & middle() const
const Image< Rgba32 > & top() const
const Image< Rgba32 > & bottom() const
ChainableResult< void > read(Tileset &dest, const ArtifactKey &src_key, const TilesetArtifact &artifact) const override
Reads an artifact from the backing store and updates the target Tileset.
Represents a tilemap entry referencing a tile with palette and flip attributes.
unsigned int tile_index() const
Represents a Pokémon Generation III decomp tileset artifact with type and optional metadata.
Type type() const
Gets the artifact type.
@ porytiles_anim_frame
Animation frame PNG for Porytiles-format animation.
@ attributes_csv
CSV file containing metatile attribute overrides.
@ middle_png
Middle layer PNG input image.
@ metatile_attributes_bin
Metatile attributes output for Porymap.
@ bottom_png
Bottom layer PNG input image.
@ top_png
Top layer PNG input image.
@ pal_n
JASC palette data file.
@ metatiles_bin
Metatile data output for Porymap.
@ pal_override_n
JASC palette override file.
@ tiles_png
Combined tile sheet PNG output for Porymap.
@ porymap_anim_frame
Animation frame PNG for Porymap-format animation.
std::optional< unsigned int > index() const
Gets the artifact index if present.
A complete tileset containing both Porytiles and Porymap components.
const PorytilesTilesetComponent & porytiles_component() const
const PorymapTilesetComponent & porymap_component() const
constexpr std::size_t bytes_per_attr_emerald
ChainableResult< LayerType > layer_type_from_int(std::uint8_t i)
constexpr std::size_t bytes_per_attr_firered
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.