"Correct" IPS applier to resize file if it tries to write off end. I'm not sure what the spec behavior is, but this works for at least one file in the wild.
This commit is contained in:
parent
5d5a4d10f2
commit
c4f608a39b
|
@ -5,7 +5,7 @@ namespace BizHawk.Client.Common
|
||||||
{
|
{
|
||||||
public static class IPS
|
public static class IPS
|
||||||
{
|
{
|
||||||
public static void Patch(byte[] rom, Stream patch)
|
public static byte[] Patch(byte[] rom, Stream patch)
|
||||||
{
|
{
|
||||||
var ipsHeader = new byte[5];
|
var ipsHeader = new byte[5];
|
||||||
patch.Read(ipsHeader, 0, 5);
|
patch.Read(ipsHeader, 0, 5);
|
||||||
|
@ -16,32 +16,40 @@ namespace BizHawk.Client.Common
|
||||||
if (ipsHeader[i] != header[i])
|
if (ipsHeader[i] != header[i])
|
||||||
{
|
{
|
||||||
Console.WriteLine("Patch file specified is invalid.");
|
Console.WriteLine("Patch file specified is invalid.");
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// header verified, loop over patch entries
|
// header verified, loop over patch entries
|
||||||
uint EOF = ('E' * 0x10000 + 'O' * 0x100 + 'F');
|
uint EOF = ('E' * 0x10000 + 'O' * 0x100 + 'F');
|
||||||
|
|
||||||
|
var ret = new MemoryStream(rom.Length);
|
||||||
|
ret.Write(rom, 0, rom.Length);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
uint offset = Read24(patch);
|
uint offset = Read24(patch);
|
||||||
if (offset == EOF) return;
|
if (offset == EOF)
|
||||||
|
return ret.ToArray();
|
||||||
ushort size = Read16(patch);
|
ushort size = Read16(patch);
|
||||||
|
|
||||||
|
ret.Seek(offset, SeekOrigin.Begin);
|
||||||
|
|
||||||
if (size != 0) // non-RLE patch
|
if (size != 0) // non-RLE patch
|
||||||
{
|
{
|
||||||
var patchData = new byte[size];
|
var patchData = new byte[size];
|
||||||
patch.Read(patchData, 0, size);
|
patch.Read(patchData, 0, size);
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
rom[offset++] = patchData[i];
|
ret.Write(patchData, 0, patchData.Length);
|
||||||
}
|
}
|
||||||
else // RLE patch
|
else // RLE patch
|
||||||
{
|
{
|
||||||
size = Read16(patch);
|
size = Read16(patch);
|
||||||
byte value = (byte)patch.ReadByte();
|
byte value = (byte)patch.ReadByte();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
rom[offset++] = value;
|
{
|
||||||
|
ret.WriteByte(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace BizHawk.Client.Common
|
||||||
patchFile.BindFirstOf("IPS");
|
patchFile.BindFirstOf("IPS");
|
||||||
if (patchFile.IsBound)
|
if (patchFile.IsBound)
|
||||||
{
|
{
|
||||||
IPS.Patch(RomData, patchFile.GetStream());
|
RomData = IPS.Patch(RomData, patchFile.GetStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue