summary refs log tree commit diff stats
path: root/tools/sprite_dumper/common.h
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2021-01-31 20:04:51 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2021-01-31 20:04:51 -0500
commita64c85a3f5641581a19ef52a5c7898ec3cb71754 (patch)
tree8df10037fa552887966d9f0d5b147e0fd35abbf4 /tools/sprite_dumper/common.h
parent66e8f5b7d5d245bb7f5d4c4963e70e6b97e0bd4d (diff)
downloadtanetane-a64c85a3f5641581a19ef52a5c7898ec3cb71754.tar.gz
tanetane-a64c85a3f5641581a19ef52a5c7898ec3cb71754.tar.bz2
tanetane-a64c85a3f5641581a19ef52a5c7898ec3cb71754.zip
Abstracted some of the sprite dumper functionality out
Diffstat (limited to 'tools/sprite_dumper/common.h')
-rw-r--r--tools/sprite_dumper/common.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/tools/sprite_dumper/common.h b/tools/sprite_dumper/common.h new file mode 100644 index 0000000..dca5de9 --- /dev/null +++ b/tools/sprite_dumper/common.h
@@ -0,0 +1,139 @@
1#ifndef COMMON_H_04DD2B2A
2#define COMMON_H_04DD2B2A
3
4#include <vector>
5#include <string_view>
6#include <fstream>
7#include <stdexcept>
8
9class BufferView {
10public:
11
12 BufferView(const std::vector<char>& buffer) : data_(&buffer) {}
13
14 int ReadNextByte() {
15 int o2r = offset_;
16 offset_++;
17 return ReadByte(o2r);
18 }
19
20 int ReadByte(int addr) const {
21 return static_cast<unsigned char>((*data_)[addr]);
22 }
23
24 int ReadNextTwoBytes() {
25 int o2r = offset_;
26 offset_+=2;
27 return ReadTwoBytes(o2r);
28 }
29
30 int ReadTwoBytes(int addr) const {
31 return static_cast<unsigned char>((*data_)[addr]) | (static_cast<unsigned char>((*data_)[addr + 1]) << 8);
32 }
33
34 int ReadNextFourBytes() {
35 int o2r = offset_;
36 offset_+=4;
37 return ReadFourBytes(o2r);
38 }
39
40 unsigned long ReadFourBytes(int addr) const {
41 return static_cast<unsigned char>((*data_)[addr]) | (static_cast<unsigned char>((*data_)[addr + 1]) << 8) | (static_cast<unsigned char>((*data_)[addr + 2]) << 16) | (static_cast<unsigned char>((*data_)[addr + 3]) << 24);
42 }
43
44 void Seek(int offset) {
45 offset_ = offset;
46 }
47
48 void SeekAdd(int delta) {
49 offset_ += delta;
50 }
51
52 std::vector<char> Decompress(int addr) {
53 int start = addr;
54 Seek(addr);
55 if (ReadNextByte() != 0x10) {
56 throw std::domain_error("No LZ77 signature");
57 }
58
59 int length = ReadNextByte();
60 length += (ReadNextByte() << 8);
61 length += (ReadNextByte() << 16);
62
63 std::vector<char> result(length, 0);
64
65 int bPos = 0;
66 while (bPos < length) {
67 unsigned char ch = ReadNextByte();
68 for (int i=0;i<8;i++) {
69 switch ((ch >> (7-i)) & 1) {
70 case 0: {
71 if (bPos >= length) break;
72 result[bPos++] = ReadNextByte();
73 break;
74 }
75 case 1: {
76 int t = (ReadNextByte() << 8);
77 t += ReadNextByte();
78 int n = ((t >> 12) & 0xF) + 3; // num of bytes to copy
79 int o = (t & 0xFFF);
80
81 memcpy(result.data() + bPos, result.data() + bPos - o - 1, n);
82 bPos += n;
83 break;
84 }
85 default: break;
86 }
87 }
88 }
89
90 return result;
91 }
92
93private:
94
95 const std::vector<char>* data_;
96 int offset_ = 0;
97};
98
99class Rom {
100public:
101
102 explicit Rom(std::string_view filename) {
103 std::ifstream romfile(filename.data(), std::ios::binary);
104 if (!romfile.is_open()) {
105 throw std::invalid_argument("Could not find ROM file: " + std::string(filename));
106 }
107
108 romfile.seekg(0, romfile.end);
109 int length = romfile.tellg();
110 romfile.seekg(0, romfile.beg);
111
112 if (length != 0x2000000) {
113 throw std::invalid_argument("Incorrect ROM length");
114 }
115
116 data_ = std::vector<char>(length, 0);
117 romfile.read(data_.data(), length);
118
119 const char header[] = {'M','O','T','H','E','R','3',0,0,0,0,0,'A','3','U','J'};
120 std::string headerTest;
121 for (int i = 0xA0; i < 0xB0; i++) {
122 if (data_.at(i) != header[i-0xA0]) {
123 std::cout << i << std::endl;
124
125 throw std::invalid_argument("Invalid ROM header");
126 }
127 }
128 }
129
130 const std::vector<char>& data() const { return data_; }
131
132 BufferView buffer() const { return {data_}; }
133
134private:
135
136 std::vector<char> data_;
137};
138
139#endif /* end of include guard: COMMON_H_04DD2B2A */