Advertisement
Guest User

Untitled

a guest
Dec 14th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.80 KB | None | 0 0
  1. /*
  2.  * Author: Dan
  3.  * Date: December 2018
  4.  *
  5.  * This code is released under the GPL v3.0 license.
  6.  * All other rights (c) their respective parties; I make no claims of ownership.
  7.  */
  8.  
  9. namespace MetroidTools.Utilities
  10. {
  11.     #region using
  12.  
  13.     using System;
  14.     using System.Collections.Generic;
  15.     using System.Windows.Forms;
  16.  
  17.     using MetroidTools;
  18.     using MetroidTools.Data;
  19.     using MetroidTools.Utilities;
  20.  
  21.     #endregion
  22.  
  23.     /// <summary>
  24.     /// Contains methods to compress and decompress game data
  25.     /// </summary>
  26.     public static class Compression
  27.     {
  28.         #region public static methods
  29.  
  30.         // TODO:
  31.         // - Many functions are not implemented
  32.         // - Compression is not implemented
  33.         // - No bounds checking yet, etc
  34.         // - Find a good way to determine buffer size, if possible
  35.  
  36.         #region Compress
  37.  
  38.         public static void Compress(byte[] sourceBuffer, int sourceAddress, byte[] targetBuffer, int targetAddress)
  39.         {
  40.             throw new NotImplementedException();
  41.         }
  42.  
  43.         public static void Compress(ByteWriter source, ByteWriter target)
  44.         {
  45.             Compress(source.Buffer, source.Address, target.Buffer, target.Address);
  46.         }
  47.  
  48.         #endregion
  49.         #region Decompress
  50.  
  51.         public static int Decompress(byte[] sourceBuffer, int sourceAddress, byte[] targetBuffer, int targetAddress)
  52.         {
  53.             int start = sourceAddress;
  54.  
  55.             while (true)
  56.             {
  57.                 byte data = sourceBuffer[sourceAddress++];
  58.                 int size = 0x00;
  59.                 int code = 0x00;
  60.  
  61.                 if (data == 0xFF)
  62.                     break;
  63.  
  64.                 code = (data >> 0x05);
  65.                 if (code != 0x07)
  66.                     size = (data & 0x1F) + 1;
  67.                 else
  68.                 {
  69.                     size = ((data & 3) << 0x08 | sourceBuffer[sourceAddress++]) + 1;
  70.                     code = (data >> 2) & 0x07;
  71.                 }
  72.  
  73.                 Console.WriteLine("OPCODE: {0:X2}, SIZE: {1:X2}, ADDRESS: {2:X6} (+{3:X4})",
  74.                     code, size, sourceAddress, sourceAddress - start);
  75.  
  76.                 #region opcodes
  77.  
  78.                 // 00: Direct copy
  79.                 if (code == 0x00)
  80.                 {
  81.                     Array.Copy(
  82.                         sourceBuffer, sourceAddress,
  83.                         targetBuffer, targetAddress, size);
  84.  
  85.                     sourceAddress += size;
  86.                     targetAddress += size;
  87.                 }
  88.  
  89.                 // 01: Byte fill
  90.                 if (code == 0x01)
  91.                 {
  92.                     data = sourceBuffer[sourceAddress++];
  93.                     for (int i = 0; i < size; i++)
  94.                         targetBuffer[targetAddress++] = data;
  95.                 }
  96.  
  97.                 // 02: Word fill
  98.                 if (code == 0x02)
  99.                 {
  100.                     byte value1 = sourceBuffer[sourceAddress++];
  101.                     byte value2 = sourceBuffer[sourceAddress++];
  102.  
  103.                     for(int i = 0; i < size >> 1; i++)
  104.                     {
  105.                         targetBuffer[targetAddress++] = value1;
  106.                         targetBuffer[targetAddress++] = value2;
  107.                     }
  108.  
  109.                     if ((size & 1) > 0)
  110.                         targetBuffer[targetAddress++] = value1;
  111.                 }
  112.  
  113.                 // 03: Incremental fill
  114.                 if (code == 0x03)
  115.                 {
  116.  
  117.                 }
  118.  
  119.                 // 04: Dictionary copy
  120.                 if (code == 0x04)
  121.                 {
  122.                 }
  123.  
  124.                 // 05: Dictionary copy, inverted
  125.                 if (code == 0x05)
  126.                 {
  127.                     ushort value = BitHelper.ToUInt16(sourceBuffer, sourceAddress);
  128.                     sourceAddress += 2;
  129.  
  130.                     for (int i = value; i < value + size; i++)
  131.                         targetBuffer[targetAddress++] = (byte)~targetBuffer[i];
  132.                 }
  133.  
  134.                 // 06: Sliding dictionary copy
  135.                 if (code == 0x06)
  136.                 {
  137.                     int offset = targetAddress - sourceBuffer[sourceAddress++];
  138.                     for (int i = offset; i < offset + size; i++)
  139.                         targetBuffer[targetAddress++] = targetBuffer[i];
  140.                 }
  141.  
  142.                 // 07: Sliding dictionary copy, inverted
  143.                 if (code == 0x07)
  144.                 {
  145.                 }
  146.  
  147.                 #endregion
  148.             }
  149.  
  150.             return targetAddress;
  151.         }
  152.  
  153.         public static int Decompress(ByteWriter source, ByteWriter target)
  154.         {
  155.             return Decompress(source.Buffer, source.Address, target.Buffer, target.Address);
  156.         }
  157.  
  158.         #endregion
  159.        
  160.         #endregion
  161.     }
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement