shithub: rgbds

Download patch

ref: a1a919579cf3065eb2408319d78f58bc81549227
parent: a47da5f71f1b755b3a2fa03736cda60534dfb639
author: Eldred Habert <[email protected]>
date: Fri Sep 30 19:09:28 EDT 2022

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

Fixes #1063

--- a/src/gfx/pal_spec.cpp
+++ b/src/gfx/pal_spec.cpp
@@ -191,6 +191,15 @@
 	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`.
  */
@@ -295,7 +304,7 @@
 	}
 }
 
-void parseACTFile(std::filebuf &file) {
+static void parseACTFile(std::filebuf &file) {
 	// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1070626
 
 	std::array<char, 772> buf;
@@ -344,8 +353,8 @@
 	}
 }
 
-void parseACOFile(std::filebuf &file) {
-	// rhttps://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819
+static void parseACOFile(std::filebuf &file) {
+	// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_pgfId-1055819
 	// http://www.nomodes.com/aco.html
 
 	char buf[10];
@@ -412,6 +421,29 @@
 	// `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) {
 	// `fmt:path`, parse the file according to the given format
 
@@ -427,6 +459,7 @@
 	    std::tuple{"PSP", &parsePSPFile, std::ios::in    },
 	    std::tuple{"ACT", &parseACTFile, 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(),
--- a/src/gfx/process.cpp
+++ b/src/gfx/process.cpp
@@ -997,7 +997,7 @@
 				 *         protoPalettes.erase(protoPalettes.begin() + i);
 				 *     }
 				 * }
-				*/
+				 */
 				[[fallthrough]];
 
 			case ProtoPalette::THEY_BIGGER: