Add support for GBC palette dumps to -c (#1075)

Fixes #1063
This commit is contained in:
Eldred Habert
2022-09-30 23:09:28 +02:00
committed by GitHub
parent a47da5f71f
commit a1a919579c
2 changed files with 37 additions and 4 deletions

View File

@@ -191,6 +191,15 @@ static T readBE(U const *bytes) {
return val; return val;
} }
template<typename T, typename U>
static T readLE(U const *bytes) {
T val = 0;
for (size_t i = 0; i < sizeof(val); ++i) {
val |= static_cast<uint8_t>(bytes[i]) << (i * 8);
}
return val;
}
/* /*
* **Appends** the first line read from `file` to the end of the provided `buffer`. * **Appends** the first line read from `file` to the end of the provided `buffer`.
*/ */
@@ -295,7 +304,7 @@ static void parsePSPFile(std::filebuf &file) {
} }
} }
void parseACTFile(std::filebuf &file) { static void parseACTFile(std::filebuf &file) {
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626 // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626
std::array<char, 772> buf; std::array<char, 772> buf;
@@ -344,8 +353,8 @@ void parseACTFile(std::filebuf &file) {
} }
} }
void parseACOFile(std::filebuf &file) { static void parseACOFile(std::filebuf &file) {
// rhttps://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819 // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819
// http://www.nomodes.com/aco.html // http://www.nomodes.com/aco.html
char buf[10]; char buf[10];
@@ -412,6 +421,29 @@ void parseACOFile(std::filebuf &file) {
// `codecvt` can be used to convert from UTF-16 to UTF-8 // `codecvt` can be used to convert from UTF-16 to UTF-8
} }
static void parseGBCFile(std::filebuf &file) {
// This only needs to be able to read back files generated by `rgbgfx -p`
options.palSpec.clear();
for (;;) {
char buf[2 * 4];
auto len = file.sgetn(buf, sizeof(buf));
if (len == 0) {
break;
} else if (len != sizeof(buf)) {
error("GBC palette dump contains %zu 8-byte palette%s, plus %zu byte%s",
options.palSpec.size(), options.palSpec.size() == 1 ? "" : "s",
len, len == 1 ? "" : "s");
break;
}
options.palSpec.push_back({Rgba::fromCGBColor(readLE<uint16_t>(&buf[0])),
Rgba::fromCGBColor(readLE<uint16_t>(&buf[2])),
Rgba::fromCGBColor(readLE<uint16_t>(&buf[4])),
Rgba::fromCGBColor(readLE<uint16_t>(&buf[6]))});
}
}
void parseExternalPalSpec(char const *arg) { void parseExternalPalSpec(char const *arg) {
// `fmt:path`, parse the file according to the given format // `fmt:path`, parse the file according to the given format
@@ -427,6 +459,7 @@ void parseExternalPalSpec(char const *arg) {
std::tuple{"PSP", &parsePSPFile, std::ios::in }, std::tuple{"PSP", &parsePSPFile, std::ios::in },
std::tuple{"ACT", &parseACTFile, std::ios::binary}, std::tuple{"ACT", &parseACTFile, std::ios::binary},
std::tuple{"ACO", &parseACOFile, std::ios::binary}, std::tuple{"ACO", &parseACOFile, std::ios::binary},
std::tuple{"GBC", &parseGBCFile, std::ios::binary},
}; };
auto iter = std::find_if(parsers.begin(), parsers.end(), auto iter = std::find_if(parsers.begin(), parsers.end(),