19 const auto blocks = room.
blocks();
39 std::vector<SDL_Color> palette_colors;
40 if (SDL_Surface* bg_surface = room.
bg1_buffer().bitmap().surface()) {
42 palette_colors.assign(palette->colors,
43 palette->colors + palette->ncolors);
48 constexpr size_t kSheetBytes = 128 * 32;
51 const size_t offset = i * kSheetBytes;
54 meta.block_id = blocks[i];
55 meta.source_offset = offset;
56 if (offset + kSheetBytes > gfx_buffer.size()) {
61 std::vector<uint8_t> sheet_pixels(
62 gfx_buffer.begin() + offset, gfx_buffer.begin() + offset + kSheetBytes);
63 meta.nonzero_pixels =
static_cast<int>(
64 std::count_if(sheet_pixels.begin(), sheet_pixels.end(),
65 [](uint8_t value) { return value != 0; }));
69 if (!palette_colors.empty()) {
77 meta.palette_colors =
static_cast<int>(palette_colors.size());
94 rooms_ = &ctx.editor->rooms();
100 ImGui::TextDisabled(tr(
"No room data available"));
105 if (active_room_id < 0 ||
106 active_room_id >=
static_cast<int>(
rooms_->
size())) {
107 ImGui::TextDisabled(tr(
"Invalid room ID: %d"), active_room_id);
111 auto& room = (*rooms_)[active_room_id];
112 bool needs_render =
false;
113 if (room.blocks().empty()) {
114 room.LoadRoomGraphics();
117 if (!room.AreObjectsLoaded()) {
121 auto& bg1_bitmap = room.bg1_buffer().bitmap();
122 if (needs_render || !bg1_bitmap.is_active() || bg1_bitmap.width() == 0) {
123 room.RenderRoomGraphics();
126 room.LoadRoomGraphics();
132 auto blocks = room.blocks();
134 constexpr float kBlockWidth = 128.0f;
135 constexpr float kBlockHeight = 32.0f;
136 constexpr int kBlocksPerRow = 2;
137 constexpr float kPadding = 4.0f;
139 const int block_count =
static_cast<int>(blocks.size());
140 const int row_count =
141 std::max(1, (block_count + kBlocksPerRow - 1) / kBlocksPerRow);
142 const ImVec2 canvas_size(
143 std::max(ImGui::GetContentRegionAvail().x,
144 kPadding + (kBlockWidth + kPadding) *
145 static_cast<float>(kBlocksPerRow)),
146 kPadding + (kBlockHeight + kPadding) *
static_cast<float>(row_count));
148 ImGui::Text(tr(
"Room %03X Graphics Blocks"), active_room_id);
149 ImGui::TextDisabled(tr(
"Blockset %02X | Spriteset %02X"), room.blockset(),
164 const float grid_width =
165 kPadding + (kBlockWidth + kPadding) *
static_cast<float>(kBlocksPerRow);
166 const float x_offset = std::max(0.0f, (canvas_size.x - grid_width) * 0.5f);
167 ImDrawList* draw_list = ImGui::GetWindowDrawList();
168 for (
int i = 0; i < block_count; ++i) {
169 const uint8_t block_id = blocks[
static_cast<size_t>(i)];
170 const int row = i / kBlocksPerRow;
171 const int col = i % kBlocksPerRow;
172 const ImVec2 local_pos(x_offset + kPadding + col * (kBlockWidth + kPadding),
173 kPadding + row * (kBlockHeight + kPadding));
179 preview_opts.
dest_size = ImVec2(kBlockWidth, kBlockHeight);
190 const ImVec2 screen_pos(zero.x + local_pos.x, zero.y + local_pos.y);
191 const ImVec2 screen_end(screen_pos.x + kBlockWidth * scale,
192 screen_pos.y + kBlockHeight * scale);
193 draw_list->AddRect(screen_pos, screen_end,
195 draw_list->AddText(ImVec2(screen_pos.x + 6.0f, screen_pos.y + 6.0f),
197 block_id == 0 ?
"Empty" :
"Missing");
205 ImGuiTreeNodeFlags_DefaultOpen)) {
206 ImGui::TextDisabled(tr(
207 "Source: Room::get_gfx_buffer() -> preview bitmap -> queued texture"));
208 ImGui::TextDisabled(tr(
"Room buffer bytes: %zu"),
209 room.get_gfx_buffer().size());
212 i < std::min(block_count,
216 const uintptr_t texture_value =
reinterpret_cast<uintptr_t
>(
220 tr(
"Slot %02d | Block %02X | Buf +0x%04zX | %dx%d | nz=%d | pal=%d | "
221 "active=%d surf=%d tex=%d (0x%zx)"),
222 i, meta.block_id, meta.source_offset, meta.width, meta.height,
223 meta.nonzero_pixels, meta.palette_colors, meta.bitmap_active,
224 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_