Update z3ed CLI tool and project build configuration

- Updated `.clang-tidy` and `.clangd` configurations for improved code quality checks and diagnostics.
- Added new submodules for JSON and HTTP libraries to support future features.
- Refined README and documentation files to standardize naming conventions and improve clarity.
- Introduced a new command palette in the CLI for easier command access and execution.
- Implemented various CLI handlers for managing ROM, sprites, palettes, and dungeon functionalities.
- Enhanced the TUI components for better user interaction and command execution.
- Added AI service integration for generating commands based on user prompts, expanding the CLI's capabilities.
This commit is contained in:
scawful
2025-10-01 08:57:10 -04:00
parent e7d4f5ea02
commit ba50d89e7d
46 changed files with 2421 additions and 965 deletions

View File

@@ -1,6 +1,14 @@
#include "asar-dll-bindings/c/asar.h"
#include "cli/z3ed.h"
#include "cli/tui/asar_patch.h"
#include "util/bps.h"
#include "app/core/asar_wrapper.h"
#include "absl/flags/flag.h"
#include "absl/flags/declare.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
ABSL_DECLARE_FLAG(std::string, rom);
namespace yaze {
namespace cli {
@@ -26,97 +34,56 @@ absl::Status ApplyPatch::Run(const std::vector<std::string>& arg_vec) {
return absl::OkStatus();
}
AsarPatch::AsarPatch() {}
absl::Status AsarPatch::Run(const std::vector<std::string>& arg_vec) {
if (arg_vec.size() < 2) {
return absl::InvalidArgumentError("Usage: asar <patch_file> <rom_file>");
if (arg_vec.empty()) {
return absl::InvalidArgumentError("Usage: patch apply-asar <patch.asm>");
}
const std::string& patch_file = arg_vec[0];
std::string rom_file = absl::GetFlag(FLAGS_rom);
if (rom_file.empty()) {
return absl::InvalidArgumentError("ROM file must be provided via --rom flag.");
}
rom_.LoadFromFile(rom_file);
if (!rom_.is_loaded()) {
return absl::AbortedError("Failed to load ROM.");
}
app::core::AsarWrapper wrapper;
auto init_status = wrapper.Initialize();
if (!init_status.ok()) {
return init_status;
}
std::string patch_filename = arg_vec[0];
std::string rom_filename = arg_vec[1];
// Load ROM file
RETURN_IF_ERROR(rom_.LoadFromFile(rom_filename))
// Get ROM data
auto rom_data = rom_.vector();
int buflen = static_cast<int>(rom_data.size());
int romlen = buflen;
// Ensure we have enough buffer space
const int max_rom_size = asar_maxromsize();
if (buflen < max_rom_size) {
rom_data.resize(max_rom_size, 0);
buflen = max_rom_size;
auto patch_result = wrapper.ApplyPatch(patch_file, rom_data);
if (!patch_result.ok()) {
return patch_result.status();
}
// Apply Asar patch
if (!asar_patch(patch_filename.c_str(),
reinterpret_cast<char*>(rom_data.data()),
buflen, &romlen)) {
std::string error_message = "Failed to apply Asar patch:\n";
int num_errors = 0;
const errordata* errors = asar_geterrors(&num_errors);
for (int i = 0; i < num_errors; i++) {
error_message += absl::StrFormat(" %s\n", errors[i].fullerrdata);
}
return absl::InternalError(error_message);
const auto& result = patch_result.value();
if (!result.success) {
return absl::AbortedError(absl::StrJoin(result.errors, "; "));
}
// Resize ROM to actual size
rom_data.resize(romlen);
// Update the ROM data by writing the patched data back
for (size_t i = 0; i < rom_data.size(); ++i) {
auto status = rom_.WriteByte(i, rom_data[i]);
if (!status.ok()) {
return status;
}
}
// Save patched ROM
std::string output_filename = rom_filename;
size_t dot_pos = output_filename.find_last_of('.');
if (dot_pos != std::string::npos) {
output_filename.insert(dot_pos, "_patched");
} else {
output_filename += "_patched";
}
Rom::SaveSettings settings;
settings.filename = output_filename;
RETURN_IF_ERROR(rom_.SaveToFile(settings))
std::cout << "✅ Asar patch applied successfully!" << std::endl;
std::cout << "📁 Output: " << output_filename << std::endl;
std::cout << "📊 Final ROM size: " << romlen << " bytes" << std::endl;
// Show warnings if any
int num_warnings = 0;
const errordata* warnings = asar_getwarnings(&num_warnings);
if (num_warnings > 0) {
std::cout << "⚠️ Warnings:" << std::endl;
for (int i = 0; i < num_warnings; i++) {
std::cout << " " << warnings[i].fullerrdata << std::endl;
}
}
// Show extracted symbols
int num_labels = 0;
const labeldata* labels = asar_getalllabels(&num_labels);
if (num_labels > 0) {
std::cout << "🏷️ Extracted " << num_labels << " symbols:" << std::endl;
for (int i = 0; i < std::min(10, num_labels); i++) { // Show first 10
std::cout << " " << labels[i].name << " @ $"
<< std::hex << std::uppercase << labels[i].location << std::endl;
}
if (num_labels > 10) {
std::cout << " ... and " << (num_labels - 10) << " more" << std::endl;
}
}
// TODO: Save the patched ROM
std::cout << "Patch applied successfully!" << std::endl;
return absl::OkStatus();
}
void AsarPatch::RunTUI(ftxui::ScreenInteractive& screen) {
// TODO: Implement Asar patch TUI
(void)screen; // Suppress unused parameter warning
}
// ... rest of the file
absl::Status CreatePatch::Run(const std::vector<std::string>& arg_vec) {
std::vector<uint8_t> source;
std::vector<uint8_t> target;