9#include "absl/status/status.h"
10#include "absl/strings/numbers.h"
11#include "absl/strings/str_format.h"
15#include "nlohmann/json.hpp"
29 : provider_(provider), previous_(provider.hack_manifest()) {}
42 std::map<int, std::string> names;
44 if (
auto it = registry.all_resource_labels.find(
"overworld_map");
45 it != registry.all_resource_labels.end()) {
46 for (
const auto& [key, label] : it->second) {
48 if (absl::SimpleAtoi(key, &
id) &&
id >= 0 &&
54 for (
const auto& area : registry.overworld_areas) {
57 names[area.area_id] = area.name;
67 if (manifest !=
nullptr && manifest->
loaded()) {
70 uint32_t snes) -> std::optional<std::pair<std::string, bool>> {
77 const uint32_t address = snes & 0x7FFFFF;
79 if (address >= hook.start && address < hook.end &&
80 !hook.module.empty()) {
81 note = absl::StrFormat(
"%s (%s)", note, hook.module);
87 if (
auto it = banks.find(
static_cast<uint8_t
>((snes >> 16) & 0x7F));
88 it != banks.end() && !it->second.ownership_note.empty()) {
89 note = absl::StrFormat(
"%s: %s", note, it->second.ownership_note);
96 return std::make_pair(note, blocking);
99 if (symbols !=
nullptr && symbols->
HasSymbols()) {
102 annotator.
symbol = [symbols](uint32_t snes) -> std::string {
103 auto anonymous = [](
const std::string& name) {
104 return name.empty() || name[0] ==
':' || name.rfind(
"pos_", 0) == 0 ||
105 name.rfind(
"neg_", 0) == 0;
107 const uint32_t start = snes >= 0x1000 ? snes - 0x1000 : 0;
110 for (
const auto& symbol : candidates) {
111 if (symbol.address <= snes && !anonymous(symbol.name) &&
116 if (best ==
nullptr) {
117 return std::string();
121 : absl::StrFormat(
"%s+$%X", best->
name, snes - best->
address);
132 if (rom ==
nullptr || !rom->
is_loaded()) {
133 return absl::FailedPreconditionError(
"ROM not loaded");
137 std::unique_ptr<project::YazeProject> opened_project;
138 std::optional<ScopedLabelManifestRestore> restore_labels;
140 if (
auto project_arg = parser.
GetString(
"project"); project_arg.has_value()) {
141 opened_project = std::make_unique<project::YazeProject>();
145 status = opened_project->Open(*project_arg);
146 }
catch (
const std::exception& error) {
147 return absl::InvalidArgumentError(absl::StrFormat(
148 "Cannot load project '%s': %s", *project_arg, error.what()));
153 manifest = &opened_project->hack_manifest;
159 if (manifest !=
nullptr && manifest->
loaded()) {
160 options.
area_names = AreaNamesFromManifest(*manifest);
164 if (!report_or.ok()) {
165 return report_or.status();
169 std::optional<zelda3::TailMapExpansionCheck> tail_check;
170 if (parser.
HasFlag(
"tail-check")) {
176 tail_check.has_value() ? &*tail_check :
nullptr;
179 const auto json = nlohmann::ordered_json::parse(
181 for (
auto it = json.begin(); it != json.end(); ++it) {
187 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 Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
ScopedLabelManifestRestore(zelda3::ResourceLabelProvider &provider)
~ScopedLabelManifestRestore()
ScopedLabelManifestRestore & operator=(const ScopedLabelManifestRestore &)=delete
ScopedLabelManifestRestore(const ScopedLabelManifestRestore &)=delete
zelda3::ResourceLabelProvider & provider_
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
bool HasFlag(const std::string &name) const
Check if a flag is present.
project::YazeProject * project_
emu::debug::SymbolProvider * symbol_provider_
Loads and queries the hack manifest JSON for yaze-ASM integration.
AddressOwnership ClassifyAddress(uint32_t address) const
Classify a ROM address by ownership.
const std::unordered_map< uint8_t, OwnedBank > & owned_banks() const
const ProjectRegistry & project_registry() const
const std::vector< ProtectedRegion > & protected_regions() const
bool loaded() const
Check if the manifest has been loaded.
Provider for symbol (label) resolution in disassembly.
std::vector< Symbol > GetSymbolsInRange(uint32_t start, uint32_t end) const
Get all symbols in an address range.
bool HasSymbols() const
Check if any symbols are loaded.
Unified interface for accessing resource labels with project overrides.
zelda3::TailCheckAnnotator MakeAnnotator(const core::HackManifest *manifest, const emu::debug::SymbolProvider *symbols)
std::map< int, std::string > AreaNamesFromManifest(const core::HackManifest &manifest)
std::string AddressOwnershipToString(AddressOwnership ownership)
constexpr int kAllocationAreaCount
TailMapExpansionCheck CheckTailMapExpansion(const Rom &rom, const TailMapExpansionPlan &plan, const TailCheckAnnotator &annotator)
std::string FormatOverworldAllocationText(const OverworldAllocationReport &report, const TailMapExpansionCheck *tail_check)
std::string OverworldAllocationToJson(const OverworldAllocationReport &report, const TailMapExpansionCheck *tail_check)
absl::StatusOr< OverworldAllocationReport > BuildOverworldAllocationReport(Rom *rom, const OverworldAllocationOptions &options)
ResourceLabelProvider & GetResourceLabels()
Get the global ResourceLabelProvider instance.
Read-only map of overworld area IDs $00-$BF: which IDs are used, which per-area tables cover each ID,...
Information about a symbol (label, constant, or address)
core::HackManifest hack_manifest
std::map< int, std::string > area_names
std::function< std::string(uint32_t)> symbol
Returns a symbol for a SNES address (empty when none).
std::function< std::optional< std::pair< std::string, bool > >(uint32_t)> ownership