Refactor command handlers for improved code organization and readability

This commit is contained in:
scawful
2024-08-31 09:56:11 -04:00
parent dc0d947e35
commit f682f22eab
6 changed files with 114 additions and 105 deletions

View File

@@ -62,65 +62,17 @@ class CommandHandler {
class ApplyPatch : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
std::string rom_filename = arg_vec[1];
std::string patch_filename = arg_vec[2];
RETURN_IF_ERROR(rom_.LoadFromFile(rom_filename))
auto source = rom_.vector();
std::ifstream patch_file(patch_filename, std::ios::binary);
std::vector<uint8_t> patch;
patch.resize(rom_.size());
patch_file.read((char*)patch.data(), patch.size());
// Apply patch
std::vector<uint8_t> patched;
app::core::ApplyBpsPatch(source, patch, patched);
// Save patched file
std::ofstream patched_rom("patched.sfc", std::ios::binary);
patched_rom.write((char*)patched.data(), patched.size());
patched_rom.close();
return absl::OkStatus();
}
absl::Status handle(const std::vector<std::string>& arg_vec) override;
};
class AsarPatch : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
std::string patch_filename = arg_vec[1];
std::string rom_filename = arg_vec[2];
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: ";
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);
}
return absl::InternalError(error_message);
}
return absl::OkStatus();
}
absl::Status handle(const std::vector<std::string>& arg_vec) override;
};
class CreatePatch : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
std::vector<uint8_t> source;
std::vector<uint8_t> target;
std::vector<uint8_t> patch;
// Create patch
app::core::CreateBpsPatch(source, target, patch);
// Save patch to file
// std::ofstream patchFile("patch.bps", ios::binary);
// patchFile.write(reinterpret_cast<const char*>(patch.data()),
// patch.size()); patchFile.close();
return absl::OkStatus();
}
absl::Status handle(const std::vector<std::string>& arg_vec) override;
};
/**
@@ -161,10 +113,7 @@ class Backup : public CommandHandler {
// Compress Graphics
class Compress : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
std::cout << "Compress selected with argument: " << arg_vec[0] << std::endl;
return absl::OkStatus();
}
absl::Status handle(const std::vector<std::string>& arg_vec) override;
};
// Decompress (Export) Graphics
@@ -174,27 +123,7 @@ class Compress : public CommandHandler {
// mode:
class Decompress : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
ColorModifier underline(ColorCode::FG_UNDERLINE);
ColorModifier reset(ColorCode::FG_RESET);
std::cout << "Please specify the tilesheets you want to export\n";
std::cout << "You can input an individual sheet, a range X-Y, or comma "
"separate values.\n\n";
std::cout << underline << "Tilesheets\n" << reset;
std::cout << "0-112 -> compressed 3bpp bgr \n";
std::cout << "113-114 -> compressed 2bpp\n";
std::cout << "115-126 -> uncompressed 3bpp sprites\n";
std::cout << "127-217 -> compressed 3bpp sprites\n";
std::cout << "218-222 -> compressed 2bpp\n";
std::cout << "Enter tilesheets: ";
std::string sheet_input;
std::cin >> sheet_input;
std::cout << "Decompress selected with argument: " << arg_vec[0]
<< std::endl;
return absl::UnimplementedError("Decompress not implemented");
}
absl::Status handle(const std::vector<std::string>& arg_vec) override;
};
/**
@@ -311,30 +240,11 @@ class Expand : public CommandHandler {
}
};
/**
* @brief Start the emulator on a SNES Rom file.
* @param arg_vec `-emu <rom_file> <optional:num_cpu_cycles>`
* @return absl::Status
*/
class Emulator : public CommandHandler {
public:
absl::Status handle(const std::vector<std::string>& arg_vec) override {
std::string filename = arg_vec[0];
RETURN_IF_ERROR(rom_.LoadFromFile(filename))
return absl::OkStatus();
}
app::emu::SNES snes;
};
/**
* @brief Command handler for the CLI.
*/
struct Commands {
std::unordered_map<std::string, std::shared_ptr<CommandHandler>> handlers = {
{"-emu", std::make_shared<Emulator>()},
{"-a", std::make_shared<ApplyPatch>()},
{"-asar", std::make_shared<AsarPatch>()},
{"-c", std::make_shared<CreatePatch>()},

View File

@@ -0,0 +1,33 @@
#include "cli/command.h"
namespace yaze {
namespace cli {
absl::Status Compress::handle(const std::vector<std::string>& arg_vec) {
std::cout << "Compress selected with argument: " << arg_vec[0] << std::endl;
return absl::OkStatus();
}
absl::Status Decompress::handle(const std::vector<std::string>& arg_vec) {
ColorModifier underline(ColorCode::FG_UNDERLINE);
ColorModifier reset(ColorCode::FG_RESET);
std::cout << "Please specify the tilesheets you want to export\n";
std::cout << "You can input an individual sheet, a range X-Y, or comma "
"separate values.\n\n";
std::cout << underline << "Tilesheets\n" << reset;
std::cout << "0-112 -> compressed 3bpp bgr \n";
std::cout << "113-114 -> compressed 2bpp\n";
std::cout << "115-126 -> uncompressed 3bpp sprites\n";
std::cout << "127-217 -> compressed 3bpp sprites\n";
std::cout << "218-222 -> compressed 2bpp\n";
std::cout << "Enter tilesheets: ";
std::string sheet_input;
std::cin >> sheet_input;
std::cout << "Decompress selected with argument: " << arg_vec[0] << std::endl;
return absl::UnimplementedError("Decompress not implemented");
}
} // namespace cli
} // namespace yaze

61
src/cli/handlers/patch.cc Normal file
View File

@@ -0,0 +1,61 @@
#include "cli/command.h"
namespace yaze {
namespace cli {
absl::Status ApplyPatch::handle(const std::vector<std::string>& arg_vec) {
std::string rom_filename = arg_vec[1];
std::string patch_filename = arg_vec[2];
RETURN_IF_ERROR(rom_.LoadFromFile(rom_filename))
auto source = rom_.vector();
std::ifstream patch_file(patch_filename, std::ios::binary);
std::vector<uint8_t> patch;
patch.resize(rom_.size());
patch_file.read((char*)patch.data(), patch.size());
// Apply patch
std::vector<uint8_t> patched;
app::core::ApplyBpsPatch(source, patch, patched);
// Save patched file
std::ofstream patched_rom("patched.sfc", std::ios::binary);
patched_rom.write((char*)patched.data(), patched.size());
patched_rom.close();
return absl::OkStatus();
}
absl::Status AsarPatch::handle(const std::vector<std::string>& arg_vec) {
std::string patch_filename = arg_vec[1];
std::string rom_filename = arg_vec[2];
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: ";
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);
}
return absl::InternalError(error_message);
}
return absl::OkStatus();
}
absl::Status CreatePatch::handle(const std::vector<std::string>& arg_vec) {
std::vector<uint8_t> source;
std::vector<uint8_t> target;
std::vector<uint8_t> patch;
// Create patch
app::core::CreateBpsPatch(source, target, patch);
// Save patch to file
// std::ofstream patchFile("patch.bps", ios::binary);
// patchFile.write(reinterpret_cast<const char*>(patch.data()),
// patch.size()); patchFile.close();
return absl::OkStatus();
}
} // namespace cli
} // namespace yaze

