19inline absl::StatusOr<std::vector<uint8_t>>
Decode(
20 std::span<const uint8_t> bytes,
int bpp) {
21 if (bpp < 2 || bpp > 4 || bytes.size() !=
static_cast<size_t>(64 * 8 * bpp))
22 return absl::InvalidArgumentError(
23 "A sprite graphics slot needs 64 complete 2bpp, 3bpp, or 4bpp tiles");
24 std::vector<uint8_t> pixels(4096, 0);
25 for (
int tile = 0; tile < 64; ++tile) {
27 for (
int y = 0; y < 8; ++y)
28 for (
int x = 0; x < 8; ++x)
29 pixels[((tile / 16) * 8 + y) * 128 + (tile % 16) * 8 + x] =
30 decoded.data[y * 8 + x];
36inline absl::StatusOr<std::vector<uint8_t>>
Resolve(
39 const std::filesystem::path& project_directory) {
40 if (source.
kind ==
"sheet") {
42 return absl::FailedPreconditionError(
43 "Sprite graphics sheet is unavailable in this ROM session");
45 return std::vector<uint8_t>(pixels.begin(), pixels.end());
47 if (source.
bpp < 2 || source.
bpp > 4)
48 return absl::InvalidArgumentError(
49 "Sprite graphics depth must be 2, 3, or 4");
50 const size_t length = 64 * 8 * source.
bpp;
51 if (source.
kind ==
"raw_rom") {
53 return absl::FailedPreconditionError(
"Load a ROM for raw ROM graphics");
55 return absl::OutOfRangeError(
56 "Sprite graphics range extends past the ROM");
58 std::span<const uint8_t>(rom->
vector().data() + source.
offset, length),
61 if (source.
kind !=
"bin" || source.
path.empty() ||
62 source.
path.find(
'\0') != std::string::npos)
63 return absl::InvalidArgumentError(
"Select a BIN path or raw ROM source");
64 auto path = std::filesystem::path(source.
path);
65 if (path.is_relative()) {
66 if (project_directory.empty())
67 return absl::FailedPreconditionError(
68 "Save a project or use an absolute BIN path");
69 path = project_directory / path;
72 if (!std::filesystem::is_regular_file(path, ec))
73 return absl::NotFoundError(
74 "Sprite graphics BIN is missing or unreadable: " + path.string());
75 std::ifstream input(path, std::ios::binary | std::ios::ate);
77 return absl::PermissionDeniedError(
"Cannot open sprite graphics BIN: " +
79 const auto end = input.tellg();
80 if (end < 0 ||
static_cast<uint64_t
>(end) < source.
offset ||
81 length >
static_cast<uint64_t
>(end) - source.
offset)
82 return absl::OutOfRangeError(
"Sprite graphics range extends past the BIN");
83 std::vector<uint8_t> bytes(length);
84 input.seekg(source.
offset);
85 if (!input.read(
reinterpret_cast<char*
>(bytes.data()), bytes.size()))
86 return absl::DataLossError(
"Could not read complete sprite graphics slot");