yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
lyra_terrain_document.h
Go to the documentation of this file.
1#ifndef YAZE_CORE_LYRA_TERRAIN_DOCUMENT_H_
2#define YAZE_CORE_LYRA_TERRAIN_DOCUMENT_H_
3
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <optional>
8#include <string>
9#include <string_view>
10#include <unordered_map>
11#include <vector>
12
13#include "absl/status/status.h"
14#include "absl/status/statusor.h"
15
16namespace yaze::core {
17
19 std::array<uint8_t, 8> graphics_sheets = {0x3A, 0x3B, 0x3C, 0x3D,
20 0x47, 0x48, 0x3E, 0x5B};
21 uint8_t main_palette = 0;
22 uint8_t palette_set = 1;
23 // Project-owned BG colors only; native ROM palettes and OBJ colors are unchanged.
24 std::optional<std::array<uint16_t, 128>> background_palette;
25 uint8_t animated_sheet = 0x5B;
26 std::array<int, 3> sprite_graphics = {-1, -1, -1};
27 std::array<int, 3> sprite_palettes = {-1, -1, -1};
28 std::array<uint8_t, 4> music = {0, 0, 0, 0};
29 uint16_t message_id = 0;
30
31 bool operator==(const LyraMapProperties&) const = default;
32};
33
35 uint32_t id = 0;
36 uint8_t sprite_id = 0;
37 int x = 0;
38 int y = 0;
39 int state = 0;
40
41 bool operator==(const LyraSpritePlacement&) const = default;
42};
43
45 uint32_t id = 0;
46 int x = 0;
47 int y = 0;
48 std::optional<int> entrance_id;
49
50 bool operator==(const LyraDoorPlacement&) const = default;
51};
52
54 uint32_t id = 0;
55 int room_id = 0;
56 int x = 0;
57 int y = 0;
58 std::optional<int> exit_row;
59
60 bool operator==(const LyraExitPlacement&) const = default;
61};
62
65 std::vector<LyraSpritePlacement> sprites;
66 std::vector<LyraDoorPlacement> doors;
67 std::vector<LyraExitPlacement> exits;
68 std::array<std::string, 3> asset_bindings;
69
70 bool operator==(const LyraMapAuthoring&) const = default;
71};
72
74 uint32_t id = 0;
75 int map_id = 0;
76 int x = 0;
77 int y = 0;
78 std::string name;
79 std::optional<int> runtime_slot;
80
81 bool operator==(const LyraFlightPoint&) const = default;
82};
83
84// Inclusive Tile16 positions 0..31 along the shared edge.
86 int first_tile = 0;
87 int last_tile = 0;
88
89 bool operator==(const LyraEdgePassage&) const = default;
90};
91
92// Authoring draft only: nothing here opens a route at runtime. Stored with
93// map_a < map_b. An absent passage is undecided, never the whole edge.
95 uint32_t id = 0;
96 int map_a = 0;
97 int map_b = 0;
98 std::optional<LyraEdgePassage> passage;
99
100 bool operator==(const LyraEdgeConnection&) const = default;
101};
102
103// True when both maps are $98-$9B or $A0-$BF, at least one is $A0+, and they
104// share a cardinal edge in the eight-column grid. Order-insensitive.
105bool LyraEdgeMapsAdjacent(int map_a, int map_b);
106
107// Project-owned gameplay composition only; this does not publish native maps.
109 kSmall = 0,
110 kLarge = 1,
111 kWide = 2,
112 kTall = 3
113};
114
122
123// Exact row-major footprint in the A0-BF eight-column, four-row grid. Any
124// in-bounds parent is allowed; footprints cannot wrap or leave that grid.
125absl::StatusOr<std::vector<int>> LyraGameplayAreaFootprint(
126 int parent_map_id, LyraGameplayAreaSize size);
127
129 std::array<LyraMapAuthoring, 32> maps;
130 std::vector<LyraFlightPoint> flight_points;
131 std::vector<LyraEdgeConnection> edge_connections;
132 std::vector<LyraGameplayArea> gameplay_areas;
133
134 bool operator==(const LyraAuthoringState&) const = default;
135};
136
137// A Tile16 number is meaningful only with the exact definitions and rendered
138// assets from which it was selected. Fingerprints are content-derived by the
139// editor adapter; this document never reads or writes a ROM.
141 std::array<uint8_t, 8> graphics_sheets = {0x3A, 0x3B, 0x3C, 0x3D,
142 0x47, 0x48, 0x3E, 0x5B};
143 uint8_t main_palette = 0;
144 uint8_t palette_set = 1;
145 uint8_t animated_sheet = 0x5B;
146 uint32_t tile_count = 0;
151
152 bool operator==(const LyraTerrainProfile&) const = default;
153 absl::Status Validate() const;
154};
155
157 int map_id = 0;
158 int x = 0;
159 int y = 0;
160 uint16_t before = 0;
161 uint16_t after = 0;
162};
163
164// One pointer-down/up gesture, including every map it crosses. The editor wraps
165// this data in its existing UndoAction so normal editor history stays primary.
167 std::vector<LyraTerrainCellChange> changes;
168 bool empty() const { return changes.empty(); }
169};
170
172 public:
173 static constexpr int kSchemaVersion = 5;
174 static constexpr int kMaxEdgeConnections = 64;
175 static constexpr int kFirstMap = 0xA0;
176 static constexpr int kMapCount = 32;
177 static constexpr int kColumns = 8;
178 static constexpr int kRows = 4;
179 static constexpr int kMapSize = 32;
180 static constexpr int kTilePixels = 16;
181 static constexpr int kWidth = kColumns * kMapSize;
182 static constexpr int kHeight = kRows * kMapSize;
183 using Map = std::array<uint16_t, kMapSize * kMapSize>;
184 using Maps = std::array<Map, kMapCount>;
185
186 static absl::StatusOr<LyraTerrainDocument> Create(
187 const LyraTerrainProfile& profile, uint16_t fill_tile = 0);
188 static absl::StatusOr<LyraTerrainDocument> Parse(
189 std::string_view text, const LyraTerrainProfile& expected_profile);
190 std::string Serialize() const;
191
192 const LyraTerrainProfile& profile() const { return profile_; }
193 const Maps& maps() const { return maps_; }
194 const LyraAuthoringState& authoring() const { return authoring_; }
195 // Returns the explicit owner of a parent or child map; absent is unassigned.
196 const LyraGameplayArea* GameplayAreaForMap(int map_id) const;
197 absl::Status SetAuthoring(const LyraAuthoringState& before,
198 const LyraAuthoringState& after);
199 absl::StatusOr<uint16_t> tile(int global_x, int global_y) const;
200 absl::StatusOr<uint16_t> MapTile(int map_id, int x, int y) const;
201
202 absl::Status BeginStroke();
203 absl::Status Paint(int global_x, int global_y, uint16_t tile_id);
204 absl::StatusOr<LyraTerrainStroke> EndStroke();
205 void CancelStroke();
206 bool stroke_active() const { return stroke_active_; }
207 // Refuses stale or malformed history before changing any cell.
208 absl::Status ApplyStroke(const LyraTerrainStroke& stroke, bool undo);
209
210 bool dirty() const {
212 }
217
218 private:
225 bool stroke_active_ = false;
227 std::unordered_map<size_t, size_t> active_cells_;
228};
229
230} // namespace yaze::core
231
232#endif // YAZE_CORE_LYRA_TERRAIN_DOCUMENT_H_
std::array< Map, kMapCount > Maps
const LyraAuthoringState & authoring() const
absl::StatusOr< uint16_t > tile(int global_x, int global_y) const
std::array< uint16_t, kMapSize *kMapSize > Map
const LyraTerrainProfile & profile() const
absl::StatusOr< LyraTerrainStroke > EndStroke()
static absl::StatusOr< LyraTerrainDocument > Parse(std::string_view text, const LyraTerrainProfile &expected_profile)
absl::Status ApplyStroke(const LyraTerrainStroke &stroke, bool undo)
absl::Status Paint(int global_x, int global_y, uint16_t tile_id)
std::unordered_map< size_t, size_t > active_cells_
absl::StatusOr< uint16_t > MapTile(int map_id, int x, int y) const
const LyraGameplayArea * GameplayAreaForMap(int map_id) const
static absl::StatusOr< LyraTerrainDocument > Create(const LyraTerrainProfile &profile, uint16_t fill_tile=0)
absl::Status SetAuthoring(const LyraAuthoringState &before, const LyraAuthoringState &after)
absl::StatusOr< std::vector< int > > LyraGameplayAreaFootprint(int parent_map_id, LyraGameplayAreaSize size)
bool LyraEdgeMapsAdjacent(int map_a, int map_b)
std::vector< LyraGameplayArea > gameplay_areas
bool operator==(const LyraAuthoringState &) const =default
std::array< LyraMapAuthoring, 32 > maps
std::vector< LyraFlightPoint > flight_points
std::vector< LyraEdgeConnection > edge_connections
bool operator==(const LyraDoorPlacement &) const =default
bool operator==(const LyraEdgeConnection &) const =default
std::optional< LyraEdgePassage > passage
bool operator==(const LyraEdgePassage &) const =default
bool operator==(const LyraExitPlacement &) const =default
bool operator==(const LyraFlightPoint &) const =default
bool operator==(const LyraGameplayArea &) const =default
std::array< std::string, 3 > asset_bindings
bool operator==(const LyraMapAuthoring &) const =default
std::vector< LyraExitPlacement > exits
std::vector< LyraSpritePlacement > sprites
std::vector< LyraDoorPlacement > doors
std::optional< std::array< uint16_t, 128 > > background_palette
std::array< uint8_t, 8 > graphics_sheets
bool operator==(const LyraMapProperties &) const =default
bool operator==(const LyraSpritePlacement &) const =default
bool operator==(const LyraTerrainProfile &) const =default
std::array< uint8_t, 8 > graphics_sheets
std::vector< LyraTerrainCellChange > changes