Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
decode.cpp
Go to the documentation of this file.
1#include <haio_codec.hpp>
2#include <haio_codecs.hpp>
3#include <haio_convert.hpp>
4
5namespace {
6
7/**
8 * a pattern table: four kilobytes, which is 256 tiles, which is 128 by 128 pixels.
9 *
10 * this is the unit people mean by a chr bank when they look at one, and it is why
11 * every tool that shows chr data shows a 128 by 128 square.
12 */
13constexpr size_t bankBytes = 4096;
14constexpr int bankSide = 128;
15
16}
17
18namespace Haio::Codecs {
19
20/**
21 * every pattern table in the cartridge, stacked one below another.
22 *
23 * the header says where they start: sixteen bytes of it, then a trainer if there is
24 * one, then the program itself, and only then the pattern data. picking which bank
25 * to look at is left to the caller, because by then it is a crop.
26 *
27 * @todo a cartridge with no chr rom keeps its patterns in ram and builds them as it
28 * runs, so there is nothing in the file to show. those are refused rather than drawn
29 * as an empty square.
30 */
31template <>
33 const auto& data = blob.data;
34 if (data.size() < 16) HAIO_FAIL(InvalidInput, "this file is too short to be a rom");
35
36 const size_t programBanks = data[4];
37 const size_t patternBanks = static_cast<size_t>(data[5]) * 2; // 8k of chr is two tables
38 const bool hasTrainer = (data[6] & 4) != 0;
39
40 if (patternBanks == 0) {
41 HAIO_FAIL(UnsupportedFormat, "this cartridge builds its patterns as it runs, so the file holds none");
42 }
43
44 const auto from = 16 + (hasTrainer ? 512u : 0u) + programBanks * 16384;
45 if (from + patternBanks * bankBytes > data.size()) {
46 HAIO_FAIL(InvalidInput, "the rom header promises more pattern data than the file holds");
47 }
48
49 std::vector<uint8_t> out(data.begin() + from, data.begin() + from + patternBanks * bankBytes);
50 return Image<Color::CHR_NES>{bankSide, bankSide * static_cast<int>(patternBanks), std::move(out)};
51}
52
53}
#define HAIO_FAIL(why, message)
Result< Image< Color::CHR_NES > > Decode< Format::ROM, Color::CHR_NES >(const Blob &blob)
Definition decode.cpp:32
std::vector< uint8_t > data
std::expected< T, Error > Result