Refactor graphics sheet management with singleton class
Refactor the handling of graphics sheets by introducing a singleton class `GraphicsSheetManager`. This centralizes the management of graphics sheets, replacing direct access through the `Rom` object. Key changes include: - Updated various methods across multiple classes to use `GraphicsSheetManager::GetInstance()` for accessing and manipulating graphics sheets. - Introduced standalone functions `LoadLinkGraphics`, `LoadAllGraphicsData`, and `SaveAllGraphicsData` for loading and saving graphics data. - Refactored the `Rom` class to remove methods and member variables related to graphics sheet management. - Updated `OverworldEditor` to use `std::array` for `maps_bmp_` and added error handling for `std::bad_alloc` exceptions. - Improved code modularity and error handling throughout the application.
This commit is contained in:
@@ -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]);
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<std::string> 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_))
|
||||
|
||||
@@ -93,6 +93,7 @@ class Tile16Editor : public gfx::GfxContext, public SharedRom {
|
||||
absl::Status status_;
|
||||
|
||||
Rom transfer_rom_;
|
||||
std::array<gfx::Bitmap, kNumGfxSheets> transfer_gfx_;
|
||||
absl::Status transfer_status_;
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<gfx::Bitmap, zelda3::kNumOverworldMaps> maps_bmp_;
|
||||
gfx::BitmapTable current_graphics_set_;
|
||||
gfx::BitmapTable sprite_previews_;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "rom.h"
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
@@ -53,26 +54,27 @@ absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom &rom) {
|
||||
return sheet;
|
||||
}
|
||||
|
||||
absl::Status Rom::LoadLinkGraphics() {
|
||||
absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> 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<gfx::Bitmap, kNumLinkSheets> 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<std::array<gfx::Bitmap, kNumGfxSheets>>
|
||||
LoadAllGraphicsData(Rom& rom, bool defer_render) {
|
||||
std::array<gfx::Bitmap, kNumGfxSheets> graphics_sheets;
|
||||
std::vector<uint8_t> 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::Bitmap, kNumGfxSheets>& 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<uint8_t> 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
|
||||
|
||||
@@ -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<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
|
||||
uint32_t length) {
|
||||
uint32_t length) const {
|
||||
RETURN_IF_ERROR(ReadWritePreconditions());
|
||||
if (offset + length > static_cast<uint32_t>(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<uint8_t> 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<uint8_t> graphics_buffer_;
|
||||
|
||||
// All graphics sheets in the game
|
||||
std::array<gfx::Bitmap, kNumGfxSheets> graphics_sheets_;
|
||||
|
||||
// All graphics sheets for Link
|
||||
std::array<gfx::Bitmap, kNumLinkSheets> 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::Bitmap, kNumGfxSheets>& 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::Bitmap, kNumGfxSheets> 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<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(Rom& rom, bool defer_render = false);
|
||||
|
||||
absl::Status SaveAllGraphicsData(Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
|
||||
|
||||
/**
|
||||
* @brief Loads 2bpp graphics from Rom data.
|
||||
*
|
||||
@@ -564,6 +565,11 @@ class Rom {
|
||||
*/
|
||||
absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
|
||||
|
||||
/**
|
||||
* @brief Loads the players 4bpp graphics sheet from Rom data.
|
||||
*/
|
||||
absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(const Rom& rom);
|
||||
|
||||
/**
|
||||
* @brief A class to hold a shared pointer to a Rom object.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user