tighten up RomGame file loading and in particular for n64 to avoid some buffer copies and re-dearchiving operations

This commit is contained in:
zeromus 2013-10-07 05:59:44 +00:00
parent 0b340d3176
commit 092337b065
1 changed files with 66 additions and 36 deletions

View File

@ -21,33 +21,52 @@ namespace BizHawk.MultiClient
if (!file.Exists) if (!file.Exists)
throw new Exception("The file needs to exist, yo."); throw new Exception("The file needs to exist, yo.");
var stream = file.GetStream();
FileData = Util.ReadAllBytes(stream);
Extension = file.Extension; Extension = file.Extension;
var stream = file.GetStream();
int fileLength = (int)stream.Length;
//read the entire contents of the file into memory.
//unfortunate in the case of large files, but thats what we've got to work with for now.
// if we're offset exactly 512 bytes from a 1024-byte boundary, // if we're offset exactly 512 bytes from a 1024-byte boundary,
// assume we have a header of that size. Otherwise, assume it's just all rom. // assume we have a header of that size. Otherwise, assume it's just all rom.
// Other 'recognized' header sizes may need to be added. // Other 'recognized' header sizes may need to be added.
int header = (int)(stream.Length % BankSize); int headerOffset = fileLength % BankSize;
if (header.In(0, 512) == false) if (headerOffset.In(0, 512) == false)
{ {
Console.WriteLine("ROM was not a multiple of 1024 bytes, and not a recognized header size: {0}. Assume it's purely ROM data.", header); Console.WriteLine("ROM was not a multiple of 1024 bytes, and not a recognized header size: {0}. Assume it's purely ROM data.", headerOffset);
header = 0; headerOffset = 0;
} }
else if (header > 0) else if (headerOffset > 0)
Console.WriteLine("Assuming header of {0} bytes.", header); Console.WriteLine("Assuming header of {0} bytes.", headerOffset);
stream.Position = header; //read the entire file into FileData.
int length = (int)stream.Length - header; FileData = new byte[fileLength];
stream.Read(FileData, 0, fileLength);
RomData = new byte[length]; //if there was no header offset, RomData is equivalent to FileData
stream.Read(RomData, 0, length); //(except in cases where the original interleaved file data is necessary.. in that case we'll have problems..
//but this whole architecture is not going to withstand every peculiarity and be fast as well.
if (headerOffset == 0)
{
RomData = FileData;
}
else
{
//if there was a header offset, read the whole file into FileData and then copy it into RomData (this is unfortunate, in case RomData isnt needed)
int romLength = fileLength - headerOffset;
RomData = new byte[romLength];
Buffer.BlockCopy(FileData, headerOffset, RomData, 0, romLength);
}
if (file.Extension == ".SMD") if (file.Extension == ".SMD")
RomData = DeInterleaveSMD(RomData); RomData = DeInterleaveSMD(RomData);
if (file.Extension == ".Z64" || file.Extension == ".N64" || file.Extension == ".V64") if (file.Extension == ".Z64" || file.Extension == ".N64" || file.Extension == ".V64")
RomData = SwapN64(RomData); RomData = MutateSwapN64(RomData);
//note: this will be taking several hashes, of a potentially large amount of data.. yikes!
GameInfo = Database.GetGameInfo(RomData, file.Name); GameInfo = Database.GetGameInfo(RomData, file.Name);
CheckForPatchOptions(); CheckForPatchOptions();
@ -84,7 +103,7 @@ namespace BizHawk.MultiClient
return output; return output;
} }
private static byte[] SwapN64(byte[] source) private unsafe static byte[] MutateSwapN64(byte[] source)
{ {
// N64 roms are in one of the following formats: // N64 roms are in one of the following formats:
// .Z64 = No swapping // .Z64 = No swapping
@ -94,34 +113,45 @@ namespace BizHawk.MultiClient
// File extension does not always match the format // File extension does not always match the format
int size = source.Length; int size = source.Length;
byte[] output = new byte[size];
// V64 format // V64 format
if (source[0] == 0x37) fixed (byte* pSource = &source[0])
{ {
for (int i = 0; i < size; i += 2) if (pSource[0] == 0x37)
{
for (int i = 0; i < size; i += 2)
{
byte temp = pSource[i];
pSource[i] = pSource[i + 1];
pSource[i + 1] = temp;
}
}
// N64 format
else if (pSource[0] == 0x40)
{
for (int i = 0; i < size; i += 4)
{
//output[i] = source[i + 3];
//output[i + 3] = source[i];
//output[i + 1] = source[i + 2];
//output[i + 2] = source[i + 1];
byte temp = pSource[i];
pSource[i] = source[i + 3];
pSource[i + 3] = temp;
temp = pSource[i + 1];
pSource[i + 1] = pSource[i + 2];
pSource[i + 2] = temp;
}
}
// Z64 format (or some other unknown format)
else
{ {
output[i] = source[i + 1];
output[i + 1] = source[i];
} }
} }
// N64 format
else if (source[0] == 0x40) return source;
{
for (int i = 0; i < size; i += 4)
{
output[i] = source[i + 3];
output[i + 3] = source[i];
output[i + 1] = source[i + 2];
output[i + 2] = source[i + 1];
}
}
// Z64 format (or some other unknown format)
else
{
return source;
}
return output;
} }
private void CheckForPatchOptions() private void CheckForPatchOptions()