Added WIP Geo Layout Exporter and some code cleanups

This commit is contained in:
KiritoDv
2024-01-31 12:05:40 -06:00
committed by Lywx
parent 06134be57a
commit 57f61f8e65
16 changed files with 1400 additions and 1070 deletions
+20 -7
View File
@@ -6,6 +6,7 @@
#include "factories/sm64/DialogFactory.h"
#include "factories/sm64/DictionaryFactory.h"
#include "factories/sm64/TextFactory.h"
#include "factories/sm64/GeoLayoutFactory.h"
#include "factories/BankFactory.h"
#include "factories/AudioHeaderFactory.h"
#include "factories/SampleFactory.h"
@@ -49,7 +50,7 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("SM64:TEXT", std::make_shared<SM64::TextFactory>());
this->RegisterFactory("SM64:DICTIONARY", std::make_shared<SM64::DictionaryFactory>());
this->RegisterFactory("SM64:ANIM", std::make_shared<SM64::AnimationFactory>());
// this->RegisterFactory("GEO_LAYOUT", new SGeoFactory());
this->RegisterFactory("SM64:GEO_LAYOUT", std::make_shared<SM64::GeoLayoutFactory>());
// MK64 specific
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointFactory>());
@@ -61,10 +62,15 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar
std::ostringstream stream;
auto type = node["type"].as<std::string>();
auto offset = node["offset"].as<uint32_t>();
std::transform(type.begin(), type.end(), type.begin(), ::toupper);
SPDLOG_INFO("[{}] Processing {} at 0x{:X}", type, name, offset);
if(node["offset"]) {
auto offset = node["offset"].as<uint32_t>();
SPDLOG_INFO("[{}] Processing {} at 0x{:X}", type, name, offset);
} else {
SPDLOG_INFO("[{}] Processing {}", type, name);
}
auto factory = this->GetFactory(type);
if(!factory.has_value()){
SPDLOG_ERROR("No factory found for {}", name);
@@ -108,7 +114,9 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar
}
SPDLOG_INFO("Processed {}", name);
this->gWriteMap[this->gCurrentFile][type].emplace_back(node["offset"].as<uint32_t>(), stream.str());
if(node["offset"]) {
this->gWriteMap[this->gCurrentFile][type].emplace_back(node["offset"].as<uint32_t>(), stream.str());
}
}
void Companion::Process() {
@@ -403,13 +411,18 @@ void Companion::Pack(const std::string& folder, const std::string& output) {
wrapper.Close();
}
void Companion::RegisterAsset(const std::string& name, YAML::Node& node) {
if(!node["offset"]) return;
std::optional<std::tuple<std::string, YAML::Node>> Companion::RegisterAsset(const std::string& name, YAML::Node& node) {
if(!node["offset"]) return std::nullopt;
this->gAssetDependencies[this->gCurrentFile][name] = std::make_pair(node, false);
auto output = (this->gCurrentDirectory / name).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = std::make_tuple(output, node);
auto entry = std::make_tuple(output, node);
this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = entry;
return entry;
}
void Companion::RegisterFactory(const std::string& type, const std::shared_ptr<BaseFactory>& factory) {
+1 -1
View File
@@ -45,7 +45,7 @@ public:
static void Pack(const std::string& folder, const std::string& output);
std::string NormalizeAsset(const std::string& name) const;
void RegisterAsset(const std::string& name, YAML::Node& node);
std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(const std::string& name, YAML::Node& node);
private:
bool gOTRMode = false;
bool gIsDebug = false;
+6 -19
View File
@@ -5,23 +5,10 @@
#include "Companion.h"
#include <gfxd.h>
#include <fstream>
#include <utils/TorchUtils.h>
#define C0(pos, width) ((w0 >> (pos)) & ((1U << width) - 1))
template< typename T >
std::string to_hex(T number, const bool append0x = true) {
std::stringstream stream;
if(append0x) {
stream << "0x";
}
stream << std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << number;
auto format = stream.str();
std::transform(format.begin(), format.end(), format.begin(), ::toupper);
return format;
}
void GFXDSetGBIVersion(){
switch (Companion::Instance->GetGBIVersion()) {
case GBIVersion::f3d:
@@ -270,7 +257,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if(!dec.has_value()){
SPDLOG_INFO("Addr to Display list command at 0x{:X} not in yaml, autogenerating it", w1);
SPDLOG_INFO("Addr to Display list command at 0x{:X} not in yaml, autogenerating it", w1);
auto addr = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1));
if(!addr.has_value()) {
SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1));
@@ -279,7 +266,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
auto rom = Companion::Instance->GetRomData();
auto factory = Companion::Instance->GetFactory("GFX")->get();
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_dl_" + to_hex(w1, false));
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_dl_" + Torch::to_hex(w1, false));
YAML::Node dl;
dl["type"] = "GFX";
dl["mio0"] = addr.value();
@@ -307,7 +294,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
}
if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); !decl.has_value()){
SPDLOG_INFO("Addr to Lights1 command at 0x{:X} not in yaml, autogenerating it", w1);
SPDLOG_INFO("Addr to Lights1 command at 0x{:X} not in yaml, autogenerating it", w1);
auto addr = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1));
if(!addr.has_value()) {
SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1));
@@ -315,7 +302,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
}
auto rom = Companion::Instance->GetRomData();
auto factory = Companion::Instance->GetFactory("LIGHTS")->get();
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_lights1_" + to_hex(w1, false));
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_lights1_" + Torch::to_hex(w1, false));
YAML::Node light;
light["type"] = "lights";
light["mio0"] = addr.value();
@@ -356,7 +343,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
auto rom = Companion::Instance->GetRomData();
auto factory = Companion::Instance->GetFactory("VTX")->get();
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + to_hex(w1, false));
std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + Torch::to_hex(w1, false));
YAML::Node vtx;
vtx["type"] = "VTX";
vtx["mio0"] = addr.value();
+1 -1
View File
@@ -23,7 +23,7 @@ enum class ResourceType {
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
Dictionary = 0x44494354, // DICT
Geo = 0x47454F20, // GEO
GeoLayout = 0x47454F20, // GEO
// MK64
Waypoints = 0x46665666, // TrackWaypoints
-436
View File
@@ -1,436 +0,0 @@
#pragma once
#include "n64/CommandMacros.h"
typedef float Vec2f[2];
typedef float Vec3f[3]; // X, Y, Z, where Y is up
typedef int16_t Vec3s[3];
typedef int32_t Vec3i[3];
typedef float Vec4f[4];
typedef int16_t Vec4s[4];
#define cur_geo_cmd_u8(offset) \
(cmd[CMD_PROCESS_OFFSET(offset)])
#define cur_geo_cmd_s16(offset) \
BSWAP16((*(int16_t *) &cmd[CMD_PROCESS_OFFSET(offset)]))
#define cur_geo_cmd_i32(offset) \
(*(int32_t *) &cmd[CMD_PROCESS_OFFSET(offset)])
#define cur_geo_cmd_u32(offset) \
BSWAP32((*(uint32_t *) &cmd[CMD_PROCESS_OFFSET(offset)]))
#define CMD_NOP(c) GeoCommand::c: writer->Write((uint32_t) GeoCommand::c); cmd += 0x04 << CMD_SIZE_SHIFT; print_cmd(c, #c); break;
//#define CMD_NOP(c) GeoCommand::c: cmd += 0x04 << CMD_SIZE_SHIFT; print_cmd(c, #c); break;
#define CMD_INFO(c) GeoCommand::c: print_cmd(c, #c);
#define next_s16_in_geo_script(src) ((uint32_t)(*(*src)++))
#define cur_geo_cmd_s32(offset) \
(*(s32 *) &cmd[CMD_PROCESS_OFFSET(offset)])
/**
* 0x00: Branch and store return address
* 0x04: scriptTarget, segment address of geo layout
*/
#define GEO_BRANCH_AND_LINK(scriptTarget) \
CMD_BBH(0x00, 0x00, 0x0000), \
CMD_PTR(scriptTarget)
/**
* 0x01: Terminate geo layout
* 0x01-0x03: unused
*/
#define GEO_END() \
CMD_BBH(0x01, 0x00, 0x0000)
/**
* 0x02: Branch
* 0x01: if 1, store next geo layout address on stack
* 0x02-0x03: unused
* 0x04: scriptTarget, segment address of geo layout
*/
#define GEO_BRANCH(type, scriptTarget) \
CMD_BBH(0x02, type, 0x0000), \
CMD_PTR(scriptTarget)
/**
* 0x03: Return from branch
* 0x01-0x03: unused
*/
#define GEO_RETURN() \
CMD_BBH(0x03, 0x00, 0x0000)
/**
* 0x04: Open node
* 0x01-0x03: unused
*/
#define GEO_OPEN_NODE() \
CMD_BBH(0x04, 0x00, 0x0000)
/**
* 0x05: Close node
* 0x01-0x03: unused
*/
#define GEO_CLOSE_NODE() \
CMD_BBH(0x05, 0x00, 0x0000)
/**
* 0x06: Register the current node at the given index in the gGeoViews array
* 0x01: unused
* 0x02: s16 index
*/
#define GEO_ASSIGN_AS_VIEW(index) \
CMD_BBH(0x06, 0x00, index)
/**
* 0x07: Update current scene graph node flags
* 0x01: u8 operation (0 = reset, 1 = set, 2 = clear)
* 0x02: s16 bits
*/
#define GEO_UPDATE_NODE_FLAGS(operation, flagBits) \
CMD_BBH(0x07, operation, flagBits)
/**
* 0x08: Create screen area scene graph node
* 0x01: unused
* 0x02: s16 num entries (+2) to allocate
* 0x04: s16 x
* 0x06: s16 y
* 0x08: s16 width
* 0x0A: s16 height
*/
#define GEO_NODE_SCREEN_AREA(numEntries, x, y, width, height) \
CMD_BBH(0x08, 0x00, numEntries), \
CMD_HH(x, y), \
CMD_HH(width, height)
/**
* 0x09: Create orthographic projection scene graph node
* 0x02: s16 scale as percentage
*/
#define GEO_NODE_ORTHO(scale) \
CMD_BBH(0x09, 0x00, scale)
/**
* 0x0A: Create camera frustum scene graph node
* 0x01: u8 if nonzero, enable function field
* 0x02: s16 field of view
* 0x04: s16 near
* 0x06: s16 far
* 0x08: [GraphNodeFunc function]
*/
#define GEO_CAMERA_FRUSTUM(fov, near, far) \
CMD_BBH(0x0A, 0x00, fov), \
CMD_HH(near, far)
#define GEO_CAMERA_FRUSTUM_WITH_FUNC(fov, near, far, func) \
CMD_BBH(0x0A, 0x01, fov), \
CMD_HH(near, far), \
CMD_PTR(func)
/**
* 0x0B: Create a root scene graph node
* 0x01-0x03: unused
*/
#define GEO_NODE_START() \
CMD_BBH(0x0B, 0x00, 0x0000)
/**
* 0x0C: Create zbuffer-toggling scene graph node
* 0x01: u8 enableZBuffer (1 = on, 0 = off)
* 0x02-0x03: unused
*/
#define GEO_ZBUFFER(enable) \
CMD_BBH(0x0C, enable, 0x0000)
/**
* 0x0D: Create render range scene graph node
* 0x01-0x03: unused
* 0x04: s16 minDistance
* 0x06: s16 maxDistance
*/
#define GEO_RENDER_RANGE(minDistance, maxDistance) \
CMD_BBH(0x0D, 0x00, 0x0000), \
CMD_HH(minDistance, maxDistance)
/**
* 0x0E: Create switch-case scene graph node
* 0x01: unused
* 0x02: s16 numCases
* 0x04: GraphNodeFunc caseSelectorFunc
*/
#define GEO_SWITCH_CASE(count, function) \
CMD_BBH(0x0E, 0x00, count), \
CMD_PTR(function)
/**
* 0x0F: Create a camera scene graph node.
* 0x01: unused
* 0x02: s16 camera type
* 0x04: s16 posX
* 0x06: s16 posY
* 0x08: s16 posZ
* 0x0A: s16 focusX
* 0x0C: s16 focusY
* 0x0E: s16 focusZ
* 0x10: GraphNodeFunc function
*/
#define GEO_CAMERA(type, x1, y1, z1, x2, y2, z2, function) \
CMD_BBH(0x0F, 0x00, type), \
CMD_HHHHHH(x1, y1, z1, x2, y2, z2), \
CMD_PTR(function)
/**
* 0x10: Create translation & rotation scene graph node with optional display list
* Four different versions of 0x10
* cmd+0x01: u8 params
* 0b1000_0000: if set, enable displayList field and drawingLayer
* 0b0111_0000: fieldLayout (determines how rest of data is formatted
* 0b0000_1111: drawingLayer
*
* fieldLayout = 0: Translate & Rotate
* 0x04: s16 xTranslation
* 0x06: s16 yTranslation
* 0x08: s16 zTranslation
* 0x0A: s16 xRotation
* 0x0C: s16 yRotation
* 0x0E: s16 zRotation
* 0x10: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_TRANSLATE_ROTATE(layer, tx, ty, tz, rx, ry, rz) \
CMD_BBH(0x10, (0x00 | layer), 0x0000), \
CMD_HHHHHH(tx, ty, tz, rx, ry, rz)
#define GEO_TRANSLATE_ROTATE_WITH_DL(layer, tx, ty, tz, rx, ry, rz, displayList) \
CMD_BBH(0x10, (0x00 | layer | 0x80), 0x0000), \
CMD_HHHHHH(tx, ty, tz, rx, ry, rz), \
CMD_PTR(displayList)
/**
* fieldLayout = 1: Translate
* 0x02: s16 xTranslation
* 0x04: s16 yTranslation
* 0x06: s16 zTranslation
* 0x08: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_TRANSLATE(layer, tx, ty, tz) \
CMD_BBH(0x10, (0x10 | layer), tx), \
CMD_HH(ty, tz)
#define GEO_TRANSLATE_WITH_DL(layer, tx, ty, tz, displayList) \
CMD_BBH(0x10, (0x10 | layer | 0x80), tx), \
CMD_HH(ty, tz), \
CMD_PTR(displayList)
/**
* fieldLayout = 2: Rotate
* 0x02: s16 xRotation
* 0x04: s16 yRotation
* 0x06: s16 zRotation
* 0x08: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_ROTATE(layer, rx, ry, rz) \
CMD_BBH(0x10, (0x20 | layer), rx), \
CMD_HH(ry, rz)
#define GEO_ROTATE_WITH_DL(layer, rx, ry, rz, displayList) \
CMD_BBH(0x10, (0x20 | layer | 0x80), rx), \
CMD_HH(ry, rz), \
CMD_PTR(displayList)
/**
* fieldLayout = 3: Rotate Y
* 0x02: s16 yRotation
* 0x04: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_ROTATE_Y(layer, ry) \
CMD_BBH(0x10, (0x30 | layer), ry)
#define GEO_ROTATE_Y_WITH_DL(layer, ry, displayList) \
CMD_BBH(0x10, (0x30 | layer | 0x80), ry), \
CMD_PTR(displayList)
/**
* 0x11: Create translation scene graph node with optional display list
* 0x01: u8 params
* 0b1000_0000: if set, enable displayList field and drawingLayer
* 0b0000_1111: drawingLayer
* 0x02: s16 translationX
* 0x04: s16 translationY
* 0x06: s16 translationZ
* 0x08: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_TRANSLATE_NODE(layer, ux, uy, uz) \
CMD_BBH(0x11, layer, ux), \
CMD_HH(uy, uz)
#define GEO_TRANSLATE_NODE_WITH_DL(layer, ux, uy, uz, displayList) \
CMD_BBH(0x11, (layer | 0x80), ux), \
CMD_HH(uy, uz), \
CMD_PTR(displayList)
/**
* 0x12: Create rotation scene graph node with optional display list
* 0x01: u8 params
* 0b1000_0000: if set, enable displayList field and drawingLayer
* 0b0000_1111: drawingLayer
* 0x02: s16 rotationX
* 0x04: s16 rotationY
* 0x06: s16 rotationZ
* 0x08: [u32 displayList: if MSbit of params set, display list segmented address]
*/
#define GEO_ROTATION_NODE(layer, ux, uy, uz) \
CMD_BBH(0x12, layer, ux), \
CMD_HH(uy, uz)
#define GEO_ROTATION_NODE_WITH_DL(layer, ux, uy, uz, displayList) \
CMD_BBH(0x12, (layer | 0x80), ux), \
CMD_HH(uy, uz), \
CMD_PTR(displayList)
/**
* 0x13: Create a scene graph node that is rotated by the object's animation.
* 0x01: u8 drawingLayer
* 0x02: s16 xTranslation
* 0x04: s16 yTranslation
* 0x06: s16 zTranslation
* 0x08: u32 displayList: dislay list segmented address
*/
#define GEO_ANIMATED_PART(layer, x, y, z, displayList) \
CMD_BBH(0x13, layer, x), \
CMD_HH(y, z), \
CMD_PTR(displayList)
/**
* 0x14: Create billboarding node with optional display list
* 0x01: u8 params
* 0b1000_0000: if set, enable displayList field and drawingLayer
* 0b0000_1111: drawingLayer
* 0x02: s16 xTranslation
* 0x04: s16 yTranslation
* 0x06: s16 zTranslation
* 0x08: [u32 displayList: if MSbit of params is set, display list segmented address]
*/
#define GEO_BILLBOARD_WITH_PARAMS(layer, tx, ty, tz) \
CMD_BBH(0x14, layer, tx), \
CMD_HH(ty, tz)
#define GEO_BILLBOARD_WITH_PARAMS_AND_DL(layer, tx, ty, tz, displayList) \
CMD_BBH(0x14, (layer | 0x80), tx), \
CMD_HH(ty, tz), \
CMD_PTR(displayList)
#define GEO_BILLBOARD() \
GEO_BILLBOARD_WITH_PARAMS(0, 0, 0, 0)
/**
* 0x15: Create plain display list scene graph node
* 0x01: u8 drawingLayer
* 0x02-0x03: unused
* 0x04: u32 displayList: display list segmented address
*/
#define GEO_DISPLAY_LIST(layer, displayList) \
CMD_BBH(0x15, layer, 0x0000), \
CMD_PTR(displayList)
/**
* 0x16: Create shadow scene graph node
* 0x01: unused
* 0x02: s16 shadowType (cast to u8)
* 0x04: s16 shadowSolidity (cast to u8)
* 0x06: s16 shadowScale
*/
#define GEO_SHADOW(type, solidity, scale) \
CMD_BBH(0x16, 0x00, type), \
CMD_HH(solidity, scale)
/**
* 0x17: Create render object scene graph node
* 0x01-0x03: unused
*/
#define GEO_RENDER_OBJ() \
CMD_BBH(0x17, 0x00, 0x0000)
/**
* 0x18: Create dynamically generated displaylist scene graph node
* 0x01: unused
* 0x02: s16 parameter
* 0x04: GraphNodeFunc function
*/
#define GEO_ASM(param, function) \
CMD_BBH(0x18, 0x00, param), \
CMD_PTR(function)
/**
* 0x19: Create background scene graph node
* 0x02: s16 background: background ID, or RGBA5551 color if backgroundFunc is null
* 0x04: GraphNodeFunc backgroundFunc
*/
#define GEO_BACKGROUND(background, function) \
CMD_BBH(0x19, 0x00, background), \
CMD_PTR(function)
#define GEO_BACKGROUND_COLOR(background) \
GEO_BACKGROUND(background, NULL)
/**
* 0x1A: No operation
*/
#define GEO_NOP_1A() \
CMD_BBH(0x1A, 0x00, 0x0000), \
CMD_HH(0x0000, 0x0000)
/**
* 0x1B: Copy the shared children from an object parent node from a specific view
* to a newly created object parent.
* 0x02: s16 index of array
*/
#define GEO_COPY_VIEW(index) \
CMD_BBH(0x1B, 0x00, index)
/**
* 0x1C: Create a held object scene graph node
* cmd+0x01: u8 unused
* cmd+0x02: s16 offsetX
* cmd+0x04: s16 offsetY
* cmd+0x06: s16 offsetZ
* cmd+0x08: GraphNodeFunc nodeFunc
*/
#define GEO_HELD_OBJECT(param, ux, uy, uz, nodeFunc) \
CMD_BBH(0x1C, param, ux), \
CMD_HH(uy, uz), \
CMD_PTR(nodeFunc)
/**
* 0x1D: Create scale scene graph node with optional display list
* 0x01: u8 params
* 0b1000_0000: if set, enable displayList field and drawingLayer
* 0b0000_1111: drawingLayer
* 0x02-0x03: unused
* 0x04: u32 scale (0x10000 = 1.0)
* 0x08: [u32 displayList: if MSbit of params is set, display list segment address]
*/
#define GEO_SCALE(layer, scale) \
CMD_BBH(0x1D, layer, 0x0000), \
CMD_W(scale)
#define GEO_SCALE_WITH_DL(layer, scale, displayList) \
CMD_BBH(0x1D, (layer | 0x80), 0x0000), \
CMD_W(scale), \
CMD_PTR(displayList)
/**
* 0x1E: No operation
*/
#define GEO_NOP_1E() \
CMD_BBH(0x1E, 0x00, 0x0000), \
CMD_HH(0x0000, 0x0000)
/**
* 0x1F: No operation
*/
#define GEO_NOP_1F() \
CMD_BBH(0x1F, 0x00, 0x0000), \
CMD_HH(0x0000, 0x0000), \
CMD_HH(0x0000, 0x0000), \
CMD_HH(0x0000, 0x0000)
/**
* 0x20: Create a scene graph node that specifies for an object the radius that
* is used for frustum culling.
* 0x01: unused
* 0x02: s16 cullingRadius
*/
#define GEO_CULLING_RADIUS(cullingRadius) \
CMD_BBH(0x20, 0x00, cullingRadius)
File diff suppressed because it is too large Load Diff
-9
View File
@@ -1,9 +0,0 @@
#pragma once
#include "../RawFactory.h"
class SGeoFactory : public RawFactory {
public:
SGeoFactory() = default;
bool process(LUS::BinaryWriter* write, YAML::Node& data, std::vector<uint8_t>& buffer) override;
};
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include "../BaseFactory.h"
#include "geo/GeoCommand.h"
namespace SM64 {
typedef std::variant<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, Vec2f, Vec3f, Vec3s, Vec3i, Vec4f, Vec4s> GeoArgument;
struct GeoCommand {
GeoOpcode opcode;
std::vector<GeoArgument> arguments;
};
class GeoLayout : public IParsedData {
public:
std::vector<GeoCommand> commands;
explicit GeoLayout(std::vector<GeoCommand> commands) : commands(std::move(commands)) {}
};
class GeoHeaderExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class GeoBinaryExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class GeoLayoutFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(Header, GeoHeaderExporter)
REGISTER(Binary, GeoBinaryExporter)
};
}
};
}
+485
View File
@@ -0,0 +1,485 @@
int current_tab_size = 0;
static inline void print_cmd(GeoCommand cmd, std::string c){
if(cmd == GeoCommand::CLOSE_NODE){
current_tab_size--;
}
for(int i = 0; i < current_tab_size; i++){
std::cout << "\t";
}
if(cmd == GeoCommand::OPEN_NODE){
current_tab_size++;
}
std::cout << "GEO_" << c << "()" << std::endl;
}
typedef uint32_t GeoLayout;
auto offset = data["offset"].as<size_t>();
auto cmd = (uint8_t*) buffer.data() + offset;
auto processing = true;
std::vector<GeoLayout> layout;
auto geo_writer = new LUS::BinaryWriter();
// #define GeoWrite(x) layout.insert(layout.end(), {x})
//
// while(processing){
// auto opcode = cmd[0x00];
// switch (opcode) {
// case CMD_INFO(BRANCH_AND_LINK) {
// geo_writer->Write((uint8_t) BRANCH_AND_LINK_OTR);
// uint32_t ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04)));
// auto decl = Companion::Instance->GetNodeByAddr(ptr);
//
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found geo: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find geo at 0x{:X}", ptr);
// geo_writer->Write((uint64_t) 0);
// }
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(BRANCH) {
// geo_writer->Write((uint8_t) BRANCH_OTR);
// geo_writer->Write(cur_geo_cmd_u8(0x01));
//
// int32_t ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04)));
// auto decl = Companion::Instance->GetNodeByAddr(ptr);
//
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found geo: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find geo at 0x{:X}", ptr);
// geo_writer->Write((uint64_t) 0);
// }
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(END)
// geo_writer->Write((uint8_t) END);
// processing = false;
// break;
// case CMD_INFO(RETURN)
// geo_writer->Write((uint8_t) RETURN);
// processing = false;
// break;
// case CMD_NOP(OPEN_NODE)
// case CMD_NOP(CLOSE_NODE)
// case CMD_INFO(ASSIGN_AS_VIEW) {
// geo_writer->Write(ASSIGN_AS_VIEW);
// geo_writer->Write(cur_geo_cmd_s16(0x02));
// break;
// }
// case CMD_INFO(UPDATE_NODE_FLAGS) {
// geo_writer->Write((uint8_t) UPDATE_NODE_FLAGS);
// geo_writer->Write(cur_geo_cmd_u8(0x01));
// geo_writer->Write(cur_geo_cmd_s16(0x02));
// break;
// }
// case CMD_INFO(NODE_ROOT) {
// auto a1 = cur_geo_cmd_s16(0x02);
// auto a2 = cur_geo_cmd_s16(0x04);
// auto a3 = cur_geo_cmd_s16(0x06);
// auto a4 = cur_geo_cmd_s16(0x08);
// auto a5 = cur_geo_cmd_s16(0x0A);
// GeoWrite(GEO_NODE_SCREEN_AREA(a1, a2, a3, a4, a5));
// cmd += 0x0C << CMD_SIZE_SHIFT;
// processing = false;
// }
// case CMD_INFO(NODE_ORTHO_PROJECTION) {
// geo_writer->Write((uint8_t) NODE_ORTHO_PROJECTION);
// geo_writer->Write(cur_geo_cmd_s16(0x02));
// cmd += 0x04 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_PERSPECTIVE) {
// geo_writer->Write((uint8_t) NODE_PERSPECTIVE);
// auto param = cur_geo_cmd_u8(0x01);
// auto fov = cur_geo_cmd_s16(0x02);
// auto near = cur_geo_cmd_s16(0x04);
// auto far = cur_geo_cmd_s16(0x06);
//
// geo_writer->Write(param);
// geo_writer->Write(fov);
// geo_writer->Write(near);
// geo_writer->Write(far);
//
// if (param != 0) {
// auto func = cur_geo_cmd_u32(0x08);
// geo_writer->Write(func);
// cmd += 4 << CMD_SIZE_SHIFT;
// }
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_NOP(NODE_START)
// case CMD_INFO(NODE_MASTER_LIST) {
// geo_writer->Write((uint8_t) NODE_MASTER_LIST);
// geo_writer->Write(cur_geo_cmd_u8(0x01));
// cmd += 0x04 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_LEVEL_OF_DETAIL) {
// geo_writer->Write((uint8_t) NODE_LEVEL_OF_DETAIL);
// int16_t minDistance = cur_geo_cmd_s16(0x04);
// int16_t maxDistance = cur_geo_cmd_s16(0x06);
//
// geo_writer->Write(minDistance);
// geo_writer->Write(maxDistance);
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_SWITCH_CASE) {
// geo_writer->Write((uint8_t) NODE_SWITCH_CASE_OTR);
// auto cs = cur_geo_cmd_s16(0x02);
// auto ptr = cur_geo_cmd_u32(0x04);
//
// geo_writer->Write(cs);
// geo_writer->Write(ptr);
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_CAMERA) {
// geo_writer->Write((uint8_t) NODE_CAMERA_OTR);
// auto cmd_pos = (int16_t *) &cmd[4];
// auto mode = cur_geo_cmd_s16(0x02);
//
// geo_writer->Write(mode);
//
// Vec3f pos, focus;
//
// cmd_pos = read_vec3s_to_vec3f(pos, cmd_pos);
// read_vec3s_to_vec3f(focus, cmd_pos);
//
// geo_writer->Write(pos[0]);
// geo_writer->Write(pos[1]);
// geo_writer->Write(pos[2]);
// geo_writer->Write(focus[0]);
// geo_writer->Write(focus[1]);
// geo_writer->Write(focus[2]);
//
// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x10)));
// geo_writer->Write(ptr);
//
// cmd += 0x14 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_TRANSLATION_ROTATION) {
// geo_writer->Write(NODE_TRANSLATION_ROTATION_OTR);
// auto params = cur_geo_cmd_u8(0x01);
// auto cmd_pos = (int16_t*) cmd;
//
// Vec3s translation, rotation;
//
// geo_writer->Write(params);
//
// switch ((params & 0x70) >> 4) {
// case 0:
// cmd_pos = read_vec3s(translation, &cmd_pos[2]);
// geo_writer->Write(translation[0]);
// geo_writer->Write(translation[1]);
// geo_writer->Write(translation[2]);
// cmd_pos = read_vec3s_angle(rotation, cmd_pos);
// geo_writer->Write(rotation[0]);
// geo_writer->Write(rotation[1]);
// geo_writer->Write(rotation[2]);
// break;
// case 1:
// cmd_pos = read_vec3s(translation, &cmd_pos[1]);
// geo_writer->Write(translation[0]);
// geo_writer->Write(translation[1]);
// geo_writer->Write(translation[2]);
// break;
// case 2:
// cmd_pos = read_vec3s_angle(rotation, &cmd_pos[1]);
// geo_writer->Write(rotation[0]);
// geo_writer->Write(rotation[1]);
// geo_writer->Write(rotation[2]);
// break;
// case 3:
// cmd_pos += 2 << CMD_SIZE_SHIFT;
// break;
// }
//
// if (params & 0x80) {
// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0]));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
// cmd_pos += 2 << CMD_SIZE_SHIFT;
// }
//
// cmd = (uint8_t*) cmd_pos;
// break;
// }
// case CMD_INFO(NODE_TRANSLATION) {
// geo_writer->Write(NODE_TRANSLATION_OTR);
// auto params = cur_geo_cmd_u8(0x01);
// auto cmd_pos = (int16_t*) cmd;
//
// Vec3s translation;
// cmd_pos = read_vec3s(translation, &cmd_pos[1]);
//
// geo_writer->Write(translation[0]);
// geo_writer->Write(translation[1]);
// geo_writer->Write(translation[2]);
//
// if (params & 0x80) {
// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0]));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
// cmd_pos += 2 << CMD_SIZE_SHIFT;
// }
//
// cmd = (uint8_t*) cmd_pos;
// break;
// }
// case CMD_INFO(NODE_ROTATION) {
// geo_writer->Write(NODE_ROTATION_OTR);
// auto params = cur_geo_cmd_u8(0x01);
// auto cmd_pos = (int16_t*) cmd;
//
// Vec3s sp2c;
// cmd_pos = read_vec3s(sp2c, &cmd_pos[1]);
//
// geo_writer->Write(sp2c[0]);
// geo_writer->Write(sp2c[1]);
// geo_writer->Write(sp2c[2]);
//
// if (params & 0x80) {
// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0]));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
// cmd_pos += 2 << CMD_SIZE_SHIFT;
// }
//
// cmd = (uint8_t*) cmd_pos;
// break;
// }
// case CMD_INFO(NODE_ANIMATED_PART) {
// geo_writer->Write(NODE_ANIMATED_PART_OTR);
//
// auto layer = cur_geo_cmd_u8(0x01);
// auto ptr = cur_geo_cmd_u32(0x08);
//
// geo_writer->Write(layer);
// geo_writer->Write(ptr);
//
// auto dlist = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08)));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
//
// cmd += 0x0C << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_BILLBOARD) {
// geo_writer->Write(NODE_BILLBOARD_OTR);
//
// Vec3s translation;
// auto params = cur_geo_cmd_u8(0x01);
// auto cmd_pos = (int16_t*) cmd;
//
// cmd_pos = read_vec3s(translation, &cmd_pos[1]);
// geo_writer->Write(params);
// if (params & 0x80) {
// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0]));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if (decl.has_value()) {
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash,
// std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
//
// cmd_pos += 2 << CMD_SIZE_SHIFT;
// }
//
// cmd = (uint8_t*) cmd_pos;
// break;
// }
// case CMD_INFO(NODE_DISPLAY_LIST) {
// geo_writer->Write((uint8_t) NODE_DISPLAY_LIST_OTR);
//
// int32_t layer = cur_geo_cmd_u8(0x01);
// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04)));
//
// geo_writer->Write(layer);
//
// auto decl = Companion::Instance->GetNodeByAddr(ptr);
//
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", ptr);
// geo_writer->Write((uint64_t) 0);
// }
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_SHADOW) {
// geo_writer->Write((uint8_t) NODE_SHADOW);
// auto type = cur_geo_cmd_s16(0x02);
// auto solidity = cur_geo_cmd_s16(0x04);
// auto scale = cur_geo_cmd_s16(0x06);
//
// geo_writer->Write(type);
// geo_writer->Write(solidity);
// geo_writer->Write(scale);
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_NOP(NODE_OBJECT_PARENT)
// case CMD_INFO(NODE_ASM) {
// geo_writer->Write(NODE_ASM_OTR);
// auto param = cur_geo_cmd_s16(0x02);
// auto ptr = cur_geo_cmd_u32(0x04);
//
// geo_writer->Write(param);
// geo_writer->Write(SEGMENT_OFFSET(BSWAP32(ptr)));
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_BACKGROUND) {
// geo_writer->Write((uint8_t) NODE_BACKGROUND_OTR);
// auto bg = cur_geo_cmd_s16(0x02);
// geo_writer->Write(bg);
//
// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04)));
// geo_writer->Write(ptr);
//
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NOP) {
// geo_writer->Write((uint8_t) NOP);
// geo_writer->Write((uint32_t) 0);
// geo_writer->Write((uint32_t) 0);
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(COPY_VIEW) {
// geo_writer->Write((uint32_t) COPY_VIEW);
// auto idx = cur_geo_cmd_s16(0x02);
// geo_writer->Write(idx);
// break;
// }
// case CMD_INFO(NODE_HELD_OBJ) {
// geo_writer->Write((uint8_t) NODE_HELD_OBJ_OTR);
//
// auto idx = cur_geo_cmd_u8(0x01);
// geo_writer->Write(idx);
//
// Vec3s c_offset;
// read_vec3s(c_offset, (int16_t*) &cmd[0x02]);
//
// geo_writer->Write(c_offset[0]);
// geo_writer->Write(c_offset[1]);
// geo_writer->Write(c_offset[2]);
//
// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08)));
// geo_writer->Write(ptr);
//
// cmd += 0x0C << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_SCALE) {
// geo_writer->Write(NODE_SCALE_OTR);
// auto params = cur_geo_cmd_u8(0x01);
// auto scale = cur_geo_cmd_u32(0x04);
//
// geo_writer->Write(params);
// geo_writer->Write(scale);
//
// if (params & 0x80) {
// auto dlist = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08)));
// auto decl = Companion::Instance->GetNodeByAddr(dlist);
// if(decl.has_value()){
// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value()));
// geo_writer->Write(hash);
// } else {
// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist);
// geo_writer->Write((uint64_t) 0);
// }
// cmd += 4 << CMD_SIZE_SHIFT;
// }
// break;
// }
// case CMD_INFO(NOP2) {
// geo_writer->Write((uint8_t) NOP2);
// geo_writer->Write((uint32_t) 0);
// geo_writer->Write((uint32_t) 0);
// cmd += 0x08 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NOP3) {
// geo_writer->Write((uint8_t) NOP3);
// geo_writer->Write((uint32_t) 0);
// geo_writer->Write((uint32_t) 0);
// geo_writer->Write((uint32_t) 0);
// cmd += 0x10 << CMD_SIZE_SHIFT;
// break;
// }
// case CMD_INFO(NODE_CULLING_RADIUS) {
// geo_writer->Write((uint8_t) NODE_CULLING_RADIUS);
// auto radius = cur_geo_cmd_s16(0x02);
// geo_writer->Write(radius);
// break;
// }
// default:
// std::cout << "Unknown command: " << std::hex << (int) cmd[0x00] << std::endl;
// break;
// }
// }
// auto size = geo_writer->GetLength();
// auto data_ptr = geo_writer->ToVector();
+208
View File
@@ -0,0 +1,208 @@
#pragma once
#include "endianness.h"
#include "n64/CommandMacros.h"
#include <string>
#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#include <binarytools/BinaryWriter.h>
struct Vec2f {
float x;
float y;
};
struct Vec3f {
float x;
float y;
float z;
};
struct Vec3s {
int16_t x;
int16_t y;
int16_t z;
};
struct Vec3i {
int32_t x;
int32_t y;
int32_t z;
};
struct Vec4f {
float x;
float y;
float z;
float w;
};
struct Vec4s {
int16_t x;
int16_t y;
int16_t z;
int16_t w;
};
enum class GeoOpcode {
BranchAndLink,
End,
Branch,
Return,
OpenNode,
CloseNode,
AssignAsView,
UpdateNodeFlags,
NodeRoot,
NodeOrthoProjection,
NodePerspective,
NodeStart,
NodeMasterList,
NodeLevelOfDetail,
NodeSwitchCase,
NodeCamera,
NodeTranslationRotation,
NodeTranslation,
NodeRotation,
NodeAnimatedPart,
NodeBillboard,
NodeDisplayList,
NodeShadow,
NodeObjectParent,
NodeAsm,
NodeBackground,
NOP,
CopyView,
NodeHeldObj,
NodeScale,
NOP2,
NOP3,
NodeCullingRadius,
};
inline std::ostream& operator<<(std::ostream& out, const GeoOpcode& opcode) {
std::string output;
switch (opcode) {
case GeoOpcode::BranchAndLink:
output = "GEO_BRANCH_AND_LINK";
break;
case GeoOpcode::End:
output = "GEO_END";
break;
case GeoOpcode::Branch:
output = "GEO_BRANCH";
break;
case GeoOpcode::Return:
output = "GEO_RETURN";
break;
case GeoOpcode::OpenNode:
output = "GEO_OPEN_NODE";
break;
case GeoOpcode::CloseNode:
output = "GEO_CLOSE_NODE";
break;
case GeoOpcode::AssignAsView:
output = "GEO_ASSIGN_AS_VIEW";
break;
case GeoOpcode::UpdateNodeFlags:
output = "GEO_UPDATE_NODE_FLAGS";
break;
case GeoOpcode::NodeRoot:
output = "GEO_NODE_SCREEN_AREA";
break;
case GeoOpcode::NodeOrthoProjection:
output = "GEO_NODE_ORTHO";
break;
case GeoOpcode::NodePerspective:
output = "GEO_CAMERA_FRUSTUM";
break;
case GeoOpcode::NodeStart:
output = "GEO_NODE_START";
break;
case GeoOpcode::NodeMasterList:
output = "GEO_ZBUFFER";
break;
case GeoOpcode::NodeLevelOfDetail:
output = "GEO_RENDER_RANGE";
break;
case GeoOpcode::NodeSwitchCase:
output = "GEO_SWITCH_CASE";
break;
case GeoOpcode::NodeCamera:
output = "GEO_CAMERA";
break;
case GeoOpcode::NodeTranslationRotation:
output = "GEO_TRANSLATE_ROTATE";
break;
case GeoOpcode::NodeTranslation:
output = "GEO_TRANSLATE";
break;
case GeoOpcode::NodeRotation:
output = "GEO_ROTATE";
break;
case GeoOpcode::NodeAnimatedPart:
output = "GEO_ANIMATED_PART";
break;
case GeoOpcode::NodeBillboard:
output = "GEO_BILLBOARD";
break;
case GeoOpcode::NodeDisplayList:
output = "GEO_DISPLAY_LIST";
break;
case GeoOpcode::NodeShadow:
output = "GEO_SHADOW";
break;
case GeoOpcode::NodeObjectParent:
output = "GEO_RENDER_OBJ";
break;
case GeoOpcode::NodeAsm:
output = "GEO_ASM";
break;
case GeoOpcode::NodeBackground:
output = "GEO_BACKGROUND";
break;
case GeoOpcode::NOP:
output = "GEO_NOP_1A";
break;
case GeoOpcode::CopyView:
output = "GEO_COPY_VIEW";
break;
case GeoOpcode::NodeHeldObj:
output = "GEO_HELD_OBJECT";
break;
case GeoOpcode::NodeScale:
output = "GEO_SCALE";
break;
case GeoOpcode::NOP2:
output = "GEO_NOP_1E";
break;
case GeoOpcode::NOP3:
output = "GEO_NOP_1F";
break;
case GeoOpcode::NodeCullingRadius:
output = "GEO_CULLING_RADIUS";
break;
default:
throw std::runtime_error("Unknown Opcode");
}
return out << output;
}
#define cur_geo_cmd_u8(offset) \
(cmd[CMD_PROCESS_OFFSET(offset)])
#define cur_geo_cmd_s16(offset) \
BSWAP16((*(int16_t *) &cmd[CMD_PROCESS_OFFSET(offset)]))
#define cur_geo_cmd_s32(offset) \
BSWAP32((*(s32 *) &cmd[CMD_PROCESS_OFFSET(offset)]))
#define cur_geo_cmd_u32(offset) \
BSWAP32((*(uint32_t *) &cmd[CMD_PROCESS_OFFSET(offset)]))
class GeoLayoutCommand {
public:
virtual void Print(std::ostream& out) = 0;
virtual void Write(LUS::BinaryWriter& write) = 0;
};
+24
View File
@@ -0,0 +1,24 @@
#include "GeoUtils.h"
#define next_s16_in_geo_script(src) BSWAP16((*(*src)++))
int16_t* read_vec3s_to_vec3f(Vec3f& dst, int16_t *src) {
dst.x = next_s16_in_geo_script(&src);
dst.y = next_s16_in_geo_script(&src);
dst.z = next_s16_in_geo_script(&src);
return src;
}
int16_t* read_vec3s(Vec3s& dst, int16_t *src) {
dst.x = next_s16_in_geo_script(&src);
dst.y = next_s16_in_geo_script(&src);
dst.z = next_s16_in_geo_script(&src);
return src;
}
int16_t* read_vec3s_angle(Vec3s& dst, int16_t *src) {
dst.x = next_s16_in_geo_script(&src);
dst.y = next_s16_in_geo_script(&src);
dst.z = next_s16_in_geo_script(&src);
return src;
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <cstdint>
#include "GeoCommand.h"
int16_t* read_vec3s_to_vec3f(Vec3f& dst, int16_t *src);
int16_t* read_vec3s(Vec3s& dst, int16_t *src);
int16_t* read_vec3s_angle(Vec3s& dst, int16_t *src);
+3 -3
View File
@@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
bool header = false;
app.require_subcommand();
/* Generate an OTR */
auto otr = app.add_subcommand("otr", "OTR - Generates an otr\n");
@@ -38,9 +38,9 @@ int main(int argc, char *argv[]) {
} else {
instance->Init(ExportType::Binary);
}
if (!folder.empty()) {
Companion::Pack(folder, target);
Companion::Pack(folder, target);
}
});
+20
View File
@@ -0,0 +1,20 @@
#include "TorchUtils.h"
#include <Companion.h>
#include <factories/BaseFactory.h>
#include "spdlog/spdlog.h"
uint32_t Torch::translate(const uint32_t offset) {
if(SEGMENT_NUMBER(offset) > 0x01) {
auto segment = SEGMENT_NUMBER(offset);
const auto addr = Companion::Instance->GetSegmentedAddr(segment);
if(!addr.has_value()) {
SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", segment);
throw std::runtime_error("Failed to find offset");
}
return addr.value() + SEGMENT_OFFSET(offset);
}
return offset;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <fstream>
#include <sstream>
namespace Torch {
template< typename T >
std::string to_hex(T number, const bool append0x = true) {
std::stringstream stream;
if(append0x) {
stream << "0x";
}
stream << std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << number;
auto format = stream.str();
std::transform(format.begin(), format.end(), format.begin(), ::toupper);
return format;
}
uint32_t translate(uint32_t offset);
};