Files
Torch/src/Companion.cpp
T

169 lines
5.8 KiB
C++
Raw Normal View History

2023-08-17 00:40:00 -06:00
#include "Companion.h"
#include "storm/SWrapper.h"
#include "utils/MIODecoder.h"
#include "factories/RawFactory.h"
2023-08-19 23:55:59 -06:00
#include "factories/BlobFactory.h"
#include "factories/debug/MIO0Factory.h"
2023-09-17 23:55:59 -06:00
#include "factories/AudioHeaderFactory.h"
#include "factories/SequenceFactory.h"
#include "factories/SampleFactory.h"
#include "factories/BankFactory.h"
2023-08-17 00:40:00 -06:00
#include "factories/TextureFactory.h"
#include "factories/sm64/SAnimFactory.h"
#include "factories/sm64/STextFactory.h"
#include "factories/sm64/SDialogFactory.h"
2023-10-04 23:18:35 -06:00
#include "factories/sm64/SDictionaryFactory.h"
2023-09-24 13:39:02 -06:00
#include "spdlog/spdlog.h"
2023-08-17 00:40:00 -06:00
2023-09-24 14:06:18 -06:00
#include <chrono>
2023-08-17 00:40:00 -06:00
#include <fstream>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
2023-09-24 14:06:18 -06:00
using namespace std::chrono;
2023-08-17 00:40:00 -06:00
2023-09-17 23:55:59 -06:00
void Companion::Init() {
2023-08-17 00:40:00 -06:00
2023-09-24 13:39:02 -06:00
spdlog::set_level(spdlog::level::debug);
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
2023-09-17 23:55:59 -06:00
this->RegisterFactory("AUDIO:HEADER", new AudioHeaderFactory());
this->RegisterFactory("SEQUENCE", new SequenceFactory());
this->RegisterFactory("SAMPLE", new SampleFactory());
this->RegisterFactory("BANK", new BankFactory());
this->RegisterFactory("TEXTURE", new TextureFactory());
this->RegisterFactory("BLOB", new BlobFactory());
// SM64 Specific
this->RegisterFactory("SM64:DIALOG", new SDialogFactory());
this->RegisterFactory("SM64:ANIM", new SAnimFactory());
this->RegisterFactory("SM64:TEXT", new STextFactory());
2023-10-04 23:18:35 -06:00
this->RegisterFactory("SM64:DICTIONARY", new SDictionaryFactory());
// Debug
this->RegisterFactory("MIO0", new MIO0Factory());
2023-09-17 23:55:59 -06:00
this->Process();
}
void Companion::Process() {
2023-08-17 00:40:00 -06:00
2023-09-24 14:26:01 -06:00
const std::string regular = "[%Y-%m-%d %H:%M:%S.%e] [%l] %v";
const std::string line = "[%Y-%m-%d %H:%M:%S.%e] [%l] > %v";
2023-09-24 14:06:18 -06:00
auto start = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
2023-08-17 00:40:00 -06:00
std::ifstream input( this->gRomPath, std::ios::binary );
this->gRomData = std::vector<uint8_t>( std::istreambuf_iterator<char>( input ), {} );
input.close();
2023-09-18 18:46:26 -06:00
this->cartridge = new N64::Cartridge(this->gRomData);
cartridge->Initialize();
2023-08-17 00:40:00 -06:00
2023-09-17 23:55:59 -06:00
YAML::Node config = YAML::LoadFile("config.yml");
2023-08-17 00:40:00 -06:00
2023-09-18 18:46:26 -06:00
if(!config[cartridge->GetHash()]){
2023-09-24 13:39:02 -06:00
SPDLOG_ERROR("No config found for {}", cartridge->GetHash());
2023-09-17 23:55:59 -06:00
return;
}
2023-09-18 18:46:26 -06:00
auto cfg = config[cartridge->GetHash()];
2023-09-17 23:55:59 -06:00
auto path = cfg["path"].as<std::string>();
auto otr = cfg["output"].as<std::string>();
2023-08-17 00:40:00 -06:00
2023-09-24 14:06:18 -06:00
SPDLOG_INFO("------------------------------------------------");
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(line);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("Starting CubeOS...");
SPDLOG_INFO("Game: {}", cartridge->GetGameTitle());
SPDLOG_INFO("CRC: {}", cartridge->GetCRC());
SPDLOG_INFO("Version: {}", cartridge->GetVersion());
SPDLOG_INFO("Country: [{}]", cartridge->GetCountryCode());
SPDLOG_INFO("Hash: {}", cartridge->GetHash());
SPDLOG_INFO("Assets: {}", path);
2023-09-17 23:55:59 -06:00
auto wrapper = SWrapper(otr);
2023-08-17 00:40:00 -06:00
2023-09-18 03:39:03 -06:00
auto vWriter = LUS::BinaryWriter();
vWriter.SetEndianness(LUS::Endianness::Big);
vWriter.Write((uint8_t) LUS::Endianness::Big);
2023-09-18 18:46:26 -06:00
vWriter.Write(cartridge->GetCRC());
2023-09-18 03:39:03 -06:00
2023-09-17 23:55:59 -06:00
for (const auto & entry : fs::directory_iterator(path)){
2023-09-23 23:31:37 +01:00
YAML::Node root = YAML::LoadFile(entry.path().string());
2023-09-17 23:55:59 -06:00
for(auto asset = root.begin(); asset != root.end(); ++asset){
auto type = asset->second["type"].as<std::string>();
2023-08-17 00:40:00 -06:00
2023-09-17 23:55:59 -06:00
LUS::BinaryWriter write = LUS::BinaryWriter();
RawFactory* factory = this->GetFactory(type);
2023-09-24 15:59:09 -06:00
factory->SetCartridge(cartridge);
2023-08-19 23:55:59 -06:00
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(regular);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("------------------------------------------------");
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(line);
2023-09-24 14:06:18 -06:00
SPDLOG_INFO("Processing {} [{}]", asset->first.as<std::string>(), type);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("Root: {}", entry.path().string());
2023-09-17 23:55:59 -06:00
if(!factory->process(&write, asset->second, this->gRomData)){
2023-09-24 13:39:02 -06:00
SPDLOG_ERROR("Failed to process {}", asset->first.as<std::string>());
2023-09-17 23:55:59 -06:00
continue;
2023-08-30 21:26:38 -06:00
}
2023-09-17 23:55:59 -06:00
auto buffer = write.ToVector();
2023-09-24 03:28:51 -06:00
auto output = (entry.path().stem() / asset->first.as<std::string>()).string();
std::replace(output.begin(), output.end(), '\\', '/');
wrapper.CreateFile(output, buffer);
2023-09-17 23:55:59 -06:00
if(type != "TEXTURE") {
2023-09-24 13:39:02 -06:00
SPDLOG_DEBUG("Writing debug file");
2023-09-24 03:28:51 -06:00
std::string dpath = "debug/" + output;
2023-09-17 23:55:59 -06:00
if(!fs::exists(fs::path(dpath).parent_path())){
fs::create_directories(fs::path(dpath).parent_path());
}
std::ofstream stream(dpath, std::ios::binary);
stream.write((char*)buffer.data(), buffer.size());
stream.close();
}
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("Processed {}", output);
2023-09-17 23:55:59 -06:00
write.Close();
2023-08-19 23:55:59 -06:00
}
2023-08-17 00:40:00 -06:00
}
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(regular);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("------------------------------------------------");
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(line);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("Writing version file");
2023-09-18 03:39:03 -06:00
wrapper.CreateFile("version", vWriter.ToVector());
vWriter.Close();
2023-09-24 14:06:18 -06:00
auto end = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
SPDLOG_INFO("Done! Took {}ms", end.count() - start.count());
SPDLOG_INFO("Exported to {}", otr);
2023-09-24 14:26:01 -06:00
spdlog::set_pattern(regular);
2023-09-24 13:39:02 -06:00
SPDLOG_INFO("------------------------------------------------");
2023-09-18 03:39:03 -06:00
2023-08-17 00:40:00 -06:00
MIO0Decoder::ClearCache();
wrapper.Close();
2023-09-18 18:46:26 -06:00
this->cartridge = nullptr;
Companion::Instance = nullptr;
2023-09-17 23:55:59 -06:00
}
void Companion::RegisterFactory(const std::string &extension, RawFactory *factory) {
this->gFactories[extension] = factory;
2023-09-24 13:39:02 -06:00
SPDLOG_DEBUG("Registered factory for {}", extension);
2023-09-17 23:55:59 -06:00
}
RawFactory *Companion::GetFactory(const std::string &extension) {
if(!this->gFactories.contains(extension)){
throw std::runtime_error("No factory found for " + extension);
}
return this->gFactories[extension];
}