summaryrefslogtreecommitdiff
path: root/src/Companion.cpp
blob: df793be9961e007bd7aef0e6de589c9b79e0e88a (plain)
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
#include "Companion.h"

#include "storm/SWrapper.h"
#include "utils/MIODecoder.h"
#include "audio/AudioManager.h"
#include "factories/RawFactory.h"
#include "factories/BlobFactory.h"
#include "factories/AudioFactory.h"
#include "factories/TextureFactory.h"
#include "factories/AnimFactory.h"

#include <fstream>
#include <iostream>
#include <filesystem>
#include <nlohmann/json.hpp>

using json = nlohmann::json;
namespace fs = std::filesystem;

static const std::unordered_map<std::string, RawFactory*> gFactories = {
    { ".png", new TextureFactory() },
    { ".anim", new AnimFactory() },
    { ".aiff", new AudioFactory() },
    { ".bnk", new AudioFactory() },
    { ".bset", new AudioFactory() },
    { ".m64", new AudioFactory() },
    { ".bin", new BlobFactory(LUS::ResourceType::Blob) },
    { ".sbox", new BlobFactory(LUS::ResourceType::Blob, true) },
};

void Companion::Start() {
    std::cout << "Super Mario 64 Rom Path: " << this->gRomPath << '\n';

    std::ifstream input( this->gRomPath, std::ios::binary );
    this->gRomData = std::vector<uint8_t>( std::istreambuf_iterator<char>( input ), {} );
    input.close();

    // TODO: Validate hash

    std::cout << "Detected Rom Size: " << this->gRomData.size() << '\n';

    AudioManager::Instance = new AudioManager();
    AudioManager::Instance->initialize(this->gRomData);

    this->ProcessAssets();
}

void Companion::ProcessAssets() {
    json assets = json::parse( std::ifstream( "assets.json" ) );

    SWrapper wrapper = SWrapper("smcube.otr");

    for( auto& [asset, data] : assets.items() ) {
        std::string extension = fs::path(asset).extension().string();
        if( gFactories.find(extension) == gFactories.end() ) {
             std::cout << "No factory found for " << asset << '\n';
            continue;
        }
        LUS::BinaryWriter write = LUS::BinaryWriter();
        std::string path = asset.substr(0, asset.find_last_of('.'));
        json entry = {
            { "path", path },
            { "offsets", data }
        };
        RawFactory* factory = gFactories.at(extension);

        if(!factory->process(&write, entry, this->gRomData)){
             std::cout << "Failed to process " << asset << '\n';
            continue;
        }

        bool isTexture = typeid(*factory) == typeid(TextureFactory);

        auto buffer = write.ToVector();
        // TODO: Change this that we all know its going to crash with other assets
        wrapper.CreateFile(isTexture ? path.substr(0, path.find_last_of('.')) : path, buffer);

        if(!isTexture) {
            // Write to file too
            std::string dpath = "debug/" + path;
            if(!fs::exists(fs::path(dpath).parent_path())){
                fs::create_directories(fs::path(dpath).parent_path());
            }
            std::ofstream output(dpath, std::ios::binary);
            output.write((char*)buffer.data(), buffer.size());
            output.close();
        }

         std::cout << "Processed " << path << std::endl;

        write.Close();
    }

    MIO0Decoder::ClearCache();
    wrapper.Close();
}