Merge remote-tracking branch 'refs/remotes/origin/master'

Merge changes made on visual studio repo.
This commit is contained in:
scawful
2025-01-06 11:13:29 -05:00
41 changed files with 700 additions and 501 deletions

View File

@@ -109,7 +109,7 @@ absl::Status DungeonEditor::Initialize() {
ASSIGN_OR_RETURN(current_palette_group_,
gfx::CreatePaletteGroupFromLargePalette(full_palette_));
graphics_bin_ = rom()->gfx_sheets();
graphics_bin_ = GraphicsSheetManager::GetInstance().gfx_sheets();
// Create a vector of pointers to the current block bitmaps
for (int block : rooms_[current_room_id_].blocks()) {
room_gfx_sheets_.emplace_back(&graphics_bin_[block]);

View File

@@ -58,19 +58,22 @@ void EditorManager::Initialize(std::string filename) {
absl::Status EditorManager::Update() {
ManageKeyboardShortcuts();
DrawYazeMenu();
DrawStatusPopup();
DrawAboutPopup();
DrawInfoPopup();
DrawMenuBar();
DrawPopups();
if (rom()->is_loaded() && !rom_assets_loaded_) {
RETURN_IF_ERROR(rom()->LoadAllGraphicsData())
auto& sheet_manager = GraphicsSheetManager::GetInstance();
ASSIGN_OR_RETURN(*sheet_manager.mutable_gfx_sheets(),
LoadAllGraphicsData(*rom()))
RETURN_IF_ERROR(overworld_editor_.LoadGraphics());
rom_assets_loaded_ = true;
}
ManageActiveEditors();
if (!current_rom_) {
DrawHomepage();
} else {
ManageActiveEditors();
}
return absl::OkStatus();
}
@@ -296,7 +299,7 @@ void EditorManager::ManageKeyboardShortcuts() {
}
}
void EditorManager::DrawStatusPopup() {
void EditorManager::DrawPopups() {
static absl::Status prev_status;
if (!status_.ok()) {
show_status_ = true;
@@ -322,9 +325,7 @@ void EditorManager::DrawStatusPopup() {
}
End();
}
}
void EditorManager::DrawAboutPopup() {
if (about_) OpenPopup("About");
if (BeginPopupModal("About", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
Text("Yet Another Zelda3 Editor - v%s", version_.c_str());
@@ -339,9 +340,7 @@ void EditorManager::DrawAboutPopup() {
}
EndPopup();
}
}
void EditorManager::DrawInfoPopup() {
if (rom_info_) OpenPopup("ROM Information");
if (BeginPopupModal("ROM Information", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
@@ -357,11 +356,29 @@ void EditorManager::DrawInfoPopup() {
}
}
void EditorManager::DrawYazeMenu() {
void EditorManager::DrawHomepage() {
TextWrapped("Welcome to the Yet Another Zelda3 Editor (yaze)!");
TextWrapped("This editor is designed to be a comprehensive tool for editing the Legend of Zelda: A Link to the Past.");
TextWrapped("The editor is still in development, so please report any bugs or issues you encounter.");
static bool managed_startup = false;
if (Button("Open ROM", ImVec2(200, 0))) {
LoadRom();
}
SameLine();
ImGui::Checkbox("Manage Startup", &managed_startup);
Separator();
settings_editor_.Update();
}
void EditorManager::DrawMenuBar() {
static bool show_display_settings = false;
if (BeginMenuBar()) {
DrawYazeMenuBar();
DrawMenuContent();
SameLine(GetWindowWidth() - GetStyle().ItemSpacing.x -
CalcTextSize(ICON_MD_DISPLAY_SETTINGS).x - 110);
PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
@@ -380,7 +397,7 @@ void EditorManager::DrawYazeMenu() {
}
}
void EditorManager::DrawYazeMenuBar() {
void EditorManager::DrawMenuContent() {
static bool save_as_menu = false;
static bool new_project_menu = false;
@@ -445,11 +462,23 @@ void EditorManager::DrawYazeMenuBar() {
MenuItem("Backup ROM", "", &backup_rom_);
MenuItem("Save New Auto", "", &save_new_auto_);
Separator();
if (BeginMenu("Experiment Flags")) {
static FlagsMenu flags_menu;
flags_menu.Draw();
static FlagsMenu flags_menu;
if (BeginMenu("System Flags")) {
flags_menu.DrawSystemFlags();
EndMenu();
}
if (BeginMenu("Overworld Flags")) {
flags_menu.DrawOverworldFlags();
EndMenu();
}
if (BeginMenu("Dungeon Flags")) {
flags_menu.DrawDungeonFlags();
EndMenu();
}
if (BeginMenu("Resource Flags")) {
flags_menu.DrawResourceFlags();
EndMenu();
}
EndMenu();
}
@@ -671,10 +700,25 @@ void EditorManager::DrawYazeMenuBar() {
}
}
void EditorManager::DrawRomMenu() {
if (roms_.empty()) return;
// Dropdown in the center of the menu bar with ROMs
if (BeginMenu("ROM")) {
for (size_t i = 0; i < roms_.size(); ++i) {
if (MenuItem(roms_[i]->title().c_str())) {
current_rom_ = roms_[i].get();
}
}
EndMenu();
}
}
void EditorManager::LoadRom() {
auto file_name = FileDialogWrapper::ShowOpenFileDialog();
auto load_rom = rom()->LoadFromFile(file_name);
if (load_rom.ok()) {
current_rom_ = rom();
static RecentFilesManager manager("recent_files.txt");
manager.Load();
manager.AddFile(file_name);
@@ -691,6 +735,10 @@ void EditorManager::SaveRom() {
status_ = overworld_editor_.Save();
RETURN_VOID_IF_ERROR(status_);
if (core::ExperimentFlags::get().kSaveGraphicsSheet)
PRINT_IF_ERROR(SaveAllGraphicsData(*rom(),
GraphicsSheetManager::GetInstance().gfx_sheets()));
status_ = rom()->SaveToFile(backup_rom_, save_new_auto_);
}
@@ -702,11 +750,13 @@ void EditorManager::OpenRomOrProject(const std::string &filename) {
}
} else {
status_ = rom()->LoadFromFile(filename);
current_rom_ = rom();
}
}
absl::Status EditorManager::OpenProject() {
RETURN_IF_ERROR(rom()->LoadFromFile(current_project_.rom_filename_));
current_rom_ = rom();
if (!rom()->resource_label()->LoadLabels(current_project_.labels_filename_)) {
return absl::InternalError(

View File

@@ -46,6 +46,7 @@ class EditorManager : public SharedRom {
active_editors_.push_back(&sprite_editor_);
active_editors_.push_back(&message_editor_);
active_editors_.push_back(&screen_editor_);
active_editors_.push_back(&settings_editor_);
std::stringstream ss;
ss << YAZE_VERSION_MAJOR << "." << YAZE_VERSION_MINOR << "."
<< YAZE_VERSION_PATCH;
@@ -56,18 +57,18 @@ class EditorManager : public SharedRom {
absl::Status Update();
auto emulator() -> emu::Emulator & { return emulator_; }
auto quit() { return quit_; }
auto quit() const { return quit_; }
private:
void ManageActiveEditors();
void ManageKeyboardShortcuts();
void DrawStatusPopup();
void DrawAboutPopup();
void DrawInfoPopup();
void DrawPopups();
void DrawHomepage();
void DrawYazeMenu();
void DrawYazeMenuBar();
void DrawMenuBar();
void DrawMenuContent();
void DrawRomMenu();
void LoadRom();
void SaveRom();
@@ -88,6 +89,8 @@ class EditorManager : public SharedRom {
absl::Status status_;
emu::Emulator emulator_;
std::vector<Editor *> active_editors_;
std::vector<std::unique_ptr<Rom>> roms_;
Rom* current_rom_ = nullptr;
Project current_project_;
EditorContext editor_context_;

View File

@@ -112,7 +112,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()->gfx_sheets().at(sheet_id);
auto &sheet = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id);
gui::BitmapCanvasPipeline(blockset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 22);
}
@@ -165,7 +165,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()->gfx_sheets().at(sheet_id);
auto &sheet = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id);
gui::BitmapCanvasPipeline(roomset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 23);
}
@@ -203,7 +203,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()->gfx_sheets().at(115 + sheet_id);
auto &sheet = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(115 + sheet_id);
gui::BitmapCanvasPipeline(spriteset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 24);
}

View File

@@ -46,9 +46,9 @@ absl::Status GraphicsEditor::Update() {
status_ = UpdateGfxEdit();
TAB_ITEM("Sheet Browser")
if (asset_browser_.Initialized == false) {
asset_browser_.Initialize(rom()->gfx_sheets());
asset_browser_.Initialize(GraphicsSheetManager::GetInstance().gfx_sheets());
}
asset_browser_.Draw(rom()->gfx_sheets());
asset_browser_.Draw(GraphicsSheetManager::GetInstance().gfx_sheets());
END_TAB_ITEM()
status_ = UpdateScadView();
status_ = UpdateLinkGfxView();
@@ -117,7 +117,7 @@ void GraphicsEditor::DrawGfxEditToolset() {
TableNextColumn();
if (Button(ICON_MD_CONTENT_COPY)) {
std::vector<uint8_t> png_data =
rom()->gfx_sheets().at(current_sheet_).GetPngData();
GraphicsSheetManager::GetInstance().gfx_sheets().at(current_sheet_).GetPngData();
core::CopyImageToClipboard(png_data);
}
HOVER_HINT("Copy to Clipboard");
@@ -128,12 +128,11 @@ void GraphicsEditor::DrawGfxEditToolset() {
int width, height;
core::GetImageFromClipboard(png_data, width, height);
if (png_data.size() > 0) {
rom()
->mutable_gfx_sheets()
GraphicsSheetManager::GetInstance().mutable_gfx_sheets()
->at(current_sheet_)
.Create(width, height, 8, png_data);
Renderer::GetInstance().UpdateBitmap(
&rom()->mutable_gfx_sheets()->at(current_sheet_));
&GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(current_sheet_));
}
}
HOVER_HINT("Paste from Clipboard");
@@ -153,9 +152,9 @@ void GraphicsEditor::DrawGfxEditToolset() {
}
TableNextColumn();
auto bitmap = rom()->gfx_sheets()[current_sheet_];
auto bitmap = GraphicsSheetManager::GetInstance().gfx_sheets()[current_sheet_];
auto palette = bitmap.palette();
for (int i = 0; i < 8; i++) {
for (int i = 0; i < palette.size(); i++) {
ImGui::SameLine();
auto color =
ImVec4(palette[i].rgb().x / 255.0f, palette[i].rgb().y / 255.0f,
@@ -192,7 +191,7 @@ absl::Status GraphicsEditor::UpdateGfxSheetList() {
(int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
int key = 0;
for (auto& value : rom()->gfx_sheets()) {
for (auto& value : GraphicsSheetManager::GetInstance().gfx_sheets()) {
ImGui::BeginChild(absl::StrFormat("##GfxSheet%02X", key).c_str(),
ImVec2(0x100 + 1, 0x40 + 1), true,
ImGuiWindowFlags_NoDecoration);
@@ -281,7 +280,7 @@ absl::Status GraphicsEditor::UpdateGfxTabView() {
ImGuiWindowFlags_AlwaysVerticalScrollbar |
ImGuiWindowFlags_AlwaysHorizontalScrollbar);
gfx::Bitmap& current_bitmap = rom()->mutable_gfx_sheets()->at(sheet_id);
gfx::Bitmap& current_bitmap = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id);
auto draw_tile_event = [&]() {
current_sheet_canvas_.DrawTileOnBitmap(tile_size_, &current_bitmap,
@@ -290,7 +289,7 @@ absl::Status GraphicsEditor::UpdateGfxTabView() {
};
current_sheet_canvas_.UpdateColorPainter(
rom()->mutable_gfx_sheets()->at(sheet_id), current_color_,
GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id), current_color_,
draw_tile_event, tile_size_, current_scale_);
ImGui::EndChild();
@@ -323,7 +322,7 @@ absl::Status GraphicsEditor::UpdateGfxTabView() {
current_sheet_ = id;
// ImVec2(0x100, 0x40),
current_sheet_canvas_.UpdateColorPainter(
rom()->mutable_gfx_sheets()->at(id), current_color_,
GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(id), current_color_,
[&]() {
},
@@ -360,12 +359,11 @@ absl::Status GraphicsEditor::UpdatePaletteColumn() {
if (refresh_graphics_ && !open_sheets_.empty()) {
RETURN_IF_ERROR(
rom()
->mutable_gfx_sheets()
GraphicsSheetManager::GetInstance().mutable_gfx_sheets()
->data()[current_sheet_]
.ApplyPaletteWithTransparent(palette, edit_palette_sub_index_));
Renderer::GetInstance().UpdateBitmap(
&rom()->mutable_gfx_sheets()->data()[current_sheet_]);
&GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->data()[current_sheet_]);
refresh_graphics_ = false;
}
}
@@ -387,7 +385,7 @@ absl::Status GraphicsEditor::UpdateLinkGfxView() {
link_canvas_.DrawGrid(16.0f);
int i = 0;
for (auto link_sheet : *rom()->mutable_link_graphics()) {
for (auto& link_sheet : link_sheets_) {
int x_offset = 0;
int y_offset = gfx::kTilesheetHeight * i * 4;
link_canvas_.DrawContextMenu(&link_sheet);
@@ -404,7 +402,7 @@ absl::Status GraphicsEditor::UpdateLinkGfxView() {
if (ImGui::Button("Load Link Graphics (Experimental)")) {
if (rom()->is_loaded()) {
// Load Links graphics from the ROM
RETURN_IF_ERROR(rom()->LoadLinkGraphics());
ASSIGN_OR_RETURN(link_sheets_, LoadLinkGraphics(*rom()));
// Split it into the pose data frames
// Create an animation step display for the poses

View File

@@ -159,7 +159,7 @@ class GraphicsEditor : public SharedRom, public Editor {
Rom temp_rom_;
Rom tilemap_rom_;
zelda3::Overworld overworld_;
zelda3::Overworld overworld_{ temp_rom_ };
MemoryEditor cgx_memory_editor_;
MemoryEditor col_memory_editor_;
PaletteEditor palette_editor_;
@@ -176,6 +176,7 @@ class GraphicsEditor : public SharedRom, public Editor {
gfx::Bitmap bin_bitmap_;
gfx::Bitmap link_full_sheet_;
std::array<gfx::Bitmap, kNumGfxSheets> gfx_sheets_;
std::array<gfx::Bitmap, kNumLinkSheets> link_sheets_;
gfx::PaletteGroup col_file_palette_group_;
gfx::SnesPalette z3_rom_palette_;

View File

@@ -383,10 +383,10 @@ void ScreenEditor::DrawDungeonMapsEditor() {
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]);
sheets_.emplace(0, GraphicsSheetManager::GetInstance().gfx_sheets()[212]);
sheets_.emplace(1, GraphicsSheetManager::GetInstance().gfx_sheets()[213]);
sheets_.emplace(2, GraphicsSheetManager::GetInstance().gfx_sheets()[214]);
sheets_.emplace(3, GraphicsSheetManager::GetInstance().gfx_sheets()[215]);
int current_tile8 = 0;
int tile_data_offset = 0;
for (int i = 0; i < 4; ++i) {

View File

@@ -43,12 +43,12 @@ using ImGui::Text;
absl::Status Tile16Editor::InitBlockset(
const gfx::Bitmap &tile16_blockset_bmp, const gfx::Bitmap &current_gfx_bmp,
const std::vector<gfx::Bitmap> &tile16_individual,
std::array<uint8_t, 0x200> &all_tiles_types) {
all_tiles_types_ = all_tiles_types;
tile16_blockset_bmp_ = tile16_blockset_bmp;
tile16_individual_ = tile16_individual;
current_gfx_bmp_ = current_gfx_bmp;
current_gfx_bmp_.Create(current_gfx_bmp.width(), current_gfx_bmp.height(),
current_gfx_bmp.depth(), current_gfx_bmp.vector());
core::Renderer::GetInstance().RenderBitmap(&tile16_blockset_bmp_);
RETURN_IF_ERROR(LoadTile8());
ImVector<std::string> tile16_names;
for (int i = 0; i < 0x200; ++i) {
@@ -373,7 +373,7 @@ absl::Status Tile16Editor::UpdateTransferTileCanvas() {
// TODO: Implement tile16 transfer
if (transfer_started_ && !transfer_blockset_loaded_) {
PRINT_IF_ERROR(transfer_rom_.LoadAllGraphicsData())
ASSIGN_OR_RETURN(transfer_gfx_, LoadAllGraphicsData(transfer_rom_))
// Load the Link to the Past overworld.
PRINT_IF_ERROR(transfer_overworld_.Load(transfer_rom_))

View File

@@ -1,6 +1,9 @@
#ifndef YAZE_APP_EDITOR_TILE16EDITOR_H
#define YAZE_APP_EDITOR_TILE16EDITOR_H
#include <array>
#include <vector>
#include "absl/status/status.h"
#include "app/core/common.h"
#include "app/editor/graphics/palette_editor.h"
@@ -20,9 +23,9 @@ namespace editor {
*/
class Tile16Editor : public gfx::GfxContext, public SharedRom {
public:
Tile16Editor(std::array<gfx::Bitmap, zelda3::kNumTile16Individual>& tile16_individual) : tile16_individual_(tile16_individual) {}
absl::Status InitBlockset(const gfx::Bitmap &tile16_blockset_bmp,
const gfx::Bitmap &current_gfx_bmp,
const std::vector<gfx::Bitmap> &tile16_individual,
std::array<uint8_t, 0x200> &all_tiles_types);
absl::Status Update();
@@ -82,17 +85,17 @@ class Tile16Editor : public gfx::GfxContext, public SharedRom {
gui::Canvas transfer_canvas_;
gfx::Bitmap transfer_blockset_bmp_;
std::vector<gfx::Bitmap> tile16_individual_;
std::array<gfx::Bitmap, zelda3::kNumTile16Individual>& tile16_individual_;
std::vector<gfx::Bitmap> current_gfx_individual_;
PaletteEditor palette_editor_;
gfx::SnesPalette palette_;
zelda3::Overworld transfer_overworld_;
absl::Status status_;
Rom transfer_rom_;
zelda3::Overworld transfer_overworld_{ transfer_rom_ };
std::array<gfx::Bitmap, kNumGfxSheets> transfer_gfx_;
absl::Status transfer_status_;
};

View File

@@ -44,11 +44,11 @@ uint8_t FindDictionaryEntry(uint8_t value);
std::vector<uint8_t> ParseMessageToData(std::string str);
struct DictionaryEntry {
uint8_t ID;
std::string Contents;
uint8_t ID = 0;
std::string Contents = "";
std::vector<uint8_t> Data;
int Length;
std::string Token;
int Length = 0;
std::string Token = "";
DictionaryEntry() = default;
DictionaryEntry(uint8_t i, std::string s)
@@ -57,11 +57,11 @@ struct DictionaryEntry {
Data = ParseMessageToData(Contents);
}
bool ContainedInString(std::string s) {
bool ContainedInString(std::string s) const {
return s.find(Contents) != std::string::npos;
}
std::string ReplaceInstancesOfIn(std::string s) {
std::string ReplaceInstancesOfIn(std::string s) const {
std::string replacedString = s;
size_t pos = replacedString.find(Contents);
while (pos != std::string::npos) {
@@ -86,8 +86,8 @@ std::string ReplaceAllDictionaryWords(std::string str,
const std::string CHEESE = "\uBEBE";
struct MessageData {
int ID;
int Address;
int ID = 0;
int Address = 0;
std::string RawString;
std::string ContentsParsed;
std::vector<uint8_t> Data;
@@ -115,7 +115,7 @@ struct MessageData {
ContentsParsed = other.ContentsParsed;
}
std::string ToString() {
std::string ToString() const {
return absl::StrFormat("%0X - %s", ID, ContentsParsed);
}
@@ -163,8 +163,8 @@ struct TextElement {
bool HasArgument;
TextElement() = default;
TextElement(uint8_t id, std::string token, bool arg,
std::string description) {
TextElement(uint8_t id, const std::string& token, bool arg,
const std::string& description) {
ID = id;
Token = token;
if (arg) {
@@ -181,7 +181,7 @@ struct TextElement {
StrictPattern = "^" + Pattern + "$";
}
std::string GetParameterizedToken(uint8_t value = 0) {
std::string GetParameterizedToken(uint8_t value = 0) const {
if (HasArgument) {
return absl::StrFormat("[%s:%02X]", Token, value);
} else {
@@ -189,7 +189,7 @@ struct TextElement {
}
}
std::string ToString() {
std::string ToString() const {
return absl::StrFormat("%s %s", GenericToken, Description);
}
@@ -200,37 +200,61 @@ struct TextElement {
return match;
}
bool Empty() { return ID == 0; }
bool Empty() const { return ID == 0; }
// Comparison operator
bool operator==(const TextElement& other) const { return ID == other.ID; }
};
const static std::string kWindowBorder = "Window border";
const static std::string kWindowPosition = "Window position";
const static std::string kScrollSpeed = "Scroll speed";
const static std::string kTextDrawSpeed = "Text draw speed";
const static std::string kTextColor = "Text color";
const static std::string kPlayerName = "Player name";
const static std::string kLine1Str = "Line 1";
const static std::string kLine2Str = "Line 2";
const static std::string kLine3Str = "Line 3";
const static std::string kWaitForKey = "Wait for key";
const static std::string kScrollText = "Scroll text";
const static std::string kDelayX = "Delay X";
const static std::string kBCDNumber = "BCD number";
const static std::string kSoundEffect = "Sound effect";
const static std::string kChoose3 = "Choose 3";
const static std::string kChoose2High = "Choose 2 high";
const static std::string kChoose2Low = "Choose 2 low";
const static std::string kChoose2Indented = "Choose 2 indented";
const static std::string kChooseItem = "Choose item";
const static std::string kNextAttractImage = "Next attract image";
const static std::string kBankMarker = "Bank marker (automatic)";
const static std::string kCrash = "Crash";
static const std::vector<TextElement> TextCommands = {
TextElement(0x6B, "W", true, "Window border"),
TextElement(0x6D, "P", true, "Window position"),
TextElement(0x6E, "SPD", true, "Scroll speed"),
TextElement(0x7A, "S", true, "Text draw speed"),
TextElement(0x77, "C", true, "Text color"),
TextElement(0x6A, "L", false, "Player name"),
TextElement(0x74, "1", false, "Line 1"),
TextElement(0x75, "2", false, "Line 2"),
TextElement(0x76, "3", false, "Line 3"),
TextElement(0x7E, "K", false, "Wait for key"),
TextElement(0x73, "V", false, "Scroll text"),
TextElement(0x78, "WT", true, "Delay X"),
TextElement(0x6C, "N", true, "BCD number"),
TextElement(0x79, "SFX", true, "Sound effect"),
TextElement(0x71, "CH3", false, "Choose 3"),
TextElement(0x72, "CH2", false, "Choose 2 high"),
TextElement(0x6F, "CH2L", false, "Choose 2 low"),
TextElement(0x68, "CH2I", false, "Choose 2 indented"),
TextElement(0x69, "CHI", false, "Choose item"),
TextElement(0x67, "IMG", false, "Next attract image"),
TextElement(0x80, BANKToken, false, "Bank marker (automatic)"),
TextElement(0x70, "NONO", false, "Crash"),
TextElement(0x6B, "W", true, kWindowBorder),
TextElement(0x6D, "P", true, kWindowPosition),
TextElement(0x6E, "SPD", true, kScrollSpeed),
TextElement(0x7A, "S", true, kTextDrawSpeed),
TextElement(0x77, "C", true, kTextColor),
TextElement(0x6A, "L", false, kPlayerName),
TextElement(0x74, "1", false, kLine1Str),
TextElement(0x75, "2", false, kLine2Str),
TextElement(0x76, "3", false, kLine3Str),
TextElement(0x7E, "K", false, kWaitForKey),
TextElement(0x73, "V", false, kScrollText),
TextElement(0x78, "WT", true, kDelayX),
TextElement(0x6C, "N", true, kBCDNumber),
TextElement(0x79, "SFX", true, kSoundEffect),
TextElement(0x71, "CH3", false, kChoose3),
TextElement(0x72, "CH2", false, kChoose2High),
TextElement(0x6F, "CH2L", false, kChoose2Low),
TextElement(0x68, "CH2I", false, kChoose2Indented),
TextElement(0x69, "CHI", false, kChooseItem),
TextElement(0x67, "IMG", false, kNextAttractImage),
TextElement(0x80, BANKToken, false, kBankMarker),
TextElement(0x70, "NONO", false, kCrash),
};
TextElement FindMatchingCommand(uint8_t b);
static const std::vector<TextElement> SpecialChars = {

View File

@@ -626,7 +626,7 @@ absl::Status MessageEditor::Save() {
std::vector<uint8_t> backup = rom()->vector();
for (int i = 0; i < 100; i++) {
RETURN_IF_ERROR(rom()->Write(kCharactersWidth + i, width_array[i]));
RETURN_IF_ERROR(rom()->WriteByte(kCharactersWidth + i, width_array[i]));
}
int pos = kTextData;
@@ -634,7 +634,7 @@ absl::Status MessageEditor::Save() {
for (const auto& message : list_of_texts_) {
for (const auto value : message.Data) {
RETURN_IF_ERROR(rom()->Write(pos, value));
RETURN_IF_ERROR(rom()->WriteByte(pos, value));
if (value == kBlockTerminator) {
// Make sure we didn't go over the space available in the first block.
@@ -652,7 +652,7 @@ absl::Status MessageEditor::Save() {
}
RETURN_IF_ERROR(
rom()->Write(pos++, kMessageTerminator)); // , true, "Terminator text"
rom()->WriteByte(pos++, kMessageTerminator)); // , true, "Terminator text"
}
// Verify that we didn't go over the space available for the second block.
@@ -662,7 +662,7 @@ absl::Status MessageEditor::Save() {
return absl::InternalError(DisplayTextOverflowError(pos, false));
}
RETURN_IF_ERROR(rom()->Write(pos, 0xFF)); // , true, "End of text"
RETURN_IF_ERROR(rom()->WriteByte(pos, 0xFF)); // , true, "End of text"
return absl::OkStatus();
}

View File

@@ -1,6 +1,7 @@
#ifndef YAZE_APP_EDITOR_MESSAGE_EDITOR_H
#define YAZE_APP_EDITOR_MESSAGE_EDITOR_H
#include <array>
#include <string>
#include <vector>
@@ -81,16 +82,13 @@ class MessageEditor : public Editor, public SharedRom {
int text_position_ = 0;
int shown_lines_ = 0;
uint8_t width_array[kWidthArraySize];
std::string search_text_ = "";
std::array<uint8_t, kWidthArraySize> width_array = {0};
std::vector<uint8_t> font_gfx16_data_;
std::vector<uint8_t> current_font_gfx16_data_;
std::vector<std::string> parsed_messages_;
std::vector<MessageData> list_of_texts_;
std::vector<DictionaryEntry> all_dictionaries_;
MessageData current_message_;

View File

@@ -61,7 +61,7 @@ absl::Status OverworldEditor::Update() {
status_ = absl::OkStatus();
if (rom_.is_loaded() && !all_gfx_loaded_) {
RETURN_IF_ERROR(tile16_editor_.InitBlockset(
tile16_blockset_bmp_, current_gfx_bmp_, tile16_individual_,
tile16_blockset_bmp_, current_gfx_bmp_,
*overworld_.mutable_all_tiles_types()));
ASSIGN_OR_RETURN(entrance_tiletypes_, zelda3::LoadEntranceTileTypes(rom_));
all_gfx_loaded_ = true;
@@ -417,7 +417,7 @@ void OverworldEditor::DrawOverworldEdits() {
// Render the updated map bitmap.
RenderUpdatedMapBitmap(mouse_position,
tile16_individual_data_[current_tile16_]);
tile16_individual_[current_tile16_].vector());
// Calculate the correct superX and superY values
int superY = current_map_ / 8;
@@ -706,7 +706,7 @@ void OverworldEditor::DrawTile8Selector() {
graphics_bin_canvas_.DrawContextMenu();
if (all_gfx_loaded_) {
int key = 0;
for (auto &value : rom_.gfx_sheets()) {
for (auto &value : GraphicsSheetManager::GetInstance().gfx_sheets()) {
int offset = 0x40 * (key + 1);
int top_left_y = graphics_bin_canvas_.zero_point().y + 2;
if (key >= 1) {
@@ -1031,15 +1031,18 @@ absl::Status OverworldEditor::Save() {
}
absl::Status OverworldEditor::LoadGraphics() {
core::logf("Loading overworld.");
// Load the Link to the Past overworld.
RETURN_IF_ERROR(overworld_.Load(rom_))
palette_ = overworld_.current_area_palette();
core::logf("Loading overworld graphics.");
// Create the area graphics image
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
0x80, kOverworldMapSize, 0x40, overworld_.current_graphics(),
current_gfx_bmp_, palette_));
core::logf("Loading overworld tileset.");
// Create the tile16 blockset image
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
0x80, 0x2000, 0x08, overworld_.tile16_blockset_data(),
@@ -1048,38 +1051,42 @@ absl::Status OverworldEditor::LoadGraphics() {
// Copy the tile16 data into individual tiles.
auto tile16_data = overworld_.tile16_blockset_data();
tile16_individual_.reserve(zelda3::kNumTile16Individual);
core::logf("Loading overworld tile16 graphics.");
// Loop through the tiles and copy their pixel data into separate vectors
for (uint i = 0; i < zelda3::kNumTile16Individual; i++) {
std::vector<uint8_t> tile_data(kTile16Size * kTile16Size, 0x00);
tile16_individual_[i].Create(kTile16Size, kTile16Size, 0x08, kTile16Size * kTile16Size);
// Copy the pixel data for the current tile into the vector
for (int ty = 0; ty < kTile16Size; ty++) {
for (int tx = 0; tx < kTile16Size; tx++) {
int position = tx + (ty * kTile16Size);
uint8_t value =
tile16_data[(i % 8 * kTile16Size) + (i / 8 * kTile16Size * 0x80) +
(ty * 0x80) + tx];
tile_data[position] = value;
tile16_data[(i % 8 * kTile16Size) + (i / 8 * kTile16Size * 0x80) +
(ty * 0x80) + tx];
tile16_individual_[i].mutable_data()[position] = value;
}
}
// Add the vector for the current tile to the vector of tile pixel data
tile16_individual_data_.push_back(tile_data);
tile16_individual_.emplace_back();
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
kTile16Size, kTile16Size, 0x80, tile16_individual_data_[i],
tile16_individual_[i], palette_));
RETURN_IF_ERROR(tile16_individual_[i].ApplyPalette(palette_));
Renderer::GetInstance().RenderBitmap(&tile16_individual_[i]);
}
core::logf("Loading overworld maps.");
// Render the overworld maps loaded from the ROM.
for (int i = 0; i < zelda3::kNumOverworldMaps; ++i) {
overworld_.set_current_map(i);
auto palette = overworld_.current_area_palette();
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
kOverworldMapSize, kOverworldMapSize, 0x200,
try {
RETURN_IF_ERROR(Renderer::GetInstance().CreateAndRenderBitmap(
kOverworldMapSize, kOverworldMapSize, 0x80,
overworld_.current_map_bitmap_data(), maps_bmp_[i], palette));
}
catch (const std::bad_alloc& e) {
std::cout << "Error: " << e.what() << std::endl;
continue;
}
}
if (core::ExperimentFlags::get().overworld.kDrawOverworldSprites) {
@@ -1148,6 +1155,7 @@ void OverworldEditor::RefreshOverworldMap() {
std::async(std::launch::async, refresh_map_async, source_map_id));
for (auto &each : futures) {
each.wait();
each.get();
}
int n = is_large ? 4 : 1;
@@ -1215,12 +1223,12 @@ absl::Status OverworldEditor::RefreshTile16Blockset() {
// Copy the tile16 data into individual tiles.
const auto tile16_data = overworld_.tile16_blockset_data();
std::vector<std::future<void>> futures;
// Loop through the tiles and copy their pixel data into separate vectors
std::vector<std::future<absl::Status>> futures;
for (uint i = 0; i < zelda3::kNumTile16Individual; i++) {
futures.push_back(std::async(
std::launch::async,
[&](int index) {
[&](int index) -> absl::Status {
std::vector<uint8_t> tile_data(16 * 16, 0x00);
for (int ty = 0; ty < 16; ty++) {
for (int tx = 0; tx < 16; tx++) {
@@ -1232,17 +1240,19 @@ absl::Status OverworldEditor::RefreshTile16Blockset() {
}
}
tile16_individual_[index].set_data(tile_data);
RETURN_IF_ERROR(tile16_individual_[index].ApplyPalette(palette_));
return absl::OkStatus();
},
i));
}
for (auto &future : futures) {
future.get();
future.wait();
RETURN_IF_ERROR(future.get());
}
// Render the bitmaps of each tile.
for (uint id = 0; id < zelda3::kNumTile16Individual; id++) {
RETURN_IF_ERROR(tile16_individual_[id].ApplyPalette(palette_));
Renderer::GetInstance().UpdateBitmap(&tile16_individual_[id]);
}

View File

@@ -233,15 +233,14 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
bool is_dragging_entity_ = false;
std::vector<uint8_t> selected_tile_data_;
std::vector<std::vector<uint8_t>> tile16_individual_data_;
std::vector<gfx::Bitmap> tile16_individual_;
std::array<gfx::Bitmap, zelda3::kNumTile16Individual> tile16_individual_;
std::vector<std::vector<uint8_t>> tile8_individual_data_;
std::vector<gfx::Bitmap> tile8_individual_;
Rom& rom_;
Tile16Editor tile16_editor_;
Tile16Editor tile16_editor_{ tile16_individual_ };
GfxGroupEditor gfx_group_editor_;
PaletteEditor palette_editor_;
@@ -252,11 +251,11 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
gfx::Bitmap current_gfx_bmp_;
gfx::Bitmap all_gfx_bmp;
gfx::BitmapTable maps_bmp_;
std::array<gfx::Bitmap, zelda3::kNumOverworldMaps> maps_bmp_;
gfx::BitmapTable current_graphics_set_;
gfx::BitmapTable sprite_previews_;
zelda3::Overworld overworld_;
zelda3::Overworld overworld_{rom_};
zelda3::OverworldBlockset refresh_blockset_;
zelda3::Sprite current_sprite_;
@@ -264,10 +263,10 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
zelda3::OverworldEntrance current_entrance_;
zelda3::OverworldExit current_exit_;
zelda3::OverworldItem current_item_;
zelda3::OverworldEntranceTileTypes entrance_tiletypes_;
zelda3::OverworldEntranceTileTypes entrance_tiletypes_ = {};
zelda3::GameEntity* current_entity_;
zelda3::GameEntity* dragged_entity_;
zelda3::GameEntity* current_entity_ = nullptr;
zelda3::GameEntity* dragged_entity_ = nullptr;
gui::Canvas ow_map_canvas_{"OwMap", kOverworldCanvasSize,
gui::CanvasGridSize::k64x64};

View File

@@ -175,7 +175,7 @@ void SpriteEditor::DrawCurrentSheets() {
graphics_sheet_canvas_.DrawTileSelector(32);
for (int i = 0; i < 8; i++) {
graphics_sheet_canvas_.DrawBitmap(
rom()->gfx_sheets().at(current_sheets_[i]), 1, (i * 0x40) + 1, 2);
GraphicsSheetManager::GetInstance().gfx_sheets().at(current_sheets_[i]), 1, (i * 0x40) + 1, 2);
}
graphics_sheet_canvas_.DrawGrid();
graphics_sheet_canvas_.DrawOverlay();

View File

@@ -15,45 +15,42 @@ using ImGui::MenuItem;
using ImGui::Separator;
struct FlagsMenu {
void Draw() {
if (BeginMenu("Overworld Flags")) {
Checkbox("Enable Overworld Sprites",
&ExperimentFlags::get().overworld.kDrawOverworldSprites);
Separator();
Checkbox("Save Overworld Maps",
&ExperimentFlags::get().overworld.kSaveOverworldMaps);
Checkbox("Save Overworld Entrances",
&ExperimentFlags::get().overworld.kSaveOverworldEntrances);
Checkbox("Save Overworld Exits",
&ExperimentFlags::get().overworld.kSaveOverworldExits);
Checkbox("Save Overworld Items",
&ExperimentFlags::get().overworld.kSaveOverworldItems);
Checkbox("Save Overworld Properties",
&ExperimentFlags::get().overworld.kSaveOverworldProperties);
Checkbox("Load Custom Overworld",
&ExperimentFlags::get().overworld.kLoadCustomOverworld);
ImGui::EndMenu();
}
void DrawOverworldFlags() {
Checkbox("Enable Overworld Sprites",
&ExperimentFlags::get().overworld.kDrawOverworldSprites);
Separator();
Checkbox("Save Overworld Maps",
&ExperimentFlags::get().overworld.kSaveOverworldMaps);
Checkbox("Save Overworld Entrances",
&ExperimentFlags::get().overworld.kSaveOverworldEntrances);
Checkbox("Save Overworld Exits",
&ExperimentFlags::get().overworld.kSaveOverworldExits);
Checkbox("Save Overworld Items",
&ExperimentFlags::get().overworld.kSaveOverworldItems);
Checkbox("Save Overworld Properties",
&ExperimentFlags::get().overworld.kSaveOverworldProperties);
Checkbox("Load Custom Overworld",
&ExperimentFlags::get().overworld.kLoadCustomOverworld);
}
if (BeginMenu("Dungeon Flags")) {
Checkbox("Draw Dungeon Room Graphics",
&ExperimentFlags::get().kDrawDungeonRoomGraphics);
Separator();
Checkbox("Save Dungeon Maps", &ExperimentFlags::get().kSaveDungeonMaps);
ImGui::EndMenu();
}
void DrawDungeonFlags() {
Checkbox("Draw Dungeon Room Graphics",
&ExperimentFlags::get().kDrawDungeonRoomGraphics);
Separator();
Checkbox("Save Dungeon Maps", &ExperimentFlags::get().kSaveDungeonMaps);
}
Checkbox("Use built-in file dialog",
&ExperimentFlags::get().kNewFileDialogWrapper);
Checkbox("Enable Console Logging", &ExperimentFlags::get().kLogToConsole);
Checkbox("Enable Texture Streaming",
&ExperimentFlags::get().kLoadTexturesAsStreaming);
Checkbox("Log Instructions to Debugger",
&ExperimentFlags::get().kLogInstructions);
void DrawResourceFlags() {
Checkbox("Save All Palettes", &ExperimentFlags::get().kSaveAllPalettes);
Checkbox("Save Gfx Groups", &ExperimentFlags::get().kSaveGfxGroups);
Checkbox("Save Graphics Sheets",
&ExperimentFlags::get().kSaveGraphicsSheet);
&ExperimentFlags::get().kSaveGraphicsSheet);
}
void DrawSystemFlags() {
Checkbox("Enable Console Logging", &ExperimentFlags::get().kLogToConsole);
Checkbox("Log Instructions to Emulator Debugger",
&ExperimentFlags::get().kLogInstructions);
}
};

View File

@@ -1,6 +1,7 @@
#include "app/editor/system/settings_editor.h"
#include "app/gui/style.h"
#include "absl/status/status.h"
#include "app/editor/system/flags.h"
#include "imgui/imgui.h"
@@ -34,6 +35,10 @@ absl::Status SettingsEditor::Update() {
DrawGeneralSettings();
EndTabItem();
}
if (BeginTabItem("Font Manager")) {
gui::DrawFontManager();
EndTabItem();
}
if (BeginTabItem("Keyboard Shortcuts")) {
EndTabItem();
}
@@ -44,28 +49,44 @@ absl::Status SettingsEditor::Update() {
}
void SettingsEditor::DrawGeneralSettings() {
if (BeginTable("##SettingsTable", 2,
static FlagsMenu flags;
if (BeginTable("##SettingsTable", 4,
ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable)) {
TableSetupColumn("Experiment Flags", ImGuiTableColumnFlags_WidthFixed,
250.0f);
TableSetupColumn("General Setting", ImGuiTableColumnFlags_WidthStretch,
TableSetupColumn("System Flags", ImGuiTableColumnFlags_WidthStretch);
TableSetupColumn("Overworld Flags", ImGuiTableColumnFlags_WidthStretch);
TableSetupColumn("Dungeon Flags", ImGuiTableColumnFlags_WidthStretch);
TableSetupColumn("Resource Flags", ImGuiTableColumnFlags_WidthStretch,
0.0f);
TableHeadersRow();
TableNextColumn();
if (BeginChild("##GeneralSettingsStyleWrapper", ImVec2(0, 0),
if (BeginChild("##SystemFlags", ImVec2(0, 0),
ImGuiChildFlags_FrameStyle)) {
static FlagsMenu flags;
flags.Draw();
flags.DrawSystemFlags();
EndChild();
}
TableNextColumn();
if (BeginChild("##GeneralSettingsWrapper", ImVec2(0, 0),
ImGuiChildFlags_FrameStyle)) {
Text("TODO: Add some settings here");
if (BeginChild("##OverworldFlags", ImVec2(0, 0),
ImGuiChildFlags_FrameStyle)) {
flags.DrawOverworldFlags();
EndChild();
}
TableNextColumn();
if (BeginChild("##DungeonFlags", ImVec2(0, 0),
ImGuiChildFlags_FrameStyle)) {
flags.DrawDungeonFlags();
EndChild();
}
TableNextColumn();
if (BeginChild("##ResourceFlags", ImVec2(0, 0),
ImGuiChildFlags_FrameStyle)) {
flags.DrawResourceFlags();
EndChild();
}