summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets.json10
-rw-r--r--sequences_table.h141
-rw-r--r--src/Companion.cpp14
-rw-r--r--src/factories/AudioFactory.cpp333
-rw-r--r--src/factories/AudioFactory.h9
-rw-r--r--src/factories/BlobFactory.cpp6
-rw-r--r--src/factories/RawFactory.h1
-rw-r--r--tools/m64test.js32
8 files changed, 534 insertions, 12 deletions
diff --git a/assets.json b/assets.json
index 2db3c3b..7ee9491 100644
--- a/assets.json
+++ b/assets.json
@@ -525,8 +525,6 @@
"actors/yoshi_egg/yoshi_egg_5_unused.rgba16.png": [32,32,2048,{"jp":[1215456,32696],"us":[1222624,32696],"eu":[1094592,32696],"sh":[1071104,32696]}],
"actors/yoshi_egg/yoshi_egg_6_unused.rgba16.png": [32,32,2048,{"jp":[1215456,34744],"us":[1222624,34744],"eu":[1094592,34744],"sh":[1071104,34744]}],
"actors/yoshi_egg/yoshi_egg_7_unused.rgba16.png": [32,32,2048,{"jp":[1215456,36792],"us":[1222624,36792],"eu":[1094592,36792],"sh":[1071104,36792]}],
-"sound/sequences.aud": [114432, { "us": [8063072] }],
-"sound/bank_sets.aud": [159, { "us": [8177185] }],
"assets/demos/bbh.bin": [988,{"jp":[5733368],"us":[5741664],"eu":[5620584],"sh":[5589632]}],
"assets/demos/bitdw.bin": [1412,{"us":[5747100],"sh":[5595068]}],
"assets/demos/ccm.bin": [1320,{"jp":[5734356],"us":[5742652],"eu":[5621572],"sh":[5590620]}],
@@ -1088,6 +1086,7 @@
"sound/sequences/sh/20_cutscene_ending.m64": [1887,{"sh":[7981824]}],
"sound/sequences/sh/21_menu_file_select.m64": [786,{"sh":[7983712]}],
"sound/sequences/sh/22_cutscene_lakitu.m64": [317,{"sh":[7984512]}],
+"sound/sequences/us/00_sound_player.m64": [13452,{"us":[8063360]}],
"sound/sequences/us/01_cutscene_collect_star.m64": [619,{"us":[8076816]}],
"sound/sequences/us/02_menu_title_screen.m64": [8254,{"us":[8077440]}],
"sound/sequences/us/03_level_grass.m64": [5122,{"us":[8085696]}],
@@ -1122,6 +1121,13 @@
"sound/sequences/us/20_cutscene_ending.m64": [1882,{"us":[8174192]}],
"sound/sequences/us/21_menu_file_select.m64": [781,{"us":[8176080]}],
"sound/sequences/us/22_cutscene_lakitu.m64": [313,{"us":[8176864]}],
+"@sound.aiff": {
+ "us": {
+ "bank_sets": [8177184, 160],
+ "sound_ctl": [5748512, 97856],
+ "sound_tbl": [5846368, 2216704]
+ }
+},
"textures/cave/hmc_textures.00000.rgba16.png": [32,64,4096,{"jp":[3432432,0],"us":[3439184,0],"eu":[3312784,0],"sh":[3287152,0]}],
"textures/cave/hmc_textures.01000.rgba16.png": [32,32,2048,{"jp":[3432432,4096],"us":[3439184,4096],"eu":[3312784,4096],"sh":[3287152,4096]}],
"textures/cave/hmc_textures.01800.rgba16.png": [32,64,4096,{"jp":[3432432,6144],"us":[3439184,6144],"eu":[3312784,6144],"sh":[3287152,6144]}],
diff --git a/sequences_table.h b/sequences_table.h
new file mode 100644
index 0000000..f252b20
--- /dev/null
+++ b/sequences_table.h
@@ -0,0 +1,141 @@
+#pragma once
+#include "align_asset_macro.h"
+
+#define dgSequence01 "__OTR__sound/sequences/01_cutscene_collect_star.m64"
+static const ALIGN_ASSET(2) char gSequence01[] = dgSequence01;
+
+#define dgSequence02 "__OTR__sound/sequences/02_menu_title_screen.m64"
+static const ALIGN_ASSET(2) char gSequence02[] = dgSequence02;
+
+#define dgSequence03 "__OTR__sound/sequences/03_level_grass.m64"
+static const ALIGN_ASSET(2) char gSequence03[] = dgSequence03;
+
+#define dgSequence04 "__OTR__sound/sequences/04_level_inside_castle.m64"
+static const ALIGN_ASSET(2) char gSequence04[] = dgSequence04;
+
+#define dgSequence05 "__OTR__sound/sequences/05_level_water.m64"
+static const ALIGN_ASSET(2) char gSequence05[] = dgSequence05;
+
+#define dgSequence06 "__OTR__sound/sequences/06_level_hot.m64"
+static const ALIGN_ASSET(2) char gSequence06[] = dgSequence06;
+
+#define dgSequence07 "__OTR__sound/sequences/07_level_boss_koopa.m64"
+static const ALIGN_ASSET(2) char gSequence07[] = dgSequence07;
+
+#define dgSequence08 "__OTR__sound/sequences/08_level_snow.m64"
+static const ALIGN_ASSET(2) char gSequence08[] = dgSequence08;
+
+#define dgSequence09 "__OTR__sound/sequences/09_level_slide.m64"
+static const ALIGN_ASSET(2) char gSequence09[] = dgSequence09;
+
+#define dgSequence0A "__OTR__sound/sequences/0A_level_spooky.m64"
+static const ALIGN_ASSET(2) char gSequence0A[] = dgSequence0A;
+
+#define dgSequence0B "__OTR__sound/sequences/0B_event_piranha_plant.m64"
+static const ALIGN_ASSET(2) char gSequence0B[] = dgSequence0B;
+
+#define dgSequence0C "__OTR__sound/sequences/0C_level_underground.m64"
+static const ALIGN_ASSET(2) char gSequence0C[] = dgSequence0C;
+
+#define dgSequence0D "__OTR__sound/sequences/0D_menu_star_select.m64"
+static const ALIGN_ASSET(2) char gSequence0D[] = dgSequence0D;
+
+#define dgSequence0E "__OTR__sound/sequences/0E_event_powerup.m64"
+static const ALIGN_ASSET(2) char gSequence0E[] = dgSequence0E;
+
+#define dgSequence0F "__OTR__sound/sequences/0F_event_metal_cap.m64"
+static const ALIGN_ASSET(2) char gSequence0F[] = dgSequence0F;
+
+#define dgSequence10 "__OTR__sound/sequences/10_event_koopa_message.m64"
+static const ALIGN_ASSET(2) char gSequence10[] = dgSequence10;
+
+#define dgSequence11 "__OTR__sound/sequences/11_level_koopa_road.m64"
+static const ALIGN_ASSET(2) char gSequence11[] = dgSequence11;
+
+#define dgSequence12 "__OTR__sound/sequences/12_event_high_score.m64"
+static const ALIGN_ASSET(2) char gSequence12[] = dgSequence12;
+
+#define dgSequence13 "__OTR__sound/sequences/13_event_merry_go_round.m64"
+static const ALIGN_ASSET(2) char gSequence13[] = dgSequence13;
+
+#define dgSequence14 "__OTR__sound/sequences/14_event_race.m64"
+static const ALIGN_ASSET(2) char gSequence14[] = dgSequence14;
+
+#define dgSequence15 "__OTR__sound/sequences/15_cutscene_star_spawn.m64"
+static const ALIGN_ASSET(2) char gSequence15[] = dgSequence15;
+
+#define dgSequence16 "__OTR__sound/sequences/16_event_boss.m64"
+static const ALIGN_ASSET(2) char gSequence16[] = dgSequence16;
+
+#define dgSequence17 "__OTR__sound/sequences/17_cutscene_collect_key.m64"
+static const ALIGN_ASSET(2) char gSequence17[] = dgSequence17;
+
+#define dgSequence18 "__OTR__sound/sequences/18_event_endless_stairs.m64"
+static const ALIGN_ASSET(2) char gSequence18[] = dgSequence18;
+
+#define dgSequence19 "__OTR__sound/sequences/19_level_boss_koopa_final.m64"
+static const ALIGN_ASSET(2) char gSequence19[] = dgSequence19;
+
+#define dgSequence1A "__OTR__sound/sequences/1A_cutscene_credits.m64"
+static const ALIGN_ASSET(2) char gSequence1A[] = dgSequence1A;
+
+#define dgSequence1B "__OTR__sound/sequences/1B_event_solve_puzzle.m64"
+static const ALIGN_ASSET(2) char gSequence1B[] = dgSequence1B;
+
+#define dgSequence1C "__OTR__sound/sequences/1C_event_toad_message.m64"
+static const ALIGN_ASSET(2) char gSequence1C[] = dgSequence1C;
+
+#define dgSequence1D "__OTR__sound/sequences/1D_event_peach_message.m64"
+static const ALIGN_ASSET(2) char gSequence1D[] = dgSequence1D;
+
+#define dgSequence1E "__OTR__sound/sequences/1E_cutscene_intro.m64"
+static const ALIGN_ASSET(2) char gSequence1E[] = dgSequence1E;
+
+#define dgSequence1F "__OTR__sound/sequences/1F_cutscene_victory.m64"
+static const ALIGN_ASSET(2) char gSequence1F[] = dgSequence1F;
+
+#define dgSequence20 "__OTR__sound/sequences/20_cutscene_ending.m64"
+static const ALIGN_ASSET(2) char gSequence20[] = dgSequence20;
+
+#define dgSequence21 "__OTR__sound/sequences/21_menu_file_select.m64"
+static const ALIGN_ASSET(2) char gSequence21[] = dgSequence21;
+
+#define dgSequence22 "__OTR__sound/sequences/22_cutscene_lakitu.m64"
+static const ALIGN_ASSET(2) char gSequence22[] = dgSequence22;
+
+static const char* gSequenceTable[] = {
+ gSequence01,
+ gSequence02,
+ gSequence03,
+ gSequence04,
+ gSequence05,
+ gSequence06,
+ gSequence07,
+ gSequence08,
+ gSequence09,
+ gSequence0A,
+ gSequence0B,
+ gSequence0C,
+ gSequence0D,
+ gSequence0E,
+ gSequence0F,
+ gSequence10,
+ gSequence11,
+ gSequence12,
+ gSequence13,
+ gSequence14,
+ gSequence15,
+ gSequence16,
+ gSequence17,
+ gSequence18,
+ gSequence19,
+ gSequence1A,
+ gSequence1B,
+ gSequence1C,
+ gSequence1D,
+ gSequence1E,
+ gSequence1F,
+ gSequence20,
+ gSequence21,
+ gSequence22,
+};
diff --git a/src/Companion.cpp b/src/Companion.cpp
index 16d6c11..218f018 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -4,6 +4,7 @@
#include "utils/MIODecoder.h"
#include "factories/RawFactory.h"
#include "factories/BlobFactory.h"
+#include "factories/AudioFactory.h"
#include "factories/TextureFactory.h"
#include "factories/AnimFactory.h"
@@ -18,9 +19,10 @@ namespace fs = std::filesystem;
static const std::unordered_map<std::string, RawFactory*> gFactories = {
{ ".png", new TextureFactory() },
{ ".anim", new AnimFactory() },
+ { ".aiff", new AudioFactory() },
{ ".bin", new BlobFactory(LUS::ResourceType::Blob) },
+ { ".m64", new BlobFactory(LUS::ResourceType::Blob) },
{ ".sbox", new BlobFactory(LUS::ResourceType::Blob, true) },
- { ".aud", new BlobFactory(LUS::ResourceType::Blob, false) },
};
void Companion::Start() {
@@ -45,7 +47,7 @@ void Companion::ProcessAssets() {
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';
+ // std::cout << "No factory found for " << asset << '\n';
continue;
}
LUS::BinaryWriter write = LUS::BinaryWriter();
@@ -57,7 +59,7 @@ void Companion::ProcessAssets() {
RawFactory* factory = gFactories.at(extension);
if(!factory->process(&write, entry, this->gRomData)){
- std::cout << "Failed to process " << asset << '\n';
+ // std::cout << "Failed to process " << asset << '\n';
continue;
}
@@ -70,13 +72,15 @@ void Companion::ProcessAssets() {
if(!isTexture) {
// Write to file too
std::string dpath = "debug/" + path;
- fs::create_directories(fs::path(dpath).parent_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;
+ // std::cout << "Processed " << path << std::endl;
write.Close();
}
diff --git a/src/factories/AudioFactory.cpp b/src/factories/AudioFactory.cpp
new file mode 100644
index 0000000..62ff3d3
--- /dev/null
+++ b/src/factories/AudioFactory.cpp
@@ -0,0 +1,333 @@
+#include "AudioFactory.h"
+
+#include <vector>
+#include <iostream>
+#include <filesystem>
+#include <sstream>
+#include "Companion.h"
+#include "utils/MIODecoder.h"
+#include "binarytools/BinaryReader.h"
+
+namespace fs = std::filesystem;
+
+#define NONE 0xFFFF
+
+std::unordered_map<std::string, uint32_t> nameTable;
+
+struct ALSeqData {
+ uint8_t *offset;
+ uint32_t len;
+};
+
+struct Entry {
+ uint32_t offset;
+ uint32_t length;
+};
+
+struct SampleBank {
+ std::string name;
+ uint32_t offset;
+ std::vector<uint8_t> data;
+};
+
+struct TBLFile {
+ std::vector<SampleBank> banks;
+ std::vector<std::string> tbls;
+ std::unordered_map<std::string, uint32_t> map;
+};
+
+struct CTLHeader {
+ uint32_t instruments;
+ uint32_t numDrums;
+ uint32_t shared;
+};
+
+struct Sound {
+ int32_t offset;
+ float tuning;
+};
+
+struct Bank {
+ std::string name;
+ SampleBank sampleBank;
+};
+
+struct Inst {
+ std::string name;
+ uint32_t offset;
+ uint8_t releaseRate;
+ uint8_t normalRangeLo;
+ uint8_t normalRangeHi;
+ int32_t envelope;
+ std::optional<Sound> soundLo;
+ std::optional<Sound> soundMed;
+ std::optional<Sound> soundHi;
+};
+
+struct Drum {
+ std::string name;
+ uint32_t offset;
+ uint8_t releaseRate;
+ uint8_t pan;
+ int32_t envelope;
+ Sound sound;
+};
+
+template<typename T>
+std::vector<T> slice(std::vector<T> const &v, uint32_t m, uint32_t n) {
+ auto first = v.cbegin() + m;
+ auto last = v.cbegin() + n;
+
+ std::vector<T> vec(first, last);
+ return vec;
+}
+
+std::vector<uint32_t> range(uint32_t start, uint32_t end) {
+ std::vector<uint32_t> result;
+ for (uint32_t i = start; i < end; ++i) {
+ result.push_back(i);
+ }
+ return result;
+}
+
+template <typename T1, typename T2, typename T3>
+std::vector<std::tuple<size_t, T2, T3>> zip(const std::vector<T1>& container1, const std::vector<T2>& container2, const std::vector<T3>& container3) {
+ std::vector<std::tuple<size_t, T2, T3>> result;
+
+ size_t minSize = std::min({container1.size(), container2.size(), container3.size()});
+
+ for (size_t i = 0; i < minSize; ++i) {
+ result.emplace_back(container1[i], container2[i], container3[i]);
+ }
+
+ return result;
+}
+
+std::vector<Entry> parseSeqFile(std::vector<uint8_t>& buffer, int32_t offset){
+ std::vector<Entry> entries;
+ LUS::BinaryReader reader((char*) buffer.data(), buffer.size());
+ reader.SetEndianness(LUS::Endianness::Big);
+ reader.Seek(offset, LUS::SeekOffsetType::Start);
+
+ uint16_t magic = reader.ReadUInt16();
+ uint16_t num_entries = reader.ReadUInt16();
+
+ for (int i = 0; i < num_entries; ++i) {
+ reader.Seek((offset + 4) + (i * 8), LUS::SeekOffsetType::Start);
+ entries.push_back({reader.ReadUInt32(), reader.ReadUInt32()});
+ }
+
+ reader.Close();
+ return entries;
+}
+
+CTLHeader parseCTLHeader(std::vector<uint8_t>& data){
+ LUS::BinaryReader reader((char*) data.data(), data.size());
+ reader.SetEndianness(LUS::Endianness::Big);
+
+ CTLHeader header = { reader.ReadUInt32(), reader.ReadUInt32(), reader.ReadUInt32() };
+
+ reader.Close();
+ return header;
+}
+
+std::string gen_name(const std::string& prefix){
+ if(!nameTable.contains(prefix)){
+ nameTable[prefix] = 0;
+ }
+ nameTable[prefix] += 1;
+ return prefix + "-" + std::to_string(nameTable[prefix]);
+}
+
+std::optional<Sound> parseSound(std::vector<uint8_t> data) {
+ LUS::BinaryReader reader((char*) data.data(), data.size());
+ reader.SetEndianness(LUS::Endianness::Big);
+
+ int32_t addr = reader.ReadInt32();
+ float tuning = reader.ReadFloat();
+
+ if(addr == 0){
+ assert(tuning == 0.0f);
+ return std::nullopt;
+ }
+
+ Sound sound = { addr, tuning };
+
+ reader.Close();
+ return sound;
+}
+
+Drum parseDrum(std::vector<uint8_t>& data, uint32_t addr) {
+ LUS::BinaryReader reader((char*) data.data(), data.size());
+ reader.SetEndianness(LUS::Endianness::Big);
+ std::string name = gen_name("drum");
+
+ uint8_t releaseRate = reader.ReadInt8();
+ uint8_t pan = reader.ReadInt8();
+
+ reader.Seek(12, LUS::SeekOffsetType::Start);
+ Sound sound = parseSound(slice(data, 4, 12)).value();
+ int32_t envOffset = reader.ReadInt32();
+ assert(envOffset != 0);
+
+ Drum drum = { name, addr, releaseRate, pan, envOffset, sound };
+
+ return drum;
+}
+
+Inst parseInst(std::vector<uint8_t>& data, uint32_t addr) {
+ std::string name = gen_name("inst");
+ char* rawData = (char*) data.data();
+ uint8_t normalRangeLo = data[1];
+ uint8_t normalRangeHi = data[2];
+ uint8_t releaseRate = data[3];
+
+ int32_t envAddr;
+ memcpy(&envAddr, rawData + 4, 4);
+ envAddr = BSWAP32(envAddr);
+
+ auto soundLo = parseSound(slice(data, 8, 16));
+ auto soundMed = parseSound(slice(data, 16, 24));
+ auto soundHi = parseSound(slice(data, 24, 32));
+
+ if (soundLo == std::nullopt) {
+ assert(normalRangeLo == 0);
+ }
+ if (soundHi == std::nullopt) {
+ assert(normalRangeHi == 127);
+ }
+
+ Inst inst = { name, addr, releaseRate, normalRangeLo, normalRangeHi, envAddr, soundLo, soundMed, soundHi };
+ return inst;
+}
+
+void parseCTL(CTLHeader header, std::vector<uint8_t>& data, SampleBank bank, uint32_t index) {
+ nameTable.clear();
+ std::ostringstream ss;
+ ss << std::hex << std::setw(2) << std::setfill('0') << index;
+ std::string name = ss.str();
+ uint32_t numInstruments = header.instruments;
+ uint32_t numDrums = header.numDrums;
+ char* rawData = (char*) data.data();
+
+ uint32_t drumBaseAddr;
+ memcpy(&drumBaseAddr, rawData, 4);
+ drumBaseAddr = BSWAP32(drumBaseAddr);
+
+ std::vector<uint32_t> drumOffsets;
+
+ if(numDrums != 0){
+ for (size_t i = 0; i < numDrums; ++i) {
+ uint32_t drumOffset;
+ memcpy(&drumOffset, rawData + drumBaseAddr + (i * 4), 4);
+ drumOffsets.push_back(BSWAP32(drumOffset));
+ }
+ }
+
+ uint32_t instrumentBaseAddr = 4;
+ std::vector<uint32_t> instrumentOffsets;
+ std::vector<uint32_t> instrumentList;
+
+ for (size_t i = 0; i < numInstruments; ++i) {
+ uint32_t instOffset;
+ memcpy(&instOffset, rawData + instrumentBaseAddr + (i * 4), 4);
+ instOffset = BSWAP32(instOffset);
+ if(instOffset == 0){
+ instrumentList.push_back(NONE);
+ } else {
+ instrumentOffsets.push_back(instOffset);
+ instrumentList.push_back(instOffset);
+ }
+ }
+
+ std::sort(instrumentOffsets.begin(), instrumentOffsets.end());
+
+ std::vector<Inst> insts;
+ for(auto &offset : instrumentOffsets){
+ auto rInst = slice(data, offset, offset + 32);
+ Inst inst = parseInst(rInst, offset);
+ insts.push_back(inst);
+ }
+
+ std::vector<Drum> drums;
+ for(auto &offset : drumOffsets){
+ auto rDrum = slice(data, offset, offset + 16);
+ Drum drum = parseDrum(rDrum, offset);
+ drums.push_back(drum);
+ }
+}
+
+TBLFile parseTBL(std::vector<uint8_t>& data, std::vector<Entry>& entries) {
+ TBLFile tbl;
+ std::unordered_map<uint32_t, std::string> cache;
+ for(auto &entry : entries){
+ if(!cache.contains(entry.offset)){
+ std::string name = gen_name("sample_bank");
+ tbl.banks.push_back({name, entry.offset, slice(data, entry.offset, entry.offset + entry.length)});
+ tbl.map[name] = tbl.banks.size() - 1;
+ cache[entry.offset] = name;
+ }
+ tbl.tbls.push_back(cache[entry.offset]);
+ }
+ cache.clear();
+ return tbl;
+}
+
+bool AudioFactory::process(LUS::BinaryWriter* writer, nlohmann::json& data, std::vector<uint8_t>& buffer) {
+ auto metadata = data["offsets"];
+ std::string path = data["path"];
+
+ if(path.find("@sound") != std::string::npos){
+ auto offsets = metadata["us"];
+ std::vector<Entry> tbl = parseSeqFile(buffer, offsets["sound_tbl"][0]);
+ std::vector<Entry> ctl = parseSeqFile(buffer, offsets["sound_ctl"][0]);
+
+ std::cout << "Table entries: " << tbl.size() << std::endl;
+ std::cout << "Control entries: " << ctl.size() << std::endl;
+
+ std::vector<uint8_t> tblData = slice(buffer, offsets["sound_tbl"][0], (size_t) offsets["sound_tbl"][0] + (size_t) offsets["sound_tbl"][1]);
+ std::vector<uint8_t> ctlData = slice(buffer, offsets["sound_ctl"][0], (size_t) offsets["sound_ctl"][0] + (size_t) offsets["sound_ctl"][1]);
+ TBLFile tblFile = parseTBL(tblData, tbl);
+
+ std::cout << "TBLs: " << tblFile.tbls.size() << std::endl;
+ std::cout << "Banks: " << tblFile.banks.size() << std::endl;
+ std::cout << "Map: " << tblFile.map.size() << std::endl;
+
+ auto zipped = zip(range(0, ctl.size()), ctl, tblFile.tbls);
+
+ for (const auto& item : zipped) {
+ auto [index, ctrl, sample_bank_name] = item;
+ auto sample_bank = tblFile.map[sample_bank_name];
+ auto entry = slice(ctlData, ctrl.offset, ctrl.offset + ctrl.length);
+ auto headerRaw = slice(entry, 0, 16);
+ auto header = parseCTLHeader(headerRaw);
+ std::cout << "Instruments: " << header.instruments << std::endl;
+ std::cout << "Drums: " << header.numDrums << std::endl;
+ }
+
+ exit(0);
+ }
+
+ if(path.find("bank_sets") != std::string::npos){
+ WRITE_HEADER(LUS::ResourceType::Blob, 0);
+ char* raw = (char*) (buffer.data() + metadata[1]["us"][0]);
+ WRITE_U32(metadata[0]);
+ for(int i = 0; i < 0x23; i++){
+ int16_t value;
+ memcpy(&value, raw + (i * 2), 2);
+ WRITE_I16(BSWAP16(value));
+ }
+ writer->Write(raw + 0x46, 0x5A);
+ }
+
+ if(path.find("sound_tbl") != std::string::npos){
+ // WRITE_HEADER(LUS::ResourceType::Blob, 0);
+ // std::vector<Entry> entries = parseSeqFile(buffer, metadata[1]["us"][0]);
+ // for(auto & entry : entries){
+ // std::cout << "Offset: " << entrie.offset << std::endl;
+ // std::cout << "Len: " << entrie.length << std::endl;
+ // }
+ }
+
+ return false;
+}
diff --git a/src/factories/AudioFactory.h b/src/factories/AudioFactory.h
new file mode 100644
index 0000000..fdfdb9c
--- /dev/null
+++ b/src/factories/AudioFactory.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "RawFactory.h"
+
+class AudioFactory : public RawFactory {
+public:
+ AudioFactory() = default;
+ bool process(LUS::BinaryWriter* write, nlohmann::json& data, std::vector<uint8_t>& buffer) override;
+}; \ No newline at end of file
diff --git a/src/factories/BlobFactory.cpp b/src/factories/BlobFactory.cpp
index 7071a45..30714b1 100644
--- a/src/factories/BlobFactory.cpp
+++ b/src/factories/BlobFactory.cpp
@@ -13,11 +13,7 @@ bool BlobFactory::process(LUS::BinaryWriter* writer, nlohmann::json& data, std::
return false;
}
- if(this->bigEndian){
- WRITE_BHEADER(this->type, 0);
- } else {
- WRITE_HEADER(this->type, 0);
- }
+ WRITE_HEADER(this->type, 0);
size_t size = metadata[0];
auto offsets = metadata[1]["us"];
diff --git a/src/factories/RawFactory.h b/src/factories/RawFactory.h
index 7057740..fe6ec98 100644
--- a/src/factories/RawFactory.h
+++ b/src/factories/RawFactory.h
@@ -11,6 +11,7 @@
#define WRITE_U16(value) writer->Write((uint16_t) value)
#define WRITE_U32(value) writer->Write((uint32_t) value)
#define WRITE_U64(value) writer->Write((uint64_t) value)
+#define WRITE_I8(value) writer->Write((int8_t) value)
#define WRITE_I16(value) writer->Write((int16_t) value)
#define WRITE_DATA(vec) writer->Write((char*) vec.data(), data.size())
#define WRITE_ARRAY(data, size) writer->Write((char*) data, size)
diff --git a/tools/m64test.js b/tools/m64test.js
new file mode 100644
index 0000000..0e4a6f3
--- /dev/null
+++ b/tools/m64test.js
@@ -0,0 +1,32 @@
+const fs = require('fs');
+
+const bytes = fs.readFileSync('./baserom.us.z64');
+const bpath = '../sound/sequences/us/'
+const header = [
+ '#pragma once',
+ '#include "align_asset_macro.h"',
+ '',
+]
+const sequences = []
+
+fs.readdirSync(bpath).forEach(seq => {
+ const seqData = fs.readFileSync(bpath+seq);
+ const seqOffset = bytes.indexOf(seqData);
+ const output = `sound/sequences/${seq}`
+ const seqId = seq.split("_")[0]
+ console.log(`"${output}": ${JSON.stringify([
+ seqData.length,
+ { "us": [ seqOffset ]}
+ ])},`);
+ sequences.push(`gSequence${seqId}`);
+ header.push(`#define dgSequence${seqId} "__OTR__${output}"`);
+ header.push(`static const ALIGN_ASSET(2) char gSequence${seqId}[] = dgSequence${seqId};\n`);
+});
+
+header.push('static const char* gSequenceTable[] = {');
+for (const seq of sequences.sort((a, b) => b.localeCompare(a))) {
+ header.push(` ${seq},`);
+}
+header.push('};\n');
+
+fs.writeFileSync('./sequences_table.h', header.join('\n')); \ No newline at end of file