Actual Painting Factory

This commit is contained in:
inspectredc
2024-04-25 18:09:31 -06:00
committed by Lywx
parent 4b72a6c401
commit 4d6744dcac
5 changed files with 438 additions and 4 deletions
+2
View File
@@ -40,6 +40,7 @@
#include "factories/sm64/MacroFactory.h"
#include "factories/sm64/MovtexFactory.h"
#include "factories/sm64/MovtexQuadFactory.h"
#include "factories/sm64/PaintingFactory.h"
#include "factories/sm64/PaintingMapFactory.h"
#include "factories/sm64/TrajectoryFactory.h"
#include "factories/sm64/WaterDropletFactory.h"
@@ -106,6 +107,7 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("SM64:MACRO", std::make_shared<SM64::MacroFactory>());
this->RegisterFactory("SM64:MOVTEX_QUAD", std::make_shared<SM64::MovtexQuadFactory>());
this->RegisterFactory("SM64:MOVTEX", std::make_shared<SM64::MovtexFactory>());
this->RegisterFactory("SM64:PAINTING", std::make_shared<SM64::PaintingFactory>());
this->RegisterFactory("SM64:PAINTING_MAP", std::make_shared<SM64::PaintingMapFactory>());
this->RegisterFactory("SM64:TRAJECTORY", std::make_shared<SM64::TrajectoryFactory>());
this->RegisterFactory("SM64:WATER_DROPLET", std::make_shared<SM64::WaterDropletFactory>());
+2 -1
View File
@@ -35,7 +35,8 @@ enum class ResourceType {
MacroObject = 0x4D41434F, // MACO
Movtex = 0x4D4F5654, // MOVT
MovtexQuad = 0x4D4F5651, // MOVQ
PaintingData = 0x5041494E, // PAIN
Painting = 0x504E5420, // PNT
PaintingData = 0x504E5444, // PNTD
Trajectory = 0x5452414A, // TRAJ
WaterDroplet = 0x57545244, // WTRD
+280
View File
@@ -0,0 +1,280 @@
#include "PaintingFactory.h"
#include "spdlog/spdlog.h"
#include "Companion.h"
#include "utils/Decompressor.h"
#include "utils/TorchUtils.h"
#include <regex>
ExportResult SM64::PaintingHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
const auto symbol = GetSafeNode(node, "symbol", entryName);
if(Companion::Instance->IsOTRMode()){
write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
return std::nullopt;
}
write << "extern struct Painting " << symbol << "[];\n";
return std::nullopt;
}
ExportResult SM64::PaintingCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
auto painting = std::static_pointer_cast<SM64::Painting>(raw);
write << "struct Painting " << symbol << " = {\n";
std::stringstream textureType;
if (painting->textureType == PAINTING_IMAGE) {
textureType << "PAINTING_IMAGE";
} else if (painting->textureType == PAINTING_ENV_MAP) {
textureType << "PAINTING_ENV_MAP";
} else {
textureType << painting->textureType; // should not reach this case, throw error?
}
std::stringstream nDLSymbol;
{
auto dec = Companion::Instance->GetNodeByAddr(painting->normalDisplayList);
if (dec.has_value()) {
auto nDLNode = std::get<1>(dec.value());
nDLSymbol << GetSafeNode<std::string>(nDLNode, "symbol");
} else {
SPDLOG_WARN("Cannot find node for ptr 0x{:X}", painting->normalDisplayList);
nDLSymbol << std::hex << "0x" << painting->normalDisplayList << std::dec;
}
}
std::stringstream tMapSymbol;
{
auto dec = Companion::Instance->GetNodeByAddr(painting->textureMaps);
if (dec.has_value()) {
auto tMapNode = std::get<1>(dec.value());
tMapSymbol << GetSafeNode<std::string>(tMapNode, "symbol");
} else {
SPDLOG_WARN("Cannot find node for ptr 0x{:X}", painting->textureMaps);
tMapSymbol << std::hex << "0x" << painting->textureMaps << std::dec;
}
}
std::stringstream tArrSymbol;
{
auto dec = Companion::Instance->GetNodeByAddr(painting->textureArray);
if (dec.has_value()) {
auto tMapNode = std::get<1>(dec.value());
tArrSymbol << GetSafeNode<std::string>(tMapNode, "symbol");
} else {
SPDLOG_WARN("Cannot find node for ptr 0x{:X}", painting->textureArray);
tArrSymbol << std::hex << "0x" << painting->textureArray << std::dec;
}
}
std::stringstream rDLSymbol;
{
auto dec = Companion::Instance->GetNodeByAddr(painting->rippleDisplayList);
if (dec.has_value()) {
auto rDLNode = std::get<1>(dec.value());
rDLSymbol << GetSafeNode<std::string>(rDLNode, "symbol");
} else {
SPDLOG_WARN("Cannot find node for ptr 0x{:X}", painting->rippleDisplayList);
rDLSymbol << std::hex << "0x" << painting->rippleDisplayList << std::dec;
}
}
std::stringstream rippleTrigger;
if (painting->rippleTrigger == RIPPLE_TRIGGER_PROXIMITY) {
rippleTrigger << "RIPPLE_TRIGGER_PROXIMITY";
} else if (painting->rippleTrigger == RIPPLE_TRIGGER_CONTINUOUS) {
rippleTrigger << "RIPPLE_TRIGGER_CONTINUOUS";
} else {
rippleTrigger << painting->rippleTrigger; // should not reach this case, throw error?
}
write << fourSpaceTab << "/* id */ " << std::hex << "0x" << painting->id << ",\n";
write << fourSpaceTab << "/* Image Count */ " << std::hex << "0x" << (uint32_t)painting->imageCount << ",\n";
write << fourSpaceTab << "/* Texture Type */ " << textureType.str() << ",\n";
write << fourSpaceTab << "/* Floor Status */ " << std::hex << "0x" << (uint32_t)painting->lastFloor << ", " << std::hex << "0x" << (uint32_t)painting->currFloor << ", " << std::hex << "0x" << (uint32_t)painting->floorEntered << ",\n";
write << fourSpaceTab << "/* Ripple Status */ " << (uint32_t)painting->state << ",\n";
write << fourSpaceTab << "/* Rotation */ " << painting->pitch << ", " << painting->yaw << ",\n";
write << fourSpaceTab << "/* Position */ " << painting->posX << ", " << painting->posY << ", " << painting->posZ << ",\n";
write << fourSpaceTab << "/* Ripple Magnitude */ " << painting->currRippleMag << ", " << painting->passiveRippleMag << ", " << painting->entryRippleMag << ",\n";
write << fourSpaceTab << "/* Ripple Decay */ " << painting->rippleDecay << ", " << painting->passiveRippleDecay << ", " << painting->entryRippleDecay << ",\n";
write << fourSpaceTab << "/* Ripple Rate */ " << painting->currRippleRate << ", " << painting->passiveRippleRate << ", " << painting->entryRippleRate << ",\n";
write << fourSpaceTab << "/* Ripple Dispersion */ " << painting->dispersionFactor << ", " << painting->passiveDispersionFactor << ", " << painting->entryDispersionFactor << ",\n";
write << fourSpaceTab << "/* Curr Ripple Timer */ " << painting->rippleTimer << ",\n";
write << fourSpaceTab << "/* Curr Ripple x, y */ " << painting->rippleX << ", " << painting->rippleY << ",\n";
write << fourSpaceTab << "/* Normal DList */ " << nDLSymbol.str() << ",\n";
write << fourSpaceTab << "/* Texture Maps */ " << tMapSymbol.str() << ",\n";
write << fourSpaceTab << "/* Textures */ " << tArrSymbol.str() << ",\n";
write << fourSpaceTab << "/* Texture w, h */ " << std::dec << painting->textureWidth << ", " << painting->textureHeight << ",\n";
write << fourSpaceTab << "/* Ripple DList */ " << rDLSymbol.str() << ",\n";
write << fourSpaceTab << "/* Ripple Trigger */ " << rippleTrigger.str() << ",\n";
write << fourSpaceTab << "/* Alpha */ " << std::dec << (uint32_t)painting->alpha << ",\n";
write << fourSpaceTab << "/* Mario Below */ " << std::hex << "0x" << (uint32_t)painting->marioWasUnder << ", " << std::hex << "0x" << (uint32_t)painting->marioIsUnder << ", " << std::hex << "0x" << (uint32_t)painting->marioWentUnder << ",\n";
write << fourSpaceTab << "/* Size */ " << painting->size << ",\n";
write << "};\n";
return offset + 120;
}
ExportResult SM64::PaintingBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto writer = LUS::BinaryWriter();
auto painting = std::static_pointer_cast<SM64::Painting>(raw);
uint32_t ptr;
WriteHeader(writer, LUS::ResourceType::Painting, 0);
writer.Write(painting->id);
writer.Write(painting->imageCount);
writer.Write(painting->textureType);
writer.Write(painting->lastFloor);
writer.Write(painting->currFloor);
writer.Write(painting->floorEntered);
writer.Write(painting->state);
writer.Write(painting->pitch);
writer.Write(painting->yaw);
writer.Write(painting->posX);
writer.Write(painting->posY);
writer.Write(painting->posZ);
writer.Write(painting->currRippleMag);
writer.Write(painting->passiveRippleMag);
writer.Write(painting->entryRippleMag);
writer.Write(painting->rippleDecay);
writer.Write(painting->passiveRippleDecay);
writer.Write(painting->entryRippleDecay);
writer.Write(painting->currRippleRate);
writer.Write(painting->passiveRippleRate);
writer.Write(painting->entryRippleRate);
writer.Write(painting->dispersionFactor);
writer.Write(painting->passiveDispersionFactor);
writer.Write(painting->entryDispersionFactor);
writer.Write(painting->rippleTimer);
writer.Write(painting->rippleX);
writer.Write(painting->rippleY);
ptr = painting->normalDisplayList;
{
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if (dec.has_value()) {
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found DisplayList: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
writer.Write(hash);
} else {
SPDLOG_WARN("Could not find DisplayList at 0x{:X}", ptr);
}
}
ptr = painting->textureMaps;
{
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if (dec.has_value()) {
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found Texture Maps: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
writer.Write(hash);
} else {
SPDLOG_WARN("Could not find Texture Maps at 0x{:X}", ptr);
}
}
ptr = painting->textureArray;
{
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if (dec.has_value()) {
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found Texture Arrays: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
writer.Write(hash);
} else {
SPDLOG_WARN("Could not find Texture Arrays at 0x{:X}", ptr);
}
}
writer.Write(painting->textureWidth);
writer.Write(painting->textureHeight);
ptr = painting->rippleDisplayList;
{
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if (dec.has_value()) {
uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
SPDLOG_INFO("Found DisplayList: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
writer.Write(hash);
} else {
SPDLOG_WARN("Could not find DisplayList at 0x{:X}", ptr);
}
}
writer.Write(painting->rippleTrigger);
writer.Write(painting->alpha);
writer.Write(painting->marioWasUnder);
writer.Write(painting->marioIsUnder);
writer.Write(painting->marioWentUnder);
writer.Write(painting->size);
writer.Finish(write);
return std::nullopt;
}
std::optional<std::shared_ptr<IParsedData>> SM64::PaintingFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
LUS::BinaryReader reader(segment.data, segment.size);
reader.SetEndianness(LUS::Endianness::Big);
auto id = reader.ReadInt16();
auto imageCount = reader.ReadInt8();
auto textureType = reader.ReadInt8();
auto lastFloor = reader.ReadInt8();
auto currFloor = reader.ReadInt8();
auto floorEntered = reader.ReadInt8();
auto state = reader.ReadInt8();
auto pitch = reader.ReadFloat();
auto yaw = reader.ReadFloat();
auto posX = reader.ReadFloat();
auto posY = reader.ReadFloat();
auto posZ = reader.ReadFloat();
auto currRippleMag = reader.ReadFloat();
auto passiveRippleMag = reader.ReadFloat();
auto entryRippleMag = reader.ReadFloat();
auto rippleDecay = reader.ReadFloat();
auto passiveRippleDecay = reader.ReadFloat();
auto entryRippleDecay = reader.ReadFloat();
auto currRippleRate = reader.ReadFloat();
auto passiveRippleRate = reader.ReadFloat();
auto entryRippleRate = reader.ReadFloat();
auto dispersionFactor = reader.ReadFloat();
auto passiveDispersionFactor = reader.ReadFloat();
auto entryDispersionFactor = reader.ReadFloat();
auto rippleTimer = reader.ReadFloat();
auto rippleX = reader.ReadFloat();
auto rippleY = reader.ReadFloat();
auto normalDisplayList = reader.ReadUInt32();
auto textureMaps = reader.ReadUInt32();
auto textureArray = reader.ReadUInt32();
auto textureWidth = reader.ReadInt16();
auto textureHeight = reader.ReadInt16();
auto rippleDisplayList = reader.ReadUInt32();
auto rippleTrigger = reader.ReadInt8();
auto alpha = reader.ReadUByte();
auto marioWasUnder = reader.ReadInt8();
auto marioIsUnder = reader.ReadInt8();
auto marioWentUnder = reader.ReadInt8();
reader.ReadInt8(); // pad
reader.ReadInt8(); // pad
reader.ReadInt8(); // pad
auto size = reader.ReadFloat();
YAML::Node nDLNode;
nDLNode["type"] = "GFX";
nDLNode["offset"] = normalDisplayList;
Companion::Instance->AddAsset(nDLNode);
YAML::Node rDLNode;
rDLNode["type"] = "GFX";
rDLNode["offset"] = rippleDisplayList;
Companion::Instance->AddAsset(rDLNode);
return std::make_shared<SM64::Painting>(id, imageCount, textureType, lastFloor, currFloor, floorEntered, state, pitch, yaw, posX, posY, posZ, currRippleMag, passiveRippleMag, entryRippleMag, rippleDecay, passiveRippleDecay, entryRippleDecay, currRippleRate, passiveRippleRate, entryRippleRate, dispersionFactor, passiveDispersionFactor, entryDispersionFactor, rippleTimer, rippleX, rippleY, normalDisplayList, textureMaps, textureArray, textureWidth, textureHeight, rippleDisplayList, rippleTrigger, alpha, marioWasUnder, marioIsUnder, marioWentUnder, size);
}
+153
View File
@@ -0,0 +1,153 @@
// struct Painting ttm_slide_painting = {
// /* id */ 0x0000,
// /* Image Count */ 0x02,
// /* Texture Type */ PAINTING_IMAGE,
// /* Floor Status */ 0x00, 0x00, 0x00 /* which of the painting's nearby special floors Mario's on */,
// /* Ripple Status */ 0x00,
// /* Rotation */ 0.0f, 90.0f,
// /* Position */ 3072.0f, 921.6f, -819.2f,
// /* curr passive entry */
// /* Ripple Magnitude */ 0.0f, 20.0f, 80.0f,
// /* Ripple Decay */ 1.0f, 0.9608f, 0.9524f,
// /* Ripple Rate */ 0.0f, 0.24f, 0.14f,
// /* Ripple Dispersion */ 0.0f, 40.0f, 30.0f,
// /* Curr Ripple Timer */ 0.0f,
// /* Curr Ripple x, y */ 0.0f, 0.0f,
// /* Normal DList */ ttm_seg7_painting_dl_07012E98,
// /* Texture Maps */ ttm_seg7_painting_texture_maps_07012E88,
// /* Textures */ ttm_seg7_painting_textures_07012EF8,
// /* Texture w, h */ 64, 32,
// /* Ripple DList */ ttm_seg7_painting_dl_07012430,
// /* Ripple Trigger */ RIPPLE_TRIGGER_PROXIMITY,
// /* Alpha */ 0xFF,
// /* Mario Below */ 0x00, 0x00, 0x00, /* Whether or not Mario is below the painting */
// /* Size */ 460.8f,
// };
#pragma once
#include "factories/BaseFactory.h"
#define PAINTING_IMAGE 0
#define PAINTING_ENV_MAP 1
#define RIPPLE_TRIGGER_PROXIMITY 10
#define RIPPLE_TRIGGER_CONTINUOUS 20
namespace SM64 {
class Painting : public IParsedData {
public:
int16_t id;
int8_t imageCount;
int8_t textureType;
int8_t lastFloor;
int8_t currFloor;
int8_t floorEntered;
int8_t state;
float pitch;
float yaw;
float posX;
float posY;
float posZ;
float currRippleMag;
float passiveRippleMag;
float entryRippleMag;
float rippleDecay;
float passiveRippleDecay;
float entryRippleDecay;
float currRippleRate;
float passiveRippleRate;
float entryRippleRate;
float dispersionFactor;
float passiveDispersionFactor;
float entryDispersionFactor;
float rippleTimer;
float rippleX;
float rippleY;
uint32_t normalDisplayList;
uint32_t textureMaps;
uint32_t textureArray;
int16_t textureWidth;
int16_t textureHeight;
uint32_t rippleDisplayList;
int8_t rippleTrigger;
uint8_t alpha;
int8_t marioWasUnder;
int8_t marioIsUnder;
int8_t marioWentUnder;
float size;
Painting(
int16_t id,
int8_t imageCount,
int8_t textureType,
int8_t lastFloor, int8_t currFloor, int8_t floorEntered,
int8_t state,
float pitch, float yaw,
float posX, float posY, float posZ,
float currRippleMag, float passiveRippleMag, float entryRippleMag,
float rippleDecay, float passiveRippleDecay, float entryRippleDecay,
float currRippleRate, float passiveRippleRate, float entryRippleRate,
float dispersionFactor, float passiveDispersionFactor, float entryDispersionFactor,
float rippleTimer,
float rippleX, float rippleY,
uint32_t normalDisplayList,
uint32_t textureMaps,
uint32_t textureArray,
int16_t textureWidth, int16_t textureHeight,
uint32_t rippleDisplayList,
int8_t rippleTrigger,
uint8_t alpha,
int8_t marioWasUnder, int8_t marioIsUnder, int8_t marioWentUnder,
float size
) :
id(id),
imageCount(imageCount),
textureType(textureType),
lastFloor(lastFloor), currFloor(currFloor), floorEntered(floorEntered),
state(state),
pitch(pitch), yaw(yaw),
posX(posX), posY(posY), posZ(posZ),
currRippleMag(currRippleMag), passiveRippleMag(passiveRippleMag), entryRippleMag(entryRippleMag),
rippleDecay(rippleDecay), passiveRippleDecay(passiveRippleDecay), entryRippleDecay(entryRippleDecay),
currRippleRate(currRippleRate), passiveRippleRate(passiveRippleRate), entryRippleRate(entryRippleRate),
dispersionFactor(dispersionFactor), passiveDispersionFactor(passiveDispersionFactor), entryDispersionFactor(entryDispersionFactor),
rippleTimer(rippleTimer),
rippleX(rippleX), rippleY(rippleY),
normalDisplayList(normalDisplayList),
textureMaps(textureMaps),
textureArray(textureArray),
textureWidth(textureWidth), textureHeight(textureHeight),
rippleDisplayList(rippleDisplayList),
rippleTrigger(rippleTrigger),
alpha(alpha),
marioWasUnder(marioWasUnder), marioIsUnder(marioIsUnder), marioWentUnder(marioWentUnder),
size(size)
{}
};
class PaintingHeaderExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class PaintingBinaryExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class PaintingCodeExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class PaintingFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
return {
REGISTER(Code, PaintingCodeExporter)
REGISTER(Header, PaintingHeaderExporter)
REGISTER(Binary, PaintingBinaryExporter)
};
}
};
}
+1 -3
View File
@@ -109,9 +109,7 @@ ExportResult SM64::WaterDropletCodeExporter::Export(std::ostream &write, std::sh
write << "};\n";
size_t size = 0;
return offset + size;
return offset + 36;
}
ExportResult SM64::WaterDropletBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {