Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Author: Dan
- * Date: December 2018
- *
- * This code is released under the GPL v3.0 license.
- * All other rights (c) their respective parties; I make no claims of ownership.
- */
- namespace MetroidTools.Utilities
- {
- #region using
- using System;
- using System.Collections.Generic;
- using System.Windows.Forms;
- using MetroidTools;
- using MetroidTools.Data;
- using MetroidTools.Utilities;
- #endregion
- /// <summary>
- /// Contains methods to compress and decompress game data
- /// </summary>
- public static class Compression
- {
- #region public static methods
- // TODO:
- // - Many functions are not implemented
- // - Compression is not implemented
- // - No bounds checking yet, etc
- // - Find a good way to determine buffer size, if possible
- #region Compress
- public static void Compress(byte[] sourceBuffer, int sourceAddress, byte[] targetBuffer, int targetAddress)
- {
- throw new NotImplementedException();
- }
- public static void Compress(ByteWriter source, ByteWriter target)
- {
- Compress(source.Buffer, source.Address, target.Buffer, target.Address);
- }
- #endregion
- #region Decompress
- public static int Decompress(byte[] sourceBuffer, int sourceAddress, byte[] targetBuffer, int targetAddress)
- {
- int start = sourceAddress;
- while (true)
- {
- byte data = sourceBuffer[sourceAddress++];
- int size = 0x00;
- int code = 0x00;
- if (data == 0xFF)
- break;
- code = (data >> 0x05);
- if (code != 0x07)
- size = (data & 0x1F) + 1;
- else
- {
- size = ((data & 3) << 0x08 | sourceBuffer[sourceAddress++]) + 1;
- code = (data >> 2) & 0x07;
- }
- Console.WriteLine("OPCODE: {0:X2}, SIZE: {1:X2}, ADDRESS: {2:X6} (+{3:X4})",
- code, size, sourceAddress, sourceAddress - start);
- #region opcodes
- // 00: Direct copy
- if (code == 0x00)
- {
- Array.Copy(
- sourceBuffer, sourceAddress,
- targetBuffer, targetAddress, size);
- sourceAddress += size;
- targetAddress += size;
- }
- // 01: Byte fill
- if (code == 0x01)
- {
- data = sourceBuffer[sourceAddress++];
- for (int i = 0; i < size; i++)
- targetBuffer[targetAddress++] = data;
- }
- // 02: Word fill
- if (code == 0x02)
- {
- byte value1 = sourceBuffer[sourceAddress++];
- byte value2 = sourceBuffer[sourceAddress++];
- for(int i = 0; i < size >> 1; i++)
- {
- targetBuffer[targetAddress++] = value1;
- targetBuffer[targetAddress++] = value2;
- }
- if ((size & 1) > 0)
- targetBuffer[targetAddress++] = value1;
- }
- // 03: Incremental fill
- if (code == 0x03)
- {
- }
- // 04: Dictionary copy
- if (code == 0x04)
- {
- }
- // 05: Dictionary copy, inverted
- if (code == 0x05)
- {
- ushort value = BitHelper.ToUInt16(sourceBuffer, sourceAddress);
- sourceAddress += 2;
- for (int i = value; i < value + size; i++)
- targetBuffer[targetAddress++] = (byte)~targetBuffer[i];
- }
- // 06: Sliding dictionary copy
- if (code == 0x06)
- {
- int offset = targetAddress - sourceBuffer[sourceAddress++];
- for (int i = offset; i < offset + size; i++)
- targetBuffer[targetAddress++] = targetBuffer[i];
- }
- // 07: Sliding dictionary copy, inverted
- if (code == 0x07)
- {
- }
- #endregion
- }
- return targetAddress;
- }
- public static int Decompress(ByteWriter source, ByteWriter target)
- {
- return Decompress(source.Buffer, source.Address, target.Buffer, target.Address);
- }
- #endregion
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement