cleaned asset_processor to build without warnings

This commit is contained in:
Henny022p 2021-11-23 20:22:22 +01:00
parent dee773da4a
commit 794d5fc97c
20 changed files with 190 additions and 196 deletions

View File

@ -2,6 +2,7 @@ file(GLOB_RECURSE sources *.cpp)
add_executable(asset_processor ${sources})
target_include_directories(asset_processor PRIVATE .)
target_link_libraries(asset_processor PRIVATE nlohmann_json::nlohmann_json filesystem)
target_link_libraries(asset_processor PRIVATE project_settings)
target_link_libraries(asset_processor PRIVATE fmt::fmt nlohmann_json::nlohmann_json filesystem)
install(TARGETS asset_processor RUNTIME DESTINATION bin)

View File

@ -2,8 +2,8 @@
#include "util.h"
std::filesystem::path AifAsset::generateAssetPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".aif");
std::filesystem::path asset_path = path;
return asset_path.replace_extension(".aif");
}
void AifAsset::convertToHumanReadable(const std::vector<char>& baserom) {
@ -11,17 +11,17 @@ void AifAsset::convertToHumanReadable(const std::vector<char>& 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);
cmd.push_back(toolsPath / "bin" / "aif2pcm");
cmd.push_back(path);
cmd.push_back(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);
cmd.push_back(toolsPath / "bin" / "aif2pcm");
cmd.push_back(assetPath);
cmd.push_back(path);
check_call(cmd);
}

View File

