From 277d959bdadabed641abf94efe96037ccf37c860 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 14 Apr 2024 13:14:19 -0500 Subject: [PATCH] Refactor PaletteGroupMap --- src/app/editor/dungeon_editor.cc | 13 +- src/app/editor/graphics_editor.cc | 37 +++--- src/app/editor/modules/gfx_group_editor.cc | 27 ++--- src/app/editor/modules/palette_editor.cc | 14 +-- src/app/editor/modules/tile16_editor.cc | 8 +- src/app/editor/modules/tile16_editor.h | 4 +- src/app/gfx/snes_palette.h | 86 ++++++++++++- src/app/rom.cc | 133 ++++++++------------- src/app/rom.h | 26 ++-- src/app/zelda3/overworld_map.cc | 50 ++++---- src/app/zelda3/overworld_map.h | 4 +- src/app/zelda3/screen/inventory.cc | 4 +- 12 files changed, 218 insertions(+), 188 deletions(-) diff --git a/src/app/editor/dungeon_editor.cc b/src/app/editor/dungeon_editor.cc index 77802787..bd3d2b1a 100644 --- a/src/app/editor/dungeon_editor.cc +++ b/src/app/editor/dungeon_editor.cc @@ -59,8 +59,7 @@ absl::Status DungeonEditor::Update() { } absl::Status DungeonEditor::Initialize() { - ASSIGN_OR_RETURN(auto dungeon_man_pal_group, - rom()->palette_group("dungeon_main")); + auto dungeon_man_pal_group = rom()->palette_group().dungeon_main; for (int i = 0; i < 0x100 + 40; i++) { rooms_.emplace_back(zelda3::dungeon::Room(i)); rooms_[i].LoadHeader(); @@ -101,12 +100,11 @@ absl::Status DungeonEditor::Initialize() { absl::Status DungeonEditor::RefreshGraphics() { for (int i = 0; i < 8; i++) { int block = rooms_[current_room_id_].blocks()[i]; - graphics_bin_[block].get()->ApplyPaletteWithTransparent( - current_palette_group_[current_palette_id_], 0); + RETURN_IF_ERROR(graphics_bin_[block].get()->ApplyPaletteWithTransparent( + current_palette_group_[current_palette_id_], 0)); rom()->UpdateBitmap(graphics_bin_[block].get(), true); } - ASSIGN_OR_RETURN(auto sprites_aux1_pal_group, - rom()->palette_group("sprites_aux1")); + auto sprites_aux1_pal_group = rom()->palette_group().sprites_aux1; for (int i = 9; i < 16; i++) { int block = rooms_[current_room_id_].blocks()[i]; graphics_bin_[block].get()->ApplyPaletteWithTransparent( @@ -163,8 +161,7 @@ absl::Status DungeonEditor::UpdateDungeonRoomView() { if (palette_showing_) { ImGui::Begin("Palette Editor", &palette_showing_, 0); - ASSIGN_OR_RETURN(auto dungeon_main_pal_group, - rom()->palette_group("dungeon_main")); + auto dungeon_main_pal_group = rom()->palette_group().dungeon_main; current_palette_ = dungeon_main_pal_group[current_palette_group_id_]; gui::SelectablePalettePipeline(current_palette_id_, refresh_graphics_, current_palette_); diff --git a/src/app/editor/graphics_editor.cc b/src/app/editor/graphics_editor.cc index 7b90c9a9..1d71e4ac 100644 --- a/src/app/editor/graphics_editor.cc +++ b/src/app/editor/graphics_editor.cc @@ -322,12 +322,10 @@ absl::Status GraphicsEditor::UpdateGfxTabView() { } absl::Status GraphicsEditor::UpdatePaletteColumn() { - ASSIGN_OR_RETURN( - auto palette_group, - rom()->palette_group( - kPaletteGroupAddressesKeys[edit_palette_group_name_index_])); + auto palette_group = *rom()->palette_group().get_group( + kPaletteGroupAddressesKeys[edit_palette_group_name_index_]); - auto palette = palette_group[edit_palette_index_]; + auto palette = palette_group.palette(edit_palette_index_); if (rom()->is_loaded()) { gui::TextWithSeparators("ROM Palette"); @@ -342,11 +340,13 @@ absl::Status GraphicsEditor::UpdatePaletteColumn() { gui::SelectablePalettePipeline(edit_palette_sub_index_, refresh_graphics_, palette); - if (refresh_graphics_) { - rom()->bitmap_manager()[current_sheet_]->ApplyPaletteWithTransparent( - palette, edit_palette_sub_index_); + 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_).get()); + rom()->mutable_bitmap_manager()->mutable_bitmap(current_sheet_).get(), + true); refresh_graphics_ = false; } @@ -377,9 +377,9 @@ absl::Status GraphicsEditor::UpdateLinkGfxView() { link_canvas_.DrawGrid(); NEXT_COLUMN(); + ImGui::Text("Placeholder"); NEXT_COLUMN(); - if (ImGui::Button("Load Link Graphics (Experimental)")) { if (rom()->is_loaded()) { // Load Links graphics from the ROM @@ -736,7 +736,7 @@ absl::Status GraphicsEditor::DecompressImportData(int size) { converted_sheet); if (rom()->is_loaded()) { - ASSIGN_OR_RETURN(auto palette_group, rom()->palette_group("ow_main")); + auto palette_group = rom()->palette_group().overworld_animated; z3_rom_palette_ = palette_group[current_palette_]; if (col_file_) { bin_bitmap_.ApplyPalette(col_file_palette_); @@ -768,10 +768,10 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() { col_file_palette_group_[current_palette_index_]); } else { // ROM palette - ASSIGN_OR_RETURN( - auto palette_group, - rom()->palette_group(kPaletteGroupAddressesKeys[current_palette_])); - z3_rom_palette_ = palette_group[current_palette_index_]; + + auto palette_group = rom()->palette_group().get_group( + kPaletteGroupAddressesKeys[current_palette_]); + z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_); graphics_bin_[i].ApplyPalette(z3_rom_palette_); } @@ -794,10 +794,9 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() { col_file_palette_group_[current_palette_index_]); } else { // ROM palette - ASSIGN_OR_RETURN( - auto palette_group, - rom()->palette_group(kPaletteGroupAddressesKeys[current_palette_])); - z3_rom_palette_ = palette_group[current_palette_index_]; + auto palette_group = rom()->palette_group().get_group( + kPaletteGroupAddressesKeys[current_palette_]); + z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_); graphics_bin_[i].ApplyPalette(z3_rom_palette_); } diff --git a/src/app/editor/modules/gfx_group_editor.cc b/src/app/editor/modules/gfx_group_editor.cc index da286a82..cb84ccee 100644 --- a/src/app/editor/modules/gfx_group_editor.cc +++ b/src/app/editor/modules/gfx_group_editor.cc @@ -6,8 +6,8 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "app/editor/utils/editor.h" #include "app/editor/modules/palette_editor.h" +#include "app/editor/utils/editor.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" #include "app/gfx/snes_tile.h" @@ -220,29 +220,20 @@ void GfxGroupEditor::DrawPaletteViewer() { gui::InputHexByte("Dungeon Spr Pal 2", &dungeon_spr_pal_2_val); gui::InputHexByte("Dungeon Spr Pal 3", &dungeon_spr_pal_3_val); - auto &palette = - *rom() - ->mutable_palette_group( - "dungeon_main")[rom()->paletteset_ids[selected_paletteset][0]] - .mutable_palette(0); + auto &palette = *rom()->mutable_palette_group()->dungeon_main.mutable_palette( + rom()->paletteset_ids[selected_paletteset][0]); DrawPaletteFromPaletteGroup(palette); auto &spr_aux_pal1 = - *rom() - ->mutable_palette_group( - "sprites_aux1")[rom()->paletteset_ids[selected_paletteset][1]] - .mutable_palette(0); + *rom()->mutable_palette_group()->sprites_aux1.mutable_palette( + rom()->paletteset_ids[selected_paletteset][1]); DrawPaletteFromPaletteGroup(spr_aux_pal1); auto &spr_aux_pal2 = - *rom() - ->mutable_palette_group( - "sprites_aux2")[rom()->paletteset_ids[selected_paletteset][2]] - .mutable_palette(0); + *rom()->mutable_palette_group()->sprites_aux2.mutable_palette( + rom()->paletteset_ids[selected_paletteset][2]); DrawPaletteFromPaletteGroup(spr_aux_pal2); auto &spr_aux_pal3 = - *rom() - ->mutable_palette_group( - "sprites_aux3")[rom()->paletteset_ids[selected_paletteset][3]] - .mutable_palette(0); + *rom()->mutable_palette_group()->sprites_aux3.mutable_palette( + rom()->paletteset_ids[selected_paletteset][3]); DrawPaletteFromPaletteGroup(spr_aux_pal3); } diff --git a/src/app/editor/modules/palette_editor.cc b/src/app/editor/modules/palette_editor.cc index 2bd5d7ce..9816388b 100644 --- a/src/app/editor/modules/palette_editor.cc +++ b/src/app/editor/modules/palette_editor.cc @@ -78,7 +78,6 @@ absl::Status PaletteEditor::Update() { absl::Status PaletteEditor::EditColorInPalette(gfx::SnesPalette& palette, int index) { if (index >= palette.size()) { - // Handle error: the index is out of bounds return absl::InvalidArgumentError("Index out of bounds"); } @@ -108,18 +107,18 @@ absl::Status PaletteEditor::DrawPaletteGroup(int category) { if (!rom()->is_loaded()) { return absl::NotFoundError("ROM not open, no palettes to display"); } - ASSIGN_OR_RETURN(auto palette_group, - rom()->palette_group(kPaletteGroupNames[category].data())); + + std::string group_name = kPaletteGroupNames[category].data(); + auto palette_group = *rom()->palette_group().get_group(group_name); const auto size = palette_group.size(); - auto palettes = - rom()->mutable_palette_group(kPaletteGroupNames[category].data()); + static bool edit_color = false; for (int j = 0; j < size; j++) { // ImGui::Text("%d", j); rom()->resource_label()->SelectableLabelWithNameEdit( false, "Palette Group Name", std::to_string(j), std::string(kPaletteGroupNames[category])); - auto palette = palettes->mutable_palette(j); + auto palette = palette_group.mutable_palette(j); auto pal_size = palette->size(); for (int n = 0; n < pal_size; n++) { @@ -155,8 +154,7 @@ absl::Status PaletteEditor::HandleColorPopup(gfx::SnesPalette& palette, int i, int j, int n) { auto col = gfx::ToFloatArray(palette[n]); if (gui::SnesColorEdit4("Edit Color", palette[n], color_popup_flags)) { - RETURN_IF_ERROR(rom()->UpdatePaletteColor(kPaletteGroupNames[i].data(), j, - n, palette[n])) + // TODO: Implement new update color function } if (ImGui::Button("Copy as..", ImVec2(-1, 0))) ImGui::OpenPopup("Copy"); diff --git a/src/app/editor/modules/tile16_editor.cc b/src/app/editor/modules/tile16_editor.cc index 5d3818e8..733fea5b 100644 --- a/src/app/editor/modules/tile16_editor.cc +++ b/src/app/editor/modules/tile16_editor.cc @@ -6,8 +6,8 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "app/editor/utils/editor.h" #include "app/editor/modules/palette_editor.h" +#include "app/editor/utils/editor.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" #include "app/gfx/snes_tile.h" @@ -124,7 +124,7 @@ absl::Status Tile16Editor::UpdateBlockset() { if (notify_tile16.modified()) { current_tile16_ = notify_tile16.get(); current_tile16_bmp_ = tile16_individual_[notify_tile16]; - ASSIGN_OR_RETURN(auto ow_main_pal_group, rom()->palette_group("ow_main")); + 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(¤t_tile16_bmp_); @@ -168,7 +168,7 @@ absl::Status Tile16Editor::DrawToCurrentTile16(ImVec2 click_position) { } absl::Status Tile16Editor::UpdateTile16Edit() { - ASSIGN_OR_RETURN(auto ow_main_pal_group, rom()->palette_group("ow_main")); + auto ow_main_pal_group = rom()->palette_group().overworld_main; if (ImGui::BeginChild("Tile8 Selector", ImVec2(ImGui::GetContentRegionAvail().x, 0x175), @@ -255,7 +255,7 @@ absl::Status Tile16Editor::DrawTileEditControls() { } absl::Status Tile16Editor::LoadTile8() { - ASSIGN_OR_RETURN(auto ow_main_pal_group, rom()->palette_group("ow_main")); + auto ow_main_pal_group = rom()->palette_group().overworld_main; current_gfx_individual_.reserve(1024); diff --git a/src/app/editor/modules/tile16_editor.h b/src/app/editor/modules/tile16_editor.h index 8b91a51d..f3a322d2 100644 --- a/src/app/editor/modules/tile16_editor.h +++ b/src/app/editor/modules/tile16_editor.h @@ -7,9 +7,9 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "app/editor/utils/editor.h" #include "app/editor/context/gfx_context.h" #include "app/editor/modules/palette_editor.h" +#include "app/editor/utils/editor.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" #include "app/gfx/snes_tile.h" @@ -60,7 +60,7 @@ class Tile16Editor : public context::GfxContext, public SharedROM { absl::Status set_tile16(int id) { current_tile16_ = id; current_tile16_bmp_ = tile16_individual_[id]; - ASSIGN_OR_RETURN(auto ow_main_pal_group, rom()->palette_group("ow_main")); + 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(¤t_tile16_bmp_); diff --git a/src/app/gfx/snes_palette.h b/src/app/gfx/snes_palette.h index e8099fd6..2f29e29a 100644 --- a/src/app/gfx/snes_palette.h +++ b/src/app/gfx/snes_palette.h @@ -145,8 +145,6 @@ struct PaletteGroup { explicit PaletteGroup(uint8_t mSize); - auto mutable_palette(int i) { return &palettes[i]; } - absl::Status AddPalette(SnesPalette pal) { palettes.emplace_back(pal); size_ = palettes.size(); @@ -166,7 +164,10 @@ struct PaletteGroup { size_ = 0; } + auto name() const { return name_; } auto size() const { return palettes.size(); } + auto mutable_palette(int i) { return &palettes[i]; } + auto palette(int i) const { return palettes[i]; } SnesPalette operator[](int i) { if (i > size_) { @@ -202,9 +203,90 @@ struct PaletteGroup { private: int size_ = 0; + std::string name_; std::vector palettes; }; +/** + * @brief Represents a mapping of palette groups. + * + * Originally, this was an actual std::unordered_map but since the palette + * groups supported never change, it was changed to a struct with a method to + * get the group by name. + */ +struct PaletteGroupMap { + PaletteGroup overworld_main; + PaletteGroup overworld_aux; + PaletteGroup overworld_animated; + PaletteGroup hud; + PaletteGroup global_sprites; + PaletteGroup armors; + PaletteGroup swords; + PaletteGroup shields; + PaletteGroup sprites_aux1; + PaletteGroup sprites_aux2; + PaletteGroup sprites_aux3; + PaletteGroup dungeon_main; + PaletteGroup grass; + PaletteGroup object_3d; + PaletteGroup overworld_mini_map; + + auto get_group(const std::string& group_name) { + if (group_name == "ow_main") { + return &overworld_main; + } else if (group_name == "ow_aux") { + return &overworld_aux; + } else if (group_name == "ow_animated") { + return &overworld_animated; + } else if (group_name == "hud") { + return &hud; + } else if (group_name == "global_sprites") { + return &global_sprites; + } else if (group_name == "armors") { + return &armors; + } else if (group_name == "swords") { + return &swords; + } else if (group_name == "shields") { + return &shields; + } else if (group_name == "sprites_aux1") { + return &sprites_aux1; + } else if (group_name == "sprites_aux2") { + return &sprites_aux2; + } else if (group_name == "sprites_aux3") { + return &sprites_aux3; + } else if (group_name == "dungeon_main") { + return &dungeon_main; + } else if (group_name == "grass") { + return &grass; + } else if (group_name == "3d_object") { + return &object_3d; + } else if (group_name == "ow_mini_map") { + return &overworld_mini_map; + } else { + throw std::out_of_range("PaletteGroupMap: Group not found"); + } + } + + template + void for_each(Func&& func) { + func(overworld_main); + func(overworld_aux); + func(overworld_animated); + func(hud); + func(global_sprites); + func(armors); + func(swords); + func(shields); + func(sprites_aux1); + func(sprites_aux2); + func(sprites_aux3); + func(dungeon_main); + func(grass); + func(object_3d); + func(overworld_mini_map); + } +}; + absl::StatusOr CreatePaletteGroupFromColFile( std::vector& colors); diff --git a/src/app/rom.cc b/src/app/rom.cc index 929f7b42..4f4bdb00 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -31,156 +31,157 @@ namespace app { namespace { absl::Status LoadOverworldMainPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 6; i++) { - RETURN_IF_ERROR(palette_groups["ow_main"].AddPalette( + RETURN_IF_ERROR(palette_groups.overworld_main.AddPalette( gfx::ReadPaletteFromRom(core::overworldPaletteMain + (i * (35 * 2)), /*num_colors*/ 35, data))) } return absl::OkStatus(); } -absl::Status LoadOverworldAuxiliaryPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { +absl::Status LoadOverworldAuxiliaryPalettes( + const Bytes& rom_data, gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 20; i++) { - RETURN_IF_ERROR(palette_groups["ow_aux"].AddPalette(gfx::ReadPaletteFromRom( - core::overworldPaletteAuxialiary + (i * (21 * 2)), - /*num_colors*/ 21, data))) + RETURN_IF_ERROR( + palette_groups.overworld_aux.AddPalette(gfx::ReadPaletteFromRom( + core::overworldPaletteAuxialiary + (i * (21 * 2)), + /*num_colors*/ 21, data))) } return absl::OkStatus(); } -absl::Status LoadOverworldAnimatedPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { +absl::Status LoadOverworldAnimatedPalettes( + const Bytes& rom_data, gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 14; i++) { RETURN_IF_ERROR( - palette_groups["ow_animated"].AddPalette(gfx::ReadPaletteFromRom( + palette_groups.overworld_animated.AddPalette(gfx::ReadPaletteFromRom( core::overworldPaletteAnimated + (i * (7 * 2)), 7, data))) } return absl::OkStatus(); } absl::Status LoadHUDPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 2; i++) { - RETURN_IF_ERROR(palette_groups["hud"].AddPalette( + RETURN_IF_ERROR(palette_groups.hud.AddPalette( gfx::ReadPaletteFromRom(core::hudPalettes + (i * 64), 32, data))) } return absl::OkStatus(); } absl::Status LoadGlobalSpritePalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); - RETURN_IF_ERROR(palette_groups["global_sprites"].AddPalette( + RETURN_IF_ERROR(palette_groups.global_sprites.AddPalette( gfx::ReadPaletteFromRom(core::globalSpritePalettesLW, 60, data))) - RETURN_IF_ERROR(palette_groups["global_sprites"].AddPalette( + RETURN_IF_ERROR(palette_groups.global_sprites.AddPalette( gfx::ReadPaletteFromRom(core::globalSpritePalettesDW, 60, data))) return absl::OkStatus(); } absl::Status LoadArmorPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 5; i++) { - RETURN_IF_ERROR(palette_groups["armors"].AddPalette( + RETURN_IF_ERROR(palette_groups.armors.AddPalette( gfx::ReadPaletteFromRom(core::armorPalettes + (i * 30), 15, data))) } return absl::OkStatus(); } absl::Status LoadSwordPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 4; i++) { - RETURN_IF_ERROR(palette_groups["swords"].AddPalette( + RETURN_IF_ERROR(palette_groups.swords.AddPalette( gfx::ReadPaletteFromRom(core::swordPalettes + (i * 6), 3, data))) } return absl::OkStatus(); } absl::Status LoadShieldPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 3; i++) { - RETURN_IF_ERROR(palette_groups["shields"].AddPalette( + RETURN_IF_ERROR(palette_groups.shields.AddPalette( gfx::ReadPaletteFromRom(core::shieldPalettes + (i * 8), 4, data))) } return absl::OkStatus(); } absl::Status LoadSpriteAux1Palettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 12; i++) { - RETURN_IF_ERROR(palette_groups["sprites_aux1"].AddPalette( + RETURN_IF_ERROR(palette_groups.sprites_aux1.AddPalette( gfx::ReadPaletteFromRom(core::spritePalettesAux1 + (i * 14), 7, data))) } return absl::OkStatus(); } absl::Status LoadSpriteAux2Palettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 11; i++) { - RETURN_IF_ERROR(palette_groups["sprites_aux2"].AddPalette( + RETURN_IF_ERROR(palette_groups.sprites_aux2.AddPalette( gfx::ReadPaletteFromRom(core::spritePalettesAux2 + (i * 14), 7, data))) } return absl::OkStatus(); } absl::Status LoadSpriteAux3Palettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 24; i++) { - RETURN_IF_ERROR(palette_groups["sprites_aux3"].AddPalette( + RETURN_IF_ERROR(palette_groups.sprites_aux3.AddPalette( gfx::ReadPaletteFromRom(core::spritePalettesAux3 + (i * 14), 7, data))) } return absl::OkStatus(); } absl::Status LoadDungeonMainPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 20; i++) { RETURN_IF_ERROR( - palette_groups["dungeon_main"].AddPalette(gfx::ReadPaletteFromRom( + palette_groups.dungeon_main.AddPalette(gfx::ReadPaletteFromRom( core::dungeonMainPalettes + (i * 180), 90, data))) } return absl::OkStatus(); } absl::Status LoadGrassColors(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { - RETURN_IF_ERROR(palette_groups["grass"].AddColor( + gfx::PaletteGroupMap& palette_groups) { + RETURN_IF_ERROR(palette_groups.grass.AddColor( gfx::ReadColorFromRom(core::hardcodedGrassLW, rom_data.data()))) - RETURN_IF_ERROR(palette_groups["grass"].AddColor( + RETURN_IF_ERROR(palette_groups.grass.AddColor( gfx::ReadColorFromRom(core::hardcodedGrassDW, rom_data.data()))) - RETURN_IF_ERROR(palette_groups["grass"].AddColor( + RETURN_IF_ERROR(palette_groups.grass.AddColor( gfx::ReadColorFromRom(core::hardcodedGrassSpecial, rom_data.data()))) return absl::OkStatus(); } absl::Status Load3DObjectPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { + gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); - RETURN_IF_ERROR(palette_groups["3d_object"].AddPalette( + RETURN_IF_ERROR(palette_groups.object_3d.AddPalette( gfx::ReadPaletteFromRom(core::triforcePalette, 8, data))) - RETURN_IF_ERROR(palette_groups["3d_object"].AddPalette( + RETURN_IF_ERROR(palette_groups.object_3d.AddPalette( gfx::ReadPaletteFromRom(core::crystalPalette, 8, data))) return absl::OkStatus(); } -absl::Status LoadOverworldMiniMapPalettes(const Bytes& rom_data, - PaletteGroupMap& palette_groups) { +absl::Status LoadOverworldMiniMapPalettes( + const Bytes& rom_data, gfx::PaletteGroupMap& palette_groups) { auto data = rom_data.data(); for (int i = 0; i < 2; i++) { RETURN_IF_ERROR( - palette_groups["ow_mini_map"].AddPalette(gfx::ReadPaletteFromRom( + palette_groups.overworld_mini_map.AddPalette(gfx::ReadPaletteFromRom( core::overworldMiniMapPalettes + (i * 256), 128, data))) } return absl::OkStatus(); @@ -206,7 +207,7 @@ absl::StatusOr ROM::Load2BppGraphics() { absl::Status ROM::LoadLinkGraphics() { const auto link_gfx_offset = 0x80000; // $10:8000 const auto link_gfx_length = 0x800; // 0x4000 or 0x7000? - link_palette_ = palette_groups_["armors"][0]; + link_palette_ = palette_groups_.armors[0]; // Load Links graphics from the ROM for (int i = 0; i < 14; i++) { @@ -258,10 +259,10 @@ absl::Status ROM::LoadAllGraphicsData() { if (i > 115) { // Apply sprites palette RETURN_IF_ERROR(graphics_manager_[i]->ApplyPaletteWithTransparent( - palette_groups_["global_sprites"][0], 0)); + palette_groups_.global_sprites[0], 0)); } else { RETURN_IF_ERROR(graphics_manager_[i]->ApplyPaletteWithTransparent( - palette_groups_["dungeon_main"][0], 0)); + palette_groups_.dungeon_main[0], 0)); } graphics_manager_[i]->CreateTexture(renderer_); } @@ -484,56 +485,28 @@ absl::Status ROM::SaveToFile(bool backup, bool save_new, std::string filename) { return absl::OkStatus(); } -void ROM::SavePalette(int index, const std::string& group_name, - gfx::SnesPalette& palette) { +absl::Status ROM::SavePalette(int index, const std::string& group_name, + gfx::SnesPalette& palette) { // Iterate through all colors in the palette for (size_t j = 0; j < palette.size(); ++j) { gfx::SnesColor color = palette[j]; // If the color is modified, save the color to the ROM if (color.is_modified()) { - WriteColor(gfx::GetPaletteAddress(group_name, index, j), color); + RETURN_IF_ERROR( + WriteColor(gfx::GetPaletteAddress(group_name, index, j), color)); color.set_modified(false); // Reset the modified flag after saving } } + return absl::OkStatus(); } -void ROM::SaveAllPalettes() { - // Iterate through all palette_groups_ - for (auto& [group_name, palettes] : palette_groups_) { - // Iterate through all palettes in the group - for (size_t i = 0; i < palettes.size(); ++i) { - auto palette = palettes[i]; - SavePalette(i, group_name, palette); +absl::Status ROM::SaveAllPalettes() { + palette_groups_.for_each([&](gfx::PaletteGroup& group) { + for (size_t i = 0; i < group.size(); ++i) { + SavePalette(i, group.name(), *group.mutable_palette(i)); } - } -} + }); -absl::Status ROM::UpdatePaletteColor(const std::string& groupName, - size_t paletteIndex, size_t colorIndex, - const gfx::SnesColor& newColor) { - // Check if the groupName exists in the palette_groups_ map - if (palette_groups_.find(groupName) != palette_groups_.end()) { - // Check if the paletteIndex is within the range of available palettes in - // the group - if (paletteIndex < palette_groups_[groupName].size()) { - // Check if the colorIndex is within the range of available colors in the - // palette - if (colorIndex < palette_groups_[groupName][paletteIndex].size()) { - // Update the color value in the palette - palette_groups_[groupName][paletteIndex][colorIndex] = newColor; - palette_groups_[groupName][paletteIndex][colorIndex].set_modified(true); - } else { - return absl::AbortedError( - "Error: Invalid color index in UpdatePaletteColor."); - } - } else { - return absl::AbortedError( - "Error: Invalid palette index in UpdatePaletteColor."); - } - } else { - return absl::AbortedError( - "Error: Invalid group name in UpdatePaletteColor"); - } return absl::OkStatus(); } diff --git a/src/app/rom.h b/src/app/rom.h index 45c0a91e..b419b5c6 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -40,8 +40,6 @@ namespace yaze { namespace app { -using PaletteGroupMap = std::unordered_map; - // Define an enum class for the different versions of the game enum class Z3_Version { US = 1, // US version @@ -208,8 +206,8 @@ class ROM : public core::ExperimentFlags { * @param group_name The name of the group containing the palette. * @param palette The palette to save. */ - void SavePalette(int index, const std::string& group_name, - gfx::SnesPalette& palette); + absl::Status SavePalette(int index, const std::string& group_name, + gfx::SnesPalette& palette); /** * @brief Saves all palettes in the ROM. @@ -217,7 +215,7 @@ class ROM : public core::ExperimentFlags { * This function iterates through all palette groups and all palettes in each * group, and saves each palette using the SavePalette() function. */ - void SaveAllPalettes(); + absl::Status SaveAllPalettes(); /** * @brief Updates a color in a specified palette group. @@ -457,19 +455,11 @@ class ROM : public core::ExperimentFlags { return core::SnesToPc(snes_addr); } - absl::StatusOr palette_group(const std::string& group) { - if (palette_groups_.find(group) == palette_groups_.end()) { - return absl::InvalidArgumentError( - absl::StrCat("Palette group ", group, " not found")); - } - return palette_groups_[group]; - } - auto mutable_palette_group(const std::string& group) { - return &palette_groups_[group]; - } - auto dungeon_palette(int i) { return palette_groups_["dungeon_main"][i]; } + auto palette_group() { return palette_groups_; } + auto mutable_palette_group() { return &palette_groups_; } + auto dungeon_palette(int i) { return palette_groups_.dungeon_main[i]; } auto mutable_dungeon_palette(int i) { - return palette_groups_["dungeon_main"].mutable_palette(i); + return palette_groups_.dungeon_main.mutable_palette(i); } // Full graphical data for the game @@ -678,7 +668,7 @@ class ROM : public core::ExperimentFlags { gfx::BitmapManager graphics_manager_; gfx::BitmapTable link_graphics_; gfx::SnesPalette link_palette_; - PaletteGroupMap palette_groups_; + gfx::PaletteGroupMap palette_groups_; core::ResourceLabelManager resource_label_manager_; std::stack> changes_; diff --git a/src/app/zelda3/overworld_map.cc b/src/app/zelda3/overworld_map.cc index 56360664..f2282245 100644 --- a/src/app/zelda3/overworld_map.cc +++ b/src/app/zelda3/overworld_map.cc @@ -289,7 +289,7 @@ absl::Status SetColorsPalette(ROM& rom, int index, gfx::SnesPalette& current, k = 0; for (int y = 8; y < 9; y++) { for (int x = 1; x < 8; x++) { - ASSIGN_OR_RETURN(auto pal_group, rom.palette_group("sprites_aux1")); + auto pal_group = rom.palette_group().sprites_aux1; new_palette[x + (16 * y)] = pal_group[1][k]; k++; } @@ -299,7 +299,7 @@ absl::Status SetColorsPalette(ROM& rom, int index, gfx::SnesPalette& current, k = 0; for (int y = 8; y < 9; y++) { for (int x = 9; x < 16; x++) { - ASSIGN_OR_RETURN(auto pal_group, rom.palette_group("sprites_aux3")); + auto pal_group = rom.palette_group().sprites_aux3; new_palette[x + (16 * y)] = pal_group[0][k]; k++; } @@ -309,7 +309,7 @@ absl::Status SetColorsPalette(ROM& rom, int index, gfx::SnesPalette& current, k = 0; for (int y = 9; y < 13; y++) { for (int x = 1; x < 16; x++) { - ASSIGN_OR_RETURN(auto pal_group, rom.palette_group("global_sprites")); + auto pal_group = rom.palette_group().global_sprites; new_palette[x + (16 * y)] = pal_group[0][k]; k++; } @@ -337,7 +337,7 @@ absl::Status SetColorsPalette(ROM& rom, int index, gfx::SnesPalette& current, k = 0; for (int y = 15; y < 16; y++) { for (int x = 1; x < 16; x++) { - ASSIGN_OR_RETURN(auto pal_group, rom.palette_group("armors")); + auto pal_group = rom.palette_group().armors; new_palette[x + (16 * y)] = pal_group[0][k]; k++; } @@ -354,21 +354,16 @@ absl::Status SetColorsPalette(ROM& rom, int index, gfx::SnesPalette& current, // New helper function to get a palette from the ROM. absl::StatusOr OverworldMap::GetPalette( - const std::string& group, int index, int previousIndex, int limit) { + const gfx::PaletteGroup& palette_group, int index, int previous_index, + int limit) { if (index == 255) { index = rom_[rom_.version_constants().overworldMapPaletteGroup + - (previousIndex * 4)]; + (previous_index * 4)]; } - if (index != 255) { - if (index >= limit) { - index = limit - 1; - } - ASSIGN_OR_RETURN(auto pal_group, rom_.palette_group(group)); - return pal_group[index]; - } else { - ASSIGN_OR_RETURN(auto pal_group, rom_.palette_group(group)); - return pal_group[0]; + if (index >= limit) { + index = limit - 1; } + return palette_group[index]; } absl::Status OverworldMap::LoadPalette() { @@ -390,13 +385,14 @@ absl::Status OverworldMap::LoadPalette() { uchar pal5 = rom_[overworldSpritePaletteGroup + (sprite_palette_[game_state_] * 2) + 1]; - ASSIGN_OR_RETURN(auto grass_pal_group, rom_.palette_group("grass")); + auto grass_pal_group = rom_.palette_group().grass; ASSIGN_OR_RETURN(gfx::SnesColor bgr, grass_pal_group[0].GetColor(0)); + auto ow_aux_pal_group = rom_.palette_group().overworld_aux; ASSIGN_OR_RETURN(gfx::SnesPalette aux1, - GetPalette("ow_aux", pal1, previousPalId, 20)); + GetPalette(ow_aux_pal_group, pal1, previousPalId, 20)); ASSIGN_OR_RETURN(gfx::SnesPalette aux2, - GetPalette("ow_aux", pal2, previousPalId, 20)); + GetPalette(ow_aux_pal_group, pal2, previousPalId, 20)); // Additional handling of `pal3` and `parent_` if (pal3 == 255) { @@ -419,19 +415,23 @@ absl::Status OverworldMap::LoadPalette() { pal0 = 4; } + auto ow_main_pal_group = rom_.palette_group().overworld_main; ASSIGN_OR_RETURN(gfx::SnesPalette main, - GetPalette("ow_main", pal0, previousPalId, 255)); - ASSIGN_OR_RETURN( - gfx::SnesPalette animated, - GetPalette("ow_animated", std::min((int)pal3, 13), previousPalId, 14)); + GetPalette(ow_main_pal_group, pal0, previousPalId, 255)); + auto ow_animated_pal_group = rom_.palette_group().overworld_animated; + ASSIGN_OR_RETURN(gfx::SnesPalette animated, + GetPalette(ow_animated_pal_group, std::min((int)pal3, 13), + previousPalId, 14)); - ASSIGN_OR_RETURN(auto hud_pal_group, rom_.palette_group("hud")); + auto hud_pal_group = rom_.palette_group().hud; gfx::SnesPalette hud = hud_pal_group[0]; ASSIGN_OR_RETURN(gfx::SnesPalette spr, - GetPalette("sprites_aux3", pal4, previousSprPalId, 24)); + GetPalette(rom_.palette_group().sprites_aux3, pal4, + previousSprPalId, 24)); ASSIGN_OR_RETURN(gfx::SnesPalette spr2, - GetPalette("sprites_aux3", pal5, previousSprPalId, 24)); + GetPalette(rom_.palette_group().sprites_aux3, pal5, + previousSprPalId, 24)); RETURN_IF_ERROR(palette_internal::SetColorsPalette( rom_, parent_, current_palette_, main, animated, aux1, aux2, hud, bgr, diff --git a/src/app/zelda3/overworld_map.h b/src/app/zelda3/overworld_map.h index f2731f45..087dbec2 100644 --- a/src/app/zelda3/overworld_map.h +++ b/src/app/zelda3/overworld_map.h @@ -109,8 +109,8 @@ class OverworldMap : public editor::context::GfxContext { void LoadDeathMountainGFX(); void ProcessGraphicsBuffer(int index, int static_graphics_offset, int size); - absl::StatusOr GetPalette(const std::string& group, - int index, int previousIndex, + absl::StatusOr GetPalette(const gfx::PaletteGroup& group, + int index, int previous_index, int limit); bool built_ = false; diff --git a/src/app/zelda3/screen/inventory.cc b/src/app/zelda3/screen/inventory.cc index 7dcf1fff..b32434dd 100644 --- a/src/app/zelda3/screen/inventory.cc +++ b/src/app/zelda3/screen/inventory.cc @@ -79,9 +79,9 @@ absl::Status Inventory::BuildTileset() { test_.push_back(tilesheets_[i]); } tilesheets_bmp_.Create(128, 0x130, 64, test_); - ASSIGN_OR_RETURN(auto hud_pal_group, rom()->palette_group("hud")); + auto hud_pal_group = rom()->palette_group().hud; palette_ = hud_pal_group[0]; - tilesheets_bmp_.ApplyPalette(palette_); + RETURN_IF_ERROR(tilesheets_bmp_.ApplyPalette(palette_)) rom()->RenderBitmap(&tilesheets_bmp_); return absl::OkStatus(); }