include asar, move patching to ROM class

This commit is contained in:
scawful
2023-01-01 15:06:38 -06:00
parent 66e320357a
commit c1526cacdf
10 changed files with 89 additions and 152 deletions

5
.gitignore vendored
View File

@@ -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
src/lib/libSDL2main.a
checks.json
assets/lib/libasar.dll
cmake/yaze.plist.in

View File

@@ -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)

View File

@@ -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
)

View File

@@ -1,74 +0,0 @@
#include "script.h"
// #include <asar/interface-lib.h>
#include <array>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <string>
#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, "<HOOK>", kMosaicChangeOffset)) {
return absl::InternalError(
"Mosaic template did not have proper `<HOOK>` to replace.");
}
if (!core::StringReplace(
assembly_string, "<EXPANDED_SPACE>",
absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) {
return absl::InternalError(
"Mosaic template did not have proper `<EXPANDED_SPACE>` to replace.");
}
patch_contents_ = assembly_string;
return ApplyPatchToROM(rom);
}
} // namespace snes_asm
} // namespace app
} // namespace yaze

View File

@@ -1,52 +0,0 @@
#ifndef YAZE_APP_ASM_SCRIPT_H
#define YAZE_APP_ASM_SCRIPT_H
// #include <asar/interface-lib.h>
#include <array>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <string>
#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

View File

@@ -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();
}

View File

@@ -5,16 +5,15 @@
#include <array>
#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_;
};

View File

@@ -1,6 +1,7 @@
#include "rom.h"
#include <SDL.h>
#include <asar/src/asar/interface-lib.h>
#include <cstddef>
#include <cstdio>
@@ -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, "<HOOK>", kMosaicChangeOffset)) {
return absl::InternalError(
"Mosaic template did not have proper `<HOOK>` to replace.");
}
if (!core::StringReplace(
assembly_string, "<EXPANDED_SPACE>",
absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) {
return absl::InternalError(
"Mosaic template did not have proper `<EXPANDED_SPACE>` to replace.");
}
return ApplyAssembly(filename, assembly_string.size());
}
} // namespace app
} // namespace yaze

View File

@@ -2,6 +2,7 @@
#define YAZE_APP_ROM_H
#include <SDL.h>
#include <asar/src/asar/interface-lib.h>
#include <cstddef>
#include <cstring>
@@ -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<std::array<char, 2>, 5>;
using CommandSizeArray = std::array<uint, 5>;
using DataSizeArray = std::array<uint, 5>;
@@ -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<char*>(rom_data_.data());
}
auto char_data() { return reinterpret_cast<char*>(rom_data_.data()); }
auto size() const { return size_; }
uchar& operator[](int i) {

View File

@@ -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