yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
snes_tile_test.cc
Go to the documentation of this file.
1#include "app/gfx/snes_tile.h"
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
6#include "testing.h"
7
8namespace yaze {
9namespace test {
10
11using ::testing::Eq;
12
13TEST(SnesTileTest, UnpackBppTile) {
14 // Test 1bpp tile unpacking
15 std::vector<uint8_t> data1bpp = {0x80, 0x40, 0x20, 0x10,
16 0x08, 0x04, 0x02, 0x01};
17 auto tile1bpp = gfx::UnpackBppTile(data1bpp, 0, 1);
18 EXPECT_EQ(tile1bpp.data[0], 1); // First pixel
19 EXPECT_EQ(tile1bpp.data[7], 0); // Last pixel of first row
20 EXPECT_EQ(tile1bpp.data[56], 0); // First pixel of last row
21 EXPECT_EQ(tile1bpp.data[63], 1); // Last pixel
22
23 // Test 2bpp tile unpacking
24 // Create test data where we know the expected results
25 // For 2bpp: 16 bytes total (8 rows × 2 bytes per row)
26 // Each row has 2 bytes: plane 0 byte, plane 1 byte
27 // First pixel should be 3 (both bits set): plane0 bit7=1, plane1 bit7=1
28 // Last pixel of first row should be 1: plane0 bit0=1, plane1 bit0=0
29 std::vector<uint8_t> data2bpp = {
30 0x81, 0x80, // Row 0: plane0=10000001, plane1=10000000
31 0x00, 0x00, // Row 1: plane0=00000000, plane1=00000000
32 0x00, 0x00, // Row 2: plane0=00000000, plane1=00000000
33 0x00, 0x00, // Row 3: plane0=00000000, plane1=00000000
34 0x00, 0x00, // Row 4: plane0=00000000, plane1=00000000
35 0x00, 0x00, // Row 5: plane0=00000000, plane1=00000000
36 0x00, 0x00, // Row 6: plane0=00000000, plane1=00000000
37 0x01, 0x81 // Row 7: plane0=00000001, plane1=10000001
38 };
39 auto tile2bpp = gfx::UnpackBppTile(data2bpp, 0, 2);
40 EXPECT_EQ(tile2bpp.data[0], 3); // First pixel: 1|1<<1 = 3
41 EXPECT_EQ(tile2bpp.data[7], 1); // Last pixel of first row: 1|0<<1 = 1
42 EXPECT_EQ(tile2bpp.data[56], 2); // First pixel of last row: 0|1<<1 = 2
43 EXPECT_EQ(tile2bpp.data[63], 3); // Last pixel: 1|1<<1 = 3
44
45 // Test 4bpp tile unpacking
46 // According to SnesLab: First planes 1&2 intertwined, then planes 3&4 intertwined
47 // 32 bytes total: 16 bytes for planes 1&2, then 16 bytes for planes 3&4
48 std::vector<uint8_t> data4bpp = {
49 // Planes 1&2 intertwined (rows 0-7)
50 0x81, 0x80, // Row 0: bp1=10000001, bp2=10000000
51 0x00, 0x00, // Row 1: bp1=00000000, bp2=00000000
52 0x00, 0x00, // Row 2: bp1=00000000, bp2=00000000
53 0x00, 0x00, // Row 3: bp1=00000000, bp2=00000000
54 0x00, 0x00, // Row 4: bp1=00000000, bp2=00000000
55 0x00, 0x00, // Row 5: bp1=00000000, bp2=00000000
56 0x00, 0x00, // Row 6: bp1=00000000, bp2=00000000
57 0x01, 0x81, // Row 7: bp1=00000001, bp2=10000001
58 // Planes 3&4 intertwined (rows 0-7)
59 0x81, 0x80, // Row 0: bp3=10000001, bp4=10000000
60 0x00, 0x00, // Row 1: bp3=00000000, bp4=00000000
61 0x00, 0x00, // Row 2: bp3=00000000, bp4=00000000
62 0x00, 0x00, // Row 3: bp3=00000000, bp4=00000000
63 0x00, 0x00, // Row 4: bp3=00000000, bp4=00000000
64 0x00, 0x00, // Row 5: bp3=00000000, bp4=00000000
65 0x00, 0x00, // Row 6: bp3=00000000, bp4=00000000
66 0x01, 0x81 // Row 7: bp3=00000001, bp4=10000001
67 };
68 auto tile4bpp = gfx::UnpackBppTile(data4bpp, 0, 4);
69 EXPECT_EQ(tile4bpp.data[0], 0xF); // First pixel: 1|1<<1|1<<2|1<<3 = 15
70 EXPECT_EQ(tile4bpp.data[7], 0x5); // Last pixel of first row: 1|0<<1|1<<2|0<<3 = 5
71 EXPECT_EQ(tile4bpp.data[56], 0xA); // First pixel of last row: 0|1<<1|0<<2|1<<3 = 10
72 EXPECT_EQ(tile4bpp.data[63], 0xF); // Last pixel: 1|1<<1|1<<2|1<<3 = 15
73}
74
75TEST(SnesTileTest, PackBppTile) {
76 // Test 1bpp tile packing
77 snes_tile8 tile1bpp;
78 std::fill(tile1bpp.data, tile1bpp.data + 64, 0);
79 tile1bpp.data[0] = 1;
80 tile1bpp.data[63] = 1;
81 auto packed1bpp = gfx::PackBppTile(tile1bpp, 1);
82 EXPECT_EQ(packed1bpp[0], 0x80); // First byte
83 EXPECT_EQ(packed1bpp[7], 0x01); // Last byte
84
85 // Test 2bpp tile packing
86 snes_tile8 tile2bpp;
87 std::fill(tile2bpp.data, tile2bpp.data + 64, 0);
88 tile2bpp.data[0] = 3;
89 tile2bpp.data[7] = 1;
90 tile2bpp.data[56] = 2;
91 tile2bpp.data[63] = 3;
92 auto packed2bpp = gfx::PackBppTile(tile2bpp, 2);
93 EXPECT_EQ(packed2bpp[0], 0x81); // First byte of first plane: pixel0=3→0x80, pixel7=1→0x01
94 EXPECT_EQ(packed2bpp[1], 0x80); // First byte of second plane: pixel0=3→0x80, pixel7=1→0x00
95 EXPECT_EQ(packed2bpp[14], 0x01); // Last byte of first plane: pixel56=2→0x00, pixel63=3→0x01
96 EXPECT_EQ(packed2bpp[15], 0x81); // Last byte of second plane: pixel56=2→0x80, pixel63=3→0x01
97}
98
99TEST(SnesTileTest, ConvertBpp) {
100 // Test 2bpp to 4bpp conversion
101 std::vector<uint8_t> data2bpp = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
102 0x02, 0x01, 0x01, 0x02, 0x04, 0x08,
103 0x10, 0x20, 0x40, 0x80};
104 auto converted4bpp = gfx::ConvertBpp(data2bpp, 2, 4);
105 EXPECT_EQ(converted4bpp.size(), 32); // 4bpp tile is 32 bytes
106
107 // Test 4bpp to 2bpp conversion (using only colors 0-3 for valid 2bpp)
108 std::vector<uint8_t> data4bpp = {
109 // Planes 1&2 (rows 0-7) - create colors 0-3 only
110 0x80, 0x80, 0x40, 0x00, 0x20, 0x40, 0x10, 0x80, // rows 0-3
111 0x08, 0x00, 0x04, 0x40, 0x02, 0x80, 0x01, 0x00, // rows 4-7
112 // Planes 3&4 (rows 0-7) - all zeros to ensure colors stay ≤ 3
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // rows 0-3
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // rows 4-7
115 };
116 auto converted2bpp = gfx::ConvertBpp(data4bpp, 4, 2);
117 EXPECT_EQ(converted2bpp.size(), 16); // 2bpp tile is 16 bytes
118}
119
120TEST(SnesTileTest, TileInfo) {
121 // Test TileInfo construction and bit manipulation
122 gfx::TileInfo info(0x123, 3, true, true, true);
123 EXPECT_EQ(info.id_, 0x123);
124 EXPECT_EQ(info.palette_, 3);
125 EXPECT_TRUE(info.vertical_mirror_);
126 EXPECT_TRUE(info.horizontal_mirror_);
127 EXPECT_TRUE(info.over_);
128
129 // Test TileInfo from bytes
130 gfx::TileInfo infoFromBytes(0x23, 0xED); // v=1, h=1, o=1, p=3, id=0x123
131 EXPECT_EQ(infoFromBytes.id_, 0x123);
132 EXPECT_EQ(infoFromBytes.palette_, 3);
133 EXPECT_TRUE(infoFromBytes.vertical_mirror_);
134 EXPECT_TRUE(infoFromBytes.horizontal_mirror_);
135 EXPECT_TRUE(infoFromBytes.over_);
136
137 // Test TileInfo equality
138 EXPECT_TRUE(info == infoFromBytes);
139}
140
141TEST(SnesTileTest, TileInfoToWord) {
142 gfx::TileInfo info(0x123, 3, true, true, true);
143 uint16_t word = gfx::TileInfoToWord(info);
144
145 // Verify bit positions:
146 // vhopppcc cccccccc
147 EXPECT_EQ(word & 0x3FF, 0x123); // id (10 bits)
148 EXPECT_TRUE(word & 0x8000); // vertical mirror
149 EXPECT_TRUE(word & 0x4000); // horizontal mirror
150 EXPECT_TRUE(word & 0x2000); // over
151 EXPECT_EQ((word >> 10) & 0x07, 3); // palette (3 bits)
152}
153
154TEST(SnesTileTest, WordToTileInfo) {
155 uint16_t word = 0xED23; // v=1, h=1, o=1, p=3, id=0x123
157
158 EXPECT_EQ(info.id_, 0x123);
159 EXPECT_EQ(info.palette_, 3);
160 EXPECT_TRUE(info.vertical_mirror_);
161 EXPECT_TRUE(info.horizontal_mirror_);
162 EXPECT_TRUE(info.over_);
163}
164
165TEST(SnesTileTest, Tile32) {
166 // Test Tile32 construction and operations
167 gfx::Tile32 tile32(0x1234, 0x5678, 0x9ABC, 0xDEF0);
168 EXPECT_EQ(tile32.tile0_, 0x1234);
169 EXPECT_EQ(tile32.tile1_, 0x5678);
170 EXPECT_EQ(tile32.tile2_, 0x9ABC);
171 EXPECT_EQ(tile32.tile3_, 0xDEF0);
172
173 // Test packed value
174 uint64_t packed = tile32.GetPackedValue();
175 EXPECT_EQ(packed, 0xDEF09ABC56781234);
176
177 // Test from packed value
178 gfx::Tile32 tile32FromPacked(packed);
179 EXPECT_EQ(tile32FromPacked.tile0_, 0x1234);
180 EXPECT_EQ(tile32FromPacked.tile1_, 0x5678);
181 EXPECT_EQ(tile32FromPacked.tile2_, 0x9ABC);
182 EXPECT_EQ(tile32FromPacked.tile3_, 0xDEF0);
183
184 // Test equality
185 EXPECT_TRUE(tile32 == tile32FromPacked);
186}
187
188TEST(SnesTileTest, Tile16) {
189 // Test Tile16 construction and operations
190 gfx::TileInfo info0(0x123, 3, true, true, true);
191 gfx::TileInfo info1(0x456, 2, false, true, false);
192 gfx::TileInfo info2(0x789, 1, true, false, true);
193 gfx::TileInfo info3(0xABC, 0, false, false, false);
194
195 gfx::Tile16 tile16(info0, info1, info2, info3);
196 EXPECT_TRUE(tile16.tile0_ == info0);
197 EXPECT_TRUE(tile16.tile1_ == info1);
198 EXPECT_TRUE(tile16.tile2_ == info2);
199 EXPECT_TRUE(tile16.tile3_ == info3);
200
201 // Test array access
202 EXPECT_TRUE(tile16.tiles_info[0] == info0);
203 EXPECT_TRUE(tile16.tiles_info[1] == info1);
204 EXPECT_TRUE(tile16.tiles_info[2] == info2);
205 EXPECT_TRUE(tile16.tiles_info[3] == info3);
206}
207
208} // namespace test
209} // namespace yaze
Tile composition of four 8x8 tiles.
Definition snes_tile.h:137
std::array< TileInfo, 4 > tiles_info
Definition snes_tile.h:143
Tile composition of four 16x16 tiles.
Definition snes_tile.h:88
uint16_t tile2_
Definition snes_tile.h:92
uint16_t tile3_
Definition snes_tile.h:93
uint16_t tile0_
Definition snes_tile.h:90
uint64_t GetPackedValue() const
Definition snes_tile.h:118
uint16_t tile1_
Definition snes_tile.h:91
SNES 16-bit tile metadata container.
Definition snes_tile.h:50
uint16_t TileInfoToWord(TileInfo tile_info)
Definition snes_tile.cc:291
std::vector< uint8_t > PackBppTile(const snes_tile8 &tile, const uint32_t bpp)
Definition snes_tile.cc:72
snes_tile8 UnpackBppTile(std::span< uint8_t > data, const uint32_t offset, const uint32_t bpp)
Definition snes_tile.cc:23
TileInfo WordToTileInfo(uint16_t word)
Definition snes_tile.cc:308
std::vector< uint8_t > ConvertBpp(std::span< uint8_t > tiles, uint32_t from_bpp, uint32_t to_bpp)
Definition snes_tile.cc:115
TEST(HexTest, HexByte)
Definition hex_test.cc:10
Main namespace for the application.
8x8 SNES tile data
Definition yaze.h:277
uint8_t data[64]
Definition yaze.h:280