5#include "absl/status/status.h"
6#include "absl/strings/str_cat.h"
7#include "absl/strings/str_join.h"
26 word |=
static_cast<uint16_t
>((trace.
flags >> 3) & 0x7) << 10;
27 if (trace.
flags & 0x4)
29 if (trace.
flags & 0x1)
31 if (trace.
flags & 0x2)
44 const std::vector<uint8_t>& bytes) {
46 return absl::InvalidArgumentError(
48 " bytes, got ", bytes.size()));
54 maps.
bg1[i] =
static_cast<uint16_t
>(bytes[i * 2] | (bytes[i * 2 + 1] << 8));
56 maps.
bg2[i] =
static_cast<uint16_t
>(bytes[j] | (bytes[j + 1] << 8));
65 const auto& layout_words = layout.
buffer();
66 const auto& object_words = objects.buffer();
68 const uint16_t object_word =
69 i < object_words.size() ? object_words[i] : 0;
70 const uint16_t layout_word =
71 i < layout_words.size() ? layout_words[i] : 0;
72 out[i] = object_word != 0 ? object_word : layout_word;
83 if (
object.id_ != 0xF99) {
86 auto hides = [](
int tag) {
87 return tag == 0x27 || tag == 0x3C || tag == 0x3E ||
88 (tag >= 0x29 && tag <= 0x32);
90 return hides(tag1) || hides(tag2);
94 const std::vector<RoomObject>& objects,
96 const std::vector<bool>& hidden) {
105 std::vector<ObjectDrawer::TileTrace> trace;
117 for (
int list = 0; list < 3; ++list) {
118 for (
size_t index = 0; index < objects.size(); ++index) {
120 if (IsSpecialTableObject(source) ||
121 (index < hidden.size() && hidden[index])) {
125 if (list_index > 2) {
128 if (list_index != list) {
136 if (!drawer.
DrawObject(
object, bg1, bg2, palette_group).ok()) {
139 for (
const auto& tile : trace) {
140 if (tile.x_tile < 0 || tile.y_tile < 0 ||
145 const size_t position =
148 (bg2_tile ? owners.
bg2 : owners.
bg1)[position] =
149 static_cast<int>(index);
150 (bg2_tile ? owner_words_bg2 : owner_words_bg1)[position] =
159 if (owners.
bg1[position] >= 0 &&
160 owner_words_bg1[position] !=
yaze.bg1[position]) {
161 owners.
bg1[position] = -1;
163 if (owners.
bg2[position] >= 0 &&
164 owner_words_bg2[position] !=
yaze.bg2[position]) {
165 owners.
bg2[position] = -1;
174 const std::vector<RoomObject>& objects) {
178 for (
size_t i = 0; i < objects.size(); ++i) {
180 check.
placements[i].object_id = objects[i].id_;
183 auto compare_layer = [&](
int layer,
const std::vector<uint16_t>& game_words,
184 const std::vector<uint16_t>& yaze_words,
185 const std::vector<int>& layer_owners,
189 position < layer_owners.size() ? layer_owners[position] : -1;
190 const bool same = game_words[position] == yaze_words[position];
191 if (owner >= 0 &&
static_cast<size_t>(owner) < objects.size()) {
192 auto& placement = check.
placements[
static_cast<size_t>(owner)];
193 ++placement.tiles_owned;
195 ++placement.tiles_different;
196 placement.difference_bits |=
static_cast<uint16_t
>(
197 game_words[position] ^ yaze_words[position]);
205 difference.
layer = layer;
208 difference.
game = game_words[position];
209 difference.
yaze = yaze_words[position];
210 difference.
owner = owner;
229 std::vector<std::string> parts;
230 if (xor_bits & kTileNumberBits)
231 parts.push_back(
"tile");
232 if (xor_bits & kPaletteBits)
233 parts.push_back(
"palette");
234 if (xor_bits & kPriorityBit)
235 parts.push_back(
"priority");
236 if (xor_bits & (kHorizontalFlipBit | kVerticalFlipBit)) {
237 parts.push_back(
"flip");
239 return parts.empty() ?
"none" : absl::StrJoin(parts,
", ");
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
std::vector< uint16_t > & buffer()
Draws dungeon objects to background buffers using game patterns.
absl::Status DrawObject(const RoomObject &object, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2, const gfx::PaletteGroup &palette_group, const DungeonState *state=nullptr, gfx::BackgroundBuffer *layout_bg1=nullptr, gfx::BackgroundBuffer *layout_bg2=nullptr)
Draw a room object to background buffers.
void SetTraceCollector(std::vector< TileTrace > *collector, bool trace_only=false)
uint8_t GetLayerValue() const
auto & object_bg2_buffer()
auto & object_bg1_buffer()
constexpr uint16_t kVerticalFlipBit
constexpr uint16_t kPriorityBit
uint16_t TraceWord(const ObjectDrawer::TileTrace &trace)
bool IsSpecialTableObject(const RoomObject &object)
constexpr uint16_t kTileNumberBits
constexpr uint16_t kPaletteBits
constexpr uint16_t kHorizontalFlipBit
Zelda 3 specific classes and functions.
RoomTilemaps ComposeYazeRoomTilemaps(const Room &room)
constexpr int kRoomTilemapSize
constexpr size_t kGameRoomTilemapBytes
RoomObject::LayerType MapRoomObjectListIndexToDrawLayer(uint8_t list_index)
std::string DescribeTileWordDifference(uint16_t xor_bits)
absl::StatusOr< RoomTilemaps > ParseGameRoomTilemaps(const std::vector< uint8_t > &bytes)
constexpr size_t kRoomTilemapWords
TileOwners ComputeObjectTileOwners(Rom *rom, int room_id, const std::vector< RoomObject > &objects, const RoomTilemaps &yaze, const std::vector< bool > &hidden)
RoomTilemapCheck CompareRoomTilemaps(int room_id, const RoomTilemaps &game, const RoomTilemaps &yaze, const TileOwners &owners, const std::vector< RoomObject > &objects)
bool GameHidesObjectOnRoomLoad(int tag1, int tag2, const RoomObject &object)
Represents a group of palettes.
std::vector< ObjectPlacementCheck > placements
std::vector< TileDifference > differences
std::vector< uint16_t > bg1
std::vector< uint16_t > bg2