Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/mosaic/context.hpp
2 views
1
#ifdef NALL_MOSAIC_INTERNAL_HPP
2
3
namespace nall {
4
namespace mosaic {
5
6
struct context {
7
unsigned offset;
8
unsigned width;
9
unsigned height;
10
unsigned count;
11
12
bool endian; //0 = lsb, 1 = msb
13
bool order; //0 = linear, 1 = planar
14
unsigned depth; //1 - 24bpp
15
16
unsigned blockWidth;
17
unsigned blockHeight;
18
unsigned blockStride;
19
unsigned blockOffset;
20
array<unsigned> block;
21
22
unsigned tileWidth;
23
unsigned tileHeight;
24
unsigned tileStride;
25
unsigned tileOffset;
26
array<unsigned> tile;
27
28
unsigned mosaicWidth;
29
unsigned mosaicHeight;
30
unsigned mosaicStride;
31
unsigned mosaicOffset;
32
array<unsigned> mosaic;
33
34
unsigned paddingWidth;
35
unsigned paddingHeight;
36
unsigned paddingColor;
37
array<unsigned> palette;
38
39
inline unsigned objectWidth() const { return blockWidth * tileWidth * mosaicWidth + paddingWidth; }
40
inline unsigned objectHeight() const { return blockHeight * tileHeight * mosaicHeight + paddingHeight; }
41
inline unsigned objectSize() const {
42
unsigned size = blockStride * tileWidth * tileHeight * mosaicWidth * mosaicHeight
43
+ blockOffset * tileHeight * mosaicWidth * mosaicHeight
44
+ tileStride * mosaicWidth * mosaicHeight
45
+ tileOffset * mosaicHeight;
46
return max(1u, size);
47
}
48
49
inline unsigned eval(const string &expression) {
50
intmax_t result;
51
if(fixedpoint::eval(expression, result) == false) return 0u;
52
return result;
53
}
54
55
inline void eval(array<unsigned> &buffer, const string &expression_) {
56
string expression = expression_;
57
bool function = false;
58
for(auto &c : expression) {
59
if(c == '(') function = true;
60
if(c == ')') function = false;
61
if(c == ',' && function == true) c = ';';
62
}
63
64
lstring list = expression.split(",");
65
for(auto &item : list) {
66
item.trim();
67
if(item.wildcard("f(?*) ?*")) {
68
item.ltrim<1>("f(");
69
lstring part = item.split<1>(") ");
70
lstring args = part[0].split<3>(";");
71
for(auto &item : args) item.trim();
72
73
unsigned length = eval(args(0, "0"));
74
unsigned offset = eval(args(1, "0"));
75
unsigned stride = eval(args(2, "0"));
76
if(args.size() < 2) offset = buffer.size();
77
if(args.size() < 3) stride = 1;
78
79
for(unsigned n = 0; n < length; n++) {
80
string fn = part[1];
81
fn.replace("n", decimal(n));
82
fn.replace("o", decimal(offset));
83
fn.replace("p", decimal(buffer.size()));
84
buffer.resize(offset + 1);
85
buffer[offset] = eval(fn);
86
offset += stride;
87
}
88
} else if(item.wildcard("base64*")) {
89
unsigned offset = 0;
90
item.ltrim<1>("base64");
91
if(item.wildcard("(?*) *")) {
92
item.ltrim<1>("(");
93
lstring part = item.split<1>(") ");
94
offset = eval(part[0]);
95
item = part(1, "");
96
}
97
item.trim();
98
for(auto &c : item) {
99
if(c >= 'A' && c <= 'Z') buffer.append(offset + c - 'A' + 0);
100
if(c >= 'a' && c <= 'z') buffer.append(offset + c - 'a' + 26);
101
if(c >= '0' && c <= '9') buffer.append(offset + c - '0' + 52);
102
if(c == '-') buffer.append(offset + 62);
103
if(c == '_') buffer.append(offset + 63);
104
}
105
} else if(item.wildcard("file *")) {
106
item.ltrim<1>("file ");
107
item.trim();
108
//...
109
} else if(item.empty() == false) {
110
buffer.append(eval(item));
111
}
112
}
113
}
114
115
inline void parse(const string &data) {
116
reset();
117
118
lstring lines = data.split("\n");
119
for(auto &line : lines) {
120
lstring part = line.split<1>(":");
121
if(part.size() != 2) continue;
122
part[0].trim();
123
part[1].trim();
124
125
if(part[0] == "offset") offset = eval(part[1]);
126
if(part[0] == "width") width = eval(part[1]);
127
if(part[0] == "height") height = eval(part[1]);
128
if(part[0] == "count") count = eval(part[1]);
129
130
if(part[0] == "endian") endian = eval(part[1]);
131
if(part[0] == "order") order = eval(part[1]);
132
if(part[0] == "depth") depth = eval(part[1]);
133
134
if(part[0] == "blockWidth") blockWidth = eval(part[1]);
135
if(part[0] == "blockHeight") blockHeight = eval(part[1]);
136
if(part[0] == "blockStride") blockStride = eval(part[1]);
137
if(part[0] == "blockOffset") blockOffset = eval(part[1]);
138
if(part[0] == "block") eval(block, part[1]);
139
140
if(part[0] == "tileWidth") tileWidth = eval(part[1]);
141
if(part[0] == "tileHeight") tileHeight = eval(part[1]);
142
if(part[0] == "tileStride") tileStride = eval(part[1]);
143
if(part[0] == "tileOffset") tileOffset = eval(part[1]);
144
if(part[0] == "tile") eval(tile, part[1]);
145
146
if(part[0] == "mosaicWidth") mosaicWidth = eval(part[1]);
147
if(part[0] == "mosaicHeight") mosaicHeight = eval(part[1]);
148
if(part[0] == "mosaicStride") mosaicStride = eval(part[1]);
149
if(part[0] == "mosaicOffset") mosaicOffset = eval(part[1]);
150
if(part[0] == "mosaic") eval(mosaic, part[1]);
151
152
if(part[0] == "paddingWidth") paddingWidth = eval(part[1]);
153
if(part[0] == "paddingHeight") paddingHeight = eval(part[1]);
154
if(part[0] == "paddingColor") paddingColor = eval(part[1]);
155
if(part[0] == "palette") eval(palette, part[1]);
156
}
157
158
sanitize();
159
}
160
161
inline bool load(const string &filename) {
162
string filedata;
163
if(filedata.readfile(filename) == false) return false;
164
parse(filedata);
165
return true;
166
}
167
168
inline void sanitize() {
169
if(depth < 1) depth = 1;
170
if(depth > 24) depth = 24;
171
172
if(blockWidth < 1) blockWidth = 1;
173
if(blockHeight < 1) blockHeight = 1;
174
175
if(tileWidth < 1) tileWidth = 1;
176
if(tileHeight < 1) tileHeight = 1;
177
178
if(mosaicWidth < 1) mosaicWidth = 1;
179
if(mosaicHeight < 1) mosaicHeight = 1;
180
}
181
182
inline void reset() {
183
offset = 0;
184
width = 0;
185
height = 0;
186
count = 0;
187
188
endian = 1;
189
order = 0;
190
depth = 1;
191
192
blockWidth = 1;
193
blockHeight = 1;
194
blockStride = 0;
195
blockOffset = 0;
196
block.reset();
197
198
tileWidth = 1;
199
tileHeight = 1;
200
tileStride = 0;
201
tileOffset = 0;
202
tile.reset();
203
204
mosaicWidth = 1;
205
mosaicHeight = 1;
206
mosaicStride = 0;
207
mosaicOffset = 0;
208
mosaic.reset();
209
210
paddingWidth = 0;
211
paddingHeight = 0;
212
paddingColor = 0x000000;
213
palette.reset();
214
}
215
216
inline context() {
217
reset();
218
}
219
};
220
221
}
222
}
223
224
#endif
225
226