- Added multiple downwards drawing routines for various object types, enhancing the rendering capabilities of the ObjectDrawer. - Implemented methods for drawing 2x2 and 4x2 tiles with specific patterns and sizes, including edge cases for certain object IDs. - Updated the initialization logic to map new object IDs to their respective drawing routines, ensuring comprehensive coverage for downwards rendering. - Introduced debug logging for object drawing to facilitate troubleshooting and performance monitoring.
184 lines
9.4 KiB
C++
184 lines
9.4 KiB
C++
#ifndef YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
|
|
#define YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
|
|
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <functional>
|
|
|
|
#include "absl/status/status.h"
|
|
#include "app/gfx/background_buffer.h"
|
|
#include "app/gfx/snes_tile.h"
|
|
#include "app/gfx/snes_palette.h"
|
|
#include "app/rom.h"
|
|
#include "app/zelda3/dungeon/room_object.h"
|
|
|
|
namespace yaze {
|
|
namespace zelda3 {
|
|
|
|
/**
|
|
* @brief Draws dungeon objects to background buffers using game patterns
|
|
*
|
|
* This class interprets object IDs and draws them to BG1/BG2 buffers
|
|
* using the patterns extracted from the game's drawing routines.
|
|
* Based on ZScream's DungeonObjectData.cs and Subtype1_Draw.cs patterns.
|
|
*
|
|
* Architecture:
|
|
* 1. Load tile data from ROM for the object
|
|
* 2. Look up draw routine ID from object ID mapping
|
|
* 3. Execute appropriate draw routine with size/orientation
|
|
* 4. Write tiles to BackgroundBuffer according to pattern
|
|
* 5. Handle palette coordination and graphics sheet access
|
|
*/
|
|
class ObjectDrawer {
|
|
public:
|
|
explicit ObjectDrawer(Rom* rom, const uint8_t* room_gfx_buffer = nullptr);
|
|
|
|
/**
|
|
* @brief Draw a room object to background buffers
|
|
* @param object The object to draw
|
|
* @param bg1 Background layer 1 buffer
|
|
* @param bg2 Background layer 2 buffer
|
|
* @param palette_group Current palette group for color mapping
|
|
* @return Status of the drawing operation
|
|
*/
|
|
absl::Status DrawObject(const RoomObject& object,
|
|
gfx::BackgroundBuffer& bg1,
|
|
gfx::BackgroundBuffer& bg2,
|
|
const gfx::PaletteGroup& palette_group);
|
|
|
|
/**
|
|
* @brief Draw all objects in a room
|
|
* @param objects Vector of room objects
|
|
* @param bg1 Background layer 1 buffer
|
|
* @param bg2 Background layer 2 buffer
|
|
* @param palette_group Current palette group for color mapping
|
|
* @return Status of the drawing operation
|
|
*/
|
|
absl::Status DrawObjectList(const std::vector<RoomObject>& objects,
|
|
gfx::BackgroundBuffer& bg1,
|
|
gfx::BackgroundBuffer& bg2,
|
|
const gfx::PaletteGroup& palette_group);
|
|
|
|
/**
|
|
* @brief Get draw routine ID for an object
|
|
* @param object_id The object ID to look up
|
|
* @return Draw routine ID (0-24) based on ZScream mapping
|
|
*/
|
|
int GetDrawRoutineId(int16_t object_id) const;
|
|
|
|
/**
|
|
* @brief Initialize draw routine registry
|
|
* Must be called before drawing objects
|
|
*/
|
|
void InitializeDrawRoutines();
|
|
|
|
/**
|
|
* @brief Draw a single tile directly to bitmap
|
|
* @param bitmap Target bitmap to draw to
|
|
* @param tile_info Tile information (ID, palette, mirroring)
|
|
* @param pixel_x X pixel coordinate in bitmap
|
|
* @param pixel_y Y pixel coordinate in bitmap
|
|
* @param tiledata Source graphics data from ROM
|
|
*/
|
|
void DrawTileToBitmap(gfx::Bitmap& bitmap, const gfx::TileInfo& tile_info,
|
|
int pixel_x, int pixel_y, const uint8_t* tiledata);
|
|
|
|
private:
|
|
// Draw routine function type
|
|
using DrawRoutine = std::function<void(ObjectDrawer*, const RoomObject&, gfx::BackgroundBuffer&,
|
|
const std::vector<gfx::Tile16>&)>;
|
|
|
|
// Core draw routines (based on ZScream's subtype1_routines table)
|
|
void DrawRightwards2x2_1to15or32(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards2x4_1to15or26(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards2x4spaced4_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards2x4spaced4_1to16_BothBG(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards2x2_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDiagonalAcute_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDiagonalGrave_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDiagonalAcute_1to16_BothBG(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDiagonalGrave_1to16_BothBG(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards1x2_1to16_plus2(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsHasEdge1x1_1to16_plus3(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsHasEdge1x1_1to16_plus2(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsTopCorners1x2_1to16_plus13(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsBottomCorners1x2_1to16_plus13(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void CustomDraw(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards4x4_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwards1x1Solid_1to16_plus3(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDoorSwitcherer(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsDecor4x4spaced2_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsStatue2x3spaced2_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsPillar2x4spaced4_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsDecor4x3spaced4_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsDoubled2x2spaced2_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawRightwardsDecor2x2spaced12_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
|
|
// Downwards draw routines (missing implementation)
|
|
void DrawDownwards2x2_1to15or32(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwards4x2_1to15or26(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwards4x2_1to16_BothBG(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwardsDecor4x2spaced4_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwards2x2_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwardsHasEdge1x1_1to16_plus3(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwardsEdge1x1_1to16(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwardsLeftCorners2x1_1to16_plus12(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
void DrawDownwardsRightCorners2x1_1to16_plus12(const RoomObject& obj, gfx::BackgroundBuffer& bg,
|
|
const std::vector<gfx::Tile16>& tiles);
|
|
|
|
// Utility methods
|
|
void WriteTile8(gfx::BackgroundBuffer& bg, int tile_x, int tile_y,
|
|
const gfx::TileInfo& tile_info);
|
|
bool IsValidTilePosition(int tile_x, int tile_y) const;
|
|
|
|
// Draw routine registry
|
|
std::unordered_map<int16_t, int> object_to_routine_map_;
|
|
std::vector<DrawRoutine> draw_routines_;
|
|
bool routines_initialized_ = false;
|
|
|
|
Rom* rom_;
|
|
const uint8_t* room_gfx_buffer_; // Room-specific graphics buffer (current_gfx16_)
|
|
|
|
// Canvas dimensions in tiles (64x64 = 512x512 pixels)
|
|
static constexpr int kMaxTilesX = 64;
|
|
static constexpr int kMaxTilesY = 64;
|
|
};
|
|
|
|
} // namespace zelda3
|
|
} // namespace yaze
|
|
|
|
#endif // YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
|
|
|