Skip to content

Commit

Permalink
Can now import compiled tiles.png
Browse files Browse the repository at this point in the history
  • Loading branch information
grunt-lucas committed Sep 2, 2023
1 parent 99663c6 commit aa833ba
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 26 deletions.
22 changes: 14 additions & 8 deletions src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,12 @@ std::unique_ptr<CompiledTileset> compile(PtContext &ctx, const DecompiledTileset
internalerror_unknownCompilerMode("compiler::compile");
}

// Push back transparent tiles to pad out tileset to multiple of 16
while (compiled->tiles.size() % 16 != 0) {
compiled->tiles.push_back(GBA_TILE_TRANSPARENT);
compiled->paletteIndexesOfTile.push_back(0);
}

return compiled;
}
} // namespace porytiles
Expand Down Expand Up @@ -1716,7 +1722,7 @@ TEST_CASE("compile function should fill out primary CompiledTileset struct with
auto compiledPrimary = porytiles::compile(ctx, decompiledPrimary);

// Check that tiles are as expected
CHECK(compiledPrimary->tiles.size() == 5);
CHECK(compiledPrimary->tiles.size() == 16);
REQUIRE(std::filesystem::exists("res/tests/simple_metatiles_3/primary/expected_tiles.png"));
png::image<png::index_pixel> expectedPng{"res/tests/simple_metatiles_3/primary/expected_tiles.png"};
for (std::size_t tileIndex = 0; tileIndex < compiledPrimary->tiles.size(); tileIndex++) {
Expand All @@ -1729,7 +1735,7 @@ TEST_CASE("compile function should fill out primary CompiledTileset struct with
}

// Check that paletteIndexesOfTile are correct
CHECK(compiledPrimary->paletteIndexesOfTile.size() == 5);
CHECK(compiledPrimary->paletteIndexesOfTile.size() == 16);
CHECK(compiledPrimary->paletteIndexesOfTile[0] == 0);
CHECK(compiledPrimary->paletteIndexesOfTile[1] == 2);
CHECK(compiledPrimary->paletteIndexesOfTile[2] == 1);
Expand Down Expand Up @@ -1826,7 +1832,7 @@ TEST_CASE("compile function should fill out primary CompiledTileset struct with
CHECK(compiledPrimary->colorIndexMap[porytiles::rgbaToBgr(porytiles::RGBA_WHITE)] == 4);

// Check that tileIndexes is correct
CHECK(compiledPrimary->tileIndexes.size() == compiledPrimary->tiles.size());
CHECK(compiledPrimary->tileIndexes.size() == 5);
CHECK(compiledPrimary->tileIndexes[compiledPrimary->tiles[0]] == 0);
CHECK(compiledPrimary->tileIndexes[compiledPrimary->tiles[1]] == 1);
CHECK(compiledPrimary->tileIndexes[compiledPrimary->tiles[2]] == 2);
Expand Down Expand Up @@ -1985,7 +1991,7 @@ TEST_CASE("compile function should fill out secondary CompiledTileset struct wit
CHECK(compiledSecondary->colorIndexMap[porytiles::rgbaToBgr(porytiles::RGBA_GREY)] == 8);

// Check that tileIndexes is correct
CHECK(compiledSecondary->tileIndexes.size() == compiledSecondary->tiles.size());
CHECK(compiledSecondary->tileIndexes.size() == 6);
CHECK(compiledSecondary->tileIndexes[compiledSecondary->tiles[0]] == 0);
CHECK(compiledSecondary->tileIndexes[compiledSecondary->tiles[1]] == 1);
CHECK(compiledSecondary->tileIndexes[compiledSecondary->tiles[2]] == 2);
Expand Down Expand Up @@ -2052,7 +2058,7 @@ TEST_CASE("compile function should correctly compile primary set with animated t

auto compiledPrimary = porytiles::compile(ctx, decompiledPrimary);

CHECK(compiledPrimary->tiles.size() == 10);
CHECK(compiledPrimary->tiles.size() == 16);

REQUIRE(std::filesystem::exists("res/tests/anim_metatiles_1/primary/expected_tiles.png"));
png::image<png::index_pixel> expectedPng{"res/tests/anim_metatiles_1/primary/expected_tiles.png"};
Expand All @@ -2066,7 +2072,7 @@ TEST_CASE("compile function should correctly compile primary set with animated t
}

// Check that paletteIndexesOfTile is correct
CHECK(compiledPrimary->paletteIndexesOfTile.size() == 10);
CHECK(compiledPrimary->paletteIndexesOfTile.size() == 16);
CHECK(compiledPrimary->paletteIndexesOfTile[0] == 0);
CHECK(compiledPrimary->paletteIndexesOfTile[1] == 2);
CHECK(compiledPrimary->paletteIndexesOfTile[2] == 2);
Expand Down Expand Up @@ -2302,7 +2308,7 @@ TEST_CASE("compile function should correctly compile secondary set with animated

auto compiledSecondary = porytiles::compile(ctx, decompiledSecondary);

CHECK(compiledSecondary->tiles.size() == 8);
CHECK(compiledSecondary->tiles.size() == 16);

REQUIRE(std::filesystem::exists("res/tests/anim_metatiles_1/secondary/expected_tiles.png"));
png::image<png::index_pixel> expectedPng{"res/tests/anim_metatiles_1/secondary/expected_tiles.png"};
Expand All @@ -2316,7 +2322,7 @@ TEST_CASE("compile function should correctly compile secondary set with animated
}

// Check that paletteIndexesOfTile is correct
CHECK(compiledSecondary->paletteIndexesOfTile.size() == 8);
CHECK(compiledSecondary->paletteIndexesOfTile.size() == 16);
CHECK(compiledSecondary->paletteIndexesOfTile[0] == 5);
CHECK(compiledSecondary->paletteIndexesOfTile[1] == 5);
CHECK(compiledSecondary->paletteIndexesOfTile[2] == 5);
Expand Down
22 changes: 11 additions & 11 deletions src/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static void driveTilesEmit(PtContext &ctx, const CompiledTileset &compiledTiles,
// TODO : move this function's functionality into emitter
const std::size_t imageWidth = porytiles::TILE_SIDE_LENGTH * porytiles::TILES_PNG_WIDTH_IN_TILES;
const std::size_t imageHeight =
porytiles::TILE_SIDE_LENGTH * ((compiledTiles.tiles.size() / porytiles::TILES_PNG_WIDTH_IN_TILES) + 1);
porytiles::TILE_SIDE_LENGTH * ((compiledTiles.tiles.size() / porytiles::TILES_PNG_WIDTH_IN_TILES));
png::image<png::index_pixel> tilesPng{static_cast<png::uint_32>(imageWidth), static_cast<png::uint_32>(imageHeight)};

emitTilesPng(ctx, tilesPng, compiledTiles);
Expand Down Expand Up @@ -476,7 +476,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set

for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand Down Expand Up @@ -583,7 +583,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set
actualHeightInTiles = actual_flower_white_00.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -599,7 +599,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set
actualHeightInTiles = actual_flower_white_01.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -615,7 +615,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set
actualHeightInTiles = actual_flower_white_02.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -630,7 +630,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set
actualHeightInTiles = actual_water_00.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -645,7 +645,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 primary set
actualHeightInTiles = actual_water_01.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand Down Expand Up @@ -690,7 +690,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 secondary s

for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand Down Expand Up @@ -794,7 +794,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 secondary s
actualHeightInTiles = actual_flower_red_00.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -810,7 +810,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 secondary s
actualHeightInTiles = actual_flower_red_01.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand All @@ -826,7 +826,7 @@ TEST_CASE("drive should emit all expected files for anim_metatiles_2 secondary s
actualHeightInTiles = actual_flower_red_02.get_height() / porytiles::TILE_SIDE_LENGTH;
for (std::size_t tileIndex = 0; tileIndex < actualWidthInTiles * actualHeightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / actualWidthInTiles;
std::size_t tileCol = tileIndex % actualHeightInTiles;
std::size_t tileCol = tileIndex % actualWidthInTiles;
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
Expand Down
9 changes: 5 additions & 4 deletions src/emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,23 @@ void emitTilesPng(PtContext &ctx, png::image<png::index_pixel> &out, const Compi
std::size_t pixelCol = (tileCol * TILE_SIDE_LENGTH) + (pixelIndex % TILE_SIDE_LENGTH);
if (tileIndex < tileset.tiles.size()) {
const GBATile &tile = tileset.tiles.at(tileIndex);
png::byte paletteIndex = tileset.paletteIndexesOfTile.at(tileIndex);
png::byte paletteIndex = 0;
png::byte indexInPalette = tile.getPixel(pixelIndex);
switch (ctx.output.paletteMode) {
case TilesOutputPalette::GREYSCALE:
out[pixelRow][pixelCol] = indexInPalette;
break;
case TilesOutputPalette::TRUE_COLOR:
paletteIndex = tileset.paletteIndexesOfTile.at(tileIndex);
out[pixelRow][pixelCol] = (paletteIndex << 4) | indexInPalette;
break;
default:
internalerror("emitter::emitTilesPng unknown TilesPngPalMode");
}
}
else {
// Pad out transparent tiles at end of last tiles.png row
out[pixelRow][pixelCol] = 0;
internalerror(fmt::format("emitter::emitTilesPng tileIndex reached {} which is larger than size {}", tileIndex,
tileset.tiles.size()));
}
}
}
Expand Down Expand Up @@ -360,7 +361,7 @@ TEST_CASE("emitTilesPng should emit the expected tiles.png file")

const size_t imageWidth = porytiles::TILE_SIDE_LENGTH * porytiles::TILES_PNG_WIDTH_IN_TILES;
const size_t imageHeight =
porytiles::TILE_SIDE_LENGTH * ((compiledPrimary->tiles.size() / porytiles::TILES_PNG_WIDTH_IN_TILES) + 1);
porytiles::TILE_SIDE_LENGTH * ((compiledPrimary->tiles.size() / porytiles::TILES_PNG_WIDTH_IN_TILES));

png::image<png::index_pixel> outPng{static_cast<png::uint_32>(imageWidth), static_cast<png::uint_32>(imageHeight)};

Expand Down
33 changes: 30 additions & 3 deletions src/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <unordered_map>

#include "driver.h"
#include "emitter.h"
#include "errors_warnings.h"
#include "logger.h"
#include "ptcontext.h"
Expand Down Expand Up @@ -575,8 +576,30 @@ importAttributesFromCsv(PtContext &ctx, const std::unordered_map<std::string, st
return attributeMap;
}

static std::vector<Assignment> importMetatilesAndAttrs(PtContext &ctx, std::ifstream &metatilesBin,
std::ifstream &metatileAttributesBin)
static std::vector<GBATile> importCompiledTiles(PtContext &ctx, const png::image<png::index_pixel> &tiles)
{
std::vector<GBATile> gbaTiles{};

std::size_t widthInTiles = tiles.get_width() / porytiles::TILE_SIDE_LENGTH;
std::size_t heightInTiles = tiles.get_height() / porytiles::TILE_SIDE_LENGTH;

for (std::size_t tileIndex = 0; tileIndex < widthInTiles * heightInTiles; tileIndex++) {
std::size_t tileRow = tileIndex / widthInTiles;
std::size_t tileCol = tileIndex % widthInTiles;
GBATile tile{};
for (std::size_t pixelIndex = 0; pixelIndex < porytiles::TILE_NUM_PIX; pixelIndex++) {
std::size_t pixelRow = (tileRow * porytiles::TILE_SIDE_LENGTH) + (pixelIndex / porytiles::TILE_SIDE_LENGTH);
std::size_t pixelCol = (tileCol * porytiles::TILE_SIDE_LENGTH) + (pixelIndex % porytiles::TILE_SIDE_LENGTH);
tile.colorIndexes.at(pixelIndex) = tiles[pixelRow][pixelCol];
}
gbaTiles.push_back(tile);
}

return gbaTiles;
}

static std::vector<Assignment> importCompiledMetatilesAndAttrs(PtContext &ctx, std::ifstream &metatilesBin,
std::ifstream &metatileAttributesBin)
{
std::vector<Assignment> assignments{};

Expand Down Expand Up @@ -670,7 +693,8 @@ CompiledTileset importCompiledTileset(PtContext &ctx, const std::filesystem::pat
std::ifstream attributes{tilesetPath / "metatile_attributes.bin", std::ios::binary};
png::image<png::index_pixel> tilesheetPng{tilesetPath / "tiles.png"};

tileset.assignments = importMetatilesAndAttrs(ctx, metatiles, attributes);
tileset.tiles = importCompiledTiles(ctx, tilesheetPng);
tileset.assignments = importCompiledMetatilesAndAttrs(ctx, metatiles, attributes);

return tileset;
}
Expand Down Expand Up @@ -1175,6 +1199,9 @@ TEST_CASE("importCompiledTileset should import a triple layer pokeemerald tilese
porytiles::PtContext decompileCtx{};
porytiles::CompiledTileset importedTileset = porytiles::importCompiledTileset(decompileCtx, parentDir);

CHECK((compileCtx.compilerContext.resultTileset)->tiles.size() == importedTileset.tiles.size());
CHECK((compileCtx.compilerContext.resultTileset)->tiles == importedTileset.tiles);

CHECK((compileCtx.compilerContext.resultTileset)->assignments.size() == importedTileset.assignments.size());
for (std::size_t assignmentIndex = 0; assignmentIndex < importedTileset.assignments.size(); assignmentIndex++) {
const porytiles::Assignment &expectedAssignment =
Expand Down

0 comments on commit aa833ba

Please sign in to comment.