Merge branch 'HarbourMasters:main' into read

This commit is contained in:
MegaMech
2023-09-22 19:38:48 -06:00
committed by GitHub
13 changed files with 1416 additions and 45 deletions
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -10,7 +10,9 @@
#include "factories/SampleFactory.h"
#include "factories/BankFactory.h"
#include "factories/TextureFactory.h"
#include "factories/AnimFactory.h"
#include "factories/sm64/SAnimFactory.h"
#include "factories/sm64/STextFactory.h"
#include "factories/sm64/SDialogFactory.h"
#include <fstream>
#include <iostream>
@@ -29,7 +31,9 @@ void Companion::Init() {
this->RegisterFactory("BLOB", new BlobFactory());
// SM64 Specific
this->RegisterFactory("SM64:ANIM", new AnimFactory());
this->RegisterFactory("SM64:DIALOG", new SDialogFactory());
this->RegisterFactory("SM64:ANIM", new SAnimFactory());
this->RegisterFactory("SM64:TEXT", new STextFactory());
// Debug
this->RegisterFactory("MIO0", new MIO0Factory());
+3
View File
@@ -6,6 +6,9 @@
#include <binarytools/BinaryWriter.h>
#include <yaml-cpp/yaml.h>
#define SEGMENT_OFFSET(a) ((uint32_t)(a)&0x00FFFFFF)
#define WRITE_HEADER(type, version) this->WriteHeader(writer, type, version)
#define WRITE_BHEADER(type, version) this->WriteHeader(writer, type, version, true)
#define WRITE_U8(value) writer->Write((uint8_t) value)
+4 -5
View File
@@ -14,13 +14,12 @@ enum class ResourceType {
Array = 0x4F415252, // OARR
Blob = 0x4F424C42, // OBLB
Texture = 0x4F544558, // OTEX
// CubeOS
Demo = 0x44454D4F, // DEMO
Skybox = 0x534B5942, // SKYB
Anim = 0x414E494D, // ANIM
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
// SM64
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
};
} // namespace LUS
-1
View File
@@ -1,6 +1,5 @@
#include "TextureFactory.h"
#include "Companion.h"
#include "utils/MIODecoder.h"
namespace fs = std::filesystem;
@@ -1,4 +1,4 @@
#include "AnimFactory.h"
#include "SAnimFactory.h"
#include <iostream>
#include <filesystem>
@@ -63,7 +63,7 @@ void WriteAnimationValues(LUS::BinaryWriter* writer, YAML::Node& data, std::vect
reader.Close();
}
bool AnimFactory::process(LUS::BinaryWriter* writer, YAML::Node& data, std::vector<uint8_t>& buffer) {
bool SAnimFactory::process(LUS::BinaryWriter* writer, YAML::Node& data, std::vector<uint8_t>& buffer) {
WRITE_HEADER(LUS::ResourceType::Anim, 0);
auto header = data["header"];
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "factories/RawFactory.h"
class SAnimFactory : public RawFactory {
public:
SAnimFactory() = default;
bool process(LUS::BinaryWriter* write, YAML::Node& data, std::vector<uint8_t>& buffer) override;
};
+65
View File
@@ -0,0 +1,65 @@
#include <iostream>
#include "SDialogFactory.h"
#include "utils/MIODecoder.h"
#include "binarytools/BinaryReader.h"
namespace fs = std::filesystem;
static size_t id = 0;
bool SDialogFactory::process(LUS::BinaryWriter* writer, YAML::Node& data, std::vector<uint8_t>& buffer) {
WRITE_HEADER(LUS::ResourceType::SDialog, 0);
auto offset = data["offset"].as<size_t>();
auto mio0 = data["mio0"].as<size_t>();
std::vector<uint8_t> text;
auto decoded = MIO0Decoder::Decode(buffer, offset);
auto bytes = (uint8_t*) decoded.data();
LUS::BinaryReader reader(decoded.data(), decoded.size());
reader.SetEndianness(LUS::Endianness::Big);
reader.Seek(mio0, LUS::SeekOffsetType::Start);
auto unused = reader.ReadUInt32();
auto linesPerBox = reader.ReadUByte();
// Padding
reader.Read(1);
auto leftOffset = reader.ReadInt16();
auto width = reader.ReadInt16();
// Padding
reader.Read(2);
auto str = SEGMENT_OFFSET(reader.ReadInt32());
while(bytes[str] != 0xFF){
auto c = bytes[str++];
text.push_back(c);
}
text.push_back(0xFF);
std::cout << "unused: " << unused << std::endl;
std::cout << "linesPerBox: " << (int) linesPerBox << std::endl;
std::cout << "leftOffset: " << leftOffset << std::endl;
std::cout << "width: " << width << std::endl;
std::cout << "size: " << text.size() << std::endl;
WRITE_U32(unused);
WRITE_I8(linesPerBox);
WRITE_I16(leftOffset);
WRITE_I16(width);
WRITE_U32(text.size());
WRITE_ARRAY(text.data(), text.size());
if(id == 85){
int bp = 0;
}
id++;
return true;
}
// seg2_dialog_table
// seg2_course_name_table
// seg2_act_name_table
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "../RawFactory.h"
class SDialogFactory : public RawFactory {
public:
SDialogFactory() = default;
bool process(LUS::BinaryWriter* write, YAML::Node& data, std::vector<uint8_t>& buffer) override;
};
+28
View File
@@ -0,0 +1,28 @@
#include "STextFactory.h"
#include "utils/MIODecoder.h"
namespace fs = std::filesystem;
bool STextFactory::process(LUS::BinaryWriter* writer, YAML::Node& data, std::vector<uint8_t>& buffer) {
WRITE_HEADER(LUS::ResourceType::Blob, 0);
auto offset = data["offset"].as<size_t>();
auto mio0 = data["mio0"].as<size_t>();
std::vector<uint8_t> text;
auto decoded = MIO0Decoder::Decode(buffer, offset);
auto bytes = (uint8_t*) decoded.data();
while(bytes[mio0] != 0xFF){
auto c = bytes[mio0++];
text.push_back(c);
}
text.push_back(0xFF);
WRITE_U32(text.size());
WRITE_ARRAY(text.data(), text.size());
return true;
}
@@ -1,9 +1,9 @@
#pragma once
#include "RawFactory.h"
#include "../RawFactory.h"
class AnimFactory : public RawFactory {
class STextFactory : public RawFactory {
public:
AnimFactory() = default;
STextFactory() = default;
bool process(LUS::BinaryWriter* write, YAML::Node& data, std::vector<uint8_t>& buffer) override;
};
+2 -2
View File
@@ -1,7 +1,7 @@
const fs = require('fs');
const bytes = fs.readFileSync('./baserom.eu.z64');
const file = fs.readFileSync('./00_sound_player_eu.m64');
const bytes = fs.readFileSync('./baserom.jp.z64');
const file = Buffer.from([0x8B,0xD5,0x71,0x98,0x55,0xF0,0x82,0x9F,0x7F,0xF0,0x45,0x40,0x67,0x5E,0x4D,0x6D,0xFF]);
const offset = bytes.indexOf(file);
const size = file.length;
+113 -30
View File
@@ -1,47 +1,130 @@
const fs = require('fs');
const path = require('path');
const YAML = require('./yaml/dist/index')
let _parent = 'assets/reordered';
let bytes = Buffer.alloc(0);
// https://hack64.net/wiki/doku.php?id=super_mario_64:mio0
// https://hack64.net/wiki/doku.php?id=super_mario_64:segment_2
function toHex(value) {
let hex = value.toString(16);
if ((hex.length % 2) > 0) {
hex = "0" + hex;
const version = 'us';
const roms = {
us: {
dialog: { start: 0x0FFC8, end: 0x10A68 },
level: { start: 0x10F68, end: 0x10FD4 },
act: { start: 0x1192C, end: 0x11AB4 },
}
return `0x${hex.toUpperCase()}`;
}
function toBEU16(num){
let d = new Uint16Array(1);
d[0] = num;
return Buffer.from(d.buffer).swap16()
function toYAML(obj){
let file = `${obj.file}`;
delete obj.file;
return YAML.stringify({
[file]: obj
});
}
async function parseAnim(file){
let fimport = `./${file.replace('.js', '')}`
let data = require(fimport)
for(let id of fimport.split('_').slice(1)){
let anim = data['anim_'+id];
let hOffset = bytes.indexOf(Buffer.concat(anim.slice(0, 6).map(toBEU16)));
function align16(num){
return (num + 0xF) & ~0xF;
}
let bswValues = Buffer.concat(anim[6].map(toBEU16));
let vsOffset = bytes.indexOf(bswValues);
let bswIndices = Buffer.concat(anim[7].map(toBEU16));
let idxOffset = bytes.indexOf(bswIndices);
console.log(`"assets/anims/anim_${id}.anim": ${JSON.stringify({
header: [hOffset, 0x18],
values: [vsOffset, bswValues.length],
indices: [idxOffset, bswIndices.length],
})},`);
function seg_offset(a){
return a & 0x00ffffff
}
function readEntry(bytes, offset){
let size = 0;
let unused = bytes.readUInt32BE(offset + size);
size += 4;
let linesPerBox = bytes.readInt8(offset + size);
size += 2;
let leftOffset = bytes.readInt16BE(offset + size);
size += 2;
let width = bytes.readInt16BE(offset + size);
size += 4;
let str = seg_offset(bytes.readInt32BE(offset + size));
size += 4;
let outText = []
while(bytes[str] != 0xFF){
let c = bytes[str];
outText.push(c);
str += 1;
}
outText.push(0xFF)
return {
unused,
linesPerBox,
leftOffset,
width,
text: Buffer.from(outText),
};
}
function findDialogs(bytes, out){
let { start, end } = roms[version].dialog;
let size = align16(end - start);
for(let i = 0; i < size; i += 16){
fs.appendFileSync(out, toYAML({
file: `dialogs/dialog_${(i / 16).toString(16).padStart(2, '0').toUpperCase()}`,
type: 'SM64:DIALOG',
offset: 0x108A40,
mio0: start + i
}));
console.log(i / 16, readEntry(bytes, start + i));
}
}
function readLevel(bytes, offset){
let outText = []
while(bytes[offset] != 0xFF){
let c = bytes[offset];
outText.push(c);
offset += 1;
}
outText.push(0xFF)
return Buffer.from(outText);
}
function findLevelNames(bytes, out) {
let { start, end } = roms[version].level;
let size = ((end - start) / 4) - 1;
console.log(size)
for(let i = 0; i < size; i++){
let offset = seg_offset(bytes.readUInt32BE(start + (i * 4)));
fs.appendFileSync(out, toYAML({
file: `courses/course_${(i).toString(16).padStart(2, '0').toUpperCase()}`,
type: 'SM64:TEXT',
offset: 0x108A40,
mio0: offset
}));
}
}
function findAct(bytes, out) {
let { start, end } = roms[version].act;
let size = ((end - start) / 4) - 1;
console.log(size)
for(let i = 0; i < size; i++){
let offset = seg_offset(bytes.readUInt32BE(start + (i * 4)));
fs.appendFileSync(out, toYAML({
file: `acts/act_${(i).toString(16).padStart(2, '0').toUpperCase()}`,
type: 'SM64:TEXT',
offset: 0x108A40,
mio0: offset
}));
}
}
async function main(){
bytes = fs.readFileSync('./baserom.us.z64');
let tst = [0x46,0x00,0x52,0x00,0x54,0x00,0x56,0x00,0x58,0x00,0x5a,0x00,0x5c,0x00,0x5e,0x00,0x60,0x00,0x62,0x00,0x64,0x00,0x67,0x00,0x69,0x00,0x6b,0x00,0x6d,0x00,0x6f,0x00,0x71,0x00,0x73,0x00,0x75,0x00,0x77,0x00,0x79,0x00,0x7b,0x00,0x7d,0x00,0x7f,0x00,0x81,0x00,0x83,0x00,0x85,0x00,0x87,0x00,0x89,0x00,0x8b,0x00,0x8d,0x00,0x8f,0x00,0x91,0x00,0x93,0x00,0x95,0x00,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x01,0x22,0x01,0x11,0x01,0x22,0x01,0x0e,0x01,0x13,0x01,0x0f,0x01,0x12,0x01,0x0b,0x01,0x0d,0x02,0x21,0x10,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x12,0x01,0x19,0x01,0x1f,0x01,0x21,0x01,0x1a,0x01,0x0e,0x01,0x1b,0x01,0x1a,0x01,0x1c,0x01,0x1d,0x01,0x25,0x01,0x14,0x01,0x20,0x01,0x1e,0x01,0x1b,0x01,0x1a,0x01,0x23,0x01,0x24,0x01,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
let text = Buffer.from(tst)
console.log(bytes.indexOf(text))
let bytes = fs.readFileSync('./debug/text/text/dump');
let output = path.join('assets/sm64/us', 'texts.yml');
fs.writeFileSync(output, '');
findDialogs(bytes, output);
findLevelNames(bytes, output);
findAct(bytes, output);
}
main();