18 const auto blocks = room.
blocks();
38 std::vector<SDL_Color> palette_colors;
39 if (SDL_Surface* bg_surface = room.
bg1_buffer().bitmap().surface()) {
41 palette_colors.assign(palette->colors,
42 palette->colors + palette->ncolors);
47 constexpr size_t kSheetBytes = 128 * 32;
50 const size_t offset = i * kSheetBytes;
53 meta.block_id = blocks[i];
54 meta.source_offset = offset;
55 if (offset + kSheetBytes > gfx_buffer.size()) {
60 std::vector<uint8_t> sheet_pixels(
61 gfx_buffer.begin() + offset, gfx_buffer.begin() + offset + kSheetBytes);
62 meta.nonzero_pixels =
static_cast<int>(
63 std::count_if(sheet_pixels.begin(), sheet_pixels.end(),
64 [](uint8_t value) { return value != 0; }));
68 if (!palette_colors.empty()) {
76 meta.palette_colors =
static_cast<int>(palette_colors.size());
93 rooms_ = &ctx.editor->rooms();
99 ImGui::TextDisabled(
"No room data available");
104 if (active_room_id < 0 ||
105 active_room_id >=
static_cast<int>(
rooms_->
size())) {
106 ImGui::TextDisabled(
"Invalid room ID: %d", active_room_id);
110 auto& room = (*rooms_)[active_room_id];
111 bool needs_render =
false;
112 if (room.blocks().empty()) {
113 room.LoadRoomGraphics(room.blockset());
116 if (!room.AreObjectsLoaded()) {
120 auto& bg1_bitmap = room.bg1_buffer().bitmap();
121 if (needs_render || !bg1_bitmap.is_active() || bg1_bitmap.width() == 0) {
122 room.RenderRoomGraphics();
125 room.LoadRoomGraphics(room.blockset());
131 auto blocks = room.blocks();
133 constexpr float kBlockWidth = 128.0f;
134 constexpr float kBlockHeight = 32.0f;
135 constexpr int kBlocksPerRow = 2;
136 constexpr float kPadding = 4.0f;
138 const int block_count =
static_cast<int>(blocks.size());
139 const int row_count =
140 std::max(1, (block_count + kBlocksPerRow - 1) / kBlocksPerRow);
141 const ImVec2 canvas_size(
142 std::max(ImGui::GetContentRegionAvail().x,
143 kPadding + (kBlockWidth + kPadding) *
144 static_cast<float>(kBlocksPerRow)),
145 kPadding + (kBlockHeight + kPadding) *
static_cast<float>(row_count));
147 ImGui::Text(
"Room %03X Graphics Blocks", active_room_id);
148 ImGui::TextDisabled(
"Blockset %02X | Spriteset %02X", room.blockset(),
163 const float grid_width =
164 kPadding + (kBlockWidth + kPadding) *
static_cast<float>(kBlocksPerRow);
165 const float x_offset = std::max(0.0f, (canvas_size.x - grid_width) * 0.5f);
166 ImDrawList* draw_list = ImGui::GetWindowDrawList();
167 for (
int i = 0; i < block_count; ++i) {
168 const uint8_t block_id = blocks[
static_cast<size_t>(i)];
169 const int row = i / kBlocksPerRow;
170 const int col = i % kBlocksPerRow;
171 const ImVec2 local_pos(x_offset + kPadding + col * (kBlockWidth + kPadding),
172 kPadding + row * (kBlockHeight + kPadding));
178 preview_opts.
dest_size = ImVec2(kBlockWidth, kBlockHeight);
189 const ImVec2 screen_pos(zero.x + local_pos.x, zero.y + local_pos.y);
190 const ImVec2 screen_end(screen_pos.x + kBlockWidth * scale,
191 screen_pos.y + kBlockHeight * scale);
192 draw_list->AddRect(screen_pos, screen_end,
194 draw_list->AddText(ImVec2(screen_pos.x + 6.0f, screen_pos.y + 6.0f),
196 block_id == 0 ?
"Empty" :
"Missing");
204 ImGuiTreeNodeFlags_DefaultOpen)) {
206 "Source: Room::get_gfx_buffer() -> preview bitmap -> queued texture");
207 ImGui::TextDisabled(
"Room buffer bytes: %zu", room.get_gfx_buffer().size());
210 i < std::min(block_count,
214 const uintptr_t texture_value =
reinterpret_cast<uintptr_t
>(
218 "Slot %02d | Block %02X | Buf +0x%04zX | %dx%d | nz=%d | pal=%d | "
219 "active=%d surf=%d tex=%d (0x%zx)",
220 i, meta.block_id, meta.source_offset, meta.width, meta.height,
221 meta.nonzero_pixels, meta.palette_colors, meta.bitmap_active,
222 meta.has_surface, meta.has_texture, texture_value);
std::array< uint8_t, 16 > preview_block_ids_
void RefreshSheetPreviews(const zelda3::Room &room)
void Draw(bool *p_open) override
Draw the panel content.
gfx::IRenderer * renderer_
std::array< gfx::Bitmap, 16 > sheet_previews_
std::array< SheetPreviewMetadata, 16 > sheet_preview_metadata_
DungeonRoomStore * rooms_
gui::Canvas room_gfx_canvas_