Refactor overworld constructors to accept Rom pointers

This commit is contained in:
scawful
2025-04-12 11:27:23 -04:00
parent cb86c7b2ec
commit 42cfb3bcb2
10 changed files with 280 additions and 235 deletions

View File

@@ -78,6 +78,8 @@ class Editor {
virtual absl::Status Clear() { return absl::OkStatus(); } virtual absl::Status Clear() { return absl::OkStatus(); }
virtual void CleanupUnusedTextures(uint64_t current_time, uint64_t timeout) { }
EditorType type() const { return type_; } EditorType type() const { return type_; }
void set_context(EditorContext* context) { context_ = context; } void set_context(EditorContext* context) { context_ = context; }

View File

@@ -300,6 +300,15 @@ absl::Status EditorManager::Update() {
ImGui::End(); ImGui::End();
} }
} }
static uint64_t last_cleanup_time = 0;
uint64_t current_time = SDL_GetTicks64();
// Clean up unused textures every 5 seconds
if (current_time - last_cleanup_time > 5000) {
current_editor_set_->CleanupUnusedTextures(current_time, 5000);
last_cleanup_time = current_time;
}
} }
if (show_homepage_) { if (show_homepage_) {
@@ -481,6 +490,7 @@ absl::Status EditorManager::LoadAssets() {
return absl::FailedPreconditionError("No ROM or editor set loaded"); return absl::FailedPreconditionError("No ROM or editor set loaded");
} }
current_editor_set_->overworld_editor_.Initialize(); current_editor_set_->overworld_editor_.Initialize();
current_editor_set_->message_editor_.Initialize();
auto &sheet_manager = GraphicsSheetManager::GetInstance(); auto &sheet_manager = GraphicsSheetManager::GetInstance();
ASSIGN_OR_RETURN(*sheet_manager.mutable_gfx_sheets(), ASSIGN_OR_RETURN(*sheet_manager.mutable_gfx_sheets(),

View File

@@ -51,17 +51,17 @@ class EditorManager {
context_.popup_manager = popup_manager_.get(); context_.popup_manager = popup_manager_.get();
} }
void Initialize(const std::string &filename = ""); void Initialize(const std::string& filename = "");
absl::Status Update(); absl::Status Update();
void DrawMenuBar(); void DrawMenuBar();
auto emulator() -> emu::Emulator & { return emulator_; } auto emulator() -> emu::Emulator& { return emulator_; }
auto quit() const { return quit_; } auto quit() const { return quit_; }
auto version() const { return version_; } auto version() const { return version_; }
absl::Status SetCurrentRom(Rom *rom); absl::Status SetCurrentRom(Rom* rom);
auto GetRoms() -> std::vector<std::unique_ptr<Rom>> & { return roms_; } auto GetRoms() -> std::vector<std::unique_ptr<Rom>>& { return roms_; }
auto GetCurrentRom() -> Rom * { return current_rom_; } auto GetCurrentRom() -> Rom* { return current_rom_; }
auto GetCurrentEditorSet() -> EditorSet* { return current_editor_set_; } auto GetCurrentEditorSet() -> EditorSet* { return current_editor_set_; }
private: private:
@@ -71,7 +71,7 @@ class EditorManager {
absl::Status LoadRom(); absl::Status LoadRom();
absl::Status LoadAssets(); absl::Status LoadAssets();
absl::Status SaveRom(); absl::Status SaveRom();
absl::Status OpenRomOrProject(const std::string &filename); absl::Status OpenRomOrProject(const std::string& filename);
absl::Status OpenProject(); absl::Status OpenProject();
absl::Status SaveProject(); absl::Status SaveProject();
@@ -110,38 +110,46 @@ class EditorManager {
* @brief Contains a complete set of editors for a single ROM instance * @brief Contains a complete set of editors for a single ROM instance
*/ */
class EditorSet { class EditorSet {
public: public:
explicit EditorSet(Rom* rom) explicit EditorSet(Rom* rom = nullptr)
: assembly_editor_(rom), : assembly_editor_(rom),
dungeon_editor_(rom), dungeon_editor_(rom),
graphics_editor_(rom), graphics_editor_(rom),
music_editor_(rom), music_editor_(rom),
overworld_editor_(*rom), overworld_editor_(rom),
palette_editor_(rom), palette_editor_(rom),
screen_editor_(rom), screen_editor_(rom),
sprite_editor_(rom), sprite_editor_(rom),
settings_editor_(rom), settings_editor_(rom),
message_editor_(rom), message_editor_(rom),
memory_editor_(rom) { memory_editor_(rom) {
active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_, active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_,
&palette_editor_, &sprite_editor_, &message_editor_, &palette_editor_, &sprite_editor_, &message_editor_,
&music_editor_, &screen_editor_, &settings_editor_, &music_editor_, &screen_editor_, &settings_editor_,
&assembly_editor_}; &assembly_editor_};
} }
AssemblyEditor assembly_editor_; AssemblyEditor assembly_editor_;
DungeonEditor dungeon_editor_; DungeonEditor dungeon_editor_;
GraphicsEditor graphics_editor_; GraphicsEditor graphics_editor_;
MusicEditor music_editor_; MusicEditor music_editor_;
OverworldEditor overworld_editor_; OverworldEditor overworld_editor_;
PaletteEditor palette_editor_; PaletteEditor palette_editor_;
ScreenEditor screen_editor_; ScreenEditor screen_editor_;
SpriteEditor sprite_editor_; SpriteEditor sprite_editor_;
SettingsEditor settings_editor_; SettingsEditor settings_editor_;
MessageEditor message_editor_; MessageEditor message_editor_;
MemoryEditorWithDiffChecker memory_editor_; MemoryEditorWithDiffChecker memory_editor_;
std::vector<Editor*> active_editors_; std::vector<Editor*> active_editors_;
void CleanupUnusedTextures(uint64_t current_time, uint64_t timeout) {
if (active_editors_.size() > 0) {
for (auto editor : active_editors_) {
editor->CleanupUnusedTextures(current_time, timeout);
}
}
}
}; };
} // namespace editor } // namespace editor

View File

@@ -32,30 +32,7 @@ namespace yaze {
namespace editor { namespace editor {
using core::Renderer; using core::Renderer;
using ImGui::BeginChild; using namespace ImGui;
using ImGui::BeginTabBar;
using ImGui::BeginTabItem;
using ImGui::BeginTable;
using ImGui::BeginTooltip;
using ImGui::Button;
using ImGui::Checkbox;
using ImGui::EndChild;
using ImGui::EndTabBar;
using ImGui::EndTabItem;
using ImGui::EndTable;
using ImGui::EndTooltip;
using ImGui::IsItemHovered;
using ImGui::NewLine;
using ImGui::PopStyleColor;
using ImGui::PushStyleColor;
using ImGui::SameLine;
using ImGui::Selectable;
using ImGui::Separator;
using ImGui::TableHeadersRow;
using ImGui::TableNextColumn;
using ImGui::TableNextRow;
using ImGui::TableSetupColumn;
using ImGui::Text;
constexpr int kTile16Size = 0x10; constexpr int kTile16Size = 0x10;
@@ -70,19 +47,19 @@ void OverworldEditor::Initialize() {
gui::zeml::Bind(&*layout_node_.GetNode("OverworldTileSelector"), gui::zeml::Bind(&*layout_node_.GetNode("OverworldTileSelector"),
[this]() { status_ = DrawTileSelector(); }); [this]() { status_ = DrawTileSelector(); });
gui::zeml::Bind(&*layout_node_.GetNode("OwUsageStats"), [this]() { gui::zeml::Bind(&*layout_node_.GetNode("OwUsageStats"), [this]() {
if (rom_.is_loaded()) { if (rom_->is_loaded()) {
status_ = UpdateUsageStats(); status_ = UpdateUsageStats();
} }
}); });
gui::zeml::Bind(&*layout_node_.GetNode("owToolset"), gui::zeml::Bind(&*layout_node_.GetNode("owToolset"),
[this]() { DrawToolset(); }); [this]() { DrawToolset(); });
gui::zeml::Bind(&*layout_node_.GetNode("OwTile16Editor"), [this]() { gui::zeml::Bind(&*layout_node_.GetNode("OwTile16Editor"), [this]() {
if (rom_.is_loaded()) { if (rom_->is_loaded()) {
status_ = tile16_editor_.Update(); status_ = tile16_editor_.Update();
} }
}); });
gui::zeml::Bind(&*layout_node_.GetNode("OwGfxGroupEditor"), [this]() { gui::zeml::Bind(&*layout_node_.GetNode("OwGfxGroupEditor"), [this]() {
if (rom_.is_loaded()) { if (rom_->is_loaded()) {
status_ = gfx_group_editor_.Update(); status_ = gfx_group_editor_.Update();
} }
}); });
@@ -1072,7 +1049,7 @@ absl::Status OverworldEditor::LoadGraphics() {
map_blockset_loaded_ = true; map_blockset_loaded_ = true;
// Copy the tile16 data into individual tiles. // Copy the tile16 data into individual tiles.
auto tile16_data = overworld_.tile16_blockset_data(); auto tile16_blockset_data = overworld_.tile16_blockset_data();
util::logf("Loading overworld tile16 graphics."); util::logf("Loading overworld tile16 graphics.");
// Loop through the tiles and copy their pixel data into separate vectors // Loop through the tiles and copy their pixel data into separate vectors
@@ -1084,9 +1061,9 @@ absl::Status OverworldEditor::LoadGraphics() {
for (int ty = 0; ty < kTile16Size; ty++) { for (int ty = 0; ty < kTile16Size; ty++) {
for (int tx = 0; tx < kTile16Size; tx++) { for (int tx = 0; tx < kTile16Size; tx++) {
int position = tx + (ty * kTile16Size); int position = tx + (ty * kTile16Size);
uint8_t value = uint8_t value = tile16_blockset_data[(i % 8 * kTile16Size) +
tile16_data[(i % 8 * kTile16Size) + (i / 8 * kTile16Size * 0x80) + (i / 8 * kTile16Size * 0x80) +
(ty * 0x80) + tx]; (ty * 0x80) + tx];
tile16_individual_[i].mutable_data()[position] = value; tile16_individual_[i].mutable_data()[position] = value;
} }
} }
@@ -1400,7 +1377,7 @@ absl::Status OverworldEditor::UpdateUsageStats() {
if (BeginChild("UnusedSpritesetScroll", ImVec2(0, 0), true, if (BeginChild("UnusedSpritesetScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar)) { ImGuiWindowFlags_HorizontalScrollbar)) {
for (int i = 0; i < 0x81; i++) { for (int i = 0; i < 0x81; i++) {
auto entrance_name = rom_.resource_label()->CreateOrGetLabel( auto entrance_name = rom_->resource_label()->CreateOrGetLabel(
"Dungeon Entrance Names", util::HexByte(i), "Dungeon Entrance Names", util::HexByte(i),
zelda3::kEntranceNames[i].data()); zelda3::kEntranceNames[i].data());
std::string str = absl::StrFormat("%#x - %s", i, entrance_name); std::string str = absl::StrFormat("%#x - %s", i, entrance_name);
@@ -1516,5 +1493,34 @@ void OverworldEditor::DrawDebugWindow() {
} }
} }
absl::Status OverworldEditor::Clear() {
overworld_.Destroy();
current_graphics_set_.clear();
for (auto &bmp : tile16_individual_) {
bmp.Clear();
}
for (auto &bmp : maps_bmp_) {
bmp.Clear();
}
for (auto &bmp : sprite_previews_) {
bmp.Clear();
}
tile16_blockset_bmp_.Clear();
current_gfx_bmp_.Clear();
all_gfx_loaded_ = false;
map_blockset_loaded_ = false;
return absl::OkStatus();
}
void OverworldEditor::CleanupUnusedTextures(uint64_t current_time,
uint64_t timeout) {
for (auto &bmp : tile16_individual_) {
bmp.CleanupUnusedTexture(current_time, timeout);
}
for (auto &bmp : maps_bmp_) {
bmp.CleanupUnusedTexture(current_time, timeout);
}
}
} // namespace editor } // namespace editor
} // namespace yaze } // namespace yaze

View File

@@ -74,7 +74,7 @@ constexpr absl::string_view kOWMapTable = "#MapSettingsTable";
*/ */
class OverworldEditor : public Editor, public gfx::GfxContext { class OverworldEditor : public Editor, public gfx::GfxContext {
public: public:
OverworldEditor(Rom& rom) : rom_(rom) { type_ = EditorType::kOverworld; } explicit OverworldEditor(Rom* rom) : rom_(rom) { type_ = EditorType::kOverworld; }
void Initialize() override; void Initialize() override;
absl::Status Load() override; absl::Status Load() override;
@@ -215,7 +215,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
std::vector<std::vector<uint8_t>> tile8_individual_data_; std::vector<std::vector<uint8_t>> tile8_individual_data_;
std::vector<gfx::Bitmap> tile8_individual_; std::vector<gfx::Bitmap> tile8_individual_;
Rom& rom_; Rom* rom_;
Tile16Editor tile16_editor_{tile16_individual_}; Tile16Editor tile16_editor_{tile16_individual_};
GfxGroupEditor gfx_group_editor_; GfxGroupEditor gfx_group_editor_;

View File

@@ -17,8 +17,8 @@
namespace yaze { namespace yaze {
namespace zelda3 { namespace zelda3 {
absl::Status Overworld::Load(Rom &rom) { absl::Status Overworld::Load(Rom *rom) {
if (rom.size() == 0) { if (rom->size() == 0) {
return absl::InvalidArgumentError("ROM file not loaded"); return absl::InvalidArgumentError("ROM file not loaded");
} }
rom_ = rom; rom_ = rom;
@@ -97,10 +97,10 @@ void Overworld::FetchLargeMaps() {
absl::StatusOr<uint16_t> Overworld::GetTile16ForTile32( absl::StatusOr<uint16_t> Overworld::GetTile16ForTile32(
int index, int quadrant, int dimension, const uint32_t *map32address) { int index, int quadrant, int dimension, const uint32_t *map32address) {
ASSIGN_OR_RETURN(auto arg1, ASSIGN_OR_RETURN(
rom_.ReadByte(map32address[dimension] + quadrant + (index))); auto arg1, rom()->ReadByte(map32address[dimension] + quadrant + (index)));
ASSIGN_OR_RETURN(auto arg2, rom_.ReadWord(map32address[dimension] + (index) + ASSIGN_OR_RETURN(auto arg2, rom()->ReadWord(map32address[dimension] + (index) +
(quadrant <= 1 ? 4 : 5))); (quadrant <= 1 ? 4 : 5)));
return (uint16_t)(arg1 + return (uint16_t)(arg1 +
(((arg2 >> (quadrant % 2 == 0 ? 4 : 0)) & 0x0F) * 256)); (((arg2 >> (quadrant % 2 == 0 ? 4 : 0)) & 0x0F) * 256));
} }
@@ -108,13 +108,13 @@ absl::StatusOr<uint16_t> Overworld::GetTile16ForTile32(
absl::Status Overworld::AssembleMap32Tiles() { absl::Status Overworld::AssembleMap32Tiles() {
constexpr int kMap32TilesLength = 0x33F0; constexpr int kMap32TilesLength = 0x33F0;
int num_tile32 = kMap32TilesLength; int num_tile32 = kMap32TilesLength;
uint32_t map32address[4] = {rom_.version_constants().kMap32TileTL, uint32_t map32address[4] = {rom()->version_constants().kMap32TileTL,
rom_.version_constants().kMap32TileTR, rom()->version_constants().kMap32TileTR,
rom_.version_constants().kMap32TileBL, rom()->version_constants().kMap32TileBL,
rom_.version_constants().kMap32TileBR}; rom()->version_constants().kMap32TileBR};
if (rom()->data()[kMap32ExpandedFlagPos] != 0x04 && if (rom()->data()[kMap32ExpandedFlagPos] != 0x04 &&
core::FeatureFlags::get().overworld.kLoadCustomOverworld) { core::FeatureFlags::get().overworld.kLoadCustomOverworld) {
map32address[0] = rom_.version_constants().kMap32TileTL; map32address[0] = rom()->version_constants().kMap32TileTL;
map32address[1] = kMap32TileTRExpanded; map32address[1] = kMap32TileTRExpanded;
map32address[2] = kMap32TileBLExpanded; map32address[2] = kMap32TileBLExpanded;
map32address[3] = kMap32TileBRExpanded; map32address[3] = kMap32TileBRExpanded;
@@ -338,10 +338,8 @@ absl::Status Overworld::LoadEntrances() {
absl::Status Overworld::LoadHoles() { absl::Status Overworld::LoadHoles() {
constexpr int kNumHoles = 0x13; constexpr int kNumHoles = 0x13;
for (int i = 0; i < kNumHoles; i++) { for (int i = 0; i < kNumHoles; i++) {
ASSIGN_OR_RETURN(auto map_id, ASSIGN_OR_RETURN(auto map_id, rom()->ReadWord(kOverworldHoleArea + (i * 2)));
rom()->ReadWord(kOverworldHoleArea + (i * 2))); ASSIGN_OR_RETURN(auto map_pos, rom()->ReadWord(kOverworldHolePos + (i * 2)));
ASSIGN_OR_RETURN(auto map_pos,
rom()->ReadWord(kOverworldHolePos + (i * 2)));
ASSIGN_OR_RETURN(auto entrance_id, ASSIGN_OR_RETURN(auto entrance_id,
rom()->ReadByte(kOverworldHoleEntrance + i)); rom()->ReadByte(kOverworldHoleEntrance + i));
int p = (map_pos + 0x400) >> 1; int p = (map_pos + 0x400) >> 1;
@@ -412,8 +410,7 @@ absl::Status Overworld::LoadItems() {
rom()->ReadLong(zelda3::kOverworldItemsAddress)); rom()->ReadLong(zelda3::kOverworldItemsAddress));
uint32_t pointer_pc = SnesToPc(pointer); // 1BC2F9 -> 0DC2F9 uint32_t pointer_pc = SnesToPc(pointer); // 1BC2F9 -> 0DC2F9
for (int i = 0; i < 128; i++) { for (int i = 0; i < 128; i++) {
ASSIGN_OR_RETURN(uint16_t word_address, ASSIGN_OR_RETURN(uint16_t word_address, rom()->ReadWord(pointer_pc + i * 2));
rom()->ReadWord(pointer_pc + i * 2));
uint32_t addr = (pointer & 0xFF0000) | word_address; // 1B F9 3C uint32_t addr = (pointer & 0xFF0000) | word_address; // 1B F9 3C
addr = SnesToPc(addr); addr = SnesToPc(addr);
@@ -515,7 +512,7 @@ absl::Status Overworld::LoadSpritesFromMap(int sprites_per_gamestate_ptr,
return absl::OkStatus(); return absl::OkStatus();
} }
absl::Status Overworld::Save(Rom &rom) { absl::Status Overworld::Save(Rom *rom) {
rom_ = rom; rom_ = rom;
if (expanded_tile16_) RETURN_IF_ERROR(SaveMap16Expanded()) if (expanded_tile16_) RETURN_IF_ERROR(SaveMap16Expanded())
RETURN_IF_ERROR(SaveMap16Tiles()) RETURN_IF_ERROR(SaveMap16Tiles())
@@ -676,8 +673,8 @@ absl::Status Overworld::SaveLargeMaps() {
int parent_x_pos = overworld_maps_[i].parent() % 8; int parent_x_pos = overworld_maps_[i].parent() % 8;
// Always write the map parent since it should not matter // Always write the map parent since it should not matter
RETURN_IF_ERROR(rom()->WriteByte(kOverworldMapParentId + i, RETURN_IF_ERROR(
overworld_maps_[i].parent())) rom()->WriteByte(kOverworldMapParentId + i, overworld_maps_[i].parent()))
if (std::find(checked_map.begin(), checked_map.end(), i) != if (std::find(checked_map.begin(), checked_map.end(), i) !=
checked_map.end()) { checked_map.end()) {
@@ -700,72 +697,72 @@ absl::Status Overworld::SaveLargeMaps() {
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldScreenSize + i + offset + 64, 0x00)); rom()->WriteByte(kOverworldScreenSize + i + offset + 64, 0x00));
// Check 4 // Check 4
RETURN_IF_ERROR(rom()->WriteByte( RETURN_IF_ERROR(
kOverworldScreenSizeForLoading + i + offset, 0x04)); rom()->WriteByte(kOverworldScreenSizeForLoading + i + offset, 0x04));
RETURN_IF_ERROR(rom()->WriteByte( RETURN_IF_ERROR(rom()->WriteByte(
kOverworldScreenSizeForLoading + i + offset + kDarkWorldMapIdStart, kOverworldScreenSizeForLoading + i + offset + kDarkWorldMapIdStart,
0x04)); 0x04));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldScreenSizeForLoading + i + RETURN_IF_ERROR(rom()->WriteByte(kOverworldScreenSizeForLoading + i +
offset + kSpecialWorldMapIdStart, offset + kSpecialWorldMapIdStart,
0x04)); 0x04));
} }
// Check 5 and 6 // Check 5 and 6
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetNorth + (i * 2), rom()->WriteShort(kTransitionTargetNorth + (i * 2),
(uint16_t)((parent_y_pos * 0x200) - 0xE0))); (uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetWest + (i * 2), rom()->WriteShort(kTransitionTargetWest + (i * 2),
(uint16_t)((parent_x_pos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 2, rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 2,
(uint16_t)((parent_y_pos * 0x200) - 0xE0))); (uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetWest + (i * 2) + 2, rom()->WriteShort(kTransitionTargetWest + (i * 2) + 2,
(uint16_t)((parent_x_pos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 16, rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 16,
(uint16_t)((parent_y_pos * 0x200) - 0xE0))); (uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetWest + (i * 2) + 16, rom()->WriteShort(kTransitionTargetWest + (i * 2) + 16,
(uint16_t)((parent_x_pos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 18, rom()->WriteShort(kTransitionTargetNorth + (i * 2) + 18,
(uint16_t)((parent_y_pos * 0x200) - 0xE0))); (uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kTransitionTargetWest + (i * 2) + 18, rom()->WriteShort(kTransitionTargetWest + (i * 2) + 18,
(uint16_t)((parent_x_pos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
// Check 7 and 8 // Check 7 and 8
RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionX + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionX + (i * 2),
(parent_x_pos * 0x200))); (parent_x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionY + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionY + (i * 2),
(parent_y_pos * 0x200))); (parent_y_pos * 0x200)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 02, rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 02,
(parent_x_pos * 0x200))); (parent_x_pos * 0x200)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 02, rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 02,
(parent_y_pos * 0x200))); (parent_y_pos * 0x200)));
// problematic // problematic
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 16, rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 16,
(parent_x_pos * 0x200))); (parent_x_pos * 0x200)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 16, rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 16,
(parent_y_pos * 0x200))); (parent_y_pos * 0x200)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 18, rom()->WriteShort(kOverworldTransitionPositionX + (i * 2) + 18,
(parent_x_pos * 0x200))); (parent_x_pos * 0x200)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 18, rom()->WriteShort(kOverworldTransitionPositionY + (i * 2) + 18,
(parent_y_pos * 0x200))); (parent_y_pos * 0x200)));
// Check 9 // Check 9
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -958,14 +955,14 @@ absl::Status Overworld::SaveLargeMaps() {
} }
RETURN_IF_ERROR(rom()->WriteShort(kTransitionTargetNorth + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kTransitionTargetNorth + (i * 2),
(uint16_t)((y_pos * 0x200) - 0xE0))); (uint16_t)((y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR(rom()->WriteShort(kTransitionTargetWest + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kTransitionTargetWest + (i * 2),
(uint16_t)((x_pos * 0x200) - 0x100))); (uint16_t)((x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionX + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionX + (i * 2),
(x_pos * 0x200))); (x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionY + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldTransitionPositionY + (i * 2),
(y_pos * 0x200))); (y_pos * 0x200)));
checked_map.emplace_back(i); checked_map.emplace_back(i);
} }
@@ -1352,17 +1349,13 @@ absl::Status Overworld::SaveMap16Tiles() {
int tpos = kMap16Tiles; int tpos = kMap16Tiles;
// 3760 // 3760
for (int i = 0; i < NumberOfMap16; i += 1) { for (int i = 0; i < NumberOfMap16; i += 1) {
RETURN_IF_ERROR( RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile0_)))
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile0_)))
tpos += 2; tpos += 2;
RETURN_IF_ERROR( RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile1_)))
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile1_)))
tpos += 2; tpos += 2;
RETURN_IF_ERROR( RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile2_)))
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile2_)))
tpos += 2; tpos += 2;
RETURN_IF_ERROR( RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile3_)))
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile3_)))
tpos += 2; tpos += 2;
} }
return absl::OkStatus(); return absl::OkStatus();
@@ -1383,11 +1376,11 @@ absl::Status Overworld::SaveEntrances() {
for (int i = 0; i < kNumOverworldEntrances; i++) { for (int i = 0; i < kNumOverworldEntrances; i++) {
RETURN_IF_ERROR(rom()->WriteShort(kOverworldEntranceMap + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldEntranceMap + (i * 2),
all_entrances_[i].map_id_)) all_entrances_[i].map_id_))
RETURN_IF_ERROR(rom()->WriteShort(kOverworldEntrancePos + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(kOverworldEntrancePos + (i * 2),
all_entrances_[i].map_pos_)) all_entrances_[i].map_pos_))
RETURN_IF_ERROR(rom()->WriteByte(kOverworldEntranceEntranceId + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldEntranceEntranceId + i,
all_entrances_[i].entrance_id_)) all_entrances_[i].entrance_id_))
} }
for (int i = 0; i < kNumOverworldHoles; i++) { for (int i = 0; i < kNumOverworldHoles; i++) {
@@ -1395,8 +1388,8 @@ absl::Status Overworld::SaveEntrances() {
rom()->WriteShort(kOverworldHoleArea + (i * 2), all_holes_[i].map_id_)) rom()->WriteShort(kOverworldHoleArea + (i * 2), all_holes_[i].map_id_))
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(kOverworldHolePos + (i * 2), all_holes_[i].map_pos_)) rom()->WriteShort(kOverworldHolePos + (i * 2), all_holes_[i].map_pos_))
RETURN_IF_ERROR(rom()->WriteByte(kOverworldHoleEntrance + i, RETURN_IF_ERROR(
all_holes_[i].entrance_id_)) rom()->WriteByte(kOverworldHoleEntrance + i, all_holes_[i].entrance_id_))
} }
return absl::OkStatus(); return absl::OkStatus();
@@ -1427,9 +1420,9 @@ absl::Status Overworld::SaveExits() {
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(OWExitUnk2 + i, all_exits_[i].scroll_mod_x_)); rom()->WriteByte(OWExitUnk2 + i, all_exits_[i].scroll_mod_x_));
RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType1 + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType1 + (i * 2),
all_exits_[i].door_type_1_)); all_exits_[i].door_type_1_));
RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType2 + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType2 + (i * 2),
all_exits_[i].door_type_2_)); all_exits_[i].door_type_2_));
} }
return absl::OkStatus(); return absl::OkStatus();
@@ -1545,49 +1538,49 @@ absl::Status Overworld::SaveItems() {
absl::Status Overworld::SaveMapProperties() { absl::Status Overworld::SaveMapProperties() {
util::logf("Saving Map Properties"); util::logf("Saving Map Properties");
for (int i = 0; i < kDarkWorldMapIdStart; i++) { for (int i = 0; i < kDarkWorldMapIdStart; i++) {
RETURN_IF_ERROR(rom()->WriteByte(kAreaGfxIdPtr + i, RETURN_IF_ERROR(
overworld_maps_[i].area_graphics())); rom()->WriteByte(kAreaGfxIdPtr + i, overworld_maps_[i].area_graphics()));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldMapPaletteIds + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldMapPaletteIds + i,
overworld_maps_[i].area_palette())); overworld_maps_[i].area_palette()));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpriteset + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpriteset + i,
overworld_maps_[i].sprite_graphics(0))); overworld_maps_[i].sprite_graphics(0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpriteset + kDarkWorldMapIdStart + i, rom()->WriteByte(kOverworldSpriteset + kDarkWorldMapIdStart + i,
overworld_maps_[i].sprite_graphics(1))); overworld_maps_[i].sprite_graphics(1)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpriteset + kSpecialWorldMapIdStart + i, rom()->WriteByte(kOverworldSpriteset + kSpecialWorldMapIdStart + i,
overworld_maps_[i].sprite_graphics(2))); overworld_maps_[i].sprite_graphics(2)));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpritePaletteIds + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpritePaletteIds + i,
overworld_maps_[i].sprite_palette(0))); overworld_maps_[i].sprite_palette(0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpritePaletteIds + kDarkWorldMapIdStart + i, rom()->WriteByte(kOverworldSpritePaletteIds + kDarkWorldMapIdStart + i,
overworld_maps_[i].sprite_palette(1))); overworld_maps_[i].sprite_palette(1)));
RETURN_IF_ERROR(rom()->WriteByte( RETURN_IF_ERROR(rom()->WriteByte(
kOverworldSpritePaletteIds + kSpecialWorldMapIdStart + i, kOverworldSpritePaletteIds + kSpecialWorldMapIdStart + i,
overworld_maps_[i].sprite_palette(2))); overworld_maps_[i].sprite_palette(2)));
} }
for (int i = kDarkWorldMapIdStart; i < kSpecialWorldMapIdStart; i++) { for (int i = kDarkWorldMapIdStart; i < kSpecialWorldMapIdStart; i++) {
RETURN_IF_ERROR(rom()->WriteByte(kAreaGfxIdPtr + i, RETURN_IF_ERROR(
overworld_maps_[i].area_graphics())); rom()->WriteByte(kAreaGfxIdPtr + i, overworld_maps_[i].area_graphics()));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpriteset + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpriteset + i,
overworld_maps_[i].sprite_graphics(0))); overworld_maps_[i].sprite_graphics(0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpriteset + kDarkWorldMapIdStart + i, rom()->WriteByte(kOverworldSpriteset + kDarkWorldMapIdStart + i,
overworld_maps_[i].sprite_graphics(1))); overworld_maps_[i].sprite_graphics(1)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpriteset + kSpecialWorldMapIdStart + i, rom()->WriteByte(kOverworldSpriteset + kSpecialWorldMapIdStart + i,
overworld_maps_[i].sprite_graphics(2))); overworld_maps_[i].sprite_graphics(2)));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldMapPaletteIds + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldMapPaletteIds + i,
overworld_maps_[i].area_palette())); overworld_maps_[i].area_palette()));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kOverworldSpritePaletteIds + kDarkWorldMapIdStart + i, rom()->WriteByte(kOverworldSpritePaletteIds + kDarkWorldMapIdStart + i,
overworld_maps_[i].sprite_palette(0))); overworld_maps_[i].sprite_palette(0)));
RETURN_IF_ERROR(rom()->WriteByte( RETURN_IF_ERROR(rom()->WriteByte(
kOverworldSpritePaletteIds + kSpecialWorldMapIdStart + i, kOverworldSpritePaletteIds + kSpecialWorldMapIdStart + i,
overworld_maps_[i].sprite_palette(1))); overworld_maps_[i].sprite_palette(1)));
RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpritePaletteIds + 192 + i, RETURN_IF_ERROR(rom()->WriteByte(kOverworldSpritePaletteIds + 192 + i,
overworld_maps_[i].sprite_palette(2))); overworld_maps_[i].sprite_palette(2)));
} }
return absl::OkStatus(); return absl::OkStatus();

