yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
hack_manifest.h
Go to the documentation of this file.
1#ifndef YAZE_CORE_HACK_MANIFEST_H
2#define YAZE_CORE_HACK_MANIFEST_H
3
4#include <cstdint>
5#include <optional>
6#include <string>
7#include <unordered_map>
8#include <utility>
9#include <vector>
10
11#include "absl/status/status.h"
14
15namespace yaze::core {
16
26enum class AddressOwnership : uint8_t {
27 kVanillaSafe, // Yaze can edit; asar doesn't touch
28 kHookPatched, // Asar patches this; yaze edits are overwritten on build
29 kAsmOwned, // Entire bank owned by ASM hack
30 kShared, // Both yaze and ASM write (e.g., ZSCustomOverworld)
31 kAsmExpansion, // ROM expansion bank — only exists in patched ROM
32 kRam, // WRAM definition (not ROM data)
33 kMirror, // HiROM mirror of vanilla bank
34};
35
36std::string AddressOwnershipToString(AddressOwnership ownership);
37
42 uint32_t start;
43 uint32_t end;
45 std::string module;
46};
47
51struct OwnedBank {
52 uint8_t bank;
53 uint32_t bank_start;
54 uint32_t bank_end;
56 std::string ownership_note;
57};
58
63 uint8_t tag_id;
64 uint32_t address;
65 std::string name;
66 std::string purpose;
67 std::string source;
68 std::string feature_flag; // Empty if always enabled
69 bool enabled = true;
70};
71
76 std::string name;
77 int value;
78 bool enabled;
79 std::string source;
80};
81
86 std::string name;
87 uint32_t address;
88 std::string purpose;
89};
90
95 uint32_t hook_address; // $0ED436
96 uint32_t data_start; // $2F8000
97 uint32_t data_end; // $2FFFFF
98 uint16_t first_expanded_id; // $18D
99 uint16_t last_expanded_id; // $1D1
101 int vanilla_count; // 397
102};
103
108 std::string dev_rom;
109 std::string patched_rom;
110 std::string assembler;
111 std::string entry_point;
112 std::string build_script;
113};
114
119 uint32_t address;
121 std::string module; // From protected region, if applicable
122};
123
124// ─── Project Registry (Dungeon + Overworld data) ─────────────────────────
125
130 int id;
131 std::string name;
133 std::string type; // "entrance", "boss", "mini_boss", "connector", "normal"
135 uint8_t tag1, tag2;
136};
137
143 std::string label;
144 std::string direction; // For doors: "north"/"south"/"east"/"west"
145};
146
151 std::string id; // "D4"
152 std::string name; // "Zora Temple"
153 std::string vanilla_name; // "Thieves' Town"
154 std::vector<DungeonRoom> rooms;
155 std::vector<DungeonConnection> stairs;
156 std::vector<DungeonConnection> holewarps;
157 std::vector<DungeonConnection> doors;
158};
159
165 std::string name;
166 std::string world; // "LW", "DW", "SW"
168};
169
177 std::vector<DungeonEntry> dungeons;
178 std::vector<OverworldArea> overworld_areas;
180
181 // Universal resource labels: type -> {id_str -> label}
182 //
183 // Notes:
184 // - Keys are normalized to decimal strings for project::YazeProject::resource_labels.
185 // - Input JSON may use either decimal ("57") or hex ("0x39") IDs.
186 //
187 // Types: "room", "sprite", "item", "entrance", "overworld_map", "music"
188 std::unordered_map<std::string,
189 std::unordered_map<std::string, std::string>>
191
192 // Backward-compat accessor for room labels only
193 const std::unordered_map<std::string, std::string>& room_labels() const {
194 static const std::unordered_map<std::string, std::string> empty;
195 auto it = all_resource_labels.find("room");
196 return it != all_resource_labels.end() ? it->second : empty;
197 }
198};
199
224 public:
225 HackManifest() = default;
226
230 absl::Status LoadFromFile(const std::string& filepath);
231
235 absl::Status LoadFromString(const std::string& json_content);
236
240 [[nodiscard]] bool loaded() const { return loaded_; }
241
248 void Clear() { Reset(); }
249
250 // ─── Address Classification ───────────────────────────────
251
260 [[nodiscard]] AddressOwnership ClassifyAddress(uint32_t address) const;
261
268 [[nodiscard]] bool IsWriteOverwritten(uint32_t address) const;
269
273 [[nodiscard]] bool IsProtected(uint32_t address) const;
274
278 [[nodiscard]] std::optional<AddressOwnership> GetBankOwnership(
279 uint8_t bank) const;
280
281 // ─── Room Tags ────────────────────────────────────────────
282
286 [[nodiscard]] std::string GetRoomTagLabel(uint8_t tag_id) const;
287
291 [[nodiscard]] std::optional<RoomTagEntry> GetRoomTag(uint8_t tag_id) const;
292
296 [[nodiscard]] const std::vector<RoomTagEntry>& room_tags() const {
297 return room_tags_;
298 }
299
300 // ─── Feature Flags ────────────────────────────────────────
301
302 [[nodiscard]] bool IsFeatureEnabled(const std::string& flag_name) const;
303
304 [[nodiscard]] const std::vector<FeatureFlag>& feature_flags() const {
305 return feature_flags_;
306 }
307
308 // ─── SRAM ─────────────────────────────────────────────────
309
310 [[nodiscard]] std::string GetSramVariableName(uint32_t address) const;
311
312 [[nodiscard]] const std::vector<SramVariable>& sram_variables() const {
313 return sram_variables_;
314 }
315
316 // ─── Messages ─────────────────────────────────────────────
317
318 [[nodiscard]] const MessageLayout& message_layout() const {
319 return message_layout_;
320 }
321
322 [[nodiscard]] bool IsExpandedMessage(uint16_t message_id) const;
323
324 // ─── Protected Regions ──────────────────────────────────
325
326 [[nodiscard]] const std::vector<ProtectedRegion>& protected_regions() const {
327 return protected_regions_;
328 }
329
330 [[nodiscard]] const std::unordered_map<uint8_t, OwnedBank>& owned_banks()
331 const {
332 return owned_banks_;
333 }
334
335 // ─── Write Conflict Analysis ─────────────────────────────
336
344 [[nodiscard]] std::vector<WriteConflict> AnalyzeWriteRanges(
345 const std::vector<std::pair<uint32_t, uint32_t>>& ranges) const;
346
356 [[nodiscard]] std::vector<WriteConflict> AnalyzePcWriteRanges(
357 const std::vector<std::pair<uint32_t, uint32_t>>& pc_ranges) const;
358
359 // ─── Project Registry ────────────────────────────────────
360
367 absl::Status LoadProjectRegistry(const std::string& code_folder);
368
369 [[nodiscard]] const ProjectRegistry& project_registry() const {
370 return project_registry_;
371 }
372
373 [[nodiscard]] bool HasProjectRegistry() const {
374 return !project_registry_.dungeons.empty() ||
377 }
378
379 // ─── Oracle Progression (SRAM) ─────────────────────────────
380
381 // Updates story event completion coloring based on progression state parsed
382 // from an emulator SRAM file (.srm).
384
385 // Clears any loaded progression state and resets story graph status to
386 // default (no progress).
388
389 [[nodiscard]] std::optional<OracleProgressionState> oracle_progression_state()
390 const {
392 }
393
394 // ─── Build Pipeline ───────────────────────────────────────
395
396 [[nodiscard]] const BuildPipeline& build_pipeline() const {
397 return build_pipeline_;
398 }
399
400 // ─── Metadata ─────────────────────────────────────────────
401
402 [[nodiscard]] const std::string& hack_name() const { return hack_name_; }
403 [[nodiscard]] int manifest_version() const { return manifest_version_; }
404 [[nodiscard]] int total_hooks() const { return total_hooks_; }
405
406 private:
407 void Reset();
408
409 bool loaded_ = false;
411 std::string hack_name_;
413
414 // Protected regions (vanilla bank hooks) — sorted by start address
415 std::vector<ProtectedRegion> protected_regions_;
416
417 // Bank ownership lookup
418 std::unordered_map<uint8_t, OwnedBank> owned_banks_;
419
420 // Room tag lookup by tag ID
421 std::unordered_map<uint8_t, RoomTagEntry> room_tag_map_;
422 std::vector<RoomTagEntry> room_tags_;
423
424 // Feature flags by name
425 std::unordered_map<std::string, FeatureFlag> feature_flag_map_;
426 std::vector<FeatureFlag> feature_flags_;
427
428 // SRAM variable lookup by address
429 std::unordered_map<uint32_t, SramVariable> sram_map_;
430 std::vector<SramVariable> sram_variables_;
431
432 // Message layout
434
435 // Build pipeline
437
438 // Project registry (loaded from code_folder JSON files)
440
441 // Optional: live progression state derived from SRAM/.srm. This is used to
442 // color story event nodes and can be updated at runtime by editor panels.
443 std::optional<OracleProgressionState> oracle_progression_state_;
444};
445
446} // namespace yaze::core
447
448#endif // YAZE_CORE_HACK_MANIFEST_H
Loads and queries the hack manifest JSON for yaze-ASM integration.
std::vector< WriteConflict > AnalyzeWriteRanges(const std::vector< std::pair< uint32_t, uint32_t > > &ranges) const
Analyze a set of address ranges for write conflicts.
std::unordered_map< std::string, FeatureFlag > feature_flag_map_
std::optional< RoomTagEntry > GetRoomTag(uint8_t tag_id) const
Get the full room tag entry for a tag ID.
const std::vector< FeatureFlag > & feature_flags() const
std::unordered_map< uint8_t, OwnedBank > owned_banks_
AddressOwnership ClassifyAddress(uint32_t address) const
Classify a ROM address by ownership.
bool IsFeatureEnabled(const std::string &flag_name) const
const MessageLayout & message_layout() const
std::vector< SramVariable > sram_variables_
std::vector< ProtectedRegion > protected_regions_
bool IsWriteOverwritten(uint32_t address) const
Check if a ROM write at this address would be overwritten by asar.
const std::vector< SramVariable > & sram_variables() const
const std::vector< RoomTagEntry > & room_tags() const
Get all room tags.
const std::unordered_map< uint8_t, OwnedBank > & owned_banks() const
void Clear()
Clear any loaded manifest state.
ProjectRegistry project_registry_
bool IsExpandedMessage(uint16_t message_id) const
const std::string & hack_name() const
const ProjectRegistry & project_registry() const
BuildPipeline build_pipeline_
std::optional< AddressOwnership > GetBankOwnership(uint8_t bank) const
Get the bank ownership for a given bank number.
std::optional< OracleProgressionState > oracle_progression_state_
bool HasProjectRegistry() const
std::unordered_map< uint32_t, SramVariable > sram_map_
std::string GetSramVariableName(uint32_t address) const
std::unordered_map< uint8_t, RoomTagEntry > room_tag_map_
const std::vector< ProtectedRegion > & protected_regions() const
absl::Status LoadProjectRegistry(const std::string &code_folder)
Load project registry data from the code folder.
bool IsProtected(uint32_t address) const
Check if an address is in a protected region.
std::optional< OracleProgressionState > oracle_progression_state() const
absl::Status LoadFromFile(const std::string &filepath)
Load manifest from a JSON file path.
absl::Status LoadFromString(const std::string &json_content)
Load manifest from a JSON string.
MessageLayout message_layout_
std::string GetRoomTagLabel(uint8_t tag_id) const
Get the human-readable label for a room tag ID.
std::vector< WriteConflict > AnalyzePcWriteRanges(const std::vector< std::pair< uint32_t, uint32_t > > &pc_ranges) const
Analyze a set of PC-offset ranges for write conflicts.
bool loaded() const
Check if the manifest has been loaded.
void SetOracleProgressionState(const OracleProgressionState &state)
const BuildPipeline & build_pipeline() const
std::vector< RoomTagEntry > room_tags_
std::vector< FeatureFlag > feature_flags_
The complete Oracle narrative progression graph.
bool loaded() const
Check if the graph has been loaded.
std::string AddressOwnershipToString(AddressOwnership ownership)
AddressOwnership
Ownership classification for ROM addresses and banks.
Build pipeline information.
A connection between two rooms (stair, holewarp, or door).
A complete dungeon entry with rooms and connections.
std::vector< DungeonConnection > doors
std::vector< DungeonConnection > holewarps
std::vector< DungeonRoom > rooms
std::vector< DungeonConnection > stairs
A room within a dungeon, with spatial and metadata info.
A compile-time feature flag.
Message range information for the expanded message system.
Oracle of Secrets game progression state parsed from SRAM.
An overworld area from the overworld registry.
An expanded bank with ownership classification.
AddressOwnership ownership
std::string ownership_note
Project-level registry data loaded from the Oracle planning outputs.
std::vector< DungeonEntry > dungeons
std::vector< OverworldArea > overworld_areas
const std::unordered_map< std::string, std::string > & room_labels() const
std::unordered_map< std::string, std::unordered_map< std::string, std::string > > all_resource_labels
A contiguous protected ROM region owned by the ASM hack.
A room tag entry from the dispatch table.
A custom SRAM variable definition.
A conflict detected when yaze wants to write to an ASM-owned address.
AddressOwnership ownership