diff --git a/PCK-Studio/Classes/FileTypes/GRFFile.cs b/PCK-Studio/Classes/FileTypes/GRFFile.cs
deleted file mode 100644
index 5abf9d2e..00000000
--- a/PCK-Studio/Classes/FileTypes/GRFFile.cs
+++ /dev/null
@@ -1,283 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace PckStudio.Classes.FileTypes
-{
- public class GRFFile
- {
- public static readonly string[] ValidGameRules = new string[]
- {
- "MapOptions",
- "ApplySchematic",
- "GenerateStructure",
- "GenerateBox",
- "PlaceBlock",
- "PlaceContainer",
- "PlaceSpawner",
- "BiomeOverride",
- "StartFeature",
- "AddItem",
- "AddEnchantment",
- "WeighedTreasureItem",
- "RandomItemSet",
- "DistributeItems",
- "WorldPosition",
- "LevelRules",
- "NamedArea",
- "ActiveChunkArea",
- "TargetArea",
- "ScoreRing",
- "ThermalArea",
- "PlayerBoundsVolume",
- "Killbox",
- "BlockLayer",
- "UseBlock",
- "CollectItem",
- "CompleteAll",
- "UpdatePlayer",
- "OnGameStartSpawnPositions",
- "OnInitialiseWorld",
- "SpawnPositionSet",
- "PopulateContainer",
- "DegradationSequence",
- "RandomDissolveDegrade",
- "DirectionalDegrade",
- "GrantPermissions",
- "AllowIn",
- "LayerGeneration",
- "LayerAsset",
- "AnyCombinationOf",
- "CombinationDefinition",
- "Variations",
- "BlockDef",
- "LayerSize",
- "UniformSize",
- "RandomizeSize",
- "LinearBlendSize",
- "LayerShape",
- "BasicShape",
- "StarShape",
- "PatchyShape",
- "RingShape",
- "SpiralShape",
- "LayerFill",
- "BasicLayerFill",
- "CurvedLayerFill",
- "WarpedLayerFill",
- "LayerTheme",
- "NullTheme",
- "FilterTheme",
- "ShaftsTheme",
- "BasicPatchesTheme",
- "BlockStackTheme",
- "RainbowTheme",
- "TerracottaTheme",
- "FunctionPatchesTheme",
- "SimplePatchesTheme",
- "CarpetTrapTheme",
- "MushroomBlockTheme",
- "TextureTheme",
- "SchematicTheme",
- "BlockCollisionException",
- "Powerup",
- "Checkpoint",
- "CustomBeacon",
- "ActiveViewArea",
- };
-
- public readonly GameRule Root = null;
-
- public int Crc => _crc;
- public bool IsWorld => _isWorld;
- public CompressionType CompressionLevel => _compressionLevel;
-
- private int _crc = 0;
- private bool _isWorld = false;
- private CompressionType _compressionLevel = CompressionType.None;
-
- public enum CompressionType : byte
- {
- None = 0,
- Compressed = 1,
- CompressedRle = 2,
- CompressedRleCrc = 3,
- }
-
- ///
- /// Initializes a new GRFFile as a non-world grf file
- ///
- public GRFFile() : this(-1, false)
- {}
-
- public GRFFile(int crc, bool isWolrd) : this(crc, isWolrd, CompressionType.None)
- {}
- public GRFFile(int crc, bool isWolrd, CompressionType compressionLevel)
- {
- Root = new GameRule("__ROOT__", null);
- _compressionLevel = compressionLevel;
- _crc = crc;
- _isWorld = isWolrd;
- }
-
- public class GameRule
- {
- /// Contains all valid Parameter names
- public static readonly string[] ValidParameters = new string[]
- {
- "plus_x",
- "minus_x",
- "plus_z",
- "minus_z",
- "omni_plus_x",
- "omni_minus_x",
- "omni_plus_z",
- "omni_minus_z",
- "none",
- "plus_y",
- "minus_y",
- "plus_x",
- "minus_x",
- "plus_z",
- "minus_z",
- "descriptionName",
- "promptName",
- "dataTag",
- "enchantmentId",
- "enchantmentLevel",
- "itemId",
- "quantity",
- "auxValue",
- "slot",
- "name",
- "food",
- "health",
- "blockId",
- "useCoords",
- "seed",
- "flatworld",
- "filename",
- "rot",
- "data",
- "block",
- "entity",
- "facing",
- "edgeBlock",
- "fillBlock",
- "skipAir",
- "x",
- "x0",
- "x1",
- "y",
- "y0",
- "y1",
- "z",
- "z0",
- "z1",
- "chunkX",
- "chunkZ",
- "yRot",
- "xRot",
- "spawnX",
- "spawnY",
- "spawnZ",
- "orientation",
- "dimension",
- "topblockId",
- "biomeId",
- "feature",
- "minCount",
- "maxCount",
- "weight",
- "id",
- "probability",
- "method",
- "hasBeenInCreative",
- "cloudHeight",
- "fogDistance",
- "dayTime",
- "target",
- "speed",
- "dir",
- "type",
- "pass",
- "for",
- "random",
- "blockAux",
- "size",
- "scale",
- "freq",
- "func",
- "upper",
- "lower",
- "dY",
- "thickness",
- "points",
- "holeSize",
- "variant",
- "startHeight",
- "pattern",
- "colour",
- "primary",
- "laps",
- "liftForceModifier",
- "staticLift",
- "targetHeight",
- "speedBoost",
- "boostDirection",
- "condition_type",
- "condition_value_0",
- "condition_value_1",
- "beam_length",
- };
-
- public string Name { get; set; } = string.Empty;
-
- public GameRule Parent { get; } = null;
- public Dictionary Parameters { get; } = new Dictionary();
- public List ChildRules { get; } = new List();
-
- public GameRule(string name, GameRule parent)
- {
- Name = name;
- Parent = parent;
- }
-
- public GameRule AddRule(string gameRuleName) => AddRule(gameRuleName, false);
-
- /// Adds a new gamerule
- /// Game rule to add
- /// Wether to check the given game rule
- /// The Added GRFTag
- public GameRule AddRule(string gameRuleName, bool validate)
- {
- if (validate && !ValidGameRules.Contains(gameRuleName)) return null;
- var tag = new GameRule(gameRuleName, this);
- ChildRules.Add(tag);
- return tag;
- }
-
- public GameRule AddRule(string gameRuleName, params KeyValuePair[] parameters)
- {
- var tag = AddRule(gameRuleName); // should never return null unless its called with the validate bool set to true
- foreach(var param in parameters)
- {
- tag.Parameters[param.Key] = param.Value;
- }
- return tag;
- }
- }
-
- public void AddGameRules(IEnumerable gameRules) => Root.ChildRules.AddRange(gameRules);
-
- public GameRule AddRule(string gameRuleName)
- => AddRule(gameRuleName, false);
-
- public GameRule AddRule(string gameRuleName, bool validate)
- => Root.AddRule(gameRuleName, validate);
-
- public GameRule AddRule(string gameRuleName, params KeyValuePair[] parameters)
- => Root.AddRule(gameRuleName, parameters);
- }
-}
diff --git a/PCK-Studio/Classes/IO/GRF/GRFFileReader.cs b/PCK-Studio/Classes/IO/GRF/GRFFileReader.cs
deleted file mode 100644
index 953b2108..00000000
--- a/PCK-Studio/Classes/IO/GRF/GRFFileReader.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using PckStudio.Classes.FileTypes;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
-using PckStudio.Classes.Utils;
-using System.Diagnostics;
-
-namespace PckStudio.Classes.IO.GRF
-{
- internal class GRFFileReader : StreamDataReader
- {
- private IList StringLookUpTable;
- private GRFFile _file;
-
- public static GRFFile Read(Stream stream)
- {
- return new GRFFileReader().ReadFromStream(stream);
- }
-
- private GRFFileReader() : base(false)
- { }
-
- protected override GRFFile ReadFromStream(Stream stream)
- {
- stream = ReadHeader(stream);
- ReadBody(stream);
- return _file;
- }
-
- private Stream ReadHeader(Stream stream)
- {
- int x = ReadShort(stream);
- if (((x >> 31) | x) == 0)
- {
- // 14 bools ?...
- ReadBytes(stream, 14);
- return stream;
- }
-
- GRFFile.CompressionType compression_type = (GRFFile.CompressionType)stream.ReadByte();
- int crc = ReadInt(stream);
- int byte1 = stream.ReadByte();
- int byte2 = stream.ReadByte();
- int byte3 = stream.ReadByte();
- int byte4 = stream.ReadByte();
- if (byte4 > 0)
- {
- compression_type = (GRFFile.CompressionType)byte4;
- }
- _file = new GRFFile(crc, byte4 > 0, compression_type);
-
- if (compression_type == GRFFile.CompressionType.None && byte4 == 0)
- return stream;
-
- int buf_size = ReadInt(stream);
- var new_stream = stream;
- if (byte4 != 0)
- {
- new_stream = new MemoryStream(ReadBytes(stream, buf_size));
- buf_size = ReadInt(new_stream);
- }
- else
- {
- ReadInt(stream); // ignored cuz rest of data is compressed
- }
- var decompressed_stream = DecompressZLX(new_stream);
- new_stream.Dispose();
- if (compression_type > GRFFile.CompressionType.Compressed)
- {
- byte[] data = ReadBytes(decompressed_stream, buf_size);
- byte[] decoded_data = RLE.Decode(data).ToArray();
- decompressed_stream.Dispose();
- decompressed_stream = new MemoryStream(decoded_data);
- }
-
- if (byte4 != 0)
- ReadBytes(decompressed_stream, 23);
-
- return decompressed_stream;
- }
-
- private void ReadBody(Stream stream)
- {
- ReadStringLookUpTable(stream);
- string Name = GetString(stream);
- Debug.WriteLine(string.Format("Root Name: {0}", Name), category: nameof(GRFFile));
- ReadGameRuleHierarchy(stream, _file.Root);
- }
-
- private Stream DecompressZLX(Stream compressedStream)
- {
- Stream outputstream = new MemoryStream();
- using (var inputStream = new InflaterInputStream(compressedStream))
- {
- inputStream.IsStreamOwner = false;
- inputStream.CopyTo(outputstream);
- outputstream.Position = 0;
- };
- return outputstream;
- }
-
- private void ReadStringLookUpTable(Stream stream)
- {
- int tableSize = ReadInt(stream);
- StringLookUpTable = new List(tableSize);
- for (int i = 0; i < tableSize; i++)
- {
- string s = ReadString(stream);
- StringLookUpTable.Add(s);
- }
- }
-
- private void ReadGameRuleHierarchy(Stream stream, GRFFile.GameRule parentRule)
- {
- _ = parentRule ?? throw new ArgumentNullException(nameof(parentRule));
- int count = ReadInt(stream);
- for (int i = 0; i < count; i++)
- {
- (string Name, int Count) parameter = (GetString(stream), ReadInt(stream));
- var rule = parentRule.AddRule(parameter.Name);
- for (int j = 0; j < parameter.Count; j++)
- {
- rule.Parameters.Add(GetString(stream), ReadString(stream));
- }
- ReadGameRuleHierarchy(stream, rule);
- }
- }
-
- private string GetString(Stream stream) => StringLookUpTable[ReadInt(stream)];
-
- private string ReadString(Stream stream)
- {
- short stringLength = ReadShort(stream);
- return ReadString(stream, stringLength, Encoding.ASCII);
- }
- }
-}
diff --git a/PCK-Studio/Classes/IO/GRF/GRFFileWriter.cs b/PCK-Studio/Classes/IO/GRF/GRFFileWriter.cs
deleted file mode 100644
index 4d4127a9..00000000
--- a/PCK-Studio/Classes/IO/GRF/GRFFileWriter.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-using PckStudio.Classes.FileTypes;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
-using PckStudio.Classes.Utils.grf;
-using PckStudio.Classes.Utils;
-
-namespace PckStudio.Classes.IO.GRF
-{
- internal class GRFFileWriter : StreamDataWriter
- {
- private readonly GRFFile _grfFile;
- private List StringLookUpTable;
-
- private GRFFile.CompressionType _compressionType;
-
- public static void Write(in Stream stream, GRFFile grfFile, GRFFile.CompressionType compressionType)
- {
- new GRFFileWriter(grfFile, compressionType).WriteToStream(stream);
- }
-
- private GRFFileWriter(GRFFile grfFile, GRFFile.CompressionType compressionType) : base(false)
- {
- _compressionType = compressionType;
- if (grfFile.IsWorld)
- throw new NotImplementedException("World grf saving is currently unsupported");
- _grfFile = grfFile;
- StringLookUpTable = new List();
- PrepareLookUpTable(_grfFile.Root, StringLookUpTable);
- }
-
- private void PrepareLookUpTable(GRFFile.GameRule rule, List LUT)
- {
- if (!LUT.Contains(rule.Name)) LUT.Add(rule.Name);
- rule.ChildRules.ForEach(subRule => PrepareLookUpTable(subRule, LUT));
- foreach (var param in rule.Parameters)
- if (!LUT.Contains(param.Key)) LUT.Add(param.Key);
- }
-
- protected override void WriteToStream(Stream stream)
- {
- WriteHeader(stream);
- using (var uncompressed_stream = new MemoryStream())
- {
- WriteBody(uncompressed_stream);
- HandleCompression(stream, uncompressed_stream);
- }
- }
-
- private void HandleCompression(Stream destinationStream, MemoryStream sourceStream)
- {
- byte[] _buffer = sourceStream.ToArray();
- int _original_length = _buffer.Length;
-
- if (_compressionType >= GRFFile.CompressionType.CompressedRle)
- _buffer = CompressRle(_buffer);
- if (_compressionType >= GRFFile.CompressionType.Compressed)
- {
- _buffer = CompressZib(_buffer);
- WriteInt(destinationStream, _original_length);
- WriteInt(destinationStream, _buffer.Length);
- }
- if (_compressionType >= GRFFile.CompressionType.CompressedRleCrc)
- MakeAndWriteCrc(destinationStream, _buffer);
- WriteBytes(destinationStream, _buffer);
- return;
- }
-
- private byte[] CompressZib(byte[] buffer)
- {
- byte[] result;
- var outputStream = new MemoryStream(); // Stream gets Disposed in DeflaterOutputStream
- using (var deflateStream = new DeflaterOutputStream(outputStream))
- {
- WriteBytes(deflateStream, buffer);
- deflateStream.Flush();
- deflateStream.Finish();
- outputStream.Position = 0;
- result = outputStream.ToArray();
- }
- return result;
- }
-
- private byte[] CompressRle(byte[] buffer) => RLE.Encode(buffer).ToArray();
-
- private void MakeAndWriteCrc(Stream stream, byte[] data)
- {
- uint crc = CRC32.CRC(data);
- if (crc != _grfFile.Crc) // no writting needed if there is no change
- {
- stream.Position = 3;
- WriteUInt(stream, crc);
- stream.Seek(0, SeekOrigin.End); // reset to the end of the stream
- }
- }
-
- private void WriteHeader(Stream stream)
- {
- WriteShort(stream, 1);
- if (_compressionType < GRFFile.CompressionType.None ||
- _compressionType > GRFFile.CompressionType.CompressedRleCrc)
- throw new ArgumentException(nameof(_compressionType));
- stream.WriteByte((byte)_compressionType);
- WriteInt(stream, _grfFile.Crc);
- stream.WriteByte(0);
- stream.WriteByte(0);
- stream.WriteByte(0);
- stream.WriteByte(0); // <- used in world grf
- }
-
- private void WriteBody(Stream stream)
- {
- WriteTagLookUpTable(stream);
- SetString(stream, _grfFile.Root.Name);
- WriteInt(stream, _grfFile.Root.ChildRules.Count);
- WriteGameRuleHierarchy(stream, _grfFile.Root);
- }
-
- private void WriteTagLookUpTable(Stream stream)
- {
- WriteInt(stream, StringLookUpTable.Count);
- StringLookUpTable.ForEach( s => WriteString(stream, s) );
- }
-
- private void WriteGameRuleHierarchy(Stream stream, GRFFile.GameRule rule)
- {
- foreach (var subRule in rule.ChildRules)
- {
- SetString(stream, subRule.Name);
- WriteInt(stream, subRule.Parameters.Count);
- foreach (var param in subRule.Parameters) WriteParameter(stream, param);
- WriteInt(stream, subRule.ChildRules.Count);
- WriteGameRuleHierarchy(stream, subRule);
- }
- }
-
- private void WriteParameter(Stream stream, KeyValuePair param)
- {
- SetString(stream, param.Key);
- WriteString(stream, param.Value);
- }
-
- private void SetString(Stream stream, string s)
- {
- int i = StringLookUpTable.IndexOf(s);
- if (i == -1) throw new Exception(nameof(s));
- WriteInt(stream, i);
- }
-
- private void WriteString(Stream stream, string s)
- {
- WriteShort(stream, (short)s.Length);
- WriteString(stream, s, Encoding.ASCII);
- }
- }
-}
diff --git a/PCK-Studio/Classes/Utils/RLE.cs b/PCK-Studio/Classes/Utils/RLE.cs
deleted file mode 100644
index 2a16135e..00000000
--- a/PCK-Studio/Classes/Utils/RLE.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-namespace PckStudio.Classes.Utils;
-
-///! Credits
-///!
-
-///
-/// Provides the RLE codec for any integer data type.
-///
-/// The data's type. Must be an integer type or an ArgumentException will be thrown
-static class RLE where T : struct, IConvertible
-{
- ///
- /// This is the marker that identifies a compressed run
- ///
- private static T rleMarker;
-
- ///
- /// A run can be at most as long as the marker - 1
- ///
- private static ulong maxLength;
-
- static RLE()
- {
- GetMaxValues();
- }
-
- ///
- /// RLE-Encodes a data set.
- ///
- /// The data to encode
- /// Encoded data
- public static IEnumerable Encode(IEnumerable data)
- {
- var enumerator = data.GetEnumerator();
-
- if (!enumerator.MoveNext())
- yield break;
-
- var firstRunValue = enumerator.Current;
- ulong runLength = 1;
- while (enumerator.MoveNext())
- {
- var currentValue = enumerator.Current;
- // if the current value is the value of the current run, don't yield anything,
- // just extend the run
- if (currentValue.Equals(firstRunValue))
- runLength++;
- else
- {
- // the current value is different from the current run
- // yield what we have so far
- foreach (var item in MakeRun(firstRunValue, runLength))
- yield return item;
-
- // and reset the run
- firstRunValue = currentValue;
- runLength = 1;
- }
- // if there are very many identical values, don't exceed the max length
- if (runLength > maxLength)
- {
- foreach (var item in MakeRun(firstRunValue, maxLength))
- yield return item;
- runLength -= maxLength;
- }
- }
- //yield everything that has been buffered
- foreach (var item in MakeRun(firstRunValue, runLength))
- yield return item;
- }
-
- ///
- /// Decodes RLE-encoded data
- ///
- /// RLE-encoded data
- /// The original data
- public static IEnumerable Decode(IEnumerable data)
- {
- var enumerator = data.GetEnumerator();
- if (!enumerator.MoveNext())
- yield break;
-
- do
- {
- var value = enumerator.Current;
- if (!value.Equals(rleMarker))
- {
- //an ordinary value
- yield return value;
- }
- else
- {
- //might be flag or escape
- //examine the next value
- if (!enumerator.MoveNext())
- throw new ArgumentException("The provided data is not properly encoded.");
- if (enumerator.Current.Equals(rleMarker))
- {
- //escaped value
- yield return value;
- }
- else
- {
- //rle marker
- var length = enumerator.Current.ToInt64(CultureInfo.InvariantCulture);
- if (!enumerator.MoveNext())
- throw new ArgumentException("The provided data is not properly encoded.");
- var val = enumerator.Current;
- for (var j = 0; j < length+1; ++j)
- yield return val;
- }
- }
- }
- while (enumerator.MoveNext());
- }
-
- private static IEnumerable MakeRun(T value, ulong length)
- {
- if ((length <= 3 && !value.Equals(rleMarker)) || length <= 1)
- {
- //don't compress this run, it is just too small
- for (ulong i = 0; i < length; i++)
- {
- yield return value.Equals(rleMarker) ? rleMarker : value;
- }
- }
- else
- {
- //compressed run
- yield return rleMarker;
- yield return (T)(dynamic)(length-1);
- yield return value;
- }
- }
-
-
- private static void GetMaxValues()
- {
- TypeCode typeCode = Type.GetTypeCode(typeof(T));
- switch (typeCode)
- {
- case TypeCode.Byte:
- {
- var limit = byte.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.Char:
- {
- var limit = char.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.Int16:
- {
- var limit = short.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.Int32:
- {
- var limit = int.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.Int64:
- {
- var limit = long.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.SByte:
- {
- var limit = sbyte.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.UInt16:
- {
- var limit = ushort.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.UInt32:
- {
- var limit = uint.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- case TypeCode.UInt64:
- {
- var limit = ulong.MaxValue;
- rleMarker = __refvalue(__makeref(limit), T);
- maxLength = (ulong)(limit - 1);
- break;
- }
- default:
- throw new ArgumentException("The provided type parameter is not an integer type");
- }
- }
-}
\ No newline at end of file
diff --git a/PCK-Studio/Classes/Utils/grf/CRC32.cs b/PCK-Studio/Classes/Utils/grf/CRC32.cs
deleted file mode 100644
index 7fb171f9..00000000
--- a/PCK-Studio/Classes/Utils/grf/CRC32.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-namespace PckStudio.Classes.Utils.grf
-{
- public class CRC32
- {
- static readonly private byte[] offsets =
- {
- 0x05, 0x06, 0x07, 0x03,
- 0x04, 0x05, 0x06, 0x07,
- 0x01, 0x02, 0x06, 0x01,
- 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x05, 0x06, 0x07,
- 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x01, 0x02, 0x06,
- 0x01, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x05, 0x06,
- 0x07, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x07, 0x05,
- 0x04, 0x07, 0x05, 0x04,
- 0x07, 0x05, 0x04, 0x07,
- 0x06, 0x05, 0x04, 0x03,
- };
-
- static private uint[] CRCTable;
- static private bool hasCRCTable = false;
-
- static void MakeCRCTable()
- {
- const uint val = 0xedb88320;
- CRCTable = new uint[256];
- for (int i = 0; i < 256; i++)
- {
- uint temp = (uint)i;
-
- for (int j = 0; j < 8; j++)
- {
- if ((temp & 1) == 1)
- {
- temp >>= 1;
- temp ^= val;
- }
- else { temp >>= 1; }
- }
- CRCTable[i] = temp;
- }
- hasCRCTable = true;
- }
- public static uint UpdateCRC(uint _crc, byte[] data)
- {
- uint crc = _crc;
- if (!hasCRCTable)
- MakeCRCTable();
- long pos = 0;
- long offset = 0;
- do
- {
- var value = data[pos];
- pos += offsets[offset];
- crc = CRCTable[(crc ^ value) & 0xff] ^ crc >> 8;
- offset = offset + 1U + ((offset + 1U >> 3) / 7) * -0x38;
- } while (pos < data.Length);
- return crc;
- }
-
- public static uint CRC(byte[] data)
- {
- return ~UpdateCRC(0xffffffff, data);
- }
- }
-}
diff --git a/PCK-Studio/Classes/Utils/grf/lzxDecoder.cs b/PCK-Studio/Classes/Utils/grf/lzxDecoder.cs
deleted file mode 100644
index 272f99ce..00000000
--- a/PCK-Studio/Classes/Utils/grf/lzxDecoder.cs
+++ /dev/null
@@ -1,785 +0,0 @@
-#region HEADER
-/* This file was derived from libmspack
- * (C) 2003-2004 Stuart Caie.
- * (C) 2011 Ali Scissons.
- *
- * The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
- * by Microsoft Corporation.
- *
- * This source file is Dual licensed; meaning the end-user of this source file
- * may redistribute/modify it under the LGPL 2.1 or MS-PL licenses.
- */
-#region LGPL License
-/* GNU LESSER GENERAL PUBLIC LICENSE version 2.1
- * LzxDecoder is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License (LGPL) version 2.1
- */
-#endregion
-#region MS-PL License
-/*
- * MICROSOFT PUBLIC LICENSE
- * This source code is subject to the terms of the Microsoft Public License (Ms-PL).
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * is permitted provided that redistributions of the source code retain the above
- * copyright notices and this file header.
- *
- * Additional copyright notices should be appended to the list above.
- *
- * For details, see .
- */
-#endregion
-/*
- * This derived work is recognized by Stuart Caie and is authorized to adapt
- * any changes made to lzxd.c in his libmspack library and will still retain
- * this dual licensing scheme. Big thanks to Stuart Caie!
- *
- * DETAILS
- * This file is a pure C# port of the lzxd.c file from libmspack, with minor
- * changes towards the decompression of XNB files. The original decompression
- * software of LZX encoded data was written by Suart Caie in his
- * libmspack/cabextract projects, which can be located at
- * http://http://www.cabextract.org.uk/
- */
-#endregion
-
-using System;
-using System.Diagnostics;
-
-namespace Microsoft.Xna.Framework.Content
-{
- using System.IO;
-
- class LzxDecoder
- {
- public static uint[] position_base = null;
- public static byte[] extra_bits = null;
-
- private LzxState m_state;
-
- public LzxDecoder(int window)
- {
- uint wndsize = (uint)(1 << window);
- int posn_slots;
-
- // setup proper exception
- if (window < 15 || window > 21) throw new UnsupportedWindowSizeRange();
-
- // let's initialise our state
- m_state = new LzxState();
- m_state.actual_size = 0;
- m_state.window = new byte[wndsize];
- for (int i = 0; i < wndsize; i++) m_state.window[i] = 0xDC;
- m_state.actual_size = wndsize;
- m_state.window_size = wndsize;
- m_state.window_posn = 0;
-
- /* initialize static tables */
- if (extra_bits == null)
- {
- extra_bits = new byte[52];
- for (int i = 0, j = 0; i <= 50; i += 2)
- {
- extra_bits[i] = extra_bits[i + 1] = (byte)j;
- if ((i != 0) && (j < 17)) j++;
- }
- }
- if (position_base == null)
- {
- position_base = new uint[51];
- for (int i = 0, j = 0; i <= 50; i++)
- {
- position_base[i] = (uint)j;
- j += 1 << extra_bits[i];
- }
- }
-
- /* calculate required position slots */
- if (window == 20) posn_slots = 42;
- else if (window == 21) posn_slots = 50;
- else posn_slots = window << 1;
-
- m_state.R0 = m_state.R1 = m_state.R2 = 1;
- m_state.main_elements = (ushort)(LzxConstants.NUM_CHARS + (posn_slots << 3));
- m_state.header_read = 0;
- m_state.frames_read = 0;
- m_state.block_remaining = 0;
- m_state.block_type = LzxConstants.BLOCKTYPE.INVALID;
- m_state.intel_curpos = 0;
- m_state.intel_started = 0;
-
- // yo dawg i herd u liek arrays so we put arrays in ur arrays so u can array while u array
- m_state.PRETREE_table = new ushort[(1 << LzxConstants.PRETREE_TABLEBITS) + (LzxConstants.PRETREE_MAXSYMBOLS << 1)];
- m_state.PRETREE_len = new byte[LzxConstants.PRETREE_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
- m_state.MAINTREE_table = new ushort[(1 << LzxConstants.MAINTREE_TABLEBITS) + (LzxConstants.MAINTREE_MAXSYMBOLS << 1)];
- m_state.MAINTREE_len = new byte[LzxConstants.MAINTREE_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
- m_state.LENGTH_table = new ushort[(1 << LzxConstants.LENGTH_TABLEBITS) + (LzxConstants.LENGTH_MAXSYMBOLS << 1)];
- m_state.LENGTH_len = new byte[LzxConstants.LENGTH_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
- m_state.ALIGNED_table = new ushort[(1 << LzxConstants.ALIGNED_TABLEBITS) + (LzxConstants.ALIGNED_MAXSYMBOLS << 1)];
- m_state.ALIGNED_len = new byte[LzxConstants.ALIGNED_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
- /* initialise tables to 0 (because deltas will be applied to them) */
- for (int i = 0; i < LzxConstants.MAINTREE_MAXSYMBOLS; i++) m_state.MAINTREE_len[i] = 0;
- for (int i = 0; i < LzxConstants.LENGTH_MAXSYMBOLS; i++) m_state.LENGTH_len[i] = 0;
- }
-
- public int Decompress(Stream inData, int inLen, Stream outData, int outLen)
- {
- BitBuffer bitbuf = new BitBuffer(inData);
- long startpos = inData.Position;
- long endpos = inData.Position + inLen;
-
- byte[] window = m_state.window;
-
- uint window_posn = m_state.window_posn;
- uint window_size = m_state.window_size;
- uint R0 = m_state.R0;
- uint R1 = m_state.R1;
- uint R2 = m_state.R2;
- uint i, j;
-
- int togo = outLen, this_run, main_element, match_length, match_offset, length_footer, extra, verbatim_bits;
- int rundest, runsrc, copy_length, aligned_bits;
-
- bitbuf.InitBitStream();
-
- /* read header if necessary */
- if (m_state.header_read == 0)
- {
- uint intel = bitbuf.ReadBits(1);
- if (intel != 0)
- {
- // read the filesize
- i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(16);
- m_state.intel_filesize = (int)((i << 16) | j);
- }
- m_state.header_read = 1;
- }
-
- /* main decoding loop */
- while (togo > 0)
- {
- /* last block finished, new block expected */
- if (m_state.block_remaining == 0)
- {
- // TODO may screw something up here
- if (m_state.block_type == LzxConstants.BLOCKTYPE.UNCOMPRESSED)
- {
- if ((m_state.block_length & 1) == 1) inData.ReadByte(); /* realign bitstream to word */
- bitbuf.InitBitStream();
- }
-
- m_state.block_type = (LzxConstants.BLOCKTYPE)bitbuf.ReadBits(3); ;
- i = bitbuf.ReadBits(16);
- j = bitbuf.ReadBits(8);
- m_state.block_remaining = m_state.block_length = (uint)((i << 8) | j);
-
- switch (m_state.block_type)
- {
- case LzxConstants.BLOCKTYPE.ALIGNED:
- for (i = 0, j = 0; i < 8; i++) { j = bitbuf.ReadBits(3); m_state.ALIGNED_len[i] = (byte)j; }
- MakeDecodeTable(LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
- m_state.ALIGNED_len, m_state.ALIGNED_table);
- /* rest of aligned header is same as verbatim */
- goto case LzxConstants.BLOCKTYPE.VERBATIM;
-
- case LzxConstants.BLOCKTYPE.VERBATIM:
- ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
- ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
- MakeDecodeTable(LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
- m_state.MAINTREE_len, m_state.MAINTREE_table);
- if (m_state.MAINTREE_len[0xE8] != 0) m_state.intel_started = 1;
-
- ReadLengths(m_state.LENGTH_len, 0, LzxConstants.NUM_SECONDARY_LENGTHS, bitbuf);
- MakeDecodeTable(LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
- m_state.LENGTH_len, m_state.LENGTH_table);
- break;
-
- case LzxConstants.BLOCKTYPE.UNCOMPRESSED:
- m_state.intel_started = 1; /* because we can't assume otherwise */
- bitbuf.EnsureBits(16); /* get up to 16 pad bits into the buffer */
- if (bitbuf.GetBitsLeft() > 16) inData.Seek(-2, SeekOrigin.Current); /* and align the bitstream! */
- byte hi, mh, ml, lo;
- lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
- R0 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
- lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
- R1 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
- lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
- R2 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
- break;
-
- default:
- return -1; // TODO throw proper exception
- }
- }
-
- /* buffer exhaustion check */
- if (inData.Position > (startpos + inLen))
- {
- /* it's possible to have a file where the next run is less than
- * 16 bits in size. In this case, the READ_HUFFSYM() macro used
- * in building the tables will exhaust the buffer, so we should
- * allow for this, but not allow those accidentally read bits to
- * be used (so we check that there are at least 16 bits
- * remaining - in this boundary case they aren't really part of
- * the compressed data)
- */
- //Debug.WriteLine("WTF");
-
- if (inData.Position > (startpos + inLen + 2) || bitbuf.GetBitsLeft() < 16) return -1; //TODO throw proper exception
- }
-
- while ((this_run = (int)m_state.block_remaining) > 0 && togo > 0)
- {
- if (this_run > togo) this_run = togo;
- togo -= this_run;
- m_state.block_remaining -= (uint)this_run;
-
- /* apply 2^x-1 mask */
- window_posn &= window_size - 1;
- /* runs can't straddle the window wraparound */
- if ((window_posn + this_run) > window_size)
- return -1; //TODO throw proper exception
-
- switch (m_state.block_type)
- {
- case LzxConstants.BLOCKTYPE.VERBATIM:
- while (this_run > 0)
- {
- main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
- LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
- bitbuf);
- if (main_element < LzxConstants.NUM_CHARS)
- {
- /* literal: 0 to NUM_CHARS-1 */
- window[window_posn++] = (byte)main_element;
- this_run--;
- }
- else
- {
- /* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
- main_element -= LzxConstants.NUM_CHARS;
-
- match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS;
- if (match_length == LzxConstants.NUM_PRIMARY_LENGTHS)
- {
- length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
- LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
- bitbuf);
- match_length += length_footer;
- }
- match_length += LzxConstants.MIN_MATCH;
-
- match_offset = main_element >> 3;
-
- if (match_offset > 2)
- {
- /* not repeated offset */
- if (match_offset != 3)
- {
- extra = extra_bits[match_offset];
- verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
- match_offset = (int)position_base[match_offset] - 2 + verbatim_bits;
- }
- else
- {
- match_offset = 1;
- }
-
- /* update repeated offset LRU queue */
- R2 = R1; R1 = R0; R0 = (uint)match_offset;
- }
- else if (match_offset == 0)
- {
- match_offset = (int)R0;
- }
- else if (match_offset == 1)
- {
- match_offset = (int)R1;
- R1 = R0; R0 = (uint)match_offset;
- }
- else /* match_offset == 2 */
- {
- match_offset = (int)R2;
- R2 = R0; R0 = (uint)match_offset;
- }
-
- rundest = (int)window_posn;
- this_run -= match_length;
-
- /* copy any wrapped around source data */
- if (window_posn >= match_offset)
- {
- /* no wrap */
- runsrc = rundest - match_offset;
- }
- else
- {
- runsrc = rundest + ((int)window_size - match_offset);
- copy_length = match_offset - (int)window_posn;
- if (copy_length < match_length)
- {
- match_length -= copy_length;
- window_posn += (uint)copy_length;
- while (copy_length-- > 0) window[rundest++] = window[runsrc++];
- runsrc = 0;
- }
- }
- window_posn += (uint)match_length;
-
- /* copy match data - no worries about destination wraps */
- while (match_length-- > 0) window[rundest++] = window[runsrc++];
- }
- }
- break;
-
- case LzxConstants.BLOCKTYPE.ALIGNED:
- while (this_run > 0)
- {
- main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
- LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
- bitbuf);
-
- if (main_element < LzxConstants.NUM_CHARS)
- {
- /* literal 0 to NUM_CHARS-1 */
- window[window_posn++] = (byte)main_element;
- this_run--;
- }
- else
- {
- /* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
- main_element -= LzxConstants.NUM_CHARS;
-
- match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS;
- if (match_length == LzxConstants.NUM_PRIMARY_LENGTHS)
- {
- length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
- LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
- bitbuf);
- match_length += length_footer;
- }
- match_length += LzxConstants.MIN_MATCH;
-
- match_offset = main_element >> 3;
-
- if (match_offset > 2)
- {
- /* not repeated offset */
- extra = extra_bits[match_offset];
- match_offset = (int)position_base[match_offset] - 2;
- if (extra > 3)
- {
- /* verbatim and aligned bits */
- extra -= 3;
- verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
- match_offset += (verbatim_bits << 3);
- aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
- LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
- bitbuf);
- match_offset += aligned_bits;
- }
- else if (extra == 3)
- {
- /* aligned bits only */
- aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
- LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
- bitbuf);
- match_offset += aligned_bits;
- }
- else if (extra > 0) /* extra==1, extra==2 */
- {
- /* verbatim bits only */
- verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
- match_offset += verbatim_bits;
- }
- else /* extra == 0 */
- {
- /* ??? */
- match_offset = 1;
- }
-
- /* update repeated offset LRU queue */
- R2 = R1; R1 = R0; R0 = (uint)match_offset;
- }
- else if (match_offset == 0)
- {
- match_offset = (int)R0;
- }
- else if (match_offset == 1)
- {
- match_offset = (int)R1;
- R1 = R0; R0 = (uint)match_offset;
- }
- else /* match_offset == 2 */
- {
- match_offset = (int)R2;
- R2 = R0; R0 = (uint)match_offset;
- }
-
- rundest = (int)window_posn;
- this_run -= match_length;
-
- /* copy any wrapped around source data */
- if (window_posn >= match_offset)
- {
- /* no wrap */
- runsrc = rundest - match_offset;
- }
- else
- {
- runsrc = rundest + ((int)window_size - match_offset);
- copy_length = match_offset - (int)window_posn;
- if (copy_length < match_length)
- {
- match_length -= copy_length;
- window_posn += (uint)copy_length;
- while (copy_length-- > 0) window[rundest++] = window[runsrc++];
- runsrc = 0;
- }
- }
- window_posn += (uint)match_length;
-
- /* copy match data - no worries about destination wraps */
- while (match_length-- > 0) window[rundest++] = window[runsrc++];
- }
- }
- break;
-
- case LzxConstants.BLOCKTYPE.UNCOMPRESSED:
- if ((inData.Position + this_run) > endpos) return -1; //TODO throw proper exception
- byte[] temp_buffer = new byte[this_run];
- inData.Read(temp_buffer, 0, this_run);
- temp_buffer.CopyTo(window, (int)window_posn);
- window_posn += (uint)this_run;
- break;
-
- default:
- return -1; //TODO throw proper exception
- }
- }
- }
-
- if (togo != 0) return -1; //TODO throw proper exception
- int start_window_pos = (int)window_posn;
- if (start_window_pos == 0) start_window_pos = (int)window_size;
- start_window_pos -= outLen;
- outData.Write(window, start_window_pos, outLen);
-
- m_state.window_posn = window_posn;
- m_state.R0 = R0;
- m_state.R1 = R1;
- m_state.R2 = R2;
-
- // TODO finish intel E8 decoding
- /* intel E8 decoding */
- if ((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0)
- {
- if (outLen <= 6 || m_state.intel_started == 0)
- {
- m_state.intel_curpos += outLen;
- }
- else
- {
- int dataend = outLen - 10;
- uint curpos = (uint)m_state.intel_curpos;
-
- m_state.intel_curpos = (int)curpos + outLen;
-
- while (outData.Position < dataend)
- {
- if (outData.ReadByte() != 0xE8) { curpos++; continue; }
- }
- }
- return -1;
- }
- return 0;
- }
-
- // READ_LENGTHS(table, first, last)
- // if(lzx_read_lens(LENTABLE(table), first, last, bitsleft))
- // return ERROR (ILLEGAL_DATA)
- //
-
- // TODO make returns throw exceptions
- private int MakeDecodeTable(uint nsyms, uint nbits, byte[] length, ushort[] table)
- {
- ushort sym;
- uint leaf;
- byte bit_num = 1;
- uint fill;
- uint pos = 0; /* the current position in the decode table */
- uint table_mask = (uint)(1 << (int)nbits);
- uint bit_mask = table_mask >> 1; /* don't do 0 length codes */
- uint next_symbol = bit_mask; /* base of allocation for long codes */
-
- /* fill entries for codes short enough for a direct mapping */
- while (bit_num <= nbits)
- {
- for (sym = 0; sym < nsyms; sym++)
- {
- if (length[sym] == bit_num)
- {
- leaf = pos;
-
- if ((pos += bit_mask) > table_mask) return 1; /* table overrun */
-
- /* fill all possible lookups of this symbol with the symbol itself */
- fill = bit_mask;
- while (fill-- > 0) table[leaf++] = sym;
- }
- }
- bit_mask >>= 1;
- bit_num++;
- }
-
- /* if there are any codes longer than nbits */
- if (pos != table_mask)
- {
- /* clear the remainder of the table */
- for (sym = (ushort)pos; sym < table_mask; sym++) table[sym] = 0;
-
- /* give ourselves room for codes to grow by up to 16 more bits */
- pos <<= 16;
- table_mask <<= 16;
- bit_mask = 1 << 15;
-
- while (bit_num <= 16)
- {
- for (sym = 0; sym < nsyms; sym++)
- {
- if (length[sym] == bit_num)
- {
- leaf = pos >> 16;
- for (fill = 0; fill < bit_num - nbits; fill++)
- {
- /* if this path hasn't been taken yet, 'allocate' two entries */
- if (table[leaf] == 0)
- {
- table[(next_symbol << 1)] = 0;
- table[(next_symbol << 1) + 1] = 0;
- table[leaf] = (ushort)(next_symbol++);
- }
- /* follow the path and select either left or right for next bit */
- leaf = (uint)(table[leaf] << 1);
- if (((pos >> (int)(15 - fill)) & 1) == 1) leaf++;
- }
- table[leaf] = sym;
-
- if ((pos += bit_mask) > table_mask) return 1;
- }
- }
- bit_mask >>= 1;
- bit_num++;
- }
- }
-
- /* full talbe? */
- if (pos == table_mask) return 0;
-
- /* either erroneous table, or all elements are 0 - let's find out. */
- for (sym = 0; sym < nsyms; sym++) if (length[sym] != 0) return 1;
- return 0;
- }
-
- // TODO throw exceptions instead of returns
- private void ReadLengths(byte[] lens, uint first, uint last, BitBuffer bitbuf)
- {
- uint x, y;
- int z;
-
- // hufftbl pointer here?
-
- for (x = 0; x < 20; x++)
- {
- y = bitbuf.ReadBits(4);
- m_state.PRETREE_len[x] = (byte)y;
- }
- MakeDecodeTable(LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS,
- m_state.PRETREE_len, m_state.PRETREE_table);
-
- for (x = first; x < last;)
- {
- z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
- LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf);
- if (z == 17)
- {
- y = bitbuf.ReadBits(4); y += 4;
- while (y-- != 0) lens[x++] = 0;
- }
- else if (z == 18)
- {
- y = bitbuf.ReadBits(5); y += 20;
- while (y-- != 0) lens[x++] = 0;
- }
- else if (z == 19)
- {
- y = bitbuf.ReadBits(1); y += 4;
- z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
- LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf);
- z = lens[x] - z; if (z < 0) z += 17;
- while (y-- != 0) lens[x++] = (byte)z;
- }
- else
- {
- z = lens[x] - z; if (z < 0) z += 17;
- lens[x++] = (byte)z;
- }
- }
- }
-
- private uint ReadHuffSym(ushort[] table, byte[] lengths, uint nsyms, uint nbits, BitBuffer bitbuf)
- {
- uint i, j;
- bitbuf.EnsureBits(16);
- if ((i = table[bitbuf.PeekBits((byte)nbits)]) >= nsyms)
- {
- j = (uint)(1 << (int)((sizeof(uint) * 8) - nbits));
- do
- {
- j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? (uint)1 : 0;
- if (j == 0) return 0; // TODO throw proper exception
- } while ((i = table[i]) >= nsyms);
- }
- j = lengths[i];
- bitbuf.RemoveBits((byte)j);
-
- return i;
- }
-
- #region Our BitBuffer Class
- private class BitBuffer
- {
- uint buffer;
- byte bitsleft;
- Stream byteStream;
-
- public BitBuffer(Stream stream)
- {
- byteStream = stream;
- InitBitStream();
- }
-
- public void InitBitStream()
- {
- buffer = 0;
- bitsleft = 0;
- }
-
- public void EnsureBits(byte bits)
- {
- while (bitsleft < bits)
- {
- int lo = (byte)byteStream.ReadByte();
- int hi = (byte)byteStream.ReadByte();
- //int amount2shift = sizeof(uint)*8 - 16 - bitsleft;
- buffer |= (uint)(((hi << 8) | lo) << (sizeof(uint) * 8 - 16 - bitsleft));
- bitsleft += 16;
- }
- }
-
- public uint PeekBits(byte bits)
- {
- return (buffer >> ((sizeof(uint) * 8) - bits));
- }
-
- public void RemoveBits(byte bits)
- {
- buffer <<= bits;
- bitsleft -= bits;
- }
-
- public uint ReadBits(byte bits)
- {
- uint ret = 0;
-
- if (bits > 0)
- {
- EnsureBits(bits);
- ret = PeekBits(bits);
- RemoveBits(bits);
- }
-
- return ret;
- }
-
- public uint GetBuffer()
- {
- return buffer;
- }
-
- public byte GetBitsLeft()
- {
- return bitsleft;
- }
- }
- #endregion
-
- struct LzxState
- {
- public uint R0, R1, R2; /* for the LRU offset system */
- public ushort main_elements; /* number of main tree elements */
- public int header_read; /* have we started decoding at all yet? */
- public LzxConstants.BLOCKTYPE block_type; /* type of this block */
- public uint block_length; /* uncompressed length of this block */
- public uint block_remaining; /* uncompressed bytes still left to decode */
- public uint frames_read; /* the number of CFDATA blocks processed */
- public int intel_filesize; /* magic header value used for transform */
- public int intel_curpos; /* current offset in transform space */
- public int intel_started; /* have we seen any translateable data yet? */
-
- public ushort[] PRETREE_table;
- public byte[] PRETREE_len;
- public ushort[] MAINTREE_table;
- public byte[] MAINTREE_len;
- public ushort[] LENGTH_table;
- public byte[] LENGTH_len;
- public ushort[] ALIGNED_table;
- public byte[] ALIGNED_len;
-
- // NEEDED MEMBERS
- // CAB actualsize
- // CAB window
- // CAB window_size
- // CAB window_posn
- public uint actual_size;
- public byte[] window;
- public uint window_size;
- public uint window_posn;
- }
- }
-
- /* CONSTANTS */
- struct LzxConstants
- {
- public const ushort MIN_MATCH = 2;
- public const ushort MAX_MATCH = 257;
- public const ushort NUM_CHARS = 256;
- public enum BLOCKTYPE
- {
- INVALID = 0,
- VERBATIM = 1,
- ALIGNED = 2,
- UNCOMPRESSED = 3
- }
- public const ushort PRETREE_NUM_ELEMENTS = 20;
- public const ushort ALIGNED_NUM_ELEMENTS = 8;
- public const ushort NUM_PRIMARY_LENGTHS = 7;
- public const ushort NUM_SECONDARY_LENGTHS = 249;
-
- public const ushort PRETREE_MAXSYMBOLS = PRETREE_NUM_ELEMENTS;
- public const ushort PRETREE_TABLEBITS = 6;
- public const ushort MAINTREE_MAXSYMBOLS = NUM_CHARS + 50 * 8;
- public const ushort MAINTREE_TABLEBITS = 12;
- public const ushort LENGTH_MAXSYMBOLS = NUM_SECONDARY_LENGTHS + 1;
- public const ushort LENGTH_TABLEBITS = 12;
- public const ushort ALIGNED_MAXSYMBOLS = ALIGNED_NUM_ELEMENTS;
- public const ushort ALIGNED_TABLEBITS = 7;
-
- public const ushort LENTABLE_SAFETY = 64;
- }
-
- /* EXCEPTIONS */
- class UnsupportedWindowSizeRange : Exception
- {
- }
-}
\ No newline at end of file
diff --git a/PCK-Studio/Classes/Utils/grf/xmemdecompress.cs b/PCK-Studio/Classes/Utils/grf/xmemdecompress.cs
deleted file mode 100644
index 764e3fc7..00000000
--- a/PCK-Studio/Classes/Utils/grf/xmemdecompress.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-// MonoGame - Copyright (C) The MonoGame Team
-// This file is subject to the terms and conditions defined in
-// file 'LICENSE.txt', which is part of this source code package.
-
-using System;
-using System.IO;
-using Microsoft.Xna.Framework.Content;
-
-namespace MonoGame.Framework.Utilities
-{
- internal class LzxDecoderStream : Stream
- {
- LzxDecoder dec;
- MemoryStream decompressedStream;
-
- public LzxDecoderStream(Stream input, int decompressedSize, int compressedSize)
- {
- dec = new LzxDecoder(16);
-
- // TODO: Rewrite using block decompression like Lz4DecoderStream
- Decompress(input, decompressedSize, compressedSize);
- }
-
- // Decompress into MemoryStream
- private void Decompress(Stream stream, int decompressedSize, int compressedSize)
- {
- //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
- // default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
- decompressedStream = new MemoryStream(decompressedSize);
- long startPos = stream.Position;
- long pos = startPos;
-
- while (pos - startPos < compressedSize)
- {
- // the compressed stream is seperated into blocks that will decompress
- // into 32Kb or some other size if specified.
- // normal, 32Kb output blocks will have a short indicating the size
- // of the block before the block starts
- // blocks that have a defined output will be preceded by a byte of value
- // 0xFF (255), then a short indicating the output size and another
- // for the block size
- // all shorts for these cases are encoded in big endian order
- int hi = stream.ReadByte();
- int lo = stream.ReadByte();
- int block_size = (hi << 8) | lo;
- int frame_size = 0x8000; // frame size is 32Kb by default
- // does this block define a frame size?
- if (hi == 0xFF)
- {
- hi = lo;
- lo = (byte)stream.ReadByte();
- frame_size = (hi << 8) | lo;
- hi = (byte)stream.ReadByte();
- lo = (byte)stream.ReadByte();
- block_size = (hi << 8) | lo;
- pos += 5;
- }
- else
- pos += 2;
-
- // either says there is nothing to decode
- if (block_size == 0 || frame_size == 0)
- break;
-
- dec.Decompress(stream, block_size, decompressedStream, frame_size);
- pos += block_size;
-
- // reset the position of the input just incase the bit buffer
- // read in some unused bytes
- stream.Seek(pos, SeekOrigin.Begin);
- }
-
- Console.WriteLine(decompressedStream.Position);
- Console.WriteLine(decompressedSize);
- //if (decompressedStream.Position != decompressedSize)
- //{
- // throw new Exception("Decompression failed.");
- //}
-
- decompressedStream.Seek(0, SeekOrigin.Begin);
- using (var fs = File.OpenWrite("xmem_test.grf"))
- {
- decompressedStream.CopyTo(fs);
- }
- decompressedStream.Seek(0, SeekOrigin.Begin);
- }
-
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- if (disposing)
- {
- decompressedStream.Dispose();
- }
- dec = null;
- decompressedStream = null;
- }
-
- #region Stream internals
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return decompressedStream.Read(buffer, offset, count);
- }
-
- public override bool CanRead
- {
- get { return true; }
- }
-
-
- public override bool CanSeek
- {
- get { return false; }
- }
-
- public override bool CanWrite
- {
- get { return false; }
- }
-
- public override void Flush()
- {
- }
-
- public override long Length
- {
- get { throw new NotSupportedException(); }
- }
-
- public override long Position
- {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotImplementedException();
- }
-
- public override void SetLength(long value)
- {
- throw new NotImplementedException();
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new NotImplementedException();
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Editor/GRFEditor.Designer.cs b/PCK-Studio/Forms/Editor/GameRuleFileEditor.Designer.cs
similarity index 90%
rename from PCK-Studio/Forms/Editor/GRFEditor.Designer.cs
rename to PCK-Studio/Forms/Editor/GameRuleFileEditor.Designer.cs
index 375a9638..4c79e93d 100644
--- a/PCK-Studio/Forms/Editor/GRFEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/GameRuleFileEditor.Designer.cs
@@ -1,6 +1,6 @@
namespace PckStudio.Forms.Editor
{
- partial class GRFEditor
+ partial class GameRuleFileEditor
{
///
/// Required designer variable.
@@ -29,7 +29,7 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GRFEditor));
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GameRuleFileEditor));
this.GrfTreeView = new System.Windows.Forms.TreeView();
this.MessageContextMenu = new MetroFramework.Controls.MetroContextMenu(this.components);
this.addGameRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -44,9 +44,11 @@
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.metroPanel1 = new MetroFramework.Controls.MetroPanel();
this.compressionLvlToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox();
+ this.compressionTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.compressionTypeComboBox = new System.Windows.Forms.ToolStripComboBox();
+ this.metroPanel1 = new MetroFramework.Controls.MetroPanel();
this.MessageContextMenu.SuspendLayout();
this.DetailContextMenu.SuspendLayout();
this.menuStrip1.SuspendLayout();
@@ -153,7 +155,8 @@
this.menuStrip1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
- this.compressionLvlToolStripMenuItem});
+ this.compressionLvlToolStripMenuItem,
+ this.compressionTypeToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(25, 60);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(450, 24);
@@ -172,10 +175,10 @@
//
// openToolStripMenuItem
//
- this.openToolStripMenuItem.Enabled = false;
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.openToolStripMenuItem.Text = "Open";
+ this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
//
// saveToolStripMenuItem
//
@@ -185,6 +188,43 @@
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
//
+ // compressionLvlToolStripMenuItem
+ //
+ this.compressionLvlToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStripComboBox1});
+ this.compressionLvlToolStripMenuItem.ForeColor = System.Drawing.SystemColors.Menu;
+ this.compressionLvlToolStripMenuItem.Name = "compressionLvlToolStripMenuItem";
+ this.compressionLvlToolStripMenuItem.Size = new System.Drawing.Size(106, 20);
+ this.compressionLvlToolStripMenuItem.Text = "Compression Lvl";
+ //
+ // toolStripComboBox1
+ //
+ this.toolStripComboBox1.Items.AddRange(new object[] {
+ "None",
+ "Compressed",
+ "Compressed + RLE",
+ "Compressed + RLE + CRC"});
+ this.toolStripComboBox1.Name = "toolStripComboBox1";
+ this.toolStripComboBox1.Size = new System.Drawing.Size(121, 23);
+ this.toolStripComboBox1.Text = "None";
+ //
+ // compressionTypeToolStripMenuItem
+ //
+ this.compressionTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.compressionTypeComboBox});
+ this.compressionTypeToolStripMenuItem.Name = "compressionTypeToolStripMenuItem";
+ this.compressionTypeToolStripMenuItem.Size = new System.Drawing.Size(116, 20);
+ this.compressionTypeToolStripMenuItem.Text = "Compression Type";
+ //
+ // compressionTypeComboBox
+ //
+ this.compressionTypeComboBox.Items.AddRange(new object[] {
+ "Zlib",
+ "Deflate",
+ "XMem"});
+ this.compressionTypeComboBox.Name = "compressionTypeComboBox";
+ this.compressionTypeComboBox.Size = new System.Drawing.Size(121, 23);
+ //
// metroPanel1
//
this.metroPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
@@ -205,26 +245,6 @@
this.metroPanel1.VerticalScrollbarSize = 10;
this.metroPanel1.Resize += new System.EventHandler(this.metroPanel1_Resize);
//
- // compressionLvlToolStripMenuItem
- //
- this.compressionLvlToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.toolStripComboBox1});
- this.compressionLvlToolStripMenuItem.ForeColor = System.Drawing.SystemColors.Menu;
- this.compressionLvlToolStripMenuItem.Name = "compressionLvlToolStripMenuItem";
- this.compressionLvlToolStripMenuItem.Size = new System.Drawing.Size(106, 20);
- this.compressionLvlToolStripMenuItem.Text = "Compression Lvl";
- //
- // toolStripComboBox1
- //
- this.toolStripComboBox1.Items.AddRange(new object[] {
- "None",
- "Compressed",
- "Compressed + RLE",
- "Compressed + RLE + CRC"});
- this.toolStripComboBox1.Name = "toolStripComboBox1";
- this.toolStripComboBox1.Size = new System.Drawing.Size(121, 23);
- this.toolStripComboBox1.Text = "Zlib";
- //
// GRFEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -274,5 +294,7 @@
private MetroFramework.Controls.MetroPanel metroPanel1;
private System.Windows.Forms.ToolStripMenuItem compressionLvlToolStripMenuItem;
private System.Windows.Forms.ToolStripComboBox toolStripComboBox1;
+ private System.Windows.Forms.ToolStripMenuItem compressionTypeToolStripMenuItem;
+ private System.Windows.Forms.ToolStripComboBox compressionTypeComboBox;
}
}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Editor/GRFEditor.cs b/PCK-Studio/Forms/Editor/GameRuleFileEditor.cs
similarity index 65%
rename from PCK-Studio/Forms/Editor/GRFEditor.cs
rename to PCK-Studio/Forms/Editor/GameRuleFileEditor.cs
index 00d8cf8d..fedfd8a3 100644
--- a/PCK-Studio/Forms/Editor/GRFEditor.cs
+++ b/PCK-Studio/Forms/Editor/GameRuleFileEditor.cs
@@ -5,81 +5,101 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using PckStudio.Classes.FileTypes;
-using PckStudio.Classes.IO.GRF;
using PckStudio.Forms.Additional_Popups.Grf;
using PckStudio.Classes.Misc;
+using OMI.Formats.GameRule;
+using OMI.Workers.GameRule;
+using System.Diagnostics;
+using PckStudio.Forms.Additional_Popups.Audio;
namespace PckStudio.Forms.Editor
{
- public partial class GRFEditor : MetroFramework.Forms.MetroForm
+ public partial class GameRuleFileEditor : MetroFramework.Forms.MetroForm
{
private PCKFile.FileData _pckfile;
- private GRFFile _file;
+ private GameRuleFile _file;
-
- private GRFEditor()
+ public GameRuleFileEditor()
{
InitializeComponent();
+ PromptForCompressionType();
}
- public GRFEditor(PCKFile.FileData file) : this()
+ private void PromptForCompressionType()
+ {
+ addCategory dialog = new addCategory(compressionTypeComboBox.Items.Cast().ToArray());
+ dialog.label2.Text = "Type";
+ dialog.button1.Text = "Ok";
+ if (dialog.ShowDialog() == DialogResult.OK)
+ compressionTypeComboBox.SelectedIndex = compressionTypeComboBox.Items.IndexOf(dialog.Category);
+ }
+
+ public GameRuleFileEditor(PCKFile.FileData file) : this()
{
_pckfile = file;
- using(var stream = new MemoryStream(file.Data))
+ using (var stream = new MemoryStream(file.Data))
{
- try
- {
- _file = GRFFileReader.Read(stream);
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- MessageBox.Show("Faild to open .grf/.grh file");
- }
+ _file = OpenGameRuleFile(stream, (GameRuleFile.CompressionType)compressionTypeComboBox.SelectedIndex);
}
}
- public GRFEditor(Stream stream) : this()
+ public GameRuleFileEditor(Stream stream) : this()
+ {
+ _file = OpenGameRuleFile(stream, (GameRuleFile.CompressionType)compressionTypeComboBox.SelectedIndex);
+ }
+
+ private GameRuleFile OpenGameRuleFile(Stream stream, GameRuleFile.CompressionType compressionType)
{
try
{
- _file = GRFFileReader.Read(stream);
+ var reader = new GameRuleFileReader(compressionType);
+ return reader.FromStream(stream);
}
catch (Exception ex)
{
- Console.WriteLine(ex.Message);
+ Debug.WriteLine(ex.Message);
MessageBox.Show("Faild to open .grf/.grh file");
}
+ return default!;
}
private void OnLoad(object sender, EventArgs e)
{
RPC.SetPresence("GRF Editor", "Editing a GRF File");
- toolStripComboBox1.SelectedIndex = (int)_file.CompressionLevel;
- loadGRFTreeView(GrfTreeView.Nodes, _file.Root);
+ ReloadGameRuleTree();
}
- private void loadGRFTreeView(TreeNodeCollection root, GRFFile.GameRule parentRule)
+ private void LoadGameRuleTree(TreeNodeCollection root, GameRuleFile.GameRule parentRule)
{
foreach (var rule in parentRule.ChildRules)
{
TreeNode node = new TreeNode(rule.Name);
node.Tag = rule;
root.Add(node);
- loadGRFTreeView(node.Nodes, rule);
+ LoadGameRuleTree(node.Nodes, rule);
+ }
+ }
+
+ private void ReloadGameRuleTree()
+ {
+ GrfTreeView.Nodes.Clear();
+ if (_file is not null)
+ {
+ toolStripComboBox1.SelectedIndex = (int)_file.FileHeader.CompressionLevel;
+ LoadGameRuleTree(GrfTreeView.Nodes, _file.Root);
}
}
private void GrfTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
- if (e.Node is TreeNode t && t.Tag is GRFFile.GameRule)
+ if (e.Node is TreeNode t && t.Tag is GameRuleFile.GameRule)
ReloadParameterTreeView();
}
private void ReloadParameterTreeView()
{
GrfParametersTreeView.Nodes.Clear();
- if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule)
+ if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GameRuleFile.GameRule rule)
foreach (var param in rule.Parameters)
{
GrfParametersTreeView.Nodes.Add(new TreeNode($"{param.Key}: {param.Value}") { Tag = param});
@@ -88,8 +108,8 @@ namespace PckStudio.Forms.Editor
private void addDetailContextMenuItem_Click(object sender, EventArgs e)
{
- if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GameRule)) return;
- var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GameRule;
+ if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GameRuleFile.GameRule)) return;
+ var grfTag = GrfTreeView.SelectedNode.Tag as GameRuleFile.GameRule;
AddParameter prompt = new AddParameter();
if (prompt.ShowDialog() == DialogResult.OK)
{
@@ -105,7 +125,7 @@ namespace PckStudio.Forms.Editor
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule &&
+ if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GameRuleFile.GameRule rule &&
GrfParametersTreeView.SelectedNode is TreeNode paramNode && paramNode.Tag is KeyValuePair pair &&
rule.Parameters.ContainsKey(pair.Key) && rule.Parameters.Remove(pair.Key))
{
@@ -123,7 +143,7 @@ namespace PckStudio.Forms.Editor
private void GrfDetailsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
- if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule rule &&
+ if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GameRuleFile.GameRule rule &&
GrfParametersTreeView.SelectedNode is TreeNode paramNode && paramNode.Tag is KeyValuePair param)
{
AddParameter prompt = new AddParameter(param.Key, param.Value, false);
@@ -137,9 +157,9 @@ namespace PckStudio.Forms.Editor
private void addGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
{
- bool isValidNode = GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule;
- GRFFile.GameRule parentRule = isValidNode
- ? GrfTreeView.SelectedNode.Tag as GRFFile.GameRule
+ bool isValidNode = GrfTreeView.SelectedNode is TreeNode t && t.Tag is GameRuleFile.GameRule;
+ var parentRule = isValidNode
+ ? GrfTreeView.SelectedNode.Tag as GameRuleFile.GameRule
: _file.Root;
TreeNodeCollection root = isValidNode
@@ -164,11 +184,11 @@ namespace PckStudio.Forms.Editor
private void removeGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GRFFile.GameRule tag && removeTag(tag))
+ if (GrfTreeView.SelectedNode is TreeNode t && t.Tag is GameRuleFile.GameRule tag && removeTag(tag))
t.Remove();
}
- private bool removeTag(GRFFile.GameRule rule)
+ private bool removeTag(GameRuleFile.GameRule rule)
{
_ = rule.Parent ?? throw new ArgumentNullException(nameof(rule.Parent));
foreach (var subTag in rule.ChildRules.ToList())
@@ -184,7 +204,7 @@ namespace PckStudio.Forms.Editor
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (_file.IsWorld)
+ if (_file.FileHeader.unknownData[3] != 0)
{
MessageBox.Show("World grf saving is currently unsupported");
return;
@@ -193,7 +213,11 @@ namespace PckStudio.Forms.Editor
{
try
{
- GRFFileWriter.Write(stream, _file, (GRFFile.CompressionType)toolStripComboBox1.SelectedIndex/*GRFFile.eCompressionType.ZlibRleCrc*/);
+ var writer = new GameRuleFileWriter(
+ _file,
+ (GameRuleFile.CompressionLevel)toolStripComboBox1.SelectedIndex,
+ (GameRuleFile.CompressionType)compressionTypeComboBox.SelectedIndex);
+ writer.WriteToStream(stream);
_pckfile?.SetData(stream.ToArray());
MessageBox.Show("Saved!");
}
@@ -213,5 +237,20 @@ namespace PckStudio.Forms.Editor
// good enough
metroLabel2.Location = new Point(metroPanel1.Size.Width / 2 + 25, metroLabel2.Location.Y);
}
+
+ private void openToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog dialog = new OpenFileDialog();
+ dialog.Filter = "Game Rule File|*.grf";
+ PromptForCompressionType();
+ if (dialog.ShowDialog(this) == DialogResult.OK)
+ {
+ using (var fs = File.OpenRead(dialog.FileName))
+ {
+ _file = OpenGameRuleFile(fs, (GameRuleFile.CompressionType)compressionTypeComboBox.SelectedIndex);
+ ReloadGameRuleTree();
+ }
+ }
+ }
}
}
diff --git a/PCK-Studio/Forms/Editor/GRFEditor.resx b/PCK-Studio/Forms/Editor/GameRuleFileEditor.resx
similarity index 100%
rename from PCK-Studio/Forms/Editor/GRFEditor.resx
rename to PCK-Studio/Forms/Editor/GameRuleFileEditor.resx
diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs
index 7fd6aea1..bc972e83 100644
--- a/PCK-Studio/MainForm.cs
+++ b/PCK-Studio/MainForm.cs
@@ -8,11 +8,12 @@ using System.Drawing.Drawing2D;
using System.Diagnostics;
using System.Drawing.Imaging;
+using OMI.Formats.GameRule;
+using OMI.Workers.GameRule;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.LOC;
using PckStudio.Classes.IO.PCK;
-using PckStudio.Classes.IO.GRF;
using PckStudio.Classes.Utils;
using PckStudio.Classes.Utils.ARC;
using PckStudio.Classes._3ds.Utils;
@@ -372,7 +373,7 @@ namespace PckStudio
private void HandleGameRuleFile(PCKFile.FileData file)
{
- using GRFEditor grfEditor = new GRFEditor(file);
+ using GameRuleFileEditor grfEditor = new GameRuleFileEditor(file);
wasModified = grfEditor.ShowDialog(this) == DialogResult.OK;
UpdateRPC();
}
@@ -1256,7 +1257,7 @@ namespace PckStudio
{
var newPck = InitializeTexturePack(packId, packVersion, packName, res, true);
var gameRuleFile = newPck.CreateNew("GameRules.grf", PCKFile.FileData.FileType.GameRulesFile);
- var grfFile = new GRFFile();
+ var grfFile = new GameRuleFile();
grfFile.AddRule("MapOptions",
new KeyValuePair("seed", "0"),
new KeyValuePair("baseSaveName", string.Empty),
@@ -1272,8 +1273,9 @@ namespace PckStudio
new KeyValuePair("spawnZ", "0")
);
using (var stream = new MemoryStream())
- {
- GRFFileWriter.Write(stream, grfFile, GRFFile.CompressionType.None);
+ {
+ var writer = new GameRuleFileWriter(grfFile);
+ writer.WriteToStream(stream);
gameRuleFile.SetData(stream.ToArray());
}
return newPck;
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 34b3b86e..85ddb6fd 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -176,7 +176,6 @@
-
@@ -195,8 +194,6 @@
-
-
@@ -232,8 +229,6 @@
-
-
Form
@@ -342,11 +337,11 @@
AdvancedOptions.cs
-
+
Form
-
- GRFEditor.cs
+
+ GameRuleFileEditor.cs
Form
@@ -561,8 +556,8 @@
AdvancedOptions.cs
Designer
-
- GRFEditor.cs
+
+ GameRuleFileEditor.cs
AddParameter.cs
@@ -772,9 +767,6 @@
13.0.2
-
- 1.4.1
-
4.5.0
diff --git a/Vendor/OMI-Lib b/Vendor/OMI-Lib
index e2fa983a..16280e2f 160000
--- a/Vendor/OMI-Lib
+++ b/Vendor/OMI-Lib
@@ -1 +1 @@
-Subproject commit e2fa983abc567498059bcbf858f7a638fe006b74
+Subproject commit 16280e2f0a738bbbebc233151fe382047ab3da2d