28 assert(bpp >= 1 && bpp <= 8);
29 unsigned int bpp_pos[8];
30 for (
int row = 0; row < 8; row++) {
31 for (
int col = 0; col < 8; col++) {
33 tile.
data[row * 8 + col] = (data[offset + row] >> (7 - col)) & 0x01;
40 bpp_pos[0] = offset + row * 2;
41 bpp_pos[1] = offset + row * 2 + 1;
42 char mask = 1 << (7 - col);
43 tile.
data[row * 8 + col] = (data[bpp_pos[0]] & mask) ? 1 : 0;
44 tile.
data[row * 8 + col] |= ((data[bpp_pos[1]] & mask) ? 1 : 0) << 1;
48 bpp_pos[2] = offset + 16 + row;
49 tile.
data[row * 8 + col] |= ((data[bpp_pos[2]] & mask) ? 1 : 0) << 2;
54 bpp_pos[2] = offset + 16 + row * 2;
55 bpp_pos[3] = offset + 16 + row * 2 + 1;
56 tile.
data[row * 8 + col] |= ((data[bpp_pos[2]] & mask) ? 1 : 0) << 2;
57 tile.
data[row * 8 + col] |= ((data[bpp_pos[3]] & mask) ? 1 : 0) << 3;
60 bpp_pos[4] = offset + 32 + row * 2;
61 bpp_pos[5] = offset + 32 + row * 2 + 1;
62 bpp_pos[6] = offset + 48 + row * 2;
63 bpp_pos[7] = offset + 48 + row * 2 + 1;
64 tile.
data[row * 8 + col] |= ((data[bpp_pos[4]] & mask) ? 1 : 0) << 4;
65 tile.
data[row * 8 + col] |= ((data[bpp_pos[5]] & mask) ? 1 : 0) << 5;
66 tile.
data[row * 8 + col] |= ((data[bpp_pos[6]] & mask) ? 1 : 0) << 6;
67 tile.
data[row * 8 + col] |= ((data[bpp_pos[7]] & mask) ? 1 : 0) << 7;
76 std::vector<uint8_t> output(bpp * 8, 0);
77 unsigned maxcolor = 1 << bpp;
80 for (
unsigned int row = 0; row < 8; row++) {
81 for (
unsigned int col = 0; col < 8; col++) {
82 uint8_t color = tile.
data[row * 8 + col];
83 if (color >= maxcolor) {
84 throw std::invalid_argument(
"Invalid color value.");
89 output[row] += (uint8_t)((color & 1) << (7 - col));
93 output[row * 2] += ((color & 1) << (7 - col));
94 output[row * 2 + 1] += (((color & 2) == 2) << (7 - col));
99 output[16 + row] += (((color & 4) == 4) << (7 - col));
103 output[16 + row * 2] += (((color & 4) == 4) << (7 - col));
104 output[16 + row * 2 + 1] += (((color & 8) == 8) << (7 - col));
109 output[32 + row * 2] += (((color & 16) == 16) << (7 - col));
110 output[32 + row * 2 + 1] += (((color & 32) == 32) << (7 - col));
111 output[48 + row * 2] += (((color & 64) == 64) << (7 - col));
112 output[48 + row * 2 + 1] += (((color & 128) == 128) << (7 - col));
119std::vector<uint8_t>
ConvertBpp(std::span<const uint8_t> tiles,
120 uint32_t from_bpp, uint32_t to_bpp) {
121 unsigned int nb_tile = tiles.size() / (from_bpp * 8);
122 std::vector<uint8_t> converted(nb_tile * to_bpp * 8);
124 for (
unsigned int i = 0; i < nb_tile; i++) {
126 std::vector<uint8_t> packed_tile =
PackBppTile(tile, to_bpp);
127 std::memcpy(converted.data() + i * to_bpp * 8, packed_tile.data(),
140 int buffer_size = 0x1000;
145 buffer_size = 0x2000;
146 }
else if (bpp == 3) {
148 }
else if (bpp == 4) {
150 buffer_size = 0x4000;
151 }
else if (bpp == 8) {
155 if (num_sheets != 1) {
156 num_tiles *= num_sheets;
157 buffer_size *= num_sheets;
161 if (
static_cast<size_t>(num_tiles * bpp) > sheet.size()) {
165 num_tiles =
static_cast<int>(sheet.size()) / bpp;
171 std::vector<uint8_t> sheet_buffer_out(buffer_size);
173 for (
int i = 0; i < num_tiles; i++) {
174 for (
int y = 0; y < 8; y++) {
175 for (
int x = 0; x < 8; x++) {
186 if (b3 != 0 && bpp != 16) {
189 sheet_buffer_out[x + xx + (y * 128) + (yy * 1024)] = b;
201 return sheet_buffer_out;
211 const int default_tile_rows = (bpp == 2) ? 8 : 4;
212 const int computed_tile_rows =
214 const int tile_rows = (computed_tile_rows > 0)
215 ? std::max(default_tile_rows, computed_tile_rows)
217 const int tiles_per_sheet = tiles_per_row * tile_rows;
218 const int total_tiles = tiles_per_sheet * num_sheets;
219 const int bytes_per_tile = bpp * 8;
220 const uint8_t max_color =
221 static_cast<uint8_t
>((1u <<
static_cast<uint8_t
>(bpp)) - 1u);
223 std::vector<uint8_t> output(total_tiles * bytes_per_tile, 0);
230 for (
int i = 0; i < total_tiles; i++) {
233 for (
int y = 0; y < 8; y++) {
234 for (
int x = 0; x < 8; x++) {
237 if (index >= 0 && index <
static_cast<int>(sheet.size())) {
238 tile.
data[y * 8 + x] = sheet[index] & max_color;
244 std::copy(packed_tile.begin(), packed_tile.end(),
245 output.begin() + (pos * bytes_per_tile));
250 if (ypos >= tiles_per_row) {
273 auto buffer = std::vector<uint8_t>(data.size());
274 std::vector<std::vector<uint8_t>> bitmap_data;
275 bitmap_data.resize(0x80);
276 for (
auto& each : bitmap_data) {
283 const uint16_t sheet_width = 128;
289 for (
int i = 0; i < 4096; i++) {
291 for (
int y = 0; y < 8; y++) {
293 for (
int x = 0; x < 8; x++) {
294 const uint16_t bitmask[] = {0x80, 0x40, 0x20, 0x10,
295 0x08, 0x04, 0x02, 0x01};
296 auto b1 = (data[(y * 2) + ((bpp * 8) * pos)] & (bitmask[x]));
297 auto b2 = (data[((y * 2) + ((bpp * 8) * pos)) + 1] & (bitmask[x]));
298 auto b3 = (data[(y * 2) + ((bpp * 8) * pos) + 16] & (bitmask[x]));
299 auto b4 = (data[(y * 2) + ((bpp * 8) * pos) + 17] & (bitmask[x]));
300 auto b5 = (data[(y * 2) + ((bpp * 8) * pos) + 32] & (bitmask[x]));
301 auto b6 = (data[(y * 2) + ((bpp * 8) * pos) + 33] & (bitmask[x]));
302 auto b7 = (data[(y * 2) + ((bpp * 8) * pos) + 48] & (bitmask[x]));
303 auto b8 = (data[(y * 2) + ((bpp * 8) * pos) + 49] & (bitmask[x]));
335 bitmap_data[x + xx][y + (yy * 8)] = b;
350 for (
int y = 0; y < (data.size() / 64); y++) {
351 for (
int x = 0; x < sheet_width; x++) {
352 if (n < data.size()) {
354 buffer[n] = bitmap_data[x][y];
366 result |= tile_info.
id_ & 0x3FF;
371 result |= (tile_info.
over_ ? 1 : 0) << 13;
374 result |= (tile_info.
palette_ & 0x07) << 10;
381 uint16_t
id = word & 0x3FF;
384 bool vertical_mirror = (word >> 15) & 0x01;
385 bool horizontal_mirror = (word >> 14) & 0x01;
386 bool over = (word >> 13) & 0x01;
389 uint8_t palette = (word >> 10) & 0x07;
391 return TileInfo(
id, palette, vertical_mirror, horizontal_mirror, over);
397 if (tile_info.
over_) {
406 value |= (uint16_t)((tile_info.
palette_ << 10) & 0x1C00);
415 uint8_t p = (uint8_t)((tile >> 10) & 0x07);
425 const std::vector<uint8_t>& blockset) {
426 if (tile < 0 || x < 0 || y < 0) {
429 const size_t src_pos =
430 static_cast<size_t>((tile % 0x08) * 0x10) + (tile / 0x08) * 2048;
431 const size_t dest_pos =
static_cast<size_t>(x) + y * 0x200;
434 if (src_pos + 15 * 0x80 + 0x10 > blockset.size() ||
435 dest_pos + 15 * 0x200 + 0x10 > bitmap.size()) {
438 const uint8_t* src = blockset.data() + src_pos;
439 uint8_t* dst = bitmap.data() + dest_pos;
440 for (
int yy = 0; yy < 0x10; yy++) {
441 std::memcpy(dst + yy * 0x200, src + yy * 0x80, 0x10);
446 std::span<const uint8_t> src) {
447 std::vector<uint8_t> dest;
459 int main_index_limit =
static_cast<int>(src.size() / 32);
460 for (
int main_index = 0; main_index <= main_index_limit; main_index += 32) {
461 src_index = (main_index << 5);
462 if (
static_cast<size_t>(src_index + 31) >= src.size()) {
463 throw std::invalid_argument(
"src_index + 31 >= src.size()");
465 dest_x = main_index & 0x0F;
466 dest_y = main_index >> 4;
467 dest_index = ((dest_y << 7) + dest_x) << 3;
468 if (
static_cast<size_t>(dest_index + 903) >=
471 if (dest.size() <
static_cast<size_t>(dest_index + 904)) {
472 dest.resize(dest_index + 904);
475 for (
int i = 0; i < 16; i += 2) {
477 b0 = src[src_index + i];
478 b1 = src[src_index + i + 1];
479 b2 = src[src_index + i + 16];
480 b3 = src[src_index + i + 17];
481 for (
int j = 0; j < 8; j++) {
482 res = ((b0 & mul) | ((b1 & mul) << 1) | ((b2 & mul) << 2) |
483 ((b3 & mul) << 3)) >>
485 dest[dest_index + (7 - j) + y_adder] = (uint8_t)res;
SNES 16-bit tile metadata container.
constexpr uint16_t TileNameMask
constexpr uint16_t TileVFlipBit
std::vector< uint8_t > LoadSNES4bppGFXToIndexedColorMatrix(std::span< const uint8_t > src)
snes_tile8 UnpackBppTile(std::span< const uint8_t > data, const uint32_t offset, const uint32_t bpp)
constexpr int kTilesheetWidth
void CopyTile8bpp16(int x, int y, int tile, std::vector< uint8_t > &bitmap, const std::vector< uint8_t > &blockset)
uint16_t TileInfoToWord(TileInfo tile_info)
uint16_t TileInfoToShort(TileInfo tile_info)
std::vector< uint8_t > PackBppTile(const snes_tile8 &tile, const uint32_t bpp)
std::vector< uint8_t > Bpp8SnesToIndexed(std::vector< uint8_t > data, uint64_t bpp)
constexpr uint16_t TilePriorityBit
std::vector< uint8_t > SnesTo8bppSheet(std::span< const uint8_t > sheet, int bpp, int num_sheets)
std::vector< uint8_t > ConvertBpp(std::span< const uint8_t > tiles, uint32_t from_bpp, uint32_t to_bpp)
TileInfo GetTilesInfo(uint16_t tile)
constexpr uint8_t kGraphicsBitmap[8]
TileInfo WordToTileInfo(uint16_t word)
std::vector< uint8_t > IndexedToSnesSheet(std::span< const uint8_t > sheet, int bpp, int num_sheets)
constexpr uint16_t TileHFlipBit