Update CMake configuration and CI/CD workflows
- Upgraded CMake minimum version requirement to 3.16 and updated project version to 0.3.0. - Introduced new CMake presets for build configurations, including default, debug, and release options. - Added CI/CD workflows for continuous integration and release management, enhancing automated testing and deployment processes. - Integrated Asar assembler support with new wrapper classes and CLI commands for patching ROMs. - Implemented comprehensive tests for Asar integration, ensuring robust functionality and error handling. - Enhanced packaging configuration for cross-platform support, including Windows, macOS, and Linux. - Updated documentation and added test assets for improved clarity and usability.
This commit is contained in:
@@ -27,21 +27,93 @@ absl::Status ApplyPatch::Run(const std::vector<std::string>& arg_vec) {
|
||||
}
|
||||
|
||||
absl::Status AsarPatch::Run(const std::vector<std::string>& arg_vec) {
|
||||
std::string patch_filename = arg_vec[1];
|
||||
std::string rom_filename = arg_vec[2];
|
||||
if (arg_vec.size() < 2) {
|
||||
return absl::InvalidArgumentError("Usage: asar <patch_file> <rom_file>");
|
||||
}
|
||||
|
||||
std::string patch_filename = arg_vec[0];
|
||||
std::string rom_filename = arg_vec[1];
|
||||
|
||||
// Load ROM file
|
||||
RETURN_IF_ERROR(rom_.LoadFromFile(rom_filename))
|
||||
int buflen = rom_.vector().size();
|
||||
int romlen = rom_.vector().size();
|
||||
if (!asar_patch(patch_filename.c_str(), rom_filename.data(), buflen,
|
||||
&romlen)) {
|
||||
std::string error_message = "Failed to apply patch: ";
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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", errors[i].fullerrdata);
|
||||
error_message += absl::StrFormat(" %s\n", errors[i].fullerrdata);
|
||||
}
|
||||
return absl::InternalError(error_message);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user