diff --git a/src/app/editor/dungeon/dungeon_editor.cc b/src/app/editor/dungeon/dungeon_editor.cc index 0887fffb..618bb368 100644 --- a/src/app/editor/dungeon/dungeon_editor.cc +++ b/src/app/editor/dungeon/dungeon_editor.cc @@ -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]); diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index 48db5bf2..a7af527b 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -64,7 +64,9 @@ absl::Status EditorManager::Update() { DrawInfoPopup(); 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; } @@ -691,6 +693,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_); } diff --git a/src/app/editor/graphics/gfx_group_editor.cc b/src/app/editor/graphics/gfx_group_editor.cc index 7d984dac..ee210269 100644 --- a/src/app/editor/graphics/gfx_group_editor.cc +++ b/src/app/editor/graphics/gfx_group_editor.cc @@ -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); } diff --git a/src/app/editor/graphics/graphics_editor.cc b/src/app/editor/graphics/graphics_editor.cc index 70bf024a..025d5545 100644 --- a/src/app/editor/graphics/graphics_editor.cc +++ b/src/app/editor/graphics/graphics_editor.cc @@ -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 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,7 +152,7 @@ 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++) { ImGui::SameLine(); @@ -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_, ¤t_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 diff --git a/src/app/editor/graphics/graphics_editor.h b/src/app/editor/graphics/graphics_editor.h index 34aabd63..a1eaac25 100644 --- a/src/app/editor/graphics/graphics_editor.h +++ b/src/app/editor/graphics/graphics_editor.h @@ -176,6 +176,7 @@ class GraphicsEditor : public SharedRom, public Editor { gfx::Bitmap bin_bitmap_; gfx::Bitmap link_full_sheet_; std::array gfx_sheets_; + std::array link_sheets_; gfx::PaletteGroup col_file_palette_group_; gfx::SnesPalette z3_rom_palette_; diff --git a/src/app/editor/graphics/screen_editor.cc b/src/app/editor/graphics/screen_editor.cc index 52e430b4..c59df0f9 100644 --- a/src/app/editor/graphics/screen_editor.cc +++ b/src/app/editor/graphics/screen_editor.cc @@ -388,10 +388,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) { diff --git a/src/app/editor/graphics/tile16_editor.cc b/src/app/editor/graphics/tile16_editor.cc index f10697fc..ceeb4d54 100644 --- a/src/app/editor/graphics/tile16_editor.cc +++ b/src/app/editor/graphics/tile16_editor.cc @@ -48,7 +48,9 @@ absl::Status Tile16Editor::InitBlockset( 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 tile16_names; for (int i = 0; i < 0x200; ++i) { @@ -373,7 +375,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_)) diff --git a/src/app/editor/graphics/tile16_editor.h b/src/app/editor/graphics/tile16_editor.h index f15adee8..c2febb75 100644 --- a/src/app/editor/graphics/tile16_editor.h +++ b/src/app/editor/graphics/tile16_editor.h @@ -93,6 +93,7 @@ class Tile16Editor : public gfx::GfxContext, public SharedRom { absl::Status status_; Rom transfer_rom_; + std::array transfer_gfx_; absl::Status transfer_status_; }; diff --git a/src/app/editor/overworld/overworld_editor.cc b/src/app/editor/overworld/overworld_editor.cc index 26ea9653..1069a8f4 100644 --- a/src/app/editor/overworld/overworld_editor.cc +++ b/src/app/editor/overworld/overworld_editor.cc @@ -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) { @@ -1077,9 +1077,15 @@ absl::Status OverworldEditor::LoadGraphics() { 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) { diff --git a/src/app/editor/overworld/overworld_editor.h b/src/app/editor/overworld/overworld_editor.h index c5dd58df..f89c1477 100644 --- a/src/app/editor/overworld/overworld_editor.h +++ b/src/app/editor/overworld/overworld_editor.h @@ -252,7 +252,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext { gfx::Bitmap current_gfx_bmp_; gfx::Bitmap all_gfx_bmp; - gfx::BitmapTable maps_bmp_; + std::array maps_bmp_; gfx::BitmapTable current_graphics_set_; gfx::BitmapTable sprite_previews_; diff --git a/src/app/editor/sprite/sprite_editor.cc b/src/app/editor/sprite/sprite_editor.cc index 3e84aa66..b42ea0e1 100644 --- a/src/app/editor/sprite/sprite_editor.cc +++ b/src/app/editor/sprite/sprite_editor.cc @@ -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(); diff --git a/src/app/rom.cc b/src/app/rom.cc index 3ffcaa05..95b39eb7 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -1,5 +1,6 @@ #include "rom.h" +#include #include #include #include @@ -53,26 +54,27 @@ absl::StatusOr> Load2BppGraphics(const Rom &rom) { return sheet; } -absl::Status Rom::LoadLinkGraphics() { +absl::StatusOr> LoadLinkGraphics(const Rom& rom) { const uint32_t kLinkGfxOffset = 0x80000; // $10:8000 const uint16_t kLinkGfxLength = 0x800; // 0x4000 or 0x7000? - - // Load Links graphics from the ROM + std::array link_graphics; for (uint32_t i = 0; i < kNumLinkSheets; i++) { ASSIGN_OR_RETURN( auto link_sheet_data, - ReadByteVector(/*offset=*/kLinkGfxOffset + (i * kLinkGfxLength), - /*length=*/kLinkGfxLength)) + rom.ReadByteVector(/*offset=*/kLinkGfxOffset + (i * kLinkGfxLength), + /*length=*/kLinkGfxLength)) auto link_sheet_8bpp = gfx::SnesTo8bppSheet(link_sheet_data, /*bpp=*/4); - link_graphics_[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight, + link_graphics[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight, gfx::kTilesheetDepth, link_sheet_8bpp); - RETURN_IF_ERROR(link_graphics_[i].ApplyPalette(palette_groups_.armors[0]);) - Renderer::GetInstance().RenderBitmap(&link_graphics_[i]); + RETURN_IF_ERROR(link_graphics[i].ApplyPalette(rom.palette_group().armors[0]);) + Renderer::GetInstance().RenderBitmap(&link_graphics[i]); } - return absl::OkStatus(); + return link_graphics; } -absl::Status Rom::LoadAllGraphicsData(bool defer_render) { +absl::StatusOr> +LoadAllGraphicsData(Rom& rom, bool defer_render) { + std::array graphics_sheets; std::vector sheet; bool bpp3 = false; @@ -80,60 +82,60 @@ absl::Status Rom::LoadAllGraphicsData(bool defer_render) { if (i >= 115 && i <= 126) { // uncompressed sheets sheet.resize(Uncompressed3BPPSize); auto offset = - GetGraphicsAddress(data(), i, version_constants().kOverworldGfxPtr1, - version_constants().kOverworldGfxPtr2, - version_constants().kOverworldGfxPtr3); - for (int j = 0; j < Uncompressed3BPPSize; j++) { - sheet[j] = rom_data_[j + offset]; - } + GetGraphicsAddress(rom.data(), i, rom.version_constants().kOverworldGfxPtr1, + rom.version_constants().kOverworldGfxPtr2, + rom.version_constants().kOverworldGfxPtr3); + std::copy(rom.data() + offset, rom.data() + offset + Uncompressed3BPPSize, + sheet.begin()); bpp3 = true; } else if (i == 113 || i == 114 || i >= 218) { bpp3 = false; } else { auto offset = - GetGraphicsAddress(data(), i, version_constants().kOverworldGfxPtr1, - version_constants().kOverworldGfxPtr2, - version_constants().kOverworldGfxPtr3); + GetGraphicsAddress(rom.data(), i, rom.version_constants().kOverworldGfxPtr1, + rom.version_constants().kOverworldGfxPtr2, + rom.version_constants().kOverworldGfxPtr3); ASSIGN_OR_RETURN(sheet, - gfx::lc_lz2::DecompressV2(rom_data_.data(), offset)) + gfx::lc_lz2::DecompressV2(rom.data(), offset)) bpp3 = true; } if (bpp3) { auto converted_sheet = gfx::SnesTo8bppSheet(sheet, 3); - graphics_sheets_[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight, + graphics_sheets[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight, gfx::kTilesheetDepth, converted_sheet); - if (graphics_sheets_[i].is_active()) { + if (graphics_sheets[i].is_active()) { if (i > 115) { // Apply sprites palette - RETURN_IF_ERROR(graphics_sheets_[i].ApplyPaletteWithTransparent( - palette_groups_.global_sprites[0], 0)); + RETURN_IF_ERROR(graphics_sheets[i].ApplyPaletteWithTransparent( + rom.palette_group().global_sprites[0], 0)); } else { - RETURN_IF_ERROR(graphics_sheets_[i].ApplyPaletteWithTransparent( - palette_groups_.dungeon_main[0], 0)); + RETURN_IF_ERROR(graphics_sheets[i].ApplyPaletteWithTransparent( + rom.palette_group().dungeon_main[0], 0)); } } if (!defer_render) { - graphics_sheets_[i].CreateTexture(Renderer::GetInstance().renderer()); + graphics_sheets[i].CreateTexture(Renderer::GetInstance().renderer()); } - for (int j = 0; j < graphics_sheets_[i].size(); ++j) { - graphics_buffer_.push_back(graphics_sheets_[i].at(j)); + for (int j = 0; j < graphics_sheets[i].size(); ++j) { + rom.mutable_graphics_buffer()->push_back(graphics_sheets[i].at(j)); } } else { - for (int j = 0; j < graphics_sheets_[0].size(); ++j) { - graphics_buffer_.push_back(0xFF); + for (int j = 0; j < graphics_sheets[0].size(); ++j) { + rom.mutable_graphics_buffer()->push_back(0xFF); } } } - return absl::OkStatus(); + return graphics_sheets; } -absl::Status Rom::SaveAllGraphicsData() { +absl::Status +SaveAllGraphicsData(Rom& rom, std::array& gfx_sheets) { for (int i = 0; i < kNumGfxSheets; i++) { - if (graphics_sheets_[i].is_active()) { + if (gfx_sheets[i].is_active()) { int to_bpp = 3; std::vector final_data; bool compressed = true; @@ -145,7 +147,7 @@ absl::Status Rom::SaveAllGraphicsData() { } std::cout << "Sheet ID " << i << " BPP: " << to_bpp << std::endl; - auto sheet_data = graphics_sheets_[i].vector(); + auto sheet_data = gfx_sheets[i].vector(); std::cout << "Sheet data size: " << sheet_data.size() << std::endl; final_data = gfx::Bpp8SnesToIndexed(sheet_data, 8); int size = 0; @@ -157,11 +159,10 @@ absl::Status Rom::SaveAllGraphicsData() { } } auto offset = - GetGraphicsAddress(data(), i, version_constants().kOverworldGfxPtr1, - version_constants().kOverworldGfxPtr2, - version_constants().kOverworldGfxPtr3); - std::copy(final_data.begin(), final_data.end(), - rom_data_.begin() + offset); + GetGraphicsAddress(rom.data(), i, rom.version_constants().kOverworldGfxPtr1, + rom.version_constants().kOverworldGfxPtr2, + rom.version_constants().kOverworldGfxPtr3); + std::copy(final_data.begin(), final_data.end(), rom.begin() + offset); } } return absl::OkStatus(); @@ -319,8 +320,6 @@ absl::Status Rom::SaveToFile(bool backup, bool save_new, std::string filename) { RETURN_IF_ERROR(SaveAllPalettes()); if (core::ExperimentFlags::get().kSaveGfxGroups) RETURN_IF_ERROR(SaveGroupsToRom()); - if (core::ExperimentFlags::get().kSaveGraphicsSheet) - RETURN_IF_ERROR(SaveAllGraphicsData()); if (save_new) { // Create a file of the same name and append the date between the filename diff --git a/src/app/rom.h b/src/app/rom.h index ebf7850c..5cc4ab31 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -133,31 +133,6 @@ constexpr uint32_t kMaxGraphics = 0xC3FB5; */ class Rom { public: - /** - * @brief Loads the players 4bpp graphics sheet from Rom data. - */ - absl::Status LoadLinkGraphics(); - - /** - * @brief This function iterates over all graphics sheets in the Rom and loads - * them into memory. Depending on the sheet's index, it may be uncompressed or - * compressed using the LC-LZ2 algorithm. The uncompressed sheets are 3 bits - * per pixel (BPP), while the compressed sheets are 4 BPP. The loaded graphics - * data is converted to 8 BPP and stored in a bitmap. - * - * The graphics sheets are divided into the following ranges: - * - * | Range | Compression Type | Decompressed Size | Number of Chars | - * |---------|------------------|------------------|-----------------| - * | 0-112 | Compressed 3bpp BGR | 0x600 chars | Decompressed each | - * | 113-114 | Compressed 2bpp | 0x800 chars | Decompressed each | - * | 115-126 | Uncompressed 3bpp sprites | 0x600 chars | Each | - * | 127-217 | Compressed 3bpp sprites | 0x600 chars | Decompressed each | - * | 218-222 | Compressed 2bpp | 0x800 chars | Decompressed each | - * - */ - absl::Status LoadAllGraphicsData(bool defer_render = false); - /** * Load Rom data from a file. * @@ -181,8 +156,6 @@ class Rom { absl::Status SaveToFile(bool backup, bool save_new = false, std::string filename = ""); - absl::Status SaveAllGraphicsData(); - /** * Saves the given palette to the Rom if any of its colors have been modified. * @@ -222,7 +195,7 @@ class Rom { /** * @brief Precondition check for reading and writing to the Rom. */ - absl::Status ReadWritePreconditions() { + absl::Status ReadWritePreconditions() const { if (!is_loaded_) { return absl::FailedPreconditionError("ROM file not loaded"); } @@ -266,7 +239,7 @@ class Rom { } absl::StatusOr> ReadByteVector(uint32_t offset, - uint32_t length) { + uint32_t length) const { RETURN_IF_ERROR(ReadWritePreconditions()); if (offset + length > static_cast(rom_data_.size())) { return absl::OutOfRangeError("Offset and length out of range"); @@ -436,6 +409,7 @@ class Rom { // Full graphical data for the game std::vector graphics_buffer() const { return graphics_buffer_; } + auto mutable_graphics_buffer() { return &graphics_buffer_; } auto title() const { return title_; } auto size() const { return size_; } @@ -450,12 +424,7 @@ class Rom { auto filename() const { return filename_; } auto set_filename(std::string name) { filename_ = name; } - auto link_graphics() { return link_graphics_; } - auto mutable_link_graphics() { return &link_graphics_; } - auto gfx_sheets() { return graphics_sheets_; } - auto mutable_gfx_sheets() { return &graphics_sheets_; } - - auto palette_group() { return palette_groups_; } + auto palette_group() const { 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) { @@ -538,12 +507,6 @@ class Rom { // Full contiguous graphics space std::vector graphics_buffer_; - // All graphics sheets in the game - std::array graphics_sheets_; - - // All graphics sheets for Link - std::array link_graphics_; - // Label manager for unique resource names. ResourceLabelManager resource_label_manager_; @@ -554,6 +517,44 @@ class Rom { Z3_Version version_ = Z3_Version::US; }; +class GraphicsSheetManager { +public: + static GraphicsSheetManager& GetInstance() { + static GraphicsSheetManager instance; + return instance; + } + GraphicsSheetManager() = default; + virtual ~GraphicsSheetManager() = default; + std::array& gfx_sheets() { return gfx_sheets_; } + auto gfx_sheet(int i) { return gfx_sheets_[i]; } + auto mutable_gfx_sheet(int i) { return &gfx_sheets_[i]; } + auto mutable_gfx_sheets() { return &gfx_sheets_; } +private: + std::array gfx_sheets_; +}; + +/** + * @brief This function iterates over all graphics sheets in the Rom and loads + * them into memory. Depending on the sheet's index, it may be uncompressed or + * compressed using the LC-LZ2 algorithm. The uncompressed sheets are 3 bits + * per pixel (BPP), while the compressed sheets are 4 BPP. The loaded graphics + * data is converted to 8 BPP and stored in a bitmap. + * + * The graphics sheets are divided into the following ranges: + * + * | Range | Compression Type | Decompressed Size | Number of Chars | + * |---------|------------------|------------------|-----------------| + * | 0-112 | Compressed 3bpp BGR | 0x600 chars | Decompressed each | + * | 113-114 | Compressed 2bpp | 0x800 chars | Decompressed each | + * | 115-126 | Uncompressed 3bpp sprites | 0x600 chars | Each | + * | 127-217 | Compressed 3bpp sprites | 0x600 chars | Decompressed each | + * | 218-222 | Compressed 2bpp | 0x800 chars | Decompressed each | + * + */ +absl::StatusOr> LoadAllGraphicsData(Rom& rom, bool defer_render = false); + +absl::Status SaveAllGraphicsData(Rom& rom, std::array& gfx_sheets); + /** * @brief Loads 2bpp graphics from Rom data. * @@ -564,6 +565,11 @@ class Rom { */ absl::StatusOr> Load2BppGraphics(const Rom& rom); +/** + * @brief Loads the players 4bpp graphics sheet from Rom data. + */ +absl::StatusOr> LoadLinkGraphics(const Rom& rom); + /** * @brief A class to hold a shared pointer to a Rom object. */ diff --git a/src/app/zelda3/dungeon/object_renderer.cc b/src/app/zelda3/dungeon/object_renderer.cc index 7cf77ba2..1c5f34ed 100644 --- a/src/app/zelda3/dungeon/object_renderer.cc +++ b/src/app/zelda3/dungeon/object_renderer.cc @@ -102,7 +102,7 @@ void DungeonObjectRenderer::UpdateObjectBitmap() { int x = column * 8; int y = row * 8; - auto sheet = rom()->mutable_gfx_sheets()->at(vram_.sheets[sheet_number]); + auto sheet = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(vram_.sheets[sheet_number]); // Copy the tile from VRAM using the read tile_id sheet.Get8x8Tile(tile_id, x, y, tilemap_, tilemap_offset);