mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Move struct Palette into its own file (#1850)
This commit is contained in:
@@ -220,6 +220,8 @@ These files have been copied ("vendored") from external authors and adapted for
|
||||
Functions for sorting colors within palettes, which works differently for grayscale, RGB, or indexed-color palettes.
|
||||
- **`pal_spec.cpp`:**
|
||||
Functions for parsing various formats of palette specifications (from `-c/--colors`).
|
||||
- **`palette.cpp`:**
|
||||
`Palette` methods for working with up to four GBC-native (RGB555) colors.
|
||||
- **`png.cpp`:**
|
||||
`Png` methods for reading PNG image files, standardizing them to 8-bit RGBA pixels while also reading their indexed palette if there is one.
|
||||
- **`process.cpp`:**
|
||||
|
||||
1
Makefile
1
Makefile
@@ -118,6 +118,7 @@ rgbgfx_obj := \
|
||||
src/gfx/pal_packing.o \
|
||||
src/gfx/pal_sorting.o \
|
||||
src/gfx/pal_spec.o \
|
||||
src/gfx/palette.o \
|
||||
src/gfx/png.o \
|
||||
src/gfx/process.o \
|
||||
src/gfx/reverse.o \
|
||||
|
||||
23
include/gfx/flip.hpp
Normal file
23
include/gfx/flip.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#ifndef RGBDS_GFX_FLIP_HPP
|
||||
#define RGBDS_GFX_FLIP_HPP
|
||||
|
||||
#include <array>
|
||||
#include <stdint.h>
|
||||
|
||||
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
|
||||
static std::array<uint16_t, 256> flipTable = ([]() constexpr {
|
||||
std::array<uint16_t, 256> table{};
|
||||
for (uint16_t i = 0; i < table.size(); ++i) {
|
||||
// To flip all the bits, we'll flip both nibbles, then each nibble half, etc.
|
||||
uint16_t byte = i;
|
||||
byte = (byte & 0b0000'1111) << 4 | (byte & 0b1111'0000) >> 4;
|
||||
byte = (byte & 0b0011'0011) << 2 | (byte & 0b1100'1100) >> 2;
|
||||
byte = (byte & 0b0101'0101) << 1 | (byte & 0b1010'1010) >> 1;
|
||||
table[i] = byte;
|
||||
}
|
||||
return table;
|
||||
})();
|
||||
|
||||
#endif // RGBDS_GFX_FLIP_HPP
|
||||
@@ -5,12 +5,11 @@
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "helpers.hpp"
|
||||
#include "helpers.hpp" // assume
|
||||
|
||||
#include "gfx/rgba.hpp"
|
||||
|
||||
@@ -69,35 +68,4 @@ struct Options {
|
||||
|
||||
extern Options options;
|
||||
|
||||
struct Palette {
|
||||
// An array of 4 GBC-native (RGB555) colors
|
||||
std::array<uint16_t, 4> colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
||||
|
||||
void addColor(uint16_t color);
|
||||
uint8_t indexOf(uint16_t color) const;
|
||||
uint16_t &operator[](size_t index) { return colors[index]; }
|
||||
uint16_t const &operator[](size_t index) const { return colors[index]; }
|
||||
|
||||
decltype(colors)::iterator begin();
|
||||
decltype(colors)::iterator end();
|
||||
decltype(colors)::const_iterator begin() const;
|
||||
decltype(colors)::const_iterator end() const;
|
||||
|
||||
uint8_t size() const;
|
||||
};
|
||||
|
||||
// Flipping tends to happen fairly often, so take a bite out of dcache to speed it up
|
||||
static std::array<uint16_t, 256> flipTable = ([]() constexpr {
|
||||
std::array<uint16_t, 256> table{};
|
||||
for (uint16_t i = 0; i < table.size(); ++i) {
|
||||
// To flip all the bits, we'll flip both nibbles, then each nibble half, etc.
|
||||
uint16_t byte = i;
|
||||
byte = (byte & 0b0000'1111) << 4 | (byte & 0b1111'0000) >> 4;
|
||||
byte = (byte & 0b0011'0011) << 2 | (byte & 0b1100'1100) >> 2;
|
||||
byte = (byte & 0b0101'0101) << 1 | (byte & 0b1010'1010) >> 1;
|
||||
table[i] = byte;
|
||||
}
|
||||
return table;
|
||||
})();
|
||||
|
||||
#endif // RGBDS_GFX_MAIN_HPP
|
||||
|
||||
27
include/gfx/palette.hpp
Normal file
27
include/gfx/palette.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#ifndef RGBDS_GFX_PALETTE_HPP
|
||||
#define RGBDS_GFX_PALETTE_HPP
|
||||
|
||||
#include <array>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct Palette {
|
||||
// An array of 4 GBC-native (RGB555) colors
|
||||
std::array<uint16_t, 4> colors{UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
||||
|
||||
void addColor(uint16_t color);
|
||||
uint8_t indexOf(uint16_t color) const;
|
||||
uint16_t &operator[](size_t index) { return colors[index]; }
|
||||
uint16_t const &operator[](size_t index) const { return colors[index]; }
|
||||
|
||||
decltype(colors)::iterator begin();
|
||||
decltype(colors)::iterator end();
|
||||
decltype(colors)::const_iterator begin() const;
|
||||
decltype(colors)::const_iterator end() const;
|
||||
|
||||
uint8_t size() const;
|
||||
};
|
||||
|
||||
#endif // RGBDS_GFX_PALETTE_HPP
|
||||
@@ -92,6 +92,7 @@ set(rgbgfx_src
|
||||
"gfx/pal_packing.cpp"
|
||||
"gfx/pal_sorting.cpp"
|
||||
"gfx/pal_spec.cpp"
|
||||
"gfx/palette.cpp"
|
||||
"gfx/png.cpp"
|
||||
"gfx/process.cpp"
|
||||
"gfx/reverse.cpp"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "gfx/main.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <ios>
|
||||
@@ -848,47 +847,3 @@ int main(int argc, char *argv[]) {
|
||||
requireZeroErrors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Palette::addColor(uint16_t color) {
|
||||
for (size_t i = 0; true; ++i) {
|
||||
assume(i < colors.size()); // The packing should guarantee this
|
||||
if (colors[i] == color) { // The color is already present
|
||||
break;
|
||||
} else if (colors[i] == UINT16_MAX) { // Empty slot
|
||||
colors[i] = color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the ID of the color in the palette, or `size()` if the color is not in
|
||||
uint8_t Palette::indexOf(uint16_t color) const {
|
||||
return color == Rgba::transparent
|
||||
? 0
|
||||
: std::find(begin(), colors.end(), color) - begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::begin() -> decltype(colors)::iterator {
|
||||
// Skip the first slot if reserved for transparency
|
||||
return colors.begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::end() -> decltype(colors)::iterator {
|
||||
// Return an iterator pointing past the last non-empty element.
|
||||
// Since the palette may contain gaps, we must scan from the end.
|
||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||
}
|
||||
|
||||
auto Palette::begin() const -> decltype(colors)::const_iterator {
|
||||
// Same as the non-const begin().
|
||||
return colors.begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::end() const -> decltype(colors)::const_iterator {
|
||||
// Same as the non-const end().
|
||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||
}
|
||||
|
||||
uint8_t Palette::size() const {
|
||||
return end() - colors.begin();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "helpers.hpp"
|
||||
#include "verbosity.hpp"
|
||||
|
||||
#include "gfx/main.hpp"
|
||||
#include "gfx/palette.hpp"
|
||||
#include "gfx/rgba.hpp"
|
||||
|
||||
void sortIndexed(std::vector<Palette> &palettes, std::vector<Rgba> const &embPal) {
|
||||
|
||||
55
src/gfx/palette.cpp
Normal file
55
src/gfx/palette.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "gfx/palette.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
#include "gfx/main.hpp"
|
||||
#include "gfx/rgba.hpp"
|
||||
|
||||
void Palette::addColor(uint16_t color) {
|
||||
for (size_t i = 0; true; ++i) {
|
||||
assume(i < colors.size()); // The packing should guarantee this
|
||||
if (colors[i] == color) { // The color is already present
|
||||
break;
|
||||
} else if (colors[i] == UINT16_MAX) { // Empty slot
|
||||
colors[i] = color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the ID of the color in the palette, or `size()` if the color is not in
|
||||
uint8_t Palette::indexOf(uint16_t color) const {
|
||||
return color == Rgba::transparent
|
||||
? 0
|
||||
: std::find(begin(), colors.end(), color) - begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::begin() -> decltype(colors)::iterator {
|
||||
// Skip the first slot if reserved for transparency
|
||||
return colors.begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::end() -> decltype(colors)::iterator {
|
||||
// Return an iterator pointing past the last non-empty element.
|
||||
// Since the palette may contain gaps, we must scan from the end.
|
||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||
}
|
||||
|
||||
auto Palette::begin() const -> decltype(colors)::const_iterator {
|
||||
// Same as the non-const begin().
|
||||
return colors.begin() + options.hasTransparentPixels;
|
||||
}
|
||||
|
||||
auto Palette::end() const -> decltype(colors)::const_iterator {
|
||||
// Same as the non-const end().
|
||||
return std::find_if(RRANGE(colors), [](uint16_t c) { return c != UINT16_MAX; }).base();
|
||||
}
|
||||
|
||||
uint8_t Palette::size() const {
|
||||
return end() - colors.begin();
|
||||
}
|
||||
@@ -26,9 +26,11 @@
|
||||
#include "verbosity.hpp"
|
||||
|
||||
#include "gfx/color_set.hpp"
|
||||
#include "gfx/flip.hpp"
|
||||
#include "gfx/main.hpp"
|
||||
#include "gfx/pal_packing.hpp"
|
||||
#include "gfx/pal_sorting.hpp"
|
||||
#include "gfx/palette.hpp"
|
||||
#include "gfx/png.hpp"
|
||||
#include "gfx/rgba.hpp"
|
||||
#include "gfx/warning.hpp"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "helpers.hpp" // assume
|
||||
#include "verbosity.hpp"
|
||||
|
||||
#include "gfx/flip.hpp"
|
||||
#include "gfx/main.hpp"
|
||||
#include "gfx/rgba.hpp"
|
||||
#include "gfx/warning.hpp"
|
||||
|
||||
Reference in New Issue
Block a user