backend-infra-engineer: Pre-0.2.2 2024 Q4 snapshot

This commit is contained in:
scawful
2024-11-28 11:50:47 -05:00
parent 75bf38fa71
commit 18b7fb9abf
238 changed files with 22057 additions and 8538 deletions

View File

@@ -1,22 +1,14 @@
#include "gfx_group_editor.h"
#include "imgui/imgui.h"
#include <cmath>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/editor/utils/editor.h"
#include "absl/strings/str_cat.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/canvas.h"
#include "app/gui/color.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "app/rom.h"
#include "app/zelda3/overworld/overworld.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
@@ -27,7 +19,6 @@ using ImGui::BeginGroup;
using ImGui::BeginTabBar;
using ImGui::BeginTabItem;
using ImGui::BeginTable;
using ImGui::ColorButton;
using ImGui::EndChild;
using ImGui::EndGroup;
using ImGui::EndTabBar;
@@ -39,7 +30,6 @@ using ImGui::IsItemClicked;
using ImGui::PopID;
using ImGui::PushID;
using ImGui::SameLine;
using ImGui::Selectable;
using ImGui::Separator;
using ImGui::SetNextItemWidth;
using ImGui::TableHeadersRow;
@@ -123,7 +113,7 @@ void GfxGroupEditor::DrawBlocksetViewer(bool sheet_only) {
BeginGroup();
for (int i = 0; i < 8; i++) {
int sheet_id = rom()->main_blockset_ids[selected_blockset_][i];
auto sheet = rom()->bitmap_manager()[sheet_id];
auto sheet = rom()->gfx_sheets().at(sheet_id);
gui::BitmapCanvasPipeline(blockset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 22);
}
@@ -176,7 +166,7 @@ void GfxGroupEditor::DrawRoomsetViewer() {
BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->room_blockset_ids[selected_roomset_][i];
auto sheet = rom()->bitmap_manager()[sheet_id];
auto sheet = rom()->gfx_sheets().at(sheet_id);
gui::BitmapCanvasPipeline(roomset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 23);
}
@@ -214,7 +204,7 @@ void GfxGroupEditor::DrawSpritesetViewer(bool sheet_only) {
BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->spriteset_ids[selected_spriteset_][i];
auto sheet = rom()->bitmap_manager()[115 + sheet_id];
auto sheet = rom()->gfx_sheets().at(115 + sheet_id);
gui::BitmapCanvasPipeline(spriteset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 24);
}
@@ -229,7 +219,7 @@ void DrawPaletteFromPaletteGroup(gfx::SnesPalette &palette) {
if (palette.empty()) {
return;
}
for (int n = 0; n < palette.size(); n++) {
for (size_t n = 0; n < palette.size(); n++) {
PushID(n);
if ((n % 8) != 0) SameLine(0.0f, GetStyle().ItemSpacing.y);

View File

@@ -1,21 +1,10 @@
#ifndef YAZE_APP_EDITOR_GFX_GROUP_EDITOR_H
#define YAZE_APP_EDITOR_GFX_GROUP_EDITOR_H
#include "imgui/imgui.h"
#include <cmath>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/editor/utils/editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/style.h"
#include "app/rom.h"
#include "app/zelda3/overworld/overworld.h"
namespace yaze {
namespace app {
@@ -40,13 +29,7 @@ class GfxGroupEditor : public SharedRom {
selected_spriteset_ = spriteset;
}
void InitBlockset(gfx::Bitmap* tile16_blockset) {
tile16_blockset_bmp_ = tile16_blockset;
}
private:
int preview_palette_id_ = 0;
int last_sheet_id_ = 0;
uint8_t selected_blockset_ = 0;
uint8_t selected_roomset_ = 0;
uint8_t selected_spriteset_ = 0;
@@ -57,17 +40,9 @@ class GfxGroupEditor : public SharedRom {
gui::Canvas spriteset_canvas_;
gfx::SnesPalette palette_;
gfx::PaletteGroup palette_group_;
gfx::Bitmap* tile16_blockset_bmp_;
std::vector<Bytes> tile16_individual_data_;
std::vector<gfx::Bitmap> tile16_individual_;
gui::BitmapViewer gfx_group_viewer_;
zelda3::overworld::Overworld overworld_;
};
} // namespace editor
} // namespace app
} // namespace yaze
#endif // YAZE_APP_EDITOR_GFX_GROUP_EDITOR_H
#endif // YAZE_APP_EDITOR_GFX_GROUP_EDITOR_H

View File

@@ -1,30 +1,33 @@
#include "graphics_editor.h"
#include "ImGuiFileDialog/ImGuiFileDialog.h"
#include "imgui/imgui.h"
#include "imgui/misc/cpp/imgui_stdlib.h"
#include "imgui_memory_editor.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/core/platform/clipboard.h"
#include "app/core/platform/renderer.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/compression.h"
#include "app/gfx/scad_format.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/asset_browser.h"
#include "app/gui/canvas.h"
#include "app/gui/color.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "app/gui/modules/asset_browser.h"
#include "app/gui/style.h"
#include "app/rom.h"
#include "imgui/imgui.h"
#include "imgui/misc/cpp/imgui_stdlib.h"
#include "imgui_memory_editor.h"
namespace yaze {
namespace app {
namespace editor {
using core::Renderer;
using gfx::kPaletteGroupAddressesKeys;
using ImGui::Button;
using ImGui::InputInt;
@@ -32,70 +35,56 @@ using ImGui::InputText;
using ImGui::SameLine;
using ImGui::TableNextColumn;
static constexpr absl::string_view kGfxToolsetColumnNames[] = {
"#memoryEditor",
"##separator_gfx1",
};
constexpr ImGuiTableFlags kGfxEditTableFlags =
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable |
ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
ImGuiTableFlags_SizingFixedFit;
constexpr ImGuiTabBarFlags kGfxEditTabBarFlags =
ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable |
ImGuiTabBarFlags_FittingPolicyResizeDown |
ImGuiTabBarFlags_TabListPopupButton;
constexpr ImGuiTableFlags kGfxEditFlags = ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Resizable |
ImGuiTableFlags_SizingStretchSame;
absl::Status GraphicsEditor::Update() {
TAB_BAR("##TabBar")
status_ = UpdateGfxEdit();
TAB_ITEM("Sheet Browser")
if (asset_browser_.Initialized == false) {
asset_browser_.Initialize(rom()->mutable_bitmap_manager());
if (ImGui::BeginTabBar("##TabBar")) {
status_ = UpdateGfxEdit();
TAB_ITEM("Sheet Browser")
if (asset_browser_.Initialized == false) {
asset_browser_.Initialize(rom()->gfx_sheets());
}
asset_browser_.Draw(rom()->gfx_sheets());
END_TAB_ITEM()
status_ = UpdateScadView();
status_ = UpdateLinkGfxView();
ImGui::EndTabBar();
}
asset_browser_.Draw(rom()->mutable_bitmap_manager());
END_TAB_ITEM()
status_ = UpdateScadView();
status_ = UpdateLinkGfxView();
END_TAB_BAR()
CLEAR_AND_RETURN_STATUS(status_)
return absl::OkStatus();
}
absl::Status GraphicsEditor::UpdateGfxEdit() {
TAB_ITEM("Sheet Editor")
if (ImGui::BeginTabItem("Sheet Editor")) {
if (ImGui::BeginTable("##GfxEditTable", 3, kGfxEditTableFlags,
ImVec2(0, 0))) {
for (const auto& name :
{"Tilesheets", "Current Graphics", "Palette Controls"})
ImGui::TableSetupColumn(name);
if (ImGui::BeginTable("##GfxEditTable", 3, kGfxEditTableFlags,
ImVec2(0, 0))) {
for (const auto& name :
{"Tilesheets", "Current Graphics", "Palette Controls"})
ImGui::TableSetupColumn(name);
ImGui::TableHeadersRow();
ImGui::TableHeadersRow();
NEXT_COLUMN();
status_ = UpdateGfxSheetList();
NEXT_COLUMN();
status_ = UpdateGfxSheetList();
NEXT_COLUMN();
if (rom()->is_loaded()) {
DrawGfxEditToolset();
status_ = UpdateGfxTabView();
}
NEXT_COLUMN();
if (rom()->is_loaded()) {
DrawGfxEditToolset();
status_ = UpdateGfxTabView();
NEXT_COLUMN();
if (rom()->is_loaded()) {
status_ = UpdatePaletteColumn();
}
}
ImGui::EndTable();
NEXT_COLUMN();
if (rom()->is_loaded()) {
status_ = UpdatePaletteColumn();
}
ImGui::EndTabItem();
}
ImGui::EndTable();
END_TAB_ITEM()
return absl::OkStatus();
}
@@ -127,8 +116,8 @@ void GraphicsEditor::DrawGfxEditToolset() {
TableNextColumn();
if (Button(ICON_MD_CONTENT_COPY)) {
std::vector<uint8_t> png_data =
rom()->bitmap_manager().shared_bitmap(current_sheet_).GetPngData();
CopyImageToClipboard(png_data);
rom()->gfx_sheets().at(current_sheet_).GetPngData();
core::CopyImageToClipboard(png_data);
}
HOVER_HINT("Copy to Clipboard");
@@ -136,14 +125,14 @@ void GraphicsEditor::DrawGfxEditToolset() {
if (Button(ICON_MD_CONTENT_PASTE)) {
std::vector<uint8_t> png_data;
int width, height;
GetImageFromClipboard(png_data, width, height);
core::GetImageFromClipboard(png_data, width, height);
if (png_data.size() > 0) {
rom()
->mutable_bitmap_manager()
->mutable_bitmap(current_sheet_)
->Create(width, height, 8, png_data);
rom()->UpdateBitmap(
rom()->mutable_bitmap_manager()->mutable_bitmap(current_sheet_));
->mutable_gfx_sheets()
->at(current_sheet_)
.Create(width, height, 8, png_data);
Renderer::GetInstance().UpdateBitmap(
&rom()->mutable_gfx_sheets()->at(current_sheet_));
}
}
HOVER_HINT("Paste from Clipboard");
@@ -163,7 +152,7 @@ void GraphicsEditor::DrawGfxEditToolset() {
}
TableNextColumn();
auto bitmap = rom()->bitmap_manager()[current_sheet_];
auto bitmap = rom()->gfx_sheets()[current_sheet_];
auto palette = bitmap.palette();
for (int i = 0; i < 8; i++) {
ImGui::SameLine();
@@ -192,28 +181,28 @@ absl::Status GraphicsEditor::UpdateGfxSheetList() {
static ImGuiSelectionBasicStorage selection;
ImGuiMultiSelectFlags flags =
ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(
flags, selection.Size, rom()->bitmap_manager().size());
ImGuiMultiSelectIO* ms_io =
ImGui::BeginMultiSelect(flags, selection.Size, kNumGfxSheets);
selection.ApplyRequests(ms_io);
ImGuiListClipper clipper;
clipper.Begin(rom()->bitmap_manager().size());
clipper.Begin(kNumGfxSheets);
if (ms_io->RangeSrcItem != -1)
clipper.IncludeItemByIndex(
(int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
for (auto& [key, value] : rom()->bitmap_manager()) {
int key = 0;
for (auto& value : rom()->gfx_sheets()) {
ImGui::BeginChild(absl::StrFormat("##GfxSheet%02X", key).c_str(),
ImVec2(0x100 + 1, 0x40 + 1), true,
ImGuiWindowFlags_NoDecoration);
ImGui::PopStyleVar();
gui::Canvas graphics_bin_canvas_;
graphics_bin_canvas_.DrawBackground(ImVec2(0x100 + 1, 0x40 + 1));
graphics_bin_canvas_.DrawContextMenu();
if (value.is_active()) {
auto texture = value.texture();
graphics_bin_canvas_.draw_list()->AddImage(
(void*)texture,
(ImTextureID)(intptr_t)texture,
ImVec2(graphics_bin_canvas_.zero_point().x + 2,
graphics_bin_canvas_.zero_point().y + 2),
ImVec2(graphics_bin_canvas_.zero_point().x +
@@ -240,6 +229,8 @@ absl::Status GraphicsEditor::UpdateGfxSheetList() {
graphics_bin_canvas_.draw_list()->AddText(
text_pos, IM_COL32(125, 255, 125, 255),
absl::StrFormat("%02X", key).c_str());
key++;
}
graphics_bin_canvas_.DrawGrid(16.0f);
graphics_bin_canvas_.DrawOverlay();
@@ -256,6 +247,10 @@ absl::Status GraphicsEditor::UpdateGfxSheetList() {
absl::Status GraphicsEditor::UpdateGfxTabView() {
static int next_tab_id = 0;
constexpr ImGuiTabBarFlags kGfxEditTabBarFlags =
ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable |
ImGuiTabBarFlags_FittingPolicyResizeDown |
ImGuiTabBarFlags_TabListPopupButton;
if (ImGui::BeginTabBar("##GfxEditTabBar", kGfxEditTabBarFlags)) {
if (ImGui::TabItemButton(ICON_MD_ADD, ImGuiTabItemFlags_Trailing |
@@ -285,18 +280,17 @@ absl::Status GraphicsEditor::UpdateGfxTabView() {
ImGuiWindowFlags_AlwaysVerticalScrollbar |
ImGuiWindowFlags_AlwaysHorizontalScrollbar);
gfx::Bitmap& current_bitmap =
*rom()->mutable_bitmap_manager()->mutable_bitmap(sheet_id);
gfx::Bitmap& current_bitmap = rom()->mutable_gfx_sheets()->at(sheet_id);
auto draw_tile_event = [&]() {
current_sheet_canvas_.DrawTileOnBitmap(tile_size_, &current_bitmap,
current_color_);
rom()->UpdateBitmap(&current_bitmap, true);
Renderer::GetInstance().UpdateBitmap(&current_bitmap);
};
current_sheet_canvas_.UpdateColorPainter(
rom()->bitmap_manager()[sheet_id], current_color_, draw_tile_event,
tile_size_, current_scale_);
rom()->mutable_gfx_sheets()->at(sheet_id), current_color_,
draw_tile_event, tile_size_, current_scale_);
ImGui::EndChild();
ImGui::EndTabItem();
@@ -328,7 +322,7 @@ absl::Status GraphicsEditor::UpdateGfxTabView() {
current_sheet_ = id;
// ImVec2(0x100, 0x40),
current_sheet_canvas_.UpdateColorPainter(
rom()->bitmap_manager()[id], current_color_,
rom()->mutable_gfx_sheets()->at(id), current_color_,
[&]() {
},
@@ -365,11 +359,12 @@ absl::Status GraphicsEditor::UpdatePaletteColumn() {
if (refresh_graphics_ && !open_sheets_.empty()) {
RETURN_IF_ERROR(
rom()->bitmap_manager()[current_sheet_].ApplyPaletteWithTransparent(
palette, edit_palette_sub_index_));
rom()->UpdateBitmap(
rom()->mutable_bitmap_manager()->mutable_bitmap(current_sheet_),
true);
rom()
->mutable_gfx_sheets()
->data()[current_sheet_]
.ApplyPaletteWithTransparent(palette, edit_palette_sub_index_));
Renderer::GetInstance().UpdateBitmap(
&rom()->mutable_gfx_sheets()->data()[current_sheet_]);
refresh_graphics_ = false;
}
}
@@ -391,9 +386,9 @@ absl::Status GraphicsEditor::UpdateLinkGfxView() {
link_canvas_.DrawGrid(16.0f);
int i = 0;
for (auto [key, link_sheet] : *rom()->mutable_link_graphics()) {
for (auto link_sheet : *rom()->mutable_link_graphics()) {
int x_offset = 0;
int y_offset = core::kTilesheetHeight * i * 4;
int y_offset = gfx::kTilesheetHeight * i * 4;
link_canvas_.DrawContextMenu(&link_sheet);
link_canvas_.DrawBitmap(link_sheet, x_offset, y_offset, 4);
i++;
@@ -435,6 +430,10 @@ absl::Status GraphicsEditor::UpdateScadView() {
ImGui::End();
}
constexpr ImGuiTableFlags kGfxEditFlags = ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Resizable |
ImGuiTableFlags_SizingStretchSame;
BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
SETUP_COLUMN("File Import (BIN, CGX, ROM)")
SETUP_COLUMN("Palette (COL)")
@@ -458,17 +457,18 @@ absl::Status GraphicsEditor::UpdateScadView() {
NEXT_COLUMN()
if (super_donkey_) {
if (refresh_graphics_) {
for (int i = 0; i < graphics_bin_.size(); i++) {
status_ = graphics_bin_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);
rom()->UpdateBitmap(&graphics_bin_[i]);
}
refresh_graphics_ = false;
}
// TODO: Implement the Super Donkey 1 graphics decompression
// if (refresh_graphics_) {
// for (int i = 0; i < kNumGfxSheets; i++) {
// status_ = graphics_bin_[i].ApplyPalette(
// col_file_palette_group_[current_palette_index_]);
// Renderer::GetInstance().UpdateBitmap(&graphics_bin_[i]);
// }
// refresh_graphics_ = false;
// }
// Load the full graphics space from `super_donkey_1.bin`
gui::GraphicsBinCanvasPipeline(0x100, 0x40, 0x20, num_sheets_to_load_, 3,
super_donkey_, graphics_bin_);
// gui::GraphicsBinCanvasPipeline(0x100, 0x40, 0x20, num_sheets_to_load_, 3,
// super_donkey_, graphics_bin_);
} else if (cgx_loaded_ && col_file_) {
// Load the CGX graphics
gui::BitmapCanvasPipeline(import_canvas_, cgx_bitmap_, 0x100, 16384, 0x20,
@@ -485,6 +485,11 @@ absl::Status GraphicsEditor::UpdateScadView() {
}
absl::Status GraphicsEditor::DrawToolset() {
static constexpr absl::string_view kGfxToolsetColumnNames[] = {
"#memoryEditor",
"##separator_gfx1",
};
if (ImGui::BeginTable("GraphicsToolset", 2, ImGuiTableFlags_SizingFixedFit,
ImVec2(0, 0))) {
for (const auto& name : kGfxToolsetColumnNames)
@@ -535,7 +540,7 @@ absl::Status GraphicsEditor::DrawCgxImport() {
cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_);
if (col_file_) {
cgx_bitmap_.ApplyPalette(decoded_col_);
rom()->RenderBitmap(&cgx_bitmap_);
Renderer::GetInstance().RenderBitmap(&cgx_bitmap_);
}
}
@@ -570,7 +575,7 @@ absl::Status GraphicsEditor::DrawScrImport() {
scr_bitmap_.Create(0x100, 0x100, 8, decoded_scr_data_);
if (scr_loaded_) {
scr_bitmap_.ApplyPalette(decoded_col_);
rom()->RenderBitmap(&scr_bitmap_);
Renderer::GetInstance().RenderBitmap(&scr_bitmap_);
}
}
@@ -594,7 +599,7 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
/*z3_load=*/false);
auto col_data_ = gfx::GetColFileData(temp_rom_.data());
if (col_file_palette_group_.size() != 0) {
col_file_palette_group_.Clear();
col_file_palette_group_.clear();
}
auto col_file_palette_group_status =
gfx::CreatePaletteGroupFromColFile(col_data_);
@@ -707,7 +712,8 @@ absl::Status GraphicsEditor::DrawClipboardImport() {
if (Button("Paste From Clipboard")) {
const char* text = ImGui::GetClipboardText();
if (text) {
const auto clipboard_data = Bytes(text, text + strlen(text));
const auto clipboard_data =
std::vector<uint8_t>(text, text + strlen(text));
ImGui::MemFree((void*)text);
status_ = temp_rom_.LoadFromBytes(clipboard_data);
is_open_ = true;
@@ -762,7 +768,7 @@ absl::Status GraphicsEditor::DecompressImportData(int size) {
temp_rom_.data(), current_offset_, size))
auto converted_sheet = gfx::SnesTo8bppSheet(import_data_, 3);
bin_bitmap_.Create(core::kTilesheetWidth, 0x2000, core::kTilesheetDepth,
bin_bitmap_.Create(gfx::kTilesheetWidth, 0x2000, gfx::kTilesheetDepth,
converted_sheet);
if (rom()->is_loaded()) {
@@ -775,7 +781,7 @@ absl::Status GraphicsEditor::DecompressImportData(int size) {
}
}
rom()->RenderBitmap(&bin_bitmap_);
Renderer::GetInstance().RenderBitmap(&bin_bitmap_);
gfx_loaded_ = true;
return absl::OkStatus();
@@ -790,11 +796,10 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
auto decompressed_data,
gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000))
auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
graphics_bin_[i] =
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
core::kTilesheetDepth, converted_sheet);
gfx_sheets_[i] = gfx::Bitmap(gfx::kTilesheetWidth, gfx::kTilesheetHeight,
gfx::kTilesheetDepth, converted_sheet);
if (col_file_) {
status_ = graphics_bin_[i].ApplyPalette(
status_ = gfx_sheets_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);
} else {
// ROM palette
@@ -802,10 +807,10 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
auto palette_group = rom()->palette_group().get_group(
kPaletteGroupAddressesKeys[current_palette_]);
z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_);
status_ = graphics_bin_[i].ApplyPalette(z3_rom_palette_);
status_ = gfx_sheets_[i].ApplyPalette(z3_rom_palette_);
}
rom()->RenderBitmap(&graphics_bin_[i]);
Renderer::GetInstance().RenderBitmap(&gfx_sheets_[i]);
i++;
}
@@ -816,21 +821,20 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
auto decompressed_data,
gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000))
auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
graphics_bin_[i] =
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
core::kTilesheetDepth, converted_sheet);
gfx_sheets_[i] = gfx::Bitmap(gfx::kTilesheetWidth, gfx::kTilesheetHeight,
gfx::kTilesheetDepth, converted_sheet);
if (col_file_) {
status_ = graphics_bin_[i].ApplyPalette(
status_ = gfx_sheets_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);
} else {
// ROM palette
auto palette_group = rom()->palette_group().get_group(
kPaletteGroupAddressesKeys[current_palette_]);
z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_);
status_ = graphics_bin_[i].ApplyPalette(z3_rom_palette_);
status_ = gfx_sheets_[i].ApplyPalette(z3_rom_palette_);
}
rom()->RenderBitmap(&graphics_bin_[i]);
Renderer::GetInstance().RenderBitmap(&gfx_sheets_[i]);
i++;
}
super_donkey_ = true;

View File

@@ -1,22 +1,19 @@
#ifndef YAZE_APP_EDITOR_GRAPHICS_EDITOR_H
#define YAZE_APP_EDITOR_GRAPHICS_EDITOR_H
#include "ImGuiFileDialog/ImGuiFileDialog.h"
#include "imgui/imgui.h"
#include "imgui/misc/cpp/imgui_stdlib.h"
#include "imgui_memory_editor.h"
#include <stack>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/editor/utils/editor.h"
#include "app/editor/editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/asset_browser.h"
#include "app/gui/modules/asset_browser.h"
#include "app/gui/canvas.h"
#include "app/gui/input.h"
#include "app/rom.h"
#include "app/zelda3/overworld/overworld.h"
#include "imgui/imgui.h"
#include "imgui_memory_editor.h"
namespace yaze {
namespace app {
@@ -167,8 +164,8 @@ class GraphicsEditor : public SharedRom, public Editor {
MemoryEditor cgx_memory_editor_;
MemoryEditor col_memory_editor_;
PaletteEditor palette_editor_;
Bytes import_data_;
Bytes graphics_buffer_;
std::vector<uint8_t> import_data_;
std::vector<uint8_t> graphics_buffer_;
std::vector<uint8_t> decoded_cgx_;
std::vector<uint8_t> cgx_data_;
std::vector<uint8_t> extra_cgx_data_;
@@ -179,9 +176,8 @@ class GraphicsEditor : public SharedRom, public Editor {
gfx::Bitmap scr_bitmap_;
gfx::Bitmap bin_bitmap_;
gfx::Bitmap link_full_sheet_;
gfx::BitmapTable graphics_bin_;
gfx::BitmapTable clipboard_graphics_bin_;
gfx::BitmapTable link_graphics_;
std::array<gfx::Bitmap, kNumGfxSheets> gfx_sheets_;
gfx::PaletteGroup col_file_palette_group_;
gfx::SnesPalette z3_rom_palette_;
gfx::SnesPalette col_file_palette_;
@@ -189,11 +185,12 @@ class GraphicsEditor : public SharedRom, public Editor {
gui::Canvas import_canvas_;
gui::Canvas scr_canvas_;
gui::Canvas super_donkey_canvas_;
gui::Canvas graphics_bin_canvas_;
gui::Canvas current_sheet_canvas_{"CurrentSheetCanvas", ImVec2(0x80, 0x20),
gui::CanvasGridSize::k8x8};
gui::Canvas link_canvas_{
"LinkCanvas",
ImVec2(core::kTilesheetWidth * 4, core::kTilesheetHeight * 0x10 * 4),
ImVec2(gfx::kTilesheetWidth * 4, gfx::kTilesheetHeight * 0x10 * 4),
gui::CanvasGridSize::k16x16};
absl::Status status_;
};

View File

@@ -1,13 +1,11 @@
#include "palette_editor.h"
#include "imgui/imgui.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "app/gfx/snes_palette.h"
#include "app/gui/canvas.h"
#include "app/gui/color.h"
#include "app/gui/icons.h"
#include "app/gui/style.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
@@ -86,6 +84,93 @@ static inline float color_saturate(float f) {
0.5f)) // Saturated, always output 0..255
} // namespace
absl::Status DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
static ImVec4 color = ImVec4(0, 0, 0, 255.f);
static ImVec4 current_palette[256] = {};
ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
ImGuiColorEditFlags_NoDragDrop |
ImGuiColorEditFlags_NoOptions;
// Generate a default palette. The palette will persist and can be edited.
static bool init = false;
if (loaded && !init) {
for (int n = 0; n < palette.size(); n++) {
ASSIGN_OR_RETURN(auto color, palette.GetColor(n));
current_palette[n].x = color.rgb().x / 255;
current_palette[n].y = color.rgb().y / 255;
current_palette[n].z = color.rgb().z / 255;
current_palette[n].w = 255; // Alpha
}
init = true;
}
static ImVec4 backup_color;
bool open_popup = ColorButton("MyColor##3b", color, misc_flags);
SameLine(0, GetStyle().ItemInnerSpacing.x);
open_popup |= Button("Palette");
if (open_popup) {
OpenPopup("mypicker");
backup_color = color;
}
if (BeginPopup("mypicker")) {
TEXT_WITH_SEPARATOR("Current Overworld Palette");
ColorPicker4("##picker", (float*)&color,
misc_flags | ImGuiColorEditFlags_NoSidePreview |
ImGuiColorEditFlags_NoSmallPreview);
SameLine();
BeginGroup(); // Lock X position
Text("Current ==>");
SameLine();
Text("Previous");
if (Button("Update Map Palette")) {
}
ColorButton(
"##current", color,
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
ImVec2(60, 40));
SameLine();
if (ColorButton(
"##previous", backup_color,
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
ImVec2(60, 40)))
color = backup_color;
// List of Colors in Overworld Palette
Separator();
Text("Palette");
for (int n = 0; n < IM_ARRAYSIZE(current_palette); n++) {
PushID(n);
if ((n % 8) != 0) SameLine(0.0f, GetStyle().ItemSpacing.y);
if (ColorButton("##palette", current_palette[n], kPalButtonFlags2,
ImVec2(20, 20)))
color = ImVec4(current_palette[n].x, current_palette[n].y,
current_palette[n].z, color.w); // Preserve alpha!
if (BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
memcpy((float*)&current_palette[n], payload->Data, sizeof(float) * 3);
if (const ImGuiPayload* payload =
AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
memcpy((float*)&current_palette[n], payload->Data, sizeof(float) * 4);
EndDragDropTarget();
}
PopID();
}
EndGroup();
EndPopup();
}
return absl::OkStatus();
}
absl::Status PaletteEditor::Update() {
if (rom()->is_loaded()) {
// Initialize the labels
@@ -348,7 +433,7 @@ absl::Status PaletteEditor::HandleColorPopup(gfx::SnesPalette& palette, int i,
// SNES Format
CustomFormatString(buf, IM_ARRAYSIZE(buf), "$%04X",
ConvertRGBtoSNES(ImVec4(col[0], col[1], col[2], 1.0f)));
ConvertRgbToSnes(ImVec4(col[0], col[1], col[2], 1.0f)));
if (Selectable(buf)) SetClipboardText(buf);
EndPopup();
@@ -358,84 +443,6 @@ absl::Status PaletteEditor::HandleColorPopup(gfx::SnesPalette& palette, int i,
return absl::OkStatus();
}
void PaletteEditor::DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
static ImVec4 color = ImVec4(0, 0, 0, 255.f);
ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
ImGuiColorEditFlags_NoDragDrop |
ImGuiColorEditFlags_NoOptions;
// Generate a default palette. The palette will persist and can be edited.
static bool init = false;
if (loaded && !init) {
status_ = InitializeSavedPalette(palette);
init = true;
}
static ImVec4 backup_color;
bool open_popup = ColorButton("MyColor##3b", color, misc_flags);
SameLine(0, GetStyle().ItemInnerSpacing.x);
open_popup |= Button("Palette");
if (open_popup) {
OpenPopup("mypicker");
backup_color = color;
}
if (BeginPopup("mypicker")) {
TEXT_WITH_SEPARATOR("Current Overworld Palette");
ColorPicker4("##picker", (float*)&color,
misc_flags | ImGuiColorEditFlags_NoSidePreview |
ImGuiColorEditFlags_NoSmallPreview);
SameLine();
BeginGroup(); // Lock X position
Text("Current ==>");
SameLine();
Text("Previous");
if (Button("Update Map Palette")) {
}
ColorButton(
"##current", color,
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
ImVec2(60, 40));
SameLine();
if (ColorButton(
"##previous", backup_color,
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
ImVec2(60, 40)))
color = backup_color;
// List of Colors in Overworld Palette
Separator();
Text("Palette");
for (int n = 0; n < IM_ARRAYSIZE(saved_palette_); n++) {
PushID(n);
if ((n % 8) != 0) SameLine(0.0f, GetStyle().ItemSpacing.y);
if (ColorButton("##palette", saved_palette_[n], kPalButtonFlags2,
ImVec2(20, 20)))
color = ImVec4(saved_palette_[n].x, saved_palette_[n].y,
saved_palette_[n].z, color.w); // Preserve alpha!
if (BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
memcpy((float*)&saved_palette_[n], payload->Data, sizeof(float) * 3);
if (const ImGuiPayload* payload =
AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
memcpy((float*)&saved_palette_[n], payload->Data, sizeof(float) * 4);
EndDragDropTarget();
}
PopID();
}
EndGroup();
EndPopup();
}
}
absl::Status PaletteEditor::EditColorInPalette(gfx::SnesPalette& palette,
int index) {
if (index >= palette.size()) {

View File

@@ -1,15 +1,17 @@
#ifndef YAZE_APP_EDITOR_PALETTE_EDITOR_H
#define YAZE_APP_EDITOR_PALETTE_EDITOR_H
#include "imgui/imgui.h"
#include <deque>
#include <string>
#include <vector>
#include "absl/status/status.h"
#include "app/editor/graphics/gfx_group_editor.h"
#include "app/editor/utils/editor.h"
#include "app/editor/editor.h"
#include "app/gfx/snes_palette.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gfx/snes_color.h"
#include "app/rom.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
@@ -26,56 +28,51 @@ struct PaletteChange {
class PaletteEditorHistory {
public:
// Record a change in the palette editor
void RecordChange(const std::string& groupName, size_t paletteIndex,
size_t colorIndex, const gfx::SnesColor& originalColor,
const gfx::SnesColor& newColor) {
// Check size and remove the oldest if necessary
if (recentChanges.size() >= maxHistorySize) {
recentChanges.pop_front();
void RecordChange(const std::string& group_name, size_t palette_index,
size_t color_index, const gfx::SnesColor& original_color,
const gfx::SnesColor& new_color) {
if (recent_changes_.size() >= kMaxHistorySize) {
recent_changes_.pop_front();
}
// Push the new change
recentChanges.push_back(
{groupName, paletteIndex, colorIndex, originalColor, newColor});
recent_changes_.push_back(
{group_name, palette_index, color_index, original_color, new_color});
}
// Get recent changes for display in the palette editor
const std::deque<PaletteChange>& GetRecentChanges() const {
return recentChanges;
}
// Restore the original color
gfx::SnesColor RestoreOriginalColor(const std::string& groupName,
size_t paletteIndex,
size_t colorIndex) const {
for (const auto& change : recentChanges) {
if (change.group_name == groupName &&
change.palette_index == paletteIndex &&
change.color_index == colorIndex) {
gfx::SnesColor RestoreOriginalColor(const std::string& group_name,
size_t palette_index,
size_t color_index) const {
for (const auto& change : recent_changes_) {
if (change.group_name == group_name &&
change.palette_index == palette_index &&
change.color_index == color_index) {
return change.original_color;
}
}
// Handle error or return default (this is just an example,
// handle as appropriate for your application)
return gfx::SnesColor();
}
auto size() const { return recentChanges.size(); }
auto size() const { return recent_changes_.size(); }
gfx::SnesColor& GetModifiedColor(size_t index) {
return recentChanges[index].new_color;
return recent_changes_[index].new_color;
}
gfx::SnesColor& GetOriginalColor(size_t index) {
return recentChanges[index].original_color;
return recent_changes_[index].original_color;
}
const std::deque<PaletteChange>& GetRecentChanges() const {
return recent_changes_;
}
private:
std::deque<PaletteChange> recentChanges;
static const size_t maxHistorySize = 50; // or any other number you deem fit
std::deque<PaletteChange> recent_changes_;
static const size_t kMaxHistorySize = 50;
};
} // namespace palette_internal
absl::Status DisplayPalette(gfx::SnesPalette& palette, bool loaded);
/**
* @class PaletteEditor
* @brief Allows the user to view and edit in game palettes.
@@ -101,7 +98,6 @@ class PaletteEditor : public SharedRom, public Editor {
absl::Status EditColorInPalette(gfx::SnesPalette& palette, int index);
absl::Status ResetColorToOriginal(gfx::SnesPalette& palette, int index,
const gfx::SnesPalette& originalPalette);
void DisplayPalette(gfx::SnesPalette& palette, bool loaded);
absl::Status DrawPaletteGroup(int category, bool right_side = false);
void DrawCustomPalette();
@@ -110,16 +106,6 @@ class PaletteEditor : public SharedRom, public Editor {
private:
absl::Status HandleColorPopup(gfx::SnesPalette& palette, int i, int j, int n);
absl::Status InitializeSavedPalette(const gfx::SnesPalette& palette) {
for (int n = 0; n < palette.size(); n++) {
ASSIGN_OR_RETURN(auto color, palette.GetColor(n));
saved_palette_[n].x = color.rgb().x / 255;
saved_palette_[n].y = color.rgb().y / 255;
saved_palette_[n].z = color.rgb().z / 255;
saved_palette_[n].w = 255; // Alpha
}
return absl::OkStatus();
}
absl::Status status_;
gfx::SnesColor current_color_;
@@ -137,4 +123,4 @@ class PaletteEditor : public SharedRom, public Editor {
} // namespace app
} // namespace yaze
#endif
#endif

View File

@@ -1,44 +1,45 @@
#include "screen_editor.h"
#include "imgui/imgui.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "app/core/common.h"
#include "app/core/constants.h"
#include "app/core/platform/file_dialog.h"
#include "app/core/platform/renderer.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
#include "app/gfx/tilesheet.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "app/zelda3/dungeon/room.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
namespace editor {
absl::Status ScreenEditor::Update() {
TAB_BAR("##TabBar")
TAB_ITEM("Dungeon Maps")
if (rom()->is_loaded()) {
DrawDungeonMapsEditor();
}
END_TAB_ITEM()
DrawInventoryMenuEditor();
DrawOverworldMapEditor();
DrawTitleScreenEditor();
DrawNamingScreenEditor();
END_TAB_BAR()
using core::Renderer;
return absl::OkStatus();
constexpr uint32_t kRedPen = 0xFF0000FF;
absl::Status ScreenEditor::Update() {
if (ImGui::BeginTabBar("##ScreenEditorTabBar")) {
if (ImGui::BeginTabItem("Dungeon Maps")) {
if (rom()->is_loaded()) {
DrawDungeonMapsEditor();
}
ImGui::EndTabItem();
}
DrawInventoryMenuEditor();
DrawOverworldMapEditor();
DrawTitleScreenEditor();
DrawNamingScreenEditor();
ImGui::EndTabBar();
}
return status_;
}
void ScreenEditor::DrawInventoryMenuEditor() {
@@ -121,16 +122,16 @@ absl::Status ScreenEditor::LoadDungeonMaps() {
int ptr,
rom()->ReadWord(zelda3::screen::kDungeonMapRoomsPtr + (d * 2)));
ASSIGN_OR_RETURN(
int ptrGFX,
rom()->ReadWord(zelda3::screen::kDungeonMapRoomsPtr + (d * 2)));
ptr |= 0x0A0000; // Add bank to the short ptr
ptrGFX |= 0x0A0000; // Add bank to the short ptr
int pcPtr = core::SnesToPc(ptr); // Contains data for the next 25 rooms
int pcPtrGFX =
core::SnesToPc(ptrGFX); // Contains data for the next 25 rooms
int ptr_gfx,
rom()->ReadWord(zelda3::screen::kDungeonMapGfxPtr + (d * 2)));
ptr |= 0x0A0000; // Add bank to the short ptr
ptr_gfx |= 0x0A0000; // Add bank to the short ptr
int pc_ptr = core::SnesToPc(ptr); // Contains data for the next 25 rooms
int pc_ptr_gfx =
core::SnesToPc(ptr_gfx); // Contains data for the next 25 rooms
ASSIGN_OR_RETURN(
ushort bossRoomD,
ushort boss_room_d,
rom()->ReadWord(zelda3::screen::kDungeonMapBossRooms + (d * 2)));
ASSIGN_OR_RETURN(
@@ -157,14 +158,13 @@ absl::Status ScreenEditor::LoadDungeonMaps() {
// for each room on the floor
for (int j = 0; j < 25; j++) {
// rdata[j] = 0x0F;
gdata[j] = 0xFF;
rdata[j] = rom()->data()[pcPtr + j + (i * 25)]; // Set the rooms
rdata[j] = rom()->data()[pc_ptr + j + (i * 25)]; // Set the rooms
if (rdata[j] == 0x0F) {
gdata[j] = 0xFF;
} else {
gdata[j] = rom()->data()[pcPtrGFX++];
gdata[j] = rom()->data()[pc_ptr_gfx++];
}
std::string label = core::UppercaseHexByte(rdata[j]);
@@ -175,7 +175,7 @@ absl::Status ScreenEditor::LoadDungeonMaps() {
current_floor_rooms_d.push_back(rdata); // Add new floor data
}
dungeon_maps_.emplace_back(bossRoomD, nbr_floor_d, nbr_basement_d,
dungeon_maps_.emplace_back(boss_room_d, nbr_floor_d, nbr_basement_d,
current_floor_rooms_d, current_floor_gfx_d);
}
@@ -185,23 +185,19 @@ absl::Status ScreenEditor::LoadDungeonMaps() {
absl::Status ScreenEditor::SaveDungeonMaps() {
for (int d = 0; d < 14; d++) {
int ptr = zelda3::screen::kDungeonMapRoomsPtr + (d * 2);
int ptrGFX = zelda3::screen::kDungeonMapGfxPtr + (d * 2);
int pcPtr = core::SnesToPc(ptr);
int pcPtrGFX = core::SnesToPc(ptrGFX);
int ptr_gfx = zelda3::screen::kDungeonMapGfxPtr + (d * 2);
int pc_ptr = core::SnesToPc(ptr);
int pc_ptr_gfx = core::SnesToPc(ptr_gfx);
const int nbr_floors = dungeon_maps_[d].nbr_of_floor;
const int nbr_basements = dungeon_maps_[d].nbr_of_basement;
for (int i = 0; i < nbr_floors + nbr_basements; i++) {
for (int j = 0; j < 25; j++) {
// rom()->data()[pcPtr + j + (i * 25)] =
// dungeon_maps_[d].floor_rooms[i][j];
// rom()->data()[pcPtrGFX++] = dungeon_maps_[d].floor_gfx[i][j];
RETURN_IF_ERROR(rom()->WriteByte(ptr + j + (i * 25),
RETURN_IF_ERROR(rom()->WriteByte(pc_ptr + j + (i * 25),
dungeon_maps_[d].floor_rooms[i][j]));
RETURN_IF_ERROR(rom()->WriteByte(ptrGFX + j + (i * 25),
RETURN_IF_ERROR(rom()->WriteByte(pc_ptr_gfx + j + (i * 25),
dungeon_maps_[d].floor_gfx[i][j]));
pcPtrGFX++;
pc_ptr_gfx++;
}
}
}
@@ -209,7 +205,8 @@ absl::Status ScreenEditor::SaveDungeonMaps() {
return absl::OkStatus();
}
absl::Status ScreenEditor::LoadDungeonMapTile16() {
absl::Status ScreenEditor::LoadDungeonMapTile16(
const std::vector<uint8_t>& gfx_data, bool bin_mode) {
tile16_sheet_.Init(256, 192, gfx::TileType::Tile16);
for (int i = 0; i < 186; i++) {
@@ -230,69 +227,99 @@ absl::Status ScreenEditor::LoadDungeonMapTile16() {
ASSIGN_OR_RETURN(auto br, rom()->ReadWord(addr + 6 + (i * 8)));
gfx::TileInfo t4 = gfx::WordToTileInfo(br); // Bottom right
tile16_sheet_.ComposeTile16(rom()->graphics_buffer(), t1, t2, t3, t4);
int sheet_offset = 212;
if (bin_mode) {
sheet_offset = 0;
}
tile16_sheet_.ComposeTile16(gfx_data, t1, t2, t3, t4, sheet_offset);
}
RETURN_IF_ERROR(tile16_sheet_.mutable_bitmap()->ApplyPalette(
*rom()->mutable_dungeon_palette(3)));
rom()->RenderBitmap(&*tile16_sheet_.mutable_bitmap().get());
Renderer::GetInstance().RenderBitmap(&*tile16_sheet_.mutable_bitmap().get());
for (int i = 0; i < tile16_sheet_.num_tiles(); ++i) {
if (tile16_individual_.count(i) == 0) {
auto tile = tile16_sheet_.GetTile16(i);
tile16_individual_[i] = tile;
rom()->RenderBitmap(&tile16_individual_[i]);
}
auto tile = tile16_sheet_.GetTile16(i);
tile16_individual_[i] = tile;
RETURN_IF_ERROR(
tile16_individual_[i].ApplyPalette(*rom()->mutable_dungeon_palette(3)));
Renderer::GetInstance().RenderBitmap(&tile16_individual_[i]);
}
return absl::OkStatus();
}
absl::Status ScreenEditor::SaveDungeonMapTile16() {
for (int i = 0; i < 186; i++) {
int addr = zelda3::screen::kDungeonMapTile16;
if (rom()->data()[zelda3::screen::kDungeonMapExpCheck] != 0xB9) {
addr = zelda3::screen::kDungeonMapTile16Expanded;
}
gfx::TileInfo t1 = tile16_sheet_.tile_info()[i].tiles[0];
gfx::TileInfo t2 = tile16_sheet_.tile_info()[i].tiles[1];
gfx::TileInfo t3 = tile16_sheet_.tile_info()[i].tiles[2];
gfx::TileInfo t4 = tile16_sheet_.tile_info()[i].tiles[3];
auto tl = gfx::TileInfoToWord(t1);
RETURN_IF_ERROR(rom()->WriteWord(addr + (i * 8), tl));
auto tr = gfx::TileInfoToWord(t2);
RETURN_IF_ERROR(rom()->WriteWord(addr + 2 + (i * 8), tr));
auto bl = gfx::TileInfoToWord(t3);
RETURN_IF_ERROR(rom()->WriteWord(addr + 4 + (i * 8), bl));
auto br = gfx::TileInfoToWord(t4);
RETURN_IF_ERROR(rom()->WriteWord(addr + 6 + (i * 8), br));
}
return absl::OkStatus();
}
void ScreenEditor::DrawDungeonMapsTabs() {
auto current_dungeon = dungeon_maps_[selected_dungeon];
auto& current_dungeon = dungeon_maps_[selected_dungeon];
if (ImGui::BeginTabBar("##DungeonMapTabs")) {
auto nbr_floors =
current_dungeon.nbr_of_floor + current_dungeon.nbr_of_basement;
for (int i = 0; i < nbr_floors; i++) {
std::string tab_name = absl::StrFormat("Floor %d", i + 1);
if (i >= current_dungeon.nbr_of_floor) {
tab_name = absl::StrFormat("Basement %d",
i - current_dungeon.nbr_of_floor + 1);
int basement_num = current_dungeon.nbr_of_basement - i;
std::string tab_name = absl::StrFormat("Basement %d", basement_num);
if (i >= current_dungeon.nbr_of_basement) {
tab_name = absl::StrFormat("Floor %d",
i - current_dungeon.nbr_of_basement + 1);
}
if (ImGui::BeginTabItem(tab_name.c_str())) {
floor_number = i;
// screen_canvas_.LoadCustomLabels(dungeon_map_labels_[selected_dungeon]);
// screen_canvas_.set_current_labels(floor_number);
screen_canvas_.DrawBackground(ImVec2(325, 325));
screen_canvas_.DrawTileSelector(64.f);
auto boss_room = current_dungeon.boss_room;
for (int j = 0; j < 25; j++) {
if (current_dungeon.floor_rooms[floor_number][j] != 0x0F) {
int tile16_id = current_dungeon.floor_rooms[floor_number][j];
int tile_x = (tile16_id % 16) * 16;
int tile_y = (tile16_id / 16) * 16;
int tile16_id = current_dungeon.floor_gfx[floor_number][j];
int posX = ((j % 5) * 32);
int posY = ((j / 5) * 32);
if (tile16_individual_.count(tile16_id) == 0) {
auto tile = tile16_sheet_.GetTile16(tile16_id);
std::cout << "Tile16: " << tile16_id << std::endl;
rom()->RenderBitmap(&tile);
tile16_individual_[tile16_id] = tile;
tile16_individual_[tile16_id] =
tile16_sheet_.GetTile16(tile16_id);
Renderer::GetInstance().RenderBitmap(
&tile16_individual_[tile16_id]);
}
screen_canvas_.DrawBitmap(tile16_individual_[tile16_id], (posX * 2),
(posY * 2), 4.0f);
if (current_dungeon.floor_rooms[floor_number][j] == boss_room) {
screen_canvas_.DrawOutlineWithColor((posX * 2), (posY * 2), 64,
64, core::kRedPen);
64, kRedPen);
}
std::string label =
dungeon_map_labels_[selected_dungeon][floor_number][j];
screen_canvas_.DrawText(label, (posX * 2), (posY * 2));
std::string gfx_id = core::UppercaseHexByte(tile16_id);
screen_canvas_.DrawText(gfx_id, (posX * 2), (posY * 2) + 16);
}
}
@@ -316,31 +343,76 @@ void ScreenEditor::DrawDungeonMapsTabs() {
gui::InputHexWord("Boss Room", &current_dungeon.boss_room);
if (ImGui::Button("Copy Floor", ImVec2(100, 0))) {
const ImVec2 button_size = ImVec2(130, 0);
// Add Floor Button
if (ImGui::Button("Add Floor", button_size) &&
current_dungeon.nbr_of_floor < 8) {
current_dungeon.nbr_of_floor++;
dungeon_map_labels_[selected_dungeon].emplace_back();
}
ImGui::SameLine();
if (ImGui::Button("Remove Floor", button_size) &&
current_dungeon.nbr_of_floor > 0) {
current_dungeon.nbr_of_floor--;
dungeon_map_labels_[selected_dungeon].pop_back();
}
// Add Basement Button
if (ImGui::Button("Add Basement", button_size) &&
current_dungeon.nbr_of_basement < 8) {
current_dungeon.nbr_of_basement++;
dungeon_map_labels_[selected_dungeon].emplace_back();
}
ImGui::SameLine();
if (ImGui::Button("Remove Basement", button_size) &&
current_dungeon.nbr_of_basement > 0) {
current_dungeon.nbr_of_basement--;
dungeon_map_labels_[selected_dungeon].pop_back();
}
if (ImGui::Button("Copy Floor", button_size)) {
copy_button_pressed = true;
}
ImGui::SameLine();
if (ImGui::Button("Paste Floor", ImVec2(100, 0))) {
if (ImGui::Button("Paste Floor", button_size)) {
paste_button_pressed = true;
}
}
void ScreenEditor::DrawDungeonMapsEditor() {
if (!dungeon_maps_loaded_) {
if (LoadDungeonMaps().ok()) {
if (LoadDungeonMapTile16().ok()) {
auto bitmap_manager = rom()->mutable_bitmap_manager();
sheets_.emplace(0, *bitmap_manager->mutable_bitmap(212));
sheets_.emplace(1, *bitmap_manager->mutable_bitmap(213));
sheets_.emplace(2, *bitmap_manager->mutable_bitmap(214));
sheets_.emplace(3, *bitmap_manager->mutable_bitmap(215));
dungeon_maps_loaded_ = true;
} else {
ImGui::Text("Failed to load dungeon map tile16");
}
} else {
if (!LoadDungeonMaps().ok()) {
ImGui::Text("Failed to load dungeon maps");
}
if (LoadDungeonMapTile16(rom()->graphics_buffer()).ok()) {
// TODO: Load roomset gfx based on dungeon ID
sheets_.emplace(0, rom()->gfx_sheets()[212]);
sheets_.emplace(1, rom()->gfx_sheets()[213]);
sheets_.emplace(2, rom()->gfx_sheets()[214]);
sheets_.emplace(3, rom()->gfx_sheets()[215]);
dungeon_maps_loaded_ = true;
} else {
ImGui::Text("Failed to load dungeon map tile16");
}
}
if (ImGui::BeginTable("##DungeonMapToolset", 2, ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("Draw Mode");
ImGui::TableSetupColumn("Edit Mode");
ImGui::TableNextColumn();
if (ImGui::Button(ICON_MD_DRAW)) {
current_mode_ = EditingMode::DRAW;
}
ImGui::TableNextColumn();
if (ImGui::Button(ICON_MD_EDIT)) {
current_mode_ = EditingMode::EDIT;
}
ImGui::EndTable();
}
static std::vector<std::string> dungeon_names = {
@@ -350,7 +422,10 @@ void ScreenEditor::DrawDungeonMapsEditor() {
"Thieves' Town", "Ice Palace", "Misery Mire",
"Turtle Rock", "Ganon's Tower"};
if (ImGui::BeginTable("DungeonMapsTable", 4, ImGuiTableFlags_Resizable)) {
if (ImGui::BeginTable("DungeonMapsTable", 4,
ImGuiTableFlags_Resizable |
ImGuiTableFlags_Reorderable |
ImGuiTableFlags_Hideable)) {
ImGui::TableSetupColumn("Dungeon");
ImGui::TableSetupColumn("Map");
ImGui::TableSetupColumn("Rooms Gfx");
@@ -384,32 +459,113 @@ void ScreenEditor::DrawDungeonMapsEditor() {
if (!tilesheet_canvas_.points().empty()) {
selected_tile16_ = tilesheet_canvas_.points().front().x / 32 +
(tilesheet_canvas_.points().front().y / 32) * 16;
current_tile16_info = tile16_sheet_.tile_info().at(selected_tile16_);
// Draw the selected tile
if (!screen_canvas_.points().empty()) {
dungeon_maps_[selected_dungeon]
.floor_gfx[floor_number][selected_room] = selected_tile16_;
tilesheet_canvas_.mutable_points()->clear();
}
}
ImGui::Separator();
current_tile_canvas_.DrawBackground(ImVec2(64 * 2 + 2, 64 * 2 + 4));
current_tile_canvas_.DrawContextMenu();
current_tile_canvas_.DrawBitmap(tile16_individual_[selected_tile16_], 2,
4.0f);
current_tile_canvas_.DrawGrid(16.f);
current_tile_canvas_.DrawOverlay();
gui::InputTileInfo("TL", &current_tile16_info.tiles[0]);
ImGui::SameLine();
gui::InputTileInfo("TR", &current_tile16_info.tiles[1]);
gui::InputTileInfo("BL", &current_tile16_info.tiles[2]);
ImGui::SameLine();
gui::InputTileInfo("BR", &current_tile16_info.tiles[3]);
if (ImGui::Button("Modify Tile16")) {
tile16_sheet_.ModifyTile16(
rom()->graphics_buffer(), current_tile16_info.tiles[0],
current_tile16_info.tiles[1], current_tile16_info.tiles[2],
current_tile16_info.tiles[3], selected_tile16_, 212);
tile16_individual_[selected_tile16_] =
tile16_sheet_.GetTile16(selected_tile16_);
RETURN_VOID_IF_ERROR(tile16_individual_[selected_tile16_].ApplyPalette(
*rom()->mutable_dungeon_palette(3)));
Renderer::GetInstance().RenderBitmap(
&tile16_individual_[selected_tile16_]);
}
}
ImGui::EndChild();
ImGui::TableNextColumn();
tilemap_canvas_.DrawBackground(ImVec2(128 * 2 + 2, (192 * 2) + 4));
tilemap_canvas_.DrawBackground();
tilemap_canvas_.DrawContextMenu();
if (tilemap_canvas_.DrawTileSelector(16.f)) {
// Get the tile8 ID to use for the tile16 drawing above
selected_tile8_ = tilemap_canvas_.GetTileIdFromMousePos();
}
tilemap_canvas_.DrawBitmapTable(sheets_);
tilemap_canvas_.DrawGrid();
tilemap_canvas_.DrawOverlay();
ImGui::Text("Selected tile8: %d", selected_tile8_);
ImGui::Separator();
ImGui::Text("For use with custom inserted graphics assembly patches.");
if (ImGui::Button("Load GFX from BIN file")) LoadBinaryGfx();
ImGui::EndTable();
}
}
void ScreenEditor::LoadBinaryGfx() {
std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog();
if (!bin_file.empty()) {
std::ifstream file(bin_file, std::ios::binary);
if (file.is_open()) {
// Read the gfx data into a buffer
std::vector<uint8_t> bin_data((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
auto converted_bin = gfx::SnesTo8bppSheet(bin_data, 4, 4);
gfx_bin_data_ = converted_bin;
tile16_sheet_.clear();
if (LoadDungeonMapTile16(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].ApplyPalette(*rom()->mutable_dungeon_palette(3));
Renderer::GetInstance().RenderBitmap(&sheets_[i]);
}
binary_gfx_loaded_ = true;
} else {
status_ = absl::InternalError("Failed to load dungeon map tile16");
}
file.close();
}
}
}
void ScreenEditor::DrawTitleScreenEditor() {
TAB_ITEM("Title Screen")
END_TAB_ITEM()
if (ImGui::BeginTabItem("Title Screen")) {
ImGui::EndTabItem();
}
}
void ScreenEditor::DrawNamingScreenEditor() {
TAB_ITEM("Naming Screen")
END_TAB_ITEM()
if (ImGui::BeginTabItem("Naming Screen")) {
ImGui::EndTabItem();
}
}
void ScreenEditor::DrawOverworldMapEditor() {
TAB_ITEM("Overworld Map")
END_TAB_ITEM()
if (ImGui::BeginTabItem("Overworld Map")) {
ImGui::EndTabItem();
}
}
void ScreenEditor::DrawToolset() {

View File

@@ -1,23 +1,18 @@
#ifndef YAZE_APP_EDITOR_SCREEN_EDITOR_H
#define YAZE_APP_EDITOR_SCREEN_EDITOR_H
#include "imgui/imgui.h"
#include <array>
#include "absl/status/status.h"
#include "app/core/constants.h"
#include "app/editor/utils/editor.h"
#include "app/editor/editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gfx/tilesheet.h"
#include "app/gui/canvas.h"
#include "app/gui/color.h"
#include "app/gui/icons.h"
#include "app/rom.h"
#include "app/zelda3/screen/dungeon_map.h"
#include "app/zelda3/screen/inventory.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
@@ -38,7 +33,7 @@ namespace editor {
* The class inherits from the SharedRom class.
*/
class ScreenEditor : public SharedRom, public Editor {
public:
public:
ScreenEditor() {
screen_canvas_.SetCanvasSize(ImVec2(512, 512));
type_ = EditorType::kScreen;
@@ -55,7 +50,7 @@ class ScreenEditor : public SharedRom, public Editor {
absl::Status SaveDungeonMaps();
private:
private:
void DrawTitleScreenEditor();
void DrawNamingScreenEditor();
void DrawOverworldMapEditor();
@@ -65,42 +60,58 @@ class ScreenEditor : public SharedRom, public Editor {
void DrawInventoryToolset();
absl::Status LoadDungeonMaps();
absl::Status LoadDungeonMapTile16();
absl::Status LoadDungeonMapTile16(const std::vector<uint8_t> &gfx_data,
bool bin_mode = false);
absl::Status SaveDungeonMapTile16();
void DrawDungeonMapsTabs();
void DrawDungeonMapsEditor();
std::vector<zelda3::screen::DungeonMap> dungeon_maps_;
std::vector<std::vector<std::array<std::string, 25>>> dungeon_map_labels_;
void LoadBinaryGfx();
std::unordered_map<int, gfx::Bitmap> tile16_individual_;
enum class EditingMode { DRAW, EDIT };
EditingMode current_mode_ = EditingMode::DRAW;
bool dungeon_maps_loaded_ = false;
bool binary_gfx_loaded_ = false;
int selected_tile16_ = 0;
int selected_dungeon = 0;
uint8_t selected_room = 0;
uint8_t boss_room = 0;
int selected_tile16_ = 0;
int selected_tile8_ = 0;
int selected_dungeon = 0;
int floor_number = 1;
bool copy_button_pressed = false;
bool paste_button_pressed = false;
Bytes all_gfx_;
zelda3::screen::Inventory inventory_;
gfx::SnesPalette palette_;
gui::Canvas screen_canvas_;
gui::Canvas tilesheet_canvas_;
gui::Canvas tilemap_canvas_;
gfx::BitmapTable sheets_;
gfx::Tilesheet tile16_sheet_;
std::vector<uint8_t> all_gfx_;
std::unordered_map<int, gfx::Bitmap> tile16_individual_;
std::vector<zelda3::screen::DungeonMap> dungeon_maps_;
std::vector<std::vector<std::array<std::string, 25>>> dungeon_map_labels_;
std::array<uint16_t, 4> current_tile16_data_;
std::vector<uint8_t> gfx_bin_data_;
absl::Status status_;
gfx::SnesPalette palette_;
gfx::BitmapTable sheets_;
gfx::Tilesheet tile16_sheet_;
gfx::InternalTile16 current_tile16_info;
gui::Canvas current_tile_canvas_{"##CurrentTileCanvas"};
gui::Canvas screen_canvas_;
gui::Canvas tilesheet_canvas_;
gui::Canvas tilemap_canvas_{"##TilemapCanvas",
ImVec2(128 + 2, (192) + 4),
gui::CanvasGridSize::k8x8, 2.f};
zelda3::screen::Inventory inventory_;
};
} // namespace editor
} // namespace app
} // namespace yaze
} // namespace editor
} // namespace app
} // namespace yaze
#endif

View File

@@ -1,14 +1,13 @@
#include "tile16_editor.h"
#include "ImGuiFileDialog/ImGuiFileDialog.h"
#include "imgui/imgui.h"
#include <cmath>
#include "ImGuiFileDialog/ImGuiFileDialog.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/core/platform/renderer.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/editor/utils/editor.h"
#include "app/editor/editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
@@ -19,11 +18,14 @@
#include "app/gui/style.h"
#include "app/rom.h"
#include "app/zelda3/overworld/overworld.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
namespace editor {
using core::Renderer;
using ImGui::BeginChild;
using ImGui::BeginMenu;
using ImGui::BeginMenuBar;
@@ -48,14 +50,13 @@ using ImGui::TableSetupColumn;
using ImGui::Text;
absl::Status Tile16Editor::InitBlockset(
gfx::Bitmap* tile16_blockset_bmp, gfx::Bitmap current_gfx_bmp,
const gfx::Bitmap& tile16_blockset_bmp, const gfx::Bitmap& current_gfx_bmp,
const std::vector<gfx::Bitmap>& tile16_individual,
uint8_t all_tiles_types[0x200]) {
all_tiles_types_ = all_tiles_types;
tile16_blockset_bmp_ = tile16_blockset_bmp;
tile16_individual_ = tile16_individual;
current_gfx_bmp_ = current_gfx_bmp;
tile8_gfx_data_ = current_gfx_bmp_.vector();
RETURN_IF_ERROR(LoadTile8());
ImVector<std::string> tile16_names;
for (int i = 0; i < 0x200; ++i) {
@@ -75,7 +76,7 @@ absl::Status Tile16Editor::Update() {
RETURN_IF_ERROR(DrawMenu());
if (BeginTabBar("Tile16 Editor Tabs")) {
RETURN_IF_ERROR(DrawTile16Editor());
DrawTile16Editor();
RETURN_IF_ERROR(UpdateTile16Transfer());
EndTabBar();
}
@@ -97,7 +98,7 @@ absl::Status Tile16Editor::DrawMenu() {
return absl::OkStatus();
}
absl::Status Tile16Editor::DrawTile16Editor() {
void Tile16Editor::DrawTile16Editor() {
if (BeginTabItem("Tile16 Editing")) {
if (BeginTable("#Tile16EditorTable", 2, TABLE_BORDERS_RESIZABLE,
ImVec2(0, 0))) {
@@ -108,18 +109,23 @@ absl::Status Tile16Editor::DrawTile16Editor() {
TableHeadersRow();
TableNextRow();
TableNextColumn();
RETURN_IF_ERROR(UpdateBlockset());
status_ = UpdateBlockset();
if (!status_.ok()) {
EndTable();
}
TableNextColumn();
RETURN_IF_ERROR(UpdateTile16Edit());
RETURN_IF_ERROR(DrawTileEditControls());
status_ = UpdateTile16Edit();
if (status_ != absl::OkStatus()) {
EndTable();
}
status_ = DrawTileEditControls();
EndTable();
}
EndTabItem();
}
return absl::OkStatus();
}
absl::Status Tile16Editor::UpdateBlockset() {
@@ -127,14 +133,12 @@ absl::Status Tile16Editor::UpdateBlockset() {
gui::BeginChildWithScrollbar("##Tile16EditorBlocksetScrollRegion");
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();
EndChild();
}
blockset_canvas_.DrawContextMenu();
blockset_canvas_.DrawTileSelector(32);
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 0, map_blockset_loaded_);
blockset_canvas_.DrawGrid();
blockset_canvas_.DrawOverlay();
EndChild();
if (!blockset_canvas_.points().empty()) {
notify_tile16.mutable_get() = blockset_canvas_.GetTileIdFromMousePos();
@@ -142,11 +146,11 @@ absl::Status Tile16Editor::UpdateBlockset() {
if (notify_tile16.modified()) {
current_tile16_ = notify_tile16.get();
current_tile16_bmp_ = &tile16_individual_[notify_tile16];
current_tile16_bmp_ = tile16_individual_[notify_tile16];
auto ow_main_pal_group = rom()->palette_group().overworld_main;
RETURN_IF_ERROR(current_tile16_bmp_->ApplyPalette(
RETURN_IF_ERROR(current_tile16_bmp_.ApplyPalette(
ow_main_pal_group[current_palette_]));
rom()->RenderBitmap(current_tile16_bmp_);
Renderer::GetInstance().RenderBitmap(&current_tile16_bmp_);
}
}
@@ -166,8 +170,8 @@ absl::Status Tile16Editor::DrawToCurrentTile16(ImVec2 click_position) {
// Calculate the pixel start position within the Tile16
ImVec2 start_position;
start_position.x = ((tile_index_x) / 4) * 0x40;
start_position.y = ((tile_index_y) / 4) * 0x40;
start_position.x = tile_index_x * 0x40;
start_position.y = tile_index_y * 0x40;
std::cout << "Start Position X: " << start_position.x << std::endl;
std::cout << "Start Position Y: " << start_position.y << std::endl;
@@ -177,7 +181,7 @@ absl::Status Tile16Editor::DrawToCurrentTile16(ImVec2 click_position) {
int pixel_index =
(start_position.y + y) * tile16_size + ((start_position.x) + x);
int gfx_pixel_index = y * tile8_size + x;
current_tile16_bmp_->WriteToPixel(
current_tile16_bmp_.WriteToPixel(
pixel_index,
current_gfx_individual_[current_tile8_].data()[gfx_pixel_index]);
}
@@ -197,7 +201,8 @@ absl::Status Tile16Editor::UpdateTile16Edit() {
RETURN_IF_ERROR(
current_gfx_individual_[current_tile8_].ApplyPaletteWithTransparent(
ow_main_pal_group[0], current_palette_));
rom()->UpdateBitmap(&current_gfx_individual_[current_tile8_]);
Renderer::GetInstance().UpdateBitmap(
&current_gfx_individual_[current_tile8_]);
}
tile8_source_canvas_.DrawBitmap(current_gfx_bmp_, 0, 0, 4.0f);
tile8_source_canvas_.DrawGrid();
@@ -214,20 +219,21 @@ absl::Status Tile16Editor::UpdateTile16Edit() {
RETURN_IF_ERROR(
current_gfx_individual_[current_tile8_].ApplyPaletteWithTransparent(
ow_main_pal_group[0], current_palette_));
rom()->UpdateBitmap(&current_gfx_individual_[current_tile8_]);
Renderer::GetInstance().UpdateBitmap(
&current_gfx_individual_[current_tile8_]);
}
if (BeginChild("Tile16 Editor Options",
ImVec2(GetContentRegionAvail().x, 0x50), true)) {
tile16_edit_canvas_.DrawBackground();
tile16_edit_canvas_.DrawContextMenu(current_tile16_bmp_);
tile16_edit_canvas_.DrawBitmap(*current_tile16_bmp_, 0, 0, 4.0f);
tile16_edit_canvas_.DrawContextMenu(&current_tile16_bmp_);
tile16_edit_canvas_.DrawBitmap(current_tile16_bmp_, 0, 0, 4.0f);
if (!tile8_source_canvas_.points().empty()) {
if (tile16_edit_canvas_.DrawTilePainter(
current_gfx_individual_[current_tile8_], 16, 2.0f)) {
RETURN_IF_ERROR(
DrawToCurrentTile16(tile16_edit_canvas_.drawn_tile_position()));
rom()->UpdateBitmap(current_tile16_bmp_);
Renderer::GetInstance().UpdateBitmap(&current_tile16_bmp_);
}
}
tile16_edit_canvas_.DrawGrid();
@@ -258,10 +264,11 @@ absl::Status Tile16Editor::DrawTileEditControls() {
if (value > 0x00) {
RETURN_IF_ERROR(
current_gfx_bmp_.ApplyPaletteWithTransparent(palette, value));
Renderer::GetInstance().UpdateBitmap(&current_gfx_bmp_);
RETURN_IF_ERROR(
current_tile16_bmp_->ApplyPaletteWithTransparent(palette, value));
rom()->UpdateBitmap(&current_gfx_bmp_);
rom()->UpdateBitmap(current_tile16_bmp_);
current_tile16_bmp_.ApplyPaletteWithTransparent(palette, value));
Renderer::GetInstance().UpdateBitmap(&current_tile16_bmp_);
}
}
@@ -290,7 +297,6 @@ absl::Status Tile16Editor::LoadTile8() {
// Calculate the position in the current gfx data
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);
@@ -310,7 +316,7 @@ absl::Status Tile16Editor::LoadTile8() {
current_gfx_individual_[index].Create(0x08, 0x08, 0x08, tile_data);
RETURN_IF_ERROR(current_gfx_individual_[index].ApplyPaletteWithTransparent(
ow_main_pal_group[0], current_palette_));
rom()->RenderBitmap(&current_gfx_individual_[index]);
Renderer::GetInstance().RenderBitmap(&current_gfx_individual_[index]);
}
map_blockset_loaded_ = true;
@@ -318,8 +324,17 @@ absl::Status Tile16Editor::LoadTile8() {
return absl::OkStatus();
}
// ============================================================================
// Tile16 Transfer
absl::Status Tile16Editor::SetCurrentTile(int id) {
current_tile16_ = id;
current_tile16_bmp_ = tile16_individual_[id];
auto ow_main_pal_group = rom()->palette_group().overworld_main;
RETURN_IF_ERROR(
current_tile16_bmp_.ApplyPalette(ow_main_pal_group[current_palette_]));
Renderer::GetInstance().RenderBitmap(&current_tile16_bmp_);
return absl::OkStatus();
}
#pragma mark - Tile16Transfer
absl::Status Tile16Editor::UpdateTile16Transfer() {
if (BeginTabItem("Tile16 Transfer")) {
@@ -363,16 +378,15 @@ absl::Status Tile16Editor::UpdateTransferTileCanvas() {
// TODO: Implement tile16 transfer
if (transfer_started_ && !transfer_blockset_loaded_) {
PRINT_IF_ERROR(transfer_rom_.LoadAllGraphicsData())
graphics_bin_ = transfer_rom_.graphics_bin();
// Load the Link to the Past overworld.
PRINT_IF_ERROR(transfer_overworld_.Load(transfer_rom_))
transfer_overworld_.set_current_map(0);
palette_ = transfer_overworld_.AreaPalette();
palette_ = transfer_overworld_.current_area_palette();
// Create the tile16 blockset image
RETURN_IF_ERROR(rom()->CreateAndRenderBitmap(
0x80, 0x2000, 0x80, transfer_overworld_.Tile16Blockset(),
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
0x80, 0x2000, 0x80, transfer_overworld_.tile16_blockset_data(),
transfer_blockset_bmp_, palette_));
transfer_blockset_loaded_ = true;
}
@@ -385,16 +399,6 @@ absl::Status Tile16Editor::UpdateTransferTileCanvas() {
return absl::OkStatus();
}
absl::Status Tile16Editor::SetCurrentTile(int id) {
current_tile16_ = id;
current_tile16_bmp_ = &tile16_individual_[id];
auto ow_main_pal_group = rom()->palette_group().overworld_main;
RETURN_IF_ERROR(
current_tile16_bmp_->ApplyPalette(ow_main_pal_group[current_palette_]));
rom()->RenderBitmap(current_tile16_bmp_);
return absl::OkStatus();
}
} // namespace editor
} // namespace app
} // namespace yaze

View File

@@ -1,23 +1,16 @@
#ifndef YAZE_APP_EDITOR_TILE16EDITOR_H
#define YAZE_APP_EDITOR_TILE16EDITOR_H
#include "imgui/imgui.h"
#include <cmath>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/core/common.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/editor/utils/editor.h"
#include "app/editor/utils/gfx_context.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gfx/tilesheet.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/rom.h"
#include "app/zelda3/overworld/overworld.h"
#include "imgui/imgui.h"
namespace yaze {
namespace app {
@@ -26,17 +19,17 @@ namespace editor {
/**
* @brief Popup window to edit Tile16 data
*/
class Tile16Editor : public context::GfxContext, public SharedRom {
class Tile16Editor : public GfxContext, public SharedRom {
public:
absl::Status InitBlockset(gfx::Bitmap* tile16_blockset_bmp,
gfx::Bitmap current_gfx_bmp,
absl::Status InitBlockset(const gfx::Bitmap& tile16_blockset_bmp,
const gfx::Bitmap& current_gfx_bmp,
const std::vector<gfx::Bitmap>& tile16_individual,
uint8_t all_tiles_types[0x200]);
absl::Status Update();
absl::Status DrawMenu();
absl::Status DrawTile16Editor();
void DrawTile16Editor();
absl::Status UpdateTile16Transfer();
absl::Status UpdateBlockset();
@@ -75,38 +68,32 @@ class Tile16Editor : public context::GfxContext, public SharedRom {
// Tile16 blockset for selecting the tile to edit
gui::Canvas blockset_canvas_{"blocksetCanvas", ImVec2(0x100, 0x4000),
gui::CanvasGridSize::k32x32};
gfx::Bitmap* tile16_blockset_bmp_;
gfx::Bitmap tile16_blockset_bmp_;
// Canvas for editing the selected tile
gui::Canvas tile16_edit_canvas_{"Tile16EditCanvas", ImVec2(0x40, 0x40),
gui::CanvasGridSize::k64x64};
gfx::Bitmap* current_tile16_bmp_;
gfx::Bitmap current_tile16_bmp_;
// Tile8 canvas to get the tile to drawing in the tile16_edit_canvas_
gui::Canvas tile8_source_canvas_{
"Tile8SourceCanvas",
ImVec2(core::kTilesheetWidth * 4, core::kTilesheetHeight * 0x10 * 4),
ImVec2(gfx::kTilesheetWidth * 4, gfx::kTilesheetHeight * 0x10 * 4),
gui::CanvasGridSize::k32x32};
gfx::Bitmap current_gfx_bmp_;
gui::Canvas transfer_canvas_;
gfx::Bitmap transfer_blockset_bmp_;
std::vector<Bytes> tile16_individual_data_;
std::vector<gfx::Bitmap> tile16_individual_;
std::vector<gfx::Bitmap> current_gfx_individual_;
std::vector<uint8_t> current_tile16_data_;
std::vector<uint8_t> tile8_gfx_data_;
PaletteEditor palette_editor_;
gfx::SnesPalette palette_;
zelda3::overworld::Overworld transfer_overworld_;
gfx::BitmapTable graphics_bin_;
absl::Status status_;
Rom transfer_rom_;
absl::Status transfer_status_;
@@ -115,4 +102,4 @@ class Tile16Editor : public context::GfxContext, public SharedRom {
} // namespace editor
} // namespace app
} // namespace yaze
#endif // YAZE_APP_EDITOR_TILE16EDITOR_H
#endif // YAZE_APP_EDITOR_TILE16EDITOR_H