Skip to content
Permalink
Browse files
Added no-remap switch to shorthand command mode
  • Loading branch information
Optiroc committed May 3, 2019
1 parent ac6ebd1 commit 119d09810eed65cbd010ea7b4ad718bb1cc92d55
Showing with 33 additions and 22 deletions.
  1. +2 −1 README.md
  2. +1 −1 src/sfc_palette.cpp
  3. +30 −20 src/superfamiconv.cpp
@@ -30,6 +30,7 @@ In short hand mode, the following options are available:
-B --bpp Bits per pixel <default: 4>
-W --tile-width Tile width <default: 8>
-H --tile-height Tile height <default: 8>
-R --no-remap Don't remap colors <switch>
-D --no-discard Don't discard redundant tiles <switch>
-F --no-flip Don't discard using tile flipping <switch>
-S --sprite-mode Apply sprite output settings <switch>
@@ -53,7 +54,7 @@ Example:
Loaded image from "snes.png" (256x224px, indexed color)
Mapping optimized palette (16x16 entries)
Setting color zero to #505050
Generated palette with 24 colors [16,8]
Created palette with 24 colors [16,8]
Created optimized tileset with 156 entries (discarded 740 redudant tiles)
Mapping 896 8x8px tiles from image
Saved native palette data to "snes.palette"
@@ -114,7 +114,7 @@ int sfc_palette(int argc, char* argv[]) {
palette.add_images(image.crops(settings.tile_w, settings.tile_h));
}

if (verbose) fmt::print("Generated palette with {}\n", palette.description());
if (verbose) fmt::print("Created palette with {}\n", palette.description());

if (!settings.no_remap) {
palette.sort();
@@ -3,7 +3,6 @@
// david lindecrantz <optiroc@gmail.com>

// TODO: gbc sprite mode should set common color 0 transparency
// TODO: Add --no-remap to "shorthand" mode
// TODO: Check "shorthand" path for 16x16 tile conversion
// TODO: Don't always pad native palette output? (Pad every palette but the last? Option?)

@@ -32,6 +31,7 @@ struct Settings {
unsigned tile_w;
unsigned tile_h;

bool no_remap;
bool no_discard;
bool no_flip;
bool sprite_mode;
@@ -73,6 +73,7 @@ int superfamiconv(int argc, char* argv[]) {
options.Add(settings.bpp, 'B', "bpp", "Bits per pixel", unsigned(4), "Settings");
options.Add(settings.tile_w, 'W', "tile-width", "Tile width", unsigned(8), "Settings");
options.Add(settings.tile_h, 'H', "tile-height", "Tile height", unsigned(8), "Settings");
options.AddSwitch(settings.no_remap, 'R', "no-remap", "Don't remap colors", false, "Settings");
options.AddSwitch(settings.no_discard, 'D', "no-discard", "Don't discard redundant tiles", false, "Settings");
options.AddSwitch(settings.no_flip, 'F', "no-flip", "Don't discard using tile flipping", false, "Settings");
options.AddSwitch(settings.sprite_mode, 'S', "sprite-mode", "Apply sprite output settings", false, "Settings");
@@ -120,37 +121,46 @@ int superfamiconv(int argc, char* argv[]) {
try {
if (settings.in_image.empty()) throw std::runtime_error("Input image required");

sfc::Image in_image(settings.in_image);
if (verbose) fmt::print("Loaded image from \"{}\" ({})\n", settings.in_image, in_image.description());
sfc::Image image(settings.in_image);
if (verbose) fmt::print("Loaded image from \"{}\" ({})\n", settings.in_image, image.description());

// Make palette
sfc::Palette palette;
{
unsigned colors_per_palette = sfc::palette_size_at_bpp(settings.bpp);
unsigned palette_count = sfc::palette_count_for_mode(settings.mode, colors_per_palette);

if (verbose) fmt::print("Mapping optimized palette ({}x{} entries)\n", palette_count, colors_per_palette);
if (settings.no_remap) {
if (image.palette_size() == 0) throw std::runtime_error("no-remap requires indexed color image");
if (verbose) fmt::print("Mapping palette straight from indexed color image\n");

palette = sfc::Palette(settings.mode, palette_count, colors_per_palette);
palette = sfc::Palette(settings.mode, palette_count, colors_per_palette);
palette.add_colors(image.palette());

col0 = col0_forced ? col0 : in_image.crop(0, 0, 1, 1).rgba_data()[0];
} else {
if (verbose) fmt::print("Mapping optimized palette ({}x{} entries)\n", palette_count, colors_per_palette);

if (col0_forced || sfc::col0_is_shared_for_mode(settings.mode)) {
if (verbose) fmt::print("Setting color zero to {}\n", sfc::to_hexstring(col0, true, true));
palette.set_col0(col0);
}
palette = sfc::Palette(settings.mode, palette_count, colors_per_palette);

col0 = col0_forced ? col0 : image.crop(0, 0, 1, 1).rgba_data()[0];

palette.add_images(in_image.crops(settings.tile_w, settings.tile_h));
palette.sort();
if (verbose) fmt::print("Generated palette with {}\n", palette.description());
if (col0_forced || sfc::col0_is_shared_for_mode(settings.mode)) {
if (verbose) fmt::print("Setting color zero to {}\n", sfc::to_hexstring(col0, true, true));
palette.set_col0(col0);
}

palette.add_images(image.crops(settings.tile_w, settings.tile_h));
palette.sort();
}
if (verbose) fmt::print("Created palette with {}\n", palette.description());
}

// Make tileset
sfc::Tileset tileset(settings.mode, settings.bpp, settings.tile_w, settings.tile_h, settings.no_discard, settings.no_flip);
{
std::vector<sfc::Image> crops = in_image.crops(settings.tile_w, settings.tile_h);
std::vector<sfc::Image> crops = image.crops(settings.tile_w, settings.tile_h);

for (auto& image : crops) tileset.add(image, &palette);
for (auto& crop : crops) tileset.add(crop, &palette);
if (verbose) {
if (settings.no_discard) {
fmt::print("Created tileset with {} entries\n", tileset.size());
@@ -162,16 +172,16 @@ int superfamiconv(int argc, char* argv[]) {
}

// Make map
unsigned map_width = sfc::div_ceil(in_image.width(), settings.tile_w);
unsigned map_height = sfc::div_ceil(in_image.height(), settings.tile_h);
unsigned map_width = sfc::div_ceil(image.width(), settings.tile_w);
unsigned map_height = sfc::div_ceil(image.height(), settings.tile_h);

if (map_width * settings.tile_w != in_image.width() || map_height * settings.tile_h != in_image.height()) {
in_image = in_image.crop(0, 0, map_width * settings.tile_w, map_height * settings.tile_h);
if (map_width * settings.tile_w != image.width() || map_height * settings.tile_h != image.height()) {
image = image.crop(0, 0, map_width * settings.tile_w, map_height * settings.tile_h);
}

sfc::Map map(settings.mode, map_width, map_height);
{
std::vector<sfc::Image> crops = in_image.crops(settings.tile_w, settings.tile_h);
std::vector<sfc::Image> crops = image.crops(settings.tile_w, settings.tile_h);
if (verbose) fmt::print("Mapping {} {}x{}px tiles from image\n", crops.size(), settings.tile_w, settings.tile_h);

for (unsigned i = 0; i < crops.size(); ++i) {

0 comments on commit 119d098

Please sign in to comment.