git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

commit ff5cecd2e688dda7b398e10c266a09b1d87b6a4f
parent 6760dd051288ad436bffbaee2f31b15de9d5e147
Author: bbbbbr <bbbbbr@users.noreply.github.com>
Date:   Tue, 14 Nov 2023 01:16:01 -0800

Merge pull request #594 from bbbbbr/png2asset/misc

png2asset: all tabs to spaces
Diffstat:
Mgbdk-support/png2asset/export.cpp868++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/image_data.cpp316++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/main.cpp58+++++++++++++++++++++++++++++-----------------------------
Mgbdk-support/png2asset/map_attributes.cpp162++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/maps.cpp136++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/metasprites.cpp108++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/mttile.h12++++++------
Mgbdk-support/png2asset/png2asset.cpp162++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/png2asset.h22+++++++++++-----------
Mgbdk-support/png2asset/png2asset.sln38+++++++++++++++++++-------------------
Mgbdk-support/png2asset/process_arguments.cpp472++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/process_arguments.h94++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mgbdk-support/png2asset/tiles.cpp40++++++++++++++++++++--------------------
Mgbdk-support/png2asset/vector2.h8++++----
14 files changed, 1248 insertions(+), 1248 deletions(-)

diff --git a/gbdk-support/png2asset/export.cpp b/gbdk-support/png2asset/export.cpp @@ -32,465 +32,465 @@ using namespace std; bool export_h_file( PNG2AssetData* assetData) { - FILE* file; - - file = fopen(assetData->args->output_filename_h.c_str(), "w"); - if(!file) { - printf("Error writing file: %s", assetData->args->output_filename_h.c_str()); - return false; - } - - fprintf(file, "//AUTOGENERATED FILE FROM png2asset\n"); - fprintf(file, "#ifndef METASPRITE_%s_H\n", assetData->args->data_name.c_str()); - fprintf(file, "#define METASPRITE_%s_H\n", assetData->args->data_name.c_str()); - fprintf(file, "\n"); - fprintf(file, "#include <stdint.h>\n"); - fprintf(file, "#include <gbdk/platform.h>\n"); - fprintf(file, "#include <gbdk/metasprites.h>\n"); - fprintf(file, "\n"); - if(assetData->args->use_structs) - { - if(assetData->args->export_as_map) - { - fprintf(file, "#include \"TilesInfo.h\"\n"); - fprintf(file, "#include \"MapInfo.h\"\n"); - fprintf(file, "\n"); - fprintf(file, "extern const struct TilesInfo %s_tiles_info;\n", assetData->args->data_name.c_str()); - fprintf(file, "extern const struct MapInfo %s;\n", assetData->args->data_name.c_str()); - } - else - { - fprintf(file, "#include \"MetaSpriteInfo.h\"\n"); - fprintf(file, "\n"); - fprintf(file, "extern const struct MetaSpriteInfo %s;\n", assetData->args->data_name.c_str()); - } - } - else - { - fprintf(file, "#define %s_TILE_ORIGIN %d\n", assetData->args->data_name.c_str(), assetData->args->tile_origin); - fprintf(file, "#define %s_TILE_W %d\n", assetData->args->data_name.c_str(), assetData->image.tile_w); - fprintf(file, "#define %s_TILE_H %d\n", assetData->args->data_name.c_str(), assetData->image.tile_h); - fprintf(file, "#define %s_WIDTH %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->spriteSize.width); - fprintf(file, "#define %s_HEIGHT %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->spriteSize.height); - // The TILE_COUNT calc here is referring to number of 8x8 tiles, - // so the >> 3 for each sizes axis is to get a multiplier for larger hardware sprites such as 8x16 and 16x16 - fprintf(file, "#define %s_TILE_COUNT %d\n", assetData->args->data_name.c_str(), ((unsigned int)assetData->tiles.size() - assetData->args->source_tileset_size) * (assetData->image.tile_h >> 3) * (assetData->image.tile_w >> 3)); - if(assetData->args->include_palettes) { - fprintf(file, "#define %s_PALETTE_COUNT %d\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); - fprintf(file, "#define %s_COLORS_PER_PALETTE %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.colors_per_pal); - fprintf(file, "#define %s_TOTAL_COLORS %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count); - } - - if(assetData->args->includedMapOrMetaspriteData) { - - if(assetData->args->export_as_map) - { - fprintf(file, "#define %s_MAP_ATTRIBUTES ", assetData->args->data_name.c_str()); - if(assetData->args->use_map_attributes && assetData->map_attributes.size()) - fprintf(file, "%s_map_attributes\n", assetData->args->data_name.c_str()); - else - fprintf(file, "0\n"); - - if(assetData->args->use_map_attributes) - { - int scale = assetData->args->use_2x2_map_attributes ? 2 : 1; - fprintf(file, "#define %s_MAP_ATTRIBUTES_WIDTH %d\n", assetData->args->data_name.c_str(), (int)(scale * assetData->args->map_attributes_size.width)); - fprintf(file, "#define %s_MAP_ATTRIBUTES_HEIGHT %d\n", assetData->args->data_name.c_str(), (int)(scale * assetData->args->map_attributes_size.height)); - fprintf(file, "#define %s_MAP_ATTRIBUTES_PACKED_WIDTH %d\n", assetData->args->data_name.c_str(), (int)assetData->args->map_attributes_packed_size.width); - fprintf(file, "#define %s_MAP_ATTRIBUTES_PACKED_HEIGHT %d\n", assetData->args->data_name.c_str(), (int)assetData->args->map_attributes_packed_size.height); - } - - if(assetData->args->use_structs) - { - fprintf(file, "#define %s_TILE_PALS ", assetData->args->data_name.c_str()); - if(assetData->args->use_map_attributes) - fprintf(file, "0\n"); - else - fprintf(file, "%s_tile_pals\n", assetData->args->data_name.c_str()); - } - } - else - { - fprintf(file, "#define %s_PIVOT_X %d\n", assetData->args->data_name.c_str(), assetData->args->pivot.x); - fprintf(file, "#define %s_PIVOT_Y %d\n", assetData->args->data_name.c_str(), assetData->args->pivot.y); - fprintf(file, "#define %s_PIVOT_W %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->pivot.width); - fprintf(file, "#define %s_PIVOT_H %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->pivot.height); - } - } - fprintf(file, "\n"); - fprintf(file, "BANKREF_EXTERN(%s)\n", assetData->args->data_name.c_str()); - fprintf(file, "\n"); - - // If we are not using a source tileset, or if we have extra palettes defined - if(assetData->args->include_palettes && (assetData->image.total_color_count - assetData->args->source_total_color_count > 0 || assetData->args->source_tilesets.size()==0)) { - fprintf(file, "extern const palette_color_t %s_palettes[%d];\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count - (unsigned int)assetData->args->source_total_color_count); - } - if(assetData->args->includeTileData) { - fprintf(file, "extern const uint8_t %s_tiles[%d];\n", assetData->args->data_name.c_str(), (unsigned int)((assetData->tiles.size() - assetData->args->source_tileset_size) * (assetData->image.tile_w * assetData->image.tile_h * assetData->args->bpp / 8))); - } - - fprintf(file, "\n"); - if(assetData->args->includedMapOrMetaspriteData) { - if(assetData->args->export_as_map) - { - fprintf(file, "extern const unsigned char %s_map[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map).size()); - - if(assetData->args->use_map_attributes && assetData->map_attributes.size()) { - fprintf(file, "extern const unsigned char %s_map_attributes[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map_attributes).size()); - } - else - { - // Some platforms (like SMS/GG) encode attributes as part of map - // For compatibility, add a define that makes _map_attributes equal _map, - // so that set_bkg_attributes can work the same on these platforms - fprintf(file, "#define %s_map_attributes %s_map\n", assetData->args->data_name.c_str(), assetData->args->data_name.c_str()); - } - if(!assetData->args->use_map_attributes && (assetData->args->includeTileData) && (assetData->args->use_structs)) { - fprintf(file, "extern const unsigned char* %s_tile_pals[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->tiles).size()); - } - } - else - { - fprintf(file, "extern const metasprite_t* const %s_metasprites[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->sprites.size())); - } - } - } - fprintf(file, "\n"); - fprintf(file, "#endif\n"); - - - fclose(file); - // END: Output .h FILE - - return true; // success + FILE* file; + + file = fopen(assetData->args->output_filename_h.c_str(), "w"); + if(!file) { + printf("Error writing file: %s", assetData->args->output_filename_h.c_str()); + return false; + } + + fprintf(file, "//AUTOGENERATED FILE FROM png2asset\n"); + fprintf(file, "#ifndef METASPRITE_%s_H\n", assetData->args->data_name.c_str()); + fprintf(file, "#define METASPRITE_%s_H\n", assetData->args->data_name.c_str()); + fprintf(file, "\n"); + fprintf(file, "#include <stdint.h>\n"); + fprintf(file, "#include <gbdk/platform.h>\n"); + fprintf(file, "#include <gbdk/metasprites.h>\n"); + fprintf(file, "\n"); + if(assetData->args->use_structs) + { + if(assetData->args->export_as_map) + { + fprintf(file, "#include \"TilesInfo.h\"\n"); + fprintf(file, "#include \"MapInfo.h\"\n"); + fprintf(file, "\n"); + fprintf(file, "extern const struct TilesInfo %s_tiles_info;\n", assetData->args->data_name.c_str()); + fprintf(file, "extern const struct MapInfo %s;\n", assetData->args->data_name.c_str()); + } + else + { + fprintf(file, "#include \"MetaSpriteInfo.h\"\n"); + fprintf(file, "\n"); + fprintf(file, "extern const struct MetaSpriteInfo %s;\n", assetData->args->data_name.c_str()); + } + } + else + { + fprintf(file, "#define %s_TILE_ORIGIN %d\n", assetData->args->data_name.c_str(), assetData->args->tile_origin); + fprintf(file, "#define %s_TILE_W %d\n", assetData->args->data_name.c_str(), assetData->image.tile_w); + fprintf(file, "#define %s_TILE_H %d\n", assetData->args->data_name.c_str(), assetData->image.tile_h); + fprintf(file, "#define %s_WIDTH %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->spriteSize.width); + fprintf(file, "#define %s_HEIGHT %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->spriteSize.height); + // The TILE_COUNT calc here is referring to number of 8x8 tiles, + // so the >> 3 for each sizes axis is to get a multiplier for larger hardware sprites such as 8x16 and 16x16 + fprintf(file, "#define %s_TILE_COUNT %d\n", assetData->args->data_name.c_str(), ((unsigned int)assetData->tiles.size() - assetData->args->source_tileset_size) * (assetData->image.tile_h >> 3) * (assetData->image.tile_w >> 3)); + if(assetData->args->include_palettes) { + fprintf(file, "#define %s_PALETTE_COUNT %d\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); + fprintf(file, "#define %s_COLORS_PER_PALETTE %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.colors_per_pal); + fprintf(file, "#define %s_TOTAL_COLORS %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count); + } + + if(assetData->args->includedMapOrMetaspriteData) { + + if(assetData->args->export_as_map) + { + fprintf(file, "#define %s_MAP_ATTRIBUTES ", assetData->args->data_name.c_str()); + if(assetData->args->use_map_attributes && assetData->map_attributes.size()) + fprintf(file, "%s_map_attributes\n", assetData->args->data_name.c_str()); + else + fprintf(file, "0\n"); + + if(assetData->args->use_map_attributes) + { + int scale = assetData->args->use_2x2_map_attributes ? 2 : 1; + fprintf(file, "#define %s_MAP_ATTRIBUTES_WIDTH %d\n", assetData->args->data_name.c_str(), (int)(scale * assetData->args->map_attributes_size.width)); + fprintf(file, "#define %s_MAP_ATTRIBUTES_HEIGHT %d\n", assetData->args->data_name.c_str(), (int)(scale * assetData->args->map_attributes_size.height)); + fprintf(file, "#define %s_MAP_ATTRIBUTES_PACKED_WIDTH %d\n", assetData->args->data_name.c_str(), (int)assetData->args->map_attributes_packed_size.width); + fprintf(file, "#define %s_MAP_ATTRIBUTES_PACKED_HEIGHT %d\n", assetData->args->data_name.c_str(), (int)assetData->args->map_attributes_packed_size.height); + } + + if(assetData->args->use_structs) + { + fprintf(file, "#define %s_TILE_PALS ", assetData->args->data_name.c_str()); + if(assetData->args->use_map_attributes) + fprintf(file, "0\n"); + else + fprintf(file, "%s_tile_pals\n", assetData->args->data_name.c_str()); + } + } + else + { + fprintf(file, "#define %s_PIVOT_X %d\n", assetData->args->data_name.c_str(), assetData->args->pivot.x); + fprintf(file, "#define %s_PIVOT_Y %d\n", assetData->args->data_name.c_str(), assetData->args->pivot.y); + fprintf(file, "#define %s_PIVOT_W %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->pivot.width); + fprintf(file, "#define %s_PIVOT_H %d\n", assetData->args->data_name.c_str(), (unsigned int)assetData->args->pivot.height); + } + } + fprintf(file, "\n"); + fprintf(file, "BANKREF_EXTERN(%s)\n", assetData->args->data_name.c_str()); + fprintf(file, "\n"); + + // If we are not using a source tileset, or if we have extra palettes defined + if(assetData->args->include_palettes && (assetData->image.total_color_count - assetData->args->source_total_color_count > 0 || assetData->args->source_tilesets.size()==0)) { + fprintf(file, "extern const palette_color_t %s_palettes[%d];\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count - (unsigned int)assetData->args->source_total_color_count); + } + if(assetData->args->includeTileData) { + fprintf(file, "extern const uint8_t %s_tiles[%d];\n", assetData->args->data_name.c_str(), (unsigned int)((assetData->tiles.size() - assetData->args->source_tileset_size) * (assetData->image.tile_w * assetData->image.tile_h * assetData->args->bpp / 8))); + } + + fprintf(file, "\n"); + if(assetData->args->includedMapOrMetaspriteData) { + if(assetData->args->export_as_map) + { + fprintf(file, "extern const unsigned char %s_map[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map).size()); + + if(assetData->args->use_map_attributes && assetData->map_attributes.size()) { + fprintf(file, "extern const unsigned char %s_map_attributes[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map_attributes).size()); + } + else + { + // Some platforms (like SMS/GG) encode attributes as part of map + // For compatibility, add a define that makes _map_attributes equal _map, + // so that set_bkg_attributes can work the same on these platforms + fprintf(file, "#define %s_map_attributes %s_map\n", assetData->args->data_name.c_str(), assetData->args->data_name.c_str()); + } + if(!assetData->args->use_map_attributes && (assetData->args->includeTileData) && (assetData->args->use_structs)) { + fprintf(file, "extern const unsigned char* %s_tile_pals[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->tiles).size()); + } + } + else + { + fprintf(file, "extern const metasprite_t* const %s_metasprites[%d];\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->sprites.size())); + } + } + } + fprintf(file, "\n"); + fprintf(file, "#endif\n"); + + + fclose(file); + // END: Output .h FILE + + return true; // success } bool export_c_file( PNG2AssetData* assetData) { - FILE* file; - - file = fopen(assetData->args->output_filename.c_str(), "w"); - if(!file) { - printf("Error writing file: %s", assetData->args->output_filename.c_str()); - return false; - } - - if(assetData->args->bank >= 0) fprintf(file, "#pragma bank %d\n\n", assetData->args->bank); - - fprintf(file, "//AUTOGENERATED FILE FROM png2asset\n\n"); - - fprintf(file, "#include <stdint.h>\n"); - fprintf(file, "#include <gbdk/platform.h>\n"); - fprintf(file, "#include <gbdk/metasprites.h>\n"); - fprintf(file, "\n"); - - fprintf(file, "BANKREF(%s)\n\n", assetData->args->data_name.c_str()); - - // Are we not using a source tileset, or do we have extra colors - if(assetData->args->include_palettes && (assetData->image.total_color_count - assetData->args->source_total_color_count > 0 || !assetData->args->source_tilesets.size() == 0)) { - - // Subtract however many palettes we had in the source tileset - fprintf(file, "const palette_color_t %s_palettes[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count - (unsigned int)assetData->args->source_total_color_count); - - // Offset by however many palettes we had in the source tileset - for(size_t i = assetData->args->source_total_color_count / assetData->image.colors_per_pal; i < assetData->image.total_color_count / assetData->image.colors_per_pal; ++i) - { - if(i != 0) - fprintf(file, ",\n"); - fprintf(file, "\t"); - - unsigned char* pal_ptr = &assetData->image.palette[i * (assetData->image.colors_per_pal * RGBA32_SZ)]; - for(int c = 0; c < (int)assetData->image.colors_per_pal; ++c, pal_ptr += RGBA32_SZ) - { - size_t rgb222 = (((pal_ptr[2] >> 6) & 0x3) << 4) | - (((pal_ptr[1] >> 6) & 0x3) << 2) | - (((pal_ptr[0] >> 6) & 0x3) << 0); - if(assetData->args->convert_rgb_to_nes) { - fprintf(file, "0x%0X", rgb_to_nes[rgb222]); - } - else - fprintf(file, "RGB8(%3d,%3d,%3d)", pal_ptr[0], pal_ptr[1], pal_ptr[2]); - if(c != (int)assetData->image.colors_per_pal - 1) - fprintf(file, ", "); - // Line break every 4 color entries, to keep line width down - if(((c + 1) % 4) == 0) - fprintf(file, "\n\t"); - } - } - fprintf(file, "\n};\n"); - } - - if(assetData->args->includeTileData) { - fprintf(file, "\n"); - fprintf(file, "const uint8_t %s_tiles[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)((assetData->tiles.size() - assetData->args->source_tileset_size) * assetData->image.tile_w * assetData->image.tile_h * assetData->args->bpp / 8)); - fprintf(file, "\t"); - for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) - { - - int line_break = 1; // Start with 1 to prevent line break on first iteration - vector< unsigned char > packed_data = (*it).GetPackedData(assetData->args->pack_mode, assetData->image.tile_w, assetData->image.tile_h, assetData->args->bpp); - for(vector< unsigned char >::iterator it2 = packed_data.begin(); it2 != packed_data.end(); ++it2) - { - fprintf(file, "0x%02x", (*it2)); - if((it + 1) != assetData->tiles.end() || (it2 + 1) != packed_data.end()) - fprintf(file, ","); - // Add a line break after each 8x8 tile - if(((line_break++) % (8 / assetData->args->bpp)) == 0) - fprintf(file, "\n\t"); - } - - if((!assetData->args->export_as_map) && (it != assetData->tiles.end())) - fprintf(file, "\n"); - } - fprintf(file, "};\n\n"); - } - - if(assetData->args->includedMapOrMetaspriteData) { - - if(!assetData->args->export_as_map) - { - for(vector< MetaSprite >::iterator it = assetData->sprites.begin(); it != assetData->sprites.end(); ++it) - { - fprintf(file, "const metasprite_t %s_metasprite%d[] = {\n", assetData->args->data_name.c_str(), (int)(it - assetData->sprites.begin())); - for(MetaSprite::iterator it2 = (*it).begin(); it2 != (*it).end(); ++it2) - { - int pal_idx = (*it2).props & 0xF; - int flip_x = ((*it2).props >> 5) & 1; - int flip_y = ((*it2).props >> 6) & 1; - fprintf(file, - "\tMETASPR_ITEM(%d, %d, %d, S_PAL(%d)%s%s),\n", - (*it2).offset_y, - (*it2).offset_x, - (*it2).offset_idx, - pal_idx, - flip_x ? " | S_FLIPX" : "", - flip_y ? " | S_FLIPY" : ""); - } - fprintf(file, "\tMETASPR_TERM\n"); - fprintf(file, "};\n\n"); - } - - fprintf(file, "const metasprite_t* const %s_metasprites[%d] = {\n\t", assetData->args->data_name.c_str(), (unsigned int)(assetData->sprites.size())); - for(vector< MetaSprite >::iterator it = assetData->sprites.begin(); it != assetData->sprites.end(); ++it) - { - fprintf(file, "%s_metasprite%d", assetData->args->data_name.c_str(), (int)(it - assetData->sprites.begin())); - if(it + 1 != assetData->sprites.end()) - fprintf(file, ", "); - } - fprintf(file, "\n};\n"); - - if(assetData->args->use_structs) - { - fprintf(file, "\n"); - fprintf(file, "#include \"MetaSpriteInfo.h\"\n"); - fprintf(file, "const struct MetaSpriteInfo %s = {\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //width\n", (unsigned int)assetData->args->pivot.width); - fprintf(file, "\t%d, //height\n", (unsigned int)assetData->args->pivot.height); - fprintf(file, "\t%d, //num tiles\n", (unsigned int)assetData->tiles.size() * (assetData->image.tile_h >> 3)); - fprintf(file, "\t%s_tiles, //tiles\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //num palettes\n", (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); - fprintf(file, "\t%s_palettes, //CGB palette\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //num sprites\n", (unsigned int)assetData->sprites.size()); - fprintf(file, "\t%s_metasprites, //metasprites\n", assetData->args->data_name.c_str()); - fprintf(file, "};\n"); - } - } - else - { - if(assetData->args->includeTileData) { - if(assetData->args->use_structs) - { - //Export tiles pals (if any) - if(!assetData->args->use_map_attributes) - { - fprintf(file, "\n"); - fprintf(file, "const uint8_t %s_tile_pals[%d] = {\n\t", assetData->args->data_name.c_str(), (unsigned int)(assetData->tiles.size()) - assetData->args->source_tileset_size); - for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) - { - if(it != assetData->tiles.begin()) - fprintf(file, ", "); - fprintf(file, "%d", it->pal); - } - fprintf(file, "\n};\n"); - } - //Export Tiles Info - fprintf(file, "\n"); - fprintf(file, "#include \"TilesInfo.h\"\n"); - fprintf(file, "BANKREF(%s_tiles_info)\n", assetData->args->data_name.c_str()); - fprintf(file, "const struct TilesInfo %s_tiles_info = {\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //num tiles\n", (unsigned int)assetData->tiles.size() * (assetData->image.tile_h >> 3)); - fprintf(file, "\t%s_tiles, //tiles\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //num palettes\n", (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); - fprintf(file, "\t%s_palettes, //palettes\n", assetData->args->data_name.c_str()); - if(!assetData->args->use_map_attributes) - fprintf(file, "\t%s_tile_pals, //tile palettes\n", assetData->args->data_name.c_str()); - else - fprintf(file, "\t0 //tile palettes\n"); - fprintf(file, "};\n"); - } - } - - //Export map - fprintf(file, "\n"); - fprintf(file, "const unsigned char %s_map[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map.size())); - // TODO: These hardwired "/ 8" should be using " / assetData->image.tile_w" and "_h" - // TODO: Should also be converted to using args.map_entry_size_bytes - size_t line_size = assetData->map.size() / (assetData->image.h / 8); - if(assetData->args->output_transposed) { - - for(size_t i = 0; i < line_size; ++i) - { - fprintf(file, "\t"); - for(size_t j = 0; j < assetData->image.h / 8; ++j) - { - fprintf(file, "0x%02x,", assetData->map[j * line_size + i]); - } - fprintf(file, "\n"); - } - } - else { - - for(size_t j = 0; j < assetData->image.h / 8; ++j) - { - fprintf(file, "\t"); - for(size_t i = 0; i < line_size; ++i) - { - fprintf(file, "0x%02x,", assetData->map[j * line_size + i]); - } - fprintf(file, "\n"); - } - } - fprintf(file, "};\n"); - - - //Export map attributes (if any) - if(assetData->args->use_map_attributes && assetData->map_attributes.size()) - { - fprintf(file, "\n"); - fprintf(file, "const unsigned char %s_map_attributes[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map_attributes.size())); - if(assetData->args->output_transposed) { - for(size_t i = 0; i < assetData->args->map_attributes_packed_size.width; ++i) - { - fprintf(file, "\t"); - for(size_t j = 0; j < assetData->args->map_attributes_packed_size.height; ++j) - { - fprintf(file, "0x%02x,", assetData->map_attributes[j * assetData->args->map_attributes_packed_size.width + i]); - } - fprintf(file, "\n"); - } - } - else { - for(size_t j = 0; j < assetData->args->map_attributes_packed_size.height; ++j) - { - fprintf(file, "\t"); - for(size_t i = 0; i < assetData->args->map_attributes_packed_size.width; ++i) - { - fprintf(file, "0x%02x,", assetData->map_attributes[j * assetData->args->map_attributes_packed_size.width + i]); - } - fprintf(file, "\n"); - } - } - - fprintf(file, "};\n"); - } - - if(assetData->args->use_structs) - { - //Export Map Info - fprintf(file, "\n"); - fprintf(file, "#include \"MapInfo.h\"\n"); - fprintf(file, "BANKREF_EXTERN(%s_tiles_info)\n", assetData->args->data_name.c_str()); - fprintf(file, "const struct MapInfo %s = {\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%s_map, //map\n", assetData->args->data_name.c_str()); - fprintf(file, "\t%d, //with\n", assetData->image.w >> 3); - fprintf(file, "\t%d, //height\n", assetData->image.h >> 3); - if(assetData->args->use_map_attributes && assetData->map_attributes.size()) - fprintf(file, "\t%s_map_attributes, //map attributes\n", assetData->args->data_name.c_str()); - else - fprintf(file, "\t%s, //map attributes\n", "0"); - fprintf(file, "\tBANK(%s_tiles_info), //tiles bank\n", assetData->args->data_name.c_str()); - fprintf(file, "\t&%s_tiles_info, //tiles info\n", assetData->args->data_name.c_str()); - fprintf(file, "};\n"); - } - } - } - - fclose(file); - - return true; // success + FILE* file; + + file = fopen(assetData->args->output_filename.c_str(), "w"); + if(!file) { + printf("Error writing file: %s", assetData->args->output_filename.c_str()); + return false; + } + + if(assetData->args->bank >= 0) fprintf(file, "#pragma bank %d\n\n", assetData->args->bank); + + fprintf(file, "//AUTOGENERATED FILE FROM png2asset\n\n"); + + fprintf(file, "#include <stdint.h>\n"); + fprintf(file, "#include <gbdk/platform.h>\n"); + fprintf(file, "#include <gbdk/metasprites.h>\n"); + fprintf(file, "\n"); + + fprintf(file, "BANKREF(%s)\n\n", assetData->args->data_name.c_str()); + + // Are we not using a source tileset, or do we have extra colors + if(assetData->args->include_palettes && (assetData->image.total_color_count - assetData->args->source_total_color_count > 0 || !assetData->args->source_tilesets.size() == 0)) { + + // Subtract however many palettes we had in the source tileset + fprintf(file, "const palette_color_t %s_palettes[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)assetData->image.total_color_count - (unsigned int)assetData->args->source_total_color_count); + + // Offset by however many palettes we had in the source tileset + for(size_t i = assetData->args->source_total_color_count / assetData->image.colors_per_pal; i < assetData->image.total_color_count / assetData->image.colors_per_pal; ++i) + { + if(i != 0) + fprintf(file, ",\n"); + fprintf(file, "\t"); + + unsigned char* pal_ptr = &assetData->image.palette[i * (assetData->image.colors_per_pal * RGBA32_SZ)]; + for(int c = 0; c < (int)assetData->image.colors_per_pal; ++c, pal_ptr += RGBA32_SZ) + { + size_t rgb222 = (((pal_ptr[2] >> 6) & 0x3) << 4) | + (((pal_ptr[1] >> 6) & 0x3) << 2) | + (((pal_ptr[0] >> 6) & 0x3) << 0); + if(assetData->args->convert_rgb_to_nes) { + fprintf(file, "0x%0X", rgb_to_nes[rgb222]); + } + else + fprintf(file, "RGB8(%3d,%3d,%3d)", pal_ptr[0], pal_ptr[1], pal_ptr[2]); + if(c != (int)assetData->image.colors_per_pal - 1) + fprintf(file, ", "); + // Line break every 4 color entries, to keep line width down + if(((c + 1) % 4) == 0) + fprintf(file, "\n\t"); + } + } + fprintf(file, "\n};\n"); + } + + if(assetData->args->includeTileData) { + fprintf(file, "\n"); + fprintf(file, "const uint8_t %s_tiles[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)((assetData->tiles.size() - assetData->args->source_tileset_size) * assetData->image.tile_w * assetData->image.tile_h * assetData->args->bpp / 8)); + fprintf(file, "\t"); + for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) + { + + int line_break = 1; // Start with 1 to prevent line break on first iteration + vector< unsigned char > packed_data = (*it).GetPackedData(assetData->args->pack_mode, assetData->image.tile_w, assetData->image.tile_h, assetData->args->bpp); + for(vector< unsigned char >::iterator it2 = packed_data.begin(); it2 != packed_data.end(); ++it2) + { + fprintf(file, "0x%02x", (*it2)); + if((it + 1) != assetData->tiles.end() || (it2 + 1) != packed_data.end()) + fprintf(file, ","); + // Add a line break after each 8x8 tile + if(((line_break++) % (8 / assetData->args->bpp)) == 0) + fprintf(file, "\n\t"); + } + + if((!assetData->args->export_as_map) && (it != assetData->tiles.end())) + fprintf(file, "\n"); + } + fprintf(file, "};\n\n"); + } + + if(assetData->args->includedMapOrMetaspriteData) { + + if(!assetData->args->export_as_map) + { + for(vector< MetaSprite >::iterator it = assetData->sprites.begin(); it != assetData->sprites.end(); ++it) + { + fprintf(file, "const metasprite_t %s_metasprite%d[] = {\n", assetData->args->data_name.c_str(), (int)(it - assetData->sprites.begin())); + for(MetaSprite::iterator it2 = (*it).begin(); it2 != (*it).end(); ++it2) + { + int pal_idx = (*it2).props & 0xF; + int flip_x = ((*it2).props >> 5) & 1; + int flip_y = ((*it2).props >> 6) & 1; + fprintf(file, + "\tMETASPR_ITEM(%d, %d, %d, S_PAL(%d)%s%s),\n", + (*it2).offset_y, + (*it2).offset_x, + (*it2).offset_idx, + pal_idx, + flip_x ? " | S_FLIPX" : "", + flip_y ? " | S_FLIPY" : ""); + } + fprintf(file, "\tMETASPR_TERM\n"); + fprintf(file, "};\n\n"); + } + + fprintf(file, "const metasprite_t* const %s_metasprites[%d] = {\n\t", assetData->args->data_name.c_str(), (unsigned int)(assetData->sprites.size())); + for(vector< MetaSprite >::iterator it = assetData->sprites.begin(); it != assetData->sprites.end(); ++it) + { + fprintf(file, "%s_metasprite%d", assetData->args->data_name.c_str(), (int)(it - assetData->sprites.begin())); + if(it + 1 != assetData->sprites.end()) + fprintf(file, ", "); + } + fprintf(file, "\n};\n"); + + if(assetData->args->use_structs) + { + fprintf(file, "\n"); + fprintf(file, "#include \"MetaSpriteInfo.h\"\n"); + fprintf(file, "const struct MetaSpriteInfo %s = {\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //width\n", (unsigned int)assetData->args->pivot.width); + fprintf(file, "\t%d, //height\n", (unsigned int)assetData->args->pivot.height); + fprintf(file, "\t%d, //num tiles\n", (unsigned int)assetData->tiles.size() * (assetData->image.tile_h >> 3)); + fprintf(file, "\t%s_tiles, //tiles\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //num palettes\n", (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); + fprintf(file, "\t%s_palettes, //CGB palette\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //num sprites\n", (unsigned int)assetData->sprites.size()); + fprintf(file, "\t%s_metasprites, //metasprites\n", assetData->args->data_name.c_str()); + fprintf(file, "};\n"); + } + } + else + { + if(assetData->args->includeTileData) { + if(assetData->args->use_structs) + { + //Export tiles pals (if any) + if(!assetData->args->use_map_attributes) + { + fprintf(file, "\n"); + fprintf(file, "const uint8_t %s_tile_pals[%d] = {\n\t", assetData->args->data_name.c_str(), (unsigned int)(assetData->tiles.size()) - assetData->args->source_tileset_size); + for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) + { + if(it != assetData->tiles.begin()) + fprintf(file, ", "); + fprintf(file, "%d", it->pal); + } + fprintf(file, "\n};\n"); + } + //Export Tiles Info + fprintf(file, "\n"); + fprintf(file, "#include \"TilesInfo.h\"\n"); + fprintf(file, "BANKREF(%s_tiles_info)\n", assetData->args->data_name.c_str()); + fprintf(file, "const struct TilesInfo %s_tiles_info = {\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //num tiles\n", (unsigned int)assetData->tiles.size() * (assetData->image.tile_h >> 3)); + fprintf(file, "\t%s_tiles, //tiles\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //num palettes\n", (unsigned int)(assetData->image.total_color_count / assetData->image.colors_per_pal)); + fprintf(file, "\t%s_palettes, //palettes\n", assetData->args->data_name.c_str()); + if(!assetData->args->use_map_attributes) + fprintf(file, "\t%s_tile_pals, //tile palettes\n", assetData->args->data_name.c_str()); + else + fprintf(file, "\t0 //tile palettes\n"); + fprintf(file, "};\n"); + } + } + + //Export map + fprintf(file, "\n"); + fprintf(file, "const unsigned char %s_map[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map.size())); + // TODO: These hardwired "/ 8" should be using " / assetData->image.tile_w" and "_h" + // TODO: Should also be converted to using args.map_entry_size_bytes + size_t line_size = assetData->map.size() / (assetData->image.h / 8); + if(assetData->args->output_transposed) { + + for(size_t i = 0; i < line_size; ++i) + { + fprintf(file, "\t"); + for(size_t j = 0; j < assetData->image.h / 8; ++j) + { + fprintf(file, "0x%02x,", assetData->map[j * line_size + i]); + } + fprintf(file, "\n"); + } + } + else { + + for(size_t j = 0; j < assetData->image.h / 8; ++j) + { + fprintf(file, "\t"); + for(size_t i = 0; i < line_size; ++i) + { + fprintf(file, "0x%02x,", assetData->map[j * line_size + i]); + } + fprintf(file, "\n"); + } + } + fprintf(file, "};\n"); + + + //Export map attributes (if any) + if(assetData->args->use_map_attributes && assetData->map_attributes.size()) + { + fprintf(file, "\n"); + fprintf(file, "const unsigned char %s_map_attributes[%d] = {\n", assetData->args->data_name.c_str(), (unsigned int)(assetData->map_attributes.size())); + if(assetData->args->output_transposed) { + for(size_t i = 0; i < assetData->args->map_attributes_packed_size.width; ++i) + { + fprintf(file, "\t"); + for(size_t j = 0; j < assetData->args->map_attributes_packed_size.height; ++j) + { + fprintf(file, "0x%02x,", assetData->map_attributes[j * assetData->args->map_attributes_packed_size.width + i]); + } + fprintf(file, "\n"); + } + } + else { + for(size_t j = 0; j < assetData->args->map_attributes_packed_size.height; ++j) + { + fprintf(file, "\t"); + for(size_t i = 0; i < assetData->args->map_attributes_packed_size.width; ++i) + { + fprintf(file, "0x%02x,", assetData->map_attributes[j * assetData->args->map_attributes_packed_size.width + i]); + } + fprintf(file, "\n"); + } + } + + fprintf(file, "};\n"); + } + + if(assetData->args->use_structs) + { + //Export Map Info + fprintf(file, "\n"); + fprintf(file, "#include \"MapInfo.h\"\n"); + fprintf(file, "BANKREF_EXTERN(%s_tiles_info)\n", assetData->args->data_name.c_str()); + fprintf(file, "const struct MapInfo %s = {\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%s_map, //map\n", assetData->args->data_name.c_str()); + fprintf(file, "\t%d, //with\n", assetData->image.w >> 3); + fprintf(file, "\t%d, //height\n", assetData->image.h >> 3); + if(assetData->args->use_map_attributes && assetData->map_attributes.size()) + fprintf(file, "\t%s_map_attributes, //map attributes\n", assetData->args->data_name.c_str()); + else + fprintf(file, "\t%s, //map attributes\n", "0"); + fprintf(file, "\tBANK(%s_tiles_info), //tiles bank\n", assetData->args->data_name.c_str()); + fprintf(file, "\t&%s_tiles_info, //tiles info\n", assetData->args->data_name.c_str()); + fprintf(file, "};\n"); + } + } + } + + fclose(file); + + return true; // success } bool export_map_binary( PNG2AssetData* assetData) { - std::ofstream mapBinaryFile, mapAttributesBinaryfile, tilesBinaryFile; + std::ofstream mapBinaryFile, mapAttributesBinaryfile, tilesBinaryFile; - if (assetData->args->includeTileData) { - tilesBinaryFile.open(assetData->args->output_filename_tiles_bin, std::ios_base::binary); + if (assetData->args->includeTileData) { + tilesBinaryFile.open(assetData->args->output_filename_tiles_bin, std::ios_base::binary); - for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) - { + for(vector< Tile >::iterator it = assetData->tiles.begin() + assetData->args->source_tileset_size; it != assetData->tiles.end(); ++it) + { - vector< unsigned char > packed_data = (*it).GetPackedData(assetData->args->pack_mode, assetData->image.tile_w, assetData->image.tile_h, assetData->args->bpp); - for(vector< unsigned char >::iterator it2 = packed_data.begin(); it2 != packed_data.end(); ++it2) - { + vector< unsigned char > packed_data = (*it).GetPackedData(assetData->args->pack_mode, assetData->image.tile_w, assetData->image.tile_h, assetData->args->bpp); + for(vector< unsigned char >::iterator it2 = packed_data.begin(); it2 != packed_data.end(); ++it2) + { - const char chars[] = { (const char)(*it2) }; - tilesBinaryFile.write(chars, 1); - } + const char chars[] = { (const char)(*it2) }; + tilesBinaryFile.write(chars, 1); + } - } - // Finalize the files - tilesBinaryFile.close(); - } + } + // Finalize the files + tilesBinaryFile.close(); + } - if (assetData->args->includedMapOrMetaspriteData) { - mapBinaryFile.open(assetData->args->output_filename_bin, std::ios_base::binary); + if (assetData->args->includedMapOrMetaspriteData) { + mapBinaryFile.open(assetData->args->output_filename_bin, std::ios_base::binary); - // Open our file for writing attributes if specified - if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { - mapAttributesBinaryfile.open(assetData->args->output_filename_attributes_bin, std::ios_base::binary); - } + // Open our file for writing attributes if specified + if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { + mapAttributesBinaryfile.open(assetData->args->output_filename_attributes_bin, std::ios_base::binary); + } - int columns = assetData->image.w >> 3; - int rows = assetData->image.h >> 3; + int columns = assetData->image.w >> 3; + int rows = assetData->image.h >> 3; - // If we want the values to be column-by-column - if(assetData->args->output_transposed) { + // If we want the values to be column-by-column + if(assetData->args->output_transposed) { - int map_entry_size = assetData->args->map_entry_size_bytes; - // Swap the column/row for loops - for(int column = 0; column < columns; column++) { - for(int row = 0; row < rows; ++row) { + int map_entry_size = assetData->args->map_entry_size_bytes; + // Swap the column/row for loops + for(int column = 0; column < columns; column++) { + for(int row = 0; row < rows; ++row) { - int tile = (column + row * columns) * map_entry_size; + int tile = (column + row * columns) * map_entry_size; - // Write map items column-by-column - mapBinaryFile.write( (const char *) &(assetData->map[tile]), map_entry_size); + // Write map items column-by-column + mapBinaryFile.write( (const char *) &(assetData->map[tile]), map_entry_size); - if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { - mapAttributesBinaryfile.write( (const char*) &(assetData->map_attributes[tile]), map_entry_size); - } - } - } - } - else { - // Write the arrays as-is, row-by-row - mapBinaryFile.write((const char*)(&assetData->map[0]), assetData->map.size()); + if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { + mapAttributesBinaryfile.write( (const char*) &(assetData->map_attributes[tile]), map_entry_size); + } + } + } + } + else { + // Write the arrays as-is, row-by-row + mapBinaryFile.write((const char*)(&assetData->map[0]), assetData->map.size()); - if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { - mapAttributesBinaryfile.write((const char*)(&assetData->map_attributes[0]), assetData->map_attributes.size()); - } - } - // Finalize the files - mapBinaryFile.close(); - if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { - mapAttributesBinaryfile.close(); - } - } + if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { + mapAttributesBinaryfile.write((const char*)(&assetData->map_attributes[0]), assetData->map_attributes.size()); + } + } + // Finalize the files + mapBinaryFile.close(); + if (assetData->args->use_map_attributes && assetData->map_attributes.size()) { + mapAttributesBinaryfile.close(); + } + } - return true; // success + return true; // success } diff --git a/gbdk-support/png2asset/image_data.cpp b/gbdk-support/png2asset/image_data.cpp @@ -30,192 +30,192 @@ void loadFile(vector<unsigned char>& buffer, const std::string& filename); int ReadImageData_KeepPaletteOrder( PNG2AssetData* assetData, string input_filename) { - //load and decode png - vector<unsigned char> buffer; - lodepng::load_file(buffer, input_filename); - lodepng::State state; - - - //Calling with keep_palette_order means - //-The image should be png indexed (1-8 bits per pixel) - //-For CGB: Each 4 colors define a gbc palette, the first color is the transparent one - //-Each rectangle with dimension(tile_w, tile_h) in the image has colors from one of those palettes only - state.info_raw.colortype = LCT_PALETTE; - state.info_raw.bitdepth = 8; - - // * Do *NOT* turn color_convert ON here. - // When source PNG is indexed with bit depth was less than 8 bits per pixel then - // color_convert may mangle the packed indexed values. Instead manually unpack them. - // - // This is necessary since some PNG encoders will use the minimum possible number of bits. - // For example 2 colors in the palette -> 1bpp -> 8 pixels per byte in the decoded image. - // Also see below about requirement to use palette from source image - state.decoder.color_convert = false; - - unsigned error = lodepng::decode(assetData->image.data, assetData->image.w, assetData->image.h, state, buffer); - // Unpack the image if needed. Also checks and errors on incompatible palette type if needed - if(!image_indexed_ensure_8bpp(assetData->image.data, assetData->image.w, assetData->image.h, (int)state.info_png.color.bitdepth, (int)state.info_png.color.colortype)) - return 1; - else if(error) { - printf("decoder error %s\n", lodepng_error_text(error)); - return 1; - } - - // Use source image palette since lodepng conversion to indexed (LCT_PALETTE) won't create a palette - // So: state->info_png.color.palette/size instead of state->info_raw.palette/size - unsigned int palette_count = PaletteCountApplyMaxLimit((unsigned int)assetData->args->max_palettes, (unsigned int)(state.info_png.color.palettesize / assetData->image.colors_per_pal)); - assetData->image.total_color_count = palette_count * assetData->image.colors_per_pal; - // Copy the palette data since the source buffer (state...) won't exist outside the scope of this function - assetData->image.palette = new unsigned char[assetData->image.total_color_count * RGBA32_SZ]; - memcpy(assetData->image.palette, state.info_png.color.palette, assetData->image.total_color_count * RGBA32_SZ); - - - - if(assetData->args->repair_indexed_pal) - if(!image_indexed_repair_tile_palettes(assetData->image, assetData->args->use_2x2_map_attributes)) - return 1; - - // TODO: Enable dimension check - // // Validate image dimensions - // if (((image.w % tile_w) != 0) || ((image.h % tile_h) != 0)) - // { - // printf("Error: Image size %d x %d isn't an even multiple of tile size %d x %d\n", image.w, image.h, tile_w, tile_h); - // return 1; - // } - - if(assetData->args->source_tilesets.size()>0) { - - // Make sure these two values match when keeping palette order - if(assetData->image.total_color_count != assetData->source_tileset_image.total_color_count) { - - printf("error: The number of color palette's for your source tileset (%d) and target image (%d) do not match.", (unsigned int)assetData->source_tileset_image.total_color_count, (unsigned int)assetData->image.total_color_count); - return 1; - } - - size_t size = max(assetData->image.total_color_count, assetData->source_tileset_image.total_color_count); - - // Make sure these two values match when keeping palette order - if(memcmp(assetData->image.palette, assetData->source_tileset_image.palette, size) != 0) { - - printf("error: The palette's for your source tileset and target image do not match."); - return 1; - } - } - return 0; + //load and decode png + vector<unsigned char> buffer; + lodepng::load_file(buffer, input_filename); + lodepng::State state; + + + //Calling with keep_palette_order means + //-The image should be png indexed (1-8 bits per pixel) + //-For CGB: Each 4 colors define a gbc palette, the first color is the transparent one + //-Each rectangle with dimension(tile_w, tile_h) in the image has colors from one of those palettes only + state.info_raw.colortype = LCT_PALETTE; + state.info_raw.bitdepth = 8; + + // * Do *NOT* turn color_convert ON here. + // When source PNG is indexed with bit depth was less than 8 bits per pixel then + // color_convert may mangle the packed indexed values. Instead manually unpack them. + // + // This is necessary since some PNG encoders will use the minimum possible number of bits. + // For example 2 colors in the palette -> 1bpp -> 8 pixels per byte in the decoded image. + // Also see below about requirement to use palette from source image + state.decoder.color_convert = false; + + unsigned error = lodepng::decode(assetData->image.data, assetData->image.w, assetData->image.h, state, buffer); + // Unpack the image if needed. Also checks and errors on incompatible palette type if needed + if(!image_indexed_ensure_8bpp(assetData->image.data, assetData->image.w, assetData->image.h, (int)state.info_png.color.bitdepth, (int)state.info_png.color.colortype)) + return 1; + else if(error) { + printf("decoder error %s\n", lodepng_error_text(error)); + return 1; + } + + // Use source image palette since lodepng conversion to indexed (LCT_PALETTE) won't create a palette + // So: state->info_png.color.palette/size instead of state->info_raw.palette/size + unsigned int palette_count = PaletteCountApplyMaxLimit((unsigned int)assetData->args->max_palettes, (unsigned int)(state.info_png.color.palettesize / assetData->image.colors_per_pal)); + assetData->image.total_color_count = palette_count * assetData->image.colors_per_pal; + // Copy the palette data since the source buffer (state...) won't exist outside the scope of this function + assetData->image.palette = new unsigned char[assetData->image.total_color_count * RGBA32_SZ]; + memcpy(assetData->image.palette, state.info_png.color.palette, assetData->image.total_color_count * RGBA32_SZ); + + + + if(assetData->args->repair_indexed_pal) + if(!image_indexed_repair_tile_palettes(assetData->image, assetData->args->use_2x2_map_attributes)) + return 1; + + // TODO: Enable dimension check + // // Validate image dimensions + // if (((image.w % tile_w) != 0) || ((image.h % tile_h) != 0)) + // { + // printf("Error: Image size %d x %d isn't an even multiple of tile size %d x %d\n", image.w, image.h, tile_w, tile_h); + // return 1; + // } + + if(assetData->args->source_tilesets.size()>0) { + + // Make sure these two values match when keeping palette order + if(assetData->image.total_color_count != assetData->source_tileset_image.total_color_count) { + + printf("error: The number of color palette's for your source tileset (%d) and target image (%d) do not match.", (unsigned int)assetData->source_tileset_image.total_color_count, (unsigned int)assetData->image.total_color_count); + return 1; + } + + size_t size = max(assetData->image.total_color_count, assetData->source_tileset_image.total_color_count); + + // Make sure these two values match when keeping palette order + if(memcmp(assetData->image.palette, assetData->source_tileset_image.palette, size) != 0) { + + printf("error: The palette's for your source tileset and target image do not match."); + return 1; + } + } + return 0; } int ReadImageData_Default(PNG2AssetData* assetData, string input_filename) { - //load and decode png - vector<unsigned char> buffer; - lodepng::load_file(buffer, assetData->args->input_filename); - lodepng::State state; + //load and decode png + vector<unsigned char> buffer; + lodepng::load_file(buffer, assetData->args->input_filename); + lodepng::State state; - PNGImage image32; - image32.colors_per_pal = assetData->image.colors_per_pal; - image32.tile_w = assetData->image.tile_w; - image32.tile_h = assetData->image.tile_h; + PNGImage image32; + image32.colors_per_pal = assetData->image.colors_per_pal; + image32.tile_w = assetData->image.tile_w; + image32.tile_h = assetData->image.tile_h; - unsigned error = lodepng::decode(image32.data, image32.w, image32.h, state, buffer); //decode as 32 bit - if(error) - { - printf("decoder error %s\n", lodepng_error_text(error)); - return 1; - } + unsigned error = lodepng::decode(image32.data, image32.w, image32.h, state, buffer); //decode as 32 bit + if(error) + { + printf("decoder error %s\n", lodepng_error_text(error)); + return 1; + } - // Validate image dimensions - if(((image32.w % image32.tile_w) != 0) || ((image32.h % image32.tile_h) != 0)) - { - printf("Error: Image size %d x %d isn't an even multiple of tile size %d x %d\n", image32.w, image32.h, image32.tile_w, image32.tile_h); - return 1; - } + // Validate image dimensions + if(((image32.w % image32.tile_w) != 0) || ((image32.h % image32.tile_h) != 0)) + { + printf("Error: Image size %d x %d isn't an even multiple of tile size %d x %d\n", image32.w, image32.h, image32.tile_w, image32.tile_h); + return 1; + } - int* palettes_per_tile = BuildPalettesAndAttributes(image32, assetData->palettes, assetData->args->use_2x2_map_attributes); + int* palettes_per_tile = BuildPalettesAndAttributes(image32, assetData->palettes, assetData->args->use_2x2_map_attributes); - //Create the indexed image - assetData->image.data.clear(); - assetData->image.w = image32.w; - assetData->image.h = image32.h; + //Create the indexed image + assetData->image.data.clear(); + assetData->image.w = image32.w; + assetData->image.h = image32.h; - unsigned int palette_count = PaletteCountApplyMaxLimit((unsigned int)assetData->args->max_palettes, (unsigned int)assetData->palettes.size()); + unsigned int palette_count = PaletteCountApplyMaxLimit((unsigned int)assetData->args->max_palettes, (unsigned int)assetData->palettes.size()); - assetData->image.total_color_count = palette_count * assetData->image.colors_per_pal; - assetData->image.palette = new unsigned char[palette_count * assetData->image.colors_per_pal * RGBA32_SZ]; // total color count * 4 bytes each + assetData->image.total_color_count = palette_count * assetData->image.colors_per_pal; + assetData->image.palette = new unsigned char[palette_count * assetData->image.colors_per_pal * RGBA32_SZ]; // total color count * 4 bytes each // Pre-fill palette to all black. Prevents garbage in palette color slots that are unused (ex: only 3 colors when colors-per-pal is 4) memset(assetData->image.palette, 0, palette_count * assetData->image.colors_per_pal * RGBA32_SZ); - // If we are using a sourcetileset and have more palettes than it defines - if(assetData->args->source_tilesets.size() > 0 && (assetData->image.total_color_count > assetData->args->source_total_color_count)) { - printf("Found %d extra palette(s) for target tilemap.\n", (unsigned int)((assetData->image.total_color_count - assetData->args->source_total_color_count) / assetData->image.colors_per_pal)); - } - for(size_t p = 0; p < palette_count; ++p) - { - int* color_ptr = (int*)&assetData->image.palette[p * assetData->image.colors_per_pal * RGBA32_SZ]; - - // When palettes[p].size() != image.colors_per_pal the unused colors are left as black (see memset above) - for(SetPal::iterator it = assetData->palettes[p].begin(); it != assetData->palettes[p].end(); ++it, color_ptr++) - { - unsigned char* c = (unsigned char*)&(*it); - *color_ptr = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; - } - } - - for(size_t y = 0; y < image32.h; ++y) - { - for(size_t x = 0; x < image32.w; ++x) - { - unsigned char* c32ptr = &image32.data[(image32.w * y + x) * RGBA32_SZ]; - int color32 = (c32ptr[0] << 24) | (c32ptr[1] << 16) | (c32ptr[2] << 8) | c32ptr[3]; - unsigned char palette = palettes_per_tile[(y / image32.tile_h) * (image32.w / image32.tile_w) + (x / image32.tile_w)]; - unsigned char index = (unsigned char)std::distance(assetData->palettes[palette].begin(), assetData->palettes[palette].find(color32)); - assetData->image.data.push_back((palette << assetData->args->bpp) + index); - } - } - - //Test: output png to see how it looks - //Export(image, "temp.png"); - return 0; + // If we are using a sourcetileset and have more palettes than it defines + if(assetData->args->source_tilesets.size() > 0 && (assetData->image.total_color_count > assetData->args->source_total_color_count)) { + printf("Found %d extra palette(s) for target tilemap.\n", (unsigned int)((assetData->image.total_color_count - assetData->args->source_total_color_count) / assetData->image.colors_per_pal)); + } + for(size_t p = 0; p < palette_count; ++p) + { + int* color_ptr = (int*)&assetData->image.palette[p * assetData->image.colors_per_pal * RGBA32_SZ]; + + // When palettes[p].size() != image.colors_per_pal the unused colors are left as black (see memset above) + for(SetPal::iterator it = assetData->palettes[p].begin(); it != assetData->palettes[p].end(); ++it, color_ptr++) + { + unsigned char* c = (unsigned char*)&(*it); + *color_ptr = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; + } + } + + for(size_t y = 0; y < image32.h; ++y) + { + for(size_t x = 0; x < image32.w; ++x) + { + unsigned char* c32ptr = &image32.data[(image32.w * y + x) * RGBA32_SZ]; + int color32 = (c32ptr[0] << 24) | (c32ptr[1] << 16) | (c32ptr[2] << 8) | c32ptr[3]; + unsigned char palette = palettes_per_tile[(y / image32.tile_h) * (image32.w / image32.tile_w) + (x / image32.tile_w)]; + unsigned char index = (unsigned char)std::distance(assetData->palettes[palette].begin(), assetData->palettes[palette].find(color32)); + assetData->image.data.push_back((palette << assetData->args->bpp) + index); + } + } + + //Test: output png to see how it looks + //Export(image, "temp.png"); + return 0; } int ReadImageData( PNG2AssetData* assetData, string input_filename) { - assetData->image.colors_per_pal = static_cast<size_t>(1) << assetData->args->bpp; + assetData->image.colors_per_pal = static_cast<size_t>(1) << assetData->args->bpp; - if(assetData->args->export_as_map) - { - assetData->image.tile_w = 8; //Force tiles_w to 8 on maps - assetData->image.tile_h = 8; //Force tiles_h to 8 on maps - assetData->args->sprite_mode = SPR_NONE; - } + if(assetData->args->export_as_map) + { + assetData->image.tile_w = 8; //Force tiles_w to 8 on maps + assetData->image.tile_h = 8; //Force tiles_h to 8 on maps + assetData->args->sprite_mode = SPR_NONE; + } - int errorCode = 0; + int errorCode = 0; - // Will the specified PNG have a palette provided with it? - if(assetData->args->keep_palette_order) { - - // Save the error code - errorCode= ReadImageData_KeepPaletteOrder(assetData, input_filename); - } - else - { + // Will the specified PNG have a palette provided with it? + if(assetData->args->keep_palette_order) { + + // Save the error code + errorCode= ReadImageData_KeepPaletteOrder(assetData, input_filename); + } + else + { - // Save the error code - errorCode= ReadImageData_Default(assetData, input_filename); - } + // Save the error code + errorCode= ReadImageData_Default(assetData, input_filename); + } - if(errorCode != 0)return errorCode; + if(errorCode != 0)return errorCode; - if(assetData->args->spriteSize.width == 0) assetData->args->spriteSize.width = (int)assetData->image.w; - if(assetData->args->spriteSize.height == 0) assetData->args->spriteSize.height = (int)assetData->image.h; - if(assetData->args->pivot.x == 0xFFFFFF) assetData->args->pivot.x = (unsigned int)assetData->args->spriteSize.width / 2; - if(assetData->args->pivot.y == 0xFFFFFF) assetData->args->pivot.y = (unsigned int)assetData->args->spriteSize.height / 2; - if(assetData->args->pivot.width == 0xFFFFFF) assetData->args->pivot.width = assetData->args->spriteSize.width; - if(assetData->args->pivot.height == 0xFFFFFF) assetData->args->pivot.height = assetData->args->spriteSize.height; + if(assetData->args->spriteSize.width == 0) assetData->args->spriteSize.width = (int)assetData->image.w; + if(assetData->args->spriteSize.height == 0) assetData->args->spriteSize.height = (int)assetData->image.h; + if(assetData->args->pivot.x == 0xFFFFFF) assetData->args->pivot.x = (unsigned int)assetData->args->spriteSize.width / 2; + if(assetData->args->pivot.y == 0xFFFFFF) assetData->args->pivot.y = (unsigned int)assetData->args->spriteSize.height / 2; + if(assetData->args->pivot.width == 0xFFFFFF) assetData->args->pivot.width = assetData->args->spriteSize.width; + if(assetData->args->pivot.height == 0xFFFFFF) assetData->args->pivot.height = assetData->args->spriteSize.height; - return 0; + return 0; } diff --git a/gbdk-support/png2asset/main.cpp b/gbdk-support/png2asset/main.cpp @@ -29,47 +29,47 @@ using namespace std; int main(int argc, char* argv[]) { - int errorCode = 0; + int errorCode = 0; - // Read all arguments - PNG2AssetArguments arguments; + // Read all arguments + PNG2AssetArguments arguments; - // Make sure we had no errors - if((errorCode = processPNG2AssetArguments(argc, argv, &arguments)) != 0) { - return errorCode; - } + // Make sure we had no errors + if((errorCode = processPNG2AssetArguments(argc, argv, &arguments)) != 0) { + return errorCode; + } - PNG2AssetData png2AssetInstance; + PNG2AssetData png2AssetInstance; - // If we have a source tileset - if(arguments.source_tilesets.size() > 0) { + // If we have a source tileset + if(arguments.source_tilesets.size() > 0) { - vector<string>::iterator sourceTilesetsIterator = arguments.source_tilesets.begin(); + vector<string>::iterator sourceTilesetsIterator = arguments.source_tilesets.begin(); - // Iterate through each source tileset and execute + // Iterate through each source tileset and execute while (sourceTilesetsIterator < arguments.source_tilesets.end()) { - // Run with our source tileset filename - errorCode = png2AssetInstance.Execute(&arguments, *sourceTilesetsIterator); + // Run with our source tileset filename + errorCode = png2AssetInstance.Execute(&arguments, *sourceTilesetsIterator); - // Return the error code if the function returns non-zero - if(errorCode != 0) { - return errorCode; - } + // Return the error code if the function returns non-zero + if(errorCode != 0) { + return errorCode; + } sourceTilesetsIterator++; - } + } - // Save these values for later usage on the main execution - arguments.source_tileset_size = (unsigned int)png2AssetInstance.tiles.size(); - arguments.source_total_color_count = png2AssetInstance.image.total_color_count; - } + // Save these values for later usage on the main execution + arguments.source_tileset_size = (unsigned int)png2AssetInstance.tiles.size(); + arguments.source_total_color_count = png2AssetInstance.image.total_color_count; + } - // Run the primary input file - // Return the error code if the function returns non-zero - if((errorCode = png2AssetInstance.Execute(&arguments, arguments.input_filename)) != 0) { - return errorCode; - } + // Run the primary input file + // Return the error code if the function returns non-zero + if((errorCode = png2AssetInstance.Execute(&arguments, arguments.input_filename)) != 0) { + return errorCode; + } - return png2AssetInstance.Export(); + return png2AssetInstance.Export(); } diff --git a/gbdk-support/png2asset/map_attributes.cpp b/gbdk-support/png2asset/map_attributes.cpp @@ -20,30 +20,30 @@ using namespace std; unsigned char GetMapAttribute(size_t x, size_t y,PNG2AssetData* assetData) { - if(x < assetData->args->map_attributes_size.width && y < assetData->args->map_attributes_size.height) - return assetData->map_attributes[y * assetData->args->map_attributes_size.width + x]; - else - return 0; + if(x < assetData->args->map_attributes_size.width && y < assetData->args->map_attributes_size.height) + return assetData->map_attributes[y * assetData->args->map_attributes_size.width + x]; + else + return 0; } void ReduceMapAttributes2x2(const vector< SetPal >& palettes,PNG2AssetData* assetData) { - size_t w = (assetData->args->map_attributes_size.width + 1) / 2; - size_t h = (assetData->args->map_attributes_size.height + 1) / 2; - vector< unsigned char > map_attributes_2x2; - map_attributes_2x2.resize(w * h); - for(size_t y = 0; y < h; y++) - { - for(size_t x = 0; x < w; x++) - { - // Use only Top-left attribute, ignoring the other three as they should now be identical - map_attributes_2x2[y * w + x] = GetMapAttribute(2 * x, 2 * y,assetData); - } - } - // Overwrite old attributes - assetData->args->map_attributes_size.width = w; - assetData->args->map_attributes_size.height = h; - assetData->map_attributes = map_attributes_2x2; + size_t w = (assetData->args->map_attributes_size.width + 1) / 2; + size_t h = (assetData->args->map_attributes_size.height + 1) / 2; + vector< unsigned char > map_attributes_2x2; + map_attributes_2x2.resize(w * h); + for(size_t y = 0; y < h; y++) + { + for(size_t x = 0; x < w; x++) + { + // Use only Top-left attribute, ignoring the other three as they should now be identical + map_attributes_2x2[y * w + x] = GetMapAttribute(2 * x, 2 * y,assetData); + } + } + // Overwrite old attributes + assetData->args->map_attributes_size.width = w; + assetData->args->map_attributes_size.height = h; + assetData->map_attributes = map_attributes_2x2; } // @@ -54,29 +54,29 @@ void ReduceMapAttributes2x2(const vector< SetPal >& palettes,PNG2AssetData* asse // void AlignMapAttributes(PNG2AssetData* assetData) { - const size_t ATTRIBUTE_HEIGHT = 15; - const size_t ATTRIBUTE_ALIGNED_HEIGHT = 16; - vector< unsigned char > map_attributes_aligned; - size_t map_attributes_aligned_width = 2 * ((assetData->args->map_attributes_size.width + 1) / 2); - size_t num_vertical_nametables = (assetData->args->map_attributes_size.height + ATTRIBUTE_HEIGHT - 1) / ATTRIBUTE_HEIGHT; - map_attributes_aligned.resize(map_attributes_aligned_width * (num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT)); - for(size_t i = 0; i < num_vertical_nametables; i++) - { - bool last_nametable = (i == num_vertical_nametables - 1); - size_t height = last_nametable ? (assetData->args->map_attributes_size.height - i * ATTRIBUTE_HEIGHT) : ATTRIBUTE_HEIGHT; - for(size_t y = 0; y < height; y++) - { - for(size_t x = 0; x < assetData->args->map_attributes_size.width; x++) - { - map_attributes_aligned[(i * ATTRIBUTE_ALIGNED_HEIGHT + y) * map_attributes_aligned_width + x] = - assetData->map_attributes[(i * ATTRIBUTE_HEIGHT + y) * assetData->args->map_attributes_size.width + x]; - } - } - } - // Overwrite old attributes - assetData->args->map_attributes_size.width = map_attributes_aligned_width; - assetData->args->map_attributes_size.height = num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT; - assetData->map_attributes = map_attributes_aligned; + const size_t ATTRIBUTE_HEIGHT = 15; + const size_t ATTRIBUTE_ALIGNED_HEIGHT = 16; + vector< unsigned char > map_attributes_aligned; + size_t map_attributes_aligned_width = 2 * ((assetData->args->map_attributes_size.width + 1) / 2); + size_t num_vertical_nametables = (assetData->args->map_attributes_size.height + ATTRIBUTE_HEIGHT - 1) / ATTRIBUTE_HEIGHT; + map_attributes_aligned.resize(map_attributes_aligned_width * (num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT)); + for(size_t i = 0; i < num_vertical_nametables; i++) + { + bool last_nametable = (i == num_vertical_nametables - 1); + size_t height = last_nametable ? (assetData->args->map_attributes_size.height - i * ATTRIBUTE_HEIGHT) : ATTRIBUTE_HEIGHT; + for(size_t y = 0; y < height; y++) + { + for(size_t x = 0; x < assetData->args->map_attributes_size.width; x++) + { + map_attributes_aligned[(i * ATTRIBUTE_ALIGNED_HEIGHT + y) * map_attributes_aligned_width + x] = + assetData->map_attributes[(i * ATTRIBUTE_HEIGHT + y) * assetData->args->map_attributes_size.width + x]; + } + } + } + // Overwrite old attributes + assetData->args->map_attributes_size.width = map_attributes_aligned_width; + assetData->args->map_attributes_size.height = num_vertical_nametables * ATTRIBUTE_ALIGNED_HEIGHT; + assetData->map_attributes = map_attributes_aligned; } // @@ -85,46 +85,46 @@ void AlignMapAttributes(PNG2AssetData* assetData) // void PackMapAttributes(PNG2AssetData *assetData) { - vector< unsigned char > map_attributes_packed; - assetData->args->map_attributes_packed_size.width = (assetData->args->map_attributes_size.width + 1) / 2; - assetData->args->map_attributes_packed_size.height = (assetData->args->map_attributes_size.height + 1) / 2; - map_attributes_packed.resize(assetData->args->map_attributes_packed_size.width * assetData->args->map_attributes_packed_size.height); - for(size_t y = 0; y < assetData->args->map_attributes_packed_size.height; y++) - { - for(size_t x = 0; x < assetData->args->map_attributes_packed_size.width; x++) - { - unsigned char a_tl = GetMapAttribute(2 * x + 0, 2 * y + 0, assetData); - unsigned char a_tr = GetMapAttribute(2 * x + 1, 2 * y + 0, assetData); - unsigned char a_bl = GetMapAttribute(2 * x + 0, 2 * y + 1, assetData); - unsigned char a_br = GetMapAttribute(2 * x + 1, 2 * y + 1, assetData); - unsigned char packed_bits = (a_br << 6) | (a_bl << 4) | (a_tr << 2) | (a_tl << 0); - map_attributes_packed[assetData->args->map_attributes_packed_size.width * y + x] = packed_bits; - } - } - // Overwrite old attributes - assetData->map_attributes = map_attributes_packed; + vector< unsigned char > map_attributes_packed; + assetData->args->map_attributes_packed_size.width = (assetData->args->map_attributes_size.width + 1) / 2; + assetData->args->map_attributes_packed_size.height = (assetData->args->map_attributes_size.height + 1) / 2; + map_attributes_packed.resize(assetData->args->map_attributes_packed_size.width * assetData->args->map_attributes_packed_size.height); + for(size_t y = 0; y < assetData->args->map_attributes_packed_size.height; y++) + { + for(size_t x = 0; x < assetData->args->map_attributes_packed_size.width; x++) + { + unsigned char a_tl = GetMapAttribute(2 * x + 0, 2 * y + 0, assetData); + unsigned char a_tr = GetMapAttribute(2 * x + 1, 2 * y + 0, assetData); + unsigned char a_bl = GetMapAttribute(2 * x + 0, 2 * y + 1, assetData); + unsigned char a_br = GetMapAttribute(2 * x + 1, 2 * y + 1, assetData); + unsigned char packed_bits = (a_br << 6) | (a_bl << 4) | (a_tr << 2) | (a_tl << 0); + map_attributes_packed[assetData->args->map_attributes_packed_size.width * y + x] = packed_bits; + } + } + // Overwrite old attributes + assetData->map_attributes = map_attributes_packed; } void HandleMapAttributes(PNG2AssetData* assetData) { - assetData->args->map_attributes_size.width = assetData->image.w / 8; - assetData->args->map_attributes_size.height = assetData->image.h / 8; + assetData->args->map_attributes_size.width = assetData->image.w / 8; + assetData->args->map_attributes_size.height = assetData->image.h / 8; - // Optionally perform 2x2 reduction on attributes (NES attribute table has this format) - if(assetData->args->use_2x2_map_attributes) - { - // NES attribute map dimensions are half-resolution - ReduceMapAttributes2x2(assetData->palettes, assetData); - } - // Optionally align and pack map attributes into NES PPU format - if(assetData->args->pack_map_attributes) - { - AlignMapAttributes(assetData); - PackMapAttributes(assetData); - } - else - { - // Use original attribute dimensions for packed - assetData->args->map_attributes_packed_size.width = assetData->args->map_attributes_size.width; - assetData->args->map_attributes_packed_size.height = assetData->args->map_attributes_size.height; - } + // Optionally perform 2x2 reduction on attributes (NES attribute table has this format) + if(assetData->args->use_2x2_map_attributes) + { + // NES attribute map dimensions are half-resolution + ReduceMapAttributes2x2(assetData->palettes, assetData); + } + // Optionally align and pack map attributes into NES PPU format + if(assetData->args->pack_map_attributes) + { + AlignMapAttributes(assetData); + PackMapAttributes(assetData); + } + else + { + // Use original attribute dimensions for packed + assetData->args->map_attributes_packed_size.width = assetData->args->map_attributes_size.width; + assetData->args->map_attributes_packed_size.height = assetData->args->map_attributes_size.height; + } } diff --git a/gbdk-support/png2asset/maps.cpp b/gbdk-support/png2asset/maps.cpp @@ -24,73 +24,73 @@ using namespace std; void GetMap( PNG2AssetData* assetData) { - for(int y = 0; y < (int)assetData->image.h; y += assetData->image.tile_h) - { - for(int x = 0; x < (int)assetData->image.w; x += assetData->image.tile_w) - { - Tile tile(assetData->image.tile_w * assetData->image.tile_h); - assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes); - - size_t idx; - unsigned char props; - - if(assetData->args->keep_duplicate_tiles) - { - assetData->tiles.push_back(tile); - idx = assetData->tiles.size() - 1; - props = assetData->args->props_default; - } - else - { - if(!FindTile(tile, idx, props,assetData)) - { - if(assetData->args->source_tilesets.size() > 0) { - printf("found a tile not in the source tileset at %d,%d. The target tileset has %d extra tiles.\n", x, y, (unsigned int)assetData->args->extra_tile_count + 1); - assetData->args->extra_tile_count++; - assetData->args->includeTileData = true; - } - assetData->tiles.push_back(tile); - idx = assetData->tiles.size() - 1; - props = assetData->args->props_default; - - if(assetData->tiles.size() > 256 && assetData->args->pack_mode != Tile::SMS) - printf("Warning: found more than 256 tiles on x:%d,y:%d\n", x, y); - - if(((assetData->tiles.size() + assetData->args->tile_origin) > 256) && (assetData->args->pack_mode != Tile::SMS)) - printf("Warning: tile count (%d) + tile origin (%d) exceeds 256 at x:%d,y:%d\n", (unsigned int)assetData->tiles.size(), assetData->args->tile_origin, x, y); - } - } - - assetData->map.push_back((unsigned char)idx + assetData->args->tile_origin); - - if(assetData->args->use_map_attributes) - { - unsigned char pal_idx = assetData->image.data[y * assetData->image.w + x] >> assetData->args->bpp; //We can pick the palette from the first pixel of this tile - if(assetData->args->pack_mode == Tile::SGB) - { - props = props << 1; //Mirror flags in SGB are on bit 7 - props |= (pal_idx + 4) << 2; //Pals are in bits 2,3,4 and need to go from 4 to 7 - assetData->map.push_back(props); //Also they are stored within the map tiles - } - else if(assetData->args->pack_mode == Tile::SMS) - { - props = props >> 4; - if(idx > 255) - props |= 1; - assetData->map.push_back(props); - } - else - { - props |= pal_idx; - assetData->map_attributes.push_back(props); - } - } - - } - } - - - - HandleMapAttributes( assetData); + for(int y = 0; y < (int)assetData->image.h; y += assetData->image.tile_h) + { + for(int x = 0; x < (int)assetData->image.w; x += assetData->image.tile_w) + { + Tile tile(assetData->image.tile_w * assetData->image.tile_h); + assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes); + + size_t idx; + unsigned char props; + + if(assetData->args->keep_duplicate_tiles) + { + assetData->tiles.push_back(tile); + idx = assetData->tiles.size() - 1; + props = assetData->args->props_default; + } + else + { + if(!FindTile(tile, idx, props,assetData)) + { + if(assetData->args->source_tilesets.size() > 0) { + printf("found a tile not in the source tileset at %d,%d. The target tileset has %d extra tiles.\n", x, y, (unsigned int)assetData->args->extra_tile_count + 1); + assetData->args->extra_tile_count++; + assetData->args->includeTileData = true; + } + assetData->tiles.push_back(tile); + idx = assetData->tiles.size() - 1; + props = assetData->args->props_default; + + if(assetData->tiles.size() > 256 && assetData->args->pack_mode != Tile::SMS) + printf("Warning: found more than 256 tiles on x:%d,y:%d\n", x, y); + + if(((assetData->tiles.size() + assetData->args->tile_origin) > 256) && (assetData->args->pack_mode != Tile::SMS)) + printf("Warning: tile count (%d) + tile origin (%d) exceeds 256 at x:%d,y:%d\n", (unsigned int)assetData->tiles.size(), assetData->args->tile_origin, x, y); + } + } + + assetData->map.push_back((unsigned char)idx + assetData->args->tile_origin); + + if(assetData->args->use_map_attributes) + { + unsigned char pal_idx = assetData->image.data[y * assetData->image.w + x] >> assetData->args->bpp; //We can pick the palette from the first pixel of this tile + if(assetData->args->pack_mode == Tile::SGB) + { + props = props << 1; //Mirror flags in SGB are on bit 7 + props |= (pal_idx + 4) << 2; //Pals are in bits 2,3,4 and need to go from 4 to 7 + assetData->map.push_back(props); //Also they are stored within the map tiles + } + else if(assetData->args->pack_mode == Tile::SMS) + { + props = props >> 4; + if(idx > 255) + props |= 1; + assetData->map.push_back(props); + } + else + { + props |= pal_idx; + assetData->map_attributes.push_back(props); + } + } + + } + } + + + + HandleMapAttributes( assetData); } diff --git a/gbdk-support/png2asset/metasprites.cpp b/gbdk-support/png2asset/metasprites.cpp @@ -20,67 +20,67 @@ using namespace std; void GetMetaSprite(int _x, int _y, int _w, int _h, int pivot_x, int pivot_y, PNG2AssetData* assetData) { - int last_x = _x + pivot_x; - int last_y = _y + pivot_y; + int last_x = _x + pivot_x; + int last_y = _y + pivot_y; - assetData->sprites.push_back(MetaSprite()); - MetaSprite& mt_sprite = assetData->sprites.back(); - for(int y = _y; y < _y + _h && y < (int)assetData->image.h; y += assetData->image.tile_h) - { - for(int x = _x; x < _x + _w && x < (int)assetData->image.w; x += assetData->image.tile_w) - { - Tile tile(assetData->image.tile_h * assetData->image.tile_w); - if(assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes)) - { - size_t idx; - unsigned char props; - unsigned char pal_idx = assetData->image.data[y * assetData->image.w + x] >> 2; //We can pick the palette from the first pixel of this tile + assetData->sprites.push_back(MetaSprite()); + MetaSprite& mt_sprite = assetData->sprites.back(); + for(int y = _y; y < _y + _h && y < (int)assetData->image.h; y += assetData->image.tile_h) + { + for(int x = _x; x < _x + _w && x < (int)assetData->image.w; x += assetData->image.tile_w) + { + Tile tile(assetData->image.tile_h * assetData->image.tile_w); + if(assetData->image.ExtractTile(x, y, tile, assetData->args->sprite_mode, assetData->args->export_as_map, assetData->args->use_map_attributes)) + { + size_t idx; + unsigned char props; + unsigned char pal_idx = assetData->image.data[y * assetData->image.w + x] >> 2; //We can pick the palette from the first pixel of this tile - if(assetData->args->keep_duplicate_tiles) - { - assetData->tiles.push_back(tile); - idx = assetData->tiles.size() - 1; - props = assetData->args->props_default; - } - else - { - if(!FindTile(tile, idx, props, assetData)) - { - if(assetData->args->source_tilesets.size() > 0) { - printf("found a tile not in the source tileset at %d,%d. The target tileset has %d extra tiles.\n", x, y, (unsigned int)assetData->args->extra_tile_count + 1); - assetData->args->extra_tile_count++; - assetData->args->includeTileData = true; - } - assetData->tiles.push_back(tile); - idx = assetData->tiles.size() - 1; - props = assetData->args->props_default; - } - } + if(assetData->args->keep_duplicate_tiles) + { + assetData->tiles.push_back(tile); + idx = assetData->tiles.size() - 1; + props = assetData->args->props_default; + } + else + { + if(!FindTile(tile, idx, props, assetData)) + { + if(assetData->args->source_tilesets.size() > 0) { + printf("found a tile not in the source tileset at %d,%d. The target tileset has %d extra tiles.\n", x, y, (unsigned int)assetData->args->extra_tile_count + 1); + assetData->args->extra_tile_count++; + assetData->args->includeTileData = true; + } + assetData->tiles.push_back(tile); + idx = assetData->tiles.size() - 1; + props = assetData->args->props_default; + } + } - props |= pal_idx; + props |= pal_idx; - // Scale up index based on 8x8 tiles-per-hardware sprite - if(assetData->args->sprite_mode == SPR_8x16) - idx *= 2; - else if(assetData->args->sprite_mode == SPR_16x16_MSX) - idx *= 4; + // Scale up index based on 8x8 tiles-per-hardware sprite + if(assetData->args->sprite_mode == SPR_8x16) + idx *= 2; + else if(assetData->args->sprite_mode == SPR_16x16_MSX) + idx *= 4; - mt_sprite.push_back(MTTile(x - last_x, y - last_y, (unsigned char)idx, props)); - last_x = x; - last_y = y; - } - } - } + mt_sprite.push_back(MTTile(x - last_x, y - last_y, (unsigned char)idx, props)); + last_x = x; + last_y = y; + } + } + } } void GetAllMetasprites(PNG2AssetData* assetData) { - //Extract metasprites - for(int y = 0; y < (int)assetData->image.h; y += (unsigned int)assetData->args->spriteSize.height) - { - for(int x = 0; x < (int)assetData->image.w; x += (unsigned int)assetData->args->spriteSize.width) - { - GetMetaSprite(x, y, (unsigned int)assetData->args->spriteSize.width, (unsigned int)assetData->args->spriteSize.height, assetData->args->pivot.x, assetData->args->pivot.y, assetData); - } - } + //Extract metasprites + for(int y = 0; y < (int)assetData->image.h; y += (unsigned int)assetData->args->spriteSize.height) + { + for(int x = 0; x < (int)assetData->image.w; x += (unsigned int)assetData->args->spriteSize.width) + { + GetMetaSprite(x, y, (unsigned int)assetData->args->spriteSize.width, (unsigned int)assetData->args->spriteSize.height, assetData->args->pivot.x, assetData->args->pivot.y, assetData); + } + } } diff --git a/gbdk-support/png2asset/mttile.h b/gbdk-support/png2asset/mttile.h @@ -1,12 +1,12 @@ #pragma once struct MTTile { - char offset_x; - char offset_y; - unsigned char offset_idx; - unsigned char props; + char offset_x; + char offset_y; + unsigned char offset_idx; + unsigned char props; - MTTile(char offset_x, char offset_y, unsigned char offset_idx, unsigned char props) : offset_x(offset_x), offset_y(offset_y), offset_idx(offset_idx), props(props) {} - MTTile() : offset_x(0), offset_y(0), offset_idx(0), props(0) {} + MTTile(char offset_x, char offset_y, unsigned char offset_idx, unsigned char props) : offset_x(offset_x), offset_y(offset_y), offset_idx(offset_idx), props(props) {} + MTTile() : offset_x(0), offset_y(0), offset_idx(0), props(0) {} }; diff --git a/gbdk-support/png2asset/png2asset.cpp b/gbdk-support/png2asset/png2asset.cpp @@ -29,96 +29,96 @@ using namespace std; int PNG2AssetData::Execute(PNG2AssetArguments* arguments, string input_filename){ - this->args = arguments; - - if(arguments->sprite_mode == SPR_8x8) - { - this->image.tile_w = 8; - this->image.tile_h = 8; - } - else if(arguments->sprite_mode == SPR_8x16) - { - this->image.tile_w = 8; - this->image.tile_h = 16; - } - else if(arguments->sprite_mode == SPR_16x16_MSX) - { - this->image.tile_w = 16; - this->image.tile_h = 16; - } - - int readImageDataValue = ReadImageData(this, input_filename); - - // Return the error code if the function returns non-zero - if(readImageDataValue != 0) { - return readImageDataValue; - } - - // Get the data depending on the type - if(this->args->export_as_map)GetMap(this); - else GetAllMetasprites(this); - - return 0; + this->args = arguments; + + if(arguments->sprite_mode == SPR_8x8) + { + this->image.tile_w = 8; + this->image.tile_h = 8; + } + else if(arguments->sprite_mode == SPR_8x16) + { + this->image.tile_w = 8; + this->image.tile_h = 16; + } + else if(arguments->sprite_mode == SPR_16x16_MSX) + { + this->image.tile_w = 16; + this->image.tile_h = 16; + } + + int readImageDataValue = ReadImageData(this, input_filename); + + // Return the error code if the function returns non-zero + if(readImageDataValue != 0) { + return readImageDataValue; + } + + // Get the data depending on the type + if(this->args->export_as_map)GetMap(this); + else GetAllMetasprites(this); + + return 0; } int PNG2AssetData::Export() { - // Header file export - if(export_h_file(this) == false) return 1; // Exit with Fail + // Header file export + if(export_h_file(this) == false) return 1; // Exit with Fail - if((this->args->export_as_map) && (this->args->output_binary)) { - // Handle special case of binary map export - export_map_binary(this); - } - else { - // Normal source file export - if(export_c_file(this) == false) return 1; // Exit with Fail - } + if((this->args->export_as_map) && (this->args->output_binary)) { + // Handle special case of binary map export + export_map_binary(this); + } + else { + // Normal source file export + if(export_c_file(this) == false) return 1; // Exit with Fail + } - return 0; + return 0; } bool FindTile(const Tile& t, size_t& idx, unsigned char& props, PNG2AssetData* assetData) { - vector< Tile >::iterator it; - it = find(assetData->tiles.begin(), assetData->tiles.end(), t); - if(it != assetData->tiles.end()) - { - idx = (size_t)(it - assetData->tiles.begin()); - props = assetData->args->props_default; - return true; - } - - if(assetData->args->flip_tiles) - { - Tile tile = FlipV(t); - it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); - if(it != assetData->tiles.end()) - { - idx = (size_t)(it - assetData->tiles.begin()); - props = assetData->args->props_default | (1 << 5); - return true; - } - - tile = FlipH(tile); - it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); - if(it != assetData->tiles.end()) - { - idx = (size_t)(it - assetData->tiles.begin()); - props = assetData->args->props_default | (1 << 5) | (1 << 6); - return true; - } - - tile = FlipV(tile); - it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); - if(it != assetData->tiles.end()) - { - idx = (size_t)(it - assetData->tiles.begin()); - props = assetData->args->props_default | (1 << 6); - return true; - } - } - - return false; + vector< Tile >::iterator it; + it = find(assetData->tiles.begin(), assetData->tiles.end(), t); + if(it != assetData->tiles.end()) + { + idx = (size_t)(it - assetData->tiles.begin()); + props = assetData->args->props_default; + return true; + } + + if(assetData->args->flip_tiles) + { + Tile tile = FlipV(t); + it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); + if(it != assetData->tiles.end()) + { + idx = (size_t)(it - assetData->tiles.begin()); + props = assetData->args->props_default | (1 << 5); + return true; + } + + tile = FlipH(tile); + it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); + if(it != assetData->tiles.end()) + { + idx = (size_t)(it - assetData->tiles.begin()); + props = assetData->args->props_default | (1 << 5) | (1 << 6); + return true; + } + + tile = FlipV(tile); + it = find(assetData->tiles.begin(), assetData->tiles.end(), tile); + if(it != assetData->tiles.end()) + { + idx = (size_t)(it - assetData->tiles.begin()); + props = assetData->args->props_default | (1 << 6); + return true; + } + } + + return false; } diff --git a/gbdk-support/png2asset/png2asset.h b/gbdk-support/png2asset/png2asset.h @@ -16,20 +16,20 @@ class PNG2AssetData { public: - int Execute(PNG2AssetArguments* arguments, string input_filename); - int Export(); + int Execute(PNG2AssetArguments* arguments, string input_filename); + int Export(); - int errorCode; + int errorCode; - PNG2AssetArguments* args; + PNG2AssetArguments* args; - vector< SetPal > palettes; - vector< Tile > tiles; - vector< MetaSprite > sprites; - vector< unsigned char > map; - vector< unsigned char > map_attributes; - PNGImage source_tileset_image; - PNGImage image; + vector< SetPal > palettes; + vector< Tile > tiles; + vector< MetaSprite > sprites; + vector< unsigned char > map; + vector< unsigned char > map_attributes; + PNGImage source_tileset_image; + PNGImage image; }; diff --git a/gbdk-support/png2asset/png2asset.sln b/gbdk-support/png2asset/png2asset.sln @@ -6,23 +6,23 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "png2asset", "png2asset.vcxproj", "{6BA57070-30F6-442A-9DDA-32876359CB99}" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x64.ActiveCfg = Debug|x64 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x64.Build.0 = Debug|x64 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x86.ActiveCfg = Debug|Win32 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x86.Build.0 = Debug|Win32 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x64.ActiveCfg = Release|x64 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x64.Build.0 = Release|x64 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x86.ActiveCfg = Release|Win32 - {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x64.ActiveCfg = Debug|x64 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x64.Build.0 = Debug|x64 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x86.ActiveCfg = Debug|Win32 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Debug|x86.Build.0 = Debug|Win32 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x64.ActiveCfg = Release|x64 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x64.Build.0 = Release|x64 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x86.ActiveCfg = Release|Win32 + {6BA57070-30F6-442A-9DDA-32876359CB99}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/gbdk-support/png2asset/process_arguments.cpp b/gbdk-support/png2asset/process_arguments.cpp @@ -29,263 +29,263 @@ using namespace std; int processPNG2AssetArguments(int argc, char* argv[], PNG2AssetArguments* args) { - //default values for some params - args->spriteSize.width = 0; - args->spriteSize.height = 0; - args->pivot.x = 0xFFFFFF; - args->pivot.y = 0xFFFFFF; - args->pivot.width = 0xFFFFFF; - args->pivot.height = 0xFFFFFF; - args->bank = -1; - args->keep_palette_order = false; - args->repair_indexed_pal = false; - args->output_binary = false; - args->output_transposed = false; - args->max_palettes = 8; + //default values for some params + args->spriteSize.width = 0; + args->spriteSize.height = 0; + args->pivot.x = 0xFFFFFF; + args->pivot.y = 0xFFFFFF; + args->pivot.width = 0xFFFFFF; + args->pivot.height = 0xFFFFFF; + args->bank = -1; + args->keep_palette_order = false; + args->repair_indexed_pal = false; + args->output_binary = false; + args->output_transposed = false; + args->max_palettes = 8; - args->pack_mode = Tile::GB; + args->pack_mode = Tile::GB; args->map_entry_size_bytes = 1; - args->flip_tiles = true; - args->props_default = 0; - args->keep_duplicate_tiles = false; - args->include_palettes = true; - args->includedMapOrMetaspriteData = true; - args->includeTileData = true; - args->use_structs = false; - args->export_as_map = false; - args->use_map_attributes = false; - args->use_2x2_map_attributes = false; - args->pack_map_attributes = false; - args->convert_rgb_to_nes = false; - args->map_attributes_size.width = 0; - args->map_attributes_size.height = 0; - args->map_attributes_packed_size.width = 0; - args->map_attributes_packed_size.height = 0; - args->sprite_mode = SPR_8x16; - args->source_tileset_size = 0; - args->source_total_color_count = 0; + args->flip_tiles = true; + args->props_default = 0; + args->keep_duplicate_tiles = false; + args->include_palettes = true; + args->includedMapOrMetaspriteData = true; + args->includeTileData = true; + args->use_structs = false; + args->export_as_map = false; + args->use_map_attributes = false; + args->use_2x2_map_attributes = false; + args->pack_map_attributes = false; + args->convert_rgb_to_nes = false; + args->map_attributes_size.width = 0; + args->map_attributes_size.height = 0; + args->map_attributes_packed_size.width = 0; + args->map_attributes_packed_size.height = 0; + args->sprite_mode = SPR_8x16; + args->source_tileset_size = 0; + args->source_total_color_count = 0; - args->bpp = 2; - args->tile_origin = 0; // Default to no tile index offset + args->bpp = 2; + args->tile_origin = 0; // Default to no tile index offset - if(argc < 2) - { - printf("usage: png2asset <file>.png [options]\n"); - printf("-o ouput file (default: <png file>.c)\n"); - printf("-c deprecated, same as -o\n"); - printf("-sw <width> metasprites width size (default: png width)\n"); - printf("-sh <height> metasprites height size (default: png height)\n"); - printf("-sp <props> change default for sprite OAM property bytes (in hex) (default: 0x00)\n"); - printf("-px <x coord> metasprites pivot x coordinate (default: metasprites width / 2)\n"); - printf("-py <y coord> metasprites pivot y coordinate (default: metasprites height / 2)\n"); - printf("-pw <width> metasprites collision rect width (default: metasprites width)\n"); - printf("-ph <height> metasprites collision rect height (default: metasprites height)\n"); - printf("-spr8x8 use SPRITES_8x8\n"); - printf("-spr8x16 use SPRITES_8x16 (this is the default)\n"); - printf("-spr16x16msx use SPRITES_16x16\n"); - printf("-b <bank> bank (default: fixed bank)\n"); - printf("-keep_palette_order use png palette\n"); - printf("-repair_indexed_pal try to repair indexed tile palettes (implies \"-keep_palette_order\")\n"); - printf("-noflip disable tile flip\n"); - printf("-map Export as map (tileset + bg)\n"); - printf("-use_map_attributes Use CGB BG Map attributes\n"); - printf("-use_nes_attributes Use NES BG Map attributes\n"); - printf("-use_nes_colors Convert RGB color values to NES PPU colors\n"); - printf("-use_structs Group the exported info into structs (default: false) (used by ZGB Game Engine)\n"); - printf("-bpp bits per pixel: 1, 2, 4 (default: 2)\n"); - printf("-max_palettes max number of palettes allowed (default: 8)\n"); - printf(" (note: max colors = max_palettes x num colors per palette)\n"); - printf("-pack_mode gb, nes, sgb, sms, 1bpp (default: gb)\n"); - printf("-tile_origin tile index offset for maps (default: 0)\n"); + if(argc < 2) + { + printf("usage: png2asset <file>.png [options]\n"); + printf("-o ouput file (default: <png file>.c)\n"); + printf("-c deprecated, same as -o\n"); + printf("-sw <width> metasprites width size (default: png width)\n"); + printf("-sh <height> metasprites height size (default: png height)\n"); + printf("-sp <props> change default for sprite OAM property bytes (in hex) (default: 0x00)\n"); + printf("-px <x coord> metasprites pivot x coordinate (default: metasprites width / 2)\n"); + printf("-py <y coord> metasprites pivot y coordinate (default: metasprites height / 2)\n"); + printf("-pw <width> metasprites collision rect width (default: metasprites width)\n"); + printf("-ph <height> metasprites collision rect height (default: metasprites height)\n"); + printf("-spr8x8 use SPRITES_8x8\n"); + printf("-spr8x16 use SPRITES_8x16 (this is the default)\n"); + printf("-spr16x16msx use SPRITES_16x16\n"); + printf("-b <bank> bank (default: fixed bank)\n"); + printf("-keep_palette_order use png palette\n"); + printf("-repair_indexed_pal try to repair indexed tile palettes (implies \"-keep_palette_order\")\n"); + printf("-noflip disable tile flip\n"); + printf("-map Export as map (tileset + bg) instead of default metasprite output\n"); + printf("-use_map_attributes Use CGB BG Map attributes\n"); + printf("-use_nes_attributes Use NES BG Map attributes\n"); + printf("-use_nes_colors Convert RGB color values to NES PPU colors\n"); + printf("-use_structs Group the exported info into structs (default: false) (used by ZGB Game Engine)\n"); + printf("-bpp bits per pixel: 1, 2, 4 (default: 2)\n"); + printf("-max_palettes max number of palettes allowed (default: 8)\n"); + printf(" (note: max colors = max_palettes x num colors per palette)\n"); + printf("-pack_mode gb, nes, sgb, sms, 1bpp (default: gb)\n"); + printf("-tile_origin tile index offset for maps (default: 0)\n"); - printf("-tiles_only export tile data only\n"); - printf("-maps_only export map tilemap only\n"); - printf("-metasprites_only export metasprite descriptors only\n"); - printf("-source_tileset use source tileset (image with common tiles)\n"); - printf("-keep_duplicate_tiles do not remove duplicate tiles (default: not enabled)\n"); - printf("-no_palettes do not export palette data\n"); + printf("-tiles_only export tile data only\n"); + printf("-maps_only export map tilemap only\n"); + printf("-metasprites_only export metasprite descriptors only\n"); + printf("-source_tileset use source tileset (image with common tiles)\n"); + printf("-keep_duplicate_tiles do not remove duplicate tiles (default: not enabled)\n"); + printf("-no_palettes do not export palette data\n"); - printf("-bin export to binary format\n"); - printf("-transposed export transposed (column-by-column instead of row-by-row)\n"); + printf("-bin export to binary format\n"); + printf("-transposed export transposed (column-by-column instead of row-by-row)\n"); - return 0; - } + return 0; + } - //default params - args->input_filename = argv[1]; - args->output_filename = argv[1]; - args->output_filename = args->output_filename.substr(0, args->output_filename.size() - 4) + ".c"; + //default params + args->input_filename = argv[1]; + args->output_filename = argv[1]; + args->output_filename = args->output_filename.substr(0, args->output_filename.size() - 4) + ".c"; - //Parse argv - for(int i = 2; i < argc; ++i) - { - if(!strcmp(argv[i], "-sw")) - { - args->spriteSize.width = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-sh")) - { - args->spriteSize.height = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-sp")) - { - args->props_default = strtol(argv[++i], NULL, 16); - } - if(!strcmp(argv[i], "-px")) - { - args->pivot.x = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-py")) - { - args->pivot.y = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-pw")) - { - args->pivot.width = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-ph")) - { - args->pivot.height = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-spr8x8")) - { - args->sprite_mode = SPR_8x8; - } - else if(!strcmp(argv[i], "-spr8x16")) - { - args->sprite_mode = SPR_8x16; - } - else if(!strcmp(argv[i], "-spr16x16msx")) - { - args->sprite_mode = SPR_16x16_MSX; - } - else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "-o")) - { - args->output_filename = argv[++i]; - } - else if(!strcmp(argv[i], "-b")) - { - args->bank = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-keep_palette_order")) - { - args->keep_palette_order = true; - } - else if(!strcmp(argv[i], "-repair_indexed_pal")) - { - args->repair_indexed_pal = true; - args->keep_palette_order = true; // -repair_indexed_pal requires -keep_palette_order, so force it on - } - else if(!strcmp(argv[i], "-noflip")) - { - args->flip_tiles = false; - } - else if(!strcmp(argv[i], "-map")) - { - args->export_as_map = true; - } - else if(!strcmp(argv[i], "-use_map_attributes")) - { - args->use_map_attributes = true; - } - else if(!strcmp(argv[i], "-use_nes_attributes")) - { - args->use_map_attributes = true; - args->use_2x2_map_attributes = true; - args->pack_map_attributes = true; - } - else if(!strcmp(argv[i], "-use_nes_colors")) - { - args->convert_rgb_to_nes = true; - } - else if(!strcmp(argv[i], "-use_structs")) - { - args->use_structs = true; - } - else if(!strcmp(argv[i], "-bpp")) - { - args->bpp = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-max_palettes")) - { - args->max_palettes = atoi(argv[++i]); - if(args->max_palettes == 0) - { - printf("-max_palettes must be larger than zero\n"); - return 1; - } - } - else if(!strcmp(argv[i], "-pack_mode")) - { - std::string pack_mode_str = argv[++i]; - if(pack_mode_str == "gb") args->pack_mode = Tile::GB; - else if(pack_mode_str == "nes") args->pack_mode = Tile::NES; - else if(pack_mode_str == "sgb") { + //Parse argv + for(int i = 2; i < argc; ++i) + { + if(!strcmp(argv[i], "-sw")) + { + args->spriteSize.width = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-sh")) + { + args->spriteSize.height = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-sp")) + { + args->props_default = strtol(argv[++i], NULL, 16); + } + if(!strcmp(argv[i], "-px")) + { + args->pivot.x = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-py")) + { + args->pivot.y = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-pw")) + { + args->pivot.width = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-ph")) + { + args->pivot.height = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-spr8x8")) + { + args->sprite_mode = SPR_8x8; + } + else if(!strcmp(argv[i], "-spr8x16")) + { + args->sprite_mode = SPR_8x16; + } + else if(!strcmp(argv[i], "-spr16x16msx")) + { + args->sprite_mode = SPR_16x16_MSX; + } + else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "-o")) + { + args->output_filename = argv[++i]; + } + else if(!strcmp(argv[i], "-b")) + { + args->bank = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-keep_palette_order")) + { + args->keep_palette_order = true; + } + else if(!strcmp(argv[i], "-repair_indexed_pal")) + { + args->repair_indexed_pal = true; + args->keep_palette_order = true; // -repair_indexed_pal requires -keep_palette_order, so force it on + } + else if(!strcmp(argv[i], "-noflip")) + { + args->flip_tiles = false; + } + else if(!strcmp(argv[i], "-map")) + { + args->export_as_map = true; + } + else if(!strcmp(argv[i], "-use_map_attributes")) + { + args->use_map_attributes = true; + } + else if(!strcmp(argv[i], "-use_nes_attributes")) + { + args->use_map_attributes = true; + args->use_2x2_map_attributes = true; + args->pack_map_attributes = true; + } + else if(!strcmp(argv[i], "-use_nes_colors")) + { + args->convert_rgb_to_nes = true; + } + else if(!strcmp(argv[i], "-use_structs")) + { + args->use_structs = true; + } + else if(!strcmp(argv[i], "-bpp")) + { + args->bpp = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-max_palettes")) + { + args->max_palettes = atoi(argv[++i]); + if(args->max_palettes == 0) + { + printf("-max_palettes must be larger than zero\n"); + return 1; + } + } + else if(!strcmp(argv[i], "-pack_mode")) + { + std::string pack_mode_str = argv[++i]; + if(pack_mode_str == "gb") args->pack_mode = Tile::GB; + else if(pack_mode_str == "nes") args->pack_mode = Tile::NES; + else if(pack_mode_str == "sgb") { args->pack_mode = Tile::SGB; // SGB attributes are packed in map data, so 2 bytes per map tile args->map_entry_size_bytes = 2; } - else if(pack_mode_str == "sms") { + else if(pack_mode_str == "sms") { args->pack_mode = Tile::SMS; // SMS attributes are packed in map data, so 2 bytes per map tile args->map_entry_size_bytes = 2; } - else if(pack_mode_str == "1bpp") args->pack_mode = Tile::BPP1; - else - { - printf("-pack_mode must be one of gb, nes, sgb, sms, 1bpp\n"); - return 1; - } - } - else if(!strcmp(argv[i], "-tile_origin")) - { - args->tile_origin = atoi(argv[++i]); - } - else if(!strcmp(argv[i], "-maps_only") || !strcmp(argv[i], "-metasprites_only")) - { - args->includeTileData = false; - } - else if(!strcmp(argv[i], "-tiles_only")) - { - args->includedMapOrMetaspriteData = false; - } - else if(!strcmp(argv[i], "-keep_duplicate_tiles")) - { - args->keep_duplicate_tiles = true; - } - else if(!strcmp(argv[i], "-no_palettes")) - { - args->include_palettes = false; - } - else if(!strcmp(argv[i], "-source_tileset")) - { - args->includeTileData = false; - args->source_tilesets.push_back(argv[++i]); - } - else if(!strcmp(argv[i], "-bin")) - { - args->output_binary = true; - } - else if(!strcmp(argv[i], "-transposed")) - { - args->output_transposed = true; - } - } + else if(pack_mode_str == "1bpp") args->pack_mode = Tile::BPP1; + else + { + printf("-pack_mode must be one of gb, nes, sgb, sms, 1bpp\n"); + return 1; + } + } + else if(!strcmp(argv[i], "-tile_origin")) + { + args->tile_origin = atoi(argv[++i]); + } + else if(!strcmp(argv[i], "-maps_only") || !strcmp(argv[i], "-metasprites_only")) + { + args->includeTileData = false; + } + else if(!strcmp(argv[i], "-tiles_only")) + { + args->includedMapOrMetaspriteData = false; + } + else if(!strcmp(argv[i], "-keep_duplicate_tiles")) + { + args->keep_duplicate_tiles = true; + } + else if(!strcmp(argv[i], "-no_palettes")) + { + args->include_palettes = false; + } + else if(!strcmp(argv[i], "-source_tileset")) + { + args->includeTileData = false; + args->source_tilesets.push_back(argv[++i]); + } + else if(!strcmp(argv[i], "-bin")) + { + args->output_binary = true; + } + else if(!strcmp(argv[i], "-transposed")) + { + args->output_transposed = true; + } + } - int slash_pos = (int)args->output_filename.find_last_of('/'); - if(slash_pos == -1) - slash_pos = (int)args->output_filename.find_last_of('\\'); - int dot_pos = (int)args->output_filename.find_first_of('.', slash_pos == -1 ? 0 : slash_pos); + int slash_pos = (int)args->output_filename.find_last_of('/'); + if(slash_pos == -1) + slash_pos = (int)args->output_filename.find_last_of('\\'); + int dot_pos = (int)args->output_filename.find_first_of('.', slash_pos == -1 ? 0 : slash_pos); - args->output_filename_h = args->output_filename.substr(0, dot_pos) + ".h"; - args->output_filename_bin = args->output_filename.substr(0, dot_pos) + "_map.bin"; - args->output_filename_attributes_bin = args->output_filename.substr(0, dot_pos) + "_map_attributes.bin"; - args->output_filename_tiles_bin = args->output_filename.substr(0, dot_pos) + "_tiles.bin"; - args->data_name = args->output_filename.substr(slash_pos + 1, dot_pos - 1 - slash_pos); - replace(args->data_name.begin(), args->data_name.end(), '-', '_'); + args->output_filename_h = args->output_filename.substr(0, dot_pos) + ".h"; + args->output_filename_bin = args->output_filename.substr(0, dot_pos) + "_map.bin"; + args->output_filename_attributes_bin = args->output_filename.substr(0, dot_pos) + "_map_attributes.bin"; + args->output_filename_tiles_bin = args->output_filename.substr(0, dot_pos) + "_tiles.bin"; + args->data_name = args->output_filename.substr(slash_pos + 1, dot_pos - 1 - slash_pos); + replace(args->data_name.begin(), args->data_name.end(), '-', '_'); - return 0; + return 0; } diff --git a/gbdk-support/png2asset/process_arguments.h b/gbdk-support/png2asset/process_arguments.h @@ -14,53 +14,53 @@ using namespace std; struct PNG2AssetArguments { - Vector2Size spriteSize; - Vector2Size map_attributes_size; - Vector2Size map_attributes_packed_size; - - Rectangle pivot; - - //default values for some params - - string output_filename_h; - string output_filename_bin; - string output_filename_attributes_bin; - string output_filename_tiles_bin; - string data_name; - string output_filename; - string input_filename; - vector<string> source_tilesets; - - size_t max_palettes; - - bool keep_palette_order; - bool repair_indexed_pal; - bool output_binary; - bool output_transposed; - bool export_as_map; - bool use_map_attributes; - bool use_2x2_map_attributes; - bool pack_map_attributes; - bool convert_rgb_to_nes; - bool includeTileData; - bool includedMapOrMetaspriteData; - bool keep_duplicate_tiles; - bool include_palettes; - bool use_structs; - bool flip_tiles; - - int errorCode; - int bank; - int sprite_mode; - int bpp; - int props_default; // Default Sprite props has no attributes enabled - - unsigned int tile_origin; // Default to no tile index offset - size_t extra_tile_count; - size_t source_total_color_count; // Total number of colors (palette_count x colors_per_palette) - unsigned int source_tileset_size; - - Tile::PackMode pack_mode; + Vector2Size spriteSize; + Vector2Size map_attributes_size; + Vector2Size map_attributes_packed_size; + + Rectangle pivot; + + //default values for some params + + string output_filename_h; + string output_filename_bin; + string output_filename_attributes_bin; + string output_filename_tiles_bin; + string data_name; + string output_filename; + string input_filename; + vector<string> source_tilesets; + + size_t max_palettes; + + bool keep_palette_order; + bool repair_indexed_pal; + bool output_binary; + bool output_transposed; + bool export_as_map; + bool use_map_attributes; + bool use_2x2_map_attributes; + bool pack_map_attributes; + bool convert_rgb_to_nes; + bool includeTileData; + bool includedMapOrMetaspriteData; + bool keep_duplicate_tiles; + bool include_palettes; + bool use_structs; + bool flip_tiles; + + int errorCode; + int bank; + int sprite_mode; + int bpp; + int props_default; // Default Sprite props has no attributes enabled + + unsigned int tile_origin; // Default to no tile index offset + size_t extra_tile_count; + size_t source_total_color_count; // Total number of colors (palette_count x colors_per_palette) + unsigned int source_tileset_size; + + Tile::PackMode pack_mode; int map_entry_size_bytes; }; diff --git a/gbdk-support/png2asset/tiles.cpp b/gbdk-support/png2asset/tiles.cpp @@ -2,28 +2,28 @@ Tile FlipH(const Tile& tile) { - Tile ret; - for(int j = (int)tile.data.size() - 8; j >= 0; j -= 8) - { - for(int i = 0; i < 8; ++i) - { - ret.data.push_back(tile.data[j + i]); - } - } - ret.pal = tile.pal; - return ret; + Tile ret; + for(int j = (int)tile.data.size() - 8; j >= 0; j -= 8) + { + for(int i = 0; i < 8; ++i) + { + ret.data.push_back(tile.data[j + i]); + } + } + ret.pal = tile.pal; + return ret; } Tile FlipV(const Tile& tile) { - Tile ret; - for(int j = 0; j < (int)tile.data.size(); j += 8) - { - for(int i = 7; i >= 0; --i) - { - ret.data.push_back(tile.data[j + i]); - } - } - ret.pal = tile.pal; - return ret; + Tile ret; + for(int j = 0; j < (int)tile.data.size(); j += 8) + { + for(int i = 7; i >= 0; --i) + { + ret.data.push_back(tile.data[j + i]); + } + } + ret.pal = tile.pal; + return ret; } diff --git a/gbdk-support/png2asset/vector2.h b/gbdk-support/png2asset/vector2.h @@ -2,18 +2,18 @@ struct Vector2Position { - int x, y; + int x, y; }; struct Vector2Size { - size_t width,height; + size_t width,height; }; struct Rectangle { - int x, y; - size_t width, height; + int x, y; + size_t width, height; };

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.