include asar, move patching to ROM class
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user