forked from Gota7/SequenceConvert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBXSEQ.cs
135 lines (114 loc) · 3.85 KB
/
BXSEQ.cs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using GotaSequenceLib;
using GotaSoundIO;
using GotaSoundIO.IO;
using GotaSoundIO.Sound;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
namespace SequenceConvert {
/// <summary>
/// 3ds, Wii U, Switch.
/// </summary>
public class BXSEQ : SequenceFile {
/// <summary>
/// F type.
/// </summary>
public bool FType = true;
/// <summary>
/// If switch.
/// </summary>
public bool IsSwitch => FType && ByteOrder == ByteOrder.LittleEndian;
/// <summary>
/// Platform.
/// </summary>
/// <returns>Platform.</returns>
public override SequencePlatform Platform() => IsSwitch ? (SequencePlatform)new NX() : new CtrCafe();
/// <summary>
/// Read the file.
/// </summary>
/// <param name="r">The reader.</param>
public override void Read(FileReader r) {
//Open file.
FileHeader fileHeader;
r.OpenFile<XFileHeader>(out fileHeader);
ByteOrder = fileHeader.ByteOrder;
Version = fileHeader.Version;
FType = fileHeader.Magic.StartsWith("F");
//Data block.
uint dataSize;
r.OpenBlock(0, out _, out dataSize);
var data = r.ReadBytes((int)(dataSize - 8)).ToList();
//Remove padding.
for (int i = data.Count - 1; i >= 0; i--) {
if (data[i] == 0) {
data.RemoveAt(i);
} else {
break;
}
}
//Set data.
RawData = data.ToArray();
//Label block.
r.OpenBlock(1, out _, out _);
var labels = r.Read<Table<XReference<LabelEntry>>>().Select(x => x.Data);
Labels = new Dictionary<string, uint>();
foreach (var l in labels) {
Labels.Add(l.Str, l.Offset);
}
}
/// <summary>
/// Write the file.
/// </summary>
/// <param name="w">The writer.</param>
public override void Write(FileWriter w) {
//Init file.
w.InitFile<XFileHeader>(FType ? "FSEQ" : "CSEQ", ByteOrder, Version, 2);
//Data block.
w.InitBlock("DATA", blockType: 0x5000);
w.Write(RawData);
w.Align(0x20);
w.CloseBlock();
//Label block.
w.InitBlock("LABL", blockType: 0x5001);
w.Write((uint)Labels.Count);
for (int i = 0; i < Labels.Count; i++) {
w.InitReference<XReference<object>>("Labl" + i);
}
for (int i = 0; i < Labels.Count; i++) {
w.CloseReference("Labl" + i, 0x5100);
w.Write(new LabelEntry() { Offset = Labels.Values.ElementAt(i), Str = Labels.Keys.ElementAt(i) });
}
w.Align(0x20);
w.CloseBlock();
//Close file.
w.CloseFile();
}
/// <summary>
/// Label entry.
/// </summary>
private class LabelEntry : IReadable, IWritable {
public uint Offset;
public string Str;
public void Read(FileReader r) {
r.ReadUInt32();
Offset = r.ReadUInt32();
int strLen = r.ReadInt32();
Str = new string(r.ReadChars(strLen));
}
public void Write(FileWriter w) {
w.Write((ushort)0x1F00);
w.Write((ushort)0);
w.Write(Offset);
w.Write(Str.Length);
w.Write(Str.ToCharArray());
w.Write((byte)0);
w.Align(0x4);
}
}
}
}