Skip to content

Commit

Permalink
Updated with Main
Browse files Browse the repository at this point in the history
  • Loading branch information
KiritoDv committed Mar 9, 2024
1 parent c6810e2 commit 0d1e136
Show file tree
Hide file tree
Showing 20 changed files with 608 additions and 94 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ debug/
!src/factories/debug/
*.z64
*.n64
*.inc.c
headers/
build/
code/
Expand Down
98 changes: 88 additions & 10 deletions src/Companion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "factories/mk64/WaypointFactory.h"
#include "factories/sf64/ObjInitFactory.h"
#include "factories/DisplayListOverrides.h"
#include "factories/mk64/CourseVtx.h"
#include "factories/mk64/Waypoints.h"
#include "factories/mk64/TrackSections.h"
#include "factories/mk64/SpawnData.h"
#include "spdlog/spdlog.h"
#include "hj/sha1.h"

Expand Down Expand Up @@ -56,7 +60,10 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("SM64:GEO_LAYOUT", std::make_shared<SM64::GeoLayoutFactory>());

// MK64 specific
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointFactory>());
this->RegisterFactory("MK64:COURSEVTX", std::make_shared<MK64::CourseVtxFactory>());
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointsFactory>());
this->RegisterFactory("MK64:TRACKSECTIONS", std::make_shared<MK64::TrackSectionsFactory>());
this->RegisterFactory("MK64:SPAWNDATA", std::make_shared<MK64::SpawnDataFactory>());

// SF64 specific
this->RegisterFactory("SF64:OBJ_INIT", std::make_shared<SF64::ObjInitFactory>());
Expand Down Expand Up @@ -173,8 +180,9 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar

