diff --git a/src/app/asm/script.cc b/src/app/asm/script.cc index e7bc30b0..1972e958 100644 --- a/src/app/asm/script.cc +++ b/src/app/asm/script.cc @@ -56,6 +56,10 @@ std::string GenerateBytePool(char mosaic_tiles[core::kNumOverworldMaps]) { } absl::Status Script::ApplyPatchToROM(ROM &rom) { + if (patch_contents_.empty() || patch_filename_.empty()) { + return absl::InvalidArgumentError("No patch loaded!"); + } + char *data = (char *)rom.data(); int size = rom.GetSize(); int count = 0; @@ -68,7 +72,8 @@ absl::Status Script::ApplyPatchToROM(ROM &rom) { } absl::Status Script::GenerateMosaicChangeAssembly( - ROM &rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset) { + ROM &rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, + int hook_offset) { std::fstream file("assets/asm/mosaic_change.asm", std::ios::out | std::ios::in); if (!file.is_open()) { @@ -81,6 +86,7 @@ absl::Status Script::GenerateMosaicChangeAssembly( file.close(); auto assembly_string = assembly.str(); + if (!core::StringReplace(assembly_string, "", kMosaicChangeOffset)) { return absl::InternalError( "Mosaic template did not have proper `` to replace."); @@ -94,6 +100,7 @@ absl::Status Script::GenerateMosaicChangeAssembly( } assembly_string += GenerateBytePool(mosaic_tiles); + patch_contents_ = assembly_string; patch_filename_ = "assets/asm/mosaic_change_generated.asm"; std::ofstream new_file(patch_filename_, std::ios::out); if (new_file.is_open()) { diff --git a/src/app/asm/script.h b/src/app/asm/script.h index e5edcfe9..4b8e4a7c 100644 --- a/src/app/asm/script.h +++ b/src/app/asm/script.h @@ -23,16 +23,24 @@ namespace snes_asm { const std::string kMosaicChangeOffset = "$02AADB"; constexpr int kSNESToPCOffset = 0x138000; -class Script { +class ScriptTemplate { + public: + virtual absl::Status ApplyPatchToROM(ROM& rom) = 0; + virtual absl::Status GenerateMosaicChangeAssembly( + ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, + int hook_offset = 0) = 0; +}; + +class Script : public ScriptTemplate { public: Script() { asar_init_with_dll_path("assets/libasar.dll"); } + absl::Status ApplyPatchToROM(ROM& rom) override; absl::Status GenerateMosaicChangeAssembly( - ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset); + ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, + int hook_offset = 0) override; private: - absl::Status ApplyPatchToROM(ROM& rom); - int64_t patch_size_; std::string patch_filename_; std::string patch_contents_; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0b83417e..125c4c0d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable( yaze_test yaze_test.cc rom_test.cc + asm_test.cc ../src/app/rom.cc ../src/app/asm/script.cc ../src/app/gfx/bitmap.cc diff --git a/test/asm_test.cc b/test/asm_test.cc new file mode 100644 index 00000000..6ce8cfcc --- /dev/null +++ b/test/asm_test.cc @@ -0,0 +1,66 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "app/asm/script.h" +#include "app/core/constants.h" +#include "app/rom.h" + +namespace yaze_test { +namespace asm_test { + +using yaze::app::ROM; +using yaze::app::snes_asm::Script; + +using ::testing::_; +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::Return; + +class MockScript : public Script { + public: + MOCK_METHOD(absl::Status, ApplyPatchToROM, (ROM & rom)); + MOCK_METHOD(absl::Status, GenerateMosaicChangeAssembly, + (ROM & rom, char mosaic_tiles[yaze::app::core::kNumOverworldMaps], + int routine_offset, int hook_offset)); +}; + +TEST(ASMTest, ApplyMosaicChangePatchOk) { + ROM rom; + MockScript script; + char mosaic_tiles[yaze::app::core::kNumOverworldMaps]; + + EXPECT_CALL(script, GenerateMosaicChangeAssembly(_, Eq(mosaic_tiles), + Eq(0x1301D0 + 0x138000), 0)) + .WillOnce(Return(absl::OkStatus())); + + EXPECT_CALL(script, ApplyPatchToROM(_)).WillOnce(Return(absl::OkStatus())); + + EXPECT_THAT(script.GenerateMosaicChangeAssembly(rom, mosaic_tiles, + 0x1301D0 + 0x138000, 0), + absl::OkStatus()); + EXPECT_THAT(script.ApplyPatchToROM(rom), absl::OkStatus()); +} + +TEST(ASMTest, NoPatchLoadedError) { + ROM rom; + MockScript script; + EXPECT_CALL(script, ApplyPatchToROM(_)) + .WillOnce(Return(absl::InvalidArgumentError("No patch loaded!"))); + + EXPECT_THAT(script.ApplyPatchToROM(rom), + absl::InvalidArgumentError("No patch loaded!")); +} + +} // namespace asm_test +} // namespace yaze_test \ No newline at end of file