Skip to content

Commit 0127b80

Browse files
committed
Finished NARC support. Can now unpack ROMs, including NARCs, and append common file names.
1 parent 99adcce commit 0127b80

File tree

14 files changed

+206
-58
lines changed

14 files changed

+206
-58
lines changed

.vs/HASE/v14/.suo

1 KB
Binary file not shown.

HASE/FileScanner.cs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using System.Threading.Tasks;
8+
using System.Windows.Forms;
89

910
namespace HASE
1011
{
@@ -51,11 +52,11 @@ File Tables
5152
Overlays
5253
\*--------------------------*/
5354

54-
Folders.Add(new NDSFolder("\\Overlays", "Overlays", 0));
55+
Folders.Add(new NDSFolder("", "Overlays", 0));
5556

5657
for (int i = 0; i < fnt.FirstFile; i++)
5758
{
58-
fnt.Files[i].path = "\\Overlays\\Overlay " + i + ".bin";
59+
fnt.Files[i].path = "\\Overlays\\";
5960
fnt.Files[i].name = "Overlay " + i + ".bin";
6061
}
6162

@@ -96,15 +97,78 @@ NARC Files
9697

9798
foreach (NDSFile f in narcs)
9899
{
99-
NDSNARC narcFile = new NDSNARC(bytes, f);
100+
NDSNARC narcFile = new NDSNARC(bytes, f, debug);
101+
if (narcFile.isValid)
102+
{
103+
Folders.Add(new NDSFolder(f.path, f.name + ".narc", f.parent));
104+
Folders.AddRange(narcFile.fnt.Folders.ToList());
105+
Files.AddRange(narcFile.fnt.Files.ToList());
106+
}
107+
else
108+
{
109+
Files.Add(f);
110+
}
111+
}
112+
100113

101-
Folders.Add(new NDSFolder(f.path, f.name, f.parent));
114+
/*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*\
115+
Output Files
116+
\*--------------------------*/
117+
118+
foreach (NDSFolder folder in Folders)
119+
{
120+
// System.Console.WriteLine(path + folder.path + folder.name);
121+
Directory.CreateDirectory(path + folder.path + folder.name);
122+
}
123+
124+
foreach (NDSFile file in Files)
125+
{
126+
file.GetExtension(bytes);
127+
//System.Console.WriteLine(path + file.path + file.name + file.extension);
128+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + file.path + file.name + file.extension, FileMode.Create)))
129+
{
130+
writer.Write(bytes, file.offset, file.length);
131+
}
102132
}
103133

134+
DialogResult result = CustomMessageBox.Show(
135+
"Finished",
136+
"All files have been unpacked",
137+
"The ROM was successfully unpacked. Proceed to\n\n"
138+
+ path + "\n\nnto view your unpacked files.",
139+
475, 300,
140+
new List<string>(),
141+
new List<DialogResult>());
142+
143+
144+
/*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*\
145+
ARM7
146+
\*--------------------------*/
147+
148+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + "\\ARM7.bin", FileMode.Create)))
149+
{
150+
writer.Write(bytes, Convert.ToInt32(header.ARM7Offset), Convert.ToInt32(header.ARM7Length));
151+
}
104152

153+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + "\\ARM7 Overlay Table.bin", FileMode.Create)))
154+
{
155+
writer.Write(bytes, Convert.ToInt32(header.ARM7OverlayOffset), Convert.ToInt32(header.ARM7OverlayLength));
156+
}
105157

158+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + "\\ARM9.bin", FileMode.Create)))
159+
{
160+
writer.Write(bytes, Convert.ToInt32(header.ARM9Offset), Convert.ToInt32(header.ARM9Length));
161+
}
106162

163+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + "\\ARM9 Overlay Table.bin", FileMode.Create)))
164+
{
165+
writer.Write(bytes, Convert.ToInt32(header.ARM9OverlayOffset), Convert.ToInt32(header.ARM9OverlayLength));
166+
}
107167

168+
using (BinaryWriter writer = new BinaryWriter(File.Open(path + "\\Banner.banner", FileMode.Create)))
169+
{
170+
writer.Write(bytes, Convert.ToInt32(header.IconOffset), Convert.ToInt32(header.HeaderSize));
171+
}
108172
}
109173

110174
public List<NDSFolder> Folders = new List<NDSFolder>();

HASE/HASE.csproj.user

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
<ErrorReportUrlHistory />
1010
<FallbackCulture>en-US</FallbackCulture>
1111
<VerifyUploadedFiles>false</VerifyUploadedFiles>
12+
<ProjectView>ProjectFiles</ProjectView>
1213
</PropertyGroup>
1314
</Project>

HASE/NDSFAT.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ public NDSFAT (Stream stream, bool debug)
4747
);
4848
}
4949
}
50-
System.Console.WriteLine();
50+
if (debug)
51+
{
52+
System.Console.WriteLine();
53+
}
5154
}
5255
}
5356

