Merge 'use-OMI-lib' into 'main'

This commit is contained in:
miku-666
2023-03-13 16:41:02 +01:00
55 changed files with 693 additions and 3922 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "OMI-Lib"]
path = Vendor/OMI-Lib
url = https://github.com/PhoenixARC/-OMI-Filetype-Library.git

View File

@@ -1,10 +0,0 @@
using System.Collections.Generic;
namespace PckStudio.Classes.FileTypes
{
// filepath to file data
public class ConsoleArchive : Dictionary<string, byte[]>
{
public int SizeOfFile(string filepath) => this[filepath].Length;
}
}

View File

@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class BehaviourFile
{
public List<RiderPositionOverride> entries { get; } = new List<RiderPositionOverride>();
public class RiderPositionOverride
{
public string name;
public List<PositionOverride> overrides { get; }
public RiderPositionOverride(string name)
{
this.name = name;
overrides = new List<PositionOverride>();
}
public class PositionOverride
{
public bool EntityIsTamed;
public bool EntityHasSaddle;
public float x, y, z;
}
}
}
}

View File

@@ -1,44 +0,0 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class COLFile
{
public class ColorEntry
{
public readonly string name;
public uint color;
public ColorEntry(string name, uint color)
{
this.name = name;
this.color = color;
}
}
public class ExtendedColorEntry : ColorEntry
{
public uint color_b;
public uint color_c;
// Water entries consist of three colors
// color_a - the surface of the water
// color_b - the color displayed underwater
// color_c - the color for the distant "fog" displayed while underwater
public ExtendedColorEntry(string name, uint color_a, uint color_b, uint color_c) : base(name, color_a)
{
this.color_b = color_b;
this.color_c = color_c;
}
}
public bool hasWaterTable;
public List<ColorEntry> entries = new List<ColorEntry>();
public List<ExtendedColorEntry> waterEntries = new List<ExtendedColorEntry>();
}
}

View File

@@ -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,
}
/// <summary>
/// Initializes a new GRFFile as a non-world grf file
/// </summary>
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
{
/// <summary> Contains all valid Parameter names </summary>
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<string, string> Parameters { get; } = new Dictionary<string, string>();
public List<GameRule> ChildRules { get; } = new List<GameRule>();
public GameRule(string name, GameRule parent)
{
Name = name;
Parent = parent;
}
public GameRule AddRule(string gameRuleName) => AddRule(gameRuleName, false);
/// <summary>Adds a new gamerule</summary>
/// <param name="gameRuleName">Game rule to add</param>
/// <param name="validate">Wether to check the given game rule</param>
/// <returns>The Added GRFTag</returns>
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<string,string>[] 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<GameRule> 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<string, string>[] parameters)
=> Root.AddRule(gameRuleName, parameters);
}
}

View File

@@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class LOCFile
{
public class InvalidLanguageException : Exception
{
public string Language { get; }
public InvalidLanguageException(string message, string language) : base(message)
{
Language = language;
}
}
public static readonly string[] ValidLanguages = new string[]
{
"cs-CS",
"cs-CZ",
"da-CH",
"da-DA",
"da-DK",
"de-AT",
"de-DE",
"el-EL",
"el-GR",
"en-AU",
"en-CA",
"en-EN",
"en-GB",
"en-GR",
"en-IE",
"en-NZ",
"en-US",
"es-ES",
"es-MX",
"fi-BE",
"fi-CH",
"fi-FI",
"fr-FR",
"fr-CA",
"it-IT",
"ja-JP",
"ko-KR",
"la-LAS",
"no-NO",
"nb-NO",
"nl-NL",
"nl-BE",
"pl-PL",
"pt-BR",
"pt-PT",
"ru-RU",
"sk-SK",
"sv-SE",
"tr-TR",
"zh-CN",
"zh-HK",
"zh-SG",
"zh-TW",
"zh-CHT",
"zh-HanS",
"zh-HanT",
};
private Dictionary<string, Dictionary<string, string>> _lockeys = new Dictionary<string, Dictionary<string, string>>();
private List<string> _languages = new List<string>(ValidLanguages.Length);
public Dictionary<string, Dictionary<string, string>> LocKeys => _lockeys;
public List<string> Languages => _languages;
public void InitializeDefault(string packName)
=> Initialize("en-EN", ("IDS_DISPLAY_NAME", packName));
public void Initialize(string language, params (string, string)[] locKeyValuePairs)
{
AddLanguage(language);
foreach (var locKeyValue in locKeyValuePairs)
AddLocKey(locKeyValue.Item1, locKeyValue.Item2);
}
private Dictionary<string, string> GetTranslation(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
LocKeys.Add(locKey, new Dictionary<string, string>());
return LocKeys[locKey];
}
public Dictionary<string, string> GetLocEntries(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
throw new KeyNotFoundException("Loc key not found");
return LocKeys[locKey];
}
public bool HasLocEntry(string locKey)
=> LocKeys.ContainsKey(locKey);
public string GetLocEntry(string locKey, string language)
{
if (!LocKeys.ContainsKey(locKey))
throw new KeyNotFoundException(nameof(locKey));
if (!Languages.Contains(language)) throw new KeyNotFoundException("Language Entry not found");
return GetTranslation(locKey)[language]?? string.Empty;
}
public void SetLocEntry(string locKey, string value)
{
foreach (var language in Languages)
{
GetTranslation(locKey)[language] = value;
}
}
public void SetLocEntry(string locKey, string language, string value)
{
if (!Languages.Contains(language))
throw new KeyNotFoundException(nameof(language));
GetTranslation(locKey)[language] = value;
}
public bool AddLocKey(string locKey, string value)
{
if (LocKeys.ContainsKey(locKey))
return false;
Languages.ForEach( language => SetLocEntry(locKey, language, value) );
return true;
}
public bool RemoveLocKey(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
return false;
return LocKeys.Remove(locKey);
}
public void AddLanguage(string language)
{
if (!ValidLanguages.Contains(language))
throw new InvalidLanguageException("Invalid language", language);
if (Languages.Contains(language))
throw new InvalidLanguageException("Language already exists", language);
Languages.Add(language);
foreach(var key in LocKeys.Keys)
SetLocEntry(key, language, "");
}
public void RemoveLanguage(string language)
{
if (!ValidLanguages.Contains(language))
throw new InvalidLanguageException("Invalid language", language);
if (!Languages.Contains(language))
throw new InvalidLanguageException("Language doesn't exist", language);
if (Languages.Remove(language))
foreach (var translation in LocKeys.Values)
translation.Remove(language);
}
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class MaterialsFile
{
public List<MaterialEntry> entries { get; } = new List<MaterialEntry>();
public struct MaterialEntry
{
public string name;
public string material_type;
public MaterialEntry(string name, string material_type) : this()
{
this.name = name;
this.material_type = material_type;
}
}
}
}

View File

