Skip to content

Commit d961867

Browse files
Read palette arrays from JSON manifest files
1 parent 0732a07 commit d961867

3 files changed

Lines changed: 80 additions & 2 deletions

File tree

tools/gxc/src/SpriteManifest.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static SpriteManifest::Format parseFormat(const nlohmann::json& jFormat, const b
4141
else if (value == "palette" && hasImageFile)
4242
return SpriteManifest::Format::paletteImage;
4343
else if (value == "palette")
44-
return SpriteManifest::Format::paletteHex;
44+
return SpriteManifest::Format::paletteArray;
4545
else
4646
throw std::runtime_error("Unknown format");
4747
}
@@ -117,6 +117,43 @@ static std::optional<Range> parseRange(std::string_view s)
117117
return std::nullopt;
118118
}
119119

120+
static BGRColour parseJSONPaletteColour(const std::string& s)
121+
{
122+
uint8_t r = 0;
123+
uint8_t g = 0;
124+
uint8_t b = 0;
125+
if (s[0] == '#' && s.size() == 7)
126+
{
127+
// Expect #RRGGBB
128+
r = std::stoul(s.substr(1, 2), nullptr, 16) & 0xFF;
129+
g = std::stoul(s.substr(3, 2), nullptr, 16) & 0xFF;
130+
b = std::stoul(s.substr(5, 2), nullptr, 16) & 0xFF;
131+
}
132+
return { b, g, r };
133+
}
134+
135+
static std::vector<BGRColour> parseColours(const nlohmann::json& jPalette)
136+
{
137+
if (!jPalette.is_object())
138+
throw std::runtime_error("parseColours expects parameter jPalette to be an object");
139+
140+
auto jColours = jPalette["colours"];
141+
std::vector<BGRColour> out;
142+
143+
auto numColours = jColours.size();
144+
out.reserve(numColours * 3);
145+
146+
for (auto& jColour : jColours)
147+
{
148+
if (!jColour.is_string())
149+
throw std::runtime_error("Encountered a value that is not a string!");
150+
151+
out.push_back(parseJSONPaletteColour(jColour.get<std::string>()));
152+
}
153+
154+
return out;
155+
}
156+
120157
static SpriteManifest::Entry parseEntry(const nlohmann::json& jEntry)
121158
{
122159
SpriteManifest::Entry result;
@@ -150,14 +187,22 @@ static SpriteManifest::Entry parseEntry(const nlohmann::json& jEntry)
150187
if (jEntry.contains("path"))
151188
result.path = jEntry.at("path").get<std::string>();
152189
if (jEntry.contains("format"))
153-
result.format = parseFormat(jEntry["format"], jEntry.contains("path"));
190+
result.format = parseFormat(jEntry["format"], result.path.empty());
191+
154192
if (jEntry.contains("palette"))
155193
result.palette = parsePalette(jEntry["palette"]);
194+
if (jEntry.contains("colours"))
195+
result.colours = parseColours(jEntry);
196+
197+
if (result.format == SpriteManifest::Format::automatic && !result.colours.empty())
198+
result.format = SpriteManifest::Format::paletteArray;
156199

157200
if (jEntry.contains("x"))
158201
result.offsetX = jEntry["x"];
159202
else if (jEntry.contains("x_offset"))
160203
result.offsetX = jEntry["x_offset"];
204+
else if (jEntry.contains("index")) // palette startIndex
205+
result.offsetX = jEntry["index"]; // palette startIndex
161206

162207
if (jEntry.contains("y"))
163208
result.offsetY = jEntry["y"];

tools/gxc/src/SpriteManifest.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77

88
namespace gxc
99
{
10+
struct BGRColour
11+
{
12+
uint8_t blue{};
13+
uint8_t green{};
14+
uint8_t red{};
15+
};
16+
17+
using ColourVector = std::vector<BGRColour>;
18+
1019
class SpriteArchive;
1120

1221
class SpriteManifest
@@ -33,6 +42,7 @@ namespace gxc
3342
fs::path path;
3443
Format format{};
3544
PaletteKind palette{};
45+
ColourVector colours{};
3646
int32_t offsetX{};
3747
int32_t offsetY{};
3848
int32_t zoomOffset{};

tools/gxc/src/gxc.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ static void encodePaletteFromImage(Stream& stream, const Image& image)
6060
}
6161
}
6262

63+
static void encodePaletteFromArray(Stream& stream, const std::vector<BGRColour>& colours)
64+
{
65+
for (auto& colour : colours)
66+
{
67+
stream.write(&colour, 3);
68+
}
69+
}
70+
6371
static std::string stringifyFlags(uint16_t flags)
6472
{
6573
std::string result;
@@ -136,6 +144,21 @@ int runBuild(const CommandLineOptions& options)
136144
}
137145
try
138146
{
147+
// Palette arrays don't have an image to load, so start with those
148+
if (manifestEntry.format == SpriteManifest::Format::paletteArray)
149+
{
150+
MemoryStream ms;
151+
encodePaletteFromArray(ms, manifestEntry.colours);
152+
153+
SpriteArchive::Entry entry;
154+
entry.width = manifestEntry.colours.size();
155+
entry.height = 1;
156+
entry.offsetX = manifestEntry.offsetX;
157+
entry.flags = GxFlags::isPalette;
158+
archive.addEntry(entry, ms.asSpan<const std::byte>());
159+
continue;
160+
}
161+
139162
auto imageCacheIterator = imageCache.find(manifestEntry.path);
140163
if (imageCacheIterator == imageCache.end())
141164
{

0 commit comments

Comments
 (0)