Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/mosaic/parser.hpp
2 views
1
#ifdef NALL_MOSAIC_INTERNAL_HPP
2
3
namespace nall {
4
namespace mosaic {
5
6
struct parser {
7
image canvas;
8
9
//export from bitstream to canvas
10
inline void load(bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
11
canvas.allocate(width, height);
12
canvas.clear(ctx.paddingColor);
13
parse(1, stream, offset, ctx, width, height);
14
}
15
16
//import from canvas to bitstream
17
inline bool save(bitstream &stream, uint64_t offset, context &ctx) {
18
if(stream.readonly) return false;
19
parse(0, stream, offset, ctx, canvas.width, canvas.height);
20
return true;
21
}
22
23
inline parser() : canvas(0, 32, 0u, 255u << 16, 255u << 8, 255u << 0) {
24
}
25
26
private:
27
inline uint32_t read(unsigned x, unsigned y) const {
28
unsigned addr = y * canvas.width + x;
29
if(addr >= canvas.width * canvas.height) return 0u;
30
uint32_t *buffer = (uint32_t*)canvas.data;
31
return buffer[addr];
32
}
33
34
inline void write(unsigned x, unsigned y, uint32_t data) {
35
unsigned addr = y * canvas.width + x;
36
if(addr >= canvas.width * canvas.height) return;
37
uint32_t *buffer = (uint32_t*)canvas.data;
38
buffer[addr] = data;
39
}
40
41
inline void parse(bool load, bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
42
stream.endian = ctx.endian;
43
unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth);
44
unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight);
45
unsigned bitsPerBlock = ctx.depth * ctx.blockWidth * ctx.blockHeight;
46
47
unsigned objectOffset = 0;
48
for(unsigned objectY = 0; objectY < canvasHeight; objectY++) {
49
for(unsigned objectX = 0; objectX < canvasWidth; objectX++) {
50
if(objectOffset >= ctx.count && ctx.count > 0) break;
51
unsigned objectIX = objectX * ctx.objectWidth();
52
unsigned objectIY = objectY * ctx.objectHeight();
53
objectOffset++;
54
55
unsigned mosaicOffset = 0;
56
for(unsigned mosaicY = 0; mosaicY < ctx.mosaicHeight; mosaicY++) {
57
for(unsigned mosaicX = 0; mosaicX < ctx.mosaicWidth; mosaicX++) {
58
unsigned mosaicData = ctx.mosaic(mosaicOffset, mosaicOffset);
59
unsigned mosaicIX = (mosaicData % ctx.mosaicWidth) * (ctx.tileWidth * ctx.blockWidth);
60
unsigned mosaicIY = (mosaicData / ctx.mosaicWidth) * (ctx.tileHeight * ctx.blockHeight);
61
mosaicOffset++;
62
63
unsigned tileOffset = 0;
64
for(unsigned tileY = 0; tileY < ctx.tileHeight; tileY++) {
65
for(unsigned tileX = 0; tileX < ctx.tileWidth; tileX++) {
66
unsigned tileData = ctx.tile(tileOffset, tileOffset);
67
unsigned tileIX = (tileData % ctx.tileWidth) * ctx.blockWidth;
68
unsigned tileIY = (tileData / ctx.tileWidth) * ctx.blockHeight;
69
tileOffset++;
70
71
unsigned blockOffset = 0;
72
for(unsigned blockY = 0; blockY < ctx.blockHeight; blockY++) {
73
for(unsigned blockX = 0; blockX < ctx.blockWidth; blockX++) {
74
if(load) {
75
unsigned palette = 0;
76
for(unsigned n = 0; n < ctx.depth; n++) {
77
unsigned index = blockOffset++;
78
if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth);
79
palette |= stream.read(offset + ctx.block(index, index)) << n;
80
}
81
82
write(
83
objectIX + mosaicIX + tileIX + blockX,
84
objectIY + mosaicIY + tileIY + blockY,
85
ctx.palette(palette, palette)
86
);
87
} else /* save */ {
88
uint32_t palette = read(
89
objectIX + mosaicIX + tileIX + blockX,
90
objectIY + mosaicIY + tileIY + blockY
91
);
92
93
for(unsigned n = 0; n < ctx.depth; n++) {
94
unsigned index = blockOffset++;
95
if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth);
96
stream.write(offset + ctx.block(index, index), palette & 1);
97
palette >>= 1;
98
}
99
}
100
} //blockX
101
} //blockY
102
103
offset += ctx.blockStride;
104
} //tileX
105
106
offset += ctx.blockOffset;
107
} //tileY
108
109
offset += ctx.tileStride;
110
} //mosaicX
111
112
offset += ctx.tileOffset;
113
} //mosaicY
114
115
offset += ctx.mosaicStride;
116
} //objectX
117
118
offset += ctx.mosaicOffset;
119
} //objectY
120
}
121
};
122
123
}
124
}
125
126
#endif
127
128