yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_editor_test.cc
Go to the documentation of this file.
2
5
6namespace yaze {
7namespace test {
8
9using namespace yaze::zelda3;
10
11// ============================================================================
12// Basic Room Loading Tests
13// ============================================================================
14
15TEST_F(DungeonEditorIntegrationTest, LoadRoomFromRealRom) {
16 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
17 EXPECT_NE(room.rom(), nullptr);
18 room.LoadObjects();
19 EXPECT_FALSE(room.GetTileObjects().empty());
20}
21
23 // Test loading several different rooms
24 for (int room_id : {0x00, 0x01, 0x02, 0x10, 0x20}) {
25 auto room = zelda3::LoadRoomFromRom(rom_.get(), room_id);
26 EXPECT_NE(room.rom(), nullptr) << "Failed to load room " << std::hex << room_id;
27 room.LoadObjects();
28 // Some rooms may be empty, but loading should not fail
29 }
30}
31
32TEST_F(DungeonEditorIntegrationTest, DungeonEditorInitialization) {
33 // Initialize the editor before loading
34 dungeon_editor_->Initialize();
35
36 // Now load should succeed
37 auto status = dungeon_editor_->Load();
38 ASSERT_TRUE(status.ok()) << "Load failed: " << status.message();
39}
40
41// ============================================================================
42// Object Encoding/Decoding Tests
43// ============================================================================
44
45TEST_F(DungeonEditorIntegrationTest, ObjectEncodingRoundTrip) {
46 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
47 room.LoadObjects();
48
49 auto encoded = room.EncodeObjects();
50 EXPECT_FALSE(encoded.empty());
51 EXPECT_EQ(encoded[encoded.size()-1], 0xFF); // Terminator
52}
53
55 // Type 1: xxxxxxss yyyyyyss iiiiiiii (ID < 0x100)
56 zelda3::RoomObject obj(0x10, 5, 7, 0x12, 0); // id, x, y, size, layer
57 auto bytes = obj.EncodeObjectToBytes();
58
59 // Verify encoding format
60 EXPECT_EQ((bytes.b1 >> 2), 5) << "X coordinate should be in upper 6 bits of b1";
61 EXPECT_EQ((bytes.b2 >> 2), 7) << "Y coordinate should be in upper 6 bits of b2";
62 EXPECT_EQ(bytes.b3, 0x10) << "Object ID should be in b3";
63}
64
66 // Type 2: 111111xx xxxxyyyy yyiiiiii (ID >= 0x100 && < 0x200)
67 zelda3::RoomObject obj(0x150, 12, 8, 0, 0);
68 auto bytes = obj.EncodeObjectToBytes();
69
70 // Verify Type 2 marker
71 EXPECT_EQ((bytes.b1 & 0xFC), 0xFC) << "Type 2 objects should have 111111 prefix";
72}
73
75 // Type 3: xxxxxxii yyyyyyii 11111iii (ID >= 0xF00)
76 zelda3::RoomObject obj(0xF23, 3, 4, 0, 0);
77 auto bytes = obj.EncodeObjectToBytes();
78
79 // Verify Type 3 encoding: bytes.b3 = (id_ >> 4) & 0xFF
80 // For ID 0xF23: (0xF23 >> 4) = 0xF2
81 EXPECT_EQ(bytes.b3, 0xF2) << "Type 3: (ID >> 4) should be in b3";
82}
83
84// ============================================================================
85// Object Manipulation Tests
86// ============================================================================
87
89 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
90 room.LoadObjects();
91
92 size_t initial_count = room.GetTileObjects().size();
93
94 // Add a new object (Type 1, so size must be <= 15)
95 zelda3::RoomObject new_obj(0x20, 10, 10, 5, 0);
96 new_obj.set_rom(rom_.get());
97 auto status = room.AddObject(new_obj);
98
99 EXPECT_TRUE(status.ok()) << "Failed to add object: " << status.message();
100 EXPECT_EQ(room.GetTileObjects().size(), initial_count + 1);
101}
102
103TEST_F(DungeonEditorIntegrationTest, RemoveObjectFromRoom) {
104 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
105 room.LoadObjects();
106
107 size_t initial_count = room.GetTileObjects().size();
108 ASSERT_GT(initial_count, 0) << "Room should have at least one object";
109
110 // Remove first object
111 auto status = room.RemoveObject(0);
112
113 EXPECT_TRUE(status.ok()) << "Failed to remove object: " << status.message();
114 EXPECT_EQ(room.GetTileObjects().size(), initial_count - 1);
115}
116
118 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
119 room.LoadObjects();
120
121 ASSERT_FALSE(room.GetTileObjects().empty());
122
123 // Update first object's position
124 zelda3::RoomObject updated_obj = room.GetTileObjects()[0];
125 updated_obj.x_ = 15;
126 updated_obj.y_ = 15;
127
128 auto status = room.UpdateObject(0, updated_obj);
129
130 EXPECT_TRUE(status.ok()) << "Failed to update object: " << status.message();
131 EXPECT_EQ(room.GetTileObjects()[0].x_, 15);
132 EXPECT_EQ(room.GetTileObjects()[0].y_, 15);
133}
134
135// ============================================================================
136// Object Validation Tests
137// ============================================================================
138
139TEST_F(DungeonEditorIntegrationTest, ValidateObjectBounds) {
140 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
141
142 // Test objects within valid bounds (0-63 for x and y)
143 zelda3::RoomObject valid_obj(0x10, 0, 0, 0, 0);
144 EXPECT_TRUE(room.ValidateObject(valid_obj));
145
146 zelda3::RoomObject valid_obj2(0x10, 31, 31, 0, 0);
147 EXPECT_TRUE(room.ValidateObject(valid_obj2));
148
149 zelda3::RoomObject valid_obj3(0x10, 63, 63, 0, 0);
150 EXPECT_TRUE(room.ValidateObject(valid_obj3));
151
152 // Test objects outside bounds (> 63)
153 zelda3::RoomObject invalid_obj(0x10, 64, 64, 0, 0);
154 EXPECT_FALSE(room.ValidateObject(invalid_obj));
155
156 zelda3::RoomObject invalid_obj2(0x10, 100, 100, 0, 0);
157 EXPECT_FALSE(room.ValidateObject(invalid_obj2));
158}
159
160// ============================================================================
161// Save/Load Round-Trip Tests
162// ============================================================================
163
165 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
166 room.LoadObjects();
167
168 size_t original_count = room.GetTileObjects().size();
169
170 // Encode objects
171 auto encoded = room.EncodeObjects();
172 EXPECT_FALSE(encoded.empty());
173
174 // Create a new room and decode
175 auto room2 = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
176 room2.LoadObjects();
177
178 // Verify object count matches
179 EXPECT_EQ(room2.GetTileObjects().size(), original_count);
180}
181
182// ============================================================================
183// Object Rendering Tests
184// ============================================================================
185
186TEST_F(DungeonEditorIntegrationTest, RenderObjectWithTiles) {
187 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
188 room.LoadObjects();
189
190 ASSERT_FALSE(room.GetTileObjects().empty());
191
192 // Ensure tiles are loaded for first object
193 auto& obj = room.GetTileObjects()[0];
194 const_cast<zelda3::RoomObject&>(obj).set_rom(rom_.get());
195 const_cast<zelda3::RoomObject&>(obj).EnsureTilesLoaded();
196
197 EXPECT_FALSE(obj.tiles_.empty()) << "Object should have tiles after loading";
198}
199
200// ============================================================================
201// Multi-Layer Tests
202// ============================================================================
203
204TEST_F(DungeonEditorIntegrationTest, ObjectsOnDifferentLayers) {
205 auto room = zelda3::LoadRoomFromRom(rom_.get(), kTestRoomId);
206
207 // Add objects on different layers
208 zelda3::RoomObject obj_bg1(0x10, 5, 5, 0, 0); // Layer 0 (BG2)
209 zelda3::RoomObject obj_bg2(0x11, 6, 6, 0, 1); // Layer 1 (BG1)
210 zelda3::RoomObject obj_bg3(0x12, 7, 7, 0, 2); // Layer 2 (BG3)
211
212 room.AddObject(obj_bg1);
213 room.AddObject(obj_bg2);
214 room.AddObject(obj_bg3);
215
216 // Encode and verify layer separation
217 auto encoded = room.EncodeObjects();
218
219 // Should have layer terminators (0xFF 0xFF between layers)
220 int terminator_count = 0;
221 for (size_t i = 0; i < encoded.size() - 1; i++) {
222 if (encoded[i] == 0xFF && encoded[i+1] == 0xFF) {
223 terminator_count++;
224 }
225 }
226
227 EXPECT_GE(terminator_count, 2) << "Should have at least 2 layer terminators";
228}
229
230} // namespace test
231} // namespace yaze
Integration test framework using real ROM data.
ObjectBytes EncodeObjectToBytes() const
void set_rom(Rom *rom)
Definition room_object.h:67
TEST_F(DungeonObjectRenderingE2ETests, RunAllTests)
Zelda 3 specific classes and functions.
Room LoadRoomFromRom(Rom *rom, int room_id)
Definition room.cc:75
Main namespace for the application.