1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#include "ObjInitFactory.h"
#include "utils/Decompressor.h"
#include "Companion.h"
#include <tinyxml2.h>
#define NUM(x, w) std::dec << std::setfill(' ') << std::setw(w) << x
#define FLOAT(x, w) std::dec << std::setfill(' ') << std::setw(w) << std::fixed << std::setprecision(1) << x << "f"
ExportResult SF64::ObjInitHeaderExporter::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 ALIGN_ASSET(2) char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
return std::nullopt;
}
write << "extern ObjectInit " << symbol << "[];\n";
return std::nullopt;
}
ExportResult 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 offset = GetSafeNode<uint32_t>(node, "offset");
auto objs = std::static_pointer_cast<ObjInitData>(raw)->mObjInit;
write << "ObjectInit " << symbol << "[] = {\n";
for (auto& obj : objs) {
auto enumName = Companion::Instance->GetEnumFromValue("ObjectId", obj.id).value_or(std::to_string(obj.id));
if (obj.id >= 1000) {
enumName = "ACTOR_EVENT_ID + " + std::to_string(obj.id - 1000);
}
write << fourSpaceTab << "{ ";
write << FLOAT(obj.zPos1, 8) << ", ";
write << NUM(obj.zPos2, 7) << ", ";
write << NUM(obj.xPos, 7) << ", ";
write << NUM(obj.yPos, 7) << ", ";
write << NUM(obj.rot, 3) << ", ";
write << enumName << " },\n";
}
write << "};\n";
if (Companion::Instance->IsDebug()) {
write << "// count: " << std::to_string(objs.size()) << " ObjectInits\n";
}
return offset + sizeof(ObjectInit) * objs.size();
}
ExportResult 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, Torch::ResourceType::ObjectInit, 0);
auto count = data.size();
writer.Write((uint32_t)count);
for (size_t i = 0; i < data.size(); i++) {
writer.Write(data[i].zPos1);
writer.Write(data[i].zPos2);
writer.Write(data[i].xPos);
writer.Write(data[i].yPos);
writer.Write(data[i].rot.x);
writer.Write(data[i].rot.y);
writer.Write(data[i].rot.z);
writer.Write(data[i].id);
}
writer.Finish(write);
return std::nullopt;
}
ExportResult SF64::ObjInitXMLExporter::Export(std::ostream& write, std::shared_ptr<IParsedData> raw,
std::string& entryName, YAML::Node& node, std::string* replacement) {
auto data = std::static_pointer_cast<ObjInitData>(raw)->mObjInit;
tinyxml2::XMLPrinter printer;
tinyxml2::XMLDocument objects;
tinyxml2::XMLElement* root = objects.NewElement("ObjectList");
*replacement += ".meta";
for (auto& i : data) {
tinyxml2::XMLElement* obj = root->InsertNewChildElement("ObjInit");
auto enumName = Companion::Instance->GetEnumFromValue("ObjectId", i.id).value_or(std::to_string(i.id));
obj->SetAttribute("ID", enumName.c_str());
obj->SetAttribute("xPos", i.xPos);
obj->SetAttribute("yPos", i.yPos);
obj->SetAttribute("zPos1", i.zPos1);
obj->SetAttribute("zPos2", i.zPos2);
obj->SetAttribute("xRot", i.rot.x);
obj->SetAttribute("yRot", i.rot.y);
obj->SetAttribute("zRot", i.rot.z);
root->InsertEndChild(obj);
}
objects.InsertEndChild(root);
objects.Accept(&printer);
write.write(printer.CStr(), printer.CStrSize() - 1);
return std::nullopt;
}
std::optional<std::shared_ptr<IParsedData>> SF64::ObjInitFactory::parse(std::vector<uint8_t>& buffer,
YAML::Node& node) {
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
LUS::BinaryReader reader(segment.data, segment.size);
reader.SetEndianness(Torch::Endianness::Big);
std::vector<ObjectInit> objects;
bool terminator = false;
bool processing = true;
while (processing) {
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();
if (id == -1) {
terminator = true;
}
if (terminator && ((zPos1 * zPos2 * xPos * yPos * rotX * rotY * rotZ) != 0 || id != -1)) {
processing = false;
} else {
objects.push_back({ zPos1, zPos2, xPos, yPos, { rotX, rotY, rotZ }, id });
}
}
return std::make_shared<ObjInitData>(objects);
}
|