backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "app/editor/system/editor_card_registry.h"
|
||||
#include "app/editor/system/panel_manager.h"
|
||||
#include "app/gfx/core/bitmap.h"
|
||||
#include "app/gfx/debug/performance/performance_profiler.h"
|
||||
#include "app/gfx/resource/arena.h"
|
||||
@@ -25,43 +25,70 @@ namespace editor {
|
||||
constexpr uint32_t kRedPen = 0xFF0000FF;
|
||||
|
||||
void ScreenEditor::Initialize() {
|
||||
if (!dependencies_.card_registry)
|
||||
if (!dependencies_.panel_manager)
|
||||
return;
|
||||
auto* card_registry = dependencies_.card_registry;
|
||||
auto* panel_manager = dependencies_.panel_manager;
|
||||
|
||||
card_registry->RegisterCard({.card_id = "screen.dungeon_maps",
|
||||
.display_name = "Dungeon Maps",
|
||||
.icon = ICON_MD_MAP,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+1",
|
||||
.priority = 10});
|
||||
card_registry->RegisterCard({.card_id = "screen.inventory_menu",
|
||||
.display_name = "Inventory Menu",
|
||||
.icon = ICON_MD_INVENTORY,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+2",
|
||||
.priority = 20});
|
||||
card_registry->RegisterCard({.card_id = "screen.overworld_map",
|
||||
.display_name = "Overworld Map",
|
||||
.icon = ICON_MD_PUBLIC,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+3",
|
||||
.priority = 30});
|
||||
card_registry->RegisterCard({.card_id = "screen.title_screen",
|
||||
.display_name = "Title Screen",
|
||||
.icon = ICON_MD_TITLE,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+4",
|
||||
.priority = 40});
|
||||
card_registry->RegisterCard({.card_id = "screen.naming_screen",
|
||||
.display_name = "Naming Screen",
|
||||
.icon = ICON_MD_EDIT,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+5",
|
||||
.priority = 50});
|
||||
panel_manager->RegisterPanel({.card_id = "screen.dungeon_maps",
|
||||
.display_name = "Dungeon Maps",
|
||||
.window_title = " Dungeon Map Editor",
|
||||
.icon = ICON_MD_MAP,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+1",
|
||||
.priority = 10,
|
||||
.enabled_condition = [this]() { return rom()->is_loaded(); },
|
||||
.disabled_tooltip = "Load a ROM first"});
|
||||
panel_manager->RegisterPanel({.card_id = "screen.inventory_menu",
|
||||
.display_name = "Inventory Menu",
|
||||
.window_title = " Inventory Menu",
|
||||
.icon = ICON_MD_INVENTORY,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+2",
|
||||
.priority = 20,
|
||||
.enabled_condition = [this]() { return rom()->is_loaded(); },
|
||||
.disabled_tooltip = "Load a ROM first"});
|
||||
panel_manager->RegisterPanel({.card_id = "screen.overworld_map",
|
||||
.display_name = "Overworld Map",
|
||||
.window_title = " Overworld Map",
|
||||
.icon = ICON_MD_PUBLIC,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+3",
|
||||
.priority = 30,
|
||||
.enabled_condition = [this]() { return rom()->is_loaded(); },
|
||||
.disabled_tooltip = "Load a ROM first"});
|
||||
panel_manager->RegisterPanel({.card_id = "screen.title_screen",
|
||||
.display_name = "Title Screen",
|
||||
.window_title = " Title Screen",
|
||||
.icon = ICON_MD_TITLE,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+4",
|
||||
.priority = 40,
|
||||
.enabled_condition = [this]() { return rom()->is_loaded(); },
|
||||
.disabled_tooltip = "Load a ROM first"});
|
||||
panel_manager->RegisterPanel({.card_id = "screen.naming_screen",
|
||||
.display_name = "Naming Screen",
|
||||
.window_title = " Naming Screen",
|
||||
.icon = ICON_MD_EDIT,
|
||||
.category = "Screen",
|
||||
.shortcut_hint = "Alt+5",
|
||||
.priority = 50,
|
||||
.enabled_condition = [this]() { return rom()->is_loaded(); },
|
||||
.disabled_tooltip = "Load a ROM first"});
|
||||
|
||||
// Register EditorPanel implementations
|
||||
panel_manager->RegisterEditorPanel(std::make_unique<DungeonMapsPanel>(
|
||||
[this]() { DrawDungeonMapsEditor(); }));
|
||||
panel_manager->RegisterEditorPanel(std::make_unique<InventoryMenuPanel>(
|
||||
[this]() { DrawInventoryMenuEditor(); }));
|
||||
panel_manager->RegisterEditorPanel(std::make_unique<OverworldMapScreenPanel>(
|
||||
[this]() { DrawOverworldMapEditor(); }));
|
||||
panel_manager->RegisterEditorPanel(std::make_unique<TitleScreenPanel>(
|
||||
[this]() { DrawTitleScreenEditor(); }));
|
||||
panel_manager->RegisterEditorPanel(std::make_unique<NamingScreenPanel>(
|
||||
[this]() { DrawNamingScreenEditor(); }));
|
||||
|
||||
// Show title screen by default
|
||||
card_registry->ShowCard("screen.title_screen");
|
||||
panel_manager->ShowPanel("screen.title_screen");
|
||||
}
|
||||
|
||||
absl::Status ScreenEditor::Load() {
|
||||
@@ -70,19 +97,20 @@ absl::Status ScreenEditor::Load() {
|
||||
ASSIGN_OR_RETURN(dungeon_maps_,
|
||||
zelda3::LoadDungeonMaps(*rom(), dungeon_map_labels_));
|
||||
RETURN_IF_ERROR(zelda3::LoadDungeonMapTile16(
|
||||
tile16_blockset_, *rom(), rom()->graphics_buffer(), false));
|
||||
tile16_blockset_, *rom(), game_data(), game_data()->graphics_buffer,
|
||||
false));
|
||||
|
||||
// Load graphics sheets and apply dungeon palette
|
||||
sheets_.try_emplace(0, gfx::Arena::Get().gfx_sheets()[212]);
|
||||
sheets_.try_emplace(1, gfx::Arena::Get().gfx_sheets()[213]);
|
||||
sheets_.try_emplace(2, gfx::Arena::Get().gfx_sheets()[214]);
|
||||
sheets_.try_emplace(3, gfx::Arena::Get().gfx_sheets()[215]);
|
||||
sheets_[0] = std::make_unique<gfx::Bitmap>(gfx::Arena::Get().gfx_sheets()[212]);
|
||||
sheets_[1] = std::make_unique<gfx::Bitmap>(gfx::Arena::Get().gfx_sheets()[213]);
|
||||
sheets_[2] = std::make_unique<gfx::Bitmap>(gfx::Arena::Get().gfx_sheets()[214]);
|
||||
sheets_[3] = std::make_unique<gfx::Bitmap>(gfx::Arena::Get().gfx_sheets()[215]);
|
||||
|
||||
// Apply dungeon palette to all sheets
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sheets_[i].SetPalette(*rom()->mutable_dungeon_palette(3));
|
||||
sheets_[i]->SetPalette(*game_data()->palette_groups.dungeon_main.mutable_palette(3));
|
||||
gfx::Arena::Get().QueueTextureCommand(
|
||||
gfx::Arena::TextureCommandType::CREATE, &sheets_[i]);
|
||||
gfx::Arena::TextureCommandType::CREATE, sheets_[i].get());
|
||||
}
|
||||
|
||||
// Create a single tilemap for tile8 graphics with on-demand texture creation
|
||||
@@ -94,7 +122,7 @@ absl::Status ScreenEditor::Load() {
|
||||
|
||||
// Copy data from all 4 sheets into the combined bitmap
|
||||
for (int sheet_idx = 0; sheet_idx < 4; sheet_idx++) {
|
||||
const auto& sheet = sheets_[sheet_idx];
|
||||
const auto& sheet = *sheets_[sheet_idx];
|
||||
int dest_y_offset = sheet_idx * 32; // Each sheet is 32 pixels tall
|
||||
|
||||
for (int y = 0; y < 32; y++) {
|
||||
@@ -113,7 +141,7 @@ absl::Status ScreenEditor::Load() {
|
||||
tile8_tilemap_.tile_size = {8, 8};
|
||||
tile8_tilemap_.map_size = {256, 256}; // Logical size for tile count
|
||||
tile8_tilemap_.atlas.Create(tile8_width, tile8_height, 8, tile8_data);
|
||||
tile8_tilemap_.atlas.SetPalette(*rom()->mutable_dungeon_palette(3));
|
||||
tile8_tilemap_.atlas.SetPalette(*game_data()->palette_groups.dungeon_main.mutable_palette(3));
|
||||
|
||||
// Queue single texture creation for the atlas (not individual tiles)
|
||||
gfx::Arena::Get().QueueTextureCommand(gfx::Arena::TextureCommandType::CREATE,
|
||||
@@ -122,79 +150,9 @@ absl::Status ScreenEditor::Load() {
|
||||
}
|
||||
|
||||
absl::Status ScreenEditor::Update() {
|
||||
if (!dependencies_.card_registry)
|
||||
return absl::OkStatus();
|
||||
auto* card_registry = dependencies_.card_registry;
|
||||
|
||||
static gui::EditorCard dungeon_maps_card("Dungeon Maps", ICON_MD_MAP);
|
||||
static gui::EditorCard inventory_menu_card("Inventory Menu",
|
||||
ICON_MD_INVENTORY);
|
||||
static gui::EditorCard overworld_map_card("Overworld Map", ICON_MD_PUBLIC);
|
||||
static gui::EditorCard title_screen_card("Title Screen", ICON_MD_TITLE);
|
||||
static gui::EditorCard naming_screen_card("Naming Screen",
|
||||
ICON_MD_EDIT_ATTRIBUTES);
|
||||
|
||||
dungeon_maps_card.SetDefaultSize(800, 600);
|
||||
inventory_menu_card.SetDefaultSize(800, 600);
|
||||
overworld_map_card.SetDefaultSize(600, 500);
|
||||
title_screen_card.SetDefaultSize(600, 500);
|
||||
naming_screen_card.SetDefaultSize(500, 400);
|
||||
|
||||
// Dungeon Maps Card - Check visibility flag exists and is true before
|
||||
// rendering
|
||||
bool* dungeon_maps_visible =
|
||||
card_registry->GetVisibilityFlag("screen.dungeon_maps");
|
||||
if (dungeon_maps_visible && *dungeon_maps_visible) {
|
||||
if (dungeon_maps_card.Begin(dungeon_maps_visible)) {
|
||||
DrawDungeonMapsEditor();
|
||||
}
|
||||
dungeon_maps_card.End();
|
||||
}
|
||||
|
||||
// Inventory Menu Card - Check visibility flag exists and is true before
|
||||
// rendering
|
||||
bool* inventory_menu_visible =
|
||||
card_registry->GetVisibilityFlag("screen.inventory_menu");
|
||||
if (inventory_menu_visible && *inventory_menu_visible) {
|
||||
if (inventory_menu_card.Begin(inventory_menu_visible)) {
|
||||
DrawInventoryMenuEditor();
|
||||
}
|
||||
inventory_menu_card.End();
|
||||
}
|
||||
|
||||
// Overworld Map Card - Check visibility flag exists and is true before
|
||||
// rendering
|
||||
bool* overworld_map_visible =
|
||||
card_registry->GetVisibilityFlag("screen.overworld_map");
|
||||
if (overworld_map_visible && *overworld_map_visible) {
|
||||
if (overworld_map_card.Begin(overworld_map_visible)) {
|
||||
DrawOverworldMapEditor();
|
||||
}
|
||||
overworld_map_card.End();
|
||||
}
|
||||
|
||||
// Title Screen Card - Check visibility flag exists and is true before
|
||||
// rendering
|
||||
bool* title_screen_visible =
|
||||
card_registry->GetVisibilityFlag("screen.title_screen");
|
||||
if (title_screen_visible && *title_screen_visible) {
|
||||
if (title_screen_card.Begin(title_screen_visible)) {
|
||||
DrawTitleScreenEditor();
|
||||
}
|
||||
title_screen_card.End();
|
||||
}
|
||||
|
||||
// Naming Screen Card - Check visibility flag exists and is true before
|
||||
// rendering
|
||||
bool* naming_screen_visible =
|
||||
card_registry->GetVisibilityFlag("screen.naming_screen");
|
||||
if (naming_screen_visible && *naming_screen_visible) {
|
||||
if (naming_screen_card.Begin(naming_screen_visible)) {
|
||||
DrawNamingScreenEditor();
|
||||
}
|
||||
naming_screen_card.End();
|
||||
}
|
||||
|
||||
// Panel drawing is handled centrally by PanelManager::DrawAllVisiblePanels()
|
||||
// via the EditorPanel implementations registered in Initialize().
|
||||
// No local drawing needed here - this fixes duplicate panel rendering.
|
||||
return status_;
|
||||
}
|
||||
|
||||
@@ -205,8 +163,8 @@ void ScreenEditor::DrawToolset() {
|
||||
|
||||
void ScreenEditor::DrawInventoryMenuEditor() {
|
||||
static bool create = false;
|
||||
if (!create && rom()->is_loaded()) {
|
||||
status_ = inventory_.Create(rom());
|
||||
if (!create && rom()->is_loaded() && game_data()) {
|
||||
status_ = inventory_.Create(rom(), game_data());
|
||||
if (status_.ok()) {
|
||||
palette_ = inventory_.palette();
|
||||
create = true;
|
||||
@@ -227,18 +185,27 @@ void ScreenEditor::DrawInventoryMenuEditor() {
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
screen_canvas_.DrawBackground();
|
||||
screen_canvas_.DrawContextMenu();
|
||||
screen_canvas_.DrawBitmap(inventory_.bitmap(), 2, create);
|
||||
screen_canvas_.DrawGrid(32.0f);
|
||||
screen_canvas_.DrawOverlay();
|
||||
{
|
||||
gui::CanvasFrameOptions frame_opts;
|
||||
frame_opts.draw_grid = true;
|
||||
frame_opts.grid_step = 32.0f;
|
||||
frame_opts.render_popups = true;
|
||||
auto runtime = gui::BeginCanvas(screen_canvas_, frame_opts);
|
||||
gui::DrawBitmap(runtime, inventory_.bitmap(), 2, create ? 1.0f : 0.0f);
|
||||
gui::EndCanvas(screen_canvas_, runtime, frame_opts);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, (192 * 2) + 4));
|
||||
tilesheet_canvas_.DrawContextMenu();
|
||||
tilesheet_canvas_.DrawBitmap(inventory_.tilesheet(), 2, create);
|
||||
tilesheet_canvas_.DrawGrid(16.0f);
|
||||
tilesheet_canvas_.DrawOverlay();
|
||||
{
|
||||
gui::CanvasFrameOptions frame_opts;
|
||||
frame_opts.canvas_size = ImVec2(128 * 2 + 2, (192 * 2) + 4);
|
||||
frame_opts.draw_grid = true;
|
||||
frame_opts.grid_step = 16.0f;
|
||||
frame_opts.render_popups = true;
|
||||
auto runtime = gui::BeginCanvas(tilesheet_canvas_, frame_opts);
|
||||
gui::DrawBitmap(runtime, inventory_.tilesheet(), 2, create ? 1.0f : 0.0f);
|
||||
gui::EndCanvas(tilesheet_canvas_, runtime, frame_opts);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
DrawInventoryItemIcons();
|
||||
@@ -536,24 +503,42 @@ void ScreenEditor::DrawDungeonMapsRoomGfx() {
|
||||
gfx::ScopedTimer timer("screen_editor_draw_dungeon_maps_room_gfx");
|
||||
|
||||
if (ImGui::BeginChild("##DungeonMapTiles", ImVec2(0, 0), true)) {
|
||||
// Enhanced tilesheet canvas with improved tile selection
|
||||
tilesheet_canvas_.DrawBackground(ImVec2((256 * 2) + 2, (192 * 2) + 4));
|
||||
tilesheet_canvas_.DrawContextMenu();
|
||||
// Enhanced tilesheet canvas with BeginCanvas/EndCanvas pattern
|
||||
{
|
||||
gui::CanvasFrameOptions tilesheet_opts;
|
||||
tilesheet_opts.canvas_size = ImVec2((256 * 2) + 2, (192 * 2) + 4);
|
||||
tilesheet_opts.draw_grid = true;
|
||||
tilesheet_opts.grid_step = 32.0f;
|
||||
tilesheet_opts.render_popups = true;
|
||||
|
||||
// Interactive tile16 selector with grid snapping
|
||||
if (tilesheet_canvas_.DrawTileSelector(32.f)) {
|
||||
selected_tile16_ = tilesheet_canvas_.points().front().x / 32 +
|
||||
(tilesheet_canvas_.points().front().y / 32) * 16;
|
||||
auto tilesheet_rt = gui::BeginCanvas(tilesheet_canvas_, tilesheet_opts);
|
||||
|
||||
// Render selected tile16 and cache tile metadata
|
||||
gfx::RenderTile16(nullptr, tile16_blockset_, selected_tile16_);
|
||||
std::ranges::copy(tile16_blockset_.tile_info[selected_tile16_],
|
||||
current_tile16_info.begin());
|
||||
// Interactive tile16 selector with grid snapping
|
||||
ImVec2 selected_pos;
|
||||
if (gui::DrawTileSelector(tilesheet_rt, 32, 0, &selected_pos)) {
|
||||
// Double-click detected - handle tile confirmation if needed
|
||||
}
|
||||
|
||||
// Check for single-click selection (legacy compatibility)
|
||||
if (tilesheet_canvas_.IsMouseHovering() &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
if (!tilesheet_canvas_.points().empty()) {
|
||||
selected_tile16_ =
|
||||
static_cast<int>(tilesheet_canvas_.points().front().x / 32 +
|
||||
(tilesheet_canvas_.points().front().y / 32) * 16);
|
||||
|
||||
// Render selected tile16 and cache tile metadata
|
||||
gfx::RenderTile16(nullptr, tile16_blockset_, selected_tile16_);
|
||||
std::ranges::copy(tile16_blockset_.tile_info[selected_tile16_],
|
||||
current_tile16_info.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// Use stateless bitmap rendering for tilesheet
|
||||
gui::DrawBitmap(tilesheet_rt, tile16_blockset_.atlas, 1, 1, 2.0F, 255);
|
||||
|
||||
gui::EndCanvas(tilesheet_canvas_, tilesheet_rt, tilesheet_opts);
|
||||
}
|
||||
// Use direct bitmap rendering for tilesheet
|
||||
tilesheet_canvas_.DrawBitmap(tile16_blockset_.atlas, 1, 1, 2.0F, 255);
|
||||
tilesheet_canvas_.DrawGrid(32.f);
|
||||
tilesheet_canvas_.DrawOverlay();
|
||||
|
||||
if (!tilesheet_canvas_.points().empty() &&
|
||||
!screen_canvas_.points().empty()) {
|
||||
@@ -563,73 +548,84 @@ void ScreenEditor::DrawDungeonMapsRoomGfx() {
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
current_tile_canvas_.DrawBackground(); // ImVec2(64 * 2 + 2, 64 * 2 + 4));
|
||||
current_tile_canvas_.DrawContextMenu();
|
||||
|
||||
// Get tile8 from cache on-demand (only create texture when needed)
|
||||
if (selected_tile8_ >= 0 && selected_tile8_ < 256) {
|
||||
auto* cached_tile8 = tile8_tilemap_.tile_cache.GetTile(selected_tile8_);
|
||||
// Current tile canvas with BeginCanvas/EndCanvas pattern
|
||||
{
|
||||
gui::CanvasFrameOptions current_tile_opts;
|
||||
current_tile_opts.draw_grid = true;
|
||||
current_tile_opts.grid_step = 16.0f;
|
||||
current_tile_opts.render_popups = true;
|
||||
|
||||
if (!cached_tile8) {
|
||||
// Extract tile from atlas and cache it
|
||||
const int tiles_per_row =
|
||||
tile8_tilemap_.atlas.width() / 8; // 128 / 8 = 16
|
||||
const int tile_x = (selected_tile8_ % tiles_per_row) * 8;
|
||||
const int tile_y = (selected_tile8_ / tiles_per_row) * 8;
|
||||
auto current_tile_rt =
|
||||
gui::BeginCanvas(current_tile_canvas_, current_tile_opts);
|
||||
|
||||
// Extract 8x8 tile data from atlas
|
||||
std::vector<uint8_t> tile_data(64);
|
||||
for (int py = 0; py < 8; py++) {
|
||||
for (int px = 0; px < 8; px++) {
|
||||
int src_x = tile_x + px;
|
||||
int src_y = tile_y + py;
|
||||
int src_index = src_y * tile8_tilemap_.atlas.width() + src_x;
|
||||
int dst_index = py * 8 + px;
|
||||
// Get tile8 from cache on-demand (only create texture when needed)
|
||||
if (selected_tile8_ >= 0 && selected_tile8_ < 256) {
|
||||
auto* cached_tile8 = tile8_tilemap_.tile_cache.GetTile(selected_tile8_);
|
||||
|
||||
if (src_index < tile8_tilemap_.atlas.size() && dst_index < 64) {
|
||||
tile_data[dst_index] = tile8_tilemap_.atlas.data()[src_index];
|
||||
if (!cached_tile8) {
|
||||
// Extract tile from atlas and cache it
|
||||
const int tiles_per_row =
|
||||
tile8_tilemap_.atlas.width() / 8; // 128 / 8 = 16
|
||||
const int tile_x = (selected_tile8_ % tiles_per_row) * 8;
|
||||
const int tile_y = (selected_tile8_ / tiles_per_row) * 8;
|
||||
|
||||
// Extract 8x8 tile data from atlas
|
||||
std::vector<uint8_t> tile_data(64);
|
||||
for (int py = 0; py < 8; py++) {
|
||||
for (int px = 0; px < 8; px++) {
|
||||
int src_x = tile_x + px;
|
||||
int src_y = tile_y + py;
|
||||
int src_index = src_y * tile8_tilemap_.atlas.width() + src_x;
|
||||
int dst_index = py * 8 + px;
|
||||
|
||||
if (src_index < tile8_tilemap_.atlas.size() && dst_index < 64) {
|
||||
tile_data[dst_index] = tile8_tilemap_.atlas.data()[src_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Bitmap new_tile8(8, 8, 8, tile_data);
|
||||
new_tile8.SetPalette(tile8_tilemap_.atlas.palette());
|
||||
tile8_tilemap_.tile_cache.CacheTile(selected_tile8_,
|
||||
std::move(new_tile8));
|
||||
cached_tile8 = tile8_tilemap_.tile_cache.GetTile(selected_tile8_);
|
||||
}
|
||||
|
||||
gfx::Bitmap new_tile8(8, 8, 8, tile_data);
|
||||
new_tile8.SetPalette(tile8_tilemap_.atlas.palette());
|
||||
tile8_tilemap_.tile_cache.CacheTile(selected_tile8_,
|
||||
std::move(new_tile8));
|
||||
cached_tile8 = tile8_tilemap_.tile_cache.GetTile(selected_tile8_);
|
||||
if (cached_tile8 && cached_tile8->is_active()) {
|
||||
// Create texture on-demand only when needed
|
||||
if (!cached_tile8->texture()) {
|
||||
gfx::Arena::Get().QueueTextureCommand(
|
||||
gfx::Arena::TextureCommandType::CREATE, cached_tile8);
|
||||
}
|
||||
|
||||
// DrawTilePainter still uses member function (not yet migrated)
|
||||
if (current_tile_canvas_.DrawTilePainter(*cached_tile8, 16)) {
|
||||
// Modify the tile16 based on the selected tile and
|
||||
// current_tile16_info
|
||||
gfx::ModifyTile16(tile16_blockset_, game_data()->graphics_buffer,
|
||||
current_tile16_info[0], current_tile16_info[1],
|
||||
current_tile16_info[2], current_tile16_info[3],
|
||||
212, selected_tile16_);
|
||||
gfx::UpdateTile16(nullptr, tile16_blockset_, selected_tile16_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cached_tile8 && cached_tile8->is_active()) {
|
||||
// Create texture on-demand only when needed
|
||||
if (!cached_tile8->texture()) {
|
||||
// Get selected tile from cache and draw with stateless helper
|
||||
auto* selected_tile =
|
||||
tile16_blockset_.tile_cache.GetTile(selected_tile16_);
|
||||
if (selected_tile && selected_tile->is_active()) {
|
||||
// Ensure the selected tile has a valid texture
|
||||
if (!selected_tile->texture()) {
|
||||
gfx::Arena::Get().QueueTextureCommand(
|
||||
gfx::Arena::TextureCommandType::CREATE, cached_tile8);
|
||||
gfx::Arena::TextureCommandType::CREATE, selected_tile);
|
||||
}
|
||||
gui::DrawBitmap(current_tile_rt, *selected_tile, 2, 2, 4.0f, 255);
|
||||
}
|
||||
|
||||
if (current_tile_canvas_.DrawTilePainter(*cached_tile8, 16)) {
|
||||
// Modify the tile16 based on the selected tile and
|
||||
// current_tile16_info
|
||||
gfx::ModifyTile16(tile16_blockset_, rom()->graphics_buffer(),
|
||||
current_tile16_info[0], current_tile16_info[1],
|
||||
current_tile16_info[2], current_tile16_info[3], 212,
|
||||
selected_tile16_);
|
||||
gfx::UpdateTile16(nullptr, tile16_blockset_, selected_tile16_);
|
||||
}
|
||||
}
|
||||
gui::EndCanvas(current_tile_canvas_, current_tile_rt, current_tile_opts);
|
||||
}
|
||||
// Get selected tile from cache
|
||||
auto* selected_tile = tile16_blockset_.tile_cache.GetTile(selected_tile16_);
|
||||
if (selected_tile && selected_tile->is_active()) {
|
||||
// Ensure the selected tile has a valid texture
|
||||
if (!selected_tile->texture()) {
|
||||
// Queue texture creation via Arena's deferred system
|
||||
gfx::Arena::Get().QueueTextureCommand(
|
||||
gfx::Arena::TextureCommandType::CREATE, selected_tile);
|
||||
}
|
||||
current_tile_canvas_.DrawBitmap(*selected_tile, 2, 2, 4.0f, 255);
|
||||
}
|
||||
current_tile_canvas_.DrawGrid(16.f);
|
||||
current_tile_canvas_.DrawOverlay();
|
||||
|
||||
gui::InputTileInfo("TL", ¤t_tile16_info[0]);
|
||||
ImGui::SameLine();
|
||||
@@ -639,7 +635,7 @@ void ScreenEditor::DrawDungeonMapsRoomGfx() {
|
||||
gui::InputTileInfo("BR", ¤t_tile16_info[3]);
|
||||
|
||||
if (ImGui::Button("Modify Tile16")) {
|
||||
gfx::ModifyTile16(tile16_blockset_, rom()->graphics_buffer(),
|
||||
gfx::ModifyTile16(tile16_blockset_, game_data()->graphics_buffer,
|
||||
current_tile16_info[0], current_tile16_info[1],
|
||||
current_tile16_info[2], current_tile16_info[3], 212,
|
||||
selected_tile16_);
|
||||
@@ -742,19 +738,19 @@ void ScreenEditor::LoadBinaryGfx() {
|
||||
std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
if (auto converted_bin = gfx::SnesTo8bppSheet(bin_data, 4, 4);
|
||||
zelda3::LoadDungeonMapTile16(tile16_blockset_, *rom(), converted_bin,
|
||||
true)
|
||||
zelda3::LoadDungeonMapTile16(tile16_blockset_, *rom(), game_data(),
|
||||
converted_bin, true)
|
||||
.ok()) {
|
||||
sheets_.clear();
|
||||
std::vector<std::vector<uint8_t>> gfx_sheets;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gfx_sheets.emplace_back(converted_bin.begin() + (i * 0x1000),
|
||||
converted_bin.begin() + ((i + 1) * 0x1000));
|
||||
sheets_.emplace(i, gfx::Bitmap(128, 32, 8, gfx_sheets[i]));
|
||||
sheets_[i].SetPalette(*rom()->mutable_dungeon_palette(3));
|
||||
sheets_[i] = std::make_unique<gfx::Bitmap>(128, 32, 8, gfx_sheets[i]);
|
||||
sheets_[i]->SetPalette(*game_data()->palette_groups.dungeon_main.mutable_palette(3));
|
||||
// Queue texture creation via Arena's deferred system
|
||||
gfx::Arena::Get().QueueTextureCommand(
|
||||
gfx::Arena::TextureCommandType::CREATE, &sheets_[i]);
|
||||
gfx::Arena::TextureCommandType::CREATE, sheets_[i].get());
|
||||
}
|
||||
binary_gfx_loaded_ = true;
|
||||
} else {
|
||||
@@ -767,8 +763,8 @@ void ScreenEditor::LoadBinaryGfx() {
|
||||
|
||||
void ScreenEditor::DrawTitleScreenEditor() {
|
||||
// Initialize title screen on first draw
|
||||
if (!title_screen_loaded_ && rom()->is_loaded()) {
|
||||
status_ = title_screen_.Create(rom());
|
||||
if (!title_screen_loaded_ && rom()->is_loaded() && game_data()) {
|
||||
status_ = title_screen_.Create(rom(), game_data());
|
||||
if (!status_.ok()) {
|
||||
ImGui::TextColored(ImVec4(1, 0, 0, 1), "Error loading title screen: %s",
|
||||
status_.message().data());
|
||||
|
||||
Reference in New Issue
Block a user