diff --git a/.gitignore b/.gitignore index 49288515..a22892fc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,7 @@ src/lib/libSDL2_test.a src/lib/libSDL2-2.0.0.dylib src/lib/libSDL2.a src/lib/libSDL2.dylib -src/lib/libSDL2main.a \ No newline at end of file +src/lib/libSDL2main.a +checks.json +assets/lib/libasar.dll +cmake/yaze.plist.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 51cc0ff6..47398dda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,9 @@ else() find_package(SDL2) endif() +# Asar ------------------------------------------------------------------------ +add_subdirectory(src/lib/asar/src) +include(cmake/asar.cmake) # ImGui ----------------------------------------------------------------------- include(cmake/imgui.cmake) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fd59e5b..dbc43580 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,11 +32,6 @@ set( app/zelda3/sprite.cc ) -set( - YAZE_APP_ASM_SRC - app/asm/script.cc -) - set( YAZE_GUI_SRC gui/canvas.cc @@ -52,12 +47,12 @@ add_executable( yaze app/yaze.cc app/rom.cc - ${YAZE_APP_ASM_SRC} ${YAZE_APP_CORE_SRC} ${YAZE_APP_EDITOR_SRC} ${YAZE_APP_GFX_SRC} ${YAZE_APP_ZELDA3_SRC} ${YAZE_GUI_SRC} + ${ASAR_STATIC_SRC} ${IMGUI_SRC} ) @@ -71,6 +66,7 @@ target_include_directories( ${PNG_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS} + lib/asar/src/asar/ ) set(SDL_TARGETS SDL2::SDL2) @@ -90,6 +86,7 @@ target_link_libraries( ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES} ${CMAKE_DL_LIBS} + asar-static ImGui ) diff --git a/src/app/asm/script.cc b/src/app/asm/script.cc deleted file mode 100644 index 6027cd28..00000000 --- a/src/app/asm/script.cc +++ /dev/null @@ -1,74 +0,0 @@ -#include "script.h" - -// #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/core/common.h" -#include "app/core/constants.h" -#include "app/rom.h" - -namespace yaze { -namespace app { -namespace snes_asm { - -absl::Status Script::ApplyPatchToROM(ROM &rom) { - if (patch_contents_.empty() || patch_filename_.empty()) { - return absl::InvalidArgumentError("No patch loaded!"); - } - int count = 0; - auto data = (char *)rom.data(); - int size = rom.size(); - // if (!asar_patch(patch_filename_.c_str(), data, patch_size_, &size)) { - // auto asar_error = asar_geterrors(&count); - // auto full_error = asar_error->fullerrdata; - // return absl::InternalError(absl::StrCat("ASAR Error: ", full_error)); - // } - return absl::OkStatus(); -} - -absl::Status Script::PatchOverworldMosaic( - ROM &rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, - int hook_offset) { - for (int i = 0; i < core::kNumOverworldMaps; i++) { - if (mosaic_tiles[i]) { - rom[core::overworldCustomMosaicArray + i] = 0x01; - } else { - rom[core::overworldCustomMosaicArray + i] = 0x00; - } - } - std::fstream file("assets/asm/mosaic_change.asm", - std::ios::out | std::ios::in); - if (!file.is_open()) { - return absl::InvalidArgumentError( - "Unable to open mosaic change assembly source"); - } - std::stringstream assembly; - assembly << file.rdbuf(); - file.close(); - auto assembly_string = assembly.str(); - if (!core::StringReplace(assembly_string, "", kMosaicChangeOffset)) { - return absl::InternalError( - "Mosaic template did not have proper `` to replace."); - } - if (!core::StringReplace( - assembly_string, "", - absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) { - return absl::InternalError( - "Mosaic template did not have proper `` to replace."); - } - patch_contents_ = assembly_string; - return ApplyPatchToROM(rom); -} - -} // namespace snes_asm -} // namespace app -} // namespace yaze \ No newline at end of file diff --git a/src/app/asm/script.h b/src/app/asm/script.h deleted file mode 100644 index 7a128c97..00000000 --- a/src/app/asm/script.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef YAZE_APP_ASM_SCRIPT_H -#define YAZE_APP_ASM_SCRIPT_H - -// #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/core/constants.h" -#include "app/rom.h" - -namespace yaze { -namespace app { -namespace snes_asm { - -const std::string kMosaicChangeOffset = "$02AADB"; -constexpr int kSNESToPCOffset = 0x138000; - -class ScriptTemplate { - public: - virtual ~ScriptTemplate() = default; - virtual absl::Status ApplyPatchToROM(ROM& rom) = 0; - virtual absl::Status PatchOverworldMosaic( - ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, - int hook_offset = 0) = 0; -}; - -class Script : public ScriptTemplate { - public: - absl::Status ApplyPatchToROM(ROM& rom) override; - absl::Status PatchOverworldMosaic( - ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset, - int hook_offset = 0) override; - - private: - int64_t patch_size_; - std::string patch_filename_; - std::string patch_contents_; -}; - -} // namespace snes_asm -} // namespace app -} // namespace yaze - -#endif \ No newline at end of file diff --git a/src/app/editor/screen_editor.cc b/src/app/editor/screen_editor.cc index f61f3534..bcf19352 100644 --- a/src/app/editor/screen_editor.cc +++ b/src/app/editor/screen_editor.cc @@ -11,7 +11,6 @@ #include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "app/asm/script.h" #include "app/core/common.h" #include "app/core/constants.h" #include "app/gfx/bitmap.h" @@ -97,7 +96,7 @@ void ScreenEditor::DrawInventoryMenuEditor() { ImGui::EndTable(); } - ImGui::Separator(); + ImGui::Separator(); END_TAB_ITEM() } @@ -142,8 +141,8 @@ void ScreenEditor::DrawMosaicEditor() { gui::InputHex("Routine Location", &overworldCustomMosaicASM); if (ImGui::Button("Generate Mosaic Assembly")) { - auto mosaic = mosaic_script_.PatchOverworldMosaic( - rom_, mosaic_tiles_, overworldCustomMosaicASM); + auto mosaic = + rom_.PatchOverworldMosaic(mosaic_tiles_, overworldCustomMosaicASM); if (!mosaic.ok()) { std::cout << mosaic; } @@ -173,7 +172,8 @@ void ScreenEditor::DrawToolset() { } void ScreenEditor::DrawInventoryToolset() { - if (ImGui::BeginTable("InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit, ImVec2(0, 0))) { + if (ImGui::BeginTable("InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit, + ImVec2(0, 0))) { ImGui::TableSetupColumn("#drawTool"); ImGui::TableSetupColumn("#sep1"); ImGui::TableSetupColumn("#zoomOut"); @@ -183,14 +183,14 @@ void ScreenEditor::DrawInventoryToolset() { ImGui::TableSetupColumn("#bg3Tool"); ImGui::TableSetupColumn("#itemTool"); - BUTTON_COLUMN(ICON_MD_UNDO) - BUTTON_COLUMN(ICON_MD_REDO) - TEXT_COLUMN(ICON_MD_MORE_VERT) - BUTTON_COLUMN(ICON_MD_ZOOM_OUT) + BUTTON_COLUMN(ICON_MD_UNDO) + BUTTON_COLUMN(ICON_MD_REDO) + TEXT_COLUMN(ICON_MD_MORE_VERT) + BUTTON_COLUMN(ICON_MD_ZOOM_OUT) BUTTON_COLUMN(ICON_MD_ZOOM_IN) - TEXT_COLUMN(ICON_MD_MORE_VERT) + TEXT_COLUMN(ICON_MD_MORE_VERT) BUTTON_COLUMN(ICON_MD_DRAW) - BUTTON_COLUMN(ICON_MD_BUILD) + BUTTON_COLUMN(ICON_MD_BUILD) ImGui::EndTable(); } diff --git a/src/app/editor/screen_editor.h b/src/app/editor/screen_editor.h index c6635dec..6de72848 100644 --- a/src/app/editor/screen_editor.h +++ b/src/app/editor/screen_editor.h @@ -5,16 +5,15 @@ #include -#include "app/asm/script.h" #include "app/core/constants.h" #include "app/gfx/bitmap.h" -#include "app/gfx/snes_tile.h" #include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" #include "app/rom.h" #include "app/zelda3/inventory.h" #include "gui/canvas.h" -#include "gui/icons.h" #include "gui/color.h" +#include "gui/icons.h" namespace yaze { namespace app { @@ -50,7 +49,6 @@ class ScreenEditor { Bytes all_gfx_; zelda3::Inventory inventory_; gfx::SNESPalette palette_; - snes_asm::Script mosaic_script_; gui::Canvas screen_canvas_; gui::Canvas tilesheet_canvas_; }; diff --git a/src/app/rom.cc b/src/app/rom.cc index e3cd4f90..30b7e998 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -1,6 +1,7 @@ #include "rom.h" #include +#include #include #include @@ -793,5 +794,57 @@ void ROM::LoadAllPalettes() { } } +absl::Status ROM::ApplyAssembly(const absl::string_view& filename, + size_t patch_size) { + int count = 0; + auto patch = filename.data(); + auto data = (char*)rom_data_.data(); + if (int size = size_; !asar_patch(patch, data, patch_size, &size)) { + auto asar_error = asar_geterrors(&count); + auto full_error = asar_error->fullerrdata; + return absl::InternalError(absl::StrCat("ASAR Error: ", full_error)); + } + return absl::OkStatus(); +} + +// TODO(scawful): Test me! +absl::Status ROM::PatchOverworldMosaic( + char mosaic_tiles[core::kNumOverworldMaps], int routine_offset) { + // Write the data for the mosaic tile array used by the assembly code. + for (int i = 0; i < core::kNumOverworldMaps; i++) { + if (mosaic_tiles[i]) { + rom_data_[core::overworldCustomMosaicArray + i] = 0x01; + } else { + rom_data_[core::overworldCustomMosaicArray + i] = 0x00; + } + } + + std::string filename = "assets/asm/mosaic_change.asm"; + std::fstream file(filename, std::ios::out | std::ios::in); + if (!file.is_open()) { + return absl::InvalidArgumentError( + "Unable to open mosaic change assembly source"); + } + + std::stringstream assembly; + assembly << file.rdbuf(); + file.close(); + auto assembly_string = assembly.str(); + + if (!core::StringReplace(assembly_string, "", kMosaicChangeOffset)) { + return absl::InternalError( + "Mosaic template did not have proper `` to replace."); + } + + if (!core::StringReplace( + assembly_string, "", + absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) { + return absl::InternalError( + "Mosaic template did not have proper `` to replace."); + } + + return ApplyAssembly(filename, assembly_string.size()); +} + } // namespace app } // namespace yaze \ No newline at end of file diff --git a/src/app/rom.h b/src/app/rom.h index be1af8ff..5e2a59b6 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -2,6 +2,7 @@ #define YAZE_APP_ROM_H #include +#include #include #include @@ -52,6 +53,9 @@ constexpr int kCompressionStringMod = 7 << 5; constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +const std::string kMosaicChangeOffset = "$02AADB"; +constexpr int kSNESToPCOffset = 0x138000; + using CommandArgumentArray = std::array, 5>; using CommandSizeArray = std::array; using DataSizeArray = std::array; @@ -94,6 +98,11 @@ class ROM { void RenderBitmap(gfx::Bitmap* bitmap) const; + absl::Status ApplyAssembly(const absl::string_view& filename, + size_t patch_size); + absl::Status PatchOverworldMosaic(char mosaic_tiles[core::kNumOverworldMaps], + int routine_offset); + auto GetTitle() const { return title; } auto GetGraphicsBin() const { return graphics_bin_; } auto GetGraphicsBuffer() const { return graphics_buffer_; } @@ -105,9 +114,7 @@ class ROM { auto begin() { return rom_data_.begin(); } auto end() { return rom_data_.end(); } auto data() { return rom_data_.data(); } - auto char_data() { - return reinterpret_cast(rom_data_.data()); - } + auto char_data() { return reinterpret_cast(rom_data_.data()); } auto size() const { return size_; } uchar& operator[](int i) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 443d6cd9..06f9870a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,17 +15,18 @@ add_executable( yaze_test.cc rom_test.cc ../src/app/rom.cc - ../src/app/asm/script.cc ../src/app/gfx/bitmap.cc ../src/app/gfx/snes_tile.cc ../src/app/gfx/snes_palette.cc ../src/app/core/common.cc + ${ASAR_STATIC_SRC} ) target_include_directories( yaze_test PUBLIC ../src/ ../src/lib/ + ../src/lib/asar/src/asar/ ${SDL_INCLUDE_DIRS} ) @@ -35,6 +36,7 @@ target_link_libraries( ${ABSL_TARGETS} ${OPENGL_LIBRARIES} ${CMAKE_DL_LIBS} + asar-static gmock_main gmock gtest_main