Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom samples support and XML support #161

Merged
merged 7 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,17 @@ endif()

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/binarytools)
add_dependencies(${PROJECT_NAME} BinaryTools)
target_link_libraries(${PROJECT_NAME} PRIVATE BinaryTools)

# Link n64graphics

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/n64graphics)
add_dependencies(${PROJECT_NAME} N64Graphics)
target_link_libraries(${PROJECT_NAME} PRIVATE N64Graphics)

# Link StormLib

if (BUILD_STORMLIB)
set(STORMLIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/StormLib)
add_subdirectory(${STORMLIB_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE storm)
endif()

# Link YamlCpp
Expand All @@ -193,7 +190,8 @@ FetchContent_Declare(
)
set(YAML_CPP_BUILD_TESTS OFF)
FetchContent_MakeAvailable(yaml-cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE yaml-cpp)

#Link Spdlog

FetchContent_Declare(
spdlog
Expand All @@ -202,7 +200,18 @@ FetchContent_Declare(
)

FetchContent_MakeAvailable(spdlog)
target_link_libraries(${PROJECT_NAME} PRIVATE spdlog)

# Link TinyXML2
set(tinyxml2_BUILD_TESTING OFF)
FetchContent_Declare(
tinyxml2
GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git
GIT_TAG 10.0.0
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(tinyxml2)

target_link_libraries(${PROJECT_NAME} PRIVATE spdlog tinyxml2 yaml-cpp storm N64Graphics BinaryTools)

if((CMAKE_SYSTEM_NAME MATCHES "Windows") AND ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
include(../cmake/HandleCompilerRT.cmake)
Expand Down
167 changes: 64 additions & 103 deletions src/Companion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ std::string ExportTypeToString(ExportType type) {
case ExportType::Header: return "Header";
case ExportType::Code: return "Code";
case ExportType::Modding: return "Modding";
case ExportType::XML: return "XML";
default:
throw std::runtime_error("Invalid ExportType");
}
Expand Down Expand Up @@ -562,66 +563,31 @@ void Companion::ProcessFile(YAML::Node root) {
for(auto asset = root.begin(); asset != root.end(); ++asset){
auto node = asset->second;
auto entryName = asset->first.as<std::string>();
auto output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');

// Parse horizontal assets
if(node["files"]){
auto segment = node["segment"] ? node["segment"].as<uint8_t>() : -1;
const auto files = node["files"];
for (const auto& file : files) {
auto assetNode = file.as<YAML::Node>();
auto childName = assetNode["name"].as<std::string>();
auto output = (this->gCurrentDirectory / entryName / childName).string();
std::replace(output.begin(), output.end(), '\\', '/');

if(assetNode["type"]){
const auto type = GetSafeNode<std::string>(assetNode, "type");
if(type == "NAUDIO:V0:SAMPLE"){
AudioManager::Instance->bind_sample(assetNode, output);
}
}

if(!assetNode["offset"]) {
continue;
}

if(segment != -1 || gCurrentSegmentNumber) {
assetNode["offset"] = (segment << 24) | assetNode["offset"].as<uint32_t>();
}

if(!gCurrentVirtualPath.empty()) {
node["path"] = gCurrentVirtualPath;
}

this->gAddrMap[this->gCurrentFile][assetNode["offset"].as<uint32_t>()] = std::make_tuple(output, assetNode);
}
} else {

auto output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');

if(node["type"]){
const auto type = GetSafeNode<std::string>(node, "type");
if(type == "NAUDIO:V0:SAMPLE"){
AudioManager::Instance->bind_sample(node, output);
}
}

if(!node["offset"]) {
continue;
if(node["type"]){
const auto type = GetSafeNode<std::string>(node, "type");
if(type == "NAUDIO:V0:SAMPLE"){
AudioManager::Instance->bind_sample(node, output);
}
}

if(gCurrentSegmentNumber) {
if (IS_SEGMENTED(node["offset"].as<uint32_t>()) == false) {
node["offset"] = (gCurrentSegmentNumber << 24) | node["offset"].as<uint32_t>();
}
}
if(!node["offset"]) {
continue;
}

if(!gCurrentVirtualPath.empty()) {
node["path"] = gCurrentVirtualPath;
if(gCurrentSegmentNumber) {
if (IS_SEGMENTED(node["offset"].as<uint32_t>()) == false) {
node["offset"] = (gCurrentSegmentNumber << 24) | node["offset"].as<uint32_t>();
}
}

this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = std::make_tuple(output, node);
if(!gCurrentVirtualPath.empty()) {
node["path"] = gCurrentVirtualPath;
}

this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = std::make_tuple(output, node);
}

// Stupid hack because the iteration broke the assets
Expand Down Expand Up @@ -659,53 +625,23 @@ void Companion::ProcessFile(YAML::Node root) {
continue;
}

// Parse horizontal assets
if(assetNode["files"]){
auto segment = assetNode["segment"] ? assetNode["segment"].as<uint8_t>() : -1;
auto files = assetNode["files"];
for (const auto& file : files) {
auto node = file.as<YAML::Node>();
auto childName = node["name"].as<std::string>();

if(!node["offset"]) {
continue;
}

if(segment != -1 || gCurrentFileOffset) {
node["offset"] = (segment << 24) | node["offset"].as<uint32_t>();
}

if(!gCurrentVirtualPath.empty()) {
node["path"] = gCurrentVirtualPath;
}

auto output = (this->gCurrentDirectory / entryName / childName).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gConfig.segment.temporal.clear();
auto result = this->ParseNode(node, output);
if(result.has_value()) {
this->gParseResults[this->gCurrentFile].push_back(result.value());
}
}
} else {
if(gCurrentFileOffset && assetNode["offset"]) {
const auto offset = assetNode["offset"].as<uint32_t>();
if (!IS_SEGMENTED(offset)) {
assetNode["offset"] = (gCurrentSegmentNumber << 24) | offset;
}
if(gCurrentFileOffset && assetNode["offset"]) {
const auto offset = assetNode["offset"].as<uint32_t>();
if (!IS_SEGMENTED(offset)) {
assetNode["offset"] = (gCurrentSegmentNumber << 24) | offset;
}
}

if(!gCurrentVirtualPath.empty()) {
assetNode["path"] = gCurrentVirtualPath;
}
if(!gCurrentVirtualPath.empty()) {
assetNode["path"] = gCurrentVirtualPath;
}

std::string output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gConfig.segment.temporal.clear();
auto result = this->ParseNode(assetNode, output);
if(result.has_value()) {
this->gParseResults[this->gCurrentFile].push_back(result.value());
}
std::string output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gConfig.segment.temporal.clear();
auto result = this->ParseNode(assetNode, output);
if(result.has_value()) {
this->gParseResults[this->gCurrentFile].push_back(result.value());
}

spdlog::set_pattern(regular);
Expand Down Expand Up @@ -733,8 +669,16 @@ void Companion::ProcessFile(YAML::Node root) {
exporter->get()->Export(stream, data, result.name, result.node, &result.name);
auto data = stream.str();
this->gCurrentWrapper->CreateFile(result.name, std::vector(data.begin(), data.end()));

for(auto& entry : this->gCompanionFiles){
auto output = (this->gCurrentDirectory / entry.first).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gCurrentWrapper->CreateFile(output, entry.second);
}

break;
}
case ExportType::XML:
case ExportType::Modding: {
stream.str("");
stream.clear();
Expand All @@ -751,12 +695,24 @@ void Companion::ProcessFile(YAML::Node root) {
create_directories(fs::path(dpath).parent_path());
}

SPDLOG_INFO(ogname);
this->gModdedAssetPaths[ogname] = result.name;

std::ofstream file(dpath, std::ios::binary);
file.write(data.c_str(), data.size());
file.close();

for(auto& entry : this->gCompanionFiles){
auto cpath = (Instance->GetOutputPath() / this->gCurrentDirectory / entry.first).string();
std::replace(cpath.begin(), cpath.end(), '\\', '/');
if(!exists(fs::path(cpath).parent_path())){
create_directories(fs::path(cpath).parent_path());
}

std::ofstream cfile(cpath, std::ios::binary);
cfile.write(entry.second.data(), entry.second.size());
cfile.close();
}

break;
}
default: {
Expand All @@ -765,6 +721,8 @@ void Companion::ProcessFile(YAML::Node root) {
}
}

this->gCompanionFiles.clear();

if(result.node["offset"]) {
auto alignment = GetSafeNode<uint32_t>(result.node, "alignment", impl->GetAlignment());
if(!endptr.has_value()) {
Expand Down Expand Up @@ -810,7 +768,7 @@ void Companion::ProcessFile(YAML::Node root) {

auto fsout = fs::path(this->gConfig.outputPath);

if(this->gConfig.exporterType == ExportType::Modding) {
if(this->gConfig.exporterType == ExportType::Modding || this->gConfig.exporterType == ExportType::XML) {
fsout /= "modding.yml";
YAML::Node modding;

Expand Down Expand Up @@ -1087,6 +1045,7 @@ void Companion::Process() {
this->gConfig.outputPath = opath && opath["code"] ? opath["code"].as<std::string>() : "code";
break;
}
case ExportType::XML:
case ExportType::Modding: {
this->gConfig.outputPath = modding_path;
break;
Expand Down Expand Up @@ -1310,9 +1269,7 @@ std::optional<std::tuple<std::string, YAML::Node>> Companion::RegisterAsset(cons

auto entry = std::make_tuple(output, node);
this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = entry;




return entry;
}

Expand Down Expand Up @@ -1459,6 +1416,11 @@ std::optional<std::vector<std::tuple<std::string, YAML::Node>>> Companion::GetNo

}

void Companion::RegisterCompanionFile(const std::string path, std::vector<char> data) {
this->gCompanionFiles[path] = data;
SPDLOG_TRACE("Registered companion file {}", path);
}

std::string Companion::NormalizeAsset(const std::string& name) const {
auto path = fs::path(this->gCurrentFile).stem().string() + "_" + name;
return path;
Expand Down Expand Up @@ -1493,7 +1455,6 @@ std::optional<YAML::Node> Companion::AddAsset(YAML::Node asset) {
const auto symbol = GetSafeNode<std::string>(asset, "symbol", "");
const auto decl = this->GetNodeByAddr(offset);


if(decl.has_value()) {
return std::get<1>(decl.value());
}
Expand Down
2 changes: 2 additions & 0 deletions src/Companion.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class Companion {
static void Pack(const std::string& folder, const std::string& output);
std::string NormalizeAsset(const std::string& name) const;
std::string RelativePath(const std::string& path) const;
void RegisterCompanionFile(const std::string path, std::vector<char> data);

TorchConfig& GetConfig() { return this->gConfig; }
SWrapper* GetCurrentWrapper() { return this->gCurrentWrapper; }
Expand Down Expand Up @@ -190,6 +191,7 @@ class Companion {
std::vector<std::string> gCurrentExternalFiles;
std::unordered_set<std::string> gProcessedFiles;

std::unordered_map<std::string, std::vector<char>> gCompanionFiles;
std::unordered_map<std::string, std::vector<ParseResultData>> gParseResults;

std::unordered_map<std::string, std::string> gModdedAssetPaths;
Expand Down
6 changes: 5 additions & 1 deletion src/factories/BaseFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
#include <variant>
#include <optional>
#include <yaml-cpp/yaml.h>
#include <filesystem>
#include <strhash64/StrHash64.h>
#include "lib/binarytools/BinaryWriter.h"
#include "lib/binarytools/BinaryReader.h"

namespace fs = std::filesystem;

#define REGISTER(type, c) { ExportType::type, std::make_shared<c>() },

#define SEGMENT_OFFSET(a) ((uint32_t)(a) & 0x00FFFFFF)
Expand All @@ -37,7 +40,8 @@ enum class ExportType {
Header,
Code,
Binary,
Modding
Modding,
XML
};

template<typename T>
Expand Down
Loading
Loading