@@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
namespace PckStudio.Classes.FileTypes
{
[Serializable]
internal class ModelNotFoundException : Exception
{
public ModelNotFoundException()
{
}
public ModelNotFoundException(string message) : base(message)
{
}
public ModelNotFoundException(string message, Exception innerException) : base(message, innerException)
{
}
protected ModelNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
public class ModelFile
{
public List<Model> Models { get; } = new List<Model>();
public void AddModel(Model model)
{
Models.Add(model);
}
bool Contains(string name) => Models.FindIndex(m => m.name == name) > -1;
/// <exception cref="ModelNotFoundException"></exception>
Model GetModelByName(string name)
{
return Contains(name) ? Models.First(m => m.name.Equals(name)) : throw new ModelNotFoundException(nameof(name));
}
public struct Model
{
public readonly string name;
public Size textureSize;
public List<Part> parts { get; } = new List<Part>();
public Model(string name, int textureWidth, int textureHeight)
{
this.name = name;
textureSize = new Size(textureWidth, textureHeight);
}
public struct Part
{
public string name;
public (float x, float y, float z) position;
public (float yaw, float pitch, float roll) rotation;
public List<Box> Boxes { get; } = new List<Box>();
public struct Box
{
public (float x, float y, float z) Position;
public (int width, int height, int length) Size;
public float U, V;
public float Scale;
public bool Mirror;
public Box((float x, float y, float z) position,
(int width, int height, int length) size,
float u, float v, float scale, bool mirror)
{
Position = position;
Size = size;
U = u;
V = v;
Scale = scale;
Mirror = mirror;
}
}
public Part(string name,
(float x, float y, float z) pos,
(float yaw, float pitch, float roll) rot) : this(name)
{
position = pos;
rotation = rot;
}
public Part(string name)
{
this.name = name;
this.position = (0, 0, 0);
this.rotation = (0, 0, 0);
}
public void AddBox((float x, float y, float z) position,
(int width, int height, int length) size,
float u, float v, float scale, bool mirror)
{
Boxes.Add(new Box(position, size, u, v, scale, mirror));
}
}
public void AddPart(Part part)
{
parts.Add(part);
}
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OMI.Formats.Languages;
namespace PckStudio.Classes.FileTypes
{

View File

@@ -1,171 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace PckStudio.Classes.FileTypes
{
public class PCKFile
{
public int type { get; }
public List<FileData> Files { get; } = new List<FileData>();
public const string XMLVersionString = "XMLVERSION";
public class FileData
{
public enum FileType : int
{
SkinFile = 0, // *.png
CapeFile = 1, // *.png
TextureFile = 2, // *.png
UIDataFile = 3, // *.fui ????
/// <summary>
/// "0" file
/// </summary>
InfoFile = 4,
/// <summary>
/// (x16|x32|x64)Info.pck
/// </summary>
TexturePackInfoFile = 5,
/// <summary>
/// languages.loc/localisation.loc
/// </summary>
LocalisationFile = 6,
/// <summary>
/// GameRules.grf
/// </summary>
GameRulesFile = 7,
/// <summary>
/// audio.pck
/// </summary>
AudioFile = 8,
/// <summary>
/// colours.col
/// </summary>
ColourTableFile = 9,
/// <summary>
/// GameRules.grh
/// </summary>
GameRulesHeader = 10,
/// <summary>
/// Skins.pck
/// </summary>
SkinDataFile = 11,
/// <summary>
/// models.bin
/// </summary>
ModelsFile = 12,
/// <summary>
/// behaviours.bin
/// </summary>
BehavioursFile = 13,
/// <summary>
/// entityMaterials.bin
/// </summary>
MaterialFile = 14,
}
public string Filename {
get => filename;
set => filename = value.Replace('\\', '/');
}
public FileType Filetype { get; set; }
public byte[] Data => _data;
public int Size => _data is null ? 0 : _data.Length;
public PCKProperties Properties { get; } = new PCKProperties();
private string filename;
private byte[] _data = new byte[0];
public FileData(string name, FileType type)
{
Filetype = type;
Filename = name;
}
public FileData(string name, FileType type, int dataSize) : this(name, type)
{
_data = new byte[dataSize];
}
public FileData(FileData file) : this(file.Filename, file.Filetype)
{
Properties = file.Properties;
SetData(file.Data);
}
public void SetData(byte[] data)
{
_data = data;
}
}
public PCKFile(int type)
{
this.type = type;
}
public List<string> GetPropertyList()
{
var LUT = new List<string>();
Files.ForEach(file => file.Properties.ForEach(pair =>
{
if (!LUT.Contains(pair.property))
LUT.Add(pair.property);
})
);
return LUT;
}
/// <summary>
/// Creates and adds new <see cref="FileData"/> object.
/// </summary>
/// <param name="name">Filename</param>
/// <param name="type">Filetype</param>
/// <returns>Added <see cref="FileData"/> object</returns>
public FileData CreateNew(string name, FileData.FileType type)
{
var file = new FileData(name, type);
Files.Add(file);
return file;
}
/// <summary>
/// Checks wether a file with <paramref name="filepath"/> and <paramref name="type"/> exists
/// </summary>
/// <param name="filepath">Path to the file in the pck</param>
/// <param name="type">Type of the file <see cref="FileData.FileType"/></param>
/// <returns>True when file exists, otherwise false </returns>
public bool HasFile(string filepath, FileData.FileType type)
{
return GetFile(filepath, type) is FileData;
}
/// <summary>
/// Gets the first file that Equals <paramref name="filepath"/> and <paramref name="type"/>
/// </summary>
/// <param name="filepath">Path to the file in the pck</param>
/// <param name="type">Type of the file <see cref="FileData.FileType"/></param>
/// <returns>FileData if found, otherwise null</returns>
public FileData GetFile(string filepath, FileData.FileType type)
{
return Files.FirstOrDefault(file => file.Filename.Equals(filepath) && file.Filetype.Equals(type));
}
/// <summary>
/// Tries to get a file with <paramref name="filepath"/> and <paramref name="type"/>.
/// </summary>
/// <param name="filepath">Path to the file in the pck</param>
/// <param name="type">Type of the file <see cref="FileData.FileType"/></param>
/// <param name="file">If succeeded <paramref name="file"/> will be non-null, otherwise null</param>
/// <returns>True if succeeded, otherwise false</returns>
public bool TryGetFile(string filepath, FileData.FileType type, out FileData file)
{
file = GetFile(filepath, type);
return file is FileData;
}
}
}

View File

@@ -1,57 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class PCKProperties : List<(string property, string value)>
{
public bool Contains(string property)
{
return HasProperty(property);
}
public bool HasProperty(string property)
{
return GetProperty(property) != default;
}
public (string, string) GetProperty(string property)
{
return this.FirstOrDefault(p => p.property.Equals(property));
}
public T GetPropertyValue<T>(string property, Func<string, T> func)
{
return func(GetPropertyValue(property));
}
public string GetPropertyValue(string property)
{
return GetProperty(property).Item2;
}
public (string, string)[] GetProperties(string property)
{
return FindAll(p => p.property == property).ToArray();
}
public bool HasMoreThanOneOf(string property)
{
return GetProperties(property).Length > 1;
}
public void SetProperty(string property, string value)
{
if (HasProperty(property))
{
this[IndexOf(GetProperty(property))] = (property, value);
return;
}
Add((property, value));
}
}
}

View File

@@ -1,49 +0,0 @@
using System;
using System.IO;
using System.Text;
using PckStudio.Classes.FileTypes;
namespace PckStudio.Classes.IO.ARC
{
internal class ARCFileReader : StreamDataReader<ConsoleArchive>
{
public static ConsoleArchive Read(Stream stream, bool useLittleEndian = false)
{
return new ARCFileReader(useLittleEndian).ReadFromStream(stream);
}
private ARCFileReader(bool useLittleEndian) : base(useLittleEndian)
{
}
protected override ConsoleArchive ReadFromStream(Stream stream)
{
ConsoleArchive _archive = new ConsoleArchive();
int numberOfFiles = ReadInt(stream);
for(int i = 0; i < numberOfFiles; i++)
{
string name = ReadString(stream);
int offset = ReadInt(stream);
int size = ReadInt(stream);
_archive[name] = ReadBytesFromPosition(stream, offset, size);
}
return _archive;
}
private string ReadString(Stream stream)
{
short length = ReadShort(stream);
return ReadString(stream, length, Encoding.UTF8);
}
private byte[] ReadBytesFromPosition(Stream stream, int position, int size)
{
long originalPOS = stream.Position;
if (stream.Seek(position, SeekOrigin.Begin) != position) throw new Exception();
byte[] data = ReadBytes(stream, size);
if (stream.Seek(originalPOS, SeekOrigin.Begin) != originalPOS) throw new Exception();
return data;
}
}
}

View File

@@ -1,47 +0,0 @@
using System.IO;
using System.Linq;
using System.Text;
using PckStudio.Classes.FileTypes;
namespace PckStudio.Classes.IO.ARC
{
internal class ARCFileWriter : StreamDataWriter
{
private ConsoleArchive _archive;
public static void Write(Stream stream, ConsoleArchive archive, bool useLittleEndian = false)
{
new ARCFileWriter(archive, useLittleEndian).WriteToStream(stream);
}
public ARCFileWriter(ConsoleArchive archive, bool useLittleEndian) : base(useLittleEndian)
{
_archive = archive;
}
protected override void WriteToStream(Stream stream)
{
var arc = _archive.ToArray();
WriteInt(stream, arc.Length);
int offset = 4 + arc.Sum(pair => 10 + pair.Key.Length);
foreach (var pair in arc)
{
int size = pair.Value.Length;
WriteString(stream, pair.Key);
WriteInt(stream, offset);
WriteInt(stream, size);
offset += size;
}
foreach (var pair in arc)
{
WriteBytes(stream, pair.Value);
}
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteString(stream, s, Encoding.ASCII);
}
}
}

View File

@@ -1,53 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.IO.Behaviour
{
public class BehavioursReader : StreamDataReader<BehaviourFile>
{
public static BehaviourFile Read(Stream stream)
{
return new BehavioursReader().ReadFromStream(stream);
}
protected BehavioursReader() : base(false) // Doesn't seem that Behaviours uses little endian
{
}
protected override BehaviourFile ReadFromStream(Stream stream)
{
BehaviourFile behaviourFile = new BehaviourFile();
_ = ReadInt(stream);
int riderPosOverrideCount = ReadInt(stream);
for (int i = 0; i < riderPosOverrideCount; i++)
{
string name = ReadString(stream);
var riderPositionOverride = new BehaviourFile.RiderPositionOverride(name);
int posOverideCount = ReadInt(stream);
for (; 0 < posOverideCount; posOverideCount--)
{
var posOverride = new BehaviourFile.RiderPositionOverride.PositionOverride();
posOverride.EntityIsTamed = ReadBool(stream);
posOverride.EntityHasSaddle = ReadBool(stream);
posOverride.x = ReadFloat(stream);
posOverride.y = ReadFloat(stream);
posOverride.z = ReadFloat(stream);
riderPositionOverride.overrides.Add(posOverride);
}
behaviourFile.entries.Add(riderPositionOverride);
}
return behaviourFile;
}
private string ReadString(Stream stream)
{
short length = ReadShort(stream);
return ReadString(stream, length, Encoding.ASCII);
}
}
}

View File

@@ -1,47 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.Behaviour
{
internal class BehavioursWriter : StreamDataWriter
{
private BehaviourFile behaviourFile;
public static void Write(Stream stream, BehaviourFile file)
{
new BehavioursWriter(file).WriteToStream(stream);
}
public BehavioursWriter(BehaviourFile file) : base(false)
{
behaviourFile = file;
}
protected override void WriteToStream(Stream stream)
{
WriteInt(stream, 0);
WriteInt(stream, behaviourFile.entries.Count);
foreach (var entry in behaviourFile.entries)
{
WriteString(stream, entry.name);
WriteInt(stream, entry.overrides.Count);
foreach(var posOverride in entry.overrides)
{
WriteBool(stream, posOverride.EntityIsTamed);
WriteBool(stream, posOverride.EntityHasSaddle);
WriteFloat(stream, posOverride.x);
WriteFloat(stream, posOverride.y);
WriteFloat(stream, posOverride.z);
}
}
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteString(stream, s, Encoding.ASCII);
}
}
}

View File

@@ -1,50 +0,0 @@
using PckStudio.Classes.FileTypes;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.COL
{
internal class COLFileReader : StreamDataReader<COLFile>
{
public static COLFile Read(Stream stream)
{
return new COLFileReader().ReadFromStream(stream);
}
private COLFileReader() : base(false)
{}
protected override COLFile ReadFromStream(Stream stream)
{
COLFile colourFile = new COLFile();
int has_water_colors = ReadInt(stream);
colourFile.hasWaterTable = has_water_colors > 0;
int color_entries = ReadInt(stream);
for (int i = 0; i < color_entries; i++)
{
string name = ReadString(stream);
uint color = ReadUInt(stream);
colourFile.entries.Add(new COLFile.ColorEntry(name, color));
}
if (has_water_colors > 0)
{
int water_color_entries = ReadInt(stream);
for (int i = 0; i < water_color_entries; i++)
{
string name = ReadString(stream);
uint colorA = ReadUInt(stream);
uint colorB = ReadUInt(stream);
uint colorC = ReadUInt(stream);
colourFile.waterEntries.Add(new COLFile.ExtendedColorEntry(name, colorA, colorB, colorC));
}
}
return colourFile;
}
private string ReadString(Stream stream)
{
short strlen = ReadShort(stream);
return ReadString(stream, strlen, Encoding.ASCII);
}
}
}

View File

@@ -1,50 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.COL
{
internal class COLFileWriter : StreamDataWriter
{
private COLFile colourFile;
public static void Write(Stream stream, COLFile file)
{
new COLFileWriter(file).WriteToStream(stream);
}
public COLFileWriter(COLFile file) : base(false)
{
colourFile = file;
}
protected override void WriteToStream(Stream stream)
{
WriteInt(stream, Convert.ToInt32(colourFile.waterEntries.Count > 0));
WriteInt(stream, colourFile.entries.Count);
foreach (var colorEntry in colourFile.entries)
{
WriteString(stream, colorEntry.name);
WriteUInt(stream, colorEntry.color);
}
if (colourFile.waterEntries.Count > 0)
{
WriteInt(stream, colourFile.waterEntries.Count);
foreach (var colorEntry in colourFile.waterEntries)
{
WriteString(stream, colorEntry.name);
WriteUInt(stream, colorEntry.color);
WriteUInt(stream, colorEntry.color_b);
WriteUInt(stream, colorEntry.color_c);
}
}
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteString(stream, s, Encoding.ASCII);
}
}
}

View File

@@ -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<GRFFile>
{
private IList<string> 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<byte>.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<string>(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);
}
}
}

View File

@@ -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<string> 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<string>();
PrepareLookUpTable(_grfFile.Root, StringLookUpTable);
}
private void PrepareLookUpTable(GRFFile.GameRule rule, List<string> 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<byte>.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<string, string> 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);
}
}
}

View File

@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using PckStudio.Classes.FileTypes;
namespace PckStudio.Classes.IO.LOC
{
internal class LOCFileReader : StreamDataReader<LOCFile>
{
internal LOCFile _file;
public static LOCFile Read(Stream stream)
{
return new LOCFileReader().ReadFromStream(stream);
}
private LOCFileReader() : base(false)
{
_file = new LOCFile();
}
protected override LOCFile ReadFromStream(Stream stream)
{
int loc_type = ReadInt(stream);
int language_count = ReadInt(stream);
bool lookUpKey = loc_type == 2;
List<string> keys = lookUpKey ? ReadKeys(stream) : null;
for (int i = 0; i < language_count; i++)
{
string language = ReadString(stream);
ReadInt(stream); // unknown value
_file.Languages.Add(language);
}
for (int i = 0; i < language_count; i++)
{
if (0 < ReadInt(stream))
stream.ReadByte();
string language = ReadString(stream);
if (!_file.Languages.Contains(language))
throw new KeyNotFoundException(nameof(language));
int count = ReadInt(stream);
for (int j = 0; j < count; j++)
{
string key = lookUpKey ? keys[j] : ReadString(stream);
string value = ReadString(stream);
_file.SetLocEntry(key, language, value);
}
}
return _file;
}
private List<string> ReadKeys(Stream stream)
{
bool useUniqueIds = Convert.ToBoolean(stream.ReadByte());
int keyCount = ReadInt(stream);
List<string> keys = new List<string>(keyCount);
for (int i = 0; i < keyCount; i++)
{
string key = useUniqueIds ? ReadInt(stream).ToString("X08") : ReadString(stream);
keys.Add(key);
}
return keys;
}
private string ReadString(Stream stream)
{
int length = ReadShort(stream);
return ReadString(stream, length, Encoding.UTF8);
}
}
}

View File