View File

@@ -109,11 +109,11 @@ constexpr int kNumMapsPerWorld = 0x40;
* This class is responsible for loading and saving the overworld data, * This class is responsible for loading and saving the overworld data,
* as well as creating the tilesets and tilemaps for the overworld. * as well as creating the tilesets and tilemaps for the overworld.
*/ */
class Overworld : public SharedRom { class Overworld {
public: public:
Overworld(Rom &rom) : rom_(rom) {} Overworld(Rom *rom) : rom_(rom) {}
absl::Status Load(Rom &rom); absl::Status Load(Rom *rom);
absl::Status LoadOverworldMaps(); absl::Status LoadOverworldMaps();
void LoadTileTypes(); void LoadTileTypes();
absl::Status LoadEntrances(); absl::Status LoadEntrances();
@@ -125,7 +125,7 @@ class Overworld : public SharedRom {
absl::Status LoadSpritesFromMap(int sprite_start, int sprite_count, absl::Status LoadSpritesFromMap(int sprite_start, int sprite_count,
int sprite_index); int sprite_index);
absl::Status Save(Rom &rom); absl::Status Save(Rom *rom);
absl::Status SaveOverworldMaps(); absl::Status SaveOverworldMaps();
absl::Status SaveLargeMaps(); absl::Status SaveLargeMaps();
absl::Status SaveEntrances(); absl::Status SaveEntrances();
@@ -140,6 +140,9 @@ class Overworld : public SharedRom {
absl::Status SaveMapProperties(); absl::Status SaveMapProperties();
auto rom() const { return rom_; }
auto mutable_rom() { return rom_; }
void Destroy() { void Destroy() {
for (auto &map : overworld_maps_) { for (auto &map : overworld_maps_) {
map.Destroy(); map.Destroy();
@@ -151,6 +154,9 @@ class Overworld : public SharedRom {
for (auto &sprites : all_sprites_) { for (auto &sprites : all_sprites_) {
sprites.clear(); sprites.clear();
} }
tiles16_.clear();
tiles32_.clear();
tiles32_unique_.clear();
is_loaded_ = false; is_loaded_ = false;
} }
@@ -234,7 +240,7 @@ class Overworld : public SharedRom {
int &ttpos); int &ttpos);
void DecompressAllMapTiles(); void DecompressAllMapTiles();
Rom &rom_; Rom *rom_;
bool is_loaded_ = false; bool is_loaded_ = false;
bool expanded_tile16_ = false; bool expanded_tile16_ = false;

View File

@@ -97,13 +97,14 @@ struct OverworldEntranceTileTypes {
}; };
inline absl::StatusOr<OverworldEntranceTileTypes> LoadEntranceTileTypes( inline absl::StatusOr<OverworldEntranceTileTypes> LoadEntranceTileTypes(
Rom &rom) { Rom *rom) {
OverworldEntranceTileTypes tiletypes; OverworldEntranceTileTypes tiletypes;
for (int i = 0; i < kNumEntranceTileTypes; i++) { for (int i = 0; i < kNumEntranceTileTypes; i++) {
ASSIGN_OR_RETURN(auto value_low, rom.ReadWord(kEntranceTileTypePtrLow + i)); ASSIGN_OR_RETURN(auto value_low,
rom->ReadWord(kEntranceTileTypePtrLow + i));
tiletypes.low[i] = value_low; tiletypes.low[i] = value_low;
ASSIGN_OR_RETURN(auto value_high, ASSIGN_OR_RETURN(auto value_high,
rom.ReadWord(kEntranceTileTypePtrHigh + i)); rom->ReadWord(kEntranceTileTypePtrHigh + i));
tiletypes.high[i] = value_high; tiletypes.high[i] = value_high;
} }
return tiletypes; return tiletypes;

View File

@@ -15,14 +15,14 @@
namespace yaze { namespace yaze {
namespace zelda3 { namespace zelda3 {
OverworldMap::OverworldMap(int index, Rom &rom) OverworldMap::OverworldMap(int index, Rom *rom)
: index_(index), parent_(index), rom_(rom) { : index_(index), parent_(index), rom_(rom) {
LoadAreaInfo(); LoadAreaInfo();
if (core::FeatureFlags::get().overworld.kLoadCustomOverworld) { if (core::FeatureFlags::get().overworld.kLoadCustomOverworld) {
// If the custom overworld ASM has NOT already been applied, manually set // If the custom overworld ASM has NOT already been applied, manually set
// the vanilla values. // the vanilla values.
uint8_t asm_version = rom_[OverworldCustomASMHasBeenApplied]; uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
if (asm_version == 0x00) { if (asm_version == 0x00) {
LoadCustomOverworldData(); LoadCustomOverworldData();
} else { } else {
@@ -40,15 +40,15 @@ absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
if (parent_ != index_ && !initialized_) { if (parent_ != index_ && !initialized_) {
if (index_ >= kSpecialWorldMapIdStart && index_ <= 0x8A && if (index_ >= kSpecialWorldMapIdStart && index_ <= 0x8A &&
index_ != 0x88) { index_ != 0x88) {
area_graphics_ = rom_[kOverworldSpecialGfxGroup + area_graphics_ = (*rom_)[kOverworldSpecialGfxGroup +
(parent_ - kSpecialWorldMapIdStart)]; (parent_ - kSpecialWorldMapIdStart)];
area_palette_ = rom_[kOverworldSpecialPalGroup + 1]; area_palette_ = (*rom_)[kOverworldSpecialPalGroup + 1];
} else if (index_ == 0x88) { } else if (index_ == 0x88) {
area_graphics_ = 0x51; area_graphics_ = 0x51;
area_palette_ = 0x00; area_palette_ = 0x00;
} else { } else {
area_graphics_ = rom_[kAreaGfxIdPtr + parent_]; area_graphics_ = (*rom_)[kAreaGfxIdPtr + parent_];
area_palette_ = rom_[kOverworldMapPaletteIds + parent_]; area_palette_ = (*rom_)[kOverworldMapPaletteIds + parent_];
} }
initialized_ = true; initialized_ = true;
@@ -67,14 +67,14 @@ absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
void OverworldMap::LoadAreaInfo() { void OverworldMap::LoadAreaInfo() {
if (index_ != kSpecialWorldMapIdStart) { if (index_ != kSpecialWorldMapIdStart) {
if (index_ <= 128) if (index_ <= 128)
large_map_ = (rom_[kOverworldMapSize + (index_ & 0x3F)] != 0); large_map_ = ((*rom_)[kOverworldMapSize + (index_ & 0x3F)] != 0);
else { else {
large_map_ = large_map_ =
index_ == 129 || index_ == 130 || index_ == 137 || index_ == 138; index_ == 129 || index_ == 130 || index_ == 137 || index_ == 138;
} }
} }
auto message_id = rom_.ReadWord(kOverworldMessageIds + (parent_ * 2)); auto message_id = rom_->ReadWord(kOverworldMessageIds + (parent_ * 2));
if (message_id.ok()) { if (message_id.ok()) {
message_id_ = message_id.value(); message_id_ = message_id.value();
} else { } else {
@@ -83,43 +83,43 @@ void OverworldMap::LoadAreaInfo() {
} }
if (index_ < kDarkWorldMapIdStart) { if (index_ < kDarkWorldMapIdStart) {
area_graphics_ = rom_[kAreaGfxIdPtr + parent_]; area_graphics_ = (*rom_)[kAreaGfxIdPtr + parent_];
area_palette_ = rom_[kOverworldMapPaletteIds + parent_]; area_palette_ = (*rom_)[kOverworldMapPaletteIds + parent_];
area_music_[0] = rom_[kOverworldMusicBeginning + parent_]; area_music_[0] = (*rom_)[kOverworldMusicBeginning + parent_];
area_music_[1] = rom_[kOverworldMusicZelda + parent_]; area_music_[1] = (*rom_)[kOverworldMusicZelda + parent_];
area_music_[2] = rom_[kOverworldMusicMasterSword + parent_]; area_music_[2] = (*rom_)[kOverworldMusicMasterSword + parent_];
area_music_[3] = rom_[kOverworldMusicAgahnim + parent_]; area_music_[3] = (*rom_)[kOverworldMusicAgahnim + parent_];
sprite_graphics_[0] = rom_[kOverworldSpriteset + parent_]; sprite_graphics_[0] = (*rom_)[kOverworldSpriteset + parent_];
sprite_graphics_[1] = sprite_graphics_[1] =
rom_[kOverworldSpriteset + parent_ + kDarkWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kDarkWorldMapIdStart];
sprite_graphics_[2] = sprite_graphics_[2] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[0] = rom_[kOverworldSpritePaletteIds + parent_]; sprite_palette_[0] = (*rom_)[kOverworldSpritePaletteIds + parent_];
sprite_palette_[1] = sprite_palette_[1] =
rom_[kOverworldSpritePaletteIds + parent_ + kDarkWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kDarkWorldMapIdStart];
sprite_palette_[2] = sprite_palette_[2] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
} else if (index_ < kSpecialWorldMapIdStart) { } else if (index_ < kSpecialWorldMapIdStart) {
area_graphics_ = rom_[kAreaGfxIdPtr + parent_]; area_graphics_ = (*rom_)[kAreaGfxIdPtr + parent_];
area_palette_ = rom_[kOverworldMapPaletteIds + parent_]; area_palette_ = (*rom_)[kOverworldMapPaletteIds + parent_];
area_music_[0] = rom_[kOverworldMusicDarkWorld + (parent_ - 64)]; area_music_[0] = (*rom_)[kOverworldMusicDarkWorld + (parent_ - 64)];
sprite_graphics_[0] = sprite_graphics_[0] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_graphics_[1] = sprite_graphics_[1] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_graphics_[2] = sprite_graphics_[2] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[0] = sprite_palette_[0] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[1] = sprite_palette_[1] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[2] = sprite_palette_[2] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
} else { } else {
if (index_ == 0x94) { if (index_ == 0x94) {
parent_ = 0x80; parent_ = 0x80;
@@ -145,35 +145,35 @@ void OverworldMap::LoadAreaInfo() {
} }
area_palette_ = area_palette_ =
rom_[kOverworldSpecialPalGroup + parent_ - kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpecialPalGroup + parent_ - kSpecialWorldMapIdStart];
if ((index_ >= kSpecialWorldMapIdStart && index_ <= 0x8A && if ((index_ >= kSpecialWorldMapIdStart && index_ <= 0x8A &&
index_ != 0x88) || index_ != 0x88) ||
index_ == 0x94) { index_ == 0x94) {
area_graphics_ = area_graphics_ =
rom_[kOverworldSpecialGfxGroup + (parent_ - kSpecialWorldMapIdStart)]; (*rom_)[kOverworldSpecialGfxGroup + (parent_ - kSpecialWorldMapIdStart)];
area_palette_ = rom_[kOverworldSpecialPalGroup + 1]; area_palette_ = (*rom_)[kOverworldSpecialPalGroup + 1];
} else if (index_ == 0x88) { } else if (index_ == 0x88) {
area_graphics_ = 0x51; area_graphics_ = 0x51;
area_palette_ = 0x00; area_palette_ = 0x00;
} else { } else {
// pyramid bg use 0x5B map // pyramid bg use 0x5B map
area_graphics_ = rom_[kAreaGfxIdPtr + parent_]; area_graphics_ = (*rom_)[kAreaGfxIdPtr + parent_];
area_palette_ = rom_[kOverworldMapPaletteIds + parent_]; area_palette_ = (*rom_)[kOverworldMapPaletteIds + parent_];
} }
sprite_graphics_[0] = sprite_graphics_[0] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_graphics_[1] = sprite_graphics_[1] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_graphics_[2] = sprite_graphics_[2] =
rom_[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpriteset + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[0] = sprite_palette_[0] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[1] = sprite_palette_[1] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
sprite_palette_[2] = sprite_palette_[2] =
rom_[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart]; (*rom_)[kOverworldSpritePaletteIds + parent_ + kSpecialWorldMapIdStart];
} }
} }
@@ -213,38 +213,39 @@ void OverworldMap::LoadCustomOverworldData() {
} }
const auto overworld_gfx_groups2 = const auto overworld_gfx_groups2 =
rom_.version_constants().kOverworldGfxGroups2; rom_->version_constants().kOverworldGfxGroups2;
// Main Blocksets // Main Blocksets
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
custom_gfx_ids_[i] = custom_gfx_ids_[i] =
(uint8_t)rom_[overworld_gfx_groups2 + (index_world * 8) + i]; (uint8_t)(*rom_)[overworld_gfx_groups2 + (index_world * 8) + i];
} }
const auto overworldgfxGroups = rom_.version_constants().kOverworldGfxGroups1; const auto overworldgfxGroups =
rom_->version_constants().kOverworldGfxGroups1;
// Replace the variable tiles with the variable ones. // Replace the variable tiles with the variable ones.
uint8_t temp = rom_[overworldgfxGroups + (area_graphics_ * 4)]; uint8_t temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4)];
if (temp != 0) { if (temp != 0) {
custom_gfx_ids_[3] = temp; custom_gfx_ids_[3] = temp;
} else { } else {
custom_gfx_ids_[3] = 0xFF; custom_gfx_ids_[3] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 1]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 1];
if (temp != 0) { if (temp != 0) {
custom_gfx_ids_[4] = temp; custom_gfx_ids_[4] = temp;
} else { } else {
custom_gfx_ids_[4] = 0xFF; custom_gfx_ids_[4] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 2]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 2];
if (temp != 0) { if (temp != 0) {
custom_gfx_ids_[5] = temp; custom_gfx_ids_[5] = temp;
} else { } else {
custom_gfx_ids_[5] = 0xFF; custom_gfx_ids_[5] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 3]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 3];
if (temp != 0) { if (temp != 0) {
custom_gfx_ids_[6] = temp; custom_gfx_ids_[6] = temp;
} else { } else {
@@ -290,18 +291,18 @@ void OverworldMap::LoadCustomOverworldData() {
} }
void OverworldMap::SetupCustomTileset(uint8_t asm_version) { void OverworldMap::SetupCustomTileset(uint8_t asm_version) {
area_palette_ = rom_[OverworldCustomMainPaletteArray + index_]; area_palette_ = (*rom_)[OverworldCustomMainPaletteArray + index_];
mosaic_ = rom_[OverworldCustomMosaicArray + index_] != 0x00; mosaic_ = (*rom_)[OverworldCustomMosaicArray + index_] != 0x00;
// This is just to load the GFX groups for ROMs that have an older version // This is just to load the GFX groups for ROMs that have an older version
// of the Overworld ASM already applied. // of the Overworld ASM already applied.
if (asm_version >= 0x01 && asm_version != 0xFF) { if (asm_version >= 0x01 && asm_version != 0xFF) {
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
custom_gfx_ids_[i] = custom_gfx_ids_[i] =
rom_[OverworldCustomTileGFXGroupArray + (index_ * 8) + i]; (*rom_)[OverworldCustomTileGFXGroupArray + (index_ * 8) + i];
} }
animated_gfx_ = rom_[OverworldCustomAnimatedGFXArray + index_]; animated_gfx_ = (*rom_)[OverworldCustomAnimatedGFXArray + index_];
} else { } else {
int index_world = 0x20; int index_world = 0x20;
@@ -317,38 +318,38 @@ void OverworldMap::SetupCustomTileset(uint8_t asm_version) {
// Main Blocksets // Main Blocksets
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
custom_gfx_ids_[i] = custom_gfx_ids_[i] =
(uint8_t)rom_[rom_.version_constants().kOverworldGfxGroups2 + (uint8_t)(*rom_)[rom_->version_constants().kOverworldGfxGroups2 +
(index_world * 8) + i]; (index_world * 8) + i];
} }
const auto overworldgfxGroups = const auto overworldgfxGroups =
rom_.version_constants().kOverworldGfxGroups1; rom_->version_constants().kOverworldGfxGroups1;
// Replace the variable tiles with the variable ones. // Replace the variable tiles with the variable ones.
// If the variable is 00 set it to 0xFF which is the new "don't load // If the variable is 00 set it to 0xFF which is the new "don't load
// anything" value. // anything" value.
uint8_t temp = rom_[overworldgfxGroups + (area_graphics_ * 4)]; uint8_t temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4)];
if (temp != 0x00) { if (temp != 0x00) {
custom_gfx_ids_[3] = temp; custom_gfx_ids_[3] = temp;
} else { } else {
custom_gfx_ids_[3] = 0xFF; custom_gfx_ids_[3] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 1]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 1];
if (temp != 0x00) { if (temp != 0x00) {
custom_gfx_ids_[4] = temp; custom_gfx_ids_[4] = temp;
} else { } else {
custom_gfx_ids_[4] = 0xFF; custom_gfx_ids_[4] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 2]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 2];
if (temp != 0x00) { if (temp != 0x00) {
custom_gfx_ids_[5] = temp; custom_gfx_ids_[5] = temp;
} else { } else {
custom_gfx_ids_[5] = 0xFF; custom_gfx_ids_[5] = 0xFF;
} }
temp = rom_[overworldgfxGroups + (area_graphics_ * 4) + 3]; temp = (*rom_)[overworldgfxGroups + (area_graphics_ * 4) + 3];
if (temp != 0x00) { if (temp != 0x00) {
custom_gfx_ids_[6] = temp; custom_gfx_ids_[6] = temp;
} else { } else {
@@ -365,7 +366,7 @@ void OverworldMap::SetupCustomTileset(uint8_t asm_version) {
} }
subscreen_overlay_ = subscreen_overlay_ =
rom_[OverworldCustomSubscreenOverlayArray + (index_ * 2)]; (*rom_)[OverworldCustomSubscreenOverlayArray + (index_ * 2)];
} }
void OverworldMap::LoadMainBlocksetId() { void OverworldMap::LoadMainBlocksetId() {
@@ -388,7 +389,7 @@ void OverworldMap::LoadSpritesBlocksets() {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
static_graphics_[12 + i] = static_graphics_[12 + i] =
(rom_[rom_.version_constants().kSpriteBlocksetPointer + ((*rom_)[rom_->version_constants().kSpriteBlocksetPointer +
(sprite_graphics_[game_state_] * 4) + i] + (sprite_graphics_[game_state_] * 4) + i] +
static_graphics_base); static_graphics_base);
} }
@@ -396,7 +397,7 @@ void OverworldMap::LoadSpritesBlocksets() {
void OverworldMap::LoadMainBlocksets() { void OverworldMap::LoadMainBlocksets() {
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
static_graphics_[i] = rom_[rom_.version_constants().kOverworldGfxGroups2 + static_graphics_[i] = (*rom_)[rom_->version_constants().kOverworldGfxGroups2 +
(main_gfx_id_ * 8) + i]; (main_gfx_id_ * 8) + i];
} }
} }
@@ -426,7 +427,7 @@ void OverworldMap::DrawAnimatedTiles() {
void OverworldMap::LoadAreaGraphicsBlocksets() { void OverworldMap::LoadAreaGraphicsBlocksets() {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
uint8_t value = rom_[rom_.version_constants().kOverworldGfxGroups1 + uint8_t value = (*rom_)[rom_->version_constants().kOverworldGfxGroups1 +
(area_graphics_ * 4) + i]; (area_graphics_ * 4) + i];
if (value != 0) { if (value != 0) {
static_graphics_[3 + i] = value; static_graphics_[3 + i] = value;
@@ -581,7 +582,7 @@ absl::StatusOr<gfx::SnesPalette> OverworldMap::GetPalette(
const gfx::PaletteGroup &palette_group, int index, int previous_index, const gfx::PaletteGroup &palette_group, int index, int previous_index,
int limit) { int limit) {
if (index == 255) { if (index == 255) {
index = rom_[rom_.version_constants().kOverworldMapPaletteGroup + index = (*rom_)[rom_->version_constants().kOverworldMapPaletteGroup +
(previous_index * 4)]; (previous_index * 4)];
} }
if (index >= limit) { if (index >= limit) {
@@ -592,28 +593,28 @@ absl::StatusOr<gfx::SnesPalette> OverworldMap::GetPalette(
absl::Status OverworldMap::LoadPalette() { absl::Status OverworldMap::LoadPalette() {
int previous_pal_id = int previous_pal_id =
index_ > 0 ? rom_[kOverworldMapPaletteIds + parent_ - 1] : 0; index_ > 0 ? (*rom_)[kOverworldMapPaletteIds + parent_ - 1] : 0;
int previous_spr_pal_id = int previous_spr_pal_id =
index_ > 0 ? rom_[kOverworldSpritePaletteIds + parent_ - 1] : 0; index_ > 0 ? (*rom_)[kOverworldSpritePaletteIds + parent_ - 1] : 0;
area_palette_ = std::min((int)area_palette_, 0xA3); area_palette_ = std::min((int)area_palette_, 0xA3);
uint8_t pal0 = 0; uint8_t pal0 = 0;
uint8_t pal1 = rom_[rom_.version_constants().kOverworldMapPaletteGroup + uint8_t pal1 = (*rom_)[rom_->version_constants().kOverworldMapPaletteGroup +
(area_palette_ * 4)]; (area_palette_ * 4)];
uint8_t pal2 = rom_[rom_.version_constants().kOverworldMapPaletteGroup + uint8_t pal2 = (*rom_)[rom_->version_constants().kOverworldMapPaletteGroup +
(area_palette_ * 4) + 1]; (area_palette_ * 4) + 1];
uint8_t pal3 = rom_[rom_.version_constants().kOverworldMapPaletteGroup + uint8_t pal3 = (*rom_)[rom_->version_constants().kOverworldMapPaletteGroup +
(area_palette_ * 4) + 2]; (area_palette_ * 4) + 2];
uint8_t pal4 = uint8_t pal4 =
rom_[kOverworldSpritePaletteGroup + (sprite_palette_[game_state_] * 2)]; (*rom_)[kOverworldSpritePaletteGroup + (sprite_palette_[game_state_] * 2)];
uint8_t pal5 = rom_[kOverworldSpritePaletteGroup + uint8_t pal5 = (*rom_)[kOverworldSpritePaletteGroup +
(sprite_palette_[game_state_] * 2) + 1]; (sprite_palette_[game_state_] * 2) + 1];
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)); ASSIGN_OR_RETURN(gfx::SnesColor bgr, grass_pal_group[0].GetColor(0));
auto ow_aux_pal_group = rom_.palette_group().overworld_aux; auto ow_aux_pal_group = rom_->palette_group().overworld_aux;
ASSIGN_OR_RETURN(gfx::SnesPalette aux1, ASSIGN_OR_RETURN(gfx::SnesPalette aux1,
GetPalette(ow_aux_pal_group, pal1, previous_pal_id, 20)); GetPalette(ow_aux_pal_group, pal1, previous_pal_id, 20));
ASSIGN_OR_RETURN(gfx::SnesPalette aux2, ASSIGN_OR_RETURN(gfx::SnesPalette aux2,
@@ -621,7 +622,7 @@ absl::Status OverworldMap::LoadPalette() {
// Additional handling of `pal3` and `parent_` // Additional handling of `pal3` and `parent_`
if (pal3 == 255) { if (pal3 == 255) {
pal3 = rom_[rom_.version_constants().kOverworldMapPaletteGroup + pal3 = (*rom_)[rom_->version_constants().kOverworldMapPaletteGroup +
(previous_pal_id * 4) + 2]; (previous_pal_id * 4) + 2];
} }
@@ -641,26 +642,26 @@ absl::Status OverworldMap::LoadPalette() {
pal0 = 4; pal0 = 4;
} }
auto ow_main_pal_group = rom_.palette_group().overworld_main; auto ow_main_pal_group = rom_->palette_group().overworld_main;
ASSIGN_OR_RETURN(gfx::SnesPalette main, ASSIGN_OR_RETURN(gfx::SnesPalette main,
GetPalette(ow_main_pal_group, pal0, previous_pal_id, 255)); GetPalette(ow_main_pal_group, pal0, previous_pal_id, 255));
auto ow_animated_pal_group = rom_.palette_group().overworld_animated; auto ow_animated_pal_group = rom_->palette_group().overworld_animated;
ASSIGN_OR_RETURN(gfx::SnesPalette animated, ASSIGN_OR_RETURN(gfx::SnesPalette animated,
GetPalette(ow_animated_pal_group, std::min((int)pal3, 13), GetPalette(ow_animated_pal_group, std::min((int)pal3, 13),
previous_pal_id, 14)); previous_pal_id, 14));
auto hud_pal_group = rom_.palette_group().hud; auto hud_pal_group = rom_->palette_group().hud;
gfx::SnesPalette hud = hud_pal_group[0]; gfx::SnesPalette hud = hud_pal_group[0];
ASSIGN_OR_RETURN(gfx::SnesPalette spr, ASSIGN_OR_RETURN(gfx::SnesPalette spr,
GetPalette(rom_.palette_group().sprites_aux3, pal4, GetPalette(rom_->palette_group().sprites_aux3, pal4,
previous_spr_pal_id, 24)); previous_spr_pal_id, 24));
ASSIGN_OR_RETURN(gfx::SnesPalette spr2, ASSIGN_OR_RETURN(gfx::SnesPalette spr2,
GetPalette(rom_.palette_group().sprites_aux3, pal5, GetPalette(rom_->palette_group().sprites_aux3, pal5,
previous_spr_pal_id, 24)); previous_spr_pal_id, 24));
RETURN_IF_ERROR(palette_internal::SetColorsPalette( RETURN_IF_ERROR(palette_internal::SetColorsPalette(
rom_, parent_, current_palette_, main, animated, aux1, aux2, hud, bgr, *rom_, parent_, current_palette_, main, animated, aux1, aux2, hud, bgr,
spr, spr2)); spr, spr2));
if (palettesets_.count(area_palette_) == 0) { if (palettesets_.count(area_palette_) == 0) {
@@ -691,7 +692,7 @@ absl::Status OverworldMap::BuildTileset() {
if (current_gfx_.size() == 0) current_gfx_.resize(0x10000, 0x00); if (current_gfx_.size() == 0) current_gfx_.resize(0x10000, 0x00);
for (int i = 0; i < 0x10; i++) { for (int i = 0; i < 0x10; i++) {
ProcessGraphicsBuffer(i, static_graphics_[i], 0x1000, ProcessGraphicsBuffer(i, static_graphics_[i], 0x1000,
rom_.graphics_buffer().data()); rom_->graphics_buffer().data());
} }
return absl::OkStatus(); return absl::OkStatus();
} }

View File

@@ -77,7 +77,7 @@ typedef struct OverworldMapTiles {
class OverworldMap : public gfx::GfxContext { class OverworldMap : public gfx::GfxContext {
public: public:
OverworldMap() = default; OverworldMap() = default;
OverworldMap(int index, Rom& rom); OverworldMap(int index, Rom* rom);
absl::Status BuildMap(int count, int game_state, int world, absl::Status BuildMap(int count, int game_state, int world,
std::vector<gfx::Tile16>& tiles16, std::vector<gfx::Tile16>& tiles16,
@@ -148,6 +148,24 @@ class OverworldMap : public gfx::GfxContext {
current_blockset_.clear(); current_blockset_.clear();
current_gfx_.clear(); current_gfx_.clear();
bitmap_data_.clear(); bitmap_data_.clear();
map_tiles_.light_world.clear();
map_tiles_.dark_world.clear();
map_tiles_.special_world.clear();
built_ = false;
initialized_ = false;
large_map_ = false;
mosaic_ = false;
index_ = 0;
parent_ = 0;
large_index_ = 0;
world_ = 0;
game_state_ = 0;
main_gfx_id_ = 0;
message_id_ = 0;
area_graphics_ = 0;
area_palette_ = 0;
animated_gfx_ = 0;
subscreen_overlay_ = 0;
} }
private: private:
@@ -167,7 +185,7 @@ class OverworldMap : public gfx::GfxContext {
int index, int previous_index, int index, int previous_index,
int limit); int limit);
Rom rom_; Rom *rom_;
bool built_ = false; bool built_ = false;
bool large_map_ = false; bool large_map_ = false;