NesHawk - cleanup Unif.cs
This commit is contained in:
parent
22f6df3a70
commit
01584431c4
|
@ -339,9 +339,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
unif = new Unif(new MemoryStream(file));
|
unif = new Unif(new MemoryStream(file));
|
||||||
LoadWriteLine("Found UNIF header:");
|
LoadWriteLine("Found UNIF header:");
|
||||||
LoadWriteLine(unif.CartInfo);
|
LoadWriteLine(unif.Cart);
|
||||||
LoadWriteLine("Since this is UNIF we can confidently parse PRG/CHR banks to hash.");
|
LoadWriteLine("Since this is UNIF we can confidently parse PRG/CHR banks to hash.");
|
||||||
hash_sha1 = unif.CartInfo.Sha1;
|
hash_sha1 = unif.Cart.Sha1;
|
||||||
hash_sha1_several.Add(hash_sha1);
|
hash_sha1_several.Add(hash_sha1);
|
||||||
LoadWriteLine("headerless rom hash: {0}", hash_sha1);
|
LoadWriteLine("headerless rom hash: {0}", hash_sha1);
|
||||||
}
|
}
|
||||||
|
@ -519,8 +519,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
}
|
}
|
||||||
else if (unif != null)
|
else if (unif != null)
|
||||||
{
|
{
|
||||||
if (choice.PrgSize == -1) choice.PrgSize = unif.CartInfo.PrgSize;
|
if (choice.PrgSize == -1) choice.PrgSize = unif.Cart.PrgSize;
|
||||||
if (choice.ChrSize == -1) choice.ChrSize = unif.CartInfo.ChrSize;
|
if (choice.ChrSize == -1) choice.ChrSize = unif.Cart.ChrSize;
|
||||||
// unif has no wram\vram sizes; hope the board impl can figure it out...
|
// unif has no wram\vram sizes; hope the board impl can figure it out...
|
||||||
if (choice.VramSize == -1) choice.VramSize = 0;
|
if (choice.VramSize == -1) choice.VramSize = 0;
|
||||||
if (choice.WramSize == -1) choice.WramSize = 0;
|
if (choice.WramSize == -1) choice.WramSize = 0;
|
||||||
|
@ -549,7 +549,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
if (unif != null)
|
if (unif != null)
|
||||||
{
|
{
|
||||||
LoadWriteLine("Using information from UNIF header");
|
LoadWriteLine("Using information from UNIF header");
|
||||||
choice = unif.CartInfo;
|
choice = unif.Cart;
|
||||||
//ok, i have this Q-Boy rom with no VROM and no VRAM.
|
//ok, i have this Q-Boy rom with no VROM and no VRAM.
|
||||||
//we also certainly have games with VROM and no VRAM.
|
//we also certainly have games with VROM and no VRAM.
|
||||||
//looks like FCEUX policy is to allocate 8KB of chr ram no matter what UNLESS certain flags are set. but what's the justification for this? please leave a note if you go debugging in it again.
|
//looks like FCEUX policy is to allocate 8KB of chr ram no matter what UNLESS certain flags are set. but what's the justification for this? please leave a note if you go debugging in it again.
|
||||||
|
@ -684,8 +684,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
}
|
}
|
||||||
else if (unif != null)
|
else if (unif != null)
|
||||||
{
|
{
|
||||||
Board.Rom = unif.PRG;
|
Board.Rom = unif.Prg;
|
||||||
Board.Vrom = unif.CHR;
|
Board.Vrom = unif.Chr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,101 +15,106 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Unif
|
public class Unif
|
||||||
{
|
{
|
||||||
CartInfo ci = new CartInfo();
|
private Dictionary<string, byte[]> Chunks { get; } = new Dictionary<string, byte[]>();
|
||||||
byte[] prgrom;
|
|
||||||
byte[] chrrom;
|
|
||||||
|
|
||||||
Dictionary<string, byte[]> chunks = new Dictionary<string, byte[]>();
|
private void TryAdd(Stream s, string key)
|
||||||
|
{
|
||||||
void TryAdd(Stream s, string key)
|
if (!Chunks.TryGetValue(key, out var data))
|
||||||
{
|
{
|
||||||
if (!chunks.TryGetValue(key, out var data))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s.Write(data, 0, data.Length);
|
s.Write(data, 0, data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unif(Stream s)
|
public Unif(Stream s)
|
||||||
{
|
{
|
||||||
BinaryReader br = new BinaryReader(s, Encoding.ASCII);
|
var br = new BinaryReader(s, Encoding.ASCII);
|
||||||
|
|
||||||
if (!Encoding.ASCII.GetBytes("UNIF").SequenceEqual(br.ReadBytes(4)))
|
if (!Encoding.ASCII.GetBytes("UNIF")
|
||||||
|
.SequenceEqual(br.ReadBytes(4)))
|
||||||
|
{
|
||||||
throw new Exception("Missing \"UNIF\" header mark!");
|
throw new Exception("Missing \"UNIF\" header mark!");
|
||||||
|
}
|
||||||
|
|
||||||
int ver = br.ReadInt32();
|
int ver = br.ReadInt32();
|
||||||
//if (ver != 7)
|
|
||||||
// throw new Exception($"Unknown UNIF version {ver}!");
|
|
||||||
Console.WriteLine("Processing Version {0} UNIF...", ver);
|
Console.WriteLine("Processing Version {0} UNIF...", ver);
|
||||||
br.ReadBytes(32 - 4 - 4);
|
br.ReadBytes(32 - 4 - 4);
|
||||||
|
|
||||||
while (br.PeekChar() > 0)
|
while (br.PeekChar() > 0)
|
||||||
{
|
{
|
||||||
string chunkid = Encoding.ASCII.GetString(br.ReadBytes(4));
|
string chunkId = Encoding.ASCII.GetString(br.ReadBytes(4));
|
||||||
int length = br.ReadInt32();
|
int length = br.ReadInt32();
|
||||||
byte[] chunkdata = br.ReadBytes(length);
|
byte[] chunkData = br.ReadBytes(length);
|
||||||
chunks.Add(chunkid, chunkdata);
|
Chunks.Add(chunkId, chunkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryStream prgs = new MemoryStream();
|
var prgs = new MemoryStream();
|
||||||
MemoryStream chrs = new MemoryStream();
|
var chrs = new MemoryStream();
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
TryAdd(prgs, $"PRG{i:X1}");
|
TryAdd(prgs, $"PRG{i:X1}");
|
||||||
TryAdd(chrs, $"CHR{i:X1}");
|
TryAdd(chrs, $"CHR{i:X1}");
|
||||||
}
|
}
|
||||||
|
|
||||||
prgs.Close();
|
prgs.Close();
|
||||||
chrs.Close();
|
chrs.Close();
|
||||||
prgrom = prgs.ToArray();
|
Prg = prgs.ToArray();
|
||||||
chrrom = chrs.ToArray();
|
Chr = chrs.ToArray();
|
||||||
|
|
||||||
ci.PrgSize = (short)(prgrom.Length / 1024);
|
Cart.PrgSize = (short)(Prg.Length / 1024);
|
||||||
ci.ChrSize = (short)(chrrom.Length / 1024);
|
Cart.ChrSize = (short)(Chr.Length / 1024);
|
||||||
|
|
||||||
if (chunks.TryGetValue("MIRR", out var tmp))
|
if (Chunks.TryGetValue("MIRR", out var tmp))
|
||||||
{
|
{
|
||||||
switch (tmp[0])
|
switch (tmp[0])
|
||||||
{
|
{
|
||||||
case 0: // hmirror
|
case 0: // h mirror
|
||||||
ci.PadH = 0;
|
Cart.PadH = 0;
|
||||||
ci.PadV = 1;
|
Cart.PadV = 1;
|
||||||
break;
|
break;
|
||||||
case 1: // vmirror
|
case 1: // v mirror
|
||||||
ci.PadH = 1;
|
Cart.PadH = 1;
|
||||||
ci.PadV = 0;
|
Cart.PadV = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunks.TryGetValue("MAPR", out tmp))
|
if (Chunks.TryGetValue("MAPR", out tmp))
|
||||||
{
|
{
|
||||||
ci.BoardType = new BinaryReader(new MemoryStream(tmp)).ReadStringUtf8NullTerminated();
|
Cart.BoardType = new BinaryReader(new MemoryStream(tmp)).ReadStringUtf8NullTerminated();
|
||||||
}
|
}
|
||||||
|
|
||||||
ci.BoardType = ci.BoardType.TrimEnd('\0');
|
Cart.BoardType = Cart.BoardType.TrimEnd('\0');
|
||||||
ci.BoardType = "UNIF_" + ci.BoardType;
|
Cart.BoardType = "UNIF_" + Cart.BoardType;
|
||||||
|
|
||||||
if (chunks.TryGetValue("BATR", out tmp))
|
if (Chunks.TryGetValue("BATR", out _))
|
||||||
{
|
{
|
||||||
// apparently, this chunk just existing means battery is yes
|
// apparently, this chunk just existing means battery is yes
|
||||||
ci.WramBattery = true;
|
Cart.WramBattery = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is there any way using System.Security.Cryptography.SHA1 to compute the hash of
|
// is there any way using System.Security.Cryptography.SHA1 to compute the hash of
|
||||||
// prg concatentated with chr? i couldn't figure it out, so this implementation is dumb
|
// prg concatenated with chr? i couldn't figure it out, so this implementation is dumb
|
||||||
{
|
{
|
||||||
MemoryStream ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
ms.Write(prgrom, 0, prgrom.Length);
|
ms.Write(Prg, 0, Prg.Length);
|
||||||
ms.Write(chrrom, 0, chrrom.Length);
|
ms.Write(Chr, 0, Chr.Length);
|
||||||
ms.Close();
|
ms.Close();
|
||||||
byte[] all = ms.ToArray();
|
var all = ms.ToArray();
|
||||||
ci.Sha1 = "sha1:" + all.HashSHA1(0, all.Length);
|
Cart.Sha1 = "sha1:" + all.HashSHA1(0, all.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// other code will expect this
|
// other code will expect this
|
||||||
if (chrrom.Length == 0)
|
if (Chr.Length == 0)
|
||||||
chrrom = null;
|
{
|
||||||
|
Chr = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CartInfo CartInfo => ci;
|
public CartInfo Cart { get; } = new CartInfo();
|
||||||
public byte[] PRG => prgrom;
|
public byte[] Prg { get; }
|
||||||
public byte[] CHR => chrrom;
|
public byte[] Chr { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,6 +533,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Underruns/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Underruns/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=undriven/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=undriven/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unflatten/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=unflatten/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unif/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Uninitialize/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Uninitialize/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unmerge/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=unmerge/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unparsable/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unparsable/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue