7#include "absl/status/status.h"
8#include "absl/status/statusor.h"
19absl::StatusOr<std::vector<OverworldItem>>
LoadItems(
20 Rom* rom, std::vector<OverworldMap>& overworld_maps) {
21 std::vector<OverworldItem> items;
34 uint32_t item_pointer_address =
37 for (
int i = 0; i < max_ow; i++) {
40 int bank = bank_byte & 0x7F;
43 rom->
ReadByte(item_pointer_address + (i * 2)));
45 rom->
ReadByte(item_pointer_address + (i * 2) + 1));
47 uint32_t addr = (bank << 16) +
54 if (overworld_maps[i].parent() != (uint8_t)i) {
64 if (b1 == 0xFF && b2 == 0xFF) {
68 int p = (((b2 & 0x1F) << 8) + b1) >> 1;
73 int fakeID = i % 0x40;
76 int sx = fakeID - (sy * 8);
78 items.emplace_back(b3, (uint16_t)i, (x * 16) + (sx * 512),
79 (y * 16) + (sy * 512),
false);
80 auto size = items.size();
82 items[size - 1].game_x_ = (uint8_t)x;
83 items[size - 1].game_y_ = (uint8_t)y;
90absl::Status
SaveItems(
Rom* rom,
const std::vector<OverworldItem>& items) {
93 std::vector<std::vector<OverworldItem>> room_items(pointer_count);
105 const int map_index =
static_cast<int>(item.room_map_id_);
106 if (map_index < 0 || map_index >= pointer_count) {
108 "Overworld::SaveItems",
109 "Skipping item with map index %d outside pointer table (size=%d)",
110 map_index, pointer_count);
114 room_items[map_index].push_back(item);
116 if (item.id_ == 0x86) {
117 const int lookup_index =
121 static_cast<uint16_t
>((item.game_x_ + (item.game_y_ * 64)) * 2)));
126 std::vector<int> item_pointers(pointer_count, -1);
127 std::vector<int> item_pointers_reuse(pointer_count, -1);
129 for (
int i = 0; i < pointer_count; ++i) {
130 item_pointers_reuse[i] = -1;
131 for (
int ci = 0; ci < i; ++ci) {
132 if (room_items[i].empty()) {
133 item_pointers_reuse[i] = -2;
138 item_pointers_reuse[i] = ci;
146 int empty_pointer = -1;
148 for (
int i = 0; i < pointer_count; ++i) {
149 if (item_pointers_reuse[i] == -1) {
150 item_pointers[i] = data_pos;
152 const uint16_t map_pos =
153 static_cast<uint16_t
>(((item.game_y_ << 6) + item.game_x_) << 1);
154 const uint32_t data =
155 static_cast<uint32_t
>(map_pos & 0xFF) |
156 (
static_cast<uint32_t
>((map_pos >> 8) & 0xFF) << 8) |
157 (
static_cast<uint32_t
>(item.id_) << 16);
163 empty_pointer = data_pos;
166 }
else if (item_pointers_reuse[i] == -2) {
167 if (empty_pointer < 0) {
168 item_pointers[i] = data_pos;
169 empty_pointer = data_pos;
173 item_pointers[i] = empty_pointer;
176 item_pointers[i] = item_pointers[item_pointers_reuse[i]];
181 return absl::AbortedError(
"Too many items");
189 static_cast<uint8_t
>(
199 for (
int i = 0; i < pointer_count; ++i) {
200 const uint32_t snes_addr =
PcToSnes(item_pointers[i]);
203 static_cast<uint16_t
>(snes_addr & 0xFFFF)));
208 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status WriteByte(int addr, uint8_t value)
absl::StatusOr< uint32_t > ReadLong(int offset)
absl::StatusOr< uint8_t > ReadByte(int offset)
absl::Status WriteShort(int addr, uint16_t value)
absl::Status WriteLong(uint32_t addr, uint32_t value)
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
static bool SupportsAreaEnum(OverworldVersion version)
Check if ROM supports area enum system (v3+ only)
#define LOG_WARN(category, format,...)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
void logf(const absl::FormatSpec< Args... > &format, Args &&... args)
Zelda 3 specific classes and functions.
absl::Status SaveItems(Rom *rom, const std::vector< OverworldItem > &items)
absl::StatusOr< std::vector< OverworldItem > > LoadItems(Rom *rom, std::vector< OverworldMap > &overworld_maps)
constexpr int overworldItemsAddressBank
constexpr int kNumOverworldMaps
bool CompareItemsArrays(std::vector< OverworldItem > item_array1, std::vector< OverworldItem > item_array2)
constexpr int kOverworldItemsEndData
constexpr int kOverworldItemsStartDataNew
constexpr int overworldItemsAddress
constexpr int kOverworldBombDoorItemLocationsNew
constexpr int kOverworldItemsPointersNew
uint32_t PcToSnes(uint32_t addr)
uint32_t SnesToPc(uint32_t addr) noexcept
#define RETURN_IF_ERROR(expr)