HASE/NDSFNT.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ public NDSFNT(Stream table, string parentName, int fileCount, bool debug)
2525

2626
// Initialize the Folders list, setup the root folder, and give each folder a default name and path.
2727
Folders = new NDSFolder[FolderCount];
28-
Folders[0] = new NDSFolder("\\" + parentName, parentName, 0);
28+
Folders[0] = new NDSFolder("", parentName, 0);
2929
for (int i = 1; i < FolderCount; i++)
3030
{
3131
string digits = i.ToString("D" + FolderCount.ToString().Length);
3232

33-
Folders[i] = new NDSFolder(Folders[0].path + "\\" + digits, digits, 0);
33+
Folders[i] = new NDSFolder(Folders[0].name, digits, 0);
3434
}
3535

3636
// Initialize the Files list and give each file a default name and path.
@@ -39,7 +39,7 @@ public NDSFNT(Stream table, string parentName, int fileCount, bool debug)
3939
{
4040
string digits = i.ToString("D" + fileCount.ToString().Length);
4141

42-
Files[i] = new NDSFile(Folders[0].path + "\\" + digits, digits, 0);
42+
Files[i] = new NDSFile(Folders[0].name, digits, 0);
4343
}
4444

4545
// Initialize some arrays to keep track of offsets and first files for folders.
@@ -89,7 +89,7 @@ public NDSFNT(Stream table, string parentName, int fileCount, bool debug)
8989
reader.Read(nameArray, 0, entryName);
9090
string name = System.Text.Encoding.UTF8.GetString(nameArray);
9191

92-
Files[f] = new NDSFile(Folders[i].path + "\\" + name, name, i);
92+
Files[f] = new NDSFile(Folders[i].path + Folders[i].name, name, i);
9393
Folders[i].files.Add(f);
9494
f++;
9595
}
@@ -105,11 +105,11 @@ public NDSFNT(Stream table, string parentName, int fileCount, bool debug)
105105

106106
int subFolder = reader.ReadUInt16() - 61440;
107107

108-
Folders[subFolder] = new NDSFolder(Folders[i].path + "\\" + name, name, i);
108+
Folders[subFolder] = new NDSFolder(Folders[i].path + Folders[i].name, name, i);
109109
}
110110
}
111111
}
112-
112+
113113

114114
if (debug)
115115
{

HASE/NDSFile.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public NDSFolder(string p, string n, int i)
1919
path = p;
2020
name = n;
2121
parent = i;
22+
23+
if (p.Length < 1 || p.LastIndexOf("\\") != p.Length - 1)
24+
{
25+
path += "\\";
26+
}
2227
}
2328

2429
public string name;
@@ -40,6 +45,11 @@ public NDSFile(string p, string n, int i)
4045
path = p;
4146
name = n;
4247
parent = i;
48+
49+
if (p.Length < 1 || p.LastIndexOf("\\") != p.Length - 1)
50+
{
51+
path += "\\";
52+
}
4353
}
4454

4555
public void SetOffsets(uint start, uint end)
@@ -130,15 +140,14 @@ public void GetExtension(byte[] bytes)
130140
extension = ".txt";
131141
}
132142

133-
if (extension.Length > 0 && name.Length > extension.Length && path.Length > extension.Length)
143+
if (extension.Length > 0 && name.Length > extension.Length)
134144
{
135145
int nLength = name.Length - extension.Length;
136146
string nSub = name.Substring(nLength);
137147

138-
if (nSub != extension && nSub != extension.ToUpper())
148+
if (nSub == extension || nSub == extension.ToUpper())
139149
{
140-
name += extension;
141-
path += extension;
150+
name = name.Remove(nLength);
142151
}
143152
}
144153
}

HASE/NDSNARC.cs

Lines changed: 99 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,64 +10,139 @@ namespace HASE
1010
{
1111
class NDSNARC : BaseClass
1212
{
13-
public NDSNARC(byte[] bytes, NDSFile file)
13+
public bool isValid = false;
14+
15+
public NDSFAT fat;
16+
public NDSFNT fnt;
17+
18+
public NDSNARC(byte[] bytes, NDSFile file, bool debug)
1419
{
20+
string signature;
21+
uint fSize;
22+
ushort hSize;
23+
uint aSize;
24+
uint nSize;
25+
uint iSize;
26+
27+
int aOffset;
28+
int nOffset;
29+
int iOffset;
30+
1531
using (MemoryStream stream = new MemoryStream(bytes, file.offset, file.length))
1632
{
1733
using (BinaryReader reader = new BinaryReader(stream))
1834
{
19-
string signature = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(4));
35+
signature = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(4));
2036
ushort order = reader.ReadUInt16();
2137
ushort version = reader.ReadUInt16();
22-
uint size = reader.ReadUInt32();
23-
ushort header = reader.ReadUInt16();
24-
ushort count = reader.ReadUInt16();
38+
fSize = reader.ReadUInt32();
39+
hSize = reader.ReadUInt16();
40+
ushort blocks = reader.ReadUInt16();
2541

2642
if (signature != "NARC" ||
2743
order != 65534 ||
2844
version != 256 ||
29-
size != stream.Length ||
30-
header != 16 ||
31-
count != 3)
45+
fSize != stream.Length ||
46+
hSize != 16 ||
47+
blocks != 3 &&
48+
debug)
3249
{
3350
System.Console.WriteLine(file.name + " isn't a NARC or has a malformed header.\n" +
3451
"Signture: " + signature + " | NARC\n" +
3552
"Byte Order: " + order + " | 65534\n" +
3653
"Version: " + version + " | 256\n" +
37-
"File Size: " + size + " | " + stream.Length + "\n" +
38-
"Header Size: " + header + " | 16\n" +
39-
"blocks: " + count + " | 3");
54+
"File Size: " + fSize + " | " + stream.Length + "\n" +
55+
"Header Size: " + hSize + " | 16\n" +
56+
"blocks: " + blocks + " | 3");
4057
return;
4158
}
4259

4360
signature = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(4));
44-
size = reader.ReadUInt32();
45-
count = reader.ReadUInt16();
46-
header = reader.ReadUInt16();
61+
aSize = reader.ReadUInt32();
62+
ushort count = reader.ReadUInt16();
63+
ushort reserved = reader.ReadUInt16();
4764

