fix: apply clang-format to all source files
Fixes formatting violations that were causing CI failures. Applied clang-format-14 to ensure consistent code formatting across the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,33 +17,31 @@ class ObjectRenderingTest : public ::testing::Test {
|
||||
// Create a mock ROM for testing
|
||||
rom_ = std::make_unique<Rom>();
|
||||
// Initialize with minimal ROM data for testing
|
||||
std::vector<uint8_t> mock_rom_data(1024 * 1024, 0); // 1MB mock ROM
|
||||
std::vector<uint8_t> mock_rom_data(1024 * 1024, 0); // 1MB mock ROM
|
||||
rom_->LoadFromData(mock_rom_data);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
rom_.reset();
|
||||
}
|
||||
void TearDown() override { rom_.reset(); }
|
||||
|
||||
std::unique_ptr<Rom> rom_;
|
||||
gfx::BackgroundBuffer bg1_;
|
||||
gfx::BackgroundBuffer bg2_;
|
||||
|
||||
|
||||
// Create a test palette
|
||||
gfx::SnesPalette CreateTestPalette() {
|
||||
gfx::SnesPalette palette;
|
||||
// Add some test colors
|
||||
palette.AddColor(gfx::SnesColor(0, 0, 0)); // Transparent
|
||||
palette.AddColor(gfx::SnesColor(255, 0, 0)); // Red
|
||||
palette.AddColor(gfx::SnesColor(0, 255, 0)); // Green
|
||||
palette.AddColor(gfx::SnesColor(0, 0, 255)); // Blue
|
||||
palette.AddColor(gfx::SnesColor(255, 255, 0)); // Yellow
|
||||
palette.AddColor(gfx::SnesColor(255, 0, 255)); // Magenta
|
||||
palette.AddColor(gfx::SnesColor(0, 255, 255)); // Cyan
|
||||
palette.AddColor(gfx::SnesColor(255, 255, 255)); // White
|
||||
palette.AddColor(gfx::SnesColor(0, 0, 0)); // Transparent
|
||||
palette.AddColor(gfx::SnesColor(255, 0, 0)); // Red
|
||||
palette.AddColor(gfx::SnesColor(0, 255, 0)); // Green
|
||||
palette.AddColor(gfx::SnesColor(0, 0, 255)); // Blue
|
||||
palette.AddColor(gfx::SnesColor(255, 255, 0)); // Yellow
|
||||
palette.AddColor(gfx::SnesColor(255, 0, 255)); // Magenta
|
||||
palette.AddColor(gfx::SnesColor(0, 255, 255)); // Cyan
|
||||
palette.AddColor(gfx::SnesColor(255, 255, 255)); // White
|
||||
return palette;
|
||||
}
|
||||
|
||||
|
||||
gfx::PaletteGroup CreateTestPaletteGroup() {
|
||||
gfx::PaletteGroup group;
|
||||
group.AddPalette(CreateTestPalette());
|
||||
@@ -54,7 +52,7 @@ class ObjectRenderingTest : public ::testing::Test {
|
||||
// Test object drawer initialization
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerInitializesCorrectly) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
|
||||
|
||||
// Test that drawer can be created without errors
|
||||
EXPECT_NE(rom_.get(), nullptr);
|
||||
}
|
||||
@@ -62,31 +60,31 @@ TEST_F(ObjectRenderingTest, ObjectDrawerInitializesCorrectly) {
|
||||
// Test object parser draw routine detection
|
||||
TEST_F(ObjectRenderingTest, ObjectParserDetectsDrawRoutines) {
|
||||
ObjectParser parser(rom_.get());
|
||||
|
||||
|
||||
// Test common object IDs and their expected draw routines
|
||||
auto info_00 = parser.GetObjectDrawInfo(0x00);
|
||||
EXPECT_EQ(info_00.draw_routine_id, 0);
|
||||
EXPECT_EQ(info_00.routine_name, "Rightwards2x2_1to15or32");
|
||||
EXPECT_TRUE(info_00.is_horizontal);
|
||||
|
||||
|
||||
auto info_01 = parser.GetObjectDrawInfo(0x01);
|
||||
EXPECT_EQ(info_01.draw_routine_id, 1);
|
||||
EXPECT_EQ(info_01.routine_name, "Rightwards2x4_1to15or26");
|
||||
EXPECT_TRUE(info_01.is_horizontal);
|
||||
|
||||
|
||||
auto info_09 = parser.GetObjectDrawInfo(0x09);
|
||||
EXPECT_EQ(info_09.draw_routine_id, 5);
|
||||
EXPECT_EQ(info_09.routine_name, "DiagonalAcute_1to16");
|
||||
EXPECT_FALSE(info_09.is_horizontal);
|
||||
|
||||
|
||||
auto info_34 = parser.GetObjectDrawInfo(0x34);
|
||||
EXPECT_EQ(info_34.draw_routine_id, 16);
|
||||
EXPECT_EQ(info_34.routine_name, "Rightwards1x1Solid_1to16_plus3");
|
||||
EXPECT_TRUE(info_34.is_horizontal);
|
||||
|
||||
|
||||
// Test unmapped object defaults to solid block routine
|
||||
auto info_unknown = parser.GetObjectDrawInfo(0x999);
|
||||
EXPECT_EQ(info_unknown.draw_routine_id, 16); // Default solid routine
|
||||
EXPECT_EQ(info_unknown.draw_routine_id, 16); // Default solid routine
|
||||
EXPECT_EQ(info_unknown.routine_name, "DefaultSolid");
|
||||
}
|
||||
|
||||
@@ -94,25 +92,25 @@ TEST_F(ObjectRenderingTest, ObjectParserDetectsDrawRoutines) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesVariousObjectTypes) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
// Test object 0x00 (horizontal floor tile)
|
||||
RoomObject floor_object(0x00, 10, 10, 3, 0); // ID, X, Y, size, layer
|
||||
|
||||
RoomObject floor_object(0x00, 10, 10, 3, 0); // ID, X, Y, size, layer
|
||||
|
||||
auto status = drawer.DrawObject(floor_object, bg1_, bg2_, palette_group);
|
||||
// Should succeed even if tiles aren't loaded (graceful handling)
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test object 0x09 (diagonal stairs)
|
||||
RoomObject stair_object(0x09, 15, 15, 5, 0);
|
||||
stair_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(stair_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test object 0x34 (solid block)
|
||||
RoomObject block_object(0x34, 20, 20, 1, 0);
|
||||
block_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(block_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
@@ -121,18 +119,18 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesVariousObjectTypes) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesDifferentLayers) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
// Test BG1 layer object
|
||||
RoomObject bg1_object(0x00, 5, 5, 2, 0); // Layer 0 = BG1
|
||||
RoomObject bg1_object(0x00, 5, 5, 2, 0); // Layer 0 = BG1
|
||||
bg1_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
auto status = drawer.DrawObject(bg1_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test BG2 layer object
|
||||
RoomObject bg2_object(0x01, 10, 10, 2, 1); // Layer 1 = BG2
|
||||
RoomObject bg2_object(0x01, 10, 10, 2, 1); // Layer 1 = BG2
|
||||
bg2_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(bg2_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
@@ -141,25 +139,25 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesDifferentLayers) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesSizeVariations) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
// Test small object
|
||||
RoomObject small_object(0x00, 5, 5, 1, 0); // Size = 1
|
||||
RoomObject small_object(0x00, 5, 5, 1, 0); // Size = 1
|
||||
small_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
auto status = drawer.DrawObject(small_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test large object
|
||||
RoomObject large_object(0x00, 10, 10, 15, 0); // Size = 15
|
||||
RoomObject large_object(0x00, 10, 10, 15, 0); // Size = 15
|
||||
large_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(large_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test maximum size object
|
||||
RoomObject max_object(0x00, 15, 15, 31, 0); // Size = 31 (0x1F)
|
||||
RoomObject max_object(0x00, 15, 15, 31, 0); // Size = 31 (0x1F)
|
||||
max_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(max_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
@@ -168,25 +166,25 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesSizeVariations) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesEdgeCases) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
// Test object at origin
|
||||
RoomObject origin_object(0x34, 0, 0, 1, 0);
|
||||
origin_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
auto status = drawer.DrawObject(origin_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test object with zero size
|
||||
RoomObject zero_size_object(0x34, 10, 10, 0, 0);
|
||||
zero_size_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(zero_size_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test object with maximum coordinates
|
||||
RoomObject max_coord_object(0x34, 63, 63, 1, 0); // Near buffer edge
|
||||
RoomObject max_coord_object(0x34, 63, 63, 1, 0); // Near buffer edge
|
||||
max_coord_object.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(max_coord_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
@@ -195,20 +193,20 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesEdgeCases) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesMultipleObjects) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
std::vector<RoomObject> objects;
|
||||
|
||||
|
||||
// Create various test objects
|
||||
objects.emplace_back(0x00, 5, 5, 3, 0); // Horizontal floor
|
||||
objects.emplace_back(0x01, 10, 10, 2, 0); // Vertical floor
|
||||
objects.emplace_back(0x09, 15, 15, 4, 0); // Diagonal stairs
|
||||
objects.emplace_back(0x34, 20, 20, 1, 1); // Solid block on BG2
|
||||
|
||||
objects.emplace_back(0x00, 5, 5, 3, 0); // Horizontal floor
|
||||
objects.emplace_back(0x01, 10, 10, 2, 0); // Vertical floor
|
||||
objects.emplace_back(0x09, 15, 15, 4, 0); // Diagonal stairs
|
||||
objects.emplace_back(0x34, 20, 20, 1, 1); // Solid block on BG2
|
||||
|
||||
// Set ROM for all objects
|
||||
for (auto& obj : objects) {
|
||||
obj.set_rom(rom_.get());
|
||||
}
|
||||
|
||||
|
||||
auto status = drawer.DrawObjectList(objects, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
@@ -217,36 +215,36 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesMultipleObjects) {
|
||||
TEST_F(ObjectRenderingTest, DrawRoutinesWorkCorrectly) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
// Test rightward patterns
|
||||
RoomObject rightward_obj(0x00, 5, 5, 5, 0);
|
||||
rightward_obj.set_rom(rom_.get());
|
||||
|
||||
|
||||
auto status = drawer.DrawObject(rightward_obj, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test diagonal patterns
|
||||
RoomObject diagonal_obj(0x09, 10, 10, 6, 0);
|
||||
diagonal_obj.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(diagonal_obj, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Test solid block patterns
|
||||
RoomObject solid_obj(0x34, 15, 15, 8, 0);
|
||||
solid_obj.set_rom(rom_.get());
|
||||
|
||||
|
||||
status = drawer.DrawObject(solid_obj, bg1_, bg2_, palette_group);
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
}
|
||||
|
||||
// Test object drawer error handling
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerHandlesErrorsGracefully) {
|
||||
ObjectDrawer drawer(nullptr); // No ROM
|
||||
ObjectDrawer drawer(nullptr); // No ROM
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
RoomObject test_object(0x00, 5, 5, 1, 0);
|
||||
|
||||
|
||||
auto status = drawer.DrawObject(test_object, bg1_, bg2_, palette_group);
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(status.code(), absl::StatusCode::kFailedPrecondition);
|
||||
@@ -255,32 +253,30 @@ TEST_F(ObjectRenderingTest, ObjectDrawerHandlesErrorsGracefully) {
|
||||
// Test object parser with various object IDs
|
||||
TEST_F(ObjectRenderingTest, ObjectParserHandlesVariousObjectIDs) {
|
||||
ObjectParser parser(rom_.get());
|
||||
|
||||
|
||||
// Test subtype 1 objects (0x00-0xFF)
|
||||
for (int id = 0; id <= 0x40; id += 4) { // Test every 4th object
|
||||
for (int id = 0; id <= 0x40; id += 4) { // Test every 4th object
|
||||
auto info = parser.GetObjectDrawInfo(id);
|
||||
EXPECT_GE(info.draw_routine_id, 0);
|
||||
EXPECT_LT(info.draw_routine_id, 25); // Should be within valid range
|
||||
EXPECT_LT(info.draw_routine_id, 25); // Should be within valid range
|
||||
EXPECT_FALSE(info.routine_name.empty());
|
||||
}
|
||||
|
||||
|
||||
// Test some specific important objects
|
||||
std::vector<int16_t> important_objects = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0A, 0x0B, 0x15, 0x16, 0x21, 0x22, 0x2F, 0x30, 0x31, 0x32,
|
||||
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
|
||||
0x3D, 0x3E, 0x3F, 0x40
|
||||
};
|
||||
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
|
||||
0x15, 0x16, 0x21, 0x22, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
|
||||
0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40};
|
||||
|
||||
for (int16_t obj_id : important_objects) {
|
||||
auto info = parser.GetObjectDrawInfo(obj_id);
|
||||
EXPECT_GE(info.draw_routine_id, 0);
|
||||
EXPECT_LT(info.draw_routine_id, 25);
|
||||
EXPECT_FALSE(info.routine_name.empty());
|
||||
|
||||
|
||||
// Verify tile count is reasonable
|
||||
EXPECT_GT(info.tile_count, 0);
|
||||
EXPECT_LE(info.tile_count, 64); // Reasonable upper bound
|
||||
EXPECT_LE(info.tile_count, 64); // Reasonable upper bound
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,35 +284,35 @@ TEST_F(ObjectRenderingTest, ObjectParserHandlesVariousObjectIDs) {
|
||||
TEST_F(ObjectRenderingTest, ObjectDrawerPerformanceTest) {
|
||||
ObjectDrawer drawer(rom_.get());
|
||||
auto palette_group = CreateTestPaletteGroup();
|
||||
|
||||
|
||||
std::vector<RoomObject> objects;
|
||||
|
||||
|
||||
// Create 100 test objects
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
int id = i % 65; // Cycle through object IDs 0-64
|
||||
int x = (i * 2) % 60; // Spread across buffer
|
||||
int id = i % 65; // Cycle through object IDs 0-64
|
||||
int x = (i * 2) % 60; // Spread across buffer
|
||||
int y = (i * 3) % 60;
|
||||
int size = (i % 8) + 1; // Size 1-8
|
||||
int layer = i % 2; // Alternate layers
|
||||
|
||||
int size = (i % 8) + 1; // Size 1-8
|
||||
int layer = i % 2; // Alternate layers
|
||||
|
||||
objects.emplace_back(id, x, y, size, layer);
|
||||
objects.back().set_rom(rom_.get());
|
||||
}
|
||||
|
||||
|
||||
// Time the drawing operation
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
||||
auto status = drawer.DrawObjectList(objects, bg1_, bg2_, palette_group);
|
||||
|
||||
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
end_time - start_time);
|
||||
|
||||
|
||||
EXPECT_TRUE(status.ok() || status.code() == absl::StatusCode::kOk);
|
||||
|
||||
|
||||
// Should complete in reasonable time (less than 1 second for 100 objects)
|
||||
EXPECT_LT(duration.count(), 1000);
|
||||
|
||||
|
||||
std::cout << "Drew 100 objects in " << duration.count() << "ms" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,20 +16,20 @@ class RoomManipulationTest : public ::testing::Test {
|
||||
// Create a minimal ROM for testing
|
||||
std::vector<uint8_t> dummy_data(0x200000, 0);
|
||||
rom_->LoadFromData(dummy_data, false);
|
||||
|
||||
|
||||
room_ = std::make_unique<Room>(0, rom_.get());
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Rom> rom_;
|
||||
std::unique_ptr<Room> room_;
|
||||
};
|
||||
|
||||
TEST_F(RoomManipulationTest, AddObject) {
|
||||
RoomObject obj(0x10, 10, 20, 3, 0);
|
||||
|
||||
|
||||
auto status = room_->AddObject(obj);
|
||||
ASSERT_TRUE(status.ok());
|
||||
|
||||
|
||||
auto objects = room_->GetTileObjects();
|
||||
EXPECT_EQ(objects.size(), 1);
|
||||
EXPECT_EQ(objects[0].id_, 0x10);
|
||||
@@ -40,7 +40,7 @@ TEST_F(RoomManipulationTest, AddObject) {
|
||||
TEST_F(RoomManipulationTest, AddInvalidObject) {
|
||||
// Invalid X position (> 63)
|
||||
RoomObject obj(0x10, 100, 20, 3, 0);
|
||||
|
||||
|
||||
auto status = room_->AddObject(obj);
|
||||
EXPECT_FALSE(status.ok());
|
||||
EXPECT_EQ(room_->GetTileObjects().size(), 0);
|
||||
@@ -49,15 +49,15 @@ TEST_F(RoomManipulationTest, AddInvalidObject) {
|
||||
TEST_F(RoomManipulationTest, RemoveObject) {
|
||||
RoomObject obj1(0x10, 10, 20, 3, 0);
|
||||
RoomObject obj2(0x20, 15, 25, 2, 1);
|
||||
|
||||
|
||||
room_->AddObject(obj1);
|
||||
room_->AddObject(obj2);
|
||||
|
||||
|
||||
EXPECT_EQ(room_->GetTileObjects().size(), 2);
|
||||
|
||||
|
||||
auto status = room_->RemoveObject(0);
|
||||
ASSERT_TRUE(status.ok());
|
||||
|
||||
|
||||
auto objects = room_->GetTileObjects();
|
||||
EXPECT_EQ(objects.size(), 1);
|
||||
EXPECT_EQ(objects[0].id_, 0x20);
|
||||
@@ -71,11 +71,11 @@ TEST_F(RoomManipulationTest, RemoveInvalidIndex) {
|
||||
TEST_F(RoomManipulationTest, UpdateObject) {
|
||||
RoomObject obj(0x10, 10, 20, 3, 0);
|
||||
room_->AddObject(obj);
|
||||
|
||||
|
||||
RoomObject updated(0x20, 15, 25, 5, 1);
|
||||
auto status = room_->UpdateObject(0, updated);
|
||||
ASSERT_TRUE(status.ok());
|
||||
|
||||
|
||||
auto objects = room_->GetTileObjects();
|
||||
EXPECT_EQ(objects[0].id_, 0x20);
|
||||
EXPECT_EQ(objects[0].x(), 15);
|
||||
@@ -85,14 +85,14 @@ TEST_F(RoomManipulationTest, UpdateObject) {
|
||||
TEST_F(RoomManipulationTest, FindObjectAt) {
|
||||
RoomObject obj1(0x10, 10, 20, 3, 0);
|
||||
RoomObject obj2(0x20, 15, 25, 2, 1);
|
||||
|
||||
|
||||
room_->AddObject(obj1);
|
||||
room_->AddObject(obj2);
|
||||
|
||||
|
||||
auto result = room_->FindObjectAt(15, 25, 1);
|
||||
ASSERT_TRUE(result.ok());
|
||||
EXPECT_EQ(result.value(), 1);
|
||||
|
||||
|
||||
auto not_found = room_->FindObjectAt(99, 99, 0);
|
||||
EXPECT_FALSE(not_found.ok());
|
||||
}
|
||||
@@ -101,19 +101,19 @@ TEST_F(RoomManipulationTest, ValidateObject) {
|
||||
// Valid Type 1 object
|
||||
RoomObject valid1(0x10, 10, 20, 3, 0);
|
||||
EXPECT_TRUE(room_->ValidateObject(valid1));
|
||||
|
||||
|
||||
// Valid Type 2 object
|
||||
RoomObject valid2(0x110, 30, 40, 0, 1);
|
||||
EXPECT_TRUE(room_->ValidateObject(valid2));
|
||||
|
||||
|
||||
// Invalid X (> 63)
|
||||
RoomObject invalid_x(0x10, 100, 20, 3, 0);
|
||||
EXPECT_FALSE(room_->ValidateObject(invalid_x));
|
||||
|
||||
|
||||
// Invalid layer (> 2)
|
||||
RoomObject invalid_layer(0x10, 10, 20, 3, 5);
|
||||
EXPECT_FALSE(room_->ValidateObject(invalid_layer));
|
||||
|
||||
|
||||
// Invalid size for Type 1 (> 15)
|
||||
RoomObject invalid_size(0x10, 10, 20, 20, 0);
|
||||
EXPECT_FALSE(room_->ValidateObject(invalid_size));
|
||||
@@ -125,21 +125,21 @@ TEST_F(RoomManipulationTest, MultipleOperations) {
|
||||
RoomObject obj(0x10 + i, i * 5, i * 6, i, 0);
|
||||
ASSERT_TRUE(room_->AddObject(obj).ok());
|
||||
}
|
||||
|
||||
|
||||
EXPECT_EQ(room_->GetTileObjects().size(), 5);
|
||||
|
||||
|
||||
// Update middle object
|
||||
RoomObject updated(0x99, 30, 35, 7, 1);
|
||||
ASSERT_TRUE(room_->UpdateObject(2, updated).ok());
|
||||
|
||||
|
||||
// Verify update
|
||||
auto objects = room_->GetTileObjects();
|
||||
EXPECT_EQ(objects[2].id_, 0x99);
|
||||
|
||||
|
||||
// Remove first object
|
||||
ASSERT_TRUE(room_->RemoveObject(0).ok());
|
||||
EXPECT_EQ(room_->GetTileObjects().size(), 4);
|
||||
|
||||
|
||||
// Verify first object is now what was second
|
||||
EXPECT_EQ(room_->GetTileObjects()[0].id_, 0x11);
|
||||
}
|
||||
@@ -149,16 +149,16 @@ TEST_F(RoomManipulationTest, LayerOrganization) {
|
||||
RoomObject layer0_obj(0x10, 10, 10, 2, 0);
|
||||
RoomObject layer1_obj(0x20, 20, 20, 3, 1);
|
||||
RoomObject layer2_obj(0x30, 30, 30, 4, 2);
|
||||
|
||||
|
||||
room_->AddObject(layer0_obj);
|
||||
room_->AddObject(layer1_obj);
|
||||
room_->AddObject(layer2_obj);
|
||||
|
||||
|
||||
// Verify can find by layer
|
||||
EXPECT_TRUE(room_->FindObjectAt(10, 10, 0).ok());
|
||||
EXPECT_TRUE(room_->FindObjectAt(20, 20, 1).ok());
|
||||
EXPECT_TRUE(room_->FindObjectAt(30, 30, 2).ok());
|
||||
|
||||
|
||||
// Wrong layer should not find
|
||||
EXPECT_FALSE(room_->FindObjectAt(10, 10, 1).ok());
|
||||
}
|
||||
@@ -166,4 +166,3 @@ TEST_F(RoomManipulationTest, LayerOrganization) {
|
||||
} // namespace test
|
||||
} // namespace zelda3
|
||||
} // namespace yaze
|
||||
|
||||
|
||||
@@ -45,15 +45,16 @@ TEST(RoomObjectEncodingTest, DetermineObjectTypeType3) {
|
||||
TEST(RoomObjectEncodingTest, Type1EncodeDecodeBasic) {
|
||||
// Type1: xxxxxxss yyyyyyss iiiiiiii
|
||||
// Example: Object ID 0x42, position (10, 20), size 3, layer 0
|
||||
|
||||
|
||||
RoomObject obj(0x42, 10, 20, 3, 0);
|
||||
|
||||
|
||||
// Encode
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
|
||||
|
||||
// Decode
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
// Verify
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
@@ -69,10 +70,11 @@ TEST(RoomObjectEncodingTest, Type1MaxValues) {
|
||||
// - X < 63 OR Size < 12 (b1 >= 0xFC triggers Type2 detection)
|
||||
// Safe max values: ID=0xF7, X=62, Y=63, Size=15
|
||||
RoomObject obj(0xF7, 62, 63, 15, 2);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 2);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 2);
|
||||
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
EXPECT_EQ(decoded.y(), obj.y());
|
||||
@@ -82,10 +84,11 @@ TEST(RoomObjectEncodingTest, Type1MaxValues) {
|
||||
TEST(RoomObjectEncodingTest, Type1MinValues) {
|
||||
// Test minimum values for Type1
|
||||
RoomObject obj(0x00, 0, 0, 0, 0);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
EXPECT_EQ(decoded.y(), obj.y());
|
||||
@@ -96,10 +99,11 @@ TEST(RoomObjectEncodingTest, Type1DifferentSizes) {
|
||||
// Test all valid size values (0-15)
|
||||
for (int size = 0; size <= 15; size++) {
|
||||
RoomObject obj(0x30, 15, 20, size, 1);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
EXPECT_EQ(decoded.size(), size) << "Failed for size " << size;
|
||||
}
|
||||
}
|
||||
@@ -108,9 +112,9 @@ TEST(RoomObjectEncodingTest, Type1RealWorldExample1) {
|
||||
// Example from actual ROM: Wall object
|
||||
// Bytes: 0x28 0x50 0x10
|
||||
// Expected: X=10, Y=20, Size=0, ID=0x10
|
||||
|
||||
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(0x28, 0x50, 0x10, 0);
|
||||
|
||||
|
||||
EXPECT_EQ(decoded.x(), 10);
|
||||
EXPECT_EQ(decoded.y(), 20);
|
||||
EXPECT_EQ(decoded.size(), 0);
|
||||
@@ -120,9 +124,9 @@ TEST(RoomObjectEncodingTest, Type1RealWorldExample1) {
|
||||
TEST(RoomObjectEncodingTest, Type1RealWorldExample2) {
|
||||
// Example: Ceiling object with size
|
||||
// Correct bytes for X=10, Y=20, Size=3, ID=0x00: 0x28 0x53 0x00
|
||||
|
||||
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(0x28, 0x53, 0x00, 0);
|
||||
|
||||
|
||||
EXPECT_EQ(decoded.x(), 10);
|
||||
EXPECT_EQ(decoded.y(), 20);
|
||||
EXPECT_EQ(decoded.size(), 3);
|
||||
@@ -136,18 +140,19 @@ TEST(RoomObjectEncodingTest, Type1RealWorldExample2) {
|
||||
TEST(RoomObjectEncodingTest, Type2EncodeDecodeBasic) {
|
||||
// Type2: 111111xx xxxxyyyy yyiiiiii
|
||||
// Example: Object ID 0x125, position (15, 30), size ignored, layer 1
|
||||
|
||||
|
||||
RoomObject obj(0x125, 15, 30, 0, 1);
|
||||
|
||||
|
||||
// Encode
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
|
||||
|
||||
// Verify b1 starts with 0xFC
|
||||
EXPECT_GE(bytes.b1, 0xFC);
|
||||
|
||||
|
||||
// Decode
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
// Verify
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
@@ -161,10 +166,11 @@ TEST(RoomObjectEncodingTest, Type2MaxValues) {
|
||||
// Safe max: X=63, Y=59, ID=0x13F (b3 = ((59&0x03)<<6)|(0x3F) = 0xFF still!)
|
||||
// Even safer: X=63, Y=63, ID=0x11F (b3 = (0xC0|0x1F) = 0xDF < 0xF8)
|
||||
RoomObject obj(0x11F, 63, 63, 0, 2);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 2);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 2);
|
||||
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
EXPECT_EQ(decoded.y(), obj.y());
|
||||
@@ -173,12 +179,13 @@ TEST(RoomObjectEncodingTest, Type2MaxValues) {
|
||||
TEST(RoomObjectEncodingTest, Type2RealWorldExample) {
|
||||
// Example: Large brazier (object 0x11C)
|
||||
// Position (8, 12)
|
||||
|
||||
|
||||
RoomObject obj(0x11C, 8, 12, 0, 0);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
EXPECT_EQ(decoded.id_, 0x11C);
|
||||
EXPECT_EQ(decoded.x(), 8);
|
||||
EXPECT_EQ(decoded.y(), 12);
|
||||
@@ -191,18 +198,19 @@ TEST(RoomObjectEncodingTest, Type2RealWorldExample) {
|
||||
TEST(RoomObjectEncodingTest, Type3EncodeDecodeChest) {
|
||||
// Type3: xxxxxxii yyyyyyii 11111iii
|
||||
// Example: Small chest (0xF99), position (5, 10)
|
||||
|
||||
|
||||
RoomObject obj(0xF99, 5, 10, 0, 0);
|
||||
|
||||
|
||||
// Encode
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
|
||||
|
||||
// Verify b3 >= 0xF8
|
||||
EXPECT_GE(bytes.b3, 0xF8);
|
||||
|
||||
|
||||
// Decode
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 0);
|
||||
|
||||
// Verify
|
||||
EXPECT_EQ(decoded.id_, obj.id_);
|
||||
EXPECT_EQ(decoded.x(), obj.x());
|
||||
@@ -211,12 +219,13 @@ TEST(RoomObjectEncodingTest, Type3EncodeDecodeChest) {
|
||||
|
||||
TEST(RoomObjectEncodingTest, Type3EncodeDcodeBigChest) {
|
||||
// Example: Big chest (0xFB1), position (15, 20)
|
||||
|
||||
|
||||
RoomObject obj(0xFB1, 15, 20, 0, 1);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, 1);
|
||||
|
||||
EXPECT_EQ(decoded.id_, 0xFB1);
|
||||
EXPECT_EQ(decoded.x(), 15);
|
||||
EXPECT_EQ(decoded.y(), 20);
|
||||
@@ -225,9 +234,9 @@ TEST(RoomObjectEncodingTest, Type3EncodeDcodeBigChest) {
|
||||
TEST(RoomObjectEncodingTest, Type3RealWorldExample) {
|
||||
// Example from ROM: Chest at position (10, 15)
|
||||
// Correct bytes for ID 0xF99: 0x29 0x3E 0xF9
|
||||
|
||||
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(0x29, 0x3E, 0xF9, 0);
|
||||
|
||||
|
||||
// Expected: X=10, Y=15, ID=0xF99 (small chest)
|
||||
EXPECT_EQ(decoded.x(), 10);
|
||||
EXPECT_EQ(decoded.y(), 15);
|
||||
@@ -242,40 +251,46 @@ TEST(RoomObjectEncodingTest, LayerPreservation) {
|
||||
// Test that layer information is preserved through encode/decode
|
||||
for (uint8_t layer = 0; layer <= 2; layer++) {
|
||||
RoomObject obj(0x42, 10, 20, 3, layer);
|
||||
|
||||
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, layer);
|
||||
|
||||
EXPECT_EQ(decoded.GetLayerValue(), layer) << "Failed for layer " << (int)layer;
|
||||
auto decoded =
|
||||
RoomObject::DecodeObjectFromBytes(bytes.b1, bytes.b2, bytes.b3, layer);
|
||||
|
||||
EXPECT_EQ(decoded.GetLayerValue(), layer)
|
||||
<< "Failed for layer " << (int)layer;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RoomObjectEncodingTest, BoundaryBetweenTypes) {
|
||||
// Test boundary values between object types
|
||||
// NOTE: Type1 can only go up to ID 0xF7 (b3 >= 0xF8 triggers Type3)
|
||||
|
||||
|
||||
// Last safe Type1 object
|
||||
RoomObject type1(0xF7, 10, 20, 3, 0);
|
||||
auto bytes1 = type1.EncodeObjectToBytes();
|
||||
auto decoded1 = RoomObject::DecodeObjectFromBytes(bytes1.b1, bytes1.b2, bytes1.b3, 0);
|
||||
auto decoded1 =
|
||||
RoomObject::DecodeObjectFromBytes(bytes1.b1, bytes1.b2, bytes1.b3, 0);
|
||||
EXPECT_EQ(decoded1.id_, 0xF7);
|
||||
|
||||
|
||||
// First Type2 object
|
||||
RoomObject type2(0x100, 10, 20, 0, 0);
|
||||
auto bytes2 = type2.EncodeObjectToBytes();
|
||||
auto decoded2 = RoomObject::DecodeObjectFromBytes(bytes2.b1, bytes2.b2, bytes2.b3, 0);
|
||||
auto decoded2 =
|
||||
RoomObject::DecodeObjectFromBytes(bytes2.b1, bytes2.b2, bytes2.b3, 0);
|
||||
EXPECT_EQ(decoded2.id_, 0x100);
|
||||
|
||||
|
||||
// Last Type2 object
|
||||
RoomObject type2_last(0x13F, 10, 20, 0, 0);
|
||||
auto bytes2_last = type2_last.EncodeObjectToBytes();
|
||||
auto decoded2_last = RoomObject::DecodeObjectFromBytes(bytes2_last.b1, bytes2_last.b2, bytes2_last.b3, 0);
|
||||
auto decoded2_last = RoomObject::DecodeObjectFromBytes(
|
||||
bytes2_last.b1, bytes2_last.b2, bytes2_last.b3, 0);
|
||||
EXPECT_EQ(decoded2_last.id_, 0x13F);
|
||||
|
||||
|
||||
// Type3 objects (start at 0xF80)
|
||||
RoomObject type3(0xF99, 10, 20, 0, 0);
|
||||
auto bytes3 = type3.EncodeObjectToBytes();
|
||||
auto decoded3 = RoomObject::DecodeObjectFromBytes(bytes3.b1, bytes3.b2, bytes3.b3, 0);
|
||||
auto decoded3 =
|
||||
RoomObject::DecodeObjectFromBytes(bytes3.b1, bytes3.b2, bytes3.b3, 0);
|
||||
EXPECT_EQ(decoded3.id_, 0xF99);
|
||||
}
|
||||
|
||||
@@ -283,13 +298,15 @@ TEST(RoomObjectEncodingTest, ZeroPosition) {
|
||||
// Test objects at position (0, 0)
|
||||
RoomObject type1(0x10, 0, 0, 0, 0);
|
||||
auto bytes1 = type1.EncodeObjectToBytes();
|
||||
auto decoded1 = RoomObject::DecodeObjectFromBytes(bytes1.b1, bytes1.b2, bytes1.b3, 0);
|
||||
auto decoded1 =
|
||||
RoomObject::DecodeObjectFromBytes(bytes1.b1, bytes1.b2, bytes1.b3, 0);
|
||||
EXPECT_EQ(decoded1.x(), 0);
|
||||
EXPECT_EQ(decoded1.y(), 0);
|
||||
|
||||
|
||||
RoomObject type2(0x110, 0, 0, 0, 0);
|
||||
auto bytes2 = type2.EncodeObjectToBytes();
|
||||
auto decoded2 = RoomObject::DecodeObjectFromBytes(bytes2.b1, bytes2.b2, bytes2.b3, 0);
|
||||
auto decoded2 =
|
||||
RoomObject::DecodeObjectFromBytes(bytes2.b1, bytes2.b2, bytes2.b3, 0);
|
||||
EXPECT_EQ(decoded2.x(), 0);
|
||||
EXPECT_EQ(decoded2.y(), 0);
|
||||
}
|
||||
@@ -301,21 +318,21 @@ TEST(RoomObjectEncodingTest, ZeroPosition) {
|
||||
TEST(RoomObjectEncodingTest, MultipleObjectsRoundTrip) {
|
||||
// Test encoding/decoding a batch of different objects
|
||||
std::vector<RoomObject> objects;
|
||||
|
||||
|
||||
// Add various objects
|
||||
objects.emplace_back(0x10, 5, 10, 2, 0); // Type1
|
||||
objects.emplace_back(0x42, 15, 20, 5, 1); // Type1
|
||||
objects.emplace_back(0x110, 8, 12, 0, 0); // Type2
|
||||
objects.emplace_back(0x125, 25, 30, 0, 1); // Type2
|
||||
objects.emplace_back(0xF99, 10, 15, 0, 0); // Type3 (chest)
|
||||
objects.emplace_back(0xFB1, 20, 25, 0, 2); // Type3 (big chest)
|
||||
|
||||
objects.emplace_back(0x10, 5, 10, 2, 0); // Type1
|
||||
objects.emplace_back(0x42, 15, 20, 5, 1); // Type1
|
||||
objects.emplace_back(0x110, 8, 12, 0, 0); // Type2
|
||||
objects.emplace_back(0x125, 25, 30, 0, 1); // Type2
|
||||
objects.emplace_back(0xF99, 10, 15, 0, 0); // Type3 (chest)
|
||||
objects.emplace_back(0xFB1, 20, 25, 0, 2); // Type3 (big chest)
|
||||
|
||||
for (size_t i = 0; i < objects.size(); i++) {
|
||||
auto& obj = objects[i];
|
||||
auto bytes = obj.EncodeObjectToBytes();
|
||||
auto decoded = RoomObject::DecodeObjectFromBytes(
|
||||
bytes.b1, bytes.b2, bytes.b3, obj.GetLayerValue());
|
||||
|
||||
|
||||
EXPECT_EQ(decoded.id_, obj.id_) << "Failed at index " << i;
|
||||
EXPECT_EQ(decoded.x(), obj.x()) << "Failed at index " << i;
|
||||
EXPECT_EQ(decoded.y(), obj.y()) << "Failed at index " << i;
|
||||
|
||||
@@ -18,35 +18,31 @@ namespace test {
|
||||
// Test DungeonToolset Component
|
||||
TEST(DungeonToolsetTest, BasicFunctionality) {
|
||||
editor::DungeonToolset toolset;
|
||||
|
||||
|
||||
// Test initial state
|
||||
EXPECT_EQ(toolset.background_type(), editor::DungeonToolset::kBackgroundAny);
|
||||
EXPECT_EQ(toolset.placement_type(), editor::DungeonToolset::kNoType);
|
||||
|
||||
|
||||
// Test state changes
|
||||
toolset.set_background_type(editor::DungeonToolset::kBackground1);
|
||||
EXPECT_EQ(toolset.background_type(), editor::DungeonToolset::kBackground1);
|
||||
|
||||
|
||||
toolset.set_placement_type(editor::DungeonToolset::kObject);
|
||||
EXPECT_EQ(toolset.placement_type(), editor::DungeonToolset::kObject);
|
||||
|
||||
|
||||
// Test all background types
|
||||
toolset.set_background_type(editor::DungeonToolset::kBackground2);
|
||||
EXPECT_EQ(toolset.background_type(), editor::DungeonToolset::kBackground2);
|
||||
|
||||
|
||||
toolset.set_background_type(editor::DungeonToolset::kBackground3);
|
||||
EXPECT_EQ(toolset.background_type(), editor::DungeonToolset::kBackground3);
|
||||
|
||||
|
||||
// Test all placement types
|
||||
std::vector<editor::DungeonToolset::PlacementType> placement_types = {
|
||||
editor::DungeonToolset::kSprite,
|
||||
editor::DungeonToolset::kItem,
|
||||
editor::DungeonToolset::kEntrance,
|
||||
editor::DungeonToolset::kDoor,
|
||||
editor::DungeonToolset::kChest,
|
||||
editor::DungeonToolset::kBlock
|
||||
};
|
||||
|
||||
editor::DungeonToolset::kSprite, editor::DungeonToolset::kItem,
|
||||
editor::DungeonToolset::kEntrance, editor::DungeonToolset::kDoor,
|
||||
editor::DungeonToolset::kChest, editor::DungeonToolset::kBlock};
|
||||
|
||||
for (auto type : placement_types) {
|
||||
toolset.set_placement_type(type);
|
||||
EXPECT_EQ(toolset.placement_type(), type);
|
||||
@@ -56,47 +52,48 @@ TEST(DungeonToolsetTest, BasicFunctionality) {
|
||||
// Test DungeonToolset Callbacks
|
||||
TEST(DungeonToolsetTest, CallbackFunctionality) {
|
||||
editor::DungeonToolset toolset;
|
||||
|
||||
|
||||
// Test callback setup (should not crash)
|
||||
bool undo_called = false;
|
||||
bool redo_called = false;
|
||||
bool palette_called = false;
|
||||
|
||||
|
||||
toolset.SetUndoCallback([&undo_called]() { undo_called = true; });
|
||||
toolset.SetRedoCallback([&redo_called]() { redo_called = true; });
|
||||
toolset.SetPaletteToggleCallback([&palette_called]() { palette_called = true; });
|
||||
|
||||
toolset.SetPaletteToggleCallback(
|
||||
[&palette_called]() { palette_called = true; });
|
||||
|
||||
// Callbacks are set but won't be triggered without UI interaction
|
||||
// The fact that we can set them without crashing validates the interface
|
||||
EXPECT_FALSE(undo_called); // Not called yet
|
||||
EXPECT_FALSE(redo_called); // Not called yet
|
||||
EXPECT_FALSE(undo_called); // Not called yet
|
||||
EXPECT_FALSE(redo_called); // Not called yet
|
||||
EXPECT_FALSE(palette_called); // Not called yet
|
||||
}
|
||||
|
||||
// Test DungeonUsageTracker Component
|
||||
TEST(DungeonUsageTrackerTest, BasicFunctionality) {
|
||||
editor::DungeonUsageTracker tracker;
|
||||
|
||||
|
||||
// Test initial state
|
||||
EXPECT_TRUE(tracker.GetBlocksetUsage().empty());
|
||||
EXPECT_TRUE(tracker.GetSpritesetUsage().empty());
|
||||
EXPECT_TRUE(tracker.GetPaletteUsage().empty());
|
||||
|
||||
|
||||
// Test initial selection state
|
||||
EXPECT_EQ(tracker.GetSelectedBlockset(), 0xFFFF);
|
||||
EXPECT_EQ(tracker.GetSelectedSpriteset(), 0xFFFF);
|
||||
EXPECT_EQ(tracker.GetSelectedPalette(), 0xFFFF);
|
||||
|
||||
|
||||
// Test selection setters
|
||||
tracker.SetSelectedBlockset(0x01);
|
||||
EXPECT_EQ(tracker.GetSelectedBlockset(), 0x01);
|
||||
|
||||
|
||||
tracker.SetSelectedSpriteset(0x02);
|
||||
EXPECT_EQ(tracker.GetSelectedSpriteset(), 0x02);
|
||||
|
||||
|
||||
tracker.SetSelectedPalette(0x03);
|
||||
EXPECT_EQ(tracker.GetSelectedPalette(), 0x03);
|
||||
|
||||
|
||||
// Test clear functionality
|
||||
tracker.ClearUsageStats();
|
||||
EXPECT_EQ(tracker.GetSelectedBlockset(), 0xFFFF);
|
||||
@@ -108,16 +105,16 @@ TEST(DungeonUsageTrackerTest, BasicFunctionality) {
|
||||
TEST(ComponentArchitectureTest, FileSizeReduction) {
|
||||
// This test validates that the refactoring actually reduced complexity
|
||||
// by ensuring the component files exist and are reasonably sized
|
||||
|
||||
|
||||
// The main dungeon_editor.cc should be significantly smaller
|
||||
// Before: ~1444 lines, Target: ~400-600 lines
|
||||
|
||||
|
||||
// We can't directly test file sizes, but we can test that
|
||||
// the components exist and function properly
|
||||
|
||||
|
||||
editor::DungeonToolset toolset;
|
||||
editor::DungeonUsageTracker tracker;
|
||||
|
||||
|
||||
// If we can create the components, the refactoring was successful
|
||||
EXPECT_EQ(toolset.background_type(), editor::DungeonToolset::kBackgroundAny);
|
||||
EXPECT_TRUE(tracker.GetBlocksetUsage().empty());
|
||||
|
||||
@@ -12,7 +12,7 @@ class ObjectParserStructsTest : public ::testing::Test {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectRoutineInfoDefaultConstructor) {
|
||||
zelda3::ObjectRoutineInfo info;
|
||||
|
||||
|
||||
EXPECT_EQ(info.routine_ptr, 0);
|
||||
EXPECT_EQ(info.tile_ptr, 0);
|
||||
EXPECT_EQ(info.tile_count, 0);
|
||||
@@ -22,7 +22,7 @@ TEST_F(ObjectParserStructsTest, ObjectRoutineInfoDefaultConstructor) {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectSubtypeInfoDefaultConstructor) {
|
||||
zelda3::ObjectSubtypeInfo info;
|
||||
|
||||
|
||||
EXPECT_EQ(info.subtype, 0);
|
||||
EXPECT_EQ(info.subtype_ptr, 0);
|
||||
EXPECT_EQ(info.routine_ptr, 0);
|
||||
@@ -31,7 +31,7 @@ TEST_F(ObjectParserStructsTest, ObjectSubtypeInfoDefaultConstructor) {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectSizeInfoDefaultConstructor) {
|
||||
zelda3::ObjectSizeInfo info;
|
||||
|
||||
|
||||
EXPECT_EQ(info.width_tiles, 0);
|
||||
EXPECT_EQ(info.height_tiles, 0);
|
||||
EXPECT_TRUE(info.is_horizontal);
|
||||
@@ -41,13 +41,13 @@ TEST_F(ObjectParserStructsTest, ObjectSizeInfoDefaultConstructor) {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectRoutineInfoAssignment) {
|
||||
zelda3::ObjectRoutineInfo info;
|
||||
|
||||
|
||||
info.routine_ptr = 0x12345;
|
||||
info.tile_ptr = 0x67890;
|
||||
info.tile_count = 8;
|
||||
info.is_repeatable = true;
|
||||
info.is_orientation_dependent = true;
|
||||
|
||||
|
||||
EXPECT_EQ(info.routine_ptr, 0x12345);
|
||||
EXPECT_EQ(info.tile_ptr, 0x67890);
|
||||
EXPECT_EQ(info.tile_count, 8);
|
||||
@@ -57,12 +57,12 @@ TEST_F(ObjectParserStructsTest, ObjectRoutineInfoAssignment) {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectSubtypeInfoAssignment) {
|
||||
zelda3::ObjectSubtypeInfo info;
|
||||
|
||||
|
||||
info.subtype = 2;
|
||||
info.subtype_ptr = 0x83F0;
|
||||
info.routine_ptr = 0x8470;
|
||||
info.max_tile_count = 16;
|
||||
|
||||
|
||||
EXPECT_EQ(info.subtype, 2);
|
||||
EXPECT_EQ(info.subtype_ptr, 0x83F0);
|
||||
EXPECT_EQ(info.routine_ptr, 0x8470);
|
||||
@@ -71,13 +71,13 @@ TEST_F(ObjectParserStructsTest, ObjectSubtypeInfoAssignment) {
|
||||
|
||||
TEST_F(ObjectParserStructsTest, ObjectSizeInfoAssignment) {
|
||||
zelda3::ObjectSizeInfo info;
|
||||
|
||||
|
||||
info.width_tiles = 4;
|
||||
info.height_tiles = 2;
|
||||
info.is_horizontal = false;
|
||||
info.is_repeatable = true;
|
||||
info.repeat_count = 3;
|
||||
|
||||
|
||||
EXPECT_EQ(info.width_tiles, 4);
|
||||
EXPECT_EQ(info.height_tiles, 2);
|
||||
EXPECT_FALSE(info.is_horizontal);
|
||||
|
||||
@@ -18,42 +18,44 @@ class OverworldTest : public ::testing::Test {
|
||||
// Create a mock ROM for testing
|
||||
rom_ = std::make_unique<Rom>();
|
||||
// Initialize with minimal ROM data for testing
|
||||
std::vector<uint8_t> mock_rom_data(0x200000, 0x00); // 2MB ROM filled with 0x00
|
||||
|
||||
std::vector<uint8_t> mock_rom_data(0x200000,
|
||||
0x00); // 2MB ROM filled with 0x00
|
||||
|
||||
// Set up some basic ROM data that OverworldMap expects
|
||||
mock_rom_data[0x140145] = 0xFF; // OverworldCustomASMHasBeenApplied = vanilla
|
||||
|
||||
mock_rom_data[0x140145] =
|
||||
0xFF; // OverworldCustomASMHasBeenApplied = vanilla
|
||||
|
||||
// Message IDs (2 bytes per map)
|
||||
for (int i = 0; i < 160; i++) { // 160 maps total
|
||||
for (int i = 0; i < 160; i++) { // 160 maps total
|
||||
mock_rom_data[0x3F51D + (i * 2)] = 0x00;
|
||||
mock_rom_data[0x3F51D + (i * 2) + 1] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Area graphics (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x7C9C + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Area palettes (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x7D1C + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Screen sizes (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x1788D + i] = 0x01; // Small area by default
|
||||
mock_rom_data[0x1788D + i] = 0x01; // Small area by default
|
||||
}
|
||||
|
||||
|
||||
// Sprite sets (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x7A41 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Sprite palettes (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x7B41 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Music (1 byte per map)
|
||||
for (int i = 0; i < 160; i++) {
|
||||
mock_rom_data[0x14303 + i] = 0x00;
|
||||
@@ -61,26 +63,26 @@ class OverworldTest : public ::testing::Test {
|
||||
mock_rom_data[0x14303 + 0x80 + i] = 0x00;
|
||||
mock_rom_data[0x14303 + 0xC0 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Dark World music
|
||||
for (int i = 0; i < 64; i++) {
|
||||
mock_rom_data[0x14403 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Special world graphics and palettes
|
||||
for (int i = 0; i < 32; i++) {
|
||||
mock_rom_data[0x16821 + i] = 0x00;
|
||||
mock_rom_data[0x16831 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
// Special world sprite graphics and palettes
|
||||
for (int i = 0; i < 32; i++) {
|
||||
mock_rom_data[0x0166E1 + i] = 0x00;
|
||||
mock_rom_data[0x016701 + i] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
rom_->LoadFromData(mock_rom_data);
|
||||
|
||||
|
||||
overworld_ = std::make_unique<Overworld>(rom_.get());
|
||||
}
|
||||
|
||||
@@ -96,7 +98,7 @@ class OverworldTest : public ::testing::Test {
|
||||
TEST_F(OverworldTest, OverworldMapInitialization) {
|
||||
// Test that OverworldMap can be created with valid parameters
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
EXPECT_EQ(map.area_graphics(), 0);
|
||||
EXPECT_EQ(map.area_palette(), 0);
|
||||
EXPECT_EQ(map.message_id(), 0);
|
||||
@@ -117,27 +119,27 @@ TEST_F(OverworldTest, AreaSizeEnumValues) {
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapSetters) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test main palette setter
|
||||
map.set_main_palette(5);
|
||||
EXPECT_EQ(map.main_palette(), 5);
|
||||
|
||||
|
||||
// Test area-specific background color setter
|
||||
map.set_area_specific_bg_color(0x7FFF);
|
||||
EXPECT_EQ(map.area_specific_bg_color(), 0x7FFF);
|
||||
|
||||
|
||||
// Test subscreen overlay setter
|
||||
map.set_subscreen_overlay(0x1234);
|
||||
EXPECT_EQ(map.subscreen_overlay(), 0x1234);
|
||||
|
||||
|
||||
// Test animated GFX setter
|
||||
map.set_animated_gfx(10);
|
||||
EXPECT_EQ(map.animated_gfx(), 10);
|
||||
|
||||
|
||||
// Test custom tileset setter
|
||||
map.set_custom_tileset(0, 20);
|
||||
EXPECT_EQ(map.custom_tileset(0), 20);
|
||||
|
||||
|
||||
// Test area size setter
|
||||
map.SetAreaSize(AreaSizeEnum::LargeArea);
|
||||
EXPECT_EQ(map.area_size(), AreaSizeEnum::LargeArea);
|
||||
@@ -145,14 +147,14 @@ TEST_F(OverworldTest, OverworldMapSetters) {
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapLargeMapSetup) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test SetAsLargeMap
|
||||
map.SetAsLargeMap(10, 2);
|
||||
EXPECT_EQ(map.parent(), 10);
|
||||
EXPECT_EQ(map.large_index(), 2);
|
||||
EXPECT_TRUE(map.is_large_map());
|
||||
EXPECT_EQ(map.area_size(), AreaSizeEnum::LargeArea);
|
||||
|
||||
|
||||
// Test SetAsSmallMap
|
||||
map.SetAsSmallMap(5);
|
||||
EXPECT_EQ(map.parent(), 5);
|
||||
@@ -163,13 +165,13 @@ TEST_F(OverworldTest, OverworldMapLargeMapSetup) {
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapCustomTilesetArray) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test setting all 8 custom tileset slots
|
||||
for (int i = 0; i < 8; i++) {
|
||||
map.set_custom_tileset(i, i + 10);
|
||||
EXPECT_EQ(map.custom_tileset(i), i + 10);
|
||||
}
|
||||
|
||||
|
||||
// Test mutable access
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*map.mutable_custom_tileset(i) = i + 20;
|
||||
@@ -179,21 +181,21 @@ TEST_F(OverworldTest, OverworldMapCustomTilesetArray) {
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapSpriteProperties) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test sprite graphics setters
|
||||
map.set_sprite_graphics(0, 1);
|
||||
map.set_sprite_graphics(1, 2);
|
||||
map.set_sprite_graphics(2, 3);
|
||||
|
||||
|
||||
EXPECT_EQ(map.sprite_graphics(0), 1);
|
||||
EXPECT_EQ(map.sprite_graphics(1), 2);
|
||||
EXPECT_EQ(map.sprite_graphics(2), 3);
|
||||
|
||||
|
||||
// Test sprite palette setters
|
||||
map.set_sprite_palette(0, 4);
|
||||
map.set_sprite_palette(1, 5);
|
||||
map.set_sprite_palette(2, 6);
|
||||
|
||||
|
||||
EXPECT_EQ(map.sprite_palette(0), 4);
|
||||
EXPECT_EQ(map.sprite_palette(1), 5);
|
||||
EXPECT_EQ(map.sprite_palette(2), 6);
|
||||
@@ -201,52 +203,52 @@ TEST_F(OverworldTest, OverworldMapSpriteProperties) {
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapBasicProperties) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test basic property setters
|
||||
map.set_area_graphics(15);
|
||||
EXPECT_EQ(map.area_graphics(), 15);
|
||||
|
||||
|
||||
map.set_area_palette(8);
|
||||
EXPECT_EQ(map.area_palette(), 8);
|
||||
|
||||
|
||||
map.set_message_id(0x1234);
|
||||
EXPECT_EQ(map.message_id(), 0x1234);
|
||||
}
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapMutableAccessors) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Test mutable accessors
|
||||
*map.mutable_area_graphics() = 25;
|
||||
EXPECT_EQ(map.area_graphics(), 25);
|
||||
|
||||
|
||||
*map.mutable_area_palette() = 12;
|
||||
EXPECT_EQ(map.area_palette(), 12);
|
||||
|
||||
|
||||
*map.mutable_message_id() = 0x5678;
|
||||
EXPECT_EQ(map.message_id(), 0x5678);
|
||||
|
||||
|
||||
*map.mutable_main_palette() = 7;
|
||||
EXPECT_EQ(map.main_palette(), 7);
|
||||
|
||||
|
||||
*map.mutable_animated_gfx() = 15;
|
||||
EXPECT_EQ(map.animated_gfx(), 15);
|
||||
|
||||
|
||||
*map.mutable_subscreen_overlay() = 0x9ABC;
|
||||
EXPECT_EQ(map.subscreen_overlay(), 0x9ABC);
|
||||
}
|
||||
|
||||
TEST_F(OverworldTest, OverworldMapDestroy) {
|
||||
OverworldMap map(0, rom_.get());
|
||||
|
||||
|
||||
// Set some properties
|
||||
map.set_area_graphics(10);
|
||||
map.set_main_palette(5);
|
||||
map.SetAreaSize(AreaSizeEnum::LargeArea);
|
||||
|
||||
|
||||
// Destroy and verify reset
|
||||
map.Destroy();
|
||||
|
||||
|
||||
EXPECT_EQ(map.area_graphics(), 0);
|
||||
EXPECT_EQ(map.main_palette(), 0);
|
||||
EXPECT_EQ(map.area_size(), AreaSizeEnum::SmallArea);
|
||||
@@ -257,34 +259,34 @@ TEST_F(OverworldTest, OverworldMapDestroy) {
|
||||
TEST_F(OverworldTest, WorldBasedSpriteFiltering) {
|
||||
// This test verifies the logic used in DrawOverworldSprites
|
||||
// for filtering sprites by world
|
||||
|
||||
int current_world = 1; // Dark World
|
||||
int sprite_map_id = 0x50; // Map 0x50 (Dark World)
|
||||
|
||||
|
||||
int current_world = 1; // Dark World
|
||||
int sprite_map_id = 0x50; // Map 0x50 (Dark World)
|
||||
|
||||
// Test that sprite should be shown for Dark World
|
||||
bool should_show = (sprite_map_id < 0x40 + (current_world * 0x40) &&
|
||||
sprite_map_id >= (current_world * 0x40));
|
||||
EXPECT_TRUE(should_show);
|
||||
|
||||
|
||||
// Test that sprite should NOT be shown for Light World
|
||||
current_world = 0; // Light World
|
||||
current_world = 0; // Light World
|
||||
should_show = (sprite_map_id < 0x40 + (current_world * 0x40) &&
|
||||
sprite_map_id >= (current_world * 0x40));
|
||||
EXPECT_FALSE(should_show);
|
||||
|
||||
|
||||
// Test boundary conditions
|
||||
current_world = 1; // Dark World
|
||||
sprite_map_id = 0x40; // First Dark World map
|
||||
current_world = 1; // Dark World
|
||||
sprite_map_id = 0x40; // First Dark World map
|
||||
should_show = (sprite_map_id < 0x40 + (current_world * 0x40) &&
|
||||
sprite_map_id >= (current_world * 0x40));
|
||||
EXPECT_TRUE(should_show);
|
||||
|
||||
sprite_map_id = 0x7F; // Last Dark World map
|
||||
|
||||
sprite_map_id = 0x7F; // Last Dark World map
|
||||
should_show = (sprite_map_id < 0x40 + (current_world * 0x40) &&
|
||||
sprite_map_id >= (current_world * 0x40));
|
||||
EXPECT_TRUE(should_show);
|
||||
|
||||
sprite_map_id = 0x80; // First Special World map
|
||||
|
||||
sprite_map_id = 0x80; // First Special World map
|
||||
should_show = (sprite_map_id < 0x40 + (current_world * 0x40) &&
|
||||
sprite_map_id >= (current_world * 0x40));
|
||||
EXPECT_FALSE(should_show);
|
||||
|
||||
@@ -26,18 +26,18 @@ class TestDungeonObjects : public ::testing::Test {
|
||||
// Test helpers
|
||||
absl::Status CreateTestRom();
|
||||
absl::Status SetupObjectData();
|
||||
|
||||
|
||||
// Mock data generators
|
||||
std::vector<uint8_t> CreateObjectSubtypeTable(int base_addr, int count);
|
||||
std::vector<uint8_t> CreateTileData(int base_addr, int tile_count);
|
||||
std::vector<uint8_t> CreateRoomHeader(int room_id);
|
||||
|
||||
std::unique_ptr<MockRom> test_rom_;
|
||||
|
||||
|
||||
// Test constants
|
||||
static constexpr int kTestObjectId = 0x01;
|
||||
static constexpr int kTestRoomId = 0x00;
|
||||
static constexpr size_t kTestRomSize = 0x100000; // 1MB test ROM
|
||||
static constexpr size_t kTestRomSize = 0x100000; // 1MB test ROM
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
Reference in New Issue
Block a user