diff --git a/src/app/editor/dungeon/dungeon_canvas_viewer.cc b/src/app/editor/dungeon/dungeon_canvas_viewer.cc index 91e23ead..300b05da 100644 --- a/src/app/editor/dungeon/dungeon_canvas_viewer.cc +++ b/src/app/editor/dungeon/dungeon_canvas_viewer.cc @@ -204,9 +204,9 @@ void DungeonCanvasViewer::RenderObjectInCanvas(const zelda3::RoomObject &object, break; } - // Calculate object size (16x16 is base, size affects width/height) - int object_width = 16 + (object.size_ & 0x0F) * 8; - int object_height = 16 + ((object.size_ >> 4) & 0x0F) * 8; + // Calculate object size (8x8 is base, size affects width/height) + int object_width = 8 + (object.size_ & 0x0F) * 8; + int object_height = 8 + ((object.size_ >> 4) & 0x0F) * 8; canvas_.DrawRect(canvas_x, canvas_y, object_width, object_height, object_color); canvas_.DrawRect(canvas_x, canvas_y, object_width, object_height, @@ -259,12 +259,12 @@ void DungeonCanvasViewer::RenderStairObjects(const zelda3::Room& room, } void DungeonCanvasViewer::RenderSprites(const zelda3::Room& room) { - // Render sprites as simple 16x16 squares with sprite name/ID + // Render sprites as simple 8x8 squares with sprite name/ID for (const auto& sprite : room.GetSprites()) { auto [canvas_x, canvas_y] = RoomToCanvasCoordinates(sprite.x(), sprite.y()); - if (IsWithinCanvasBounds(canvas_x, canvas_y, 16)) { - // Draw 16x16 square for sprite + if (IsWithinCanvasBounds(canvas_x, canvas_y, 8)) { + // Draw 8x8 square for sprite ImVec4 sprite_color; // Color-code sprites based on layer @@ -274,10 +274,10 @@ void DungeonCanvasViewer::RenderSprites(const zelda3::Room& room) { sprite_color = ImVec4(0.2f, 0.2f, 0.8f, 0.8f); // Blue for layer 1 } - canvas_.DrawRect(canvas_x, canvas_y, 16, 16, sprite_color); + canvas_.DrawRect(canvas_x, canvas_y, 8, 8, sprite_color); // Draw sprite border - canvas_.DrawRect(canvas_x, canvas_y, 16, 16, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + canvas_.DrawRect(canvas_x, canvas_y, 8, 8, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); // Draw sprite ID and name std::string sprite_text; @@ -319,21 +319,21 @@ void DungeonCanvasViewer::RenderChests(const zelda3::Room& room) { ImVec4(0.8f, 0.6f, 0.2f, 0.9f) : // Gold for big chest ImVec4(0.6f, 0.4f, 0.2f, 0.9f); // Brown for small chest - int chest_size = is_big_chest ? 24 : 16; // Big chests are larger - canvas_.DrawRect(canvas_x, canvas_y + 8, chest_size, 8, chest_color); + int chest_size = is_big_chest ? 16 : 8; // Big chests are larger + canvas_.DrawRect(canvas_x, canvas_y + 4, chest_size, 4, chest_color); // Draw chest lid (slightly lighter) ImVec4 lid_color = is_big_chest ? ImVec4(0.9f, 0.7f, 0.3f, 0.9f) : ImVec4(0.7f, 0.5f, 0.3f, 0.9f); - canvas_.DrawRect(canvas_x, canvas_y + 4, chest_size, 6, lid_color); + canvas_.DrawRect(canvas_x, canvas_y + 2, chest_size, 3, lid_color); // Draw chest borders - canvas_.DrawRect(canvas_x, canvas_y + 4, chest_size, 12, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + canvas_.DrawRect(canvas_x, canvas_y + 2, chest_size, 6, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); // Draw text label std::string chest_text = is_big_chest ? "BIG\nCHEST" : "CHEST"; - canvas_.DrawText(chest_text, canvas_x + chest_size + 2, canvas_y + 6); + canvas_.DrawText(chest_text, canvas_x + chest_size + 2, canvas_y + 3); } } } @@ -355,19 +355,19 @@ void DungeonCanvasViewer::RenderDoorObjects(const zelda3::Room& room) { if (is_door) { auto [canvas_x, canvas_y] = RoomToCanvasCoordinates(object.x_, object.y_); - if (IsWithinCanvasBounds(canvas_x, canvas_y, 32)) { + if (IsWithinCanvasBounds(canvas_x, canvas_y, 16)) { // Draw door frame - canvas_.DrawRect(canvas_x, canvas_y, 32, 32, ImVec4(0.5f, 0.3f, 0.2f, 0.8f)); // Brown frame + canvas_.DrawRect(canvas_x, canvas_y, 16, 16, ImVec4(0.5f, 0.3f, 0.2f, 0.8f)); // Brown frame // Draw door opening (darker) - canvas_.DrawRect(canvas_x + 4, canvas_y + 4, 24, 24, ImVec4(0.1f, 0.1f, 0.1f, 0.9f)); + canvas_.DrawRect(canvas_x + 2, canvas_y + 2, 12, 12, ImVec4(0.1f, 0.1f, 0.1f, 0.9f)); // Draw door border - canvas_.DrawRect(canvas_x, canvas_y, 32, 32, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + canvas_.DrawRect(canvas_x, canvas_y, 16, 16, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); // Draw text label std::string door_text = absl::StrFormat("DOOR\n0x%X", object.id_); - canvas_.DrawText(door_text, canvas_x + 34, canvas_y + 8); + canvas_.DrawText(door_text, canvas_x + 18, canvas_y + 4); } } } @@ -405,27 +405,28 @@ void DungeonCanvasViewer::RenderWallObjects(const zelda3::Room& room) { // Calculate wall size with proper length handling int wall_width, wall_height; - // For walls, use the size field to determine length + // For walls, use the size field to determine length and orientation if (object.id_ >= 0x10 && object.id_ <= 0x1F) { uint8_t size_x = object.size_ & 0x0F; uint8_t size_y = (object.size_ >> 4) & 0x0F; if (size_x > size_y) { // Horizontal wall - wall_width = 16 + size_x * 16; - wall_height = 16; + wall_width = 8 + size_x * 8; + wall_height = 8; } else if (size_y > size_x) { // Vertical wall - wall_width = 16; - wall_height = 16 + size_y * 16; + wall_width = 8; + wall_height = 8 + size_y * 8; } else { // Square wall or corner - wall_width = 16 + size_x * 8; - wall_height = 16 + size_y * 8; + wall_width = 8 + size_x * 4; + wall_height = 8 + size_y * 4; } } else { - wall_width = 16 + (object.size_ & 0x0F) * 8; - wall_height = 16 + ((object.size_ >> 4) & 0x0F) * 8; + // For other objects, use standard size calculation + wall_width = 8 + (object.size_ & 0x0F) * 4; + wall_height = 8 + ((object.size_ >> 4) & 0x0F) * 4; } wall_width = std::min(wall_width, 256); wall_height = std::min(wall_height, 256); @@ -455,22 +456,22 @@ void DungeonCanvasViewer::RenderPotObjects(const zelda3::Room& room) { if (object.id_ == 0x2F || object.id_ == 0x2B) { // Pot objects from assembly auto [canvas_x, canvas_y] = RoomToCanvasCoordinates(object.x_, object.y_); - if (IsWithinCanvasBounds(canvas_x, canvas_y, 16)) { + if (IsWithinCanvasBounds(canvas_x, canvas_y, 8)) { // Draw pot base (wider at bottom) - canvas_.DrawRect(canvas_x + 2, canvas_y + 10, 12, 6, ImVec4(0.7f, 0.5f, 0.3f, 0.8f)); // Brown base + canvas_.DrawRect(canvas_x + 1, canvas_y + 5, 6, 3, ImVec4(0.7f, 0.5f, 0.3f, 0.8f)); // Brown base // Draw pot middle - canvas_.DrawRect(canvas_x + 3, canvas_y + 6, 10, 6, ImVec4(0.8f, 0.6f, 0.4f, 0.8f)); // Lighter middle + canvas_.DrawRect(canvas_x + 2, canvas_y + 3, 4, 3, ImVec4(0.8f, 0.6f, 0.4f, 0.8f)); // Lighter middle // Draw pot rim - canvas_.DrawRect(canvas_x + 4, canvas_y + 4, 8, 4, ImVec4(0.9f, 0.7f, 0.5f, 0.8f)); // Lightest top + canvas_.DrawRect(canvas_x + 2, canvas_y + 2, 4, 2, ImVec4(0.9f, 0.7f, 0.5f, 0.8f)); // Lightest top // Draw pot outline - canvas_.DrawRect(canvas_x + 2, canvas_y + 4, 12, 12, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + canvas_.DrawRect(canvas_x + 1, canvas_y + 2, 6, 6, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); // Draw text label std::string pot_text = absl::StrFormat("POT\n0x%X", object.id_); - canvas_.DrawText(pot_text, canvas_x + 18, canvas_y + 6); + canvas_.DrawText(pot_text, canvas_x + 9, canvas_y + 3); } } } @@ -517,8 +518,8 @@ bool DungeonCanvasViewer::IsWithinCanvasBounds(int canvas_x, int canvas_y, void DungeonCanvasViewer::CalculateWallDimensions(const zelda3::RoomObject& object, int& width, int& height) { // Default base size - width = 16; - height = 16; + width = 8; + height = 8; // For walls, use the size field to determine length and orientation if (object.id_ >= 0x10 && object.id_ <= 0x1F) { @@ -529,21 +530,21 @@ void DungeonCanvasViewer::CalculateWallDimensions(const zelda3::RoomObject& obje // Walls can be horizontal or vertical based on size parameters if (size_x > size_y) { // Horizontal wall - width = 16 + size_x * 16; // Each unit adds 16 pixels - height = 16; + width = 8 + size_x * 8; // Each unit adds 8 pixels + height = 8; } else if (size_y > size_x) { // Vertical wall - width = 16; - height = 16 + size_y * 16; + width = 8; + height = 8 + size_y * 8; } else { // Square wall or corner - width = 16 + size_x * 8; - height = 16 + size_y * 8; + width = 8 + size_x * 4; + height = 8 + size_y * 4; } } else { // For other objects, use standard size calculation - width = 16 + (object.size_ & 0x0F) * 8; - height = 16 + ((object.size_ >> 4) & 0x0F) * 8; + width = 8 + (object.size_ & 0x0F) * 4; + height = 8 + ((object.size_ >> 4) & 0x0F) * 4; } // Clamp to reasonable limits diff --git a/src/app/rom.h b/src/app/rom.h index 3a546b23..16c13643 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -88,6 +88,11 @@ class Rom { absl::Status LoadZelda3(const RomLoadOptions& options); absl::Status LoadGfxGroups(); + absl::Status InitializeForTesting() { + RETURN_IF_ERROR(LoadZelda3(RomLoadOptions::AppDefaults())); + return absl::OkStatus(); + } + absl::Status SaveGfxGroups(); absl::Status SaveToFile(const SaveSettings& settings); absl::Status SavePalette(int index, const std::string& group_name, diff --git a/src/app/zelda3/dungeon/dungeon_object_editor.cc b/src/app/zelda3/dungeon/dungeon_object_editor.cc index 3400e423..75677624 100644 --- a/src/app/zelda3/dungeon/dungeon_object_editor.cc +++ b/src/app/zelda3/dungeon/dungeon_object_editor.cc @@ -13,18 +13,8 @@ namespace yaze { namespace zelda3 { -DungeonObjectEditor::DungeonObjectEditor(Rom* rom) - : rom_(rom) - , renderer_(std::make_unique(rom)) - , config_{} - , editing_state_{} - , selection_state_{} { - - // Initialize editor - auto status = InitializeEditor(); - if (!status.ok()) { - // Log error but don't fail construction - } +DungeonObjectEditor::DungeonObjectEditor(Rom* rom) : rom_(rom) { + renderer_ = std::make_unique(rom); } absl::Status DungeonObjectEditor::InitializeEditor() { diff --git a/src/app/zelda3/dungeon/object_renderer.cc b/src/app/zelda3/dungeon/object_renderer.cc index 4d9e82c5..c5e0b7cb 100644 --- a/src/app/zelda3/dungeon/object_renderer.cc +++ b/src/app/zelda3/dungeon/object_renderer.cc @@ -571,8 +571,8 @@ absl::StatusOr ObjectRenderer::RenderObjects( } // Calculate object position in the bitmap - int obj_x = object.x_ * 16; // Convert room coordinates to pixel coordinates - int obj_y = object.y_ * 16; + int obj_x = object.x_ * 8; // Convert room coordinates to pixel coordinates + int obj_y = object.y_ * 8; // Render each tile of the object for (size_t i = 0; i < object.tiles().size(); ++i) { @@ -616,7 +616,7 @@ absl::StatusOr ObjectRenderer::RenderObjectWithSize( if (tile_x < size_info.width_tiles && tile_y < size_info.height_tiles) { auto status = RenderTile(object.tiles()[i], bitmap, - tile_x * 16, tile_y * 16, palette); + tile_x * 8, tile_y * 8, palette); if (!status.ok()) { return status; } @@ -632,7 +632,7 @@ absl::StatusOr ObjectRenderer::RenderObjectWithSize( if (tile_x < size_info.width_tiles && tile_y < size_info.height_tiles) { auto status = RenderTile(object.tiles()[i], bitmap, - tile_x * 16, tile_y * 16, palette); + tile_x * 8, tile_y * 8, palette); if (!status.ok()) { return status; } @@ -882,8 +882,8 @@ std::pair ObjectRenderer::CalculateOptimalBitmapSize(const std::vector int max_x = 0, max_y = 0; for (const auto& obj : objects) { - int obj_max_x = obj.x_ * 16 + 16; - int obj_max_y = obj.y_ * 16 + 16; + int obj_max_x = obj.x_ * 8 + 16; + int obj_max_y = obj.y_ * 8 + 16; max_x = std::max(max_x, obj_max_x); max_y = std::max(max_y, obj_max_y); @@ -904,8 +904,8 @@ std::pair ObjectRenderer::CalculateOptimalBitmapSize(const std::vector } bool ObjectRenderer::IsObjectInBounds(const RoomObject& object, int bitmap_width, int bitmap_height) { - int obj_x = object.x_ * 16; - int obj_y = object.y_ * 16; + int obj_x = object.x_ * 8; + int obj_y = object.y_ * 8; return obj_x >= 0 && obj_y >= 0 && obj_x < bitmap_width && obj_y < bitmap_height; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 699918f9..15b46243 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -149,8 +149,6 @@ if(YAZE_BUILD_TESTS AND NOT YAZE_BUILD_TESTS STREQUAL "OFF") ) endif() - - # Configure test executable only when tests are enabled target_include_directories( yaze_test PUBLIC @@ -248,4 +246,4 @@ if(YAZE_BUILD_TESTS AND NOT YAZE_BUILD_TESTS STREQUAL "OFF") endif() endif() -include(test.cmake) \ No newline at end of file +include(test.cmake) diff --git a/test/integration/dungeon_editor_test.h b/test/integration/dungeon_editor_test.h index b5bb72eb..af8af0c8 100644 --- a/test/integration/dungeon_editor_test.h +++ b/test/integration/dungeon_editor_test.h @@ -28,6 +28,7 @@ class DungeonEditorIntegrationTest : public ::testing::Test { status = rom_->LoadFromFile("zelda3.sfc"); } ASSERT_TRUE(status.ok()) << "Could not load zelda3.sfc from any location"; + ASSERT_TRUE(rom_->InitializeForTesting().ok()); // Pass ROM to constructor so all components are initialized with it dungeon_editor_ = std::make_unique(rom_.get());