@ -2,33 +2,34 @@
#include "reader.h"
#include <fstream>
#include <iostream>
#include <fmt/format.h>
void AnimationAsset::convertToHumanReadable(const std::vector<char>& baserom) {
Reader reader(baserom, this->start, this->size);
Reader reader(baserom, start, size);
std::vector<std::string> lines;
bool end_of_animation = false;
while (!end_of_animation && reader.cursor + 3 < this->size) {
while (!end_of_animation && reader.cursor + 3 < 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");
lines.push_back(fmt::format("\tkeyframe frame_index={}", frame_index));
lines.push_back(opt_param(", duration={}", 0, keyframe_duration));
lines.push_back(opt_param(", bitfield={:#x}", 0, bitfield));
lines.push_back(opt_param(", bitfield2={:#x}", 0, bitfield2));
lines.emplace_back("\n");
}
if (!end_of_animation) {
lines.push_back("@ TODO why no terminator?\n");
lines.emplace_back("@ TODO why no terminator?\n");
}
while (reader.cursor < this->size) {
while (reader.cursor < size) {
u8 keyframe_count = reader.read_u8();
lines.push_back(string_format("\t.byte %d @ keyframe count\n", keyframe_count));
lines.push_back(fmt::format("\t.byte {} @ keyframe count\n", keyframe_count));
}
std::ofstream out(this->assetPath);
std::ofstream out(assetPath);
for (const auto& line : lines) {
out << line;
}

View File

@ -2,10 +2,10 @@
#include <fstream>
void BaseAsset::extractBinary(const std::vector<char>& baserom) {
auto first = baserom.begin() + this->start;
auto last = baserom.begin() + this->start + this->size;
auto first = baserom.begin() + start;
auto last = baserom.begin() + start + size;
std::vector<char> data(first, last);
std::fstream file(this->path, std::ios::out | std::ios::binary);
file.write(&data[0], data.size());
std::fstream file(path, std::ios::out | std::ios::binary);
file.write(&data[0], static_cast<std::streamsize>(data.size()));
file.close();
}

View File

@ -6,27 +6,27 @@
#include <nlohmann/json_fwd.hpp>
#include <string>
#include <iostream>
#include <utility>
class BaseAsset {
public:
BaseAsset(std::filesystem::path path, int start, int size, const nlohmann::json& asset)
: path(path), start(start), size(size), asset(asset) {
BaseAsset(std::filesystem::path path_, int start_, int size_, const nlohmann::json& asset_)
: path(std::move(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();
assetPath = generateAssetPath();
buildPath = 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;
virtual void convertToHumanReadable([[maybe_unused]] const std::vector<char>& baserom) {
}
// Build the asset from the human readable form back to the binary.
@ -34,30 +34,31 @@ class BaseAsset {
}
// Returns the path to the binary file extracted from the baserom.
std::filesystem::path getPath() const {
[[nodiscard]] std::filesystem::path getPath() const {
return path;
}
// Returns the path to the human readable asset file.
std::filesystem::path getAssetPath() const {
[[nodiscard]] std::filesystem::path getAssetPath() const {
return assetPath;
}
// Returns the path to the resulting file after building.
std::filesystem::path getBuildPath() const {
[[nodiscard]] std::filesystem::path getBuildPath() const {
return buildPath;
}
// Returns the base of the filename of the asset.
std::string getSymbol() const {
[[nodiscard]] std::string getSymbol() const {
// Need to get the stem twice to remove both of the .4bpp.lz extensions.
return (this->path.stem()).stem();
return (path.stem()).stem();
}
// Returns the start address of this asset.
int getStart() const {
[[nodiscard]] int getStart() const {
return start;
}
protected:
std::filesystem::path path;
std::filesystem::path assetPath;
@ -68,10 +69,10 @@ class BaseAsset {
private:
virtual std::filesystem::path generateAssetPath() {
return this->path;
return path;
}
virtual std::filesystem::path generateBuildPath() {
return this->path;
return path;
}
};

View File

@ -2,11 +2,12 @@
#include "reader.h"
#include <fstream>
#include <iostream>
#include <fmt/format.h>
void ExitListAsset::convertToHumanReadable(const std::vector<char>& baserom) {
Reader reader(baserom, this->start, this->size);
Reader reader(baserom, start, size);
std::vector<std::string> lines;
while (reader.cursor < this->size) {
while (reader.cursor < size) {
u16 transition_type = reader.read_u16();
u16 x_pos = reader.read_u16();
u16 y_pos = reader.read_u16();
@ -21,26 +22,26 @@ void ExitListAsset::convertToHumanReadable(const std::vector<char>& baserom) {
u16 unknown_5 = reader.read_u16();
u16 padding_1 = reader.read_u16();
if (transition_type == 0xffff) {
lines.push_back("\texit_list_end\n");
lines.emplace_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");
lines.push_back(fmt::format("\texit transition={}", transition_type));
lines.push_back(opt_param(", x={:#x}", 0, x_pos));
lines.push_back(opt_param(", y={:#x}", 0, y_pos));
lines.push_back(opt_param(", destX={:#x}", 0, dest_x));
lines.push_back(opt_param(", destY={:#x}", 0, dest_y));
lines.push_back(opt_param(", screenEdge={:#x}", 0, screen_edge));
lines.push_back(opt_param(", destArea={:#x}", 0, dest_area));
lines.push_back(opt_param(", destRoom={:#x}", 0, dest_room));
lines.push_back(opt_param(", unknown={:#x}", 0, unknown_2));
lines.push_back(opt_param(", unknown2={:#x}", 0, unknown_3));
lines.push_back(opt_param(", unknown3={:#x}", 0, unknown_4));
lines.push_back(opt_param(", unknown4={:#x}", 0, unknown_5));
lines.push_back(opt_param(", padding={:#x}", 0, padding_1));
lines.emplace_back("\n");
}
std::ofstream out(this->assetPath);
std::ofstream out(assetPath);
for (const auto& line : lines) {
out << line;
}

View File

@ -3,17 +3,18 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <fmt/format.h>
void FrameObjListsAsset::convertToHumanReadable(const std::vector<char>& baserom) {
Reader reader(baserom, this->start, this->size);
Reader reader(baserom, start, size);
std::vector<int> first_level;
std::vector<int> second_level;
std::vector<u32> first_level;
std::vector<u32> second_level;
std::vector<std::string> lines;
lines.push_back("@ First level of offsets\n");
lines.emplace_back("@ First level of offsets\n");
while (reader.cursor < this->size) {
while (reader.cursor < size) {
if (std::find(first_level.begin(), first_level.end(), reader.cursor) != first_level.end()) {
// End of first level
break;
@ -21,58 +22,58 @@ void FrameObjListsAsset::convertToHumanReadable(const std::vector<char>& baserom
u32 pointer = reader.read_u32();
first_level.push_back(pointer);
lines.push_back(string_format("\t.4byte 0x%x\n", pointer));
lines.push_back(fmt::format("\t.4byte {:#x}\n", pointer));
}
lines.push_back("\n@ Second level of offsets\n");
lines.emplace_back("\n@ Second level of offsets\n");
while (reader.cursor < this->size) {
while (reader.cursor < 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));
lines.push_back(fmt::format("\t.4byte {:#x}\n", pointer));
}
int max_second_level = *std::max_element(second_level.begin(), second_level.end());
u32 max_second_level = *std::max_element(second_level.begin(), second_level.end());
while (reader.cursor < this->size) {
if (reader.cursor > max_second_level) {
while (reader.cursor < size) {
if (static_cast<u32>(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;
if (i > static_cast<u32>(reader.cursor) && (next == -1 || i < static_cast<u32>(next))) {
next = static_cast<int>(i);
}
}
int diff = next - reader.cursor;
lines.push_back(string_format("@ Skipping %d bytes\n", diff));
lines.push_back(fmt::format("@ Skipping {} 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));
lines.push_back(fmt::format("\t.byte {}\n", byte));
}
}
u8 num_objects = reader.read_u8();
lines.push_back(string_format("\t.byte %d @ num_objs\n", num_objects));
lines.push_back(fmt::format("\t.byte {} @ 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");
lines.push_back(fmt::format("\tobj x={}, y={}", x_offset, y_offset));
lines.push_back(opt_param(", bitfield={:#x}", 0, bitfield));
lines.push_back(opt_param(", bitfield2={:#x}", 0, bitfield2));
lines.emplace_back("\n");
}
}
std::ofstream out(this->assetPath);
std::ofstream out(assetPath);
for (const auto& line : lines) {
out << line;
}

View File

@ -3,7 +3,7 @@
#include <nlohmann/json.hpp>
std::filesystem::path GfxAsset::generateAssetPath() {
std::filesystem::path pngPath = this->path;
std::filesystem::path pngPath = path;
if (pngPath.extension() == ".lz") {
pngPath.replace_extension("");
}
@ -16,11 +16,11 @@ void GfxAsset::convertToHumanReadable(const std::vector<char>& 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(toolsPath / "bin" / "gbagfx");
cmd.push_back(path);
cmd.push_back(assetPath);
if (asset.contains("options")) {
for (const auto& it : asset["options"].items()) {
cmd.push_back("-" + it.key());
cmd.push_back(to_string(it.value()));
}
@ -31,8 +31,8 @@ void GfxAsset::convertToHumanReadable(const std::vector<char>& baserom) {
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);
cmd.push_back(toolsPath / "bin" / "gbagfx");
cmd.push_back(assetPath);
cmd.push_back(path);
check_call(cmd);
}

View File

@ -2,19 +2,19 @@
#include <fstream>
std::filesystem::path BaseMacroAsmAsset::generateAssetPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".s");
std::filesystem::path asset_path = path;
return asset_path.replace_extension(".s");
}
std::filesystem::path BaseMacroAsmAsset::generateBuildPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".s");
std::filesystem::path build_path = path;
return build_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";
std::ofstream out(assetPath);
out << "\t.incbin " << path << "\n";
out.close();
}

View File

@ -5,51 +5,52 @@
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include <fmt/format.h>
extern std::string gBaseromPath;
std::filesystem::path MidiAsset::generateAssetPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".mid");
std::filesystem::path asset_path = path;
return asset_path.replace_extension(".mid");
}
std::filesystem::path MidiAsset::generateBuildPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".s");
std::filesystem::path build_path = path;
return build_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::string label = path.stem();
std::filesystem::path tracksPath = this->path;
std::filesystem::path tracksPath = path;
tracksPath.replace_filename(label + "_tracks.bin");
std::filesystem::path headerPath = this->path;
std::filesystem::path headerPath = path;
headerPath.replace_filename(label + "_header.bin");
int headerOffset = this->asset["options"]["headerOffset"];
int headerOffset = asset["options"]["headerOffset"];
// Extract tracks
{
auto first = baserom.begin() + this->start;
auto last = baserom.begin() + this->start + headerOffset;
auto first = baserom.begin() + start;
auto last = baserom.begin() + 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.write(&data[0], static_cast<std::streamsize>(data.size()));
file.close();
}
// Extract header
{
auto first = baserom.begin() + this->start + headerOffset;
auto last = baserom.begin() + this->start + this->size;
auto first = baserom.begin() + start + headerOffset;
auto last = baserom.begin() + start + size;
std::vector<char> data(first, last);
std::fstream file(headerPath, std::ios::out | std::ios::binary);
file.write(&data[0], data.size());
file.write(&data[0], static_cast<std::streamsize>(data.size()));
file.close();
}
// Create dummy .s file.
std::ofstream out(this->buildPath);
std::ofstream out(buildPath);
out << "\t.incbin " << tracksPath << "\n";
out << label << "::\n";
out << "\t.incbin " << headerPath << "\n";
@ -59,35 +60,35 @@ void MidiAsset::extractBinary(const std::vector<char>& baserom) {
void MidiAsset::parseOptions(std::vector<std::string>& commonParams, std::vector<std::string>& agb2midParams) {
bool exactGateTime = true;
for (const auto& it : this->asset["options"].items()) {
for (const auto& it : asset["options"].items()) {
const std::string& key = it.key();
if (key == "group" || key == "G") {
commonParams.push_back("-G");
commonParams.emplace_back("-G");
commonParams.push_back(to_string(it.value()));
} else if (key == "priority" || key == "P") {
commonParams.push_back("-P");
commonParams.emplace_back("-P");
commonParams.push_back(to_string(it.value()));
} else if (key == "reverb" || key == "R") {
commonParams.push_back("-R");
commonParams.emplace_back("-R");
commonParams.push_back(to_string(it.value()));
} else if (key == "nominator") {
agb2midParams.push_back("-n");
agb2midParams.emplace_back("-n");
agb2midParams.push_back(to_string(it.value()));
} else if (key == "denominator") {
agb2midParams.push_back("-d");
agb2midParams.emplace_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.emplace_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.emplace_back("-t");
agb2midParams.push_back(to_string(value["nominator"]));
agb2midParams.push_back(to_string(value["denominator"]));
agb2midParams.push_back(to_string(value["time"]));
@ -107,7 +108,7 @@ void MidiAsset::parseOptions(std::vector<std::string>& commonParams, std::vector
}
if (exactGateTime) {
commonParams.push_back("-E");
commonParams.emplace_back("-E");
}
}
@ -117,26 +118,26 @@ void MidiAsset::convertToHumanReadable(const std::vector<char>& baserom) {
// Convert the options
std::vector<std::string> commonParams;
std::vector<std::string> agb2midParams;
this->parseOptions(commonParams, agb2midParams);
parseOptions(commonParams, agb2midParams);
int headerOffset = this->asset["options"]["headerOffset"];
int headerOffset = asset["options"]["headerOffset"];
std::filesystem::path toolPath = "tools";
std::vector<std::string> cmd;
cmd.push_back(toolPath / "agb2mid" / "agb2mid");
cmd.push_back(toolPath / "bin" / "agb2mid");
cmd.push_back(gBaseromPath);
cmd.push_back(string_format("0x%x", this->start + headerOffset));
cmd.push_back(fmt::format("{:#x}", start + headerOffset));
cmd.push_back(gBaseromPath); // TODO deduplicate?
cmd.push_back(this->assetPath);
cmd.push_back(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.push_back(toolPath / "bin" / "mid2agb");
cmd.push_back(assetPath);
cmd.push_back(buildPath);
cmd.insert(cmd.end(), commonParams.begin(), commonParams.end());
check_call(cmd);
}
@ -145,12 +146,12 @@ void MidiAsset::buildToBinary() {
// Convert the options
std::vector<std::string> commonParams;
std::vector<std::string> agb2midParams;
this->parseOptions(commonParams, agb2midParams);
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.push_back(toolPath / "bin" / "mid2agb");
cmd.push_back(assetPath);
cmd.push_back(buildPath);
cmd.insert(cmd.end(), commonParams.begin(), commonParams.end());
check_call(cmd);
}

View File

@ -2,8 +2,8 @@
#include "util.h"
std::filesystem::path PaletteAsset::generateAssetPath() {
std::filesystem::path path = this->path;
return path.replace_extension(".pal");
std::filesystem::path asset_path = path;
return asset_path.replace_extension(".pal");
}
void PaletteAsset::convertToHumanReadable(const std::vector<char>& baserom) {
@ -11,17 +11,17 @@ void PaletteAsset::convertToHumanReadable(const std::vector<char>& 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(toolsPath / "bin" / "gbagfx");
cmd.push_back(path);
cmd.push_back(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);
cmd.push_back(toolsPath / "bin" / "gbagfx");
cmd.push_back(assetPath);
cmd.push_back(path);
check_call(cmd);
}

View File

@ -2,22 +2,23 @@
#include "reader.h"
#include <fstream>
#include <iostream>
#include <fmt/format.h>
void SpriteFrameAsset::convertToHumanReadable(const std::vector<char>& baserom) {
Reader reader(baserom, this->start, this->size);
Reader reader(baserom, start, size);
std::vector<std::string> lines;
while (reader.cursor < this->size) {
while (reader.cursor < 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");
lines.push_back(fmt::format("\tsprite_frame first_tile_index={:#x}", first_gfx_tile_index));
lines.push_back(opt_param(", num_tiles={}", 0, num_gfx_tiles));
lines.push_back(opt_param(", unknown={:#x}", 0, unk));
lines.emplace_back("\n");
}
std::ofstream out(this->assetPath);
std::ofstream out(assetPath);
for (const auto& line : lines) {
out << line;
}

View File

@ -2,7 +2,7 @@
#include "util.h"
std::filesystem::path TilesetAsset::generateAssetPath() {
std::filesystem::path pngPath = this->path;
std::filesystem::path pngPath = path;
if (pngPath.extension() == ".lz") {
pngPath.replace_extension("");
}
@ -15,9 +15,9 @@ void TilesetAsset::convertToHumanReadable(const std::vector<char>& 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(toolsPath / "bin" / "gbagfx");
cmd.push_back(path);
cmd.push_back(assetPath);
cmd.push_back("-mwidth");
cmd.push_back("32");
check_call(cmd);
@ -26,8 +26,8 @@ void TilesetAsset::convertToHumanReadable(const std::vector<char>& baserom) {
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);
cmd.push_back(toolsPath / "bin" / "gbagfx");
cmd.push_back(assetPath);
cmd.push_back(path);
check_call(cmd);
}

View File

@ -13,6 +13,7 @@
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <fmt/format.h>
using nlohmann::json;
@ -107,12 +108,12 @@ int main(int argc, char** argv) {
// Read baserom.
std::ifstream file(gBaseromPath, std::ios::binary | std::ios::ate);
std::streamsize size = file.tellg();
auto size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<char> baserom(size);
std::vector<char> baserom(static_cast<size_t>(size));
if (!file.read(baserom.data(), size)) {
std::cerr << "Could not read baserom " << gBaseromPath << std::endl;
fmt::print(stderr, "Could not read baserom {}\n", gBaseromPath);
std::exit(1);
}
file.close();
@ -141,7 +142,7 @@ int main(int argc, char** argv) {
std::unique_ptr<OffsetCalculator> offsetCalculator;
uint currentOffset = 0;
int currentOffset = 0;
for (const auto& asset : assets) {
if (asset.contains("offsets")) { // Offset definition
if (asset["offsets"].contains(gVariant)) {
@ -221,7 +222,7 @@ std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& pa
start = asset["starts"][gVariant];
}
std::string type = "";
std::string type;
if (asset.contains("type")) {
type = asset["type"];
}
@ -256,11 +257,11 @@ std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& pa
type == "map_collision" || type == "unknown") {
// TODO implement conversions
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
} else if (type == "") {
} else if (type.empty()) {
// Unknown binary asset
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
} else {
std::cerr << "Error: Unimplemented asset type `" << type << "`" << std::endl;
fmt::print(stderr, "Error: Unimplemented asset type \"{}\"", type);
std::exit(1);
}
assetHandler->setup();
@ -287,7 +288,7 @@ bool shouldExtractAsset(const std::filesystem::path& path, const std::filesystem
void extractAsset(std::unique_ptr<BaseAsset>& assetHandler, const std::vector<char>& baserom) {
// Create the parent directory
std::filesystem::path parentDir = std::filesystem::path(assetHandler->getPath());
std::filesystem::path parentDir = assetHandler->getPath();
parentDir.remove_filename();
std::filesystem::create_directories(parentDir);

View File

@ -1,9 +1,9 @@
#include "offsets.h"
OffsetCalculator::OffsetCalculator(std::filesystem::path outputFile, int baseOffset) : baseOffset(baseOffset) {
output = std::ofstream(outputFile);
OffsetCalculator::OffsetCalculator(const std::filesystem::path& outputFile, int baseOffset_)
: output(outputFile), baseOffset(baseOffset_) {
}
void OffsetCalculator::addAsset(int start, std::string symbol) {
this->output << "\t.equiv offset_" << symbol << ", " << start - this->baseOffset << std::endl;
void OffsetCalculator::addAsset(int start, const std::string& symbol) {
output << "\t.equiv offset_" << symbol << ", " << start - baseOffset << std::endl;
}

View File

@ -7,8 +7,8 @@
class OffsetCalculator {
public:
OffsetCalculator(std::filesystem::path offsetsFile, int baseOffset);
void addAsset(int start, std::string symbol);
OffsetCalculator(const std::filesystem::path& offsetsFile, int baseOffset_);
void addAsset(int start, const std::string& symbol);
private:
std::ofstream output;

View File

@ -1,10 +1,3 @@
#include "reader.h"
#include "util.h"
#include <string>
std::string opt_param(const std::string& format, int defaultVal, int value) {
if (value != defaultVal) {
return string_format(format, value);
}
return "";
}

View File

@ -1,7 +1,7 @@
#ifndef READER_H
#define READER_H
#include <stdint.h>
#include <cstdint>
#include <vector>
typedef uint8_t u8;
@ -21,26 +21,22 @@ class Reader {
data = std::vector<char>(first, last);
}
u8 read_u8() {
return this->data[this->cursor++];
s8 read_s8() {
return data[static_cast<unsigned long>(cursor++)];
}
s8 read_s8() {
return (s8)this->read_u8();
u8 read_u8() {
return static_cast<u8>(read_s8());
}
u16 read_u16() {
u16 val = (u8)this->data[this->cursor] + (((u8)this->data[this->cursor + 1]) << 8);
this->cursor += 2;
return val;
return static_cast<u16>(read_u8() + (read_u8() << 8));
}
u32 read_u32() {
u32 val = ((u8)this->data[this->cursor]) + (((u8)this->data[this->cursor + 1]) << 8) +
(((u8)this->data[this->cursor + 2]) << 16) + (((u8)this->data[this->cursor + 3]) << 24);
this->cursor += 4;
return val;
return static_cast<u32>(read_u16() + (read_u16() << 16));
}
int cursor = 0;
private:

View File

@ -1,5 +1,6 @@
#include "util.h"
#include <iostream>
#include <fmt/format.h>
void check_call(const std::vector<std::string>& cmd) {
std::string cmdstr;
@ -18,3 +19,10 @@ void check_call(const std::vector<std::string>& cmd) {
std::exit(1);
}
}
std::string opt_param(const std::string& format, int defaultVal, int value) {
if (value != defaultVal) {
return fmt::format(format, value);
}
return "";
}

View File

@ -20,17 +20,6 @@ typedef int64_t s64;
void check_call(const std::vector<std::string>& cmd);
template <typename... Args> std::string string_format(const std::string& format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size_s <= 0) {
throw std::runtime_error("Error during formatting.");
}
auto size = static_cast<size_t>(size_s);
auto buf = std::make_unique<char[]>(size);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
}
std::string opt_param(const std::string& format, int defaultVal, int value);
#endif