summaryrefslogtreecommitdiff
path: root/src/factories/TextureFactory.cpp
diff options
context:
space:
mode:
authorLywx <kiritodev01@gmail.com>2023-11-15 15:11:15 -0600
committerGitHub <noreply@github.com>2023-11-15 15:11:15 -0600
commiteaddecd0b402c12a780831e3139d7a35e78322e6 (patch)
tree0c961e1ba2339f52892b54f44b8ff0018b77c382 /src/factories/TextureFactory.cpp
parenta66b259d7c10c3367a04819c6b55d47fb9a99f5e (diff)
Torch v0.1 (#12)
* Splitted version yamls and implemented wip geo and dlist extraction * Fixed linux compilation * Added PoC WSL 2 detection * Add undefined behaviour * Added gfxdis as submodule * update * Removed gfxdis as a submodule * Code works * Replace ByteSwap with BSWAP * Cleanup vertice factory * readability * readability 2 * Cleanup gfxfactory * last one * Rename name to symbol * More implementation * Implemented first PoC of C file generation * Added output formatting on factories * changes * Moved generated dlists onto their respective folder * Migrated more factories onto the new extractor system * Fully ported all factories and added header generation * Some updates * Added Lights factory * fix * Fixed vtx extraction * Lights work now * delete old startup_logo yaml * Generate all sections in single file * Added support to generate header and code for textures * Added O3 for release builds * Added WIP dlist extraction and moved to use f3dold microcode * Added segment support, autogeneration and fixed C generation * Added symbol names on display list extraction * Removed warnings * Moved back to transform and replace * Removed unnecesary macros * Added extraction order and reversed vtx order * Implemented true backwards sort * [WIP] Implemented runtime gbi, more headers and a few config features * Fix CLI11 on WSL and variety of fixes * Fixes * Update DisplayListFactory.h * Update TextureFactory.cpp * wip lights * fix * Correct callback * Added waypoints * Update ceremony_data.yml * Changes * Update TextureFactory.cpp * Update commandline args * Update comment * Remove printf * Update couple commands * Renamed cubeos to torch * Removed unused stuff and added an example config file --------- Co-authored-by: KiritoDv <kiritodev01@gmail.com> Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
Diffstat (limited to 'src/factories/TextureFactory.cpp')
-rw-r--r--src/factories/TextureFactory.cpp133
1 files changed, 101 insertions, 32 deletions
diff --git a/src/factories/TextureFactory.cpp b/src/factories/TextureFactory.cpp
index d929d7c..f49db17 100644
--- a/src/factories/TextureFactory.cpp
+++ b/src/factories/TextureFactory.cpp
@@ -1,13 +1,16 @@
#include "TextureFactory.h"
-
#include "utils/MIODecoder.h"
#include "spdlog/spdlog.h"
-
-namespace fs = std::filesystem;
+#include "Companion.h"
+#include <iomanip>
static const std::unordered_map <std::string, TextureType> gTextureTypes = {
{ "RGBA16", TextureType::RGBA16bpp },
{ "RGBA32", TextureType::RGBA32bpp },
+ { "CI4", TextureType::Palette4bpp },
+ { "CI8", TextureType::Palette8bpp },
+ { "I4", TextureType::Grayscale4bpp },
+ { "I8", TextureType::Grayscale8bpp },
{ "IA1", TextureType::GrayscaleAlpha1bpp },
{ "IA4", TextureType::GrayscaleAlpha4bpp },
{ "IA8", TextureType::GrayscaleAlpha8bpp },
@@ -18,7 +21,7 @@ uint8_t* alloc_ia8_text_from_i1(uint16_t *in, int16_t width, int16_t height) {
int32_t inPos;
uint16_t bitMask;
int16_t outPos = 0;
- uint8_t* out = new uint8_t[width * height];
+ auto out = new uint8_t[width * height];
for (inPos = 0; inPos < (width * height) / 16; inPos++) {
bitMask = 0x8000;
@@ -38,47 +41,113 @@ uint8_t* alloc_ia8_text_from_i1(uint16_t *in, int16_t width, int16_t height) {
return out;
}
-bool TextureFactory::process(LUS::BinaryWriter* writer, YAML::Node& data, std::vector<uint8_t>& buffer) {
+void TextureHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName;
+ auto data = std::static_pointer_cast<TextureData>(raw)->mBuffer;
- auto format = data["format"].as<std::string>();
- auto width = data["width"].as<uint32_t>();
- auto height = data["height"].as<uint32_t>();
- auto size = data["size"].as<size_t>();
- auto offset = data["offset"].as<size_t>();
+ if(Companion::Instance->IsOTRMode()){
+ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n";
+ return;
+ }
+
+ write << "extern u8 " << symbol << "[" << data.size() << "];\n";
+}
+
+void TextureCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto data = std::static_pointer_cast<TextureData>(raw)->mBuffer;
+ auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName;
+ auto format = node["format"].as<std::string>();
+
+ std::transform(format.begin(), format.end(), format.begin(), tolower);
+ (*replacement) += "." + format;
+
+ std::string dpath = Companion::Instance->GetOutputPath() + "/" + (*replacement);
+ if(!exists(fs::path(dpath).parent_path())){
+ create_directories(fs::path(dpath).parent_path());
+ }
+
+ std::ofstream file(dpath + ".inc.c", std::ios::binary);
+
+ for (int i = 0; i < data.size(); i++) {
+ if (i % 16 == 0 && i != 0) {
+ file << std::endl;
+ }
+
+ file << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << ", ";
+ }
+
+ file.close();
+
+ if (Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) {
+ write << "u8 " << symbol << "[] = {\n";
+ } else {
+ write << "ALIGNED8 static const u8 " << symbol << "[] = {\n";
+ }
+ write << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << (*replacement) << ".inc.c\"\n";
+ write << "};\n\n";
+}
+
+void TextureBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto writer = LUS::BinaryWriter();
+ auto texture = std::static_pointer_cast<TextureData>(raw);
+ auto data = texture->mBuffer;
+
+ WriteHeader(writer, LUS::ResourceType::Texture, 0);
+
+ writer.Write((uint32_t) texture->mType);
+ writer.Write(texture->mWidth);
+ writer.Write(texture->mHeight);
+
+ writer.Write((uint32_t) data.size());
+ writer.Write((char*) data.data(), data.size());
+ writer.Finish(write);
+}
+
+std::optional<std::shared_ptr<IParsedData>> TextureFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
+ auto format = node["format"].as<std::string>();
+ auto width = node["width"].as<uint32_t>();
+ auto height = node["height"].as<uint32_t>();
+ auto size = node["size"].as<size_t>();
+ auto offset = node["offset"].as<size_t>();
+
+ if (format.empty()) {
+ SPDLOG_ERROR("Texture entry at {:X} in yaml missing format node\n\
+ Please add one of the following formats\n\
+ rgba16, rgba32, ia16, ia8, ia4, i8, i4, ci8, ci4, 1bpp", offset);
+ return std::nullopt;
+ }
if(!gTextureTypes.contains(format)) {
- return false;
+ return std::nullopt;
}
TextureType type = gTextureTypes.at(format);
- WRITE_HEADER(LUS::ResourceType::Texture, 0);
-
- WRITE_U32(type);
- WRITE_U32(width);
- WRITE_U32(height);
+ std::vector<uint8_t> result;
- if(data["mio0"]){
- auto mio0 = data["mio0"].as<size_t>();
- auto decoded = MIO0Decoder::Decode(buffer, offset);
- auto data = decoded.data() + mio0;
+ if(node["mio0"]){
+ auto mio0 = node["mio0"].as<size_t>();
+ auto decoded = MIO0Decoder::Decode(buffer, mio0);
+ auto data = decoded.data() + offset;
if(type == TextureType::GrayscaleAlpha1bpp){
- auto ia8 = alloc_ia8_text_from_i1((uint16_t*)data, 8, 16);
- WRITE_U32(8 * 16);
- WRITE_ARRAY(ia8, 8 * 16);
+ auto ia8 = alloc_ia8_text_from_i1((uint16_t*) data, 8, 16);
+ result = std::vector(ia8, ia8 + 8 * 16);
delete[] ia8;
- } else {
- WRITE_U32(size);
- WRITE_ARRAY(data, size);
}
- } else {
- WRITE_U32(size);
- WRITE_ARRAY(buffer.data() + offset, size);
- }
+
+ result = std::vector(data, data + size);
+ } else {
+ result = std::vector(buffer.data() + offset, buffer.data() + offset + size);
+ }
SPDLOG_INFO("Texture: {} {}x{} {}", format, width, height, size);
SPDLOG_INFO("Offset: {}", offset);
- SPDLOG_INFO("Has MIO0: {}", data["mio0"] ? "true" : "false");
+ SPDLOG_INFO("Has MIO0: {}", node["mio0"] ? "true" : "false");
+ SPDLOG_INFO("Size: {}", result.size());
+
+ if(result.size() == 0){
+ return std::nullopt;
+ }
- return true;
+ return std::make_shared<TextureData>(type, width, height, result);
}