yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
rom_commands.cc
Go to the documentation of this file.
2
3#include <fstream>
4#include "absl/strings/str_format.h"
5#include "util/macro.h"
6
7namespace yaze {
8namespace cli {
9namespace handlers {
10
12 const resources::ArgumentParser& parser,
13 resources::OutputFormatter& formatter) {
14 if (!rom || !rom->is_loaded()) {
15 return absl::FailedPreconditionError("ROM must be loaded");
16 }
17
18 formatter.AddField("title", rom->title());
19 formatter.AddField("size", absl::StrFormat("0x%X", rom->size()));
20 formatter.AddField("size_bytes", static_cast<int>(rom->size()));
21
22 return absl::OkStatus();
23}
24
26 const resources::ArgumentParser& parser,
27 resources::OutputFormatter& formatter) {
28 if (!rom || !rom->is_loaded()) {
29 return absl::FailedPreconditionError("ROM must be loaded");
30 }
31
32 bool all_ok = true;
33 std::vector<std::string> validation_results;
34
35 // Basic ROM validation - check if ROM is loaded and has reasonable size
36 if (rom->is_loaded() && rom->size() > 0) {
37 validation_results.push_back("checksum: PASSED");
38 } else {
39 validation_results.push_back("checksum: FAILED");
40 all_ok = false;
41 }
42
43 // Header validation
44 if (rom->title() == "THE LEGEND OF ZELDA") {
45 validation_results.push_back("header: PASSED");
46 } else {
47 validation_results.push_back("header: FAILED (Invalid title: " + rom->title() + ")");
48 all_ok = false;
49 }
50
51 formatter.AddField("validation_passed", all_ok);
52 std::string results_str;
53 for (const auto& result : validation_results) {
54 if (!results_str.empty()) results_str += "; ";
55 results_str += result;
56 }
57 formatter.AddField("results", results_str);
58
59 return absl::OkStatus();
60}
61
63 const resources::ArgumentParser& parser,
64 resources::OutputFormatter& formatter) {
65 auto rom_a_opt = parser.GetString("rom_a");
66 auto rom_b_opt = parser.GetString("rom_b");
67
68 if (!rom_a_opt.has_value()) {
69 return absl::InvalidArgumentError("Missing required argument: rom_a");
70 }
71 if (!rom_b_opt.has_value()) {
72 return absl::InvalidArgumentError("Missing required argument: rom_b");
73 }
74
75 std::string rom_a_path = rom_a_opt.value();
76 std::string rom_b_path = rom_b_opt.value();
77
78 Rom rom_a;
79 auto status_a = rom_a.LoadFromFile(rom_a_path, RomLoadOptions::CliDefaults());
80 if (!status_a.ok()) {
81 return status_a;
82 }
83
84 Rom rom_b;
85 auto status_b = rom_b.LoadFromFile(rom_b_path, RomLoadOptions::CliDefaults());
86 if (!status_b.ok()) {
87 return status_b;
88 }
89
90 if (rom_a.size() != rom_b.size()) {
91 formatter.AddField("size_match", false);
92 formatter.AddField("size_a", static_cast<int>(rom_a.size()));
93 formatter.AddField("size_b", static_cast<int>(rom_b.size()));
94 return absl::OkStatus();
95 }
96
97 int differences = 0;
98 std::vector<std::string> diff_details;
99
100 for (size_t i = 0; i < rom_a.size(); ++i) {
101 if (rom_a.vector()[i] != rom_b.vector()[i]) {
102 differences++;
103 if (differences <= 10) { // Limit output to first 10 differences
104 diff_details.push_back(absl::StrFormat("0x%08X: 0x%02X vs 0x%02X",
105 i, rom_a.vector()[i], rom_b.vector()[i]));
106 }
107 }
108 }
109
110 formatter.AddField("identical", differences == 0);
111 formatter.AddField("differences_count", differences);
112 if (!diff_details.empty()) {
113 std::string diff_str;
114 for (const auto& diff : diff_details) {
115 if (!diff_str.empty()) diff_str += "; ";
116 diff_str += diff;
117 }
118 formatter.AddField("differences", diff_str);
119 }
120
121 return absl::OkStatus();
122}
123
125 const resources::ArgumentParser& parser,
126 resources::OutputFormatter& formatter) {
127 auto rom_opt = parser.GetString("rom_file");
128 auto golden_opt = parser.GetString("golden_file");
129
130 if (!rom_opt.has_value()) {
131 return absl::InvalidArgumentError("Missing required argument: rom_file");
132 }
133 if (!golden_opt.has_value()) {
134 return absl::InvalidArgumentError("Missing required argument: golden_file");
135 }
136
137 std::string rom_path = rom_opt.value();
138 std::string golden_path = golden_opt.value();
139
140 Rom source_rom;
141 auto status = source_rom.LoadFromFile(rom_path, RomLoadOptions::CliDefaults());
142 if (!status.ok()) {
143 return status;
144 }
145
146 std::ofstream file(golden_path, std::ios::binary);
147 if (!file.is_open()) {
148 return absl::NotFoundError("Could not open file for writing: " + golden_path);
149 }
150
151 file.write(reinterpret_cast<const char*>(source_rom.vector().data()), source_rom.size());
152
153 formatter.AddField("status", "success");
154 formatter.AddField("golden_file", golden_path);
155 formatter.AddField("source_file", rom_path);
156 formatter.AddField("size", static_cast<int>(source_rom.size()));
157
158 return absl::OkStatus();
159}
160
161} // namespace handlers
162} // namespace cli
163} // namespace yaze
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
Definition rom.cc:289
auto vector() const
Definition rom.h:207
auto size() const
Definition rom.h:202
bool is_loaded() const
Definition rom.h:197
auto title() const
Definition rom.h:201
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
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)
Utility for consistent output formatting across commands.
void AddField(const std::string &key, const std::string &value)
Add a key-value pair.
Main namespace for the application.
static RomLoadOptions CliDefaults()
Definition rom.cc:49