if(this->gConfig.exporterType == ExportType::Code) {
if(node["pad"]){
auto filename = this->gCurrentDirectory.filename().string();
auto pad = GetSafeNode<uint32_t>(node, "pad");
stream << "char pad_" << gCurrentPad++ << "[] = {\n" << tab;
stream << "char pad_" << filename << "_" << std::to_string(gCurrentPad++) << "[] = {\n" << tab;
for(int i = 0; i < pad; i++){
stream << "0x00, ";
}
Expand Down Expand Up @@ -208,11 +216,30 @@ void Companion::ParseModdingConfig() {

void Companion::ParseCurrentFileConfig(YAML::Node node) {
if(node["segments"]) {
for(auto segment = node["segments"].begin(); segment != node["segments"].end(); ++segment) {
const auto id = std::stoi(segment->first.as<std::string>().substr(3));
const auto replacement = segment->second.as<uint32_t>();
this->gConfig.segment.local[id] = replacement;
SPDLOG_DEBUG("Segment {} replaced with 0x{:X}", id, replacement);
auto segments = node["segments"];

// Set global variables for segmented data
if (segments.IsSequence() && segments.size()) {
if (segments[0].IsSequence() && segments[0].size() == 2) {
gCurrentSegmentNumber = segments[0][0].as<uint32_t>();
gCurrentFileOffset = segments[0][1].as<uint32_t>();
gCurrentCompressionType = GetCompressionType(this->gRomData, gCurrentFileOffset);
} else {
throw std::runtime_error("Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, <offset_of_compressed_file>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
}
}

// Set file offset for later use.
for(size_t i = 0; i < segments.size(); i++) {
auto segment = segments[i];
if (segment.IsSequence() && segment.size() == 2) {
const auto id = segment[0].as<uint32_t>();
const auto replacement = segment[1].as<uint32_t>();
this->gConfig.segment.local[id] = replacement;
SPDLOG_DEBUG("Segment {} replaced with 0x{:X}", id, replacement);
} else {
throw std::runtime_error("Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, <offset_of_compressed_file>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
}
}
}
if(node["header"]) {
Expand Down Expand Up @@ -399,6 +426,19 @@ void Companion::Process() {
this->gCurrentDirectory = relative(entry.path(), path).replace_extension("");
this->gCurrentFile = yamlPath;

// Set compressed file offsets and compression type
if (auto segments = root[":config"]["segments"]) {
if (segments.IsSequence() && segments.size() > 0) {
if (segments[0].IsSequence() && segments[0].size() == 2) {
gCurrentSegmentNumber = segments[0][0].as<uint32_t>();
gCurrentFileOffset = segments[0][1].as<uint32_t>();
gCurrentCompressionType = GetCompressionType(this->gRomData, gCurrentFileOffset);
} else {
throw std::runtime_error("Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, <offset_of_compressed_file>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
}
}
}

for(auto asset = root.begin(); asset != root.end(); ++asset){
auto node = asset->second;
auto entryName = asset->first.as<std::string>();
Expand All @@ -424,16 +464,18 @@ void Companion::Process() {
continue;
}

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

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 == "SAMPLE"){
Expand All @@ -445,6 +487,12 @@ void Companion::Process() {
continue;
}

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);
}
}
Expand All @@ -454,6 +502,7 @@ void Companion::Process() {
this->gConfig.segment.local.clear();
this->gFileHeader.clear();
GFXDOverride::ClearVtx();
this->gCurrentPad = 0;

if(root[":config"]) {
this->ParseCurrentFileConfig(root[":config"]);
Expand All @@ -472,6 +521,7 @@ void Companion::Process() {
continue;
}


// Parse horizontal assets
if(assetNode["files"]){
auto segment = assetNode["segment"] ? assetNode["segment"].as<uint8_t>() : -1;
Expand All @@ -484,7 +534,7 @@ void Companion::Process() {
continue;
}

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

Expand All @@ -494,6 +544,11 @@ void Companion::Process() {
this->ExtractNode(node, output, wrapper);
}
} else {
if(gCurrentFileOffset) {
if (IS_SEGMENTED(assetNode["offset"].as<uint32_t>()) == false) {
assetNode["offset"] = (gCurrentSegmentNumber << 24) | assetNode["offset"].as<uint32_t>();
}
}
std::string output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gConfig.segment.temporal.clear();
Expand Down Expand Up @@ -708,7 +763,30 @@ std::optional<std::string> Companion::GetEnumFromValue(const std::string& key, i
return enums[id];
}

std::optional<std::uint32_t> Companion::GetSegmentedAddr(const uint8_t segment) const {
/**
* @param offset Rom offset of compressed mio0 file.
* @returns CompressionType
*/
CompressionType Companion::GetCompressionType(std::vector<uint8_t>& buffer, const uint32_t offset) {
if (offset) {
LUS::BinaryReader reader((char*) buffer.data() + offset, sizeof(uint32_t));
reader.SetEndianness(LUS::Endianness::Big);

const std::string header = reader.ReadCString();

// Check if a compressed header exists
if (header == "MIO0") {
return CompressionType::MIO0;
} else if (header == "YAY0") {
return CompressionType::YAY0;
} else if (header == "YAZ0") {
return CompressionType::YAZ0;
}
}
return CompressionType::None;
}

std::optional<std::uint32_t> Companion::GetFileOffsetFromSegmentedAddr(const uint8_t segment) const {

auto segments = this->gConfig.segment;

Expand Down
11 changes: 10 additions & 1 deletion src/Companion.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <variant>
#include "factories/BaseFactory.h"
#include "n64/Cartridge.h"
#include "utils/Decompressor.h"

class SWrapper;
namespace fs = std::filesystem;
Expand Down Expand Up @@ -73,11 +74,16 @@ class Companion {
GBIVersion GetGBIVersion() const { return this->gConfig.gbi.version; }
GBIMinorVersion GetGBIMinorVersion() const { return this->gConfig.gbi.subversion; }

std::optional<std::uint32_t> GetSegmentedAddr(uint8_t segment) const;
std::optional<std::uint32_t> GetFileOffsetFromSegmentedAddr(uint8_t segment) const;
std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr);
std::optional<std::shared_ptr<BaseFactory>> GetFactory(const std::string& type);
std::optional<std::string> GetEnumFromValue(const std::string& key, int id);

std::optional<std::uint32_t> GetFileOffset(void) const { return this->gCurrentFileOffset; };
std::optional<std::uint32_t> GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; };
CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; };
CompressionType GetCompressionType(std::vector<uint8_t>& buffer, const uint32_t offset);

static std::string CalculateHash(const std::vector<uint8_t>& data);
static void Pack(const std::string& folder, const std::string& output);
std::string NormalizeAsset(const std::string& name) const;
Expand All @@ -103,6 +109,9 @@ class Companion {
std::unordered_map<std::string, std::map<std::string, std::pair<YAML::Node, bool>>> gAssetDependencies;
std::unordered_map<std::string, std::map<std::string, std::vector<std::pair<uint32_t, std::string>>>> gWriteMap;
std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
uint32_t gCurrentFileOffset;
uint32_t gCurrentSegmentNumber;
CompressionType gCurrentCompressionType;

void ParseCurrentFileConfig(YAML::Node node);
void ParseModdingConfig();
Expand Down
11 changes: 4 additions & 7 deletions src/factories/DisplayListFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void DListHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat
void DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
const auto cmds = std::static_pointer_cast<DListData>(raw)->mGfxs;
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
auto offset = GetSafeNode<uint32_t>(node, "offset");

char out[0xFFFF] = {0};

Expand Down Expand Up @@ -113,6 +113,9 @@ void DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData>
GFXDSetGBIVersion();

if (Companion::Instance->IsDebug()) {
if (IS_SEGMENTED(offset)) {
offset = SEGMENT_OFFSET(offset);
}
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}

Expand Down Expand Up @@ -273,9 +276,6 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
LUS::BinaryReader reader(segment.data, segment.size);
reader.SetEndianness(LUS::Endianness::Big);

// Validate this
// reader.Seek(offset, LUS::SeekOffsetType::Start);

std::vector<uint32_t> gfxs;
auto processing = true;

Expand Down Expand Up @@ -315,7 +315,6 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(ptr, false));
}

Decompressor::CopyCompression(node, dl);
dl["type"] = "GFX";
dl["offset"] = ptr;
dl["symbol"] = output;
Expand Down Expand Up @@ -373,7 +372,6 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
output = Companion::Instance->NormalizeAsset("lights1_" + Torch::to_hex(w1, false));
}

Decompressor::CopyCompression(node, light);
light["type"] = "lights";
light["offset"] = ptr;
light["symbol"] = output;
Expand Down Expand Up @@ -425,7 +423,6 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
output = Companion::Instance->NormalizeAsset("vtx_" + Torch::to_hex(w1, false));
}

Decompressor::CopyCompression(node, vtx);
vtx["type"] = "VTX";
vtx["offset"] = ptr;
vtx["count"] = nvtx;
Expand Down
35 changes: 20 additions & 15 deletions src/factories/ResourceType.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,33 @@ enum class ResourceType {
None = 0x00000000,

// Common
Archive = 0x4F415243, // OARC (UNUSED)
DisplayList = 0x4F444C54, // ODLT
Vertex = 0x4F565458, // OVTX
Matrix = 0x4F4D5458, // OMTX
Array = 0x4F415252, // OARR
Blob = 0x4F424C42, // OBLB
Texture = 0x4F544558, // OTEX
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
Lights = 0x46669697, // LGTS
Archive = 0x4F415243, // OARC (UNUSED)
DisplayList = 0x4F444C54, // ODLT
Vertex = 0x4F565458, // OVTX
Matrix = 0x4F4D5458, // OMTX
Array = 0x4F415252, // OARR
Blob = 0x4F424C42, // OBLB
Texture = 0x4F544558, // OTEX
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
Lights = 0x46669697, // LGTS

// SM64
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
Dictionary = 0x44494354, // DICT
GeoLayout = 0x47454F20, // GEO
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
Dictionary = 0x44494354, // DICT
GeoLayout = 0x47454F20, // GEO

// MK64
Waypoints = 0x46665666, // TrackWaypoints

// SF64
ObjectInit = 0x4F424A49, // OBJI
CourseVertex = 0x43565458, // CVTX
TrackSection = 0x5343544E, // SCTN
Waypoints = 0x57505453, // WPTS
Metadata = 0x4D444154, // MDAT
SpawnData = 0x53444154, // SDAT
};
} // namespace LUS
2 changes: 0 additions & 2 deletions src/factories/TextureFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ std::optional<std::shared_ptr<IParsedData>> TextureFactory::parse(std::vector<ui
}
SPDLOG_INFO("Size: {}", size);
SPDLOG_INFO("Offset: 0x{:X}", offset);
SPDLOG_INFO("Is Compressed: {}", Decompressor::IsCompressed(node) ? "true" : "false");

if(result.size() == 0){
return std::nullopt;
Expand Down Expand Up @@ -360,7 +359,6 @@ std::optional<std::shared_ptr<IParsedData>> TextureFactory::parse_modding(std::v
}
SPDLOG_INFO("Size: {}", size);
SPDLOG_INFO("Offset: 0x{:X}", offset);
SPDLOG_INFO("Is Compressed: {}", Decompressor::IsCompressed(node) ? "true" : "false");

if(result.size() == 0){
return std::nullopt;
Expand Down
9 changes: 7 additions & 2 deletions src/factories/VtxFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "VtxFactory.h"
#include "spdlog/spdlog.h"

#include "Companion.h"
#include "utils/Decompressor.h"
Expand All @@ -20,7 +21,11 @@ void VtxHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData>
void VtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto vtx = std::static_pointer_cast<VtxData>(raw)->mVtxs;
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
auto offset = GetSafeNode<uint32_t>(node, "offset");

if (IS_SEGMENTED(offset)) {
offset = SEGMENT_OFFSET(offset);
}

if (Companion::Instance->IsDebug()) {
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
Expand Down Expand Up @@ -54,7 +59,7 @@ void VtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> r
}

if (Companion::Instance->IsDebug()) {
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (16 * vtx.size())) << "\n";
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (sizeof(VtxRaw) * vtx.size())) << "\n";
}

write << "}; // size = 0x" << std::hex << std::uppercase << (sizeof(VtxRaw) * vtx.size()) << "\n\n";
Expand Down
Loading

0 comments on commit 0d1e136

Please sign in to comment.