Refactor OverworldEditor and Tile16Editor to use Tilemap instead of array of Bitmap

This commit is contained in:
scawful
2025-04-29 00:26:16 -04:00
parent 3dc8a1f0ee
commit 718a14ca62
7 changed files with 92 additions and 91 deletions

View File

@@ -11,7 +11,7 @@ set(
app/editor/graphics/screen_editor.cc
app/editor/graphics/graphics_editor.cc
app/editor/graphics/palette_editor.cc
app/editor/graphics/tile16_editor.cc
app/editor/overworld/tile16_editor.cc
app/editor/graphics/gfx_group_editor.cc
app/editor/overworld/entity.cc
app/editor/system/settings_editor.cc

View File

@@ -14,6 +14,7 @@
#include "app/editor/overworld/entity.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/tilemap.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
@@ -427,8 +428,8 @@ void OverworldEditor::DrawOverworldEdits() {
}
// Render the updated map bitmap.
RenderUpdatedMapBitmap(mouse_position,
tile16_individual_[current_tile16_].vector());
RenderUpdatedMapBitmap(
mouse_position, gfx::GetTilemapData(tile16_blockset_, current_tile16_));
// Calculate the correct superX and superY values
int superY = current_map_ / 8;
@@ -484,8 +485,7 @@ void OverworldEditor::CheckForOverworldEdits() {
if (!blockset_canvas_.points().empty() &&
!ow_map_canvas_.select_rect_active()) {
// Left click is pressed
if (ow_map_canvas_.DrawTilePainter(tile16_individual_[current_tile16_],
kTile16Size)) {
if (ow_map_canvas_.DrawTilemapPainter(tile16_blockset_, current_tile16_)) {
DrawOverworldEdits();
}
}
@@ -563,7 +563,7 @@ void OverworldEditor::CheckForSelectRectangle() {
}
}
// Create a composite image of all the tile16s selected
ow_map_canvas_.DrawBitmapGroup(tile16_ids, tile16_individual_, 0x10);
ow_map_canvas_.DrawBitmapGroup(tile16_ids, tile16_blockset_, 0x10);
}
absl::Status OverworldEditor::CheckForCurrentMap() {
@@ -685,7 +685,7 @@ absl::Status OverworldEditor::DrawTile16Selector() {
gui::EndNoPadding();
{
blockset_canvas_.DrawContextMenu();
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, /*border_offset=*/2,
blockset_canvas_.DrawBitmap(tile16_blockset_.atlas, /*border_offset=*/2,
map_blockset_loaded_);
if (blockset_canvas_.DrawTileSelector(32.0f)) {
@@ -1050,27 +1050,11 @@ absl::Status OverworldEditor::LoadGraphics() {
// Copy the tile16 data into individual tiles.
auto tile16_blockset_data = overworld_.tile16_blockset_data();
util::logf("Loading overworld tile16 graphics.");
// Loop through the tiles and copy their pixel data into separate vectors
for (unsigned int i = 0; i < zelda3::kNumTile16Individual; i++) {
std::vector<uint8_t> tile16_data(kTile16Size * kTile16Size);
tile16_individual_[i].Create(kTile16Size, kTile16Size, 0x08, tile16_data);
// Copy the pixel data for the current tile into the vector
for (int ty = 0; ty < kTile16Size; ty++) {
for (int tx = 0; tx < kTile16Size; tx++) {
int position = tx + (ty * kTile16Size);
uint8_t value = tile16_blockset_data[(i % 8 * kTile16Size) +
(i / 8 * kTile16Size * 0x80) +
(ty * 0x80) + tx];
tile16_individual_[i].mutable_data()[position] = value;
}
}
tile16_individual_[i].SetPalette(palette_);
Renderer::GetInstance().RenderBitmap(&tile16_individual_[i]);
}
tile16_blockset_ =
gfx::CreateTilemap(tile16_blockset_data, 0x80, 0x2000, kTile16Size,
zelda3::kNumTile16Individual, palette_);
util::logf("Loading overworld maps.");
// Render the overworld maps loaded from the ROM.
@@ -1216,46 +1200,11 @@ absl::Status OverworldEditor::RefreshTile16Blockset() {
overworld_.set_current_map(current_map_);
palette_ = overworld_.current_area_palette();
// Create the tile16 blockset image
Renderer::GetInstance().UpdateBitmap(&tile16_blockset_bmp_);
tile16_blockset_bmp_.SetPalette(palette_);
// Copy the tile16 data into individual tiles.
const auto tile16_data = overworld_.tile16_blockset_data();
// Loop through the tiles and copy their pixel data into separate vectors
std::vector<std::future<absl::Status>> futures;
for (unsigned int i = 0; i < zelda3::kNumTile16Individual; i++) {
futures.push_back(std::async(
std::launch::async,
[&](int index) -> absl::Status {
std::vector<uint8_t> tile_data(16 * 16, 0x00);
for (int ty = 0; ty < 16; ty++) {
for (int tx = 0; tx < 16; tx++) {
int position = tx + (ty * 0x10);
uint8_t value =
tile16_data[(index % 8 * 16) + (index / 8 * 16 * 0x80) +
(ty * 0x80) + tx];
tile_data[position] = value;
}
}
tile16_individual_[index].set_data(tile_data);
tile16_individual_[index].SetPalette(palette_);
return absl::OkStatus();
},
i));
}
for (auto &future : futures) {
future.wait();
RETURN_IF_ERROR(future.get());
}
// Render the bitmaps of each tile.
for (unsigned int id = 0; id < zelda3::kNumTile16Individual; id++) {
Renderer::GetInstance().UpdateBitmap(&tile16_individual_[id]);
}
gfx::UpdateTilemap(tile16_blockset_, tile16_data);
tile16_blockset_.atlas.SetPalette(palette_);
return absl::OkStatus();
}
@@ -1496,9 +1445,6 @@ void OverworldEditor::DrawDebugWindow() {
absl::Status OverworldEditor::Clear() {
overworld_.Destroy();
current_graphics_set_.clear();
for (auto &bmp : tile16_individual_) {
bmp.Clear();
}
for (auto &bmp : maps_bmp_) {
bmp.Clear();
}
@@ -1514,9 +1460,6 @@ absl::Status OverworldEditor::Clear() {
void OverworldEditor::CleanupUnusedTextures(uint64_t current_time,
uint64_t timeout) {
for (auto &bmp : tile16_individual_) {
bmp.CleanupUnusedTexture(current_time, timeout);
}
for (auto &bmp : maps_bmp_) {
bmp.CleanupUnusedTexture(current_time, timeout);
}

View File

@@ -5,9 +5,10 @@
#include "app/editor/editor.h"
#include "app/editor/graphics/gfx_group_editor.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/editor/graphics/tile16_editor.h"
#include "app/editor/overworld/tile16_editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/tilemap.h"
#include "app/gui/canvas.h"
#include "app/gui/input.h"
#include "app/gui/zeml.h"
@@ -74,7 +75,9 @@ constexpr absl::string_view kOWMapTable = "#MapSettingsTable";
*/
class OverworldEditor : public Editor, public gfx::GfxContext {
public:
explicit OverworldEditor(Rom* rom) : rom_(rom) { type_ = EditorType::kOverworld; }
explicit OverworldEditor(Rom* rom) : rom_(rom) {
type_ = EditorType::kOverworld;
}
void Initialize() override;
absl::Status Load() override;
@@ -89,7 +92,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
absl::Status Clear() override;
void CleanupUnusedTextures(uint64_t current_time, uint64_t timeout) override;
int jump_to_tab() { return jump_to_tab_; }
int jump_to_tab_ = -1;
@@ -213,14 +216,14 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
bool is_dragging_entity_ = false;
std::vector<uint8_t> selected_tile_data_;
std::array<gfx::Bitmap, zelda3::kNumTile16Individual> tile16_individual_;
gfx::Tilemap tile16_blockset_;
std::vector<std::vector<uint8_t>> tile8_individual_data_;
std::vector<gfx::Bitmap> tile8_individual_;
Rom* rom_;
Tile16Editor tile16_editor_{&tile16_individual_};
Tile16Editor tile16_editor_{&tile16_blockset_};
GfxGroupEditor gfx_group_editor_;
PaletteEditor palette_editor_;

View File

@@ -187,10 +187,11 @@ absl::Status Tile16Editor::UpdateBlockset() {
if (notify_tile16.modified()) {
current_tile16_ = notify_tile16.get();
current_tile16_bmp_ = (*tile16_individual_)[notify_tile16];
gfx::RenderTile(*tile16_blockset_, current_tile16_);
current_tile16_bmp_ = tile16_blockset_->tile_bitmaps[notify_tile16];
auto ow_main_pal_group = rom()->palette_group().overworld_main;
current_tile16_bmp_.SetPalette(ow_main_pal_group[current_palette_]);
Renderer::GetInstance().RenderBitmap(&current_tile16_bmp_);
Renderer::GetInstance().UpdateBitmap(&current_tile16_bmp_);
}
}
@@ -487,10 +488,11 @@ absl::Status Tile16Editor::LoadTile8() {
absl::Status Tile16Editor::SetCurrentTile(int id) {
current_tile16_ = id;
current_tile16_bmp_ = (*tile16_individual_)[id];
gfx::RenderTile(*tile16_blockset_, current_tile16_);
current_tile16_bmp_ = tile16_blockset_->tile_bitmaps[current_tile16_];
auto ow_main_pal_group = rom()->palette_group().overworld_main;
current_tile16_bmp_.SetPalette(ow_main_pal_group[current_palette_]);
Renderer::GetInstance().RenderBitmap(&current_tile16_bmp_);
Renderer::GetInstance().UpdateBitmap(&current_tile16_bmp_);
return absl::OkStatus();
}
@@ -561,8 +563,11 @@ absl::Status Tile16Editor::CopyTile16ToClipboard(int tile_id) {
}
// Create a copy of the tile16 bitmap
clipboard_tile16_.Create(16, 16, 8, (*tile16_individual_)[tile_id].vector());
clipboard_tile16_.SetPalette((*tile16_individual_)[tile_id].palette());
gfx::RenderTile(*tile16_blockset_, tile_id);
clipboard_tile16_.Create(16, 16, 8,
tile16_blockset_->tile_bitmaps[tile_id].vector());
clipboard_tile16_.SetPalette(
tile16_blockset_->tile_bitmaps[tile_id].palette());
core::Renderer::GetInstance().RenderBitmap(&clipboard_tile16_);
clipboard_has_data_ = true;

View File

@@ -24,9 +24,7 @@ namespace editor {
*/
class Tile16Editor : public gfx::GfxContext, public SharedRom {
public:
Tile16Editor(
std::array<gfx::Bitmap, zelda3::kNumTile16Individual> *tile16_individual)
: tile16_individual_(tile16_individual) {}
Tile16Editor(gfx::Tilemap *tile16_blockset) : tile16_blockset_(tile16_blockset) {}
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp,
const gfx::Bitmap &current_gfx_bmp,
std::array<uint8_t, 0x200> &all_tiles_types);
@@ -102,8 +100,7 @@ class Tile16Editor : public gfx::GfxContext, public SharedRom {
gui::Table tile_edit_table_{"##TileEditTable", 3, ImGuiTableFlags_Borders};
std::array<gfx::Bitmap, zelda3::kNumTile16Individual> *tile16_individual_ =
nullptr;
gfx::Tilemap *tile16_blockset_ = nullptr;
std::vector<gfx::Bitmap> current_gfx_individual_;
PaletteEditor palette_editor_;