Add OverworldMap tile editing
This commit is contained in:
@@ -83,11 +83,11 @@ void ButtonPipe(absl::string_view button_text, std::function<void()> callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitmapCanvasPipeline(int width, int height, int tile_size, bool is_loaded,
|
void BitmapCanvasPipeline(gui::Canvas& canvas, gfx::Bitmap& bitmap, int width,
|
||||||
gfx::Bitmap& bitmap, bool scrollbar, int canvas_id) {
|
int height, int tile_size, bool is_loaded,
|
||||||
gui::Canvas canvas;
|
bool scrollbar, int canvas_id) {
|
||||||
|
auto draw_canvas = [](gui::Canvas& canvas, gfx::Bitmap& bitmap, int width,
|
||||||
auto draw_canvas = [&]() {
|
int height, int tile_size, bool is_loaded) {
|
||||||
canvas.DrawBackground(ImVec2(width + 1, height + 1));
|
canvas.DrawBackground(ImVec2(width + 1, height + 1));
|
||||||
canvas.DrawContextMenu();
|
canvas.DrawContextMenu();
|
||||||
canvas.DrawBitmap(bitmap, 2, is_loaded);
|
canvas.DrawBitmap(bitmap, 2, is_loaded);
|
||||||
@@ -100,11 +100,11 @@ void BitmapCanvasPipeline(int width, int height, int tile_size, bool is_loaded,
|
|||||||
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)canvas_id);
|
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)canvas_id);
|
||||||
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
|
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
|
||||||
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
draw_canvas();
|
draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
} else {
|
} else {
|
||||||
draw_canvas();
|
draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "app/core/constants.h"
|
#include "app/core/constants.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/gui/canvas.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
@@ -28,8 +29,9 @@ void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
|
|||||||
|
|
||||||
void ButtonPipe(absl::string_view button_text, std::function<void()> callback);
|
void ButtonPipe(absl::string_view button_text, std::function<void()> callback);
|
||||||
|
|
||||||
void BitmapCanvasPipeline(int width, int height, int tile_size, bool is_loaded,
|
void BitmapCanvasPipeline(gui::Canvas& canvas, gfx::Bitmap& bitmap, int width,
|
||||||
gfx::Bitmap& bitmap, bool scrollbar, int canvas_id);
|
int height, int tile_size, bool is_loaded,
|
||||||
|
bool scrollbar, int canvas_id);
|
||||||
|
|
||||||
void BuildAndRenderBitmapPipeline(int width, int height, int depth, Bytes data,
|
void BuildAndRenderBitmapPipeline(int width, int height, int depth, Bytes data,
|
||||||
ROM& z3_rom, gfx::Bitmap& bitmap,
|
ROM& z3_rom, gfx::Bitmap& bitmap,
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include "app/gui/style.h"
|
#include "app/gui/style.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
@@ -33,25 +35,24 @@ absl::Status GraphicsEditor::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
|
BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
|
||||||
SETUP_COLUMN("Graphics (BIN, CGX, SCR)")
|
SETUP_COLUMN("File Import (BIN, CGX, ROM)")
|
||||||
SETUP_COLUMN("Palette (COL)")
|
SETUP_COLUMN("Palette (COL)")
|
||||||
ImGui::TableSetupColumn("Maps and Animations (SCR, PNL)",
|
ImGui::TableSetupColumn("Tilemaps and Objects (SCR, PNL, OBJ)",
|
||||||
ImGuiTableColumnFlags_WidthFixed);
|
ImGuiTableColumnFlags_WidthFixed);
|
||||||
SETUP_COLUMN("Preview")
|
SETUP_COLUMN("Graphics Preview")
|
||||||
TABLE_HEADERS()
|
TABLE_HEADERS()
|
||||||
NEXT_COLUMN()
|
NEXT_COLUMN() {
|
||||||
|
status_ = DrawCgxImport();
|
||||||
|
status_ = DrawClipboardImport();
|
||||||
|
status_ = DrawFileImport();
|
||||||
|
status_ = DrawExperimentalFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
status_ = DrawCgxImport();
|
NEXT_COLUMN() { status_ = DrawPaletteControls(); }
|
||||||
status_ = DrawClipboardImport();
|
|
||||||
status_ = DrawFileImport();
|
|
||||||
status_ = DrawExperimentalFeatures();
|
|
||||||
|
|
||||||
NEXT_COLUMN()
|
NEXT_COLUMN()
|
||||||
status_ = DrawPaletteControls();
|
core::BitmapCanvasPipeline(scr_canvas_, scr_bitmap_, 0x200, 0x200, 0x20,
|
||||||
|
scr_loaded_, false, 0);
|
||||||
NEXT_COLUMN()
|
|
||||||
core::BitmapCanvasPipeline(0x200, 0x200, 0x20, scr_loaded_, scr_bitmap_,
|
|
||||||
false, 0);
|
|
||||||
status_ = DrawScrImport();
|
status_ = DrawScrImport();
|
||||||
|
|
||||||
NEXT_COLUMN()
|
NEXT_COLUMN()
|
||||||
@@ -69,12 +70,12 @@ absl::Status GraphicsEditor::Update() {
|
|||||||
super_donkey_, graphics_bin_);
|
super_donkey_, graphics_bin_);
|
||||||
} else if (cgx_loaded_ && col_file_) {
|
} else if (cgx_loaded_ && col_file_) {
|
||||||
// Load the CGX graphics
|
// Load the CGX graphics
|
||||||
core::BitmapCanvasPipeline(0x100, 16384, 0x20, cgx_loaded_, cgx_bitmap_,
|
core::BitmapCanvasPipeline(import_canvas_, cgx_bitmap_, 0x100, 16384, 0x20,
|
||||||
true, 5);
|
cgx_loaded_, true, 5);
|
||||||
} else {
|
} else {
|
||||||
// Load the BIN/Clipboard Graphics
|
// Load the BIN/Clipboard Graphics
|
||||||
core::BitmapCanvasPipeline(0x100, 16384, 0x20, gfx_loaded_, bitmap_, true,
|
core::BitmapCanvasPipeline(import_canvas_, bitmap_, 0x100, 16384, 0x20,
|
||||||
2);
|
gfx_loaded_, true, 2);
|
||||||
}
|
}
|
||||||
END_TABLE()
|
END_TABLE()
|
||||||
|
|
||||||
@@ -124,7 +125,7 @@ absl::Status GraphicsEditor::DrawCgxImport() {
|
|||||||
core::ButtonPipe("Copy CGX Path",
|
core::ButtonPipe("Copy CGX Path",
|
||||||
[this]() { ImGui::SetClipboardText(cgx_file_path_); });
|
[this]() { ImGui::SetClipboardText(cgx_file_path_); });
|
||||||
|
|
||||||
core::ButtonPipe("Decompress CGX Data", [this]() {
|
core::ButtonPipe("Load CGX Data", [this]() {
|
||||||
status_ = gfx::LoadCgx(current_bpp_, cgx_file_path_, cgx_data_,
|
status_ = gfx::LoadCgx(current_bpp_, cgx_file_path_, cgx_data_,
|
||||||
decoded_cgx_, extra_cgx_data_);
|
decoded_cgx_, extra_cgx_data_);
|
||||||
cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_);
|
cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_);
|
||||||
@@ -217,6 +218,49 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status GraphicsEditor::DrawObjImport() {
|
||||||
|
gui::TextWithSeparators("OBJ Import");
|
||||||
|
|
||||||
|
ImGui::InputText("##ObjFile", obj_file_path_, sizeof(obj_file_path_));
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
core::FileDialogPipeline(
|
||||||
|
"ImportObjKey", ".obj,.OBJ,.bak,.BAK\0", "Open OBJ", [this]() {
|
||||||
|
strncpy(file_path_,
|
||||||
|
ImGuiFileDialog::Instance()->GetFilePathName().c_str(),
|
||||||
|
sizeof(file_path_));
|
||||||
|
status_ = temp_rom_.LoadFromFile(file_path_);
|
||||||
|
is_open_ = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status GraphicsEditor::DrawTilemapImport() {
|
||||||
|
gui::TextWithSeparators("Tilemap Import");
|
||||||
|
|
||||||
|
ImGui::InputText("##TMapFile", tilemap_file_path_,
|
||||||
|
sizeof(tilemap_file_path_));
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
core::FileDialogPipeline(
|
||||||
|
"ImportTilemapKey", ".DAT,.dat,.BIN,.bin,.hex,.HEX\0", "Open Tilemap",
|
||||||
|
[this]() {
|
||||||
|
strncpy(tilemap_file_path_,
|
||||||
|
ImGuiFileDialog::Instance()->GetFilePathName().c_str(),
|
||||||
|
sizeof(tilemap_file_path_));
|
||||||
|
status_ = tilemap_rom_.LoadFromFile(tilemap_file_path_);
|
||||||
|
|
||||||
|
// Extract the high and low bytes from the file.
|
||||||
|
auto decomp_sheet = gfx::lc_lz2::DecompressV2(
|
||||||
|
tilemap_rom_.data(), gfx::lc_lz2::kNintendoMode1);
|
||||||
|
tilemap_loaded_ = true;
|
||||||
|
is_open_ = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
absl::Status GraphicsEditor::DrawFileImport() {
|
absl::Status GraphicsEditor::DrawFileImport() {
|
||||||
gui::TextWithSeparators("BIN Import");
|
gui::TextWithSeparators("BIN Import");
|
||||||
|
|
||||||
@@ -290,8 +334,7 @@ absl::Status GraphicsEditor::DrawExperimentalFeatures() {
|
|||||||
}
|
}
|
||||||
ImGui::SetItemTooltip(
|
ImGui::SetItemTooltip(
|
||||||
"Requires `super_donkey_1.bin` to be imported under the "
|
"Requires `super_donkey_1.bin` to be imported under the "
|
||||||
"BIN import "
|
"BIN import section.");
|
||||||
"section.");
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,11 +357,11 @@ absl::Status GraphicsEditor::DecompressImportData(int size) {
|
|||||||
|
|
||||||
if (rom()->isLoaded()) {
|
if (rom()->isLoaded()) {
|
||||||
auto palette_group = rom()->GetPaletteGroup("ow_main");
|
auto palette_group = rom()->GetPaletteGroup("ow_main");
|
||||||
palette_ = palette_group[current_palette_];
|
z3_rom_palette_ = palette_group[current_palette_];
|
||||||
if (col_file_) {
|
if (col_file_) {
|
||||||
bitmap_.ApplyPalette(col_file_palette_);
|
bitmap_.ApplyPalette(col_file_palette_);
|
||||||
} else {
|
} else {
|
||||||
bitmap_.ApplyPalette(palette_);
|
bitmap_.ApplyPalette(z3_rom_palette_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,8 +390,8 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
|
|||||||
// ROM palette
|
// ROM palette
|
||||||
auto palette_group =
|
auto palette_group =
|
||||||
rom()->GetPaletteGroup(kPaletteGroupAddressesKeys[current_palette_]);
|
rom()->GetPaletteGroup(kPaletteGroupAddressesKeys[current_palette_]);
|
||||||
palette_ = palette_group[current_palette_index_];
|
z3_rom_palette_ = palette_group[current_palette_index_];
|
||||||
graphics_bin_[i].ApplyPalette(palette_);
|
graphics_bin_[i].ApplyPalette(z3_rom_palette_);
|
||||||
}
|
}
|
||||||
|
|
||||||
rom()->RenderBitmap(&graphics_bin_[i]);
|
rom()->RenderBitmap(&graphics_bin_[i]);
|
||||||
@@ -372,8 +415,8 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
|
|||||||
// ROM palette
|
// ROM palette
|
||||||
auto palette_group =
|
auto palette_group =
|
||||||
rom()->GetPaletteGroup(kPaletteGroupAddressesKeys[current_palette_]);
|
rom()->GetPaletteGroup(kPaletteGroupAddressesKeys[current_palette_]);
|
||||||
palette_ = palette_group[current_palette_index_];
|
z3_rom_palette_ = palette_group[current_palette_index_];
|
||||||
graphics_bin_[i].ApplyPalette(palette_);
|
graphics_bin_[i].ApplyPalette(z3_rom_palette_);
|
||||||
}
|
}
|
||||||
|
|
||||||
rom()->RenderBitmap(&graphics_bin_[i]);
|
rom()->RenderBitmap(&graphics_bin_[i]);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/gui/input.h"
|
#include "app/gui/input.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
#include "app/zelda3/overworld.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -65,9 +66,13 @@ class GraphicsEditor : public SharedROM {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
absl::Status DrawToolset();
|
absl::Status DrawToolset();
|
||||||
|
|
||||||
absl::Status DrawCgxImport();
|
absl::Status DrawCgxImport();
|
||||||
absl::Status DrawScrImport();
|
absl::Status DrawScrImport();
|
||||||
absl::Status DrawFileImport();
|
absl::Status DrawFileImport();
|
||||||
|
absl::Status DrawObjImport();
|
||||||
|
absl::Status DrawTilemapImport();
|
||||||
|
|
||||||
absl::Status DrawPaletteControls();
|
absl::Status DrawPaletteControls();
|
||||||
absl::Status DrawClipboardImport();
|
absl::Status DrawClipboardImport();
|
||||||
absl::Status DrawExperimentalFeatures();
|
absl::Status DrawExperimentalFeatures();
|
||||||
@@ -77,9 +82,9 @@ class GraphicsEditor : public SharedROM {
|
|||||||
|
|
||||||
absl::Status DecompressSuperDonkey();
|
absl::Status DecompressSuperDonkey();
|
||||||
|
|
||||||
|
int current_palette_ = 0;
|
||||||
uint64_t current_offset_ = 0;
|
uint64_t current_offset_ = 0;
|
||||||
uint64_t current_size_ = 0;
|
uint64_t current_size_ = 0;
|
||||||
int current_palette_ = 0;
|
|
||||||
uint64_t current_palette_index_ = 0;
|
uint64_t current_palette_index_ = 0;
|
||||||
|
|
||||||
int current_bpp_ = 0;
|
int current_bpp_ = 0;
|
||||||
@@ -95,12 +100,17 @@ class GraphicsEditor : public SharedROM {
|
|||||||
|
|
||||||
bool refresh_graphics_ = false;
|
bool refresh_graphics_ = false;
|
||||||
bool open_memory_editor_ = false;
|
bool open_memory_editor_ = false;
|
||||||
|
|
||||||
bool gfx_loaded_ = false;
|
bool gfx_loaded_ = false;
|
||||||
bool is_open_ = false;
|
bool is_open_ = false;
|
||||||
bool super_donkey_ = false;
|
bool super_donkey_ = false;
|
||||||
|
|
||||||
bool col_file_ = false;
|
bool col_file_ = false;
|
||||||
bool cgx_loaded_ = false;
|
bool cgx_loaded_ = false;
|
||||||
bool scr_loaded_ = false;
|
bool scr_loaded_ = false;
|
||||||
|
bool obj_loaded_ = false;
|
||||||
|
|
||||||
|
bool tilemap_loaded_ = false;
|
||||||
|
|
||||||
char file_path_[256] = "";
|
char file_path_[256] = "";
|
||||||
char col_file_path_[256] = "";
|
char col_file_path_[256] = "";
|
||||||
@@ -112,7 +122,14 @@ class GraphicsEditor : public SharedROM {
|
|||||||
char scr_file_path_[256] = "";
|
char scr_file_path_[256] = "";
|
||||||
char scr_file_name_[256] = "";
|
char scr_file_name_[256] = "";
|
||||||
|
|
||||||
|
char obj_file_path_[256] = "";
|
||||||
|
|
||||||
|
char tilemap_file_path_[256] = "";
|
||||||
|
char tilemap_file_name_[256] = "";
|
||||||
|
|
||||||
ROM temp_rom_;
|
ROM temp_rom_;
|
||||||
|
ROM tilemap_rom_;
|
||||||
|
|
||||||
Bytes import_data_;
|
Bytes import_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
|
|
||||||
@@ -124,6 +141,8 @@ class GraphicsEditor : public SharedROM {
|
|||||||
std::vector<uint8_t> scr_data_;
|
std::vector<uint8_t> scr_data_;
|
||||||
std::vector<uint8_t> decoded_scr_data_;
|
std::vector<uint8_t> decoded_scr_data_;
|
||||||
|
|
||||||
|
zelda3::Overworld overworld_;
|
||||||
|
|
||||||
MemoryEditor cgx_memory_editor_;
|
MemoryEditor cgx_memory_editor_;
|
||||||
MemoryEditor col_memory_editor_;
|
MemoryEditor col_memory_editor_;
|
||||||
|
|
||||||
@@ -135,6 +154,8 @@ class GraphicsEditor : public SharedROM {
|
|||||||
gfx::Bitmap bitmap_;
|
gfx::Bitmap bitmap_;
|
||||||
gui::Canvas import_canvas_;
|
gui::Canvas import_canvas_;
|
||||||
|
|
||||||
|
gui::Canvas scr_canvas_;
|
||||||
|
|
||||||
gui::Canvas super_donkey_canvas_;
|
gui::Canvas super_donkey_canvas_;
|
||||||
gfx::BitmapTable graphics_bin_;
|
gfx::BitmapTable graphics_bin_;
|
||||||
|
|
||||||
@@ -142,7 +163,7 @@ class GraphicsEditor : public SharedROM {
|
|||||||
|
|
||||||
gfx::PaletteGroup col_file_palette_group_;
|
gfx::PaletteGroup col_file_palette_group_;
|
||||||
|
|
||||||
gfx::SNESPalette palette_;
|
gfx::SNESPalette z3_rom_palette_;
|
||||||
gfx::SNESPalette col_file_palette_;
|
gfx::SNESPalette col_file_palette_;
|
||||||
|
|
||||||
absl::Status status_;
|
absl::Status status_;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/gui/input.h"
|
#include "app/gui/input.h"
|
||||||
#include "app/gui/style.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"
|
||||||
|
|
||||||
@@ -194,14 +195,68 @@ void OverworldEditor::DrawOverworldSprites() {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void OverworldEditor::DrawOverworldEdits() const {
|
void OverworldEditor::DrawOverworldEdits() {
|
||||||
auto mouse_position = ow_map_canvas_.GetCurrentDrawnTilePosition();
|
auto mouse_position = ow_map_canvas_.GetCurrentDrawnTilePosition();
|
||||||
auto canvas_size = ow_map_canvas_.GetCanvasSize();
|
auto canvas_size = ow_map_canvas_.GetCanvasSize();
|
||||||
int x = mouse_position.x / canvas_size.x;
|
int x = mouse_position.x / canvas_size.x;
|
||||||
int y = mouse_position.y / canvas_size.y;
|
int y = mouse_position.y / canvas_size.y;
|
||||||
auto index = x + (y * 64);
|
auto index = x + (y * 64);
|
||||||
|
|
||||||
std::cout << "==> " << index << std::endl;
|
// Determine which overworld map the user is currently editing.
|
||||||
|
DetermineActiveMap(mouse_position);
|
||||||
|
|
||||||
|
// Render the updated map bitmap.
|
||||||
|
RenderUpdatedMapBitmap(mouse_position,
|
||||||
|
tile16_individual_data_[current_tile16_]);
|
||||||
|
|
||||||
|
// Queue up the raw ROM changes.
|
||||||
|
QueueROMChanges(index, current_tile16_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::RenderUpdatedMapBitmap(const ImVec2 &click_position,
|
||||||
|
const Bytes &tile_data) {
|
||||||
|
// 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) / tile_size;
|
||||||
|
int tile_index_y = static_cast<int>(click_position.y) / 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;
|
||||||
|
|
||||||
|
// Get the current map's bitmap from the BitmapTable
|
||||||
|
gfx::Bitmap ¤t_bitmap = maps_bmp_[current_map_];
|
||||||
|
|
||||||
|
// 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_bitmap.width() +
|
||||||
|
(start_position.x + x);
|
||||||
|
current_bitmap.WriteToPixel(pixel_index, tile_data[y * tile_size + x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the updated bitmap to the canvas
|
||||||
|
rom()->RenderBitmap(¤t_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::QueueROMChanges(int index, ushort new_tile16) {
|
||||||
|
// Store the changes made by the user to the ROM (or project file)
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::DetermineActiveMap(const ImVec2 &mouse_position) {
|
||||||
|
// Assuming each small map is 256x256 pixels (adjust as needed)
|
||||||
|
constexpr int small_map_size = 512;
|
||||||
|
|
||||||
|
// Calculate which small map the mouse is currently over
|
||||||
|
int map_x = mouse_position.x / small_map_size;
|
||||||
|
int map_y = mouse_position.y / small_map_size;
|
||||||
|
|
||||||
|
// Calculate the index of the map in the `maps_bmp_` vector
|
||||||
|
current_map_ = map_x + map_y * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -225,8 +280,7 @@ void OverworldEditor::DrawOverworldCanvas() {
|
|||||||
if (!blockset_canvas_.Points().empty()) {
|
if (!blockset_canvas_.Points().empty()) {
|
||||||
int x = blockset_canvas_.Points().front().x / 32;
|
int x = blockset_canvas_.Points().front().x / 32;
|
||||||
int y = blockset_canvas_.Points().front().y / 32;
|
int y = blockset_canvas_.Points().front().y / 32;
|
||||||
current_tile16_ = x + (y * 0x10);
|
current_tile16_ = x + (y * 8);
|
||||||
|
|
||||||
if (ow_map_canvas_.DrawTilePainter(tile16_individual_[current_tile16_],
|
if (ow_map_canvas_.DrawTilePainter(tile16_individual_[current_tile16_],
|
||||||
16)) {
|
16)) {
|
||||||
// Update the overworld map.
|
// Update the overworld map.
|
||||||
@@ -272,8 +326,9 @@ void OverworldEditor::DrawTileSelector() {
|
|||||||
if (ImGui::BeginTabBar(kTileSelectorTab.data(),
|
if (ImGui::BeginTabBar(kTileSelectorTab.data(),
|
||||||
ImGuiTabBarFlags_FittingPolicyScroll)) {
|
ImGuiTabBarFlags_FittingPolicyScroll)) {
|
||||||
if (ImGui::BeginTabItem("Tile16")) {
|
if (ImGui::BeginTabItem("Tile16")) {
|
||||||
core::BitmapCanvasPipeline(0x100, (8192 * 2), 0x20, map_blockset_loaded_,
|
core::BitmapCanvasPipeline(blockset_canvas_, tile16_blockset_bmp_, 0x100,
|
||||||
tile16_blockset_bmp_, true, 1);
|
(8192 * 2), 0x20, map_blockset_loaded_, true,
|
||||||
|
1);
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Tile8")) {
|
if (ImGui::BeginTabItem("Tile8")) {
|
||||||
@@ -286,8 +341,9 @@ void OverworldEditor::DrawTileSelector() {
|
|||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Area Graphics")) {
|
if (ImGui::BeginTabItem("Area Graphics")) {
|
||||||
core::BitmapCanvasPipeline(256, 0x10 * 0x40, 0x20, overworld_.isLoaded(),
|
core::BitmapCanvasPipeline(current_gfx_canvas_, current_gfx_bmp_, 256,
|
||||||
current_gfx_bmp_, true, 3);
|
0x10 * 0x40, 0x20, overworld_.isLoaded(), true,
|
||||||
|
3);
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
@@ -319,17 +375,19 @@ absl::Status OverworldEditor::LoadGraphics() {
|
|||||||
// Copy the tile16 data into individual tiles.
|
// Copy the tile16 data into individual tiles.
|
||||||
auto tile16_data = overworld_.Tile16Blockset();
|
auto tile16_data = overworld_.Tile16Blockset();
|
||||||
|
|
||||||
|
std::cout << tile16_data.size() << std::endl;
|
||||||
|
|
||||||
// Loop through the tiles and copy their pixel data into separate vectors
|
// Loop through the tiles and copy their pixel data into separate vectors
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
// Create a new vector for the pixel data of the current tile
|
// Create a new vector for the pixel data of the current tile
|
||||||
Bytes tile_data;
|
Bytes tile_data(16 * 16, 0x00); // More efficient initialization
|
||||||
for (int j = 0; j < 16 * 16; j++) tile_data.push_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 < 16; ty++) {
|
for (int ty = 0; ty < 16; ty++) {
|
||||||
for (int tx = 0; tx < 16; tx++) {
|
for (int tx = 0; tx < 16; tx++) {
|
||||||
int position = (tx + (ty * 0x10));
|
int position = tx + (ty * 0x10);
|
||||||
uchar value = tile16_data[i + tx + (ty * 0x80)];
|
uchar value =
|
||||||
|
tile16_data[(i % 8 * 16) + (i / 8 * 16 * 0x80) + (ty * 0x80) + tx];
|
||||||
tile_data[position] = value;
|
tile_data[position] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,20 +447,25 @@ absl::Status OverworldEditor::DrawExperimentalModal() {
|
|||||||
ImGui::InputText("##TilemapFile", &ow_tilemap_filename_);
|
ImGui::InputText("##TilemapFile", &ow_tilemap_filename_);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
core::FileDialogPipeline(
|
core::FileDialogPipeline(
|
||||||
"ImportTilemapsKey", ".CGX,.cgx\0", "Tilemap Hex File", [this]() {
|
"ImportTilemapsKey", ".DAT,.dat\0", "Tilemap Hex File", [this]() {
|
||||||
ow_tilemap_filename_ = ImGuiFileDialog::Instance()->GetFilePathName();
|
ow_tilemap_filename_ = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::InputText("##Tile32ConfigurationFile",
|
ImGui::InputText("##Tile32ConfigurationFile",
|
||||||
&tile32_configuration_filename_);
|
&tile32_configuration_filename_);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
core::FileDialogPipeline("ImportTile32Key", ".CGX,.cgx\0", "Tile32 Hex File",
|
core::FileDialogPipeline("ImportTile32Key", ".DAT,.dat\0", "Tile32 Hex File",
|
||||||
[this]() {
|
[this]() {
|
||||||
tile32_configuration_filename_ =
|
tile32_configuration_filename_ =
|
||||||
ImGuiFileDialog::Instance()->GetFilePathName();
|
ImGuiFileDialog::Instance()->GetFilePathName();
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::Button("Load Prototype Overworld with ROM graphics");
|
if (ImGui::Button("Load Prototype Overworld with ROM graphics")) {
|
||||||
|
if (rom()->isLoaded() && !all_gfx_loaded_) {
|
||||||
|
RETURN_IF_ERROR(LoadGraphics())
|
||||||
|
all_gfx_loaded_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gui::TextWithSeparators("Configuration");
|
gui::TextWithSeparators("Configuration");
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,13 @@ class OverworldEditor : public Editor, public SharedROM {
|
|||||||
void DrawOverworldEntrances();
|
void DrawOverworldEntrances();
|
||||||
void DrawOverworldMaps();
|
void DrawOverworldMaps();
|
||||||
void DrawOverworldSprites();
|
void DrawOverworldSprites();
|
||||||
void DrawOverworldEdits() const;
|
|
||||||
|
void DrawOverworldEdits();
|
||||||
|
void RenderUpdatedMapBitmap(const ImVec2 &click_position,
|
||||||
|
const Bytes &tile_data);
|
||||||
|
void QueueROMChanges(int index, ushort new_tile16);
|
||||||
|
void DetermineActiveMap(const ImVec2 &mouse_position);
|
||||||
|
|
||||||
void DrawOverworldCanvas();
|
void DrawOverworldCanvas();
|
||||||
|
|
||||||
void DrawTile8Selector();
|
void DrawTile8Selector();
|
||||||
|
|||||||
@@ -3,15 +3,12 @@
|
|||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "app/gfx/snes_palette.h"
|
#include "app/gfx/snes_palette.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
@@ -33,6 +30,49 @@ struct PaletteChange {
|
|||||||
size_t paletteIndex;
|
size_t paletteIndex;
|
||||||
size_t colorIndex;
|
size_t colorIndex;
|
||||||
gfx::SNESColor originalColor;
|
gfx::SNESColor originalColor;
|
||||||
|
gfx::SNESColor newColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the new change
|
||||||
|
recentChanges.push_back(
|
||||||
|
{groupName, paletteIndex, colorIndex, originalColor, newColor});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get recent changes for display in the palette editor
|
||||||
|
const std::deque<PaletteChange>& GetRecentChanges() const {
|
||||||
|
return recentChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the original color
|
||||||
|
gfx::SNESColor GetOriginalColor(const std::string& groupName,
|
||||||
|
size_t paletteIndex,
|
||||||
|
size_t colorIndex) const {
|
||||||
|
for (const auto& change : recentChanges) {
|
||||||
|
if (change.groupName == groupName &&
|
||||||
|
change.paletteIndex == paletteIndex &&
|
||||||
|
change.colorIndex == colorIndex) {
|
||||||
|
return change.originalColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Handle error or return default (this is just an example,
|
||||||
|
// handle as appropriate for your application)
|
||||||
|
return gfx::SNESColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::deque<PaletteChange> recentChanges;
|
||||||
|
static const size_t maxHistorySize = 50; // or any other number you deem fit
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaletteEditor : public SharedROM {
|
class PaletteEditor : public SharedROM {
|
||||||
@@ -42,7 +82,6 @@ class PaletteEditor : public SharedROM {
|
|||||||
void EditColorInPalette(gfx::SNESPalette& palette, int index);
|
void EditColorInPalette(gfx::SNESPalette& palette, int index);
|
||||||
void ResetColorToOriginal(gfx::SNESPalette& palette, int index,
|
void ResetColorToOriginal(gfx::SNESPalette& palette, int index,
|
||||||
const gfx::SNESPalette& originalPalette);
|
const gfx::SNESPalette& originalPalette);
|
||||||
|
|
||||||
void DisplayPalette(gfx::SNESPalette& palette, bool loaded);
|
void DisplayPalette(gfx::SNESPalette& palette, bool loaded);
|
||||||
|
|
||||||
void DrawPortablePalette(gfx::SNESPalette& palette);
|
void DrawPortablePalette(gfx::SNESPalette& palette);
|
||||||
@@ -60,7 +99,7 @@ class PaletteEditor : public SharedROM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stack<PaletteChange> changeHistory;
|
PaletteEditorHistory history_;
|
||||||
|
|
||||||
ImVec4 saved_palette_[256] = {};
|
ImVec4 saved_palette_[256] = {};
|
||||||
ImVec4 current_color_;
|
ImVec4 current_color_;
|
||||||
|
|||||||
@@ -704,6 +704,11 @@ absl::StatusOr<Bytes> DecompressOverworld(const uchar* data, int pos,
|
|||||||
return DecompressV2(data, pos, size, kNintendoMode1);
|
return DecompressV2(data, pos, size, kNintendoMode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<Bytes> DecompressOverworld(const std::vector<uint8_t> data,
|
||||||
|
int pos, int size) {
|
||||||
|
return DecompressV2(data.data(), pos, size, kNintendoMode1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lc_lz2
|
} // namespace lc_lz2
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ absl::StatusOr<Bytes> DecompressV2(const uchar* data, int offset,
|
|||||||
int size = 0x800, int mode = 1);
|
int size = 0x800, int mode = 1);
|
||||||
absl::StatusOr<Bytes> DecompressGraphics(const uchar* data, int pos, int size);
|
absl::StatusOr<Bytes> DecompressGraphics(const uchar* data, int pos, int size);
|
||||||
absl::StatusOr<Bytes> DecompressOverworld(const uchar* data, int pos, int size);
|
absl::StatusOr<Bytes> DecompressOverworld(const uchar* data, int pos, int size);
|
||||||
|
absl::StatusOr<Bytes> DecompressOverworld(const std::vector<uint8_t> data, int pos, int size);
|
||||||
|
|
||||||
// Compression V1
|
// Compression V1
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
constexpr uint32_t kRectangleColor = IM_COL32(32, 32, 32, 255);
|
constexpr uint32_t kRectangleColor = IM_COL32(32, 32, 32, 255);
|
||||||
@@ -209,4 +211,5 @@ void Canvas::DrawOverlay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
using app::gfx::Bitmap;
|
using app::gfx::Bitmap;
|
||||||
@@ -83,6 +84,7 @@ class Canvas {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "app/gfx/snes_palette.h"
|
#include "app/gfx/snes_palette.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded) {
|
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded) {
|
||||||
@@ -83,4 +85,5 @@ void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -10,11 +10,14 @@
|
|||||||
#include "app/gfx/snes_palette.h"
|
#include "app/gfx/snes_palette.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded);
|
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded);
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
const int kStepOneHex = 0x01;
|
const int kStepOneHex = 0x01;
|
||||||
@@ -67,4 +68,5 @@ void ItemLabel(absl::string_view title, ItemLabelFlags flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
} // namespace yaze
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
constexpr ImVec2 kDefaultModalSize = ImVec2(200, 0);
|
constexpr ImVec2 kDefaultModalSize = ImVec2(200, 0);
|
||||||
@@ -27,6 +28,7 @@ using ItemLabelFlags = enum ItemLabelFlag {
|
|||||||
IMGUI_API void ItemLabel(absl::string_view title, ItemLabelFlags flags);
|
IMGUI_API void ItemLabel(absl::string_view title, ItemLabelFlags flags);
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "imgui/imgui_internal.h"
|
#include "imgui/imgui_internal.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
void TextWithSeparators(const absl::string_view &text) {
|
void TextWithSeparators(const absl::string_view &text) {
|
||||||
@@ -111,4 +113,5 @@ void ColorsYaze() {
|
|||||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
|
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
|
||||||
}
|
}
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
|
||||||
void TextWithSeparators(const absl::string_view& text);
|
void TextWithSeparators(const absl::string_view& text);
|
||||||
@@ -14,6 +15,7 @@ void TextWithSeparators(const absl::string_view& text);
|
|||||||
void ColorsYaze();
|
void ColorsYaze();
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
@@ -93,4 +94,5 @@ TextEditor::LanguageDefinition GetAssemblyLanguageDef() {
|
|||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -2,18 +2,72 @@
|
|||||||
#define YAZE_GUI_WIDGETS_H
|
#define YAZE_GUI_WIDGETS_H
|
||||||
|
|
||||||
#include <ImGuiColorTextEdit/TextEditor.h>
|
#include <ImGuiColorTextEdit/TextEditor.h>
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
|
#include "app/gfx/bitmap.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
TextEditor::LanguageDefinition GetAssemblyLanguageDef();
|
TextEditor::LanguageDefinition GetAssemblyLanguageDef();
|
||||||
|
|
||||||
|
class BitmapViewer {
|
||||||
|
public:
|
||||||
|
BitmapViewer() : current_bitmap_index_(0) {}
|
||||||
|
|
||||||
|
void Display(const std::vector<gfx::Bitmap>& bitmaps) {
|
||||||
|
if (bitmaps.empty()) {
|
||||||
|
ImGui::Text("No bitmaps available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the current bitmap index and total count.
|
||||||
|
ImGui::Text("Viewing Bitmap %d / %zu", current_bitmap_index_ + 1,
|
||||||
|
bitmaps.size());
|
||||||
|
|
||||||
|
// Buttons to navigate through bitmaps.
|
||||||
|
if (ImGui::Button("<- Prev")) {
|
||||||
|
if (current_bitmap_index_ > 0) {
|
||||||
|
--current_bitmap_index_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Next ->")) {
|
||||||
|
if (current_bitmap_index_ < bitmaps.size() - 1) {
|
||||||
|
++current_bitmap_index_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the current bitmap.
|
||||||
|
const gfx::Bitmap& current_bitmap = bitmaps[current_bitmap_index_];
|
||||||
|
// Assuming Bitmap has a function to get its texture ID, and width and
|
||||||
|
// height.
|
||||||
|
ImTextureID tex_id = current_bitmap.texture();
|
||||||
|
ImVec2 size(current_bitmap.width(), current_bitmap.height());
|
||||||
|
ImGui::Image(tex_id, size);
|
||||||
|
|
||||||
|
// Scroll if the image is larger than the display area.
|
||||||
|
if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false,
|
||||||
|
ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||||
|
ImGui::Image(tex_id, size);
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int current_bitmap_index_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/container/flat_hash_map.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
@@ -35,6 +38,57 @@ uint GetOwMapGfxLowPtr(const uchar *rom, int index, uint32_t map_low_ptr) {
|
|||||||
return core::SnesToPc(p2);
|
return core::SnesToPc(p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::flat_hash_map<int, MapData> parseFile(const std::string &filename) {
|
||||||
|
absl::flat_hash_map<int, MapData> resultMap;
|
||||||
|
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "Failed to open file: " << filename << std::endl;
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int currentKey;
|
||||||
|
bool isHigh = true;
|
||||||
|
|
||||||
|
while (getline(file, line)) {
|
||||||
|
// Skip empty or whitespace-only lines
|
||||||
|
if (line.find_first_not_of(" \t\r\n") == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the line starts with "MAPDTH" or "MAPDTL", extract the ID.
|
||||||
|
if (line.find("MAPDTH") == 0) {
|
||||||
|
auto num_str = line.substr(6); // Extract ID after "MAPDTH"
|
||||||
|
currentKey = std::stoi(num_str);
|
||||||
|
isHigh = true;
|
||||||
|
} else if (line.find("MAPDTL") == 0) {
|
||||||
|
auto num_str = line.substr(6); // Extract ID after "MAPDTH"
|
||||||
|
currentKey = std::stoi(num_str);
|
||||||
|
isHigh = false;
|
||||||
|
} else {
|
||||||
|
// Check if the currentKey is already in the map. If not, initialize it.
|
||||||
|
if (resultMap.find(currentKey) == resultMap.end()) {
|
||||||
|
resultMap[currentKey] = MapData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the line by commas and convert to uint8_t.
|
||||||
|
std::stringstream ss(line);
|
||||||
|
std::string valueStr;
|
||||||
|
while (getline(ss, valueStr, ',')) {
|
||||||
|
uint8_t value = std::stoi(valueStr, nullptr, 16);
|
||||||
|
if (isHigh) {
|
||||||
|
resultMap[currentKey].highData.push_back(value);
|
||||||
|
} else {
|
||||||
|
resultMap[currentKey].lowData.push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
absl::Status Overworld::Load(ROM &rom) {
|
absl::Status Overworld::Load(ROM &rom) {
|
||||||
@@ -463,6 +517,39 @@ absl::Status Overworld::DecompressAllMapTiles() {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status Overworld::DecompressProtoMapTiles(const std::string &filename) {
|
||||||
|
proto_map_data_ = parseFile(filename);
|
||||||
|
int sx = 0;
|
||||||
|
int sy = 0;
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 0; i < proto_map_data_.size(); i++) {
|
||||||
|
int ttpos = 0;
|
||||||
|
|
||||||
|
ASSIGN_OR_RETURN(auto bytes, gfx::lc_lz2::DecompressOverworld(
|
||||||
|
proto_map_data_[i].lowData, 0,
|
||||||
|
proto_map_data_[i].lowData.size()))
|
||||||
|
ASSIGN_OR_RETURN(auto bytes2, gfx::lc_lz2::DecompressOverworld(
|
||||||
|
proto_map_data_[i].highData, 0,
|
||||||
|
proto_map_data_[i].highData.size()))
|
||||||
|
OrganizeMapTiles(bytes, bytes2, i, sx, sy, ttpos);
|
||||||
|
|
||||||
|
sx++;
|
||||||
|
if (sx >= 8) {
|
||||||
|
sy++;
|
||||||
|
sx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
c++;
|
||||||
|
if (c >= 64) {
|
||||||
|
sx = 0;
|
||||||
|
sy = 0;
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Overworld::FetchLargeMaps() {
|
void Overworld::FetchLargeMaps() {
|
||||||
@@ -619,13 +706,13 @@ void Overworld::LoadSpritesFromMap(int spriteStart, int spriteCount,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Overworld::LoadPrototype(ROM &rom, std::vector<uint8_t> &tilemap,
|
absl::Status Overworld::LoadPrototype(ROM &rom,
|
||||||
std::vector<uint8_t> tile32) {
|
const std::string &tilemap_filename) {
|
||||||
rom_ = rom;
|
rom_ = rom;
|
||||||
|
|
||||||
AssembleMap32Tiles();
|
AssembleMap32Tiles();
|
||||||
AssembleMap16Tiles();
|
AssembleMap16Tiles();
|
||||||
RETURN_IF_ERROR(DecompressAllMapTiles())
|
RETURN_IF_ERROR(DecompressProtoMapTiles(tilemap_filename))
|
||||||
|
|
||||||
for (int map_index = 0; map_index < kNumOverworldMaps; ++map_index)
|
for (int map_index = 0; map_index < kNumOverworldMaps; ++map_index)
|
||||||
overworld_maps_.emplace_back(map_index, rom_, tiles16);
|
overworld_maps_.emplace_back(map_index, rom_, tiles16);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/container/flat_hash_map.h"
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
@@ -171,6 +172,11 @@ constexpr int LimitOfMap32 = 8864;
|
|||||||
constexpr int NumberOfOWSprites = 352;
|
constexpr int NumberOfOWSprites = 352;
|
||||||
constexpr int NumberOfMap32 = Map32PerScreen * kNumOverworldMaps;
|
constexpr int NumberOfMap32 = Map32PerScreen * kNumOverworldMaps;
|
||||||
|
|
||||||
|
struct MapData {
|
||||||
|
std::vector<uint8_t> highData;
|
||||||
|
std::vector<uint8_t> lowData;
|
||||||
|
};
|
||||||
|
|
||||||
class Overworld {
|
class Overworld {
|
||||||
public:
|
public:
|
||||||
absl::Status Load(ROM &rom);
|
absl::Status Load(ROM &rom);
|
||||||
@@ -189,6 +195,9 @@ class Overworld {
|
|||||||
auto AreaPalette() const {
|
auto AreaPalette() const {
|
||||||
return overworld_maps_[current_map_].AreaPalette();
|
return overworld_maps_[current_map_].AreaPalette();
|
||||||
}
|
}
|
||||||
|
auto AreaPaletteById(int id) const {
|
||||||
|
return overworld_maps_[id].AreaPalette();
|
||||||
|
}
|
||||||
auto BitmapData() const { return overworld_maps_[current_map_].BitmapData(); }
|
auto BitmapData() const { return overworld_maps_[current_map_].BitmapData(); }
|
||||||
auto Tile16Blockset() const {
|
auto Tile16Blockset() const {
|
||||||
return overworld_maps_[current_map_].Tile16Blockset();
|
return overworld_maps_[current_map_].Tile16Blockset();
|
||||||
@@ -197,8 +206,7 @@ class Overworld {
|
|||||||
auto isLoaded() const { return is_loaded_; }
|
auto isLoaded() const { return is_loaded_; }
|
||||||
void SetCurrentMap(int i) { current_map_ = i; }
|
void SetCurrentMap(int i) { current_map_ = i; }
|
||||||
|
|
||||||
absl::Status LoadPrototype(ROM &rom_, std::vector<uint8_t> &tilemap,
|
absl::Status LoadPrototype(ROM &rom_, const std::string &tilemap_filename);
|
||||||
std::vector<uint8_t> tile32);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Dimension {
|
enum Dimension {
|
||||||
@@ -216,13 +224,12 @@ class Overworld {
|
|||||||
void OrganizeMapTiles(Bytes &bytes, Bytes &bytes2, int i, int sx, int sy,
|
void OrganizeMapTiles(Bytes &bytes, Bytes &bytes2, int i, int sx, int sy,
|
||||||
int &ttpos);
|
int &ttpos);
|
||||||
absl::Status DecompressAllMapTiles();
|
absl::Status DecompressAllMapTiles();
|
||||||
|
absl::Status DecompressProtoMapTiles(const std::string &filename);
|
||||||
void FetchLargeMaps();
|
void FetchLargeMaps();
|
||||||
void LoadEntrances();
|
void LoadEntrances();
|
||||||
void LoadSprites();
|
void LoadSprites();
|
||||||
void LoadSpritesFromMap(int spriteStart, int spriteCount, int spriteIndex);
|
void LoadSpritesFromMap(int spriteStart, int spriteCount, int spriteIndex);
|
||||||
|
|
||||||
void LoadOverworldMap();
|
|
||||||
|
|
||||||
int game_state_ = 0;
|
int game_state_ = 0;
|
||||||
int current_map_ = 0;
|
int current_map_ = 0;
|
||||||
uchar map_parent_[160];
|
uchar map_parent_[160];
|
||||||
@@ -238,6 +245,8 @@ class Overworld {
|
|||||||
std::vector<OverworldEntrance> all_entrances_;
|
std::vector<OverworldEntrance> all_entrances_;
|
||||||
std::vector<OverworldEntrance> all_holes_;
|
std::vector<OverworldEntrance> all_holes_;
|
||||||
std::vector<std::vector<Sprite>> all_sprites_;
|
std::vector<std::vector<Sprite>> all_sprites_;
|
||||||
|
|
||||||
|
absl::flat_hash_map<int, MapData> proto_map_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace zelda3
|
} // namespace zelda3
|
||||||
|
|||||||
Reference in New Issue
Block a user