From fd73cc1bdecdc66fdea7c9242828a0d9bd487924 Mon Sep 17 00:00:00 2001 From: Justin Scofield Date: Sat, 23 Jul 2022 21:30:17 -0400 Subject: [PATCH] LoadAllGraphicsDataV2 Impl --- src/app/editor/overworld_editor.cc | 19 ++++++---- src/app/editor/overworld_editor.h | 2 ++ src/app/rom.cc | 57 ++++++++++++++++++++++-------- src/app/rom.h | 11 ++++-- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/app/editor/overworld_editor.cc b/src/app/editor/overworld_editor.cc index 5d9db1a9..1f2e0852 100644 --- a/src/app/editor/overworld_editor.cc +++ b/src/app/editor/overworld_editor.cc @@ -5,6 +5,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/status/statusor.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" @@ -275,7 +276,7 @@ void OverworldEditor::DrawTile8Selector() { ImVec2(256 + 1, kNumSheetsToLoad * 64 + 1)); graphics_bin_canvas_.UpdateContext(); if (all_gfx_loaded_) { - for (const auto &[key, value] : graphics_bin_) { + for (const auto &[key, value] : graphics_bin_v2_) { int offset = 64 * (key + 1); int top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 2; if (key >= 1) { @@ -319,12 +320,18 @@ void OverworldEditor::LoadGraphics() { rom_.LoadAllGraphicsData(); graphics_bin_ = rom_.GetGraphicsBin(); - for (auto &[key, value] : graphics_bin_) { - auto tilesheet = value.CreateTiles(); - if (!tilesheet.ok()) { - std::cout << "Error loading" << std::endl; - } + + absl::Status graphics_data_status = rom_.LoadAllGraphicsDataV2(); + if (!graphics_data_status.ok()) { + std::cout << "Error " << graphics_data_status.ToString() << std::endl; } + graphics_bin_v2_ = rom_.GetGraphicsBinV2(); + // for (auto &[key, value] : graphics_bin_) { + // auto tilesheet = value.CreateTiles(); + // if (!tilesheet.ok()) { + // std::cout << "Error loading" << std::endl; + // } + // } tile16_blockset_bmp_.Create(128 * 2, 8192 * 2, 8, 1048576); current_gfx_bmp_.Create(128 * 2, 512 * 2, 8, 32768); } diff --git a/src/app/editor/overworld_editor.h b/src/app/editor/overworld_editor.h index 6d14d08f..0b4eb8bb 100644 --- a/src/app/editor/overworld_editor.h +++ b/src/app/editor/overworld_editor.h @@ -6,6 +6,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/status/statusor.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" @@ -63,6 +64,7 @@ class OverworldEditor { ImGuiTableFlags_SizingStretchSame; std::unordered_map graphics_bin_; + absl::flat_hash_map graphics_bin_v2_; ROM rom_; zelda3::Overworld overworld_; diff --git a/src/app/rom.cc b/src/app/rom.cc index 19b6d6a3..035a26ef 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -51,7 +51,7 @@ void ROM::Close() { } void ROM::SetupRenderer(std::shared_ptr renderer) { - sdl_renderer_ = renderer; + renderer_ = renderer; } // TODO: check if the rom has a header on load @@ -100,7 +100,7 @@ void ROM::LoadAllGraphicsData() { gfx::Bitmap tilesheet_bmp(core::kTilesheetWidth, core::kTilesheetHeight, core::kTilesheetDepth, SNES3bppTo8bppSheet(data)); - tilesheet_bmp.CreateTexture(sdl_renderer_); + tilesheet_bmp.CreateTexture(renderer_); graphics_bin_[i] = tilesheet_bmp; for (int j = 0; j < sizeof(data); j++) { @@ -113,6 +113,42 @@ void ROM::LoadAllGraphicsData() { master_gfx_bin_ = buffer; } +absl::Status ROM::LoadAllGraphicsDataV2() { + Bytes sheet; + int buffer_pos = 0; + + for (int i = 0; i < core::NumberOfSheets; i++) { + if (i >= 115 && i <= 126) { // uncompressed sheets + sheet.resize(core::Uncompressed3BPPSize); + auto offset = GetGraphicsAddress(i); + for (int j = 0; j < core::Uncompressed3BPPSize; j++) { + sheet[j] = rom_data_[j + offset]; + } + } else { + auto offset = GetGraphicsAddress(i); + absl::StatusOr new_sheet = + DecompressV2(offset, core::UncompressedSheetSize); + if (!new_sheet.ok()) { + return new_sheet.status(); + } else { + sheet = std::move(*new_sheet); + } + } + + absl::StatusOr converted_sheet = Convert3bppTo8bppSheet(sheet); + if (!converted_sheet.ok()) { + return converted_sheet.status(); + } else { + Bytes result = std::move(*converted_sheet); + gfx::Bitmap tilesheet_bmp(core::kTilesheetWidth, core::kTilesheetHeight, + core::kTilesheetDepth, result.data()); + tilesheet_bmp.CreateTexture(renderer_); + graphics_bin_v2_[i] = tilesheet_bmp; + } + } + return absl::OkStatus(); +} + uint ROM::GetGraphicsAddress(uint8_t offset) const { uint snes_address = 0; uint pc_address = 0; @@ -234,15 +270,13 @@ absl::StatusOr ROM::DecompressV2(int offset, int size, bool reversed) { switch (cmd) { case kCommandDirectCopy: - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) buffer[buffer_pos++] = rom_data_[offset++]; - } // Do not advance in the ROM break; case kCommandByteFill: - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i++) buffer[buffer_pos++] = rom_data_[offset]; - } offset += 1; // Advance 1 byte in the ROM break; case kCommandWordFill: @@ -254,9 +288,7 @@ absl::StatusOr ROM::DecompressV2(int offset, int size, bool reversed) { break; case kCommandIncreasingFill: { uchar inc_byte = rom_data_[offset]; - for (int i = 0; i < length; i++) { - buffer[buffer_pos++] = inc_byte++; - } + for (int i = 0; i < length; i++) buffer[buffer_pos++] = inc_byte++; offset += 1; // Advance 1 byte in the ROM } break; case kCommandRepeatingBytes: { @@ -265,7 +297,6 @@ absl::StatusOr ROM::DecompressV2(int offset, int size, bool reversed) { // Reversed byte order for overworld maps if (reversed) { auto addr = (rom_data_[offset + 2]) | ((rom_data_[offset + 1]) << 8); - if (addr > buffer_pos) { return absl::InternalError( absl::StrFormat("DecompressOverworldV2: Offset for command " @@ -290,10 +321,6 @@ absl::StatusOr ROM::DecompressV2(int offset, int size, bool reversed) { offset += 2; // Advance 2 bytes in the ROM } } break; - default: { - return absl::InternalError( - "DecompressV2: Invalid command in the header for decompression"); - } } } @@ -411,7 +438,7 @@ SDL_Texture *ROM::DrawGraphicsSheet(int offset) { surface->pixels = sheet_buffer; std::cout << "Creating texture from surface..." << std::endl; SDL_Texture *sheet_texture = nullptr; - sheet_texture = SDL_CreateTextureFromSurface(sdl_renderer_.get(), surface); + sheet_texture = SDL_CreateTextureFromSurface(renderer_.get(), surface); if (sheet_texture == nullptr) { std::cout << "Error: " << SDL_GetError() << std::endl; } diff --git a/src/app/rom.h b/src/app/rom.h index 879590f1..3df7a519 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -10,6 +10,7 @@ #include #include +#include "absl/container/flat_hash_map.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" @@ -41,6 +42,9 @@ class ROM { public: absl::Status OpenFromFile(const absl::string_view& filename); + // absl::Status SaveOverworld(); + // absl::Status SaveDungeons(); + void Close(); void SetupRenderer(std::shared_ptr renderer); void LoadFromFile(const std::string& path); @@ -56,6 +60,7 @@ class ROM { absl::StatusOr DecompressV2(int offset, int size = 0x800, bool reversed = false); absl::StatusOr Convert3bppTo8bppSheet(Bytes sheet, int size = 0x1000); + absl::Status LoadAllGraphicsDataV2(); uchar* SNES3bppTo8bppSheet(uchar* buffer_in, int sheet_id = 0, int size = 0x1000); @@ -66,8 +71,9 @@ class ROM { uchar* data() { return current_rom_; } const uchar* getTitle() const { return title; } bool isLoaded() const { return is_loaded_; } - auto Renderer() { return sdl_renderer_; } + auto Renderer() { return renderer_; } auto GetGraphicsBin() const { return graphics_bin_; } + auto GetGraphicsBinV2() const { return graphics_bin_v2_; } auto GetMasterGraphicsBin() const { return master_gfx_bin_; } auto GetVRAM() const { return pseudo_vram_; } @@ -86,8 +92,9 @@ class ROM { std::vector decompressed_graphic_sheets_; std::vector converted_graphic_sheets_; - std::shared_ptr sdl_renderer_; + std::shared_ptr renderer_; std::unordered_map graphics_bin_; + absl::flat_hash_map graphics_bin_v2_; }; } // namespace app