public static WriteInt32 ( Stream stream, uint value ) : void | ||
stream | Stream | The stream to write to. |
value | uint | The number to write. |
return | void |
/// <summary> /// Writes a big-endian 32-bit word into memory. /// </summary> /// <param name="offset">The address to write to.</param> /// <param name="value">The value to write.</param> /// <exception cref="VMException">The address is below RamStart.</exception> public void WriteInt32(uint offset, uint value) { if (offset < ramstart) { throw new VMException("Writing into ROM"); } BigEndian.WriteInt32(memory, offset, value); }
/// <summary> /// Saves the heap state to a byte array. /// </summary> /// <returns>A byte array describing the current heap state.</returns> public byte[] Save() { byte[] result = new byte[8 + blocks.Count * 8]; BigEndian.WriteInt32(result, 0, heapAddress); BigEndian.WriteInt32(result, 4, (uint)blocks.Count); for (int i = 0; i < blocks.Count; i++) { BigEndian.WriteInt32(result, 8 * i + 8, blocks[i].Start); BigEndian.WriteInt32(result, 8 * i + 12, blocks[i].Length); } return(result); }
/// <summary> /// Compresses a block of memory by comparing it with the original /// version from the game file. /// </summary> /// <param name="original">An array containing the original block of memory.</param> /// <param name="origStart">The offset within the array where the original block /// starts.</param> /// <param name="origLength">The length of the original block, in bytes.</param> /// <param name="changed">An array containing the changed block to be compressed.</param> /// <param name="changedStart">The offset within the array where the changed /// block starts.</param> /// <param name="changedLength">The length of the changed block. This may be /// greater than <paramref name="origLength"/>, but may not be less.</param> /// <returns>The RLE-compressed set of differences between the old and new /// blocks, prefixed with a 4-byte length.</returns> public static byte[] CompressMemory(byte[] original, int origStart, int origLength, byte[] changed, int changedStart, int changedLength) { if (origStart + origLength > original.Length) { throw new ArgumentException("Original array is too small"); } if (changedStart + changedLength > changed.Length) { throw new ArgumentException("Changed array is too small"); } if (changedLength < origLength) { throw new ArgumentException("New block must be no smaller than old block"); } MemoryStream mstr = new MemoryStream(); BigEndian.WriteInt32(mstr, (uint)changedLength); for (int i = 0; i < origLength; i++) { byte b = (byte)(original[origStart + i] ^ changed[changedStart + i]); if (b == 0) { int runLength; for (runLength = 1; i + runLength < origLength; runLength++) { if (runLength == 256) { break; } if (original[origStart + i + runLength] != changed[changedStart + i + runLength]) { break; } } mstr.WriteByte(0); mstr.WriteByte((byte)(runLength - 1)); i += runLength - 1; } else { mstr.WriteByte(b); } } return(mstr.ToArray()); }
/// <summary> /// Writes the chunks to a Quetzal file. /// </summary> /// <param name="stream">The stream to write to.</param> public void WriteToStream(Stream stream) { BigEndian.WriteInt32(stream, FORM); // IFF tag BigEndian.WriteInt32(stream, 0); // file length (filled in later) BigEndian.WriteInt32(stream, IFZS); // FORM sub-ID for Quetzal uint totalSize = 4; // includes sub-ID foreach (KeyValuePair <uint, byte[]> pair in chunks) { BigEndian.WriteInt32(stream, pair.Key); // chunk type BigEndian.WriteInt32(stream, (uint)pair.Value.Length); // chunk length stream.Write(pair.Value, 0, pair.Value.Length); // chunk data totalSize += 8 + (uint)(pair.Value.Length); } if (totalSize % 2 == 1) { stream.WriteByte(0); // padding (not counted in file length) } stream.Seek(4, SeekOrigin.Begin); BigEndian.WriteInt32(stream, totalSize); //stream.SetLength(totalSize); }