@@ -1,89 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.LOC
{
internal class LOCFileWriter : StreamDataWriter
{
private LOCFile _locfile;
private int _type;
public static void Write(Stream stream, LOCFile file, int type = 2)
{
new LOCFileWriter(file, type).WriteToStream(stream);
}
private LOCFileWriter(LOCFile file, int type) : base(false)
{
_type = type;
_locfile = file;
}
protected override void WriteToStream(Stream stream)
{
_ = _locfile ?? throw new ArgumentNullException(nameof(_locfile));
WriteInt(stream, _type);
WriteInt(stream, _locfile.Languages.Count);
if (_type == 2) WriteLocKeys(stream);
WriteLanguages(stream, _type);
WriteLanguageEntries(stream, _type);
}
private void WriteLocKeys(Stream stream)
{
stream.WriteByte(0); // dont use stringIds(ints)
WriteInt(stream, _locfile.LocKeys.Count);
foreach (var key in _locfile.LocKeys.Keys)
WriteString(stream, key);
}
private void WriteLanguages(Stream stream, int type)
{
foreach(var language in _locfile.Languages)
{
WriteString(stream, language);
//Calculate the size of the language entry
int size = 0;
size += sizeof(int); // null long
size += sizeof(byte); // null byte
size += (sizeof(short) + Encoding.UTF8.GetByteCount(language)); // language name string
size += sizeof(int); // key count
foreach (var locKey in _locfile.LocKeys.Keys)
{
if (type == 0) size += (2 + Encoding.UTF8.GetByteCount(locKey)); // loc key string
size += (2 + Encoding.UTF8.GetByteCount(_locfile.LocKeys[locKey][language])); // loc key string
}
WriteInt(stream, size);
};
}
private void WriteLanguageEntries(Stream stream, int type)
{
foreach (var language in _locfile.Languages)
{
WriteInt(stream, 0x6D696B75); // :P
stream.WriteByte(0); // <- only write when the previous written int was >0
WriteString(stream, language);
WriteInt(stream, _locfile.LocKeys.Keys.Count);
foreach(var locKey in _locfile.LocKeys.Keys)
{
if (type == 0) WriteString(stream, locKey);
WriteString(stream, _locfile.LocKeys[locKey][language]);
}
};
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, Convert.ToInt16(Encoding.UTF8.GetByteCount(s)));
WriteString(stream, s, Encoding.UTF8);
}
}
}

View File

@@ -1,42 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.IO.Materials
{
public class MaterialsReader : StreamDataReader<MaterialsFile>
{
public static MaterialsFile Read(Stream stream)
{
return new MaterialsReader().ReadFromStream(stream);
}
protected MaterialsReader() : base(false) // Doesn't seem that Behaviours uses little endian
{
}
protected override MaterialsFile ReadFromStream(Stream stream)
{
MaterialsFile materialsFile = new MaterialsFile();
_ = ReadInt(stream);
int entryCount = ReadInt(stream);
for (int i = 0; i < entryCount; i++)
{
string name = ReadString(stream);
string material_type = ReadString(stream);
materialsFile.entries.Add(new MaterialsFile.MaterialEntry(name, material_type));
}
return materialsFile;
}
private string ReadString(Stream stream)
{
short length = ReadShort(stream);
return ReadString(stream, length, Encoding.ASCII);
}
}
}

View File

@@ -1,39 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.Materials
{
internal class MaterialsWriter : StreamDataWriter
{
private MaterialsFile materialsFile;
public static void Write(Stream stream, MaterialsFile file)
{
new MaterialsWriter(file).WriteToStream(stream);
}
public MaterialsWriter(MaterialsFile file) : base(false)
{
materialsFile = file;
}
protected override void WriteToStream(Stream stream)
{
WriteInt(stream, 0);
WriteInt(stream, materialsFile.entries.Count);
foreach (var entry in materialsFile.entries)
{
WriteString(stream, entry.name);
WriteString(stream, entry.material_type);
}
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteString(stream, s, Encoding.ASCII);
}
}
}

View File

@@ -1,82 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.Model
{
public class ModelFileReader : StreamDataReader<ModelFile>
{
public static ModelFile Read(Stream stream)
{
return new ModelFileReader().ReadFromStream(stream);
}
private ModelFileReader() : base(false)
{
}
protected override ModelFile ReadFromStream(Stream stream)
{
var modelFile = new ModelFile();
int version = ReadInt(stream);
int modelCount = ReadInt(stream);
for (; 0 < modelCount; modelCount--)
{
string name = ReadString(stream);
int width = ReadInt(stream);
int height = ReadInt(stream);
var model = new ModelFile.Model(name, width, height);
int partCount = ReadInt(stream);
for (; 0 < partCount; partCount--)
{
string partName = ReadString(stream);
if (version > 1)
{
string partParentName = ReadString(stream);
Debug.WriteLineIf(partParentName.Length > 0, partParentName, category: nameof(ModelFileReader));
}
float x = ReadFloat(stream);
float y = ReadFloat(stream);
float z = ReadFloat(stream);
float yaw = ReadFloat(stream);
float pitch = ReadFloat(stream);
float roll = ReadFloat(stream);
var part = new ModelFile.Model.Part(partName, (x, y, z), (yaw, pitch, roll));
if (version > 0)
{
float _1 = ReadFloat(stream);
float _2 = ReadFloat(stream);
float _3 = ReadFloat(stream);
Debug.WriteLine(string.Format("{0}, {1}, {2}", _1, _2, _3), category: nameof(ModelFileReader));
}
int boxCount = ReadInt(stream);
for (; 0 < boxCount; boxCount--)
{
var pos = (ReadFloat(stream), ReadFloat(stream), ReadFloat(stream));
var size = (ReadInt(stream), ReadInt(stream), ReadInt(stream));
float u = ReadFloat(stream), v = ReadFloat(stream);
float scale = ReadFloat(stream);
bool mirrored = ReadBool(stream);
part.AddBox(pos, size, u, v, scale, mirrored);
}
model.AddPart(part);
}
modelFile.AddModel(model);
}
return modelFile;
}
private string ReadString(Stream stream)
{
short length = ReadShort(stream);
return ReadString(stream, length, Encoding.ASCII);
}
}
}

View File

@@ -1,89 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.IO.Model
{
internal class ModelFileWriter : StreamDataWriter
{
private ModelFile _modelFile;
private int _fileVersion;
public static void Write(Stream stream, ModelFile modelFile, int fileVersion = 1)
{
new ModelFileWriter(modelFile, fileVersion).WriteToStream(stream);
}
public ModelFileWriter(ModelFile modelFile, int fileVersion) : base(false)
{
_modelFile = modelFile;
if (fileVersion < 0 || fileVersion > 2)
throw new InvalidDataException(nameof(fileVersion));
_fileVersion = fileVersion;
}
protected override void WriteToStream(Stream stream)
{
WriteInt(stream, _fileVersion);
WriteInt(stream, _modelFile.Models.Count);
foreach (var model in _modelFile.Models)
{
WriteString(stream, model.name);
WriteInt(stream, model.textureSize.Width);
WriteInt(stream, model.textureSize.Height);
WriteInt(stream, model.parts.Count);
foreach (var part in model.parts)
{
WriteString(stream, part.name);
if (_fileVersion > 1)
{
WriteString(stream, model.parts[0].name.Equals(part.name) ? string.Empty : model.parts[0].name);
}
WriteFloat(stream, part.position.x);
WriteFloat(stream, part.position.y);
WriteFloat(stream, part.position.z);
WriteFloat(stream, part.rotation.yaw);
WriteFloat(stream, part.rotation.pitch);
WriteFloat(stream, part.rotation.roll);
if (_fileVersion > 0)
{
WriteFloat(stream, 0.0f);
WriteFloat(stream, 0.0f);
WriteFloat(stream, 0.0f);
}
WriteInt(stream, part.Boxes.Count);
foreach (var box in part.Boxes)
{
WriteFloat(stream, box.Position.x);
WriteFloat(stream, box.Position.y);
WriteFloat(stream, box.Position.z);
WriteInt(stream, box.Size.width);
WriteInt(stream, box.Size.height);
WriteInt(stream, box.Size.length);
WriteFloat(stream, box.U);
WriteFloat(stream, box.V);
WriteFloat(stream, box.Scale);
WriteBool(stream, box.Mirror);
}
}
}
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteString(stream, s, Encoding.ASCII);
}
}
}

View File

@@ -1,86 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.PCK
{
internal class PCKFileReader : StreamDataReader<PCKFile>
{
private PCKFile _file;
private IList<string> _propertyList;
public static PCKFile Read(Stream stream, bool isLittleEndian)
{
return new PCKFileReader(isLittleEndian).ReadFromStream(stream);
}
private PCKFileReader(bool isLittleEndian) : base(isLittleEndian)
{
}
protected override PCKFile ReadFromStream(Stream stream)
{
int pck_type = ReadInt(stream);
if (pck_type > 0xf0_00_00) // 03 00 00 00 == true
throw new OverflowException(nameof(pck_type));
else if (pck_type < 3) throw new Exception(pck_type.ToString());
_file = new PCKFile(pck_type);
ReadLookUpTable(stream);
ReadFileEntries(stream);
ReadFileContents(stream);
return _file;
}
private void ReadLookUpTable(Stream stream)
{
int count = ReadInt(stream);
_propertyList = new List<string>(count);
for (int i = 0; i < count; i++)
{
int index = ReadInt(stream);
string value = ReadString(stream);
_propertyList.Insert(index, value);
}
if (_propertyList.Contains(PCKFile.XMLVersionString))
Console.WriteLine(ReadInt(stream)); // xml version num ??
}
private void ReadFileEntries(Stream stream)
{
int file_entry_count = ReadInt(stream);
for (; 0 < file_entry_count; file_entry_count--)
{
int file_size = ReadInt(stream);
var file_type = (PCKFile.FileData.FileType)ReadInt(stream);
string file_name = ReadString(stream).Replace('\\', '/');
var entry = new PCKFile.FileData(file_name, file_type, file_size);
_file.Files.Add(entry);
}
}
private void ReadFileContents(Stream stream)
{
foreach (var file in _file.Files)
{
int property_count = ReadInt(stream);
for (; 0 < property_count; property_count--)
{
string key = _propertyList[ReadInt(stream)];
string value = ReadString(stream);
file.Properties.Add((key, value));
}
stream.Read(file.Data, 0, file.Size);
};
}
private string ReadString(Stream stream)
{
int len = ReadInt(stream);
string s = ReadString(stream, len, IsUsingLittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode);
ReadInt(stream); // padding
return s;
}
}
}

View File

@@ -1,81 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.PCK
{
internal class PCKFileWriter : StreamDataWriter
{
private PCKFile _pckfile;
private IList<string> _propertyList;
public static void Write(Stream stream, PCKFile file, bool isLittleEndian, bool isSkinsPCK = false)
{
new PCKFileWriter(file, isLittleEndian, isSkinsPCK).WriteToStream(stream);
}
private PCKFileWriter(PCKFile file, bool isLittleEndian, bool isSkinsPCK) : base(isLittleEndian)
{
_pckfile = file;
_propertyList = _pckfile.GetPropertyList();
if (!_propertyList.Contains(PCKFile.XMLVersionString) && isSkinsPCK)
_propertyList.Insert(0, PCKFile.XMLVersionString);
}
protected override void WriteToStream(Stream stream)
{
WriteInt(stream, _pckfile.type);
WriteLookUpTable(stream);
WriteFileEntries(stream);
WriteFileContents(stream);
}
private void WriteString(Stream stream, string s)
{
WriteInt(stream, s.Length);
WriteString(stream, s, IsUsingLittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode);
WriteInt(stream, 0); // padding
}
private void WriteLookUpTable(Stream stream)
{
WriteInt(stream, _propertyList.Count);
foreach (var entry in _propertyList)
{
WriteInt(stream, _propertyList.IndexOf(entry));
WriteString(stream, entry);
};
if (_propertyList.Contains(PCKFile.XMLVersionString))
WriteInt(stream, 0x1337); // :^)
}
private void WriteFileEntries(Stream stream)
{
WriteInt(stream, _pckfile.Files.Count);
foreach (var file in _pckfile.Files)
{
WriteInt(stream, file.Size);
WriteInt(stream, (int)file.Filetype);
WriteString(stream, file.Filename);
}
}
private void WriteFileContents(Stream stream)
{
foreach (var file in _pckfile.Files)
{
WriteInt(stream, file.Properties.Count);
foreach (var property in file.Properties)
{
if (!_propertyList.Contains(property.Item1))
throw new Exception("Tag not in Look Up Table: " + property.Item1);
WriteInt(stream, _propertyList.IndexOf(property.Item1));
WriteString(stream, property.Item2);
}
WriteBytes(stream, file.Data, file.Size);
}
}
}
}

View File

@@ -1,4 +1,4 @@
using PckStudio.Classes.IO.ARC;
using OMI.Workers.Archive;
using System.IO;
namespace PckStudio.Classes.Utils.ARC
@@ -7,10 +7,12 @@ namespace PckStudio.Classes.Utils.ARC
{
public static void Inject(Stream stream, (string filepath, byte[] data) entry)
{
var archive = ARCFileReader.Read(stream);
stream.Seek(0, SeekOrigin.Begin);
var reader = new ARCFileReader();
var archive = reader.FromStream(stream);
archive.Add(entry.filepath, entry.data);
ARCFileWriter.Write(stream, archive);
var writer = new ARCFileWriter(archive);
stream.Seek(0, SeekOrigin.Begin);
writer.WriteToStream(stream);
}
}
}

View File

@@ -1,212 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace PckStudio.Classes.Utils;
///! Credits
///! <see cref="https://nicoschertler.wordpress.com/2014/06/04/generic-run-length-encoding-rle-for-c/"/>
/// <summary>
/// Provides the RLE codec for any integer data type.
/// </summary>
/// <typeparam name="T">The data's type. Must be an integer type or an ArgumentException will be thrown</typeparam>
static class RLE<T> where T : struct, IConvertible
{
/// <summary>
/// This is the marker that identifies a compressed run
/// </summary>
private static T rleMarker;
/// <summary>
/// A run can be at most as long as the marker - 1
/// </summary>
private static ulong maxLength;
static RLE()
{
GetMaxValues();
}
/// <summary>
/// RLE-Encodes a data set.
/// </summary>
/// <param name="data">The data to encode</param>
/// <returns>Encoded data</returns>
public static IEnumerable<T> Encode(IEnumerable<T> 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;
}
/// <summary>
/// Decodes RLE-encoded data
/// </summary>
/// <param name="data">RLE-encoded data</param>
/// <returns>The original data</returns>
public static IEnumerable<T> Decode(IEnumerable<T> 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<T> 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");
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 <http://www.opensource.org/licenses/ms-pl.html>.
*/
#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
{
}
}

View File

@@ -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
}
}

View File

@@ -17,12 +17,13 @@ using PckStudio.Forms.Utilities;
using PckStudio.Classes.Extentions;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Editor
{
public partial class AnimationEditor : MetroForm
{
PCKFile.FileData animationFile;
PckFile.FileData animationFile;
Animation currentAnimation;
AnimationPlayer player;
@@ -237,7 +238,7 @@ namespace PckStudio.Forms.Editor
}
}
public AnimationEditor(PCKFile.FileData file)
public AnimationEditor(PckFile.FileData file)
{
InitializeComponent();

View File

@@ -13,6 +13,8 @@ using PckStudio.Classes;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.PCK;
using PckStudio.Forms.Additional_Popups.Audio;
using OMI.Formats.Languages;
using OMI.Formats.Pck;
// Audio Editor by MattNL
// additional work and optimization by Miku-666
@@ -23,7 +25,7 @@ namespace PckStudio.Forms.Editor
{
public string defaultType = "yes";
PCKAudioFile audioFile = null;
PCKFile.FileData audioPCK;
PckFile.FileData audioPCK;
LOCFile loc;
bool _isLittleEndian = false;
MainForm parent = null;
@@ -52,7 +54,7 @@ namespace PckStudio.Forms.Editor
return (PCKAudioFile.AudioCategory.EAudioType)Categories.IndexOf(category);
}
public AudioEditor(PCKFile.FileData file, LOCFile locFile, bool isLittleEndian)
public AudioEditor(PckFile.FileData file, LOCFile locFile, bool isLittleEndian)
{
InitializeComponent();
loc = locFile;

View File

@@ -6,17 +6,18 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.Behaviour;
using PckStudio.Forms.Additional_Popups.EntityForms;
using Newtonsoft.Json.Linq;
using OMI.Formats.Behaviour;
using OMI.Workers.Behaviour;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Editor
{
public partial class BehaviourEditor : MetroForm
{
// Behaviours File Format research by Miku and MattNL
private readonly PCKFile.FileData _file;
private readonly PckFile.FileData _file;
BehaviourFile behaviourFile;
void SetUpTree()
@@ -55,14 +56,15 @@ namespace PckStudio.Forms.Editor
treeView1.EndUpdate();
}
public BehaviourEditor(PCKFile.FileData file)
public BehaviourEditor(PckFile.FileData file)
{
InitializeComponent();
_file = file;
using (var stream = new MemoryStream(file.Data))
{
behaviourFile = BehavioursReader.Read(stream);
var reader = new BehavioursReader();
behaviourFile = reader.FromStream(stream);
}
treeView1.ImageList = new ImageList();
@@ -267,7 +269,8 @@ namespace PckStudio.Forms.Editor
}
}
BehavioursWriter.Write(stream, behaviourFile);
var writer = new BehavioursWriter(behaviourFile);
writer.WriteToStream(stream);
_file.SetData(stream.ToArray());
}
DialogResult = DialogResult.OK;

View File

@@ -5,32 +5,34 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.COL;
using OMI.Formats.Color;
using OMI.Formats.Pck;
using OMI.Workers.Color;
namespace PckStudio.Forms.Editor
{
public partial class COLEditor : MetroForm
{
COLFile default_colourfile = COLFileReader.Read(new MemoryStream(Properties.Resources.tu69colours));
COLFile colourfile;
COLFile.ColorEntry clipboard_color;
ColorContainer default_colourfile;
ColorContainer colourfile;
ColorContainer.Color clipboard_color;
private readonly PCKFile.FileData _file;
private readonly PckFile.FileData _file;
List<TreeNode> colorCache = new List<TreeNode>();
List<TreeNode> waterCache = new List<TreeNode>();
List<TreeNode> underwaterCache = new List<TreeNode>();
List<TreeNode> fogCache = new List<TreeNode>();
public COLEditor(PCKFile.FileData file)
public COLEditor(PckFile.FileData file)
{
InitializeComponent();
_file = file;
using(var stream = new MemoryStream(file.Data))
{
colourfile = COLFileReader.Read(stream);
var reader = new COLFileReader();
colourfile = reader.FromStream(stream);
}
TU12ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 0);
@@ -48,28 +50,30 @@ namespace PckStudio.Forms.Editor
_1_9_1ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 12);
SetUpTable(false);
}
SetUpDefaultFile(null, EventArgs.Empty, 11);
}
private void SetUpDefaultFile(object sender, EventArgs e, int ID)
{
var result = MessageBox.Show(this, "This function will set up your colour table to match that of the chosen version. You may lose some entries in the table. Are you sure you would like to continue?", "Target update version?", MessageBoxButtons.YesNo);
if (result == DialogResult.No) return;
var reader = new COLFileReader();
switch(ID)
switch (ID)
{
case 0: using (var stream = new MemoryStream(Properties.Resources.tu12colours)) default_colourfile = COLFileReader.Read(stream); break;
case 1: using (var stream = new MemoryStream(Properties.Resources.tu13colours)) default_colourfile = COLFileReader.Read(stream); break;
case 2: using (var stream = new MemoryStream(Properties.Resources.tu14colours)) default_colourfile = COLFileReader.Read(stream); break;
case 3: using (var stream = new MemoryStream(Properties.Resources.tu19colours)) default_colourfile = COLFileReader.Read(stream); break;
case 4: using (var stream = new MemoryStream(Properties.Resources.tu31colours)) default_colourfile = COLFileReader.Read(stream); break;
case 5: using (var stream = new MemoryStream(Properties.Resources.tu32colours)) default_colourfile = COLFileReader.Read(stream); break;
case 6: using (var stream = new MemoryStream(Properties.Resources.tu43colours)) default_colourfile = COLFileReader.Read(stream); break;
case 7: using (var stream = new MemoryStream(Properties.Resources.tu46colours)) default_colourfile = COLFileReader.Read(stream); break;
case 8: using (var stream = new MemoryStream(Properties.Resources.tu51colours)) default_colourfile = COLFileReader.Read(stream); break;
case 9: using (var stream = new MemoryStream(Properties.Resources.tu53colours)) default_colourfile = COLFileReader.Read(stream); break;
case 10: using (var stream = new MemoryStream(Properties.Resources.tu54colours)) default_colourfile = COLFileReader.Read(stream); break;
case 11: using (var stream = new MemoryStream(Properties.Resources.tu69colours)) default_colourfile = COLFileReader.Read(stream); break;
case 12: using (var stream = new MemoryStream(Properties.Resources._1_91_colours)) default_colourfile = COLFileReader.Read(stream); break;
case 0: using (var stream = new MemoryStream(Properties.Resources.tu12colours)) default_colourfile = reader.FromStream(stream); break;
case 1: using (var stream = new MemoryStream(Properties.Resources.tu13colours)) default_colourfile = reader.FromStream(stream); break;
case 2: using (var stream = new MemoryStream(Properties.Resources.tu14colours)) default_colourfile = reader.FromStream(stream); break;
case 3: using (var stream = new MemoryStream(Properties.Resources.tu19colours)) default_colourfile = reader.FromStream(stream); break;
case 4: using (var stream = new MemoryStream(Properties.Resources.tu31colours)) default_colourfile = reader.FromStream(stream); break;
case 5: using (var stream = new MemoryStream(Properties.Resources.tu32colours)) default_colourfile = reader.FromStream(stream); break;
case 6: using (var stream = new MemoryStream(Properties.Resources.tu43colours)) default_colourfile = reader.FromStream(stream); break;
case 7: using (var stream = new MemoryStream(Properties.Resources.tu46colours)) default_colourfile = reader.FromStream(stream); break;
case 8: using (var stream = new MemoryStream(Properties.Resources.tu51colours)) default_colourfile = reader.FromStream(stream); break;
case 9: using (var stream = new MemoryStream(Properties.Resources.tu53colours)) default_colourfile = reader.FromStream(stream); break;
case 10: using (var stream = new MemoryStream(Properties.Resources.tu54colours)) default_colourfile = reader.FromStream(stream); break;
case 11: using (var stream = new MemoryStream(Properties.Resources.tu69colours)) default_colourfile = reader.FromStream(stream); break;
case 12: using (var stream = new MemoryStream(Properties.Resources._1_91_colours)) default_colourfile = reader.FromStream(stream); break;
default: return;
}
SetUpTable(true);
@@ -82,35 +86,35 @@ namespace PckStudio.Forms.Editor
underwaterTreeView.Nodes.Clear();
fogTreeView.Nodes.Clear();
COLFile temp = targetVersion ? default_colourfile : colourfile;
ColorContainer temp = targetVersion ? default_colourfile : colourfile;
List<string> CurrentEntries = new List<string>();
foreach (var obj in temp.entries)
foreach (var obj in temp.Colors)
{
COLFile.ColorEntry entry = colourfile.entries.Find(color => color.name == obj.name);
TreeNode tn = new TreeNode(obj.name);
var entry = colourfile.Colors.Find(color => color.Name == obj.Name);
TreeNode tn = new TreeNode(obj.Name);
tn.Tag = entry != null ? entry : obj;
if (CurrentEntries.Contains(obj.name)) continue;
CurrentEntries.Add(obj.name);
if (CurrentEntries.Contains(obj.Name)) continue;
CurrentEntries.Add(obj.Name);
colorTreeView.Nodes.Add(tn);
colorCache.Add(tn);
}
CurrentEntries.Clear();
foreach (var obj in temp.waterEntries)
foreach (var obj in temp.WaterColors)
{
COLFile.ExtendedColorEntry entry = colourfile.waterEntries.Find(color => color.name == obj.name);
TreeNode tn = new TreeNode(obj.name);
var entry = colourfile.WaterColors.Find(color => color.Name == obj.Name);
TreeNode tn = new TreeNode(obj.Name);
tn.Tag = entry != null ? entry : obj;
if (CurrentEntries.Contains(obj.name)) continue;
CurrentEntries.Add(obj.name);
if (CurrentEntries.Contains(obj.Name)) continue;
CurrentEntries.Add(obj.Name);
waterTreeView.Nodes.Add(tn);
waterCache.Add(tn);
TreeNode tnB = new TreeNode(obj.name);
TreeNode tnB = new TreeNode(obj.Name);
tnB.Tag = entry != null ? entry : obj;
underwaterTreeView.Nodes.Add(tnB);
underwaterCache.Add(tnB);
TreeNode tnC = new TreeNode(obj.name);
TreeNode tnC = new TreeNode(obj.Name);
tnC.Tag = entry != null ? entry : obj;
fogTreeView.Nodes.Add(tnC);
fogCache.Add(tnC);
@@ -139,15 +143,15 @@ namespace PckStudio.Forms.Editor
{
if (colorTreeView.SelectedNode.Tag == null)
return;
var colorEntry = (COLFile.ColorEntry)colorTreeView.SelectedNode.Tag;
var color = colorEntry.color;
var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag;
var color = colorEntry.ColorPallette.ToArgb();
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
redUpDown.Value = color >> 16 & 0xff;
greenUpDown.Value = color >> 8 & 0xff;
blueUpDown.Value = color & 0xff;
pictureBox1.BackColor = Color.FromArgb(0xff << 24 | (int)color);
pictureBox1.BackColor = Color.FromArgb(0xff << 24 | color);
SetUpValueChanged(true);
}
@@ -155,8 +159,8 @@ namespace PckStudio.Forms.Editor
{
if (waterTreeView.SelectedNode.Tag == null)
return;
var colorEntry = (COLFile.ExtendedColorEntry)waterTreeView.SelectedNode.Tag;
int color = (int)colorEntry.color;
var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag;
int color = colorEntry.SurfaceColor.ToArgb();
SetUpValueChanged(false);
alphaUpDown.Enabled = true;
alphaUpDown.Visible = true;
@@ -165,7 +169,7 @@ namespace PckStudio.Forms.Editor
redUpDown.Value = color >> 16 & 0xff;
greenUpDown.Value = color >> 8 & 0xff;
blueUpDown.Value = color & 0xff;
pictureBox1.BackColor = Color.FromArgb(color);
pictureBox1.BackColor = colorEntry.SurfaceColor;
SetUpValueChanged(true);
}
@@ -173,8 +177,8 @@ namespace PckStudio.Forms.Editor
{
if (underwaterTreeView.SelectedNode.Tag == null)
return;
var colorEntry = (COLFile.ExtendedColorEntry)underwaterTreeView.SelectedNode.Tag;
int color = (int)colorEntry.color_b;
var colorEntry = (ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag;
int color = colorEntry.UnderwaterColor.ToArgb();
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
@@ -189,8 +193,8 @@ namespace PckStudio.Forms.Editor
{
if (fogTreeView.SelectedNode.Tag == null)
return;
var colorEntry = (COLFile.ExtendedColorEntry)fogTreeView.SelectedNode.Tag;
int color = (int)colorEntry.color_c;
var colorEntry = (ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag;
int color = colorEntry.FogColor.ToArgb();
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
@@ -203,22 +207,24 @@ namespace PckStudio.Forms.Editor
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
List<string> PS4Biomes = new List<string>();
PS4Biomes.Add("bamboo_jungle");
PS4Biomes.Add("bamboo_jungle_hills");
PS4Biomes.Add("mesa_mutated");
PS4Biomes.Add("mega_spruce_taiga_mutated");
PS4Biomes.Add("mega_taiga_mutated");
List<string> PS4Biomes = new List<string>
{
"bamboo_jungle",
"bamboo_jungle_hills",
"mesa_mutated",
"mega_spruce_taiga_mutated",
"mega_taiga_mutated"
};
if (colourfile.waterEntries.Find(e => PS4Biomes.Contains(e.name)) != null)
if (colourfile.WaterColors.Find(e => PS4Biomes.Contains(e.Name)) != null)
{
var result = MessageBox.Show(this, "Biomes exclusive to PS4 Edition v1.91 were found in the water section of this colour table. This will crash all other editions of the game and PS4 Edition v1.90 and below. Would you like to remove them?", "Potentially unsupported biomes found", MessageBoxButtons.YesNoCancel);
switch (result)
{
case DialogResult.Yes:
foreach (var col in colourfile.waterEntries.ToList())
foreach (var col in colourfile.WaterColors.ToList())
{
if(PS4Biomes.Contains(col.name)) colourfile.waterEntries.Remove(col);
if(PS4Biomes.Contains(col.Name)) colourfile.WaterColors.Remove(col);
}
break;
case DialogResult.No:
@@ -229,45 +235,25 @@ namespace PckStudio.Forms.Editor
}
using (var stream = new MemoryStream())
{
COLFileWriter.Write(stream, colourfile);
var writer = new COLFileWriter(colourfile);
writer.WriteToStream(stream);
_file.SetData(stream.ToArray());
}
DialogResult = DialogResult.OK;
}
static byte[] StringToByteArrayFastest(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
static int GetHexVal(char hex)
{
int val = hex;
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
public void treeView1_KeyDown(object sender, KeyEventArgs e)
{
var node = colorTreeView.SelectedNode;
if (e.KeyCode == Keys.Delete && node.Tag is COLFile.ColorEntry)
if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.Color)
{
restoreOriginalColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.C && node.Tag is COLFile.ColorEntry)
else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.Color)
{
copyColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.V && node.Tag is COLFile.ColorEntry)
else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.Color)
{
pasteColorToolStripMenuItem_Click(sender, e);
}
@@ -276,15 +262,15 @@ namespace PckStudio.Forms.Editor
private void treeView2_KeyDown(object sender, KeyEventArgs e)
{
var node = waterTreeView.SelectedNode;
if (e.KeyCode == Keys.Delete && node.Tag is COLFile.ExtendedColorEntry)
if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor)
{
restoreOriginalColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.C && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor)
{
copyColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.V && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor)
{
pasteColorToolStripMenuItem_Click(sender, e);
}
@@ -293,15 +279,15 @@ namespace PckStudio.Forms.Editor
private void treeView3_KeyDown(object sender, KeyEventArgs e)
{
var node = underwaterTreeView.SelectedNode;
if (e.KeyCode == Keys.Delete && node.Tag is COLFile.ExtendedColorEntry)
if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor)
{
restoreOriginalColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.C && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor)
{
copyColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.V && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor)
{
pasteColorToolStripMenuItem_Click(sender, e);
}
@@ -310,15 +296,15 @@ namespace PckStudio.Forms.Editor
private void treeView4_KeyDown(object sender, KeyEventArgs e)
{
var node = fogTreeView.SelectedNode;
if (e.KeyCode == Keys.Delete && node.Tag is COLFile.ExtendedColorEntry)
if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor)
{
restoreOriginalColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.C && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor)
{
copyColorToolStripMenuItem_Click(sender, e);
}
else if (e.Control && e.KeyCode == Keys.V && node.Tag is COLFile.ExtendedColorEntry)
else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor)
{
pasteColorToolStripMenuItem_Click(sender, e);
}
@@ -354,19 +340,16 @@ namespace PckStudio.Forms.Editor
Color fixed_color = new Color();
if (tabControl.SelectedTab == colorsTab)
{
var colorEntry = (COLFile.ColorEntry)colorTreeView.SelectedNode.Tag;
fixed_color = Color.FromArgb(255, (int)redUpDown.Value, (int)greenUpDown.Value, (int)blueUpDown.Value);
colorEntry.color = (uint)(((255 << 24) | (fixed_color.R << 16) | (fixed_color.G << 8) | fixed_color.B) & 0xffffffffL);
var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag;
colorEntry.ColorPallette = fixed_color = Color.FromArgb(255, (int)redUpDown.Value, (int)greenUpDown.Value, (int)blueUpDown.Value);
}
else if (tabControl.SelectedTab != null && waterTreeView.SelectedNode != null) // just in case
{
var colorEntry = (COLFile.ExtendedColorEntry)waterTreeView.SelectedNode.Tag;
var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag;
fixed_color = Color.FromArgb(tabControl.SelectedTab == waterTab ? (int)alphaUpDown.Value : 255, (int)redUpDown.Value, (int)greenUpDown.Value, (int)blueUpDown.Value);
uint value = (uint)(((fixed_color.A << 24) | (fixed_color.R << 16) | (fixed_color.G << 8) | fixed_color.B) & 0xffffffffL);
if (tabControl.SelectedTab == waterTab) colorEntry.color = value;
else if (tabControl.SelectedTab == underwaterTab) colorEntry.color_b = value;
else colorEntry.color_c = value;
fixed_color = Color.FromArgb((int)value);
if (tabControl.SelectedTab == waterTab) colorEntry.SurfaceColor = fixed_color;
else if (tabControl.SelectedTab == underwaterTab) colorEntry.UnderwaterColor = fixed_color;
else colorEntry.FogColor = fixed_color;
}
pictureBox1.BackColor = fixed_color;
@@ -381,42 +364,40 @@ namespace PckStudio.Forms.Editor
if (colorPick.ShowDialog() != DialogResult.OK) return;
pictureBox1.BackColor = colorPick.Color;
if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode != null &&
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)waterTreeView.SelectedNode.Tag);
var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag;
// preserves the alpha so the user can handle it since the color picker doesn't support alpha
Color fixed_color = Color.FromArgb(Color.FromArgb((int)colorEntry.color).A, colorPick.Color);
colorEntry.color = (uint)fixed_color.ToArgb();
pictureBox1.BackColor = fixed_color;
pictureBox1.BackColor = colorEntry.SurfaceColor = Color.FromArgb(colorEntry.SurfaceColor.A, colorPick.Color);
redUpDown.Value = colorPick.Color.R;
greenUpDown.Value = colorPick.Color.G;
blueUpDown.Value = colorPick.Color.B;
}
else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode != null &&
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)underwaterTreeView.SelectedNode.Tag);
var colorEntry = (ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag;
// the game doesn't care about the alpha value for underwater colors
colorEntry.color_b = (uint)Color.FromArgb(0, colorPick.Color).ToArgb();
colorEntry.UnderwaterColor = Color.FromArgb(0, colorPick.Color);
redUpDown.Value = colorPick.Color.R;
greenUpDown.Value = colorPick.Color.G;
blueUpDown.Value = colorPick.Color.B;
}
else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode != null &&
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)fogTreeView.SelectedNode.Tag);
var colorEntry = (ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag;
// the game doesn't care about the alpha value for fog colors
colorEntry.color_c = (uint)Color.FromArgb(0, colorPick.Color).ToArgb();
colorEntry.FogColor = Color.FromArgb(0, colorPick.Color);
redUpDown.Value = colorPick.Color.R;
greenUpDown.Value = colorPick.Color.G;
blueUpDown.Value = colorPick.Color.B;
}
else if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode != null &&
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is COLFile.ColorEntry)
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is ColorContainer.Color)
{
var colorEntry = ((COLFile.ColorEntry)colorTreeView.SelectedNode.Tag);
colorEntry.color = (uint)colorPick.Color.ToArgb() & 0xffffff;
var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag;
colorEntry.ColorPallette = colorPick.Color;
redUpDown.Value = colorPick.Color.R;
greenUpDown.Value = colorPick.Color.G;
blueUpDown.Value = colorPick.Color.B;
@@ -427,12 +408,10 @@ namespace PckStudio.Forms.Editor
private void alpha_ValueChanged(object sender, EventArgs e)
{
if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode != null &&
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)waterTreeView.SelectedNode.Tag);
Color fixed_color = Color.FromArgb((int)alphaUpDown.Value, Color.FromArgb((int)colorEntry.color));
colorEntry.color = (uint)fixed_color.ToArgb();
pictureBox1.BackColor = fixed_color;
var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag;
pictureBox1.BackColor = colorEntry.SurfaceColor = Color.FromArgb((int)alphaUpDown.Value, colorEntry.SurfaceColor);
}
}
@@ -440,51 +419,45 @@ namespace PckStudio.Forms.Editor
{
SetUpValueChanged(false);
if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode != null &&
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is COLFile.ColorEntry colorInfoD)
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is ColorContainer.Color colorInfoD)
{
COLFile.ColorEntry entry = default_colourfile.entries.Find(color => color.name == colorTreeView.SelectedNode.Text);
colorInfoD.color = entry.color;
redUpDown.Value = colorInfoD.color >> 16 & 0xff;
greenUpDown.Value = colorInfoD.color >> 8 & 0xff;
blueUpDown.Value = colorInfoD.color & 0xff;
pictureBox1.BackColor = Color.FromArgb(0xff << 24 | (int)colorInfoD.color);
var entry = default_colourfile.Colors.Find(color => color.Name == colorTreeView.SelectedNode.Text);
colorInfoD.ColorPallette = entry.ColorPallette;
UpdateDisplayColor(entry.ColorPallette);
}
else if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode != null &&
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfo)
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfo)
{
COLFile.ExtendedColorEntry entry = default_colourfile.waterEntries.Find(color => color.name == waterTreeView.SelectedNode.Text);
colorInfo.color = entry.color;
alphaUpDown.Value = colorInfo.color >> 24 & 0xff;
redUpDown.Value = colorInfo.color >> 16 & 0xff;
greenUpDown.Value = colorInfo.color >> 8 & 0xff;
blueUpDown.Value = colorInfo.color & 0xff;
pictureBox1.BackColor = Color.FromArgb((int)colorInfo.color);
var entry = default_colourfile.WaterColors.Find(color => color.Name == waterTreeView.SelectedNode.Text);
colorInfo.SurfaceColor = entry.SurfaceColor;
UpdateDisplayColor(entry.SurfaceColor);
}
else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode != null &&
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfoB)
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfoB)
{
COLFile.ExtendedColorEntry entry = default_colourfile.waterEntries.Find(color => color.name == underwaterTreeView.SelectedNode.Text);
colorInfoB.color_b = entry.color_b;
alphaUpDown.Value = colorInfoB.color_b >> 24 & 0xff;
redUpDown.Value = colorInfoB.color_b >> 16 & 0xff;
greenUpDown.Value = colorInfoB.color_b >> 8 & 0xff;
blueUpDown.Value = colorInfoB.color_b & 0xff;
pictureBox1.BackColor = Color.FromArgb(0xff << 24 | (int)colorInfoB.color_b);
var entry = default_colourfile.WaterColors.Find(color => color.Name == underwaterTreeView.SelectedNode.Text);
colorInfoB.UnderwaterColor = entry.UnderwaterColor;
UpdateDisplayColor(entry.UnderwaterColor);
}
else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode != null &&
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfoC)
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfoC)
{
COLFile.ExtendedColorEntry entry = default_colourfile.waterEntries.Find(color => color.name == fogTreeView.SelectedNode.Text);
colorInfoC.color_c = entry.color_c;
alphaUpDown.Value = colorInfoC.color_c >> 24 & 0xff;
redUpDown.Value = colorInfoC.color_c >> 16 & 0xff;
greenUpDown.Value = colorInfoC.color_c >> 8 & 0xff;
blueUpDown.Value = colorInfoC.color_c & 0xff;
pictureBox1.BackColor = Color.FromArgb(0xff << 24 | (int)colorInfoC.color_c);
}
var entry = default_colourfile.WaterColors.Find(color => color.Name == fogTreeView.SelectedNode.Text);
colorInfoC.FogColor = entry.FogColor;
UpdateDisplayColor(entry.FogColor);
}
SetUpValueChanged(true);
}
private void UpdateDisplayColor(Color color)
{
alphaUpDown.Value = color.A;
redUpDown.Value = color.R;
greenUpDown.Value = color.G;
blueUpDown.Value = color.B;
pictureBox1.BackColor = Color.FromArgb(0xff, color);
}
private void metroTextBox1_TextChanged(object sender, EventArgs e)
{
// Some code in this function is modified code from this StackOverflow answer - MattNL
@@ -558,22 +531,26 @@ namespace PckStudio.Forms.Editor
private void copyColorToolStripMenuItem_Click(object sender, EventArgs e)
{
COLFile.ColorEntry colorToCopy = new COLFile.ColorEntry("", 0);
if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode.Tag is COLFile.ColorEntry colorInfoD)
var colorToCopy = new ColorContainer.Color()
{
Name = "",
ColorPallette = new Color()
};
if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode.Tag is ColorContainer.Color colorInfoD)
{
colorToCopy = colorInfoD;
}
else if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfo)
else if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfo)
{
colorToCopy = colorInfo;
colorToCopy.ColorPallette = colorInfo.SurfaceColor;
}
else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfoB)
else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfoB)
{
colorToCopy = colorInfoB;
colorToCopy.ColorPallette = colorInfoB.UnderwaterColor;
}
else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry colorInfoC)
else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode.Tag is ColorContainer.WaterColor colorInfoC)
{
colorToCopy = colorInfoC;
colorToCopy.ColorPallette = colorInfoC.FogColor;
}
clipboard_color = colorToCopy;
}
@@ -582,36 +559,36 @@ namespace PckStudio.Forms.Editor
{
if (clipboard_color == null) return;
SetUpValueChanged(false);
Color fixed_color = Color.FromArgb(255, Color.FromArgb(0xff << 24 | (int)clipboard_color.color));
Color fixed_color = Color.FromArgb(255, Color.FromArgb(0xff, clipboard_color.ColorPallette));
if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode != null &&
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)waterTreeView.SelectedNode.Tag);
colorEntry.color = (uint)fixed_color.ToArgb();
var colorEntry = ((ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag);
colorEntry.SurfaceColor = fixed_color;
}
else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode != null &&
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)underwaterTreeView.SelectedNode.Tag);
colorEntry.color_b = (uint)fixed_color.ToArgb();
var colorEntry = ((ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag);
colorEntry.UnderwaterColor = fixed_color;
}
else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode != null &&
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is COLFile.ExtendedColorEntry)
fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is ColorContainer.WaterColor)
{
var colorEntry = ((COLFile.ExtendedColorEntry)fogTreeView.SelectedNode.Tag);
colorEntry.color_c = (uint)fixed_color.ToArgb();
var colorEntry = ((ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag);
colorEntry.FogColor = fixed_color;
}
else if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode != null &&
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is COLFile.ColorEntry)
colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is ColorContainer.Color)
{
var colorEntry = ((COLFile.ColorEntry)colorTreeView.SelectedNode.Tag);
colorEntry.color = (uint)fixed_color.ToArgb() & 0xffffff;
var colorEntry = ((ColorContainer.Color)colorTreeView.SelectedNode.Tag);
colorEntry.ColorPallette = fixed_color;
}
redUpDown.Value = clipboard_color.color >> 16 & 0xff;
greenUpDown.Value = clipboard_color.color >> 8 & 0xff;
blueUpDown.Value = clipboard_color.color & 0xff;
redUpDown.Value = clipboard_color.ColorPallette.R;
greenUpDown.Value = clipboard_color.ColorPallette.G;
blueUpDown.Value = clipboard_color.ColorPallette.B;
pictureBox1.BackColor = fixed_color;
SetUpValueChanged(true);
}