View File

@@ -1,12 +1,11 @@
#include "cli/command_handler.h"
#include <string>
#include <vector>
#include <string> // for basic_string, char_traits, stoi
#include <vector> // for vector, vector<>::value_type
#include "absl/status/status.h" // for OkStatus, Status
#include "app/core/common.h" // for app
#include "app/core/constants.h" // for RETURN_IF_ERROR
#include "app/rom.h" // for ROM
#include "absl/status/status.h"
#include "app/core/common.h"
#include "app/core/constants.h"
#include "app/rom.h"
#include "cli/command.h"
namespace yaze {
namespace cli {

View File

@@ -8,10 +8,14 @@
#include <unordered_map>
#include <vector>
#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "app/core/constants.h"
#include "app/rom.h"
#include "cli/command_handler.h"
#include "cli/command.h"
ABSL_FLAG(bool, verbose, false, "Enable verbose output");
ABSL_FLAG(bool, debug, false, "Enable debug output");
namespace yaze {

View File

@@ -1,7 +1,9 @@
add_executable(
z3ed
cli/z3ed.cc
cli/command_handler.cc
cli/handlers/compress.cc
cli/handlers/patch.cc
cli/handlers/tile16_transfer.cc
app/rom.cc
app/core/common.cc
app/core/labeling.cc