Fully implemented tables and message factories

This commit is contained in:
KiritoDv
2024-03-11 00:05:16 -06:00
committed by Lywx
parent 595f7512d4
commit 0277b06b47
4 changed files with 117 additions and 94 deletions
+24
View File
@@ -245,6 +245,7 @@ void Companion::ParseCurrentFileConfig(YAML::Node node) {
}
}
}
if(node["header"]) {
auto header = node["header"];
switch (this->gConfig.exporterType) {
@@ -267,6 +268,18 @@ void Companion::ParseCurrentFileConfig(YAML::Node node) {
default: break;
}
}
if(node["tables"]){
for(auto table = node["tables"].begin(); table != node["tables"].end(); ++table){
auto name = table->first.as<std::string>();
auto range = table->second["range"].as<std::vector<uint32_t>>();
auto start = gCurrentSegmentNumber ? gCurrentSegmentNumber << 24 | range[0] : range[0];
auto end = gCurrentSegmentNumber ? gCurrentSegmentNumber << 24 | range[1] : range[1];
auto mode = GetSafeNode<std::string>(table->second, "mode", "APPEND");
TableMode tMode = mode == "REFERENCE" ? TableMode::Reference : TableMode::Append;
this->gTables.push_back({name, start, end, tMode});
}
}
}
void Companion::Process() {
@@ -491,6 +504,7 @@ void Companion::Process() {
this->gConfig.segment.local.clear();
this->gFileHeader.clear();
this->gCurrentPad = 0;
this->gTables.clear();
GFXDOverride::ClearVtx();
if(root[":config"]) {
@@ -762,6 +776,16 @@ CompressionType Companion::GetCompressionType(std::vector<uint8_t>& buffer, cons
return CompressionType::None;
}
std::optional<Table> Companion::SearchTable(uint32_t addr){
for(auto& table : this->gTables){
if(addr >= table.start || addr <= table.end){
return table;
}
}
return std::nullopt;
}
std::optional<std::uint32_t> Companion::GetFileOffsetFromSegmentedAddr(const uint8_t segment) const {
auto segments = this->gConfig.segment;
+17 -3
View File
@@ -28,12 +28,24 @@ enum class GBIMinorVersion {
SM64
};
enum class TableMode {
Reference,
Append
};
struct SegmentConfig {
std::unordered_map<uint32_t, uint32_t> global;
std::unordered_map<uint32_t, uint32_t> local;
std::unordered_map<uint32_t, uint32_t> temporal;
};
struct Table {
std::string name;
uint32_t start;
uint32_t end;
TableMode mode;
};
struct GBIConfig {
GBIVersion version = GBIVersion::f3d;
GBIMinorVersion subversion = GBIMinorVersion::None;
@@ -82,6 +94,7 @@ public:
std::optional<std::uint32_t> GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; };
CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; };
CompressionType GetCompressionType(std::vector<uint8_t>& buffer, const uint32_t offset);
std::optional<Table> SearchTable(uint32_t addr);
static std::string CalculateHash(const std::vector<uint8_t>& data);
static void Pack(const std::string& folder, const std::string& output);
@@ -102,15 +115,16 @@ private:
std::string gCurrentFile;
std::string gFileHeader;
uint32_t gCurrentPad = 0;
uint32_t gCurrentFileOffset;
uint32_t gCurrentSegmentNumber;
CompressionType gCurrentCompressionType;
std::vector<Table> gTables;
std::variant<std::vector<std::string>, std::string> gWriteOrder;
std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories;
std::unordered_map<std::string, std::string> gModdedAssetPaths;
std::unordered_map<std::string, std::map<std::string, std::pair<YAML::Node, bool>>> gAssetDependencies;
std::unordered_map<std::string, std::map<std::string, std::vector<std::pair<uint32_t, std::string>>>> gWriteMap;
std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
uint32_t gCurrentFileOffset;
uint32_t gCurrentSegmentNumber;
CompressionType gCurrentCompressionType;
void ParseCurrentFileConfig(YAML::Node node);
void ParseModdingConfig();
+37 -20
View File
@@ -9,6 +9,8 @@ extern "C" {
#include "BaseFactory.h"
}
bool isTable = false;
static const std::unordered_map <std::string, TextureFormat> gTextureFormats = {
{ "RGBA16", { TextureType::RGBA16bpp, 16 } },
{ "RGBA32", { TextureType::RGBA32bpp, 32 } },
@@ -138,29 +140,44 @@ void TextureCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}
if (Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) {
write << "u8 " << symbol << "[] = {\n";
const auto searchTable = Companion::Instance->SearchTable(offset);
if(searchTable.has_value()){
const auto [name, start, end, mode] = searchTable.value();
if(mode != TableMode::Append){
throw std::runtime_error("Reference mode is not supported for now");
}
if(start == offset){
write << GetSafeNode<std::string>(node, "ctype", "static const u8") << " " << name << "[][0x" << texture->mBuffer.size() << std::hex << std::uppercase << "] = {\n";
}
write << tab << "{\n";
write << tab << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << *replacement << ".inc.c\"\n";
write << tab << "},\n";
if(end == offset){
write << "};\n";
}
} else {
if(node["ctype"]) {
write << node["ctype"].as<std::string>() << " " << symbol << "[] = {\n";
} else {
write << "static const u8 " << symbol << "[] = {\n";
write << GetSafeNode<std::string>(node, "ctype", "static const u8") << " " << symbol << "[] = {\n";
write << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << *replacement << ".inc.c\"\n";
write << "};\n";
if (Companion::Instance->IsDebug()) {
const auto sz = data.size();
write << "// size: 0x" << std::hex << std::uppercase << sz << "\n";
if (IS_SEGMENTED(offset)) {
offset = SEGMENT_OFFSET(offset);
}
write << "// 0x" << std::hex << std::uppercase << (offset + sz) << "\n";
}
write << "\n";
}
write << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << (*replacement) << ".inc.c\"\n";
write << "};\n";
if (Companion::Instance->IsDebug()) {
const auto sz = data.size();
write << "// size: 0x" << std::hex << std::uppercase << sz << "\n";
if (IS_SEGMENTED(offset)) {
offset = SEGMENT_OFFSET(offset);
}
write << "// 0x" << std::hex << std::uppercase << (offset + sz) << "\n";
}
write << "\n";
}
void TextureBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+39 -71
View File
@@ -41,6 +41,14 @@ std::vector<std::string> gCharCodeEnums = {
"_7", "_8", "_9", "APS", "LPR", "RPR", "CLN", "PIP",
};
std::unordered_map<std::string, std::string> ASCIITable = {
{ "CLF", "(C<)" }, { "CUP", "(C^)" }, { "CRT", "(C>)" }, { "CDN", "(Cv)" },
{ "AUP", "^" }, { "ALF", "<" }, { "ADN", "v" }, { "ART", ">" },
{ "EXM", "!" }, { "QST", "?" }, { "DSH", "-" }, { "CMA", "," },
{ "PRD", "." }, { "APS", "'" }, { "LPR", "(" }, { "RPR", ")" },
{ "CLN", ":" }, { "PIP", "| " }
};
void SF64::MessageHeaderExporter::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);
@@ -53,76 +61,15 @@ void SF64::MessageHeaderExporter::Export(std::ostream &write, std::shared_ptr<IP
}
void TextToStream(std::ostream& stream, int charCode) {
switch (charCode) {
case NEWLINE_CODE:
stream << "\n// ";
break;
// case CLF:
// stream << "(C<)";
// break;
// case CUP:
// stream << "(C^)";
// break;
// case CRT:
// stream << "(C>)";
// break;
// case CDN:
// stream << "(Cv)";
// break;
// case AUP:
// stream << "^";
// break;
// case ALF:
// stream << "<";
// break;
// case ADN:
// stream << "v";
// break;
// case ART:
// stream << ">";
// break;
// case EXM:
// stream << "!";
// break;
// case QST:
// stream << "?";
// break;
// case DSH:
// stream << "-";
// break;
// case CMA:
// stream << ",";
// break;
// case PRD:
// stream << ".";
// break;
// case APS:
// stream << "'";
// break;
// case LPR:
// stream << "(";
// break;
// case RPR:
// stream << ")";
// break;
// case CLN:
// stream << ":";
// break;
// case PIP:
// stream << "|";
// break;
// case SPC:
// stream << " ";
// break;
default:
if(charCode > 23 && charCode < 50) {
stream << static_cast<char>('A' + (charCode - 24));
} else if(charCode > 49 && charCode < 58) {
stream << static_cast<char>('a' + (charCode - 58));
} else if(charCode > 80 && charCode < 90) {
stream << static_cast<char>('0' + (charCode - 81));
}
break;
std::string enumCode = gCharCodeEnums[charCode];
if(enumCode.starts_with("_")){
stream << enumCode.substr(1);
return;
}
if(ASCIITable.contains(enumCode)){
stream << ASCIITable[enumCode];
}
}
@@ -142,9 +89,30 @@ void SF64::MessageCodeExporter::Export(std::ostream &write, std::shared_ptr<IPar
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}
write << "// ";
bool lastWasSpace = false;
for (int i = 0; i < message.size(); ++i) {
TextToStream(write, message[i]);
const auto charCode = message[i];
std::string enumCode = gCharCodeEnums[charCode];
if(enumCode.find("SP") != std::string::npos){
if (lastWasSpace){
continue;
}
if (!enumCode.empty() && enumCode.back() != ' ') {
write << " ";
lastWasSpace = true;
}
} else {
lastWasSpace = false;
}
TextToStream(write,charCode );
if(message[i] == NEWLINE_CODE && i != message.size() - 2){
write << "\n// ";
}
}
write << "\n";
write << "u16 " << symbol << "[] = {\n" << fourSpaceTab;
for (int i = 0; i < message.size(); ++i) {