yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
game_tilemap_comparison.h
Go to the documentation of this file.
1#ifndef YAZE_ZELDA3_DUNGEON_GAME_TILEMAP_COMPARISON_H
2#define YAZE_ZELDA3_DUNGEON_GAME_TILEMAP_COMPARISON_H
3
4#include <cstddef>
5#include <cstdint>
6#include <string>
7#include <vector>
8
9#include "absl/status/statusor.h"
11
12namespace yaze {
13
14class Rom;
15
16namespace zelda3 {
17
18class Room;
19
20// Compares yaze's room tilemaps with tilemaps captured from the running game.
21//
22// When the game loads a room it builds both 64x64 tilemaps in WRAM:
23// TILEMAPA ($7E2000) is BG1 and TILEMAPB ($7E4000) is BG2 (usdasm wram.asm).
24// scripts/agents/capture-game-room-tilemaps.py saves them from Mesen. A tile
25// word is vhopppcc cccccccc: flips, priority, palette and tile number, so a
26// match proves an object's geometry, tiles, flips, palette row and priority.
27// It does not prove the colors in CGRAM or the graphics sheets.
28
29inline constexpr int kRoomTilemapSize = 64;
30inline constexpr size_t kRoomTilemapWords = 64 * 64;
31inline constexpr size_t kGameRoomTilemapBytes = 2 * kRoomTilemapWords * 2;
32
34 std::vector<uint16_t> bg1; // kRoomTilemapWords, row-major
35 std::vector<uint16_t> bg2;
36};
37
38// Parses a capture file: BG1 then BG2, little-endian words.
39absl::StatusOr<RoomTilemaps> ParseGameRoomTilemaps(
40 const std::vector<uint8_t>& bytes);
41
42// yaze's final tilemaps for a rendered room: the object buffer's word where an
43// object wrote one, otherwise the layout buffer's word.
45
46// For each tile, the index (into `objects`) of the room object whose own
47// drawing produced the word yaze shows there, or -1 when no object did
48// (layout, doors, or an object whose tile was later overwritten).
49struct TileOwners {
50 std::vector<int> bg1;
51 std::vector<int> bg2;
52};
53
54// True when the game does not draw `object` as the room first loads, so a
55// capture cannot judge it: RoomDraw_Chest (0xF99) skips closed chests in rooms
56// whose tag1 or tag2 is 0x27, 0x3C, 0x3E or 0x29-0x32 until they are revealed.
57bool GameHidesObjectOnRoomLoad(int tag1, int tag2, const RoomObject& object);
58
59// Draws each object alone, in the room's draw order, to find which tiles it
60// writes, then keeps an owner only where its word equals `yaze`'s final word.
61// Objects with `hidden[i]` set get no tiles, so they count as unchecked.
62TileOwners ComputeObjectTileOwners(Rom* rom, int room_id,
63 const std::vector<RoomObject>& objects,
64 const RoomTilemaps& yaze,
65 const std::vector<bool>& hidden = {});
66
68 int layer = 1; // 1 = BG1, 2 = BG2
69 int x = 0;
70 int y = 0;
71 uint16_t game = 0;
72 uint16_t yaze = 0;
73 int owner = -1; // object index, or -1
74};
75
77 size_t object_index = 0;
78 int object_id = 0;
79 int tiles_owned = 0; // tiles this object's drawing produced
80 int tiles_different = 0; // of those, how many differ from the game
81 uint16_t difference_bits = 0; // OR of (game ^ yaze) over those tiles
82};
83
85 int room_id = -1;
86 int bg1_matching = 0;
87 int bg2_matching = 0;
88 std::vector<TileDifference> differences;
89 // One entry per object, in `objects` order.
90 std::vector<ObjectPlacementCheck> placements;
91 // Differing tiles no object owns (layout, doors, runtime changes).
93};
94
96 const RoomTilemaps& yaze,
97 const TileOwners& owners,
98 const std::vector<RoomObject>& objects);
99
100// Names the tile-word fields in `xor_bits`, e.g. "priority, palette".
101std::string DescribeTileWordDifference(uint16_t xor_bits);
102
103} // namespace zelda3
104} // namespace yaze
105
106#endif // YAZE_ZELDA3_DUNGEON_GAME_TILEMAP_COMPARISON_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
RoomTilemaps ComposeYazeRoomTilemaps(const Room &room)
constexpr int kRoomTilemapSize
constexpr size_t kGameRoomTilemapBytes
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)
std::vector< ObjectPlacementCheck > placements
std::vector< TileDifference > differences