4865
if (signature != "BTAF" ||
49-
size != ((count * 8) + 12) ||
50-
header != 0)
66+
aSize != ((count * 8) + 12) ||
67+
reserved != 0 &&
68+
debug)
5169
{
5270
System.Console.WriteLine(file.name + " has a malformed BTAF header.\n" +
5371
"Signture: " + signature + " | BTAF\n" +
5472
"File Count: " + count + "\n" +
55-
"Size: " + size + " | " + ((count * 8) + 12) + "\n" +
56-
"Reserved: " + header + " | 0\n");
73+
"Size: " + aSize + " | " + ((count * 8) + 12) + "\n" +
74+
"Reserved: " + reserved + " | 0\n");
5775
return;
5876
}
59-
6077

78+
reader.BaseStream.Position += aSize - 12;
79+
80+
signature = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(4));
81+
nSize = reader.ReadUInt32();
82+
83+
if (signature != "BTNF" && debug)
84+
{
85+
System.Console.WriteLine(file.name + " has a malformed BTNF header.\n" +
86+
"Signture: " + signature + " | BTNF\n" +
87+
"Size: " + nSize + "\n");
88+
return;
89+
}
90+
91+
reader.BaseStream.Position += nSize - 8;
92+
93+
signature = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(4));
94+
iSize = reader.ReadUInt32();
95+
96+
int tSize = Convert.ToInt32(hSize + aSize + nSize + iSize);
97+
98+
if (signature != "GMIF" && debug)
99+
{
100+
System.Console.WriteLine(file.name + " has a malformed GMIF header.\n" +
101+
"Signture: " + signature + " | GMIF\n" +
102+
"Size: " + iSize + "\n");
103+
return;
104+
}
105+
106+
if (tSize != fSize && debug)
107+
{
108+
System.Console.WriteLine(file.name + " total defined size doesn't equal file size." +
109+
"Total Defined Size: " + tSize + " | " + fSize + "\n");
110+
return;
111+
}
61112
}
62113
}
63-
64114

65-
using (MemoryStream stream = new MemoryStream(bytes, file.offset, file.length))
115+
aOffset = file.offset + 28;
116+
aSize -= 12;
117+
nOffset = Convert.ToInt32(aOffset + aSize + 8);
118+
nSize -= 8;
119+
iOffset = Convert.ToInt32(nOffset + nSize + 8);
120+
iSize -= 8;
121+
122+
using (MemoryStream memoryStream = new MemoryStream(bytes, aOffset, Convert.ToInt32(aSize)))
66123
{
67-
124+
fat = new NDSFAT(memoryStream, debug);
68125
}
69-
}
70126

71-
bool isValid = false;
127+
using (MemoryStream memoryStream = new MemoryStream(bytes, nOffset, Convert.ToInt32(nSize)))
128+
{
129+
fnt = new NDSFNT(memoryStream, (file.path + file.name + file.extension), Convert.ToInt32(fat.FileCount), debug);
130+
}
131+
132+
for (int i = 0; i < fat.FileCount; i++)
133+
{
134+
NDSFile f = fnt.Files[i];
135+
f.SetOffsets(Convert.ToUInt32(fat.FileStart[i] + iOffset), Convert.ToUInt32(fat.FileEnd[i] + iOffset));
136+
f.GetExtension(bytes);
137+
if (f.extension == ".narc" && debug)
138+
{
139+
System.Console.WriteLine("Why would you put an archive inside of an archive?\n" +
140+
"Yeah, I won't be unpacking that.\n" +
141+
"You want a recursive unpacker? Pfffft!");
142+
}
143+
}
144+
145+
isValid = true;
146+
}
72147
}
73148
}

0 commit comments

Comments
 (0)