Some mostly useless formatting and code cleanup in BizHawk.Common, broke some classes up into separate files
This commit is contained in:
parent
458d6951c0
commit
de084bf6fa
|
@ -123,7 +123,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public unsafe void Clear()
|
||||
{
|
||||
FromBitmap(false);
|
||||
Util.memset(PixelPtr, 0, Stride * Height);
|
||||
Util.Memset(PixelPtr, 0, Stride * Height);
|
||||
}
|
||||
|
||||
public Bitmap PeekBitmap()
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
namespace BizHawk.Common
|
||||
{
|
||||
public static class BitReverse
|
||||
{
|
||||
static BitReverse()
|
||||
{
|
||||
MakeByte8();
|
||||
}
|
||||
|
||||
public static byte[] Byte8;
|
||||
|
||||
public static uint Reverse32(uint v)
|
||||
{
|
||||
return (uint)((Byte8[v & 0xff] << 24) |
|
||||
(Byte8[(v >> 8) & 0xff] << 16) |
|
||||
(Byte8[(v >> 16) & 0xff] << 8) |
|
||||
(Byte8[(v >> 24) & 0xff]));
|
||||
}
|
||||
|
||||
private static void MakeByte8()
|
||||
{
|
||||
int bits = 8;
|
||||
const int n = 1 << 8;
|
||||
Byte8 = new byte[n];
|
||||
|
||||
int m = 1;
|
||||
int a = n >> 1;
|
||||
int j = 2;
|
||||
|
||||
Byte8[0] = 0;
|
||||
Byte8[1] = (byte)a;
|
||||
|
||||
while ((--bits) != 0)
|
||||
{
|
||||
m <<= 1;
|
||||
a >>= 1;
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
Byte8[j++] = (byte)(Byte8[i] + a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,7 +47,9 @@
|
|||
<Compile Include="..\VersionInfo.cs">
|
||||
<Link>VersionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="BitReverse.cs" />
|
||||
<Compile Include="Buffer.cs" />
|
||||
<Compile Include="Colors.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
<Compile Include="HawkFile.cs" />
|
||||
<Compile Include="IPC\IPCRingBuffer.cs" />
|
||||
|
@ -57,6 +59,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\svnrev.cs" />
|
||||
<Compile Include="QuickCollections.cs" />
|
||||
<Compile Include="Serializer.cs" />
|
||||
<Compile Include="SwitcherStream.cs" />
|
||||
<Compile Include="Types.cs" />
|
||||
<Compile Include="UndoHistory.cs" />
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace BizHawk.Common
|
|||
this.Hnd = GCHandle.Alloc(this.Arr, GCHandleType.Pinned);
|
||||
this.Ptr = this.Hnd.AddrOfPinnedObject().ToPointer();
|
||||
this.Byteptr = (byte*)this.Ptr;
|
||||
Util.memset(this.Byteptr, 0, this.Len * itemsize);
|
||||
Util.Memset(this.Byteptr, 0, this.Len * itemsize);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
namespace BizHawk.Common
|
||||
{
|
||||
public static class Colors
|
||||
{
|
||||
public static int ARGB(byte red, byte green, byte blue)
|
||||
{
|
||||
return (int)((uint)((red << 0x10) | (green << 8) | blue | (0xFF << 0x18)));
|
||||
}
|
||||
|
||||
public static int ARGB(byte red, byte green, byte blue, byte alpha)
|
||||
{
|
||||
return (int)((uint)((red << 0x10) | (green << 8) | blue | (alpha << 0x18)));
|
||||
}
|
||||
|
||||
public static int Luminosity(byte lum)
|
||||
{
|
||||
return (int)((uint)((lum << 0x10) | (lum << 8) | lum | (0xFF << 0x18)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,942 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public unsafe class Serializer
|
||||
{
|
||||
public Serializer() { }
|
||||
|
||||
#region Public
|
||||
|
||||
public bool IsReader
|
||||
{
|
||||
get { return _isReader; }
|
||||
}
|
||||
|
||||
public bool IsWriter
|
||||
{
|
||||
get { return !IsReader; }
|
||||
}
|
||||
|
||||
public bool IsText
|
||||
{
|
||||
get { return _isText; }
|
||||
}
|
||||
|
||||
public BinaryReader BinaryReader
|
||||
{
|
||||
get { return _br; }
|
||||
}
|
||||
|
||||
public BinaryWriter BinaryWriter
|
||||
{
|
||||
get { return _bw; }
|
||||
}
|
||||
|
||||
public TextReader TextReader
|
||||
{
|
||||
get { return _tr; }
|
||||
}
|
||||
|
||||
public TextWriter TextWriter
|
||||
{
|
||||
get { return _tw; }
|
||||
}
|
||||
|
||||
public Serializer(BinaryWriter bw)
|
||||
{
|
||||
StartWrite(bw);
|
||||
}
|
||||
|
||||
public Serializer(BinaryReader br)
|
||||
{
|
||||
StartRead(br);
|
||||
}
|
||||
|
||||
public Serializer(TextWriter tw)
|
||||
{
|
||||
StartWrite(tw);
|
||||
}
|
||||
|
||||
public Serializer(TextReader tr)
|
||||
{
|
||||
StartRead(tr);
|
||||
}
|
||||
|
||||
public static Serializer CreateBinaryWriter(BinaryWriter bw)
|
||||
{
|
||||
return new Serializer(bw);
|
||||
}
|
||||
|
||||
public static Serializer CreateBinaryReader(BinaryReader br)
|
||||
{
|
||||
return new Serializer(br);
|
||||
}
|
||||
|
||||
public static Serializer CreateTextWriter(TextWriter tw)
|
||||
{
|
||||
return new Serializer(tw);
|
||||
}
|
||||
|
||||
public static Serializer CreateTextReader(TextReader tr)
|
||||
{
|
||||
return new Serializer(tr);
|
||||
}
|
||||
|
||||
public void StartWrite(BinaryWriter bw)
|
||||
{
|
||||
_bw = bw;
|
||||
_isReader = false;
|
||||
}
|
||||
|
||||
public void StartRead(BinaryReader br)
|
||||
{
|
||||
_br = br;
|
||||
_isReader = true;
|
||||
}
|
||||
|
||||
public void StartWrite(TextWriter tw)
|
||||
{
|
||||
_tw = tw;
|
||||
_isReader = false;
|
||||
_isText = true;
|
||||
}
|
||||
|
||||
public void StartRead(TextReader tr)
|
||||
{
|
||||
_tr = tr;
|
||||
_isReader = true;
|
||||
_isText = true;
|
||||
BeginTextBlock();
|
||||
}
|
||||
|
||||
public void BeginSection(string name)
|
||||
{
|
||||
this._sections.Push(name);
|
||||
if (IsText)
|
||||
{
|
||||
if (IsWriter)
|
||||
{
|
||||
_tw.WriteLine("[{0}]", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sectionStack.Push(_currSection);
|
||||
_currSection = _currSection[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EndSection()
|
||||
{
|
||||
var name = this._sections.Pop();
|
||||
if (IsText)
|
||||
{
|
||||
if (IsWriter)
|
||||
{
|
||||
_tw.WriteLine("[/{0}]", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currSection = _sectionStack.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncEnum<T>(string name, ref T val) where T : struct
|
||||
{
|
||||
if (typeof(T).BaseType != typeof(Enum))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
else if (_isText)
|
||||
{
|
||||
SyncEnumText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = (T)Enum.ToObject(typeof(T), _br.ReadInt32());
|
||||
}
|
||||
else
|
||||
{
|
||||
_bw.Write(Convert.ToInt32(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncEnumText<T>(string name, ref T val) where T : struct
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = (T)Enum.Parse(typeof(T), Item(name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tw.WriteLine("{0} {1}", name, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref ByteBuffer byteBuf)
|
||||
{
|
||||
SyncBuffer(name, 1, byteBuf.Len, byteBuf.Ptr);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref IntBuffer byteBuf)
|
||||
{
|
||||
SyncBuffer(name, 4, byteBuf.Len, byteBuf.Ptr);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref byte[] val, bool useNull)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val, useNull);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ReadByteBuffer(_br, useNull);
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.WriteByteBuffer(_bw, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref byte[] val, bool useNull)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = Util.HexStringToBytes(Item(name));
|
||||
}
|
||||
|
||||
if (val != null && val.Length == 0 && useNull)
|
||||
{
|
||||
val = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = val ?? new byte[0];
|
||||
_tw.WriteLine("{0} {1}", name, Util.BytesToHexString(temp));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref short[] val, bool useNull)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val, useNull);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToShortBuffer(Util.ReadByteBuffer(_br, false));
|
||||
if (val == null && !useNull)
|
||||
{
|
||||
val = new short[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.WriteByteBuffer(_bw, Util.ShortBufferToByteBuffer(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref short[] val, bool useNull)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
var bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToShortBuffer(bytes);
|
||||
}
|
||||
|
||||
if (val != null && val.Length == 0 && useNull)
|
||||
{
|
||||
val = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = val ?? new short[0];
|
||||
_tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.ShortBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref int[] val, bool useNull)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val, useNull);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToIntBuffer(Util.ReadByteBuffer(_br, false));
|
||||
if (val == null && !useNull)
|
||||
{
|
||||
val = new int[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.WriteByteBuffer(_bw, Util.IntBufferToByteBuffer(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref int[] val, bool useNull)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
var bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToIntBuffer(bytes);
|
||||
}
|
||||
|
||||
if (val != null && val.Length == 0 && useNull)
|
||||
{
|
||||
val = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = val ?? new int[0];
|
||||
_tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.IntBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref uint[] val, bool useNull)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val, useNull);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToUintBuffer(Util.ReadByteBuffer(_br, false));
|
||||
if (val == null && !useNull)
|
||||
{
|
||||
val = new uint[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.WriteByteBuffer(_bw, Util.UintBufferToByteBuffer(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref uint[] val, bool useNull)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
var bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToUintBuffer(bytes);
|
||||
}
|
||||
|
||||
if (val != null && val.Length == 0 && useNull)
|
||||
{
|
||||
val = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = val ?? new uint[0];
|
||||
_tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.UintBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref Bit val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref Bit val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref byte val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref ushort val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref uint val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref sbyte val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref short val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref int val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref bool val)
|
||||
{
|
||||
if (IsText)
|
||||
{
|
||||
SyncText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
Read(ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(ref val);
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncFixedString(string name, ref string val, int length)
|
||||
{
|
||||
// TODO - this could be made more efficient perhaps just by writing values right out of the string..
|
||||
if (IsReader)
|
||||
{
|
||||
var buf = new char[length];
|
||||
if (_isText)
|
||||
{
|
||||
_tr.Read(buf, 0, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
_br.Read(buf, 0, length);
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
for (; len < length; len++)
|
||||
{
|
||||
if (buf[len] == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
val = new string(buf, 0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name.Length > length)
|
||||
{
|
||||
throw new InvalidOperationException("SyncFixedString too long");
|
||||
}
|
||||
|
||||
var buf = val.ToCharArray();
|
||||
var remainder = new char[length - buf.Length];
|
||||
if (IsText)
|
||||
{
|
||||
_tw.Write(buf);
|
||||
_tw.Write(remainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bw.Write(buf);
|
||||
_bw.Write(remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Privates
|
||||
|
||||
private BinaryReader _br;
|
||||
private BinaryWriter _bw;
|
||||
private TextReader _tr;
|
||||
private TextWriter _tw;
|
||||
|
||||
private bool _isText;
|
||||
private bool _isReader;
|
||||
private readonly Stack<string> _sections = new Stack<string>();
|
||||
private Section _readerSection, _currSection;
|
||||
private readonly Stack<Section> _sectionStack = new Stack<Section>();
|
||||
|
||||
private void BeginTextBlock()
|
||||
{
|
||||
if (!IsText || IsWriter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_readerSection = new Section();
|
||||
var ss = new Stack<Section>();
|
||||
ss.Push(_readerSection);
|
||||
var curs = _readerSection;
|
||||
|
||||
var rxEnd = new System.Text.RegularExpressions.Regex(@"\[/(.*?)\]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
var rxBegin = new System.Text.RegularExpressions.Regex(@"\[(.*?)\]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
|
||||
// read the entire file into a data structure for flexi-parsing
|
||||
string str;
|
||||
while ((str = _tr.ReadLine()) != null)
|
||||
{
|
||||
var end = rxEnd.Match(str);
|
||||
var begin = rxBegin.Match(str);
|
||||
if (end.Success)
|
||||
{
|
||||
var name = end.Groups[1].Value;
|
||||
if (name != curs.Name)
|
||||
{
|
||||
throw new InvalidOperationException("Mis-formed savestate blob");
|
||||
}
|
||||
|
||||
curs = ss.Pop();
|
||||
|
||||
// consume no data past the end of the last proper section
|
||||
if (curs == _readerSection)
|
||||
{
|
||||
_currSection = curs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (begin.Success)
|
||||
{
|
||||
var name = begin.Groups[1].Value;
|
||||
ss.Push(curs);
|
||||
var news = new Section { Name = name };
|
||||
if (!curs.ContainsKey(name))
|
||||
{
|
||||
curs[name] = news;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("Duplicate key \"{0}\" in serializer savestate!", name));
|
||||
}
|
||||
|
||||
curs = news;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add to current section
|
||||
if (str.Trim().Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var parts = str.Split(' ');
|
||||
var key = parts[0];
|
||||
|
||||
// UGLY: adds whole string instead of splitting the key. later, split the key, and have the individual Sync methods give up that responsibility
|
||||
if (!curs.Items.ContainsKey(key))
|
||||
{
|
||||
curs.Items[key] = parts[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("Duplicate key \"{0}\" in serializer savestate!", key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_currSection = _readerSection;
|
||||
}
|
||||
|
||||
private string Item(string key)
|
||||
{
|
||||
return _currSection.Items[key];
|
||||
}
|
||||
|
||||
private bool Present(string key)
|
||||
{
|
||||
return _currSection.Items.ContainsKey(key);
|
||||
}
|
||||
|
||||
private void SyncBuffer(string name, int elemsize, int len, void* ptr)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
byte[] temp = null;
|
||||
Sync(name, ref temp, false);
|
||||
int todo = Math.Min(temp.Length, len * elemsize);
|
||||
System.Runtime.InteropServices.Marshal.Copy(temp, 0, new IntPtr(ptr), todo);
|
||||
}
|
||||
else
|
||||
{
|
||||
int todo = len * elemsize;
|
||||
var temp = new byte[todo];
|
||||
System.Runtime.InteropServices.Marshal.Copy(new IntPtr(ptr), temp, 0, todo);
|
||||
Sync(name, ref temp, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref byte val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref ushort val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref uint val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref sbyte val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref short val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref int val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref bool val)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
ReadText(name, ref val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteText(name, ref val);
|
||||
}
|
||||
}
|
||||
|
||||
private void Read(ref Bit val)
|
||||
{
|
||||
val = _br.ReadBit();
|
||||
}
|
||||
|
||||
private void Write(ref Bit val)
|
||||
{
|
||||
_bw.WriteBit(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref Bit val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = int.Parse(this.Item(name));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref Bit val)
|
||||
{
|
||||
_tw.WriteLine("{0} {1}", name, (int)val);
|
||||
}
|
||||
|
||||
private void Read(ref byte val)
|
||||
{
|
||||
val = _br.ReadByte();
|
||||
}
|
||||
|
||||
private void Write(ref byte val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref byte val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = byte.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
private void WriteText(string name, ref byte val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X2}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref ushort val)
|
||||
{
|
||||
val = _br.ReadUInt16();
|
||||
}
|
||||
|
||||
private void Write(ref ushort val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref ushort val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = ushort.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref ushort val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X4}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref uint val)
|
||||
{
|
||||
{ val = _br.ReadUInt32(); }
|
||||
}
|
||||
|
||||
private void Write(ref uint val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref uint val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = uint.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref uint val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X8}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref sbyte val)
|
||||
{
|
||||
val = _br.ReadSByte();
|
||||
}
|
||||
|
||||
private void Write(ref sbyte val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref sbyte val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = sbyte.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref sbyte val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X2}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref short val)
|
||||
{
|
||||
val = _br.ReadInt16();
|
||||
}
|
||||
|
||||
private void Write(ref short val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref short val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = short.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref short val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X4}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref int val)
|
||||
{
|
||||
val = _br.ReadInt32();
|
||||
}
|
||||
|
||||
private void Write(ref int val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref int val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = int.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteText(string name, ref int val)
|
||||
{
|
||||
_tw.WriteLine("{0} 0x{1:X8}", name, val);
|
||||
}
|
||||
|
||||
private void Read(ref bool val)
|
||||
{
|
||||
val = _br.ReadBoolean();
|
||||
}
|
||||
|
||||
private void Write(ref bool val)
|
||||
{
|
||||
_bw.Write(val);
|
||||
}
|
||||
|
||||
private void ReadText(string name, ref bool val)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
val = bool.Parse(Item(name));
|
||||
}
|
||||
}
|
||||
private void WriteText(string name, ref bool val)
|
||||
{
|
||||
_tw.WriteLine("{0} {1}", name, val);
|
||||
}
|
||||
|
||||
private class Section : Dictionary<string, Section>
|
||||
{
|
||||
public string Name = String.Empty;
|
||||
public readonly Dictionary<string, string> Items = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
@ -9,30 +8,14 @@ using System.Text;
|
|||
|
||||
namespace BizHawk.Common
|
||||
{
|
||||
public static class Colors
|
||||
public static unsafe class Util
|
||||
{
|
||||
public static int ARGB(byte red, byte green, byte blue)
|
||||
{
|
||||
return (int)((uint)((red << 0x10) | (green << 8) | blue | (0xFF << 0x18)));
|
||||
}
|
||||
|
||||
public static int ARGB(byte red, byte green, byte blue, byte alpha)
|
||||
{
|
||||
return (int)((uint)((red << 0x10) | (green << 8) | blue | (alpha << 0x18)));
|
||||
}
|
||||
|
||||
public static int Luminosity(byte lum)
|
||||
{
|
||||
return (int)((uint)((lum << 0x10) | (lum << 8) | lum | (0xFF << 0x18)));
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe static class Util
|
||||
{
|
||||
static readonly char[] HexConvArr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
static System.Runtime.InteropServices.GCHandle HexConvHandle;
|
||||
public static char* HexConvPtr;
|
||||
static unsafe Util()
|
||||
private static readonly char[] HexConvArr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
private static System.Runtime.InteropServices.GCHandle HexConvHandle;
|
||||
|
||||
public static char* HexConvPtr { get; set; }
|
||||
|
||||
static Util()
|
||||
{
|
||||
HexConvHandle = System.Runtime.InteropServices.GCHandle.Alloc(HexConvArr, System.Runtime.InteropServices.GCHandleType.Pinned);
|
||||
HexConvPtr = (char*)HexConvHandle.AddrOfPinnedObject().ToPointer();
|
||||
|
@ -67,42 +50,58 @@ namespace BizHawk.Common
|
|||
|
||||
public static bool IsPowerOfTwo(int x)
|
||||
{
|
||||
if (x == 0) return true;
|
||||
if (x == 1) return true;
|
||||
if (x == 0 || x == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
public static int SaveRamBytesUsed(byte[] SaveRAM)
|
||||
public static int SaveRamBytesUsed(byte[] saveRam)
|
||||
{
|
||||
for (int j = SaveRAM.Length - 1; j >= 0; j--)
|
||||
if (SaveRAM[j] != 0)
|
||||
for (int j = saveRam.Length - 1; j >= 0; j--)
|
||||
{
|
||||
if (saveRam[j] != 0)
|
||||
{
|
||||
return j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read bytes from a BinaryReader and translate them into the UTF-8 string they represent.
|
||||
public static string ReadStringFixedAscii(this BinaryReader r, int bytes)
|
||||
{
|
||||
byte[] read = new byte[bytes];
|
||||
var read = new byte[bytes];
|
||||
for (int b = 0; b < bytes; b++)
|
||||
{
|
||||
read[b] = r.ReadByte();
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(read);
|
||||
}
|
||||
|
||||
public static string ReadStringAsciiZ(this BinaryReader r)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (; ; )
|
||||
var sb = new StringBuilder();
|
||||
for (;;)
|
||||
{
|
||||
int b = r.ReadByte();
|
||||
if (b <= 0) break;
|
||||
if (b <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sb.Append((char)b);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// conerts bytes to an uppercase string of hex numbers in upper case without any spacing or anything
|
||||
/// Converts bytes to an uppercase string of hex numbers in upper case without any spacing or anything
|
||||
/// //could be extension method
|
||||
/// </summary>
|
||||
public static string BytesToHexString(byte[] bytes)
|
||||
|
@ -116,34 +115,54 @@ namespace BizHawk.Common
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
//could be extension method
|
||||
// Could be extension method
|
||||
public static byte[] HexStringToBytes(string str)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
if (str.Length % 2 != 0) throw new ArgumentException();
|
||||
var ms = new MemoryStream();
|
||||
if (str.Length % 2 != 0)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
int len = str.Length / 2;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
int d = 0;
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
char c = char.ToLower(str[i * 2 + j]);
|
||||
var c = char.ToLower(str[i * 2 + j]);
|
||||
if (c >= '0' && c <= '9')
|
||||
d += (c - '0');
|
||||
{
|
||||
d += c - '0';
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
d += (c - 'a') + 10;
|
||||
else throw new ArgumentException();
|
||||
if (j == 0) d <<= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
d <<= 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ms.WriteByte((byte)d);
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
//could be extension method
|
||||
// Could be extension method
|
||||
public static void WriteByteBuffer(BinaryWriter bw, byte[] data)
|
||||
{
|
||||
if (data == null) bw.Write(0);
|
||||
if (data == null)
|
||||
{
|
||||
bw.Write(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write(data.Length);
|
||||
|
@ -154,41 +173,44 @@ namespace BizHawk.Common
|
|||
public static short[] ByteBufferToShortBuffer(byte[] buf)
|
||||
{
|
||||
int num = buf.Length / 2;
|
||||
short[] ret = new short[num];
|
||||
var ret = new short[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i] = (short)(buf[i * 2] | (buf[i * 2 + 1] << 8));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] ShortBufferToByteBuffer(short[] buf)
|
||||
{
|
||||
int num = buf.Length;
|
||||
byte[] ret = new byte[num * 2];
|
||||
var ret = new byte[num * 2];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i * 2 + 0] = (byte)(buf[i] & 0xFF);
|
||||
ret[i * 2 + 1] = (byte)((buf[i] >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static uint[] ByteBufferToUintBuffer(byte[] buf)
|
||||
{
|
||||
int num = buf.Length / 4;
|
||||
uint[] ret = new uint[num];
|
||||
var ret = new uint[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i] = (uint)(buf[i * 4] | (buf[i * 4 + 1] << 8) | (buf[i * 4 + 2] << 16) | (buf[i * 4 + 3] << 24));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] UintBufferToByteBuffer(uint[] buf)
|
||||
{
|
||||
int num = buf.Length;
|
||||
byte[] ret = new byte[num * 4];
|
||||
var ret = new byte[num * 4];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i * 4 + 0] = (byte)(buf[i] & 0xFF);
|
||||
|
@ -196,13 +218,14 @@ namespace BizHawk.Common
|
|||
ret[i * 4 + 2] = (byte)((buf[i] >> 16) & 0xFF);
|
||||
ret[i * 4 + 3] = (byte)((buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int[] ByteBufferToIntBuffer(byte[] buf)
|
||||
{
|
||||
int num = buf.Length / 4;
|
||||
int[] ret = new int[num];
|
||||
var ret = new int[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i] = buf[(i * 4) + 3];
|
||||
|
@ -213,13 +236,14 @@ namespace BizHawk.Common
|
|||
ret[i] <<= 8;
|
||||
ret[i] |= buf[(i * 4)];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] IntBufferToByteBuffer(int[] buf)
|
||||
{
|
||||
int num = buf.Length;
|
||||
byte[] ret = new byte[num * 4];
|
||||
var ret = new byte[num * 4];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ret[i * 4 + 0] = (byte)(buf[i] & 0xFF);
|
||||
|
@ -227,14 +251,19 @@ namespace BizHawk.Common
|
|||
ret[i * 4 + 2] = (byte)((buf[i] >> 16) & 0xFF);
|
||||
ret[i * 4 + 3] = (byte)((buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] ReadByteBuffer(BinaryReader br, bool return_null)
|
||||
public static byte[] ReadByteBuffer(BinaryReader br, bool returnNull)
|
||||
{
|
||||
int len = br.ReadInt32();
|
||||
if (len == 0 && return_null) return null;
|
||||
byte[] ret = new byte[len];
|
||||
if (len == 0 && returnNull)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ret = new byte[len];
|
||||
int ofs = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
|
@ -242,49 +271,58 @@ namespace BizHawk.Common
|
|||
ofs += done;
|
||||
len -= done;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static unsafe int memcmp(void* a, string b, int len)
|
||||
public static int Memcmp(void* a, string b, int len)
|
||||
{
|
||||
fixed (byte* bp = Encoding.ASCII.GetBytes(b))
|
||||
return memcmp(a, bp, len);
|
||||
return Memcmp(a, bp, len);
|
||||
}
|
||||
|
||||
public static unsafe int memcmp(void* a, void* b, int len)
|
||||
public static int Memcmp(void* a, void* b, int len)
|
||||
{
|
||||
byte* ba = (byte*)a;
|
||||
byte* bb = (byte*)b;
|
||||
var ba = (byte*)a;
|
||||
var bb = (byte*)b;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
byte _a = ba[i];
|
||||
byte _b = bb[i];
|
||||
int c = _a - _b;
|
||||
if (c != 0) return c;
|
||||
if (c != 0)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static unsafe void memset(void* ptr, int val, int len)
|
||||
public static void Memset(void* ptr, int val, int len)
|
||||
{
|
||||
byte* bptr = (byte*)ptr;
|
||||
var bptr = (byte*)ptr;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
bptr[i] = (byte)val;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void memset32(void* ptr, int val, int len)
|
||||
public static void Memset32(void* ptr, int val, int len)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(len % 4 == 0);
|
||||
int dwords = len / 4;
|
||||
int* dwptr = (int*)ptr;
|
||||
for (int i = 0; i < dwords; i++)
|
||||
{
|
||||
dwptr[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(Stream stream)
|
||||
{
|
||||
const int BUFF_SIZE = 4096;
|
||||
byte[] buffer = new byte[BUFF_SIZE];
|
||||
var buffer = new byte[BUFF_SIZE];
|
||||
|
||||
int bytesRead = 0;
|
||||
var inStream = new BufferedStream(stream);
|
||||
|
@ -337,541 +375,11 @@ namespace BizHawk.Common
|
|||
suffix = " B";
|
||||
}
|
||||
|
||||
string precision = "2";
|
||||
var precision = "2";
|
||||
return String.Format("{0:N" + precision + "}{1}", size, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe class Serializer
|
||||
{
|
||||
BinaryReader br;
|
||||
BinaryWriter bw;
|
||||
TextReader tr;
|
||||
TextWriter tw;
|
||||
public BinaryReader BinaryReader { get { return br; } }
|
||||
public BinaryWriter BinaryWriter { get { return bw; } }
|
||||
public TextReader TextReader { get { return tr; } }
|
||||
public TextWriter TextWriter { get { return tw; } }
|
||||
public Serializer() { }
|
||||
public Serializer(BinaryWriter _bw) { StartWrite(_bw); }
|
||||
public Serializer(BinaryReader _br) { StartRead(_br); }
|
||||
public Serializer(TextWriter _tw) { StartWrite(_tw); }
|
||||
public Serializer(TextReader _tr) { StartRead(_tr); }
|
||||
public static Serializer CreateBinaryWriter(BinaryWriter _bw) { return new Serializer(_bw); }
|
||||
public static Serializer CreateBinaryReader(BinaryReader _br) { return new Serializer(_br); }
|
||||
public static Serializer CreateTextWriter(TextWriter _tw) { return new Serializer(_tw); }
|
||||
public static Serializer CreateTextReader(TextReader _tr) { return new Serializer(_tr); }
|
||||
public void StartWrite(BinaryWriter _bw) { bw = _bw; isReader = false; }
|
||||
public void StartRead(BinaryReader _br) { br = _br; isReader = true; }
|
||||
public void StartWrite(TextWriter _tw) { tw = _tw; isReader = false; isText = true; }
|
||||
public void StartRead(TextReader _tr)
|
||||
{
|
||||
tr = _tr;
|
||||
isReader = true;
|
||||
isText = true;
|
||||
BeginTextBlock();
|
||||
}
|
||||
|
||||
public bool IsReader { get { return isReader; } }
|
||||
public bool IsWriter { get { return !IsReader; } }
|
||||
public bool IsText { get { return isText; } }
|
||||
bool isText;
|
||||
bool isReader;
|
||||
|
||||
readonly Stack<string> sections = new Stack<string>();
|
||||
|
||||
class Section : Dictionary<string, Section>
|
||||
{
|
||||
public string Name = String.Empty;
|
||||
public readonly Dictionary<string, string> Items = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
private Section ReaderSection, CurrSection;
|
||||
private readonly Stack<Section> SectionStack = new Stack<Section>();
|
||||
|
||||
void BeginTextBlock()
|
||||
{
|
||||
if (!IsText) return;
|
||||
if (IsWriter) return;
|
||||
|
||||
ReaderSection = new Section();
|
||||
Stack<Section> ss = new Stack<Section>();
|
||||
ss.Push(ReaderSection);
|
||||
Section curs = ReaderSection;
|
||||
|
||||
var rxEnd = new System.Text.RegularExpressions.Regex(@"\[/(.*?)\]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
var rxBegin = new System.Text.RegularExpressions.Regex(@"\[(.*?)\]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
|
||||
//read the entire file into a data structure for flexi-parsing
|
||||
string str;
|
||||
while ((str = tr.ReadLine()) != null)
|
||||
{
|
||||
var end = rxEnd.Match(str);
|
||||
var begin = rxBegin.Match(str);
|
||||
if (end.Success)
|
||||
{
|
||||
string name = end.Groups[1].Value;
|
||||
if (name != curs.Name) throw new InvalidOperationException("Mis-formed savestate blob");
|
||||
curs = ss.Pop();
|
||||
// consume no data past the end of the last proper section
|
||||
if (curs == ReaderSection)
|
||||
{
|
||||
CurrSection = curs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (begin.Success)
|
||||
{
|
||||
string name = begin.Groups[1].Value;
|
||||
ss.Push(curs);
|
||||
var news = new Section {Name = name};
|
||||
if (!curs.ContainsKey(name))
|
||||
{
|
||||
curs[name] = news;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(string.Format("Duplicate key \"{0}\" in serializer savestate!", name));
|
||||
}
|
||||
curs = news;
|
||||
}
|
||||
else
|
||||
{
|
||||
//add to current section
|
||||
if (str.Trim().Length == 0) continue;
|
||||
var parts = str.Split(' ');
|
||||
var key = parts[0];
|
||||
//UGLY: adds whole string instead of splitting the key. later, split the key, and have the individual Sync methods give up that responsibility
|
||||
if (!curs.Items.ContainsKey(key))
|
||||
curs.Items[key] = parts[1];
|
||||
else
|
||||
throw new Exception(string.Format("Duplicate key \"{0}\" in serializer savestate!", key));
|
||||
}
|
||||
}
|
||||
|
||||
CurrSection = ReaderSection;
|
||||
}
|
||||
|
||||
public void BeginSection(string name)
|
||||
{
|
||||
sections.Push(name);
|
||||
if (IsText)
|
||||
if (IsWriter) { tw.WriteLine("[{0}]", name); }
|
||||
else
|
||||
{
|
||||
SectionStack.Push(CurrSection);
|
||||
CurrSection = CurrSection[name];
|
||||
}
|
||||
}
|
||||
|
||||
public void EndSection()
|
||||
{
|
||||
string name = sections.Pop();
|
||||
if (IsText)
|
||||
{
|
||||
if (IsWriter)
|
||||
{
|
||||
tw.WriteLine("[/{0}]", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrSection = SectionStack.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string Item(string key)
|
||||
{
|
||||
return CurrSection.Items[key];
|
||||
}
|
||||
|
||||
bool Present(string key)
|
||||
{
|
||||
return CurrSection.Items.ContainsKey(key);
|
||||
}
|
||||
|
||||
public void SyncEnum<T>(string name, ref T val) where T : struct
|
||||
{
|
||||
if (typeof (T).BaseType != typeof (Enum))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
else if (isText)
|
||||
{
|
||||
SyncEnumText(name, ref val);
|
||||
}
|
||||
else if (IsReader)
|
||||
{
|
||||
val = (T) Enum.ToObject(typeof (T), br.ReadInt32());
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write(Convert.ToInt32(val));
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncEnumText<T>(string name, ref T val) where T : struct
|
||||
{
|
||||
if (IsReader) { if (Present(name)) val = (T)Enum.Parse(typeof(T), Item(name)); }
|
||||
else tw.WriteLine("{0} {1}", name, val.ToString());
|
||||
}
|
||||
|
||||
void SyncBuffer(string name, int elemsize, int len, void* ptr)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
byte[] temp = null;
|
||||
Sync(name, ref temp, false);
|
||||
int todo = Math.Min(temp.Length, len * elemsize);
|
||||
System.Runtime.InteropServices.Marshal.Copy(temp, 0, new IntPtr(ptr), todo);
|
||||
}
|
||||
else
|
||||
{
|
||||
int todo = len * elemsize;
|
||||
byte[] temp = new byte[todo];
|
||||
System.Runtime.InteropServices.Marshal.Copy(new IntPtr(ptr), temp, 0, todo);
|
||||
Sync(name, ref temp, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref ByteBuffer byteBuf)
|
||||
{
|
||||
SyncBuffer(name, 1, byteBuf.Len, byteBuf.Ptr);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref IntBuffer byteBuf)
|
||||
{
|
||||
SyncBuffer(name, 4, byteBuf.Len, byteBuf.Ptr);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref byte[] val, bool use_null)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val, use_null);
|
||||
else if (IsReader) val = Util.ReadByteBuffer(br, use_null);
|
||||
else Util.WriteByteBuffer(bw, val);
|
||||
}
|
||||
public void SyncText(string name, ref byte[] val, bool use_null)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name)) val = Util.HexStringToBytes(Item(name));
|
||||
if (val != null && val.Length == 0 && use_null) val = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] temp = val ?? new byte[0];
|
||||
tw.WriteLine("{0} {1}", name, Util.BytesToHexString(temp));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref short[] val, bool use_null)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val, use_null);
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToShortBuffer(Util.ReadByteBuffer(br, false));
|
||||
if (val == null && !use_null) val = new short[0];
|
||||
}
|
||||
else Util.WriteByteBuffer(bw, Util.ShortBufferToByteBuffer(val));
|
||||
}
|
||||
public void SyncText(string name, ref short[] val, bool use_null)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
byte[] bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToShortBuffer(bytes);
|
||||
}
|
||||
if (val != null && val.Length == 0 && use_null) val = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
short[] temp = val ?? new short[0];
|
||||
tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.ShortBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref int[] val, bool use_null)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val, use_null);
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToIntBuffer(Util.ReadByteBuffer(br, false));
|
||||
if (val == null && !use_null) val = new int[0];
|
||||
}
|
||||
else Util.WriteByteBuffer(bw, Util.IntBufferToByteBuffer(val));
|
||||
}
|
||||
public void SyncText(string name, ref int[] val, bool use_null)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
byte[] bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToIntBuffer(bytes);
|
||||
}
|
||||
if (val != null && val.Length == 0 && use_null) val = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
int[] temp = val ?? new int[0];
|
||||
tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.IntBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref uint[] val, bool use_null)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val, use_null);
|
||||
else if (IsReader)
|
||||
{
|
||||
val = Util.ByteBufferToUintBuffer(Util.ReadByteBuffer(br, false));
|
||||
if (val == null && !use_null) val = new uint[0];
|
||||
}
|
||||
else Util.WriteByteBuffer(bw, Util.UintBufferToByteBuffer(val));
|
||||
}
|
||||
public void SyncText(string name, ref uint[] val, bool use_null)
|
||||
{
|
||||
if (IsReader)
|
||||
{
|
||||
if (Present(name))
|
||||
{
|
||||
byte[] bytes = Util.HexStringToBytes(Item(name));
|
||||
val = Util.ByteBufferToUintBuffer(bytes);
|
||||
}
|
||||
if (val != null && val.Length == 0 && use_null) val = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint[] temp = val ?? new uint[0];
|
||||
tw.WriteLine("{0} {1}", name, Util.BytesToHexString(Util.UintBufferToByteBuffer(temp)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Sync(string name, ref Bit val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
public void SyncText(string name, ref Bit val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref byte val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref byte val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref ushort val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref ushort val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref uint val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref uint val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref sbyte val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref sbyte val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref short val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref short val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref int val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref int val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void Sync(string name, ref bool val)
|
||||
{
|
||||
if (IsText) SyncText(name, ref val);
|
||||
else if (IsReader) Read(ref val);
|
||||
else Write(ref val);
|
||||
}
|
||||
|
||||
private void SyncText(string name, ref bool val)
|
||||
{
|
||||
if (IsReader) ReadText(name, ref val);
|
||||
else WriteText(name, ref val);
|
||||
}
|
||||
|
||||
public void SyncFixedString(string name, ref string val, int length)
|
||||
{
|
||||
//TODO - this could be made more efficient perhaps just by writing values right out of the string..
|
||||
|
||||
if (IsReader)
|
||||
{
|
||||
char[] buf = new char[length];
|
||||
if (isText)
|
||||
{
|
||||
tr.Read(buf, 0, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
br.Read(buf, 0, length);
|
||||
}
|
||||
int len = 0;
|
||||
for (; len < length; len++)
|
||||
{
|
||||
if (buf[len] == 0) break;
|
||||
}
|
||||
val = new string(buf, 0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name.Length > length) throw new InvalidOperationException("SyncFixedString too long");
|
||||
char[] buf = val.ToCharArray();
|
||||
char[] remainder = new char[length - buf.Length];
|
||||
if (IsText)
|
||||
{
|
||||
tw.Write(buf);
|
||||
tw.Write(remainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write(buf);
|
||||
bw.Write(remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Read(ref Bit val) { val = br.ReadBit(); }
|
||||
private void Write(ref Bit val) { bw.WriteBit(val); }
|
||||
private void ReadText(string name, ref Bit val) { if (Present(name)) val = (Bit)int.Parse(Item(name)); }
|
||||
private void WriteText(string name, ref Bit val) { tw.WriteLine("{0} {1}", name, (int)val); }
|
||||
|
||||
private void Read(ref byte val) { val = br.ReadByte(); }
|
||||
private void Write(ref byte val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref byte val) { if (Present(name)) val = byte.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref byte val) { tw.WriteLine("{0} 0x{1:X2}", name, val); }
|
||||
|
||||
private void Read(ref ushort val) { val = br.ReadUInt16(); }
|
||||
private void Write(ref ushort val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref ushort val) { if (Present(name)) val = ushort.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref ushort val) { tw.WriteLine("{0} 0x{1:X4}", name, val); }
|
||||
|
||||
private void Read(ref uint val) { val = br.ReadUInt32(); }
|
||||
private void Write(ref uint val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref uint val) { if (Present(name)) val = uint.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref uint val) { tw.WriteLine("{0} 0x{1:X8}", name, val); }
|
||||
|
||||
private void Read(ref sbyte val) { val = br.ReadSByte(); }
|
||||
private void Write(ref sbyte val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref sbyte val) { if (Present(name)) val = sbyte.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref sbyte val) { tw.WriteLine("{0} 0x{1:X2}", name, val); }
|
||||
|
||||
private void Read(ref short val) { val = br.ReadInt16(); }
|
||||
private void Write(ref short val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref short val) { if (Present(name)) val = short.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref short val) { tw.WriteLine("{0} 0x{1:X4}", name, val); }
|
||||
|
||||
private void Read(ref int val) { val = br.ReadInt32(); }
|
||||
private void Write(ref int val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref int val) { if (Present(name)) val = int.Parse(Item(name).Replace("0x", ""), NumberStyles.HexNumber); }
|
||||
private void WriteText(string name, ref int val) { tw.WriteLine("{0} 0x{1:X8}", name, val); }
|
||||
|
||||
private void Read(ref bool val) { val = br.ReadBoolean(); }
|
||||
private void Write(ref bool val) { bw.Write(val); }
|
||||
private void ReadText(string name, ref bool val) { if (Present(name)) val = bool.Parse(Item(name)); }
|
||||
private void WriteText(string name, ref bool val) { tw.WriteLine("{0} {1}", name, val); }
|
||||
}
|
||||
|
||||
|
||||
public static class Bitrev
|
||||
{
|
||||
public static byte[] byte_8;
|
||||
static Bitrev()
|
||||
{
|
||||
make_byte_8();
|
||||
}
|
||||
static void make_byte_8()
|
||||
{
|
||||
int bits = 8;
|
||||
const int n = 1 << 8;
|
||||
byte_8 = new byte[n];
|
||||
|
||||
int m = 1;
|
||||
int a = n >> 1;
|
||||
int j = 2;
|
||||
|
||||
byte_8[0] = 0;
|
||||
byte_8[1] = (byte)a;
|
||||
|
||||
while ((--bits) != 0)
|
||||
{
|
||||
m <<= 1;
|
||||
a >>= 1;
|
||||
for (int i = 0; i < m; i++)
|
||||
byte_8[j++] = (byte)(byte_8[i] + a);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint reverse_32(uint v)
|
||||
{
|
||||
return (uint)((byte_8[v & 0xff] << 24) |
|
||||
(byte_8[(v >> 8) & 0xff] << 16) |
|
||||
(byte_8[(v >> 16) & 0xff] << 8) |
|
||||
(byte_8[(v >> 24) & 0xff]));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// a Dictionary-of-lists with key K and values List<V>
|
||||
/// </summary>
|
||||
|
@ -898,9 +406,13 @@ namespace BizHawk.Common
|
|||
{
|
||||
V temp;
|
||||
if (!TryGetValue(key, out temp))
|
||||
{
|
||||
temp = this[key] = new V();
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
base[key] = value;
|
||||
|
@ -941,7 +453,7 @@ namespace BizHawk.Common
|
|||
public IEnumerable KeyValuePairEnumerator { get { return dictionary; } }
|
||||
|
||||
/// <summary>
|
||||
/// the list of keys contained herein
|
||||
/// Gets the list of keys contained herein
|
||||
/// </summary>
|
||||
public IList<K> Keys { get { return new List<K>(dictionary.Keys); } }
|
||||
|
||||
|
@ -951,9 +463,13 @@ namespace BizHawk.Common
|
|||
{
|
||||
L slot;
|
||||
if (!dictionary.TryGetValue(key, out slot))
|
||||
{
|
||||
dictionary[key] = slot = new L();
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
dictionary[key] = value;
|
||||
|
@ -966,23 +482,25 @@ namespace BizHawk.Common
|
|||
{
|
||||
}
|
||||
|
||||
class SuperGloballyUniqueID
|
||||
internal class SuperGloballyUniqueID
|
||||
{
|
||||
public static string Next()
|
||||
{
|
||||
int myctr;
|
||||
lock (typeof(SuperGloballyUniqueID))
|
||||
{
|
||||
myctr = ctr++;
|
||||
return staticPart + "-" + myctr;
|
||||
}
|
||||
|
||||
return StaticPart + "-" + myctr;
|
||||
}
|
||||
|
||||
static SuperGloballyUniqueID()
|
||||
{
|
||||
staticPart = "bizhawk-" + System.Diagnostics.Process.GetCurrentProcess().Id.ToString() + "-" + Guid.NewGuid().ToString();
|
||||
StaticPart = "bizhawk-" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid();
|
||||
}
|
||||
|
||||
static int ctr;
|
||||
static string staticPart;
|
||||
private static readonly string StaticPart;
|
||||
private static int ctr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -388,8 +388,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
ppubus_read(ppur.get_atread(), true); //at or nt?
|
||||
if (realSprite) runppu(kFetchTime);
|
||||
|
||||
//TODO - fake sprites should not come through ppubus_read but rather peek it
|
||||
//(at least, they should not probe it with AddressPPU. maybe the difference between peek and read is not necessary)
|
||||
// TODO - fake sprites should not come through ppubus_read but rather peek it
|
||||
// (at least, they should not probe it with AddressPPU. maybe the difference between peek and read is not necessary)
|
||||
|
||||
if (junksprite)
|
||||
{
|
||||
|
@ -410,35 +410,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
oam->patterns[1] = ppubus_read(addr, true);
|
||||
if (realSprite) runppu(kFetchTime);
|
||||
|
||||
//hflip
|
||||
// hflip
|
||||
if ((oam->oam[2] & 0x40) == 0)
|
||||
{
|
||||
oam->patterns[0] = Bitrev.byte_8[oam->patterns[0]];
|
||||
oam->patterns[1] = Bitrev.byte_8[oam->patterns[1]];
|
||||
oam->patterns[0] = BitReverse.Byte8[oam->patterns[0]];
|
||||
oam->patterns[1] = BitReverse.Byte8[oam->patterns[1]];
|
||||
}
|
||||
}
|
||||
} //sprite pattern fetch loop
|
||||
} // sprite pattern fetch loop
|
||||
|
||||
ppuphase = PPUPHASE.BG;
|
||||
|
||||
//fetch BG: two tiles for next line
|
||||
// fetch BG: two tiles for next line
|
||||
for (int xt = 0; xt < 2; xt++)
|
||||
Read_bgdata(ref bgdata[xt]);
|
||||
|
||||
//this sequence is tuned to pass 10-even_odd_timing.nes
|
||||
// this sequence is tuned to pass 10-even_odd_timing.nes
|
||||
runppu(kFetchTime);
|
||||
bool evenOddDestiny = reg_2001.show_bg;
|
||||
runppu(kFetchTime);
|
||||
|
||||
//After memory access 170, the PPU simply rests for 4 cycles (or the
|
||||
//equivelant of half a memory access cycle) before repeating the whole
|
||||
//pixel/scanline rendering process. If the scanline being rendered is the very
|
||||
//first one on every second frame, then this delay simply doesn't exist.
|
||||
// After memory access 170, the PPU simply rests for 4 cycles (or the
|
||||
// equivelant of half a memory access cycle) before repeating the whole
|
||||
// pixel/scanline rendering process. If the scanline being rendered is the very
|
||||
// first one on every second frame, then this delay simply doesn't exist.
|
||||
if (sl == 0 && idleSynch && evenOddDestiny && chopdot)
|
||||
{ }
|
||||
else
|
||||
runppu(1);
|
||||
} //scanline loop
|
||||
} // scanline loop
|
||||
|
||||
ppur.status.sl = 241;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
public bool CheckID()
|
||||
{
|
||||
fixed (iNES_HEADER* self = &this)
|
||||
return 0 == Util.memcmp(self, "NES\x1A", 4);
|
||||
return 0 == Util.Memcmp(self, "NES\x1A", 4);
|
||||
}
|
||||
|
||||
//some cleanup code recommended by fceux
|
||||
|
@ -41,27 +41,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
fixed (iNES_HEADER* self = &this)
|
||||
{
|
||||
if (0 == Util.memcmp((byte*)(self) + 0x7, "DiskDude", 8))
|
||||
if (0 == Util.Memcmp((byte*)(self) + 0x7, "DiskDude", 8))
|
||||
{
|
||||
Util.memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
Util.Memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
}
|
||||
|
||||
if (0 == Util.memcmp((byte*)(self) + 0x7, "demiforce", 9))
|
||||
if (0 == Util.Memcmp((byte*)(self) + 0x7, "demiforce", 9))
|
||||
{
|
||||
Util.memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
Util.Memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
}
|
||||
|
||||
if (0 == Util.memcmp((byte*)(self) + 0x8, "blargg", 6)) //found a test rom with this in there, mucking up the wram size
|
||||
if (0 == Util.Memcmp((byte*)(self) + 0x8, "blargg", 6)) //found a test rom with this in there, mucking up the wram size
|
||||
{
|
||||
Util.memset((byte*)(self) + 0x8, 0, 6);
|
||||
Util.Memset((byte*)(self) + 0x8, 0, 6);
|
||||
}
|
||||
|
||||
if (0 == Util.memcmp((byte*)(self) + 0xA, "Ni03", 4))
|
||||
if (0 == Util.Memcmp((byte*)(self) + 0xA, "Ni03", 4))
|
||||
{
|
||||
if (0 == Util.memcmp((byte*)(self) + 0x7, "Dis", 3))
|
||||
Util.memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
if (0 == Util.Memcmp((byte*)(self) + 0x7, "Dis", 3))
|
||||
Util.Memset((byte*)(self) + 0x7, 0, 0x9);
|
||||
else
|
||||
Util.memset((byte*)(self) + 0xA, 0, 0x6);
|
||||
Util.Memset((byte*)(self) + 0xA, 0, 0x6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
const uint edc_poly = 0x8001801B;
|
||||
|
||||
//generate the CRC table
|
||||
uint reverse_edc_poly = Bitrev.reverse_32(edc_poly);
|
||||
uint reverse_edc_poly = BitReverse.Reverse32(edc_poly);
|
||||
for (uint i = 0; i < 256; ++i)
|
||||
{
|
||||
uint crc = i;
|
||||
|
|
Loading…
Reference in New Issue