summaryrefslogtreecommitdiff
path: root/tools/src/asset_processor/assets
diff options
context:
space:
mode:
authorHenny022p <info@henny022.de>2021-11-23 05:40:41 +0100
committerHenny022p <info@henny022.de>2021-11-23 05:40:41 +0100
commitbc4a8577f3f139a8d0b420e2decbbb9701d25c4c (patch)
tree180a00ab6fb3a51ec6776747610e56e231f4140e /tools/src/asset_processor/assets
parent47a3e614a01598cf28f9f484c5405b522fd789fe (diff)
moved asset_processor to new location
Diffstat (limited to 'tools/src/asset_processor/assets')
-rw-r--r--tools/src/asset_processor/assets/aif.cpp27
-rw-r--r--tools/src/asset_processor/assets/aif.h11
-rw-r--r--tools/src/asset_processor/assets/animation.cpp36
-rw-r--r--tools/src/asset_processor/assets/animation.h7
-rw-r--r--tools/src/asset_processor/assets/asset.cpp11
-rw-r--r--tools/src/asset_processor/assets/asset.h78
-rw-r--r--tools/src/asset_processor/assets/exitlist.cpp48
-rw-r--r--tools/src/asset_processor/assets/exitlist.h7
-rw-r--r--tools/src/asset_processor/assets/frameobjlists.cpp80
-rw-r--r--tools/src/asset_processor/assets/frameobjlists.h7
-rw-r--r--tools/src/asset_processor/assets/gfx.cpp38
-rw-r--r--tools/src/asset_processor/assets/gfx.h11
-rw-r--r--tools/src/asset_processor/assets/macroasm.cpp20
-rw-r--r--tools/src/asset_processor/assets/macroasm.h17
-rw-r--r--tools/src/asset_processor/assets/midi.cpp156
-rw-r--r--tools/src/asset_processor/assets/midi.h14
-rw-r--r--tools/src/asset_processor/assets/palette.cpp27
-rw-r--r--tools/src/asset_processor/assets/palette.h11
-rw-r--r--tools/src/asset_processor/assets/spriteframe.cpp25
-rw-r--r--tools/src/asset_processor/assets/spriteframe.h7
-rw-r--r--tools/src/asset_processor/assets/tileset.cpp33
-rw-r--r--tools/src/asset_processor/assets/tileset.h11
22 files changed, 682 insertions, 0 deletions
diff --git a/tools/src/asset_processor/assets/aif.cpp b/tools/src/asset_processor/assets/aif.cpp
new file mode 100644
index 00000000..f0c056af
--- /dev/null
+++ b/tools/src/asset_processor/assets/aif.cpp
@@ -0,0 +1,27 @@
+#include "aif.h"
+#include "util.h"
+
+std::filesystem::path AifAsset::generateAssetPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".aif");
+}
+
+void AifAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "aif2pcm" / "aif2pcm");
+ cmd.push_back(this->path);
+ cmd.push_back(this->assetPath);
+ check_call(cmd);
+}
+
+void AifAsset::buildToBinary() {
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "aif2pcm" / "aif2pcm");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->path);
+ check_call(cmd);
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/aif.h b/tools/src/asset_processor/assets/aif.h
new file mode 100644
index 00000000..131e1260
--- /dev/null
+++ b/tools/src/asset_processor/assets/aif.h
@@ -0,0 +1,11 @@
+#include "asset.h"
+
+class AifAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/animation.cpp b/tools/src/asset_processor/assets/animation.cpp
new file mode 100644
index 00000000..334d8093
--- /dev/null
+++ b/tools/src/asset_processor/assets/animation.cpp
@@ -0,0 +1,36 @@
+#include "animation.h"
+#include "reader.h"
+#include <fstream>
+#include <iostream>
+
+void AnimationAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ Reader reader(baserom, this->start, this->size);
+ std::vector<std::string> lines;
+ bool end_of_animation = false;
+ while (!end_of_animation && reader.cursor + 3 < this->size) {
+ u8 frame_index = reader.read_u8();
+ u8 keyframe_duration = reader.read_u8();
+ u8 bitfield = reader.read_u8();
+ u8 bitfield2 = reader.read_u8();
+ end_of_animation = (bitfield2 & 0x80) != 0;
+ lines.push_back(string_format("\tkeyframe frame_index=%d", frame_index));
+ lines.push_back(opt_param(", duration=%d", 0, keyframe_duration));
+ lines.push_back(opt_param(", bitfield=0x%x", 0, bitfield));
+ lines.push_back(opt_param(", bitfield2=0x%x", 0, bitfield2));
+ lines.push_back("\n");
+ }
+
+ if (!end_of_animation) {
+ lines.push_back("@ TODO why no terminator?\n");
+ }
+
+ while (reader.cursor < this->size) {
+ u8 keyframe_count = reader.read_u8();
+ lines.push_back(string_format("\t.byte %d @ keyframe count\n", keyframe_count));
+ }
+ std::ofstream out(this->assetPath);
+ for (const auto& line : lines) {
+ out << line;
+ }
+ out.close();
+}
diff --git a/tools/src/asset_processor/assets/animation.h b/tools/src/asset_processor/assets/animation.h
new file mode 100644
index 00000000..751ac8fe
--- /dev/null
+++ b/tools/src/asset_processor/assets/animation.h
@@ -0,0 +1,7 @@
+#include "macroasm.h"
+
+class AnimationAsset : public BaseMacroAsmAsset {
+ public:
+ using BaseMacroAsmAsset::BaseMacroAsmAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/asset.cpp b/tools/src/asset_processor/assets/asset.cpp
new file mode 100644
index 00000000..139f11ad
--- /dev/null
+++ b/tools/src/asset_processor/assets/asset.cpp
@@ -0,0 +1,11 @@
+#include "asset.h"
+#include <fstream>
+
+void BaseAsset::extractBinary(const std::vector<char>& baserom) {
+ auto first = baserom.begin() + this->start;
+ auto last = baserom.begin() + this->start + this->size;
+ std::vector<char> data(first, last);
+ std::fstream file(this->path, std::ios::out | std::ios::binary);
+ file.write(&data[0], data.size());
+ file.close();
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/asset.h b/tools/src/asset_processor/assets/asset.h
new file mode 100644
index 00000000..96231b0b
--- /dev/null
+++ b/tools/src/asset_processor/assets/asset.h
@@ -0,0 +1,78 @@
+#ifndef ASSET_H
+#define ASSET_H
+
+#include "util.h"
+#include <filesystem>
+#include <nlohmann/json_fwd.hpp>
+#include <string>
+#include <iostream>
+
+class BaseAsset {
+ public:
+ BaseAsset(std::filesystem::path path, int start, int size, const nlohmann::json& asset)
+ : path(path), start(start), size(size), asset(asset) {
+ }
+
+ virtual ~BaseAsset() = default;
+
+ void setup() {
+ // Cannot call virtual functions in constructor, so another function call is necessary
+ assetPath = this->generateAssetPath();
+ buildPath = this->generateBuildPath();
+ }
+
+ // Extract the binary segment for this asset from the baserom and store it in a separate file.
+ virtual void extractBinary(const std::vector<char>& baserom);
+
+ // Convert the binary data for this asset to a human readable form.
+ virtual void convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+ }
+
+ // Build the asset from the human readable form back to the binary.
+ virtual void buildToBinary() {
+ }
+
+ // Returns the path to the binary file extracted from the baserom.
+ std::filesystem::path getPath() const {
+ return path;
+ }
+ // Returns the path to the human readable asset file.
+ std::filesystem::path getAssetPath() const {
+ return assetPath;
+ }
+ // Returns the path to the resulting file after building.
+ std::filesystem::path getBuildPath() const {
+ return buildPath;
+ }
+
+ // Returns the base of the filename of the asset.
+ std::string getSymbol() const {
+ // Need to get the stem twice to remove both of the .4bpp.lz extensions.
+ return (this->path.stem()).stem();
+ }
+
+ // Returns the start address of this asset.
+ int getStart() const {
+ return start;
+ }
+
+
+ protected:
+ std::filesystem::path path;
+ std::filesystem::path assetPath;
+ std::filesystem::path buildPath;
+ int start;
+ int size;
+ const nlohmann::json& asset;
+
+ private:
+ virtual std::filesystem::path generateAssetPath() {
+ return this->path;
+ }
+ virtual std::filesystem::path generateBuildPath() {
+ return this->path;
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/exitlist.cpp b/tools/src/asset_processor/assets/exitlist.cpp
new file mode 100644
index 00000000..c4e193c6
--- /dev/null
+++ b/tools/src/asset_processor/assets/exitlist.cpp
@@ -0,0 +1,48 @@
+#include "exitlist.h"
+#include "reader.h"
+#include <fstream>
+#include <iostream>
+
+void ExitListAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ Reader reader(baserom, this->start, this->size);
+ std::vector<std::string> lines;
+ while (reader.cursor < this->size) {
+ u16 transition_type = reader.read_u16();
+ u16 x_pos = reader.read_u16();
+ u16 y_pos = reader.read_u16();
+ u16 dest_x = reader.read_u16();
+ u16 dest_y = reader.read_u16();
+ u8 screen_edge = reader.read_u8();
+ u8 dest_area = reader.read_u8();
+ u8 dest_room = reader.read_u8();
+ u8 unknown_2 = reader.read_u8();
+ u8 unknown_3 = reader.read_u8();
+ u8 unknown_4 = reader.read_u8();
+ u16 unknown_5 = reader.read_u16();
+ u16 padding_1 = reader.read_u16();
+ if (transition_type == 0xffff) {
+ lines.push_back("\texit_list_end\n");
+ break;
+ }
+ lines.push_back(string_format("\texit transition=%d", transition_type));
+ lines.push_back(opt_param(", x=0x%x", 0, x_pos));
+ lines.push_back(opt_param(", y=0x%x", 0, y_pos));
+ lines.push_back(opt_param(", destX=0x%x", 0, dest_x));
+ lines.push_back(opt_param(", destY=0x%x", 0, dest_y));
+ lines.push_back(opt_param(", screenEdge=0x%x", 0, screen_edge));
+ lines.push_back(opt_param(", destArea=0x%x", 0, dest_area));
+ lines.push_back(opt_param(", destRoom=0x%x", 0, dest_room));
+ lines.push_back(opt_param(", unknown=0x%x", 0, unknown_2));
+ lines.push_back(opt_param(", unknown2=0x%x", 0, unknown_3));
+ lines.push_back(opt_param(", unknown3=0x%x", 0, unknown_4));
+ lines.push_back(opt_param(", unknown4=0x%x", 0, unknown_5));
+ lines.push_back(opt_param(", padding=0x%x", 0, padding_1));
+ lines.push_back("\n");
+ }
+
+ std::ofstream out(this->assetPath);
+ for (const auto& line : lines) {
+ out << line;
+ }
+ out.close();
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/exitlist.h b/tools/src/asset_processor/assets/exitlist.h
new file mode 100644
index 00000000..2b039124
--- /dev/null
+++ b/tools/src/asset_processor/assets/exitlist.h
@@ -0,0 +1,7 @@
+#include "macroasm.h"
+
+class ExitListAsset : public BaseMacroAsmAsset {
+ public:
+ using BaseMacroAsmAsset::BaseMacroAsmAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/frameobjlists.cpp b/tools/src/asset_processor/assets/frameobjlists.cpp
new file mode 100644
index 00000000..fa78fddd
--- /dev/null
+++ b/tools/src/asset_processor/assets/frameobjlists.cpp
@@ -0,0 +1,80 @@
+#include "frameobjlists.h"
+#include "reader.h"
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+void FrameObjListsAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ Reader reader(baserom, this->start, this->size);
+
+ std::vector<int> first_level;
+ std::vector<int> second_level;
+
+ std::vector<std::string> lines;
+ lines.push_back("@ First level of offsets\n");
+
+ while (reader.cursor < this->size) {
+ if (std::find(first_level.begin(), first_level.end(), reader.cursor) != first_level.end()) {
+ // End of first level
+ break;
+ }
+
+ u32 pointer = reader.read_u32();
+ first_level.push_back(pointer);
+ lines.push_back(string_format("\t.4byte 0x%x\n", pointer));
+ }
+
+ lines.push_back("\n@ Second level of offsets\n");
+
+ while (reader.cursor < this->size) {
+ if (std::find(second_level.begin(), second_level.end(), reader.cursor) != second_level.end()) {
+ // End of second level
+ break;
+ }
+ u32 pointer = reader.read_u32();
+ second_level.push_back(pointer);
+ lines.push_back(string_format("\t.4byte 0x%x\n", pointer));
+ }
+
+ int max_second_level = *std::max_element(second_level.begin(), second_level.end());
+
+ while (reader.cursor < this->size) {
+ if (reader.cursor > max_second_level) {
+ break;
+ }
+ if (std::find(second_level.begin(), second_level.end(), reader.cursor) == second_level.end()) {
+ // Find nearest next value that is in the second level
+ int next = -1;
+ for (const auto& i : second_level) {
+ if (i > reader.cursor && (next == -1 || i < next)) {
+ next = i;
+ }
+ }
+ int diff = next - reader.cursor;
+ lines.push_back(string_format("@ Skipping %d bytes\n", diff));
+ for (int i = 0; i < diff; i++) {
+ u8 byte = reader.read_u8();
+ lines.push_back(string_format("\t.byte %d\n", byte));
+ }
+ }
+ u8 num_objects = reader.read_u8();
+ lines.push_back(string_format("\t.byte %d @ num_objs\n", num_objects));
+
+ for (int i = 0; i < num_objects; i++) {
+ s8 x_offset = reader.read_s8();
+ s8 y_offset = reader.read_s8();
+ u8 bitfield = reader.read_u8();
+ u16 bitfield2 = reader.read_u16();
+ lines.push_back(string_format("\tobj x=%d, y=%d", x_offset, y_offset));
+ lines.push_back(opt_param(", bitfield=0x%x", 0, bitfield));
+ lines.push_back(opt_param(", bitfield2=0x%x", 0, bitfield2));
+ lines.push_back("\n");
+ }
+ }
+
+ std::ofstream out(this->assetPath);
+ for (const auto& line : lines) {
+ out << line;
+ }
+ out.close();
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/frameobjlists.h b/tools/src/asset_processor/assets/frameobjlists.h
new file mode 100644
index 00000000..728e0229
--- /dev/null
+++ b/tools/src/asset_processor/assets/frameobjlists.h
@@ -0,0 +1,7 @@
+#include "macroasm.h"
+
+class FrameObjListsAsset : public BaseMacroAsmAsset {
+ public:
+ using BaseMacroAsmAsset::BaseMacroAsmAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/gfx.cpp b/tools/src/asset_processor/assets/gfx.cpp
new file mode 100644
index 00000000..03feca77
--- /dev/null
+++ b/tools/src/asset_processor/assets/gfx.cpp
@@ -0,0 +1,38 @@
+#include "gfx.h"
+#include "util.h"
+#include <nlohmann/json.hpp>
+
+std::filesystem::path GfxAsset::generateAssetPath() {
+ std::filesystem::path pngPath = this->path;
+ if (pngPath.extension() == ".lz") {
+ pngPath.replace_extension("");
+ }
+ pngPath.replace_extension(".png");
+ return pngPath;
+}
+
+void GfxAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->path);
+ cmd.push_back(this->assetPath);
+ if (this->asset.contains("options")) {
+ for (const auto& it : this->asset["options"].items()) {
+ cmd.push_back("-" + it.key());
+ cmd.push_back(to_string(it.value()));
+ }
+ }
+ check_call(cmd);
+}
+
+void GfxAsset::buildToBinary() {
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->path);
+ check_call(cmd);
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/gfx.h b/tools/src/asset_processor/assets/gfx.h
new file mode 100644
index 00000000..394961ea
--- /dev/null
+++ b/tools/src/asset_processor/assets/gfx.h
@@ -0,0 +1,11 @@
+#include "asset.h"
+
+class GfxAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/macroasm.cpp b/tools/src/asset_processor/assets/macroasm.cpp
new file mode 100644
index 00000000..c87f355b
--- /dev/null
+++ b/tools/src/asset_processor/assets/macroasm.cpp
@@ -0,0 +1,20 @@
+#include "macroasm.h"
+#include <fstream>
+
+std::filesystem::path BaseMacroAsmAsset::generateAssetPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".s");
+}
+
+std::filesystem::path BaseMacroAsmAsset::generateBuildPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".s");
+}
+
+void BaseMacroAsmAsset::extractBinary(const std::vector<char>& baserom) {
+ BaseAsset::extractBinary(baserom);
+ // Create dummy .s file that just incbins the .bin file.
+ std::ofstream out(this->assetPath);
+ out << "\t.incbin " << this->path << "\n";
+ out.close();
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/macroasm.h b/tools/src/asset_processor/assets/macroasm.h
new file mode 100644
index 00000000..ca1f4abf
--- /dev/null
+++ b/tools/src/asset_processor/assets/macroasm.h
@@ -0,0 +1,17 @@
+#ifndef MACROASM_H
+#define MACROASM_H
+
+#include "asset.h"
+
+// Common class for all assets that are converted to asm files consisting of macros.
+class BaseMacroAsmAsset : public BaseAsset {
+ using BaseAsset::BaseAsset;
+
+ public:
+ virtual void extractBinary(const std::vector<char>& baserom);
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+ virtual std::filesystem::path generateBuildPath();
+};
+#endif
diff --git a/tools/src/asset_processor/assets/midi.cpp b/tools/src/asset_processor/assets/midi.cpp
new file mode 100644
index 00000000..6444b05e
--- /dev/null
+++ b/tools/src/asset_processor/assets/midi.cpp
@@ -0,0 +1,156 @@
+#include "midi.h"
+#include "reader.h"
+#include "util.h"
+#include <filesystem>
+#include <iostream>
+#include <fstream>
+#include <nlohmann/json.hpp>
+
+extern std::string gBaseromPath;
+
+std::filesystem::path MidiAsset::generateAssetPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".mid");
+}
+
+std::filesystem::path MidiAsset::generateBuildPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".s");
+}
+
+void MidiAsset::extractBinary(const std::vector<char>& baserom) {
+ // Custom extraction as we need a label in the middle.
+ std::string label = this->path.stem();
+
+ std::filesystem::path tracksPath = this->path;
+ tracksPath.replace_filename(label + "_tracks.bin");
+ std::filesystem::path headerPath = this->path;
+ headerPath.replace_filename(label + "_header.bin");
+
+ int headerOffset = this->asset["options"]["headerOffset"];
+
+ // Extract tracks
+ {
+ auto first = baserom.begin() + this->start;
+ auto last = baserom.begin() + this->start + headerOffset;
+ std::vector<char> data(first, last);
+ std::fstream file(tracksPath, std::ios::out | std::ios::binary);
+ file.write(&data[0], data.size());
+ file.close();
+ }
+ // Extract header
+ {
+ auto first = baserom.begin() + this->start + headerOffset;
+ auto last = baserom.begin() + this->start + this->size;
+ std::vector<char> data(first, last);
+ std::fstream file(headerPath, std::ios::out | std::ios::binary);
+ file.write(&data[0], data.size());
+ file.close();
+ }
+
+ // Create dummy .s file.
+ std::ofstream out(this->buildPath);
+ out << "\t.incbin " << tracksPath << "\n";
+ out << label << "::\n";
+ out << "\t.incbin " << headerPath << "\n";
+ out.close();
+}
+
+void MidiAsset::parseOptions(std::vector<std::string>& commonParams, std::vector<std::string>& agb2midParams) {
+ bool exactGateTime = true;
+
+ for (const auto& it : this->asset["options"].items()) {
+ const std::string& key = it.key();
+ if (key == "group" || key == "G") {
+ commonParams.push_back("-G");
+ commonParams.push_back(to_string(it.value()));
+ } else if (key == "priority" || key == "P") {
+ commonParams.push_back("-P");
+ commonParams.push_back(to_string(it.value()));
+ } else if (key == "reverb" || key == "R") {
+ commonParams.push_back("-R");
+ commonParams.push_back(to_string(it.value()));
+ } else if (key == "nominator") {
+ agb2midParams.push_back("-n");
+ agb2midParams.push_back(to_string(it.value()));
+ } else if (key == "denominator") {
+ agb2midParams.push_back("-d");
+ agb2midParams.push_back(to_string(it.value()));
+ } else if (key == "timeChanges") {
+ const nlohmann::json& value = it.value();
+ if (value.is_array()) {
+ // Multiple time changes
+ for (const auto& change : value) {
+ agb2midParams.push_back("-t");
+ agb2midParams.push_back(to_string(change["nominator"]));
+ agb2midParams.push_back(to_string(change["denominator"]));
+ agb2midParams.push_back(to_string(change["time"]));
+ }
+ } else {
+ agb2midParams.push_back("-t");
+ agb2midParams.push_back(to_string(value["nominator"]));
+ agb2midParams.push_back(to_string(value["denominator"]));
+ agb2midParams.push_back(to_string(value["time"]));
+ }
+ } else if (key == "exactGateTime") {
+ if (it.value().get<int>() == 1) {
+ exactGateTime = true;
+ } else {
+ exactGateTime = false;
+ }
+ } else if (key == "headerOffset") {
+ // ignore here
+ } else {
+ commonParams.push_back("-" + key);
+ commonParams.push_back(to_string(it.value()));
+ }
+ }
+
+ if (exactGateTime) {
+ commonParams.push_back("-E");
+ }
+}
+
+void MidiAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+
+ // Convert the options
+ std::vector<std::string> commonParams;
+ std::vector<std::string> agb2midParams;
+ this->parseOptions(commonParams, agb2midParams);
+
+ int headerOffset = this->asset["options"]["headerOffset"];
+
+ std::filesystem::path toolPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolPath / "agb2mid" / "agb2mid");
+ cmd.push_back(gBaseromPath);
+ cmd.push_back(string_format("0x%x", this->start + headerOffset));
+ cmd.push_back(gBaseromPath); // TODO deduplicate?
+ cmd.push_back(this->assetPath);
+ cmd.insert(cmd.end(), commonParams.begin(), commonParams.end());
+ cmd.insert(cmd.end(), agb2midParams.begin(), agb2midParams.end());
+ check_call(cmd);
+
+ // We also need to build the mid to an s file here, so we get shiftability after converting.
+ cmd.clear();
+ cmd.push_back(toolPath / "mid2agb" / "mid2agb");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->buildPath);
+ cmd.insert(cmd.end(), commonParams.begin(), commonParams.end());
+ check_call(cmd);
+}
+
+void MidiAsset::buildToBinary() {
+ // Convert the options
+ std::vector<std::string> commonParams;
+ std::vector<std::string> agb2midParams;
+ this->parseOptions(commonParams, agb2midParams);
+ std::filesystem::path toolPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolPath / "mid2agb" / "mid2agb");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->buildPath);
+ cmd.insert(cmd.end(), commonParams.begin(), commonParams.end());
+ check_call(cmd);
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/midi.h b/tools/src/asset_processor/assets/midi.h
new file mode 100644
index 00000000..4bd362c6
--- /dev/null
+++ b/tools/src/asset_processor/assets/midi.h
@@ -0,0 +1,14 @@
+#include "asset.h"
+
+class MidiAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void extractBinary(const std::vector<char>& baserom);
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+
+ private:
+ void parseOptions(std::vector<std::string>& commonParams, std::vector<std::string>& agb2midParams);
+ virtual std::filesystem::path generateAssetPath();
+ virtual std::filesystem::path generateBuildPath();
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/palette.cpp b/tools/src/asset_processor/assets/palette.cpp
new file mode 100644
index 00000000..74cf94c3
--- /dev/null
+++ b/tools/src/asset_processor/assets/palette.cpp
@@ -0,0 +1,27 @@
+#include "palette.h"
+#include "util.h"
+
+std::filesystem::path PaletteAsset::generateAssetPath() {
+ std::filesystem::path path = this->path;
+ return path.replace_extension(".pal");
+}
+
+void PaletteAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->path);
+ cmd.push_back(this->assetPath);
+ check_call(cmd);
+}
+
+void PaletteAsset::buildToBinary() {
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->path);
+ check_call(cmd);
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/palette.h b/tools/src/asset_processor/assets/palette.h
new file mode 100644
index 00000000..10c36ac2
--- /dev/null
+++ b/tools/src/asset_processor/assets/palette.h
@@ -0,0 +1,11 @@
+#include "asset.h"
+
+class PaletteAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/spriteframe.cpp b/tools/src/asset_processor/assets/spriteframe.cpp
new file mode 100644
index 00000000..6aea52cf
--- /dev/null
+++ b/tools/src/asset_processor/assets/spriteframe.cpp
@@ -0,0 +1,25 @@
+#include "spriteframe.h"
+#include "reader.h"
+#include <fstream>
+#include <iostream>
+
+void SpriteFrameAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ Reader reader(baserom, this->start, this->size);
+ std::vector<std::string> lines;
+ while (reader.cursor < this->size) {
+ u8 num_gfx_tiles = reader.read_u8();
+ u8 unk = reader.read_u8();
+ u16 first_gfx_tile_index = reader.read_u16();
+
+ lines.push_back(string_format("\tsprite_frame first_tile_index=0x%x", first_gfx_tile_index));
+ lines.push_back(opt_param(", num_tiles=%d", 0, num_gfx_tiles));
+ lines.push_back(opt_param(", unknown=0x%x", 0, unk));
+ lines.push_back("\n");
+ }
+
+ std::ofstream out(this->assetPath);
+ for (const auto& line : lines) {
+ out << line;
+ }
+ out.close();
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/spriteframe.h b/tools/src/asset_processor/assets/spriteframe.h
new file mode 100644
index 00000000..2022cc74
--- /dev/null
+++ b/tools/src/asset_processor/assets/spriteframe.h
@@ -0,0 +1,7 @@
+#include "macroasm.h"
+
+class SpriteFrameAsset : public BaseMacroAsmAsset {
+ public:
+ using BaseMacroAsmAsset::BaseMacroAsmAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+}; \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/tileset.cpp b/tools/src/asset_processor/assets/tileset.cpp
new file mode 100644
index 00000000..52caaa6b
--- /dev/null
+++ b/tools/src/asset_processor/assets/tileset.cpp
@@ -0,0 +1,33 @@
+#include "tileset.h"
+#include "util.h"
+
+std::filesystem::path TilesetAsset::generateAssetPath() {
+ std::filesystem::path pngPath = this->path;
+ if (pngPath.extension() == ".lz") {
+ pngPath.replace_extension("");
+ }
+ pngPath.replace_extension(".png");
+ return pngPath;
+}
+
+void TilesetAsset::convertToHumanReadable(const std::vector<char>& baserom) {
+ (void)baserom;
+
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->path);
+ cmd.push_back(this->assetPath);
+ cmd.push_back("-mwidth");
+ cmd.push_back("32");
+ check_call(cmd);
+}
+
+void TilesetAsset::buildToBinary() {
+ std::filesystem::path toolsPath = "tools";
+ std::vector<std::string> cmd;
+ cmd.push_back(toolsPath / "gbagfx" / "gbagfx");
+ cmd.push_back(this->assetPath);
+ cmd.push_back(this->path);
+ check_call(cmd);
+} \ No newline at end of file
diff --git a/tools/src/asset_processor/assets/tileset.h b/tools/src/asset_processor/assets/tileset.h
new file mode 100644
index 00000000..0affdf4d
--- /dev/null
+++ b/tools/src/asset_processor/assets/tileset.h
@@ -0,0 +1,11 @@
+#include "asset.h"
+
+class TilesetAsset : public BaseAsset {
+ public:
+ using BaseAsset::BaseAsset;
+ virtual void convertToHumanReadable(const std::vector<char>& baserom);
+ virtual void buildToBinary();
+
+ private:
+ virtual std::filesystem::path generateAssetPath();
+}; \ No newline at end of file