Refactor OverworldEditor and Tile16Editor to use Tilemap instead of array of Bitmap
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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(¤t_tile16_bmp_);
|
||||
Renderer::GetInstance().UpdateBitmap(¤t_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(¤t_tile16_bmp_);
|
||||
Renderer::GetInstance().UpdateBitmap(¤t_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;
|
||||
@@ -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 ¤t_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_;
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "app/gui/style.h"
|
||||
#include "app/rom.h"
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_internal.h"
|
||||
#include "imgui_memory_editor.h"
|
||||
|
||||
namespace yaze {
|
||||
@@ -274,6 +273,55 @@ bool Canvas::DrawTilePainter(const Bitmap &bitmap, int size, float scale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Canvas::DrawTilemapPainter(gfx::Tilemap &tilemap, int current_tile) {
|
||||
const ImGuiIO &io = GetIO();
|
||||
const bool is_hovered = IsItemHovered();
|
||||
is_hovered_ = is_hovered;
|
||||
const ImVec2 origin(canvas_p0_.x + scrolling_.x, canvas_p0_.y + scrolling_.y);
|
||||
const ImVec2 mouse_pos(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
|
||||
const auto scaled_size = tilemap.tile_size.x * global_scale_;
|
||||
|
||||
if (!is_hovered) {
|
||||
points_.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!points_.empty()) {
|
||||
points_.clear();
|
||||
}
|
||||
|
||||
ImVec2 paint_pos = AlignPosToGrid(mouse_pos, scaled_size);
|
||||
mouse_pos_in_canvas_ = paint_pos;
|
||||
|
||||
points_.push_back(paint_pos);
|
||||
points_.push_back(
|
||||
ImVec2(paint_pos.x + scaled_size, paint_pos.y + scaled_size));
|
||||
|
||||
if (tilemap.tile_bitmaps.find(current_tile) == tilemap.tile_bitmaps.end()) {
|
||||
tilemap.tile_bitmaps[current_tile] = gfx::Bitmap(
|
||||
tilemap.tile_size.x, tilemap.tile_size.y, 8,
|
||||
gfx::GetTilemapData(tilemap, current_tile), tilemap.atlas.palette());
|
||||
auto bitmap_ptr = &tilemap.tile_bitmaps[current_tile];
|
||||
Renderer::GetInstance().RenderBitmap(bitmap_ptr);
|
||||
}
|
||||
|
||||
draw_list_->AddImage(
|
||||
(ImTextureID)(intptr_t)tilemap.tile_bitmaps[current_tile].texture(),
|
||||
ImVec2(origin.x + paint_pos.x, origin.y + paint_pos.y),
|
||||
ImVec2(origin.x + paint_pos.x + scaled_size,
|
||||
origin.y + paint_pos.y + scaled_size));
|
||||
|
||||
if (IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
drawn_tile_pos_ = paint_pos;
|
||||
return true;
|
||||
} else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
||||
drawn_tile_pos_ = paint_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Canvas::DrawSolidTilePainter(const ImVec4 &color, int tile_size) {
|
||||
const ImGuiIO &io = GetIO();
|
||||
const bool is_hovered = IsItemHovered();
|
||||
@@ -541,8 +589,7 @@ void Canvas::DrawOutlineWithColor(int x, int y, int w, int h, uint32_t color) {
|
||||
draw_list_->AddRect(origin, size, color);
|
||||
}
|
||||
|
||||
void Canvas::DrawBitmapGroup(std::vector<int> &group,
|
||||
std::array<gfx::Bitmap, 4096> &tile16_individual_,
|
||||
void Canvas::DrawBitmapGroup(std::vector<int> &group, gfx::Tilemap &tilemap,
|
||||
int tile_size, float scale) {
|
||||
if (selected_points_.size() != 2) {
|
||||
// points_ should contain exactly two points
|
||||
@@ -583,13 +630,16 @@ void Canvas::DrawBitmapGroup(std::vector<int> &group,
|
||||
int tile_id = group[i];
|
||||
|
||||
// Check if tile_id is within the range of tile16_individual_
|
||||
if (tile_id >= 0 && tile_id < tile16_individual_.size()) {
|
||||
auto tilemap_size = tilemap.atlas.width() * tilemap.atlas.height() /
|
||||
tilemap.map_size.x;
|
||||
if (tile_id >= 0 && tile_id < tilemap_size) {
|
||||
// Calculate the position of the tile within the rectangle
|
||||
int tile_pos_x = (x + start_tile_x) * tile_size * scale;
|
||||
int tile_pos_y = (y + start_tile_y) * tile_size * scale;
|
||||
|
||||
// Draw the tile bitmap at the calculated position
|
||||
DrawBitmap(tile16_individual_[tile_id], tile_pos_x, tile_pos_y, scale,
|
||||
gfx::RenderTile(tilemap, tile_id);
|
||||
DrawBitmap(tilemap.tile_bitmaps[tile_id], tile_pos_x, tile_pos_y, scale,
|
||||
150.0f);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef YAZE_GUI_CANVAS_H
|
||||
#define YAZE_GUI_CANVAS_H
|
||||
|
||||
#include "gfx/tilemap.h"
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include <cstdint>
|
||||
@@ -116,9 +117,11 @@ class Canvas : public SharedRom {
|
||||
void DrawBitmapTable(const BitmapTable &gfx_bin);
|
||||
|
||||
void DrawBitmapGroup(std::vector<int> &group,
|
||||
std::array<gfx::Bitmap, 4096> &tile16_individual_,
|
||||
gfx::Tilemap &tilemap,
|
||||
int tile_size, float scale = 1.0f);
|
||||
|
||||
bool DrawTilemapPainter(gfx::Tilemap &tilemap, int current_tile);
|
||||
|
||||
void DrawOutline(int x, int y, int w, int h);
|
||||
void DrawOutlineWithColor(int x, int y, int w, int h, ImVec4 color);
|
||||
void DrawOutlineWithColor(int x, int y, int w, int h, uint32_t color);
|
||||
|
||||
Reference in New Issue
Block a user