View File

@@ -1,6 +1,6 @@
namespace PckStudio.Forms.Editor
{
partial class GRFEditor
partial class GameRuleFileEditor
{
/// <summary>
/// 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;
}
}

View File

@@ -5,81 +5,102 @@ 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;
using OMI.Formats.Pck;
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 PckFile.FileData _pckfile;
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<string>().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 +109,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 +126,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<string, string> pair &&
rule.Parameters.ContainsKey(pair.Key) && rule.Parameters.Remove(pair.Key))
{
@@ -123,7 +144,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<string, string> param)
{
AddParameter prompt = new AddParameter(param.Key, param.Value, false);
@@ -137,9 +158,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 +185,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 +205,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 +214,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 +238,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();
}
}
}
}
}

View File

@@ -6,9 +6,10 @@ using System.Collections.Generic;
using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Classes.Misc;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.LOC;
using PckStudio.Forms.Additional_Popups.Loc;
using OMI.Formats.Languages;
using OMI.Workers.Language;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Editor
{
@@ -16,15 +17,16 @@ namespace PckStudio.Forms.Editor
{
DataTable tbl;
LOCFile currentLoc;
PCKFile.FileData _file;
PckFile.FileData _file;
public LOCEditor(PCKFile.FileData file)
public LOCEditor(PckFile.FileData file)
{
InitializeComponent();
_file = file;
using (var ms = new MemoryStream(file.Data))
{
currentLoc = LOCFileReader.Read(ms);
var reader = new LOCFileReader();
currentLoc = reader.FromStream(ms);
}
tbl = new DataTable();
tbl.Columns.Add(new DataColumn("Language") { ReadOnly = true });

View File

@@ -6,30 +6,30 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.Materials;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OMI.Formats.Pck;
using OMI.Formats.Material;
using OMI.Workers.Material;
namespace PckStudio.Forms.Editor
{
public partial class MaterialsEditor : MetroForm
{
// Behaviours File Format research by Miku and MattNL
private readonly PCKFile.FileData _file;
MaterialsFile materialFile;
private readonly PckFile.FileData _file;
MaterialContainer materialFile;
void SetUpTree()
{
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
foreach (var entry in materialFile.entries)
foreach (var entry in materialFile)
{
TreeNode EntryNode = new TreeNode(entry.name);
TreeNode EntryNode = new TreeNode(entry.Name);
foreach (JObject content in Utilities.MaterialUtil.entityData["entities"].Children())
{
var prop = content.Properties().FirstOrDefault(prop => prop.Name == entry.name);
var prop = content.Properties().FirstOrDefault(prop => prop.Name == entry.Name);
if (prop is JProperty)
{
EntryNode.Text = (string)prop.Value;
@@ -46,14 +46,15 @@ namespace PckStudio.Forms.Editor
treeView1.EndUpdate();
}
public MaterialsEditor(PCKFile.FileData file)
public MaterialsEditor(PckFile.FileData file)
{
InitializeComponent();
_file = file;
using (var stream = new MemoryStream(file.Data))
{
materialFile = MaterialsReader.Read(stream);
var reader = new MaterialFileReader();
materialFile = reader.FromStream(stream);
}
treeView1.ImageList = new ImageList();
@@ -66,13 +67,13 @@ namespace PckStudio.Forms.Editor
{
if (e.Node == null) return;
bool enable = e.Node.Tag is MaterialsFile.MaterialEntry && treeView1.SelectedNode != null;
bool enable = e.Node.Tag is MaterialContainer.Material && treeView1.SelectedNode != null;
materialComboBox.Enabled = enable;
if (e.Node.Tag is MaterialsFile.MaterialEntry entry)
if (e.Node.Tag is MaterialContainer.Material entry)
{
materialComboBox.SelectedIndexChanged -= materialComboBox_SelectedIndexChanged;
materialComboBox.SelectedIndex = materialComboBox.Items.IndexOf(entry.material_type);
materialComboBox.SelectedIndex = materialComboBox.Items.IndexOf(entry.Type);
materialComboBox.SelectedIndexChanged += materialComboBox_SelectedIndexChanged;
}
}
@@ -112,17 +113,18 @@ namespace PckStudio.Forms.Editor
{
using (var stream = new MemoryStream())
{
materialFile = new MaterialsFile();
materialFile = new MaterialContainer();
foreach (TreeNode node in treeView1.Nodes)
{
if(node.Tag is MaterialsFile.MaterialEntry entry)
if(node.Tag is MaterialContainer.Material entry)
{
materialFile.entries.Add(entry);
materialFile.Add(entry);
}
}
MaterialsWriter.Write(stream, materialFile);
var writer = new MaterialFileWriter(materialFile);
writer.WriteToStream(stream);
_file.SetData(stream.ToArray());
}
DialogResult = DialogResult.OK;
@@ -134,21 +136,19 @@ namespace PckStudio.Forms.Editor
if (diag.ShowDialog() == DialogResult.OK)
{
if (String.IsNullOrEmpty(diag.SelectedEntity)) return;
if (materialFile.entries.FindAll(mat => mat.name == diag.SelectedEntity).Count() > 0)
if (string.IsNullOrEmpty(diag.SelectedEntity)) return;
if (materialFile.FindAll(mat => mat.Name == diag.SelectedEntity).Count() > 0)
{
MessageBox.Show(this, "You cannot have two entries for one entity. Please use the \"Add New Position Override\" tool to add multiple overrides for entities", "Error", MessageBoxButtons.OK);
return;
}
MaterialsFile.MaterialEntry NewEntry = new MaterialsFile.MaterialEntry();
NewEntry.name = diag.SelectedEntity;
NewEntry.material_type = "entity_alphatest";
var NewEntry = new MaterialContainer.Material(diag.SelectedEntity, "entity_alphatest");
TreeNode NewEntryNode = new TreeNode(NewEntry.name);
TreeNode NewEntryNode = new TreeNode(NewEntry.Name);
NewEntryNode.Tag = NewEntry;
foreach (JObject content in Utilities.MaterialUtil.entityData["entities"].Children())
{
var prop = content.Properties().FirstOrDefault(prop => prop.Name == NewEntry.name);
var prop = content.Properties().FirstOrDefault(prop => prop.Name == NewEntry.Name);
if (prop is JProperty)
{
NewEntryNode.Text = (string)prop.Value;
@@ -165,9 +165,9 @@ namespace PckStudio.Forms.Editor
private void materialComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (treeView1.SelectedNode.Tag is MaterialsFile.MaterialEntry entry)
if (treeView1.SelectedNode.Tag is MaterialContainer.Material entry)
{
entry.material_type = materialComboBox.SelectedItem.ToString();
entry.Type = materialComboBox.SelectedItem.ToString();
treeView1.SelectedNode.Tag = entry;
}
}

View File

@@ -1,4 +1,4 @@
using PckStudio.Classes.FileTypes;
using OMI.Formats.Pck;
using System;
using System.Data;
using System.Drawing;
@@ -10,9 +10,9 @@ namespace PckStudio
{
public partial class AdvancedOptions : MetroFramework.Forms.MetroForm
{
PCKFile currentPCK;
PckFile currentPCK;
public AdvancedOptions(PCKFile currentPCKIn)
public AdvancedOptions(PckFile currentPCKIn)
{
InitializeComponent();
currentPCK = currentPCKIn;
@@ -26,7 +26,7 @@ namespace PckStudio
{
case "All":
{
foreach (PCKFile.FileData file in currentPCK.Files)
foreach (PckFile.FileData file in currentPCK.Files)
{
file.Properties.Add((entryTypeTextBox.Text, entryDataTextBox.Text));
}
@@ -35,7 +35,7 @@ namespace PckStudio
break;
case "64x64":
{
foreach (PCKFile.FileData file in currentPCK.Files)
foreach (PckFile.FileData file in currentPCK.Files)
{
MemoryStream png = new MemoryStream(file.Data);
if (Path.GetExtension(file.Filename) == ".png" &&
@@ -49,7 +49,7 @@ namespace PckStudio
break;
case "64x32":
{
foreach (PCKFile.FileData file in currentPCK.Files)
foreach (PckFile.FileData file in currentPCK.Files)
{
MemoryStream png = new MemoryStream(file.Data);
if (Path.GetExtension(file.Filename) == ".png" &&
@@ -63,7 +63,7 @@ namespace PckStudio
break;
case "PNG Files":
{
foreach (PCKFile.FileData file in currentPCK.Files)
foreach (PckFile.FileData file in currentPCK.Files)
{
MemoryStream png = new MemoryStream(file.Data);
if (Path.GetExtension(file.Filename) == ".png")

View File

@@ -3,27 +3,27 @@ using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using PckStudio.Classes.FileTypes;
using System.Drawing.Imaging;
using PckStudio.Classes.Utils;
using PckStudio.Classes._3ds.Utils;
using OMI.Formats.Languages;
using OMI.Formats.Pck;
namespace PckStudio
{
public partial class addNewSkin : MetroFramework.Forms.MetroForm
{
public PCKFile.FileData SkinFile => skin;
public PCKFile.FileData CapeFile => cape;
public PckFile.FileData SkinFile => skin;
public PckFile.FileData CapeFile => cape;
public bool HasCape = false;
LOCFile currentLoc;
PCKFile.FileData skin = new PCKFile.FileData("dlcskinXYXYXYXY", PCKFile.FileData.FileType.SkinFile);
PCKFile.FileData cape = new PCKFile.FileData("dlccapeXYXYXYXY", PCKFile.FileData.FileType.CapeFile);
PckFile.FileData skin = new PckFile.FileData("dlcskinXYXYXYXY", PckFile.FileData.FileType.SkinFile);
PckFile.FileData cape = new PckFile.FileData("dlccapeXYXYXYXY", PckFile.FileData.FileType.CapeFile);
SkinANIM anim = new SkinANIM();
eSkinType skinType;
PCKProperties generatedModel = new PCKProperties();
PckFile.PCKProperties generatedModel = new PckFile.PCKProperties();
enum eSkinType : int
{

View File

@@ -11,6 +11,7 @@ using Newtonsoft.Json;
using MetroFramework.Forms;
using PckStudio.Classes.FileTypes;
using System.Text.RegularExpressions;
using OMI.Formats.Pck;
namespace PckStudio
{
@@ -28,7 +29,7 @@ namespace PckStudio
right
}
PCKProperties boxes;
PckFile.PCKProperties boxes;
Color backgroundColor = Color.FromArgb(0xff, 0x50, 0x50, 0x50);
@@ -127,7 +128,7 @@ namespace PckStudio
}
public generateModel(PCKProperties skinProperties, PictureBox preview)
public generateModel(PckFile.PCKProperties skinProperties, PictureBox preview)
{
InitializeComponent();
boxes = skinProperties;

View File

@@ -4,9 +4,9 @@ using System.Linq;
using System.IO;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using System.Drawing.Imaging;
using PckStudio.Classes.Extentions;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Utilities
{
@@ -19,9 +19,9 @@ namespace PckStudio.Forms.Utilities
public static Image[] tileImages => _tileImages ??= Resources.terrain_sheet.CreateImageList(16).Concat(Resources.items_sheet.CreateImageList(16)).ToArray();
public static PCKFile.FileData CreateNewAnimationFile(Image source, string tileName, bool isItem)
public static PckFile.FileData CreateNewAnimationFile(Image source, string tileName, bool isItem)
{
PCKFile.FileData file = new PCKFile.FileData($"res/textures/{GetAnimationSection(isItem)}/{tileName}.png", PCKFile.FileData.FileType.TextureFile);
PckFile.FileData file = new PckFile.FileData($"res/textures/{GetAnimationSection(isItem)}/{tileName}.png", PckFile.FileData.FileType.TextureFile);
file.Properties.Add(("ANIM", string.Empty));
using (var stream = new MemoryStream())
{

View File

@@ -4,9 +4,10 @@ using System.Linq;
using System.IO;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.Behaviour;
using PckStudio.Classes.Extentions;
using OMI.Formats.Behaviour;
using OMI.Workers.Behaviour;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Utilities
{
@@ -17,13 +18,14 @@ namespace PckStudio.Forms.Utilities
public static Image[] entityImages => _entityImages ??= Resources.entities_sheet.CreateImageList(32).ToArray();
public static PCKFile.FileData CreateNewBehaviourFile()
public static PckFile.FileData CreateNewBehaviourFile()
{
PCKFile.FileData file = new PCKFile.FileData($"behaviours.bin", PCKFile.FileData.FileType.BehavioursFile);
PckFile.FileData file = new PckFile.FileData($"behaviours.bin", PckFile.FileData.FileType.BehavioursFile);
using (var stream = new MemoryStream())
{
BehavioursWriter.Write(stream, new BehaviourFile());
var writer = new BehavioursWriter(new BehaviourFile());
writer.WriteToStream(stream);
file.SetData(stream.ToArray());
}

View File

@@ -4,9 +4,10 @@ using System.Linq;
using System.IO;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.Materials;
using PckStudio.Classes.Extentions;
using OMI.Formats.Pck;
using OMI.Formats.Material;
using OMI.Workers.Material;
namespace PckStudio.Forms.Utilities
{
@@ -16,15 +17,18 @@ namespace PckStudio.Forms.Utilities
private static Image[] _entityImages;
public static Image[] entityImages => _entityImages ??= Resources.entities_sheet.CreateImageList(32).ToArray();
public static PCKFile.FileData CreateNewMaterialsFile()
public static PckFile.FileData CreateNewMaterialsFile()
{
PCKFile.FileData file = new PCKFile.FileData($"entityMaterials.bin", PCKFile.FileData.FileType.MaterialFile);
PckFile.FileData file = new PckFile.FileData($"entityMaterials.bin", PckFile.FileData.FileType.MaterialFile);
using (var stream = new MemoryStream())
{
var matFile = new MaterialsFile();
matFile.entries.Add(new MaterialsFile.MaterialEntry("bat", "entity_alphatest"));
MaterialsWriter.Write(stream, matFile);
var matFile = new MaterialContainer
{
new MaterialContainer.Material("bat", "entity_alphatest")
};
var writer = new MaterialFileWriter(matFile);
writer.WriteToStream(stream);
file.SetData(stream.ToArray());
}

View File

@@ -4,9 +4,10 @@ using System.Linq;
using System.IO;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.Model;
using PckStudio.Classes.Extentions;
using OMI.Formats.Model;
using OMI.Formats.Pck;
using OMI.Workers.Model;
namespace PckStudio.Forms.Utilities
{
@@ -17,13 +18,14 @@ namespace PckStudio.Forms.Utilities
public static Image[] entityImages => _entityImages ??= Resources.entities_sheet.CreateImageList(32).ToArray();
public static PCKFile.FileData CreateNewModelsFile()
public static PckFile.FileData CreateNewModelsFile()
{
PCKFile.FileData file = new PCKFile.FileData($"models.bin", PCKFile.FileData.FileType.ModelsFile);
PckFile.FileData file = new PckFile.FileData($"models.bin", PckFile.FileData.FileType.ModelsFile);
using (var stream = new MemoryStream())
{
ModelFileWriter.Write(stream, new ModelFile());
var writer = new ModelFileWriter(new ModelContainer());
writer.WriteToStream(stream);
file.SetData(stream.ToArray());
}

View File

@@ -6,12 +6,13 @@ using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using OMI.Formats.Pck;
namespace PckStudio.Forms.Utilities
{
public partial class TextureConverterUtility : MetroForm
{
public TextureConverterUtility(TreeView tv0, PCKFile pck)
public TextureConverterUtility(TreeView tv0, PckFile pck)
{
InitializeComponent();
TView = tv0;
@@ -23,7 +24,7 @@ namespace PckStudio.Forms.Utilities
bool ToPC = true;
PCKFile Pck;
PckFile Pck;
TreeView TView;
@@ -313,13 +314,13 @@ namespace PckStudio.Forms.Utilities
switch (tn.Text)
{
case ("terrain.png"):
Terrain = Image.FromStream(new MemoryStream(((PCKFile.FileData)(tn.Tag)).Data));
Terrain = Image.FromStream(new MemoryStream(((PckFile.FileData)(tn.Tag)).Data));
break;
case ("items.png"):
Items = Image.FromStream(new MemoryStream(((PCKFile.FileData)(tn.Tag)).Data));
Items = Image.FromStream(new MemoryStream(((PckFile.FileData)(tn.Tag)).Data));
break;
case ("art"):
painting = Image.FromStream(new MemoryStream(((PCKFile.FileData)(tn.Nodes[0].Tag)).Data));
painting = Image.FromStream(new MemoryStream(((PckFile.FileData)(tn.Nodes[0].Tag)).Data));
break;
case ("mob"):
EntityNode = tn;
@@ -429,7 +430,7 @@ namespace PckStudio.Forms.Utilities
string Outpath = "assets\\minecraft\\textures\\";
foreach (PCKFile.FileData mf in Pck.Files)
foreach (PckFile.FileData mf in Pck.Files)
{
FileInfo file = new FileInfo(Environment.CurrentDirectory + "\\Temp\\" + @"\" + mf.Filename);
file.Directory.Create(); // If the directory already exists, this method does nothing.
@@ -454,7 +455,7 @@ namespace PckStudio.Forms.Utilities
string Outpath = "assets\\minecraft\\textures\\";
foreach (PCKFile.FileData mf in Pck.Files)
foreach (PckFile.FileData mf in Pck.Files)
{
FileInfo file = new FileInfo(Environment.CurrentDirectory + "\\Temp\\" + @"\" + mf.Filename);
file.Directory.Create(); // If the directory already exists, this method does nothing.
@@ -479,7 +480,7 @@ namespace PckStudio.Forms.Utilities
string Outpath = "assets\\minecraft\\textures\\";
foreach (PCKFile.FileData mf in Pck.Files)
foreach (PckFile.FileData mf in Pck.Files)
{
FileInfo file = new FileInfo(Environment.CurrentDirectory + "\\Temp\\" + @"\" + mf.Filename);
file.Directory.Create(); // If the directory already exists, this method does nothing.

View File

@@ -10,8 +10,11 @@ using System.Diagnostics;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.PCK;
using PckStudio.Classes.IO.ARC;
using PckStudio.Classes.Misc;
using OMI.Formats.Archive;
using OMI.Workers.Archive;
using OMI.Workers.Pck;
using OMI.Formats.Pck;
namespace PckStudio.Forms
{
@@ -105,7 +108,7 @@ namespace PckStudio.Forms
}
}
List<pckDir> pcks = new List<pckDir>();
PCKFile currentPCK = null;
PckFile currentPCK = null;
private void updateDatabase()
{
@@ -429,17 +432,22 @@ namespace PckStudio.Forms
private string GetPackID(string filename)
{
var fs = File.OpenRead(filename);
currentPCK = PCKFileReader.Read(fs, false);
fs.Close();
return currentPCK.GetFile("0", PCKFile.FileData.FileType.InfoFile).Properties.GetProperty("PACKID").Item2;
var reader = new PckFileReader();
currentPCK = reader.FromFile(filename);
if (currentPCK.TryGetFile("0", PckFile.FileData.FileType.InfoFile, out var file) &&
file.Properties.HasProperty("PACKID"))
{
file.Properties.GetProperty("PACKID");
}
throw new KeyNotFoundException();
}
private void GetARCFromConsole()
{
using (FTPClient client = new FTPClient("ftp://" + textBoxHost.Text, "", "a3262443"))
client.DownloadFile(dlcPath + "../../Common/Media/MediaWiiU.arc", Program.AppData + "MediaWiiU.arc");
archive = ARCFileReader.Read(new MemoryStream(File.ReadAllBytes(Program.AppData + "MediaWiiU.arc")));
var reader = new ARCFileReader();
archive = reader.FromStream(new MemoryStream(File.ReadAllBytes(Program.AppData + "MediaWiiU.arc")));
}
private void ReplacePackImage(string PackID)
@@ -455,7 +463,8 @@ namespace PckStudio.Forms
using (FTPClient client = new FTPClient("ftp://" + textBoxHost.Text, "", "a3262443"))
{
MemoryStream ms = new MemoryStream();
ARCFileWriter.Write(ms, archive);
var writer = new ARCFileWriter(archive);
writer.WriteToStream(ms);
File.WriteAllBytes(Program.AppData + "MediaWiiU.arc", ms.ToArray());
client.UploadFile(Program.AppData + "MediaWiiU.arc", dlcPath + "../../Common/Media/MediaWiiU.arc");
archive.Clear();

View File

@@ -17,6 +17,8 @@ using PckStudio;
using System.IO.Compression;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.PCK;
using OMI.Formats.Pck;
using OMI.Workers.Pck;
namespace PckStudio.Forms
{
@@ -134,16 +136,14 @@ namespace PckStudio.Forms
//MessageBox.Show(root);//debug thingy to make sure filepath is correct
//add all skins to a list
List<PCKFile.FileData> skinsList = new List<PCKFile.FileData>();
List<PCKFile.FileData> capesList = new List<PCKFile.FileData>();
List<PckFile.FileData> skinsList = new List<PckFile.FileData>();
List<PckFile.FileData> capesList = new List<PckFile.FileData>();
PCKFile pck = null;
using (var stream = File.OpenRead(Program.AppData + "/PCK-Center/myPcks/" + mod + ".pck"))
{
pck = PCKFileReader.Read(stream, false); // sets opened pck
}
PCKFile currentPCK = pck; //sets opened pck
foreach (PCKFile.FileData skin in currentPCK.Files)
PckFile pck = null;
var reader = new PckFileReader();
PckFile currentPCK = reader.FromFile(Program.AppData + "/PCK-Center/myPcks/" + mod + ".pck");
foreach (PckFile.FileData skin in currentPCK.Files)
{
if (skin.Filename.Count() == 19)
{
@@ -177,7 +177,7 @@ namespace PckStudio.Forms
writeSkins.WriteLine(" \"skins\": [");
int skinAmount = 0;
foreach (PCKFile.FileData newSkin in skinsList)
foreach (PckFile.FileData newSkin in skinsList)
{
skinAmount += 1;
string skinName = "skinName";
@@ -234,7 +234,7 @@ namespace PckStudio.Forms
{
writeSkins.WriteLine("{");
int newSkinCount = 0;
foreach (PCKFile.FileData newSkin in skinsList)
foreach (PckFile.FileData newSkin in skinsList)
{
newSkinCount += 1;
@@ -1022,7 +1022,7 @@ namespace PckStudio.Forms
}
//adds skin textures
foreach (PCKFile.FileData skinTexture in skinsList)
foreach (PckFile.FileData skinTexture in skinsList)
{
var ms = new MemoryStream(skinTexture.Data);
Bitmap saveSkin = new Bitmap(Image.FromStream(ms));
@@ -1042,7 +1042,7 @@ namespace PckStudio.Forms
}
//adds cape textures
foreach (PCKFile.FileData capeTexture in capesList)
foreach (PckFile.FileData capeTexture in capesList)
{
File.WriteAllBytes(root + "/" + capeTexture.Filename, capeTexture.Data);
}

File diff suppressed because it is too large Load Diff

View File

@@ -170,30 +170,14 @@
<Compile Include="Classes\API\PCKCenter\PCKCollections.cs" />
<Compile Include="Classes\API\PCKCenter\PCKCollectionsLocal.cs" />
<Compile Include="Classes\API\PCKCenter\SaveLocalJSON.cs" />
<Compile Include="Classes\FileTypes\ARCFile.cs" />
<Compile Include="Classes\FileTypes\MaterialsFile.cs" />
<Compile Include="Classes\FileTypes\BehaviourFile.cs" />
<Compile Include="Classes\FileTypes\CSMBFile.cs" />
<Compile Include="Classes\FileTypes\ModelFile.cs" />
<Compile Include="Classes\FileTypes\PCKAudioFile.cs" />
<Compile Include="Classes\FileTypes\Binka.cs" />
<Compile Include="Classes\FileTypes\COLFile.cs" />
<Compile Include="Classes\FileTypes\CSM.cs" />
<Compile Include="Classes\FileTypes\GRFFile.cs" />
<Compile Include="Classes\IO\ARC\ARCFileWriter.cs" />
<Compile Include="Classes\IO\ARC\ARCFileReader.cs" />
<Compile Include="Classes\IO\Behaviour\BehavioursReader.cs" />
<Compile Include="Classes\IO\Behaviour\BehavioursWriter.cs" />
<Compile Include="Classes\IO\CSMB\CSMBFileReader.cs" />
<Compile Include="Classes\IO\CSMB\CSMBFileWriter.cs" />
<Compile Include="Classes\IO\Materials\MaterialsReader.cs" />
<Compile Include="Classes\IO\Materials\MaterialsWriter.cs" />
<Compile Include="Classes\IO\Model\ModelFileReader.cs" />
<Compile Include="Classes\IO\Model\ModelFileWriter.cs" />
<Compile Include="Classes\IO\PCK\PCKAudioFileReader.cs" />
<Compile Include="Classes\IO\PCK\PCKAudioFileWriter.cs" />
<Compile Include="Classes\IO\COL\COLFileReader.cs" />
<Compile Include="Classes\IO\COL\COLFileWriter.cs" />
<Compile Include="Classes\IO\Sounds\SoundIO.cs" />
<Compile Include="Classes\IO\Sounds\Sounds.cs" />
<Compile Include="Classes\Misc\FTPClient.cs" />
@@ -202,14 +186,6 @@
<Compile Include="Classes\Utils\ARC\ARCUtil.cs" />
<Compile Include="Classes\Extentions\ImageExtentions.cs" />
<Compile Include="Classes\Utils\SkinANIM.cs" />
<Compile Include="Classes\FileTypes\PCKProperties.cs" />
<Compile Include="Classes\FileTypes\PCKFile.cs" />
<Compile Include="Classes\IO\GRF\GRFFileReader.cs" />
<Compile Include="Classes\IO\GRF\GRFFileWriter.cs" />
<Compile Include="Classes\IO\LOC\LOCFileReader.cs" />
<Compile Include="Classes\IO\LOC\LOCFileWriter.cs" />
<Compile Include="Classes\IO\PCK\PCKFileReader.cs" />
<Compile Include="Classes\IO\PCK\PCKFileWriter.cs" />
<Compile Include="Classes\IO\StreamDataReader.cs" />
<Compile Include="Classes\IO\StreamDataWriter.cs" />
<Compile Include="Classes\Models\DefaultModels\Steve64x32Model.cs" />
@@ -241,8 +217,6 @@
<Compile Include="Classes\Networking\Network.cs" />
<Compile Include="Classes\Misc\RichPresenceClient.cs" />
<Compile Include="Classes\Networking\Update.cs" />
<Compile Include="Classes\Utils\GRF\CRC32.cs" />
<Compile Include="Classes\Utils\RLE.cs" />
<Compile Include="Forms\Additional-Popups\EntityForms\AddEntry.cs">
<SubType>Form</SubType>
</Compile>
@@ -351,11 +325,11 @@
<Compile Include="Forms\Skins-And-Textures\AdvancedOptions.Designer.cs">
<DependentUpon>AdvancedOptions.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editor\GRFEditor.cs">
<Compile Include="Forms\Editor\GameRuleFileEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Editor\GRFEditor.Designer.cs">
<DependentUpon>GRFEditor.cs</DependentUpon>
<Compile Include="Forms\Editor\GameRuleFileEditor.Designer.cs">
<DependentUpon>GameRuleFileEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Additional-Popups\Grf\AddParameter.cs">
<SubType>Form</SubType>
@@ -479,7 +453,6 @@
<Compile Include="Classes\ToolboxItems\InterpolationPictureBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Classes\FileTypes\LOCFile.cs" />
<Compile Include="Forms\Additional-Popups\MetaList.cs">
<SubType>Form</SubType>
</Compile>
@@ -571,8 +544,8 @@
<DependentUpon>AdvancedOptions.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Editor\GRFEditor.resx">
<DependentUpon>GRFEditor.cs</DependentUpon>
<EmbeddedResource Include="Forms\Editor\GameRuleFileEditor.resx">
<DependentUpon>GameRuleFileEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Additional-Popups\Grf\AddParameter.resx">
<DependentUpon>AddParameter.cs</DependentUpon>
@@ -789,14 +762,16 @@
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.3</Version>
</PackageReference>
<PackageReference Include="SharpZipLib">
<Version>1.4.2</Version>
</PackageReference>
<PackageReference Include="System.ValueTuple">
<Version>4.5.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\Vendor\OMI-Lib\OMI Filetypes Library\OMI Filetype Library.csproj">
<Project>{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}</Project>
<Name>OMI Filetype Library</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -5,6 +5,10 @@ VisualStudioVersion = 17.1.32414.318
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PckStudio", "PCK-Studio\PckStudio.csproj", "{0ACAAEDE-93F5-4B5D-B8D7-A0C43359C0D6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Vendor", "Vendor", "{FC87F3E5-B07E-4FFB-889F-66FA3A3CFCAA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMI Filetype Library", "Vendor\OMI-Lib\OMI Filetypes Library\OMI Filetype Library.csproj", "{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,10 +31,25 @@ Global
{0ACAAEDE-93F5-4B5D-B8D7-A0C43359C0D6}.Release|x64.Build.0 = Release|Any CPU
{0ACAAEDE-93F5-4B5D-B8D7-A0C43359C0D6}.Release|x86.ActiveCfg = Release|Any CPU
{0ACAAEDE-93F5-4B5D-B8D7-A0C43359C0D6}.Release|x86.Build.0 = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|x64.ActiveCfg = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|x64.Build.0 = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|x86.ActiveCfg = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Debug|x86.Build.0 = Debug|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|Any CPU.Build.0 = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|x64.ActiveCfg = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|x64.Build.0 = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|x86.ActiveCfg = Release|Any CPU
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB} = {FC87F3E5-B07E-4FFB-889F-66FA3A3CFCAA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9A3BF1FB-950F-401E-9F58-EA7BBADCE6F2}
EndGlobalSection

1
Vendor/OMI-Lib vendored Submodule

Submodule Vendor/OMI-Lib added at 6f00721bde