Removed GBI, added GeoLayout and Lights extraction

This commit is contained in:
KiritoDv
2024-01-31 12:05:40 -06:00
committed by Lywx
parent 57f61f8e65
commit c54ef39005
10 changed files with 333 additions and 5002 deletions
+14
View File
@@ -77,6 +77,14 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar
return;
}
if(node["segments"]) {
for(auto segment = node["segments"].begin(); segment != node["segments"].end(); ++segment) {
auto id = std::stoi(segment->first.as<std::string>().substr(3));
auto replacement = segment->second.as<uint32_t>();
this->gTemporalSegments[id] = replacement;
}
}
auto result = factory->get()->parse(this->gRomData, node);
if(!result.has_value()){
SPDLOG_ERROR("Failed to process {}", name);
@@ -265,6 +273,7 @@ void Companion::Process() {
std::string output = (this->gCurrentDirectory / entryName).string();
std::replace(output.begin(), output.end(), '\\', '/');
this->gTemporalSegments.clear();
this->ExtractNode(asset->second, output, wrapper);
}
@@ -439,6 +448,11 @@ std::optional<std::shared_ptr<BaseFactory>> Companion::GetFactory(const std::str
}
std::optional<std::uint32_t> Companion::GetSegmentedAddr(const uint8_t segment) {
if(this->gTemporalSegments.contains(segment)) {
return this->gTemporalSegments[segment];
}
if(segment >= this->gSegments.size()) {
return std::nullopt;
}
+2
View File
@@ -24,6 +24,7 @@ enum class GBIVersion {
enum class GBIMinorVersion {
None,
Mk64,
SM64
};
class Companion {
@@ -59,6 +60,7 @@ private:
std::vector<uint8_t> gRomData;
std::filesystem::path gRomPath;
std::vector<uint32_t> gSegments;
std::unordered_map<uint32_t, uint32_t> gTemporalSegments;
std::variant<std::vector<std::string>, std::string> gWriteOrder;
std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories;
+231 -185
View File
@@ -6,9 +6,42 @@
#include <gfxd.h>
#include <fstream>
#include <utils/TorchUtils.h>
#include "n64/gbi-otr.h"
#define C0(pos, width) ((w0 >> (pos)) & ((1U << width) - 1))
std::unordered_map<std::string, uint8_t> gF3DTable = {
{ "G_VTX", 0x04 },
{ "G_DL", 0x06 },
{ "G_ENDDL", 0xB8 },
{ "G_SETTIMG", 0xFD },
{ "G_MOVEMEM", 0x03 },
{ "G_MV_L0", 0x86 },
{ "G_MV_L1", 0x88 },
{ "G_MV_LIGHT", 0xA },
{ "G_TRI2", 0xB1 },
{ "G_QUAD", -1 }
};
std::unordered_map<std::string, uint8_t> gF3DExTable = {
{ "G_VTX", 0x04 },
{ "G_DL", 0x06 },
{ "G_ENDDL", 0xB8 },
{ "G_SETTIMG", 0xFD },
{ "G_MOVEMEM", 0x03 },
{ "G_MV_L0", 0x86 },
{ "G_MV_L1", 0x88 },
{ "G_MV_LIGHT", 0xA },
{ "G_TRI2", 0xB1 },
{ "G_QUAD", 0xB5 }
};
std::unordered_map<GBIVersion, std::unordered_map<std::string, uint8_t>> gGBITable = {
{ GBIVersion::f3d, gF3DTable }
};
#define GBI(cmd) gGBITable[Companion::Instance->GetGBIVersion()][#cmd]
void GFXDSetGBIVersion(){
switch (Companion::Instance->GetGBIVersion()) {
case GBIVersion::f3d:
@@ -52,30 +85,18 @@ void DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData>
gfxd_endian(gfxd_endian_host, sizeof(uint32_t));
gfxd_macro_fn([] {
auto gfx = static_cast<const Gfx*>(gfxd_macro_data());
auto opcode = (gfx->words.w0 >> 24) & 0xFF;
const uint8_t opcode = (gfx->words.w0 >> 24) & 0xFF;
gfxd_puts(fourSpaceTab);
#define QUAD 0xB5
#define TRI2 0xB1
switch(opcode) {
// For mk64 only
case QUAD:
if (Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) {
GFXDOverride::Quadrangle(gfx);
} else {
gfxd_macro_dflt();
}
break;
// Prevents mix and matching of quadrangle commands. Forces 2TRI only.
case TRI2:
GFXDOverride::Triangle2(gfx);
break;
default:
gfxd_macro_dflt();
break;
// For mk64 only
if(opcode == GBI(G_QUAD) && Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) {
GFXDOverride::Quadrangle(gfx);
// Prevents mix and matching of quadrangle commands. Forces 2TRI only.
} else if(opcode == GBI(G_TRI2)) {
GFXDOverride::Triangle2(gfx);
} else {
gfxd_macro_dflt();
}
gfxd_puts(",\n");
@@ -116,7 +137,6 @@ void DebugDisplayList(uint32_t w0, uint32_t w1){
//gfxd_light_callback(GFXDOverride::Light);
GFXDSetGBIVersion();
gfxd_execute();
int bp = 0;
}
void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
@@ -134,95 +154,106 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat
writer.Write(static_cast<uint32_t>(bhash >> 32));
writer.Write(static_cast<uint32_t>(bhash & 0xFFFFFFFF));
#ifndef _WIN32
#define case case (uint8_t)
#endif
for(size_t i = 0; i < cmds.size(); i+=2){
auto w0 = cmds[i];
auto w1 = cmds[i + 1];
uint8_t opcode = w0 >> 24;
switch (opcode) {
case G_VTX: {
auto nvtx = (C0(0, 16)) / sizeof(Vtx);
auto didx = C0(16, 4);
uint32_t ptr = SEGMENT_OFFSET(w1);
if(opcode == GBI(G_VTX)) {
auto nvtx = (C0(0, 16)) / sizeof(Vtx);
auto didx = C0(16, 4);
uint32_t ptr = SEGMENT_OFFSET(w1);
if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){
uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
SPDLOG_INFO("Found vtx: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value()));
if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){
uint64_t hash = CRC64(std::get<0>(decl.value()).c_str());
SPDLOG_INFO("Found vtx: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value()));
// TODO: Find a better way to do this because its going to break on other games
Gfx value = gsSPVertexOTR(didx, nvtx, 0);
// TODO: Find a better way to do this because its going to break on other games
Gfx value = gsSPVertexOTR(didx, nvtx, 0);
SPDLOG_INFO("gsSPVertex({}, {}, 0x{:X})", nvtx, didx, ptr);
SPDLOG_INFO("gsSPVertex({}, {}, 0x{:X})", nvtx, didx, ptr);
w0 = value.words.w0;
w1 = value.words.w1;
writer.Write(w0);
writer.Write(w1);
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find vtx at 0x{:X}", ptr);
}
break;
}
case G_DL: {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
Gfx value = gsSPDisplayListOTRHash(ptr);
w0 = value.words.w0;
w1 = value.words.w1;
writer.Write(w0);
writer.Write(w1);
if(dec.has_value()){
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", ptr);
}
break;
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find vtx at 0x{:X}", ptr);
}
case G_SETTIMG: {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
}
Gfx value = gsDPSetTextureImage(C0(21, 3), C0(19, 2), C0(0, 10), ptr);
w0 = value.words.w0 & 0x00FFFFFF;
w0 += (G_SETTIMG_OTR_HASH << 24);
w1 = value.words.w1;
if(opcode == GBI(G_DL)) {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
writer.Write(w0);
writer.Write(w1);
Gfx value = gsSPDisplayListOTRHash(ptr);
w0 = value.words.w0;
w1 = value.words.w1;
if(dec.has_value()){
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found texture: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find texture at 0x{:X}", ptr);
}
break;
writer.Write(w0);
writer.Write(w1);
if(dec.has_value()){
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", ptr);
}
}
if(opcode == GBI(G_MOVEMEM)) {
uint32_t ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
w0 &= 0x00FFFFFF;
w0 += G_MOVEMEM_OTR_HASH << 24;
w1 = 0;
writer.Write(w0);
writer.Write(w1);
if(dec.has_value()){
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found movemem: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find movemem at 0x{:X}", ptr);
}
}
if(opcode == GBI(G_SETTIMG)) {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
Gfx value = gsDPSetTextureOTRImage(C0(21, 3), C0(19, 2), C0(0, 10), ptr);
w0 = value.words.w0;
w1 = value.words.w1;
writer.Write(w0);
writer.Write(w1);
if(dec.has_value()){
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found texture: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
w0 = hash >> 32;
w1 = hash & 0xFFFFFFFF;
} else {
SPDLOG_WARN("Warning: Could not find texture at 0x{:X}", ptr);
}
default: break;
}
writer.Write(w0);
writer.Write(w1);
}
#undef case
writer.Finish(write);
}
@@ -245,119 +276,134 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
auto w1 = reader.ReadUInt32();
uint8_t opcode = w0 >> 24;
gfxs.push_back(w0);
gfxs.push_back(w1);
switch (opcode) {
case static_cast<uint8_t>(G_ENDDL):
processing = false;
break;
case static_cast<uint8_t>(G_DL): {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if(opcode == GBI(G_ENDDL)) {
processing = false;
}
if(!dec.has_value()){
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));
break;
}
if(opcode == GBI(G_DL)) {
auto ptr = SEGMENT_OFFSET(w1);
auto dec = Companion::Instance->GetNodeByAddr(ptr);
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_" + Torch::to_hex(w1, false));
YAML::Node dl;
dl["type"] = "GFX";
dl["mio0"] = addr.value();
dl["offset"] = ptr;
dl["symbol"] = output;
auto result = factory->parse(rom, dl);
if(!result.has_value()){
break;
}
Companion::Instance->RegisterAsset(output, dl);
} else {
SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", ptr);
if(!dec.has_value()){
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));
continue;
}
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_" + Torch::to_hex(addr.value() + w1, false));
YAML::Node dl;
dl["type"] = "GFX";
dl["mio0"] = addr.value();
dl["offset"] = ptr;
dl["symbol"] = output;
auto result = factory->parse(rom, dl);
if(!result.has_value()){
continue;
}
Companion::Instance->RegisterAsset(output, dl);
} else {
SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", ptr);
}
}
if(opcode == GBI(G_MOVEMEM)) {
uint8_t index = 0;
uint8_t offset = 0;
uint32_t ptr = SEGMENT_OFFSET(w1);
switch (Companion::Instance->GetGBIVersion()) {
case GBIVersion::f3d:
index = C0(16, 8);
if(index < GBI(G_MV_L0)) {
continue;
}
break;
default: {
index = C0(0, 8);
offset = C0(8, 8) * 8;
if(index != GBI(G_MV_LIGHT)) {
continue;
}
}
}
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);
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));
continue;
}
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_" + Torch::to_hex(addr.value() + w1, false));
YAML::Node light;
light["type"] = "lights";
light["mio0"] = addr.value();
light["offset"] = ptr;
light["symbol"] = output;
auto result = factory->parse(rom, light);
if(result.has_value()){
Companion::Instance->RegisterAsset(output, light);
}
}
}
if(opcode == GBI(G_VTX)) {
uint32_t nvtx;
switch (gbi) {
case GBIVersion::f3dex2:
nvtx = C0(12, 8);
break;
case GBIVersion::f3dex:
case GBIVersion::f3dexb:
nvtx = C0(10, 6);
break;
default:
nvtx = (C0(0, 16)) / sizeof(Vtx);
break;
}
// Lights1
case static_cast<uint8_t>(G_MOVEMEM): {
uint32_t ptr = SEGMENT_OFFSET(w1);
// Ignore if not a Lights1 command
if ( ( (w0 >> 16) & 0xFF ) != G_MV_L1) {
uint32_t ptr = SEGMENT_OFFSET(w1);
if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); !decl.has_value()){
SPDLOG_INFO("Addr to Vtx array 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));
break;
}
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);
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));
break;
}
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_" + Torch::to_hex(w1, false));
YAML::Node light;
light["type"] = "lights";
light["mio0"] = addr.value();
light["offset"] = ptr;
light["symbol"] = output;
auto result = factory->parse(rom, light);
if(result.has_value()){
Companion::Instance->RegisterAsset(output, light);
}
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_" + Torch::to_hex(addr.value() + w1, false));
YAML::Node vtx;
vtx["type"] = "VTX";
vtx["mio0"] = addr.value();
vtx["offset"] = ptr;
vtx["count"] = nvtx;
vtx["symbol"] = output;
auto result = factory->parse(rom, vtx);
if(result.has_value()){
Companion::Instance->RegisterAsset(output, vtx);
}
break;
}
case static_cast<uint8_t>(G_VTX): {
uint32_t nvtx;
switch (gbi) {
case GBIVersion::f3dex2:
nvtx = C0(12, 8);
break;
case GBIVersion::f3dex:
case GBIVersion::f3dexb:
nvtx = C0(10, 6);
break;
default:
nvtx = (C0(0, 16)) / sizeof(Vtx);
break;
}
uint32_t ptr = SEGMENT_OFFSET(w1);
if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); !decl.has_value()){
SPDLOG_INFO("Addr to Vtx array 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));
break;
}
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_" + Torch::to_hex(w1, false));
YAML::Node vtx;
vtx["type"] = "VTX";
vtx["mio0"] = addr.value();
vtx["offset"] = ptr;
vtx["count"] = nvtx;
vtx["symbol"] = output;
auto result = factory->parse(rom, vtx);
if(result.has_value()){
Companion::Instance->RegisterAsset(output, vtx);
}
}
break;
}
}
gfxs.push_back(w0);
gfxs.push_back(w1);
}
return std::make_shared<DListData>(gfxs);
-4
View File
@@ -3,10 +3,6 @@
#include "BaseFactory.h"
#include "n64/CommandMacros.h"
#define F3DEX
#define _LANGUAGE_C
#include "n64/gbi.h"
class DListData : public IParsedData {
public:
std::vector<uint32_t> mGfxs;
+30
View File
@@ -3,6 +3,36 @@
#include <cstdint>
#include "DisplayListFactory.h"
typedef struct {
uint32_t w0;
uint32_t w1;
} Words;
typedef union {
Words words;
long long int force_structure_alignment;
} Gfx;
typedef struct {
short ob[3];
unsigned short flag;
short tc[2];
unsigned char cn[4];
} Vtx_t;
typedef struct {
short ob[3];
unsigned short flag;
short tc[2];
signed char n[3];
unsigned char a;
} Vtx_tn;
typedef union {
Vtx_t v;
Vtx_tn n;
} Vtx;
namespace GFXDOverride {
void Quadrangle(const Gfx* gfx);
void Triangle2(const Gfx* gfx);
+13 -2
View File
@@ -49,16 +49,27 @@ void LightsCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData
void LightsBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto light = std::static_pointer_cast<LightsData>(raw)->mLights;
auto writer = LUS::BinaryWriter();
auto size = sizeof(light.l) / sizeof(LightRaw);
WriteHeader(writer, LUS::ResourceType::Lights, 0);
writer.Write((uint32_t) sizeof(light));
writer.Write(reinterpret_cast<char*>(light.a.l.col), 3);
writer.Write(reinterpret_cast<char*>(light.a.l.colc), 3);
writer.Write(static_cast<uint32_t>(size));
for(size_t i = 0; i < size; i++) {
writer.Write(reinterpret_cast<char*>(light.l[i].l.col), 3);
writer.Write(reinterpret_cast<char*>(light.l[i].l.colc), 3);
writer.Write(reinterpret_cast<char*>(light.l[i].l.dir), 3);
}
writer.Finish(write);
writer.Close();
}
std::optional<std::shared_ptr<IParsedData>> LightsFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto mio0 = node["mio0"].as<size_t>();
auto offset = node["offset"].as<uint32_t>();
auto symbol = node["symbol"].as<std::string>();
auto decoded = MIO0Decoder::Decode(buffer, mio0);
LUS::BinaryReader reader(decoded.data() + offset, sizeof(Lights1Raw));
+1 -1
View File
@@ -17,7 +17,7 @@ enum class ResourceType {
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
Lights = 0x46669697, // LIGHTS
Lights = 0x46669697, // LGTS
// SM64
Anim = 0x414E494D, // ANIM
+7 -5
View File
@@ -69,7 +69,7 @@ uint64_t RegisterOrLoadDisplayList(uint32_t ptr) {
YAML::Node dl;
dl["type"] = "GFX";
dl["mio0"] = addr.value();
dl["offset"] = ptr;
dl["offset"] = SEGMENT_OFFSET(ptr);
dl["symbol"] = output;
auto result = factory->parse(rom, dl);
@@ -379,7 +379,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
}
if (params & 0x80) {
auto ptr = *reinterpret_cast<uint32_t*>(&cmd_pos[0]);
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
cmd_pos += 2 << CMD_SIZE_SHIFT;
}
@@ -397,8 +397,10 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
cmd_pos = read_vec3s_angle(vector, &cmd_pos[1]);
arguments.emplace_back(vector);
if (params & 0x80) {
auto ptr = *reinterpret_cast<uint32_t*>(&cmd_pos[0]);
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
cmd_pos += 2 << CMD_SIZE_SHIFT;
}
@@ -410,7 +412,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
Vec3s translation = {};
auto layer = cur_geo_cmd_u8(0x01);
auto ptr = cur_geo_cmd_u32(0x08);
auto ptr = cur_geo_cmd_u32(0x08);
auto cmd_pos = reinterpret_cast<int16_t*>(cmd);
arguments.emplace_back(layer);
@@ -434,7 +436,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
arguments.emplace_back(translation);
if (params & 0x80) {
auto ptr = *reinterpret_cast<uint32_t*>(&cmd_pos[0]);
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
cmd_pos += 0x02 << CMD_SIZE_SHIFT;
}
+35 -4
View File
@@ -19,6 +19,7 @@
#define G_MTX_OTR 0x36
#define G_TEXRECT_WIDE 0x37
#define G_FILLWIDERECT 0x38
#define G_MOVEMEM_OTR_HASH 0x42
/* GFX Effects */
#define G_SETGRAYSCALE 0x39
@@ -126,10 +127,40 @@ _DW({
#define gsSPVertexOTR(v, n, v0) \
{ (_SHIFTL(G_VTX_OTR_HASH, 24, 8) | _SHIFTL((n), 12, 8) | _SHIFTL((v0) + (n), 1, 7)), (uintptr_t)(v) }
#define gsSPBranchListOTRHash(dl) gsDma1p(G_DL_OTR_HASH, dl, 0, G_DL_NOPUSH)
#define gsSPBranchListOTRFilePath(dl) gsDma1p(G_DL_OTR_FILEPATH, dl, 0, G_DL_NOPUSH)
#define gsSPDisplayListOTRHash(dl) gsDma1p(G_DL_OTR_HASH, dl, 0, G_DL_PUSH)
#define gsSPDisplayListOTRFilePath(dl) gsDma1p(G_DL_OTR_FILEPATH, dl, 0, G_DL_PUSH)
#define gsDPSetTextureOTRImage(fmt, siz, width, i) \
{{ \
_SHIFTL(G_SETTIMG_OTR_HASH, 24, 8) | _SHIFTL(fmt, 21, 3) | \
_SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12), \
(uintptr_t)(i) \
}}
#define gsSPBranchListOTRHash(dl) \
{{ \
(_SHIFTL((G_DL_OTR_HASH), 24, 8) | _SHIFTL((0x01), 16, 8) | \
_SHIFTL((0), 0, 16)), \
(uintptr_t)(dl) \
}}
#define gsSPBranchListOTRFilePath(dl) \
{{ \
(_SHIFTL((G_DL_OTR_FILEPATH), 24, 8) | _SHIFTL((0x01), 16, 8) | \
_SHIFTL((0), 0, 16)), \
(uintptr_t)(dl) \
}}
#define gsSPDisplayListOTRHash(dl) \
{{ \
(_SHIFTL((G_DL_OTR_HASH), 24, 8) | _SHIFTL((0x00), 16, 8) | \
_SHIFTL((0), 0, 16)), \
(uintptr_t)(dl) \
}}
#define gsSPDisplayListOTRFilePath(dl) \
{{ \
(_SHIFTL((G_DL_OTR_FILEPATH), 24, 8) | _SHIFTL((0x00), 16, 8) | \
_SHIFTL((0), 0, 16)), \
(uintptr_t)(dl) \
}}
#define gDPSetGrayscaleColor(pkt, r, g, b, lerp) DPRGBColor(pkt, G_SETINTENSITY, r, g, b, lerp)
#define gsDPSetGrayscaleColor(r, g, b, a) sDPRGBColor(G_SETINTENSITY, r, g, b, a)
-4801
View File
File diff suppressed because it is too large Load Diff