Skip to content

Commit

Permalink
SF64:ObjectInit Factory v0
Browse files Browse the repository at this point in the history
  • Loading branch information
KiritoDv committed Mar 5, 2024
1 parent 1712d54 commit 8912f52
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Companion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "factories/BlobFactory.h"
#include "factories/LightsFactory.h"
#include "factories/mk64/WaypointFactory.h"
#include "factories/sf64/ObjInitFactory.h"
#include "factories/DisplayListOverrides.h"
#include "spdlog/spdlog.h"
#include "hj/sha1.h"
Expand Down Expand Up @@ -57,6 +58,9 @@ void Companion::Init(const ExportType type) {
// MK64 specific
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointFactory>());

// SF64 specific
this->RegisterFactory("SF64:OBJ_INIT", std::make_shared<SF64::ObjInitFactory>());

this->Process();
}

Expand Down Expand Up @@ -277,6 +281,20 @@ void Companion::Process() {
auto gbi = cfg["gbi"];
auto modding_path = opath && opath["modding"] ? opath["modding"].as<std::string>() : "modding";

if(cfg["enums"]){
auto enums = cfg["enums"];

for(auto entry = enums.begin(); entry != enums.end(); ++entry){
auto key = entry->first.as<std::string>();
auto values = entry->second;
std::vector<std::string> enumValues;
for(auto value = values.begin(); value != values.end(); ++value){
enumValues.push_back(value->as<std::string>());
}
this->gConfig.enums[key] = enumValues;
}
}

this->gConfig.moddingPath = modding_path;
switch (this->gConfig.exporterType) {
case ExportType::Binary: {
Expand Down Expand Up @@ -677,6 +695,19 @@ std::optional<std::shared_ptr<BaseFactory>> Companion::GetFactory(const std::str
return this->gFactories[type];
}

std::optional<std::string> Companion::GetEnumFromValue(const std::string& key, int id){
if(!this->gConfig.enums.contains(key)){
return std::nullopt;
}

auto enums = this->gConfig.enums[key];
if(id >= enums.size()){
return std::nullopt;
}

return enums[id];
}

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

auto segments = this->gConfig.segment;
Expand Down
2 changes: 2 additions & 0 deletions src/Companion.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct TorchConfig {
bool otrMode;
bool debug;
bool modding;
std::unordered_map<std::string, std::vector<std::string>> enums;
};

class Companion {
Expand Down Expand Up @@ -75,6 +76,7 @@ class Companion {
std::optional<std::uint32_t> GetSegmentedAddr(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);

static std::string CalculateHash(const std::vector<uint8_t>& data);
static void Pack(const std::string& folder, const std::string& output);
Expand Down
3 changes: 3 additions & 0 deletions src/factories/ResourceType.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ enum class ResourceType {

// MK64
Waypoints = 0x46665666, // TrackWaypoints

// SF64
ObjectInit = 0x4F424A49, // OBJI
};
} // namespace LUS
74 changes: 74 additions & 0 deletions src/factories/sf64/ObjInitFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "ObjInitFactory.h"
#include "utils/Decompressor.h"
#include "Companion.h"
#include <iomanip>

void SF64::ObjInitCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto symbol = GetSafeNode(node, "symbol", entryName);
auto objs = std::static_pointer_cast<ObjInitData>(raw)->mObjInit;

write << "ObjectInit " << symbol << "[] = {\n";
for(auto& obj : objs) {
auto enumName = Companion::Instance->GetEnumFromValue("obj_id", obj.id).value_or(std::to_string(obj.id));
write << fourSpaceTab << "{ " << obj.zPos1 << ", ";
write << obj.zPos2 << ", ";
write << obj.xPos << ", ";
write << obj.yPos << ", ";
write << "{ " << std::hex << obj.rot.x << ", " << std::hex << obj.rot.y << ", " << std::hex << obj.rot.z << " }, ";
write << enumName << " },\n";
}
write << "};\n\n";
}

void SF64::ObjInitBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto writer = LUS::BinaryWriter();
auto data = std::static_pointer_cast<ObjInitData>(raw)->mObjInit;

WriteHeader(writer, LUS::ResourceType::ObjectInit, 0);
writer.Write((uint32_t) data.size());
for(auto& obj : data) {
writer.Write(obj.zPos1);
writer.Write(obj.zPos2);
writer.Write(obj.xPos);
writer.Write(obj.yPos);
writer.Write(obj.rot.x);
writer.Write(obj.rot.y);
writer.Write(obj.rot.z);
writer.Write(obj.id);
}
writer.Finish(write);
}

std::optional<std::shared_ptr<IParsedData>> SF64::ObjInitFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
auto count = GetSafeNode<size_t>(node, "count");

LUS::BinaryReader reader(segment.data, sizeof(ObjectInit) * count);
reader.SetEndianness(LUS::Endianness::Big);
std::vector<ObjectInit> objects;

for (int i = 0; i < count; i++) {

float zPos1 = reader.ReadFloat();
int16_t zPos2 = reader.ReadInt16();
int16_t xPos = reader.ReadInt16();
int16_t yPos = reader.ReadInt16();
int16_t rotX = reader.ReadInt16();
int16_t rotY = reader.ReadInt16();
int16_t rotZ = reader.ReadInt16();
int16_t id = reader.ReadInt16();
reader.ReadInt16(); // padding

ObjectInit objInit{
zPos1, zPos2,
xPos, yPos,
{ rotX, rotY, rotZ },
id
};

objects.push_back(objInit);
}


return std::make_shared<ObjInitData>(objects);
}
51 changes: 51 additions & 0 deletions src/factories/sf64/ObjInitFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include "../BaseFactory.h"
#include "../../types/RawBuffer.h"

namespace SF64 {
struct Vec3s {
/* 0x0 */ int16_t x;
/* 0x2 */ int16_t y;
/* 0x4 */ int16_t z;
}; // size = 0x6;

struct ObjectInit {
/* 0x00 */ float zPos1;
/* 0x04 */ uint16_t zPos2;
/* 0x06 */ uint16_t xPos;
/* 0x08 */ int16_t yPos;
/* 0x0A */ Vec3s rot;
/* 0x10 */ int16_t id;
};

class ObjInitData : public IParsedData {
public:
std::vector<ObjectInit> mObjInit;

explicit ObjInitData(std::vector<ObjectInit> objInit) : mObjInit(objInit) {}
};

class ObjInitBinaryExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class ObjInitCodeExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};

class ObjInitFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override {
return std::nullopt;
}
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(Binary, ObjInitBinaryExporter)
REGISTER(Code, ObjInitCodeExporter)
};
}
bool SupportModdedAssets() override { return false; }
};
}

0 comments on commit 8912f52

Please sign in to comment.