Tile16 Editor updates (big commit)
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/gui/input.h"
|
#include "app/gui/input.h"
|
||||||
#include "app/gui/pipeline.h"
|
#include "app/gui/pipeline.h"
|
||||||
|
#include "app/gui/style.h"
|
||||||
|
#include "app/gui/widgets.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
#include "app/zelda3/overworld.h"
|
#include "app/zelda3/overworld.h"
|
||||||
|
|
||||||
@@ -36,17 +38,10 @@ using ImGui::TableNextRow;
|
|||||||
using ImGui::TableSetupColumn;
|
using ImGui::TableSetupColumn;
|
||||||
|
|
||||||
absl::Status Tile16Editor::Update() {
|
absl::Status Tile16Editor::Update() {
|
||||||
// Create a tab for Tile16 Editing
|
if (rom()->is_loaded() && !map_blockset_loaded_) {
|
||||||
static bool start_task = false;
|
RETURN_IF_ERROR(LoadTile8());
|
||||||
if (ImGui::Button("Test")) {
|
|
||||||
start_task = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_task && !map_blockset_loaded_) {
|
|
||||||
LoadTile8();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a tab bar for Tile16 Editing and Tile16 Transfer
|
|
||||||
if (BeginTabBar("Tile16 Editor Tabs")) {
|
if (BeginTabBar("Tile16 Editor Tabs")) {
|
||||||
if (BeginTabItem("Tile16 Editing")) {
|
if (BeginTabItem("Tile16 Editing")) {
|
||||||
if (BeginTable("#Tile16EditorTable", 2, TABLE_BORDERS_RESIZABLE,
|
if (BeginTable("#Tile16EditorTable", 2, TABLE_BORDERS_RESIZABLE,
|
||||||
@@ -69,7 +64,6 @@ absl::Status Tile16Editor::Update() {
|
|||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a tab for Tile16 Transfer
|
|
||||||
if (BeginTabItem("Tile16 Transfer")) {
|
if (BeginTabItem("Tile16 Transfer")) {
|
||||||
if (BeginTable("#Tile16TransferTable", 2, TABLE_BORDERS_RESIZABLE,
|
if (BeginTable("#Tile16TransferTable", 2, TABLE_BORDERS_RESIZABLE,
|
||||||
ImVec2(0, 0))) {
|
ImVec2(0, 0))) {
|
||||||
@@ -99,16 +93,26 @@ absl::Status Tile16Editor::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Tile16Editor::UpdateBlockset() {
|
absl::Status Tile16Editor::UpdateBlockset() {
|
||||||
gui::BitmapCanvasPipeline(blockset_canvas_, tile16_blockset_bmp_, 0x100,
|
gui::BeginPadding(2);
|
||||||
(8192 * 2), 0x20, map_blockset_loaded_, true, 55);
|
gui::BeginChildWithScrollbar(55);
|
||||||
|
blockset_canvas_.DrawBackground();
|
||||||
|
gui::EndPadding();
|
||||||
|
blockset_canvas_.DrawContextMenu();
|
||||||
|
blockset_canvas_.DrawTileSelector(32);
|
||||||
|
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 0, map_blockset_loaded_);
|
||||||
|
blockset_canvas_.DrawGrid();
|
||||||
|
blockset_canvas_.DrawOverlay();
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
if (!blockset_canvas_.points().empty()) {
|
if (!blockset_canvas_.points().empty()) {
|
||||||
uint16_t x = blockset_canvas_.points().front().x / 32;
|
uint16_t x = blockset_canvas_.points().front().x / 32;
|
||||||
uint16_t y = blockset_canvas_.points().front().y / 32;
|
uint16_t y = blockset_canvas_.points().front().y / 32;
|
||||||
|
|
||||||
notify_tile16.mutable_get() = x + (y * 8);
|
// notify_tile16.mutable_get() = x + (y * 8);
|
||||||
|
notify_tile16.mutable_get() = blockset_canvas_.GetTileIdFromMousePos();
|
||||||
notify_tile16.apply_changes();
|
notify_tile16.apply_changes();
|
||||||
if (notify_tile16.modified()) {
|
if (notify_tile16.modified()) {
|
||||||
|
current_tile16_ = notify_tile16.get();
|
||||||
current_tile16_bmp_ = tile16_individual_[notify_tile16];
|
current_tile16_bmp_ = tile16_individual_[notify_tile16];
|
||||||
current_tile16_bmp_.ApplyPalette(
|
current_tile16_bmp_.ApplyPalette(
|
||||||
rom()->palette_group("ow_main")[current_palette_]);
|
rom()->palette_group("ow_main")[current_palette_]);
|
||||||
@@ -119,33 +123,80 @@ absl::Status Tile16Editor::UpdateBlockset() {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status Tile16Editor::DrawToCurrentTile16(ImVec2 click_position) {
|
||||||
|
// Calculate the tile position relative to the current active map
|
||||||
|
constexpr int tile_size = 8; // Tile size is 16x16 pixels
|
||||||
|
|
||||||
|
// Calculate the tile index for x and y based on the click_position
|
||||||
|
int tile_index_x = (static_cast<int>(click_position.x) % 64) / tile_size;
|
||||||
|
int tile_index_y = (static_cast<int>(click_position.y) % 64) / tile_size;
|
||||||
|
|
||||||
|
// Calculate the pixel start position based on tile index and tile size
|
||||||
|
ImVec2 start_position;
|
||||||
|
start_position.x = tile_index_x * tile_size;
|
||||||
|
start_position.y = tile_index_y * tile_size;
|
||||||
|
|
||||||
|
// Update the bitmap's pixel data based on the start_position and tile_data
|
||||||
|
for (int y = 0; y < tile_size; ++y) {
|
||||||
|
for (int x = 0; x < tile_size; ++x) {
|
||||||
|
int pixel_index = (start_position.y + y) * current_tile16_bmp_.width() +
|
||||||
|
(start_position.x + x);
|
||||||
|
current_tile16_bmp_.WriteToPixel(
|
||||||
|
pixel_index,
|
||||||
|
current_gfx_individual_[current_tile8_].data()[y * tile_size + x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
absl::Status Tile16Editor::UpdateTile16Edit() {
|
absl::Status Tile16Editor::UpdateTile16Edit() {
|
||||||
if (ImGui::BeginChild("Tile8 Selector",
|
if (ImGui::BeginChild("Tile8 Selector",
|
||||||
ImVec2(ImGui::GetContentRegionAvail().x, 0x100),
|
ImVec2(ImGui::GetContentRegionAvail().x, 0x120),
|
||||||
true)) {
|
true)) {
|
||||||
tile8_source_canvas_.DrawBackground(
|
tile8_source_canvas_.DrawBackground(
|
||||||
ImVec2(core::kTilesheetWidth * 2, core::kTilesheetHeight * 0x10 * 2));
|
ImVec2(core::kTilesheetWidth * 2, core::kTilesheetHeight * 0x10 * 2));
|
||||||
tile8_source_canvas_.DrawContextMenu();
|
tile8_source_canvas_.DrawContextMenu();
|
||||||
tile8_source_canvas_.DrawTileSelector(16);
|
if (tile8_source_canvas_.DrawTileSelector(16)) {
|
||||||
|
current_gfx_individual_[current_tile8_].ApplyPaletteWithTransparent(
|
||||||
|
rom()->palette_group("ow_main")[0], current_palette_);
|
||||||
|
rom()->UpdateBitmap(¤t_gfx_individual_[current_tile8_]);
|
||||||
|
}
|
||||||
tile8_source_canvas_.DrawBitmap(current_gfx_bmp_, 0, 0, 2.0f);
|
tile8_source_canvas_.DrawBitmap(current_gfx_bmp_, 0, 0, 2.0f);
|
||||||
tile8_source_canvas_.DrawGrid(16.0f);
|
tile8_source_canvas_.DrawGrid(16.0f);
|
||||||
tile8_source_canvas_.DrawOverlay();
|
tile8_source_canvas_.DrawOverlay();
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
if (!tile8_source_canvas_.points().empty()) {
|
||||||
|
uint16_t x = tile8_source_canvas_.points().front().x / 16;
|
||||||
|
uint16_t y = tile8_source_canvas_.points().front().y / 16;
|
||||||
|
|
||||||
|
current_tile8_ = x + (y * 8);
|
||||||
|
current_gfx_individual_[current_tile8_].ApplyPaletteWithTransparent(
|
||||||
|
rom()->palette_group("ow_main")[0], current_palette_);
|
||||||
|
rom()->UpdateBitmap(¤t_gfx_individual_[current_tile8_]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Tile16 ID: %d", current_tile16_);
|
||||||
|
ImGui::Text("Tile8 ID: %d", current_tile8_);
|
||||||
|
|
||||||
|
// static gui::BitmapViewer bitmap_viewer_;
|
||||||
|
// bitmap_viewer_.Display(current_gfx_individual_, 4.0f);
|
||||||
|
MemoryEditor memory_editor;
|
||||||
|
memory_editor.DrawWindow("Tile8 Data", tile8_gfx_data_.data(),
|
||||||
|
tile8_gfx_data_.size(), 0x0000);
|
||||||
|
|
||||||
if (ImGui::BeginChild("Tile16 Editor Options",
|
if (ImGui::BeginChild("Tile16 Editor Options",
|
||||||
ImVec2(ImGui::GetContentRegionAvail().x, 0x50), true)) {
|
ImVec2(ImGui::GetContentRegionAvail().x, 0x50), true)) {
|
||||||
tile16_edit_canvas_.DrawBackground(ImVec2(0x40, 0x40));
|
tile16_edit_canvas_.DrawBackground(ImVec2(0x40, 0x40));
|
||||||
tile16_edit_canvas_.DrawContextMenu();
|
tile16_edit_canvas_.DrawContextMenu();
|
||||||
// if (current_tile8_bmp_.modified()) {
|
|
||||||
// rom()->UpdateBitmap(¤t_tile8_bmp_);
|
|
||||||
// current_tile8_bmp_.set_modified(false);
|
|
||||||
// }
|
|
||||||
tile16_edit_canvas_.DrawBitmap(current_tile16_bmp_, 0, 0, 4.0f);
|
tile16_edit_canvas_.DrawBitmap(current_tile16_bmp_, 0, 0, 4.0f);
|
||||||
tile16_edit_canvas_.HandleTileEdits(
|
if (!tile8_source_canvas_.points().empty()) {
|
||||||
tile8_source_canvas_, current_gfx_individual_, current_tile8_bmp_,
|
if (tile16_edit_canvas_.DrawTilePainter(
|
||||||
current_tile8_, 4.0f);
|
current_gfx_individual_[current_tile8_], 32, 4.0f)) {
|
||||||
|
DrawToCurrentTile16(tile16_edit_canvas_.drawn_tile_position());
|
||||||
|
rom()->UpdateBitmap(¤t_gfx_individual_[current_tile8_]);
|
||||||
|
}
|
||||||
|
}
|
||||||
tile16_edit_canvas_.DrawGrid(128.0f);
|
tile16_edit_canvas_.DrawGrid(128.0f);
|
||||||
tile16_edit_canvas_.DrawOverlay();
|
tile16_edit_canvas_.DrawOverlay();
|
||||||
}
|
}
|
||||||
@@ -161,11 +212,12 @@ void Tile16Editor::DrawTileEditControls() {
|
|||||||
gui::InputHexByte("Palette", ¬ify_palette.mutable_get());
|
gui::InputHexByte("Palette", ¬ify_palette.mutable_get());
|
||||||
notify_palette.apply_changes();
|
notify_palette.apply_changes();
|
||||||
if (notify_palette.modified()) {
|
if (notify_palette.modified()) {
|
||||||
current_gfx_bmp_.ApplyPalette(
|
current_gfx_bmp_.ApplyPaletteWithTransparent(
|
||||||
rom()->palette_group("ow_main")[notify_palette.get()]);
|
rom()->palette_group("ow_main")[0], notify_palette.get());
|
||||||
current_tile16_bmp_.ApplyPalette(
|
current_tile16_bmp_.ApplyPaletteWithTransparent(
|
||||||
rom()->palette_group("ow_main")[notify_palette.get()]);
|
rom()->palette_group("ow_main")[0], notify_palette.get());
|
||||||
rom()->UpdateBitmap(¤t_gfx_bmp_);
|
rom()->UpdateBitmap(¤t_gfx_bmp_);
|
||||||
|
rom()->UpdateBitmap(¤t_tile16_bmp_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Checkbox("X Flip", &x_flip);
|
ImGui::Checkbox("X Flip", &x_flip);
|
||||||
@@ -220,76 +272,64 @@ absl::Status Tile16Editor::InitBlockset(
|
|||||||
tile16_blockset_bmp_ = tile16_blockset_bmp;
|
tile16_blockset_bmp_ = tile16_blockset_bmp;
|
||||||
tile16_individual_ = tile16_individual;
|
tile16_individual_ = tile16_individual;
|
||||||
current_gfx_bmp_ = current_gfx_bmp;
|
current_gfx_bmp_ = current_gfx_bmp;
|
||||||
|
tile8_gfx_data_ = current_gfx_bmp_.vector();
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Tile16Editor::LoadTile8() {
|
absl::Status Tile16Editor::LoadTile8() {
|
||||||
current_gfx_individual_.reserve(128);
|
current_gfx_individual_.reserve(1024);
|
||||||
|
|
||||||
// Define the task function
|
// std::function<void(int)> taskFunc = [&](int index) {
|
||||||
std::function<void(int)> taskFunc = [&](int index) {
|
for (int index = 0; index < 1024; index++) {
|
||||||
auto current_gfx_data = current_gfx_bmp_.mutable_data();
|
std::vector<uint8_t> tile_data(0x40, 0x00);
|
||||||
std::vector<uint8_t> tile_data;
|
|
||||||
tile_data.reserve(0x40);
|
|
||||||
for (int i = 0; i < 0x40; i++) {
|
|
||||||
tile_data.emplace_back(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the pixel data for the current tile into the vector
|
// Copy the pixel data for the current tile into the vector
|
||||||
for (int ty = 0; ty < 8; ty++) {
|
for (int ty = 0; ty < 8; ty++) {
|
||||||
for (int tx = 0; tx < 8; tx++) {
|
for (int tx = 0; tx < 8; tx++) {
|
||||||
|
// Current Gfx Data is 16 sheets of 8x8 tiles ordered 16 wide by 4 tall
|
||||||
|
|
||||||
|
// Calculate the position in the tile data vector
|
||||||
int position = tx + (ty * 0x08);
|
int position = tx + (ty * 0x08);
|
||||||
uint8_t value =
|
|
||||||
current_gfx_data[(index % 16 * 32) + (index / 16 * 32 * 0x80) +
|
// Calculate the position in the current gfx data
|
||||||
(ty * 0x80) + tx];
|
int num_columns = current_gfx_bmp_.width() / 8;
|
||||||
|
int num_rows = current_gfx_bmp_.height() / 8;
|
||||||
|
int x = (index % num_columns) * 8 + tx;
|
||||||
|
int y = (index / num_columns) * 8 + ty;
|
||||||
|
int gfx_position = x + (y * 0x100);
|
||||||
|
|
||||||
|
// Get the pixel value from the current gfx data
|
||||||
|
uint8_t value = tile8_gfx_data_[gfx_position];
|
||||||
|
|
||||||
|
if (value & 0x80) {
|
||||||
|
value -= 0x88;
|
||||||
|
}
|
||||||
|
|
||||||
tile_data[position] = value;
|
tile_data[position] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_gfx_individual_.emplace_back();
|
current_gfx_individual_.emplace_back();
|
||||||
current_gfx_individual_[index].Create(0x08, 0x08, 0x80, tile_data);
|
current_gfx_individual_[index].Create(0x08, 0x08, 0x80, tile_data);
|
||||||
current_gfx_individual_[index].ApplyPalette(
|
current_gfx_individual_[index].ApplyPaletteWithTransparent(
|
||||||
rom()->palette_group("ow_main")[current_palette_]);
|
rom()->palette_group("ow_main")[0], current_palette_);
|
||||||
rom()->RenderBitmap(¤t_gfx_individual_[index]);
|
rom()->RenderBitmap(¤t_gfx_individual_[index]);
|
||||||
};
|
|
||||||
|
|
||||||
// Create the task manager
|
|
||||||
static bool started = false;
|
|
||||||
if (!started) {
|
|
||||||
task_manager_ = TaskManager<std::function<void(int)>>(127, 1);
|
|
||||||
started = true;
|
|
||||||
}
|
}
|
||||||
task_manager_.ExecuteTasks(taskFunc);
|
// };
|
||||||
|
|
||||||
if (task_manager_.IsTaskComplete()) {
|
// // Create the task manager
|
||||||
// All tasks are complete
|
// static bool started = false;
|
||||||
current_tile8_bmp_ = current_gfx_individual_[0];
|
// if (!started) {
|
||||||
map_blockset_loaded_ = true;
|
// task_manager_ = TaskManager<std::function<void(int)>>(1024, 60);
|
||||||
}
|
// started = true;
|
||||||
|
|
||||||
// auto current_gfx_data = current_gfx_bmp_.mutable_data();
|
|
||||||
// for (int i = 0; i < 128; i++) {
|
|
||||||
// std::vector<uint8_t> tile_data(0x40, 0x00);
|
|
||||||
|
|
||||||
// Copy the pixel data for the current tile into the vector
|
|
||||||
// for (int ty = 0; ty < 8; ty++) {
|
|
||||||
// for (int tx = 0; tx < 8; tx++) {
|
|
||||||
// int position = tx + (ty * 0x10);
|
|
||||||
// uint8_t value = current_gfx_data[(i % 16 * 32) + (i / 16 * 32 * 0x80)
|
|
||||||
// +
|
|
||||||
// (ty * 0x80) + tx];
|
|
||||||
// tile_data[position] = value;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// current_gfx_individual_data_.emplace_back(tile_data);
|
|
||||||
// current_gfx_individual_.emplace_back();
|
|
||||||
// current_gfx_individual_[i].Create(0x08, 0x08, 0x80, tile_data);
|
|
||||||
// current_gfx_individual_[i].ApplyPalette(
|
|
||||||
// rom()->palette_group("ow_main")[current_palette_]);
|
|
||||||
// rom()->RenderBitmap(¤t_gfx_individual_[i]);
|
|
||||||
// }
|
// }
|
||||||
|
// task_manager_.ExecuteTasks(taskFunc);
|
||||||
|
|
||||||
|
// if (task_manager_.IsTaskComplete()) {
|
||||||
|
// // All tasks are complete
|
||||||
|
map_blockset_loaded_ = true;
|
||||||
|
// }
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "app/core/editor.h"
|
#include "app/core/editor.h"
|
||||||
#include "app/gui/pipeline.h"
|
|
||||||
#include "app/editor/modules/palette_editor.h"
|
#include "app/editor/modules/palette_editor.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
#include "app/gfx/snes_palette.h"
|
#include "app/gfx/snes_palette.h"
|
||||||
#include "app/gfx/snes_tile.h"
|
#include "app/gfx/snes_tile.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
|
#include "app/gui/pipeline.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
#include "app/zelda3/overworld.h"
|
#include "app/zelda3/overworld.h"
|
||||||
|
|
||||||
@@ -27,6 +27,9 @@ class Tile16Editor : public SharedROM {
|
|||||||
absl::Status Update();
|
absl::Status Update();
|
||||||
|
|
||||||
absl::Status UpdateBlockset();
|
absl::Status UpdateBlockset();
|
||||||
|
|
||||||
|
absl::Status DrawToCurrentTile16(ImVec2 pos);
|
||||||
|
|
||||||
absl::Status UpdateTile16Edit();
|
absl::Status UpdateTile16Edit();
|
||||||
|
|
||||||
void DrawTileEditControls();
|
void DrawTileEditControls();
|
||||||
@@ -39,6 +42,14 @@ class Tile16Editor : public SharedROM {
|
|||||||
|
|
||||||
absl::Status LoadTile8();
|
absl::Status LoadTile8();
|
||||||
|
|
||||||
|
auto set_tile16(int id) {
|
||||||
|
current_tile16_ = id;
|
||||||
|
current_tile16_bmp_ = tile16_individual_[id];
|
||||||
|
current_tile16_bmp_.ApplyPalette(
|
||||||
|
rom()->palette_group("ow_main")[current_palette_]);
|
||||||
|
rom()->RenderBitmap(¤t_tile16_bmp_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool map_blockset_loaded_ = false;
|
bool map_blockset_loaded_ = false;
|
||||||
bool transfer_started_ = false;
|
bool transfer_started_ = false;
|
||||||
@@ -48,7 +59,7 @@ class Tile16Editor : public SharedROM {
|
|||||||
int current_tile8_ = 0;
|
int current_tile8_ = 0;
|
||||||
uint8_t current_palette_ = 0;
|
uint8_t current_palette_ = 0;
|
||||||
|
|
||||||
core::NotifyValue<uint8_t> notify_tile16;
|
core::NotifyValue<uint32_t> notify_tile16;
|
||||||
core::NotifyValue<uint8_t> notify_palette;
|
core::NotifyValue<uint8_t> notify_palette;
|
||||||
|
|
||||||
// Canvas dimensions
|
// Canvas dimensions
|
||||||
@@ -65,7 +76,8 @@ class Tile16Editor : public SharedROM {
|
|||||||
int tile_size;
|
int tile_size;
|
||||||
|
|
||||||
// Tile16 blockset for selecting the tile to edit
|
// Tile16 blockset for selecting the tile to edit
|
||||||
gui::Canvas blockset_canvas_;
|
gui::Canvas blockset_canvas_{ImVec2(0x100, 0x4000),
|
||||||
|
gui::CanvasGridSize::k32x32};
|
||||||
gfx::Bitmap tile16_blockset_bmp_;
|
gfx::Bitmap tile16_blockset_bmp_;
|
||||||
|
|
||||||
// Canvas for editing the selected tile
|
// Canvas for editing the selected tile
|
||||||
@@ -88,6 +100,8 @@ class Tile16Editor : public SharedROM {
|
|||||||
|
|
||||||
std::vector<uint8_t> current_tile16_data_;
|
std::vector<uint8_t> current_tile16_data_;
|
||||||
|
|
||||||
|
std::vector<uint8_t> tile8_gfx_data_;
|
||||||
|
|
||||||
PaletteEditor palette_editor_;
|
PaletteEditor palette_editor_;
|
||||||
|
|
||||||
gfx::SNESPalette palette_;
|
gfx::SNESPalette palette_;
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ void OverworldEditor::DrawUsageGrid() {
|
|||||||
|
|
||||||
absl::Status OverworldEditor::DrawToolset() {
|
absl::Status OverworldEditor::DrawToolset() {
|
||||||
static bool show_gfx_group = false;
|
static bool show_gfx_group = false;
|
||||||
static bool show_tile16 = false;
|
|
||||||
static bool show_properties = false;
|
static bool show_properties = false;
|
||||||
|
|
||||||
if (BeginTable("OWToolset", 20, kToolsetTableFlags, ImVec2(0, 0))) {
|
if (BeginTable("OWToolset", 20, kToolsetTableFlags, ImVec2(0, 0))) {
|
||||||
@@ -260,7 +259,7 @@ absl::Status OverworldEditor::DrawToolset() {
|
|||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
if (ImGui::Button(ICON_MD_GRID_VIEW)) {
|
if (ImGui::Button(ICON_MD_GRID_VIEW)) {
|
||||||
show_tile16 = !show_tile16;
|
show_tile16_editor_ = !show_tile16_editor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableNextColumn();
|
TableNextColumn();
|
||||||
@@ -288,9 +287,9 @@ absl::Status OverworldEditor::DrawToolset() {
|
|||||||
RETURN_IF_ERROR(DrawExperimentalModal())
|
RETURN_IF_ERROR(DrawExperimentalModal())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_tile16) {
|
if (show_tile16_editor_) {
|
||||||
// Create a table in ImGui for the Tile16 Editor
|
// Create a table in ImGui for the Tile16 Editor
|
||||||
ImGui::Begin("Tile16 Editor", &show_tile16);
|
ImGui::Begin("Tile16 Editor", &show_tile16_editor_);
|
||||||
RETURN_IF_ERROR(tile16_editor_.Update())
|
RETURN_IF_ERROR(tile16_editor_.Update())
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
@@ -537,7 +536,7 @@ void DrawExitEditorPopup(zelda3::OverworldExit &exit) {
|
|||||||
|
|
||||||
void OverworldEditor::DrawOverworldExits(ImVec2 canvas_p0, ImVec2 scrolling) {
|
void OverworldEditor::DrawOverworldExits(ImVec2 canvas_p0, ImVec2 scrolling) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto &each : overworld_.Exits()) {
|
for (auto &each : *overworld_.exits()) {
|
||||||
if (each.map_id_ < 0x40 + (current_world_ * 0x40) &&
|
if (each.map_id_ < 0x40 + (current_world_ * 0x40) &&
|
||||||
each.map_id_ >= (current_world_ * 0x40)) {
|
each.map_id_ >= (current_world_ * 0x40)) {
|
||||||
ow_map_canvas_.DrawRect(each.x_, each.y_, 16, 16,
|
ow_map_canvas_.DrawRect(each.x_, each.y_, 16, 16,
|
||||||
@@ -781,7 +780,15 @@ void OverworldEditor::DrawTile16Selector() {
|
|||||||
blockset_canvas_.DrawContextMenu();
|
blockset_canvas_.DrawContextMenu();
|
||||||
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, /*border_offset=*/2,
|
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, /*border_offset=*/2,
|
||||||
map_blockset_loaded_);
|
map_blockset_loaded_);
|
||||||
blockset_canvas_.DrawTileSelector(32.0f);
|
if (blockset_canvas_.DrawTileSelector(32.0f)) {
|
||||||
|
// Open the tile16 editor to the tile
|
||||||
|
auto tile_pos = blockset_canvas_.points().front();
|
||||||
|
int grid_x = static_cast<int>(tile_pos.x / 32);
|
||||||
|
int grid_y = static_cast<int>(tile_pos.y / 32);
|
||||||
|
int id = grid_x + grid_y * 8;
|
||||||
|
tile16_editor_.set_tile16(id);
|
||||||
|
show_tile16_editor_ = true;
|
||||||
|
}
|
||||||
blockset_canvas_.DrawGrid();
|
blockset_canvas_.DrawGrid();
|
||||||
blockset_canvas_.DrawOverlay();
|
blockset_canvas_.DrawOverlay();
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
@@ -865,7 +872,7 @@ absl::Status OverworldEditor::LoadGraphics() {
|
|||||||
current_gfx_bmp_, palette_);
|
current_gfx_bmp_, palette_);
|
||||||
|
|
||||||
// Create the tile16 blockset image
|
// Create the tile16 blockset image
|
||||||
gui::BuildAndRenderBitmapPipeline(0x80, 0x2000, 0x80,
|
gui::BuildAndRenderBitmapPipeline(0x80, 0x2000, 0x08,
|
||||||
overworld_.Tile16Blockset(), *rom(),
|
overworld_.Tile16Blockset(), *rom(),
|
||||||
tile16_blockset_bmp_, palette_);
|
tile16_blockset_bmp_, palette_);
|
||||||
map_blockset_loaded_ = true;
|
map_blockset_loaded_ = true;
|
||||||
|
|||||||
@@ -332,6 +332,27 @@ void Bitmap::ApplyPalette(const SNESPalette &palette) {
|
|||||||
SDL_LockSurface(surface_.get());
|
SDL_LockSurface(surface_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::ApplyPaletteFromPaletteGroup(const SNESPalette &palette,
|
||||||
|
int palette_id) {
|
||||||
|
auto start_index = palette_id * 8;
|
||||||
|
palette_ = palette.sub_palette(start_index, start_index + 8);
|
||||||
|
SDL_UnlockSurface(surface_.get());
|
||||||
|
for (int i = 0; i < palette_.size(); ++i) {
|
||||||
|
if (palette_.GetColor(i).IsTransparent()) {
|
||||||
|
surface_->format->palette->colors[i].r = 0;
|
||||||
|
surface_->format->palette->colors[i].g = 0;
|
||||||
|
surface_->format->palette->colors[i].b = 0;
|
||||||
|
surface_->format->palette->colors[i].a = 0;
|
||||||
|
} else {
|
||||||
|
surface_->format->palette->colors[i].r = palette_.GetColor(i).GetRGB().x;
|
||||||
|
surface_->format->palette->colors[i].g = palette_.GetColor(i).GetRGB().y;
|
||||||
|
surface_->format->palette->colors[i].b = palette_.GetColor(i).GetRGB().z;
|
||||||
|
surface_->format->palette->colors[i].a = palette_.GetColor(i).GetRGB().w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_LockSurface(surface_.get());
|
||||||
|
}
|
||||||
|
|
||||||
void Bitmap::ApplyPaletteWithTransparent(const SNESPalette &palette,
|
void Bitmap::ApplyPaletteWithTransparent(const SNESPalette &palette,
|
||||||
int index) {
|
int index) {
|
||||||
auto start_index = index * 7;
|
auto start_index = index * 7;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class Bitmap {
|
|||||||
void ApplyPalette(const SNESPalette &palette);
|
void ApplyPalette(const SNESPalette &palette);
|
||||||
void ApplyPaletteWithTransparent(const SNESPalette &palette, int index);
|
void ApplyPaletteWithTransparent(const SNESPalette &palette, int index);
|
||||||
void ApplyPalette(const std::vector<SDL_Color> &palette);
|
void ApplyPalette(const std::vector<SDL_Color> &palette);
|
||||||
|
void ApplyPaletteFromPaletteGroup(const SNESPalette &palette, int palette_id);
|
||||||
|
|
||||||
void WriteToPixel(int position, uchar value) {
|
void WriteToPixel(int position, uchar value) {
|
||||||
if (pixel_data_ == nullptr) {
|
if (pixel_data_ == nullptr) {
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ class SNESPalette {
|
|||||||
|
|
||||||
auto GetColor(int i) const {
|
auto GetColor(int i) const {
|
||||||
if (i > size_) {
|
if (i > size_) {
|
||||||
throw std::out_of_range("SNESPalette: Index out of bounds");
|
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||||
|
return colors[0];
|
||||||
}
|
}
|
||||||
return colors[i];
|
return colors[i];
|
||||||
}
|
}
|
||||||
@@ -167,7 +168,8 @@ class SNESPalette {
|
|||||||
|
|
||||||
SNESColor& operator[](int i) {
|
SNESColor& operator[](int i) {
|
||||||
if (i > size_) {
|
if (i > size_) {
|
||||||
throw std::out_of_range("SNESPalette: Index out of bounds");
|
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||||
|
return colors[0];
|
||||||
}
|
}
|
||||||
return colors[i];
|
return colors[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ void Canvas::DrawTileOnBitmap(int tile_size, gfx::Bitmap &bitmap,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::DrawTileSelector(int size) {
|
bool Canvas::DrawTileSelector(int size) {
|
||||||
const ImGuiIO &io = ImGui::GetIO();
|
const ImGuiIO &io = ImGui::GetIO();
|
||||||
const bool is_hovered = ImGui::IsItemHovered();
|
const bool is_hovered = ImGui::IsItemHovered();
|
||||||
const ImVec2 origin(canvas_p0_.x + scrolling_.x, canvas_p0_.y + scrolling_.y);
|
const ImVec2 origin(canvas_p0_.x + scrolling_.x, canvas_p0_.y + scrolling_.y);
|
||||||
@@ -303,50 +303,30 @@ void Canvas::DrawTileSelector(int size) {
|
|||||||
|
|
||||||
points_.push_back(painter_pos);
|
points_.push_back(painter_pos);
|
||||||
points_.push_back(ImVec2(painter_pos.x + size, painter_pos.y + size));
|
points_.push_back(ImVec2(painter_pos.x + size, painter_pos.y + size));
|
||||||
|
mouse_pos_in_canvas_ = painter_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_hovered && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::HandleTileEdits(Canvas &blockset_canvas,
|
bool Canvas::HandleTileEdits(Canvas &blockset_canvas,
|
||||||
std::vector<gfx::Bitmap> &source_blockset,
|
std::vector<gfx::Bitmap> &source_blockset,
|
||||||
gfx::Bitmap &destination, int ¤t_tile,
|
int ¤t_tile, float scale,
|
||||||
float scale, int tile_painter_size,
|
int tile_painter_size, int tiles_per_row) {
|
||||||
int tiles_per_row) {
|
|
||||||
if (!blockset_canvas.points().empty()) {
|
if (!blockset_canvas.points().empty()) {
|
||||||
uint16_t x = blockset_canvas.points().front().x / 32;
|
uint16_t x = blockset_canvas.points().front().x / 32;
|
||||||
uint16_t y = blockset_canvas.points().front().y / 32;
|
uint16_t y = blockset_canvas.points().front().y / 32;
|
||||||
current_tile = x + (y * tiles_per_row);
|
current_tile = x + (y * tiles_per_row);
|
||||||
if (DrawTilePainter(source_blockset[current_tile], tile_painter_size,
|
if (DrawTilePainter(source_blockset[current_tile], tile_painter_size,
|
||||||
scale)) {
|
scale)) {
|
||||||
RenderUpdatedBitmap(drawn_tile_position(),
|
return true;
|
||||||
source_blockset[current_tile].mutable_data(),
|
|
||||||
destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::RenderUpdatedBitmap(const ImVec2 &click_position,
|
|
||||||
const Bytes &tile_data,
|
|
||||||
gfx::Bitmap &destination) {
|
|
||||||
// Calculate the tile position relative to the current active map
|
|
||||||
constexpr int tile_size = 16; // Tile size is 16x16 pixels
|
|
||||||
|
|
||||||
// Calculate the tile index for x and y based on the click_position
|
|
||||||
int tile_index_x = (static_cast<int>(click_position.x) % 512) / tile_size;
|
|
||||||
int tile_index_y = (static_cast<int>(click_position.y) % 512) / tile_size;
|
|
||||||
|
|
||||||
// Calculate the pixel start position based on tile index and tile size
|
|
||||||
ImVec2 start_position;
|
|
||||||
start_position.x = tile_index_x * tile_size;
|
|
||||||
start_position.y = tile_index_y * tile_size;
|
|
||||||
|
|
||||||
// Update the bitmap's pixel data based on the start_position and tile_data
|
|
||||||
for (int y = 0; y < tile_size; ++y) {
|
|
||||||
for (int x = 0; x < tile_size; ++x) {
|
|
||||||
int pixel_index =
|
|
||||||
(start_position.y + y) * destination.width() + (start_position.x + x);
|
|
||||||
destination.WriteToPixel(pixel_index, tile_data[y * tile_size + x]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, bool ready) {
|
void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, bool ready) {
|
||||||
|
|||||||
@@ -75,16 +75,12 @@ class Canvas {
|
|||||||
|
|
||||||
// Dictates which tile is currently selected based on what the user clicks
|
// Dictates which tile is currently selected based on what the user clicks
|
||||||
// in the canvas window. Represented and split apart into a grid of tiles.
|
// in the canvas window. Represented and split apart into a grid of tiles.
|
||||||
void DrawTileSelector(int size);
|
bool DrawTileSelector(int size);
|
||||||
|
|
||||||
void HandleTileEdits(Canvas& blockset_canvas,
|
bool HandleTileEdits(Canvas& blockset_canvas,
|
||||||
std::vector<gfx::Bitmap>& source_blockset,
|
std::vector<gfx::Bitmap>& source_blockset,
|
||||||
gfx::Bitmap& destination, int& current_tile,
|
int& current_tile, float scale = 1.0f,
|
||||||
float scale = 1.0f, int tile_painter_size = 16,
|
int tile_painter_size = 16, int tiles_per_row = 8);
|
||||||
int tiles_per_row = 8);
|
|
||||||
|
|
||||||
void RenderUpdatedBitmap(const ImVec2& click_position, const Bytes& tile_data,
|
|
||||||
gfx::Bitmap& destination);
|
|
||||||
|
|
||||||
// Draws the contents of the Bitmap image to the Canvas
|
// Draws the contents of the Bitmap image to the Canvas
|
||||||
void DrawBitmap(const Bitmap& bitmap, int border_offset = 0,
|
void DrawBitmap(const Bitmap& bitmap, int border_offset = 0,
|
||||||
@@ -113,6 +109,7 @@ class Canvas {
|
|||||||
|
|
||||||
auto points() const { return points_; }
|
auto points() const { return points_; }
|
||||||
auto mutable_points() { return &points_; }
|
auto mutable_points() { return &points_; }
|
||||||
|
auto push_back(ImVec2 pos) { points_.push_back(pos); }
|
||||||
auto draw_list() const { return draw_list_; }
|
auto draw_list() const { return draw_list_; }
|
||||||
auto zero_point() const { return canvas_p0_; }
|
auto zero_point() const { return canvas_p0_; }
|
||||||
auto scrolling() const { return scrolling_; }
|
auto scrolling() const { return scrolling_; }
|
||||||
@@ -121,6 +118,9 @@ class Canvas {
|
|||||||
void set_global_scale(float scale) { global_scale_ = scale; }
|
void set_global_scale(float scale) { global_scale_ = scale; }
|
||||||
auto global_scale() const { return global_scale_; }
|
auto global_scale() const { return global_scale_; }
|
||||||
auto custom_labels_enabled() const { return enable_custom_labels_; }
|
auto custom_labels_enabled() const { return enable_custom_labels_; }
|
||||||
|
auto custom_step() const { return custom_step_; }
|
||||||
|
auto width() const { return canvas_sz_.x; }
|
||||||
|
auto height() const { return canvas_sz_.y; }
|
||||||
|
|
||||||
auto labels(int i) {
|
auto labels(int i) {
|
||||||
if (i >= labels_.size()) {
|
if (i >= labels_.size()) {
|
||||||
@@ -135,6 +135,18 @@ class Canvas {
|
|||||||
return &labels_[i];
|
return &labels_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetTileIdFromMousePos() {
|
||||||
|
int x = mouse_pos_in_canvas_.x;
|
||||||
|
int y = mouse_pos_in_canvas_.y;
|
||||||
|
int num_columns = width() / custom_step_;
|
||||||
|
int num_rows = height() / custom_step_;
|
||||||
|
int tile_id = (x / custom_step_) + (y / custom_step_) * num_columns;
|
||||||
|
if (tile_id >= num_columns * num_rows) {
|
||||||
|
tile_id = -1; // Invalid tile ID
|
||||||
|
}
|
||||||
|
return tile_id;
|
||||||
|
}
|
||||||
|
|
||||||
auto set_current_labels(int i) { current_labels_ = i; }
|
auto set_current_labels(int i) { current_labels_ = i; }
|
||||||
auto set_highlight_tile_id(int i) { highlight_tile_id = i; }
|
auto set_highlight_tile_id(int i) { highlight_tile_id = i; }
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
class DynamicLayout {
|
class DynamicLayout {};
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
TextEditor::LanguageDefinition GetAssemblyLanguageDef();
|
TextEditor::LanguageDefinition GetAssemblyLanguageDef();
|
||||||
|
|
||||||
@@ -29,7 +27,7 @@ class BitmapViewer {
|
|||||||
public:
|
public:
|
||||||
BitmapViewer() : current_bitmap_index_(0) {}
|
BitmapViewer() : current_bitmap_index_(0) {}
|
||||||
|
|
||||||
void Display(const std::vector<gfx::Bitmap>& bitmaps) {
|
void Display(const std::vector<gfx::Bitmap>& bitmaps, float scale = 1.0f) {
|
||||||
if (bitmaps.empty()) {
|
if (bitmaps.empty()) {
|
||||||
ImGui::Text("No bitmaps available.");
|
ImGui::Text("No bitmaps available.");
|
||||||
return;
|
return;
|
||||||
@@ -57,8 +55,9 @@ class BitmapViewer {
|
|||||||
// Assuming Bitmap has a function to get its texture ID, and width and
|
// Assuming Bitmap has a function to get its texture ID, and width and
|
||||||
// height.
|
// height.
|
||||||
ImTextureID tex_id = current_bitmap.texture();
|
ImTextureID tex_id = current_bitmap.texture();
|
||||||
ImVec2 size(current_bitmap.width(), current_bitmap.height());
|
ImVec2 size(current_bitmap.width() * scale,
|
||||||
ImGui::Image(tex_id, size);
|
current_bitmap.height() * scale);
|
||||||
|
// ImGui::Image(tex_id, size);
|
||||||
|
|
||||||
// Scroll if the image is larger than the display area.
|
// Scroll if the image is larger than the display area.
|
||||||
if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false,
|
if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false,
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
|||||||
auto overworld_maps() const { return overworld_maps_; }
|
auto overworld_maps() const { return overworld_maps_; }
|
||||||
auto overworld_map(int i) const { return &overworld_maps_[i]; }
|
auto overworld_map(int i) const { return &overworld_maps_[i]; }
|
||||||
auto mutable_overworld_map(int i) { return &overworld_maps_[i]; }
|
auto mutable_overworld_map(int i) { return &overworld_maps_[i]; }
|
||||||
|
auto exits() const { return &all_exits_; }
|
||||||
auto mutable_exits() { return &all_exits_; }
|
auto mutable_exits() { return &all_exits_; }
|
||||||
|
|
||||||
auto Sprites(int state) const { return all_sprites_[state]; }
|
auto Sprites(int state) const { return all_sprites_[state]; }
|
||||||
@@ -362,7 +363,6 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
|||||||
return overworld_maps_[current_map_].AreaGraphics();
|
return overworld_maps_[current_map_].AreaGraphics();
|
||||||
}
|
}
|
||||||
auto &Entrances() { return all_entrances_; }
|
auto &Entrances() { return all_entrances_; }
|
||||||
auto &Exits() { return all_exits_; }
|
|
||||||
auto AreaPalette() const {
|
auto AreaPalette() const {
|
||||||
return overworld_maps_[current_map_].AreaPalette();
|
return overworld_maps_[current_map_].AreaPalette();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user