Add GRF/GRH File support

This commit is contained in:
miku-666
2022-07-14 01:02:22 +02:00
parent e7ee1f2027
commit 46dec04d48
15 changed files with 7754 additions and 2371 deletions

View File

@@ -2,36 +2,32 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class GRFFile
{
{
public GRFTag RootTag = null;
public int Crc => _crc;
public bool IsWorld => _isWorld;
public eCompressionType CompressionType => _compressionType;
private int _crc = 0;
private bool _isWorld = false;
private eCompressionType _compressionType = eCompressionType.None;
[Flags]
public enum eCompressionType : byte
{
None = 0,
Zlib = 1,
ZlibRle = 2,
/// <summary>
/// custom enum value
/// </summary>
IsWolrdGrf = 0x80,
ZlibRleCrc = 3,
}
public class GRFTag
{
private GRFTag _parent = null;
private SortedDictionary<string, string> _parameters = new SortedDictionary<string, string>();
private Dictionary<string, string> _parameters = new Dictionary<string, string>();
/// <summary>
/// Contains all valid Parameter names
@@ -226,9 +222,15 @@ namespace PckStudio.Classes.FileTypes
public string Name { get; set; } = string.Empty;
public GRFTag Parent => _parent;
public SortedDictionary<string, string> Parameters => _parameters;
public Dictionary<string, string> Parameters => _parameters;
public List<GRFTag> Tags { get; set; } = new List<GRFTag>();
/// <summary>
/// Initializes a new GRFTag.
/// If parent is null it will be treated as the root tag
/// </summary>
/// <param name="name"></param>
/// <param name="parent"></param>
public GRFTag(string name, GRFTag parent)
{
Name = name;
@@ -236,10 +238,11 @@ namespace PckStudio.Classes.FileTypes
}
}
public GRFFile(eCompressionType compressionType, int crc)
public GRFFile(eCompressionType compressionType, int crc, bool isWolrd)
{
_compressionType = compressionType;
_crc = crc;
_isWorld = isWolrd;
}
}

View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using PckStudio.Classes.Utils;
@@ -19,22 +18,20 @@ namespace PckStudio.Classes.IO.GRF
return new GRFFileReader().read(stream);
}
private GRFFile read(Stream stream)
{
stream = ReadHeader(stream);
ReadTagNames(stream);
ReadGRFTags(stream);
ReadBody(stream);
return _file;
}
private Stream ReadHeader(Stream stream)
{
int x = ReadShort(stream);
if (((x >> 31) | x) == 0)
{
ReadBytes(stream, 14); // 14 bools ?...
// 14 bools ?...
ReadBytes(stream, 14);
return stream;
}
@@ -47,35 +44,43 @@ namespace PckStudio.Classes.IO.GRF
if (byte4 > 0)
{
compression_type = (GRFFile.eCompressionType)byte4;
// Custom enum
compression_type &= GRFFile.eCompressionType.IsWolrdGrf;
}
_file = new GRFFile(compression_type, crc);
_file = new GRFFile(compression_type, crc, byte4 > 0);
if (compression_type == GRFFile.eCompressionType.None && byte4 == 0)
return stream;
int buf_size = ReadInt(stream);
var new_stream = stream;
if (byte4 != 0)
{
stream = new MemoryStream(ReadBytes(stream, buf_size));
buf_size = ReadInt(stream);
new_stream = new MemoryStream(ReadBytes(stream, buf_size));
buf_size = ReadInt(new_stream);
}
else
{
ReadInt(stream); // ignored cuz rest of data is compressed
}
stream = DecompressZLX(stream);
var decompressed_stream = DecompressZLX(new_stream);
new_stream.Dispose();
if (compression_type > GRFFile.eCompressionType.Zlib)
{
byte[] data = RLE<byte>.Decode(ReadBytes(stream, buf_size)).ToArray();
stream = new MemoryStream(data);
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(stream, 23);
ReadBytes(decompressed_stream, 23);
return stream;
return decompressed_stream;
}
private void ReadBody(Stream stream)
{
ReadTagNames(stream);
ReadGRFTags(stream);
}
private Stream DecompressZLX(Stream compressedStream)
@@ -83,6 +88,7 @@ namespace PckStudio.Classes.IO.GRF
Stream outputstream = new MemoryStream();
using (var inputStream = new InflaterInputStream(compressedStream))
{
inputStream.IsStreamOwner = false;
inputStream.CopyTo(outputstream);
outputstream.Position = 0;
};
@@ -94,29 +100,33 @@ namespace PckStudio.Classes.IO.GRF
int name_count = ReadInt(stream);
TagNames = new List<string>(name_count);
for (int i = 0; i < name_count; i++)
TagNames.Add(ReadString(stream));
{
string s = ReadString(stream);
TagNames.Add(s);
//Console.WriteLine(s);
}
}
private void ReadGRFTags(Stream stream)
{
var NameAndCount = GetTagNameAndDetailCount(stream);
var NameAndCount = GetRuleNameAndCount(stream);
_file.RootTag = new GRFFile.GRFTag(NameAndCount.Item1, null);
_file.RootTag.Tags = ReadItemList(stream, NameAndCount.Item2, _file.RootTag);
_file.RootTag.Tags = ReadTags(stream, NameAndCount.Item2, _file.RootTag);
}
internal List<GRFFile.GRFTag> ReadItemList(Stream stream, int count, GRFFile.GRFTag parent)
internal List<GRFFile.GRFTag> ReadTags(Stream stream, int count, GRFFile.GRFTag parent)
{
List<GRFFile.GRFTag> tags = new List<GRFFile.GRFTag>();
for (int i = 0; i < count; i++)
{
var valuePair = GetTagNameAndDetailCount(stream);
var valuePair = GetRuleNameAndCount(stream);
var tag = new GRFFile.GRFTag(valuePair.Item1, parent);
for (var j = 0; j < valuePair.Item2; j++)
for (int j = 0; j < valuePair.Item2; j++)
{
var tuple = GetTagNameAndValue(stream);
tag.Parameters.Add(tuple.Item1, tuple.Item2);
}
tag.Tags = ReadItemList(stream, ReadInt(stream), tag);
tag.Tags = ReadTags(stream, ReadInt(stream), tag);
tags.Add(tag);
}
return tags;
@@ -124,7 +134,7 @@ namespace PckStudio.Classes.IO.GRF
internal string GetTagName(Stream stream) => TagNames[ReadInt(stream)];
internal (string, int) GetTagNameAndDetailCount(Stream stream)
internal (string, int) GetRuleNameAndCount(Stream stream)
{
return new ValueTuple<string, int>(GetTagName(stream), ReadInt(stream));
}
@@ -161,7 +171,7 @@ namespace PckStudio.Classes.IO.GRF
{
short stringLength = ReadShort(stream);
byte[] buffer = ReadBytes(stream, stringLength);
return Encoding.UTF8.GetString(buffer);
return Encoding.ASCII.GetString(buffer);
}
}

View File

@@ -4,63 +4,154 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using PckStudio.Classes.Utils;
using PckStudio.Classes.Utils.grf;
namespace PckStudio.Classes.IO.GRF
{
public class GRFFileWriter
{
internal GRFFile _grfFile;
public static void Write(Stream stream, GRFFile grfFile)
internal readonly GRFFile _grfFile;
internal List<string> LUT;
public static void Write(in Stream stream, GRFFile grfFile)
{
new GRFFileWriter(grfFile).write(stream);
var instance = new GRFFileWriter(grfFile);
instance.write(stream);
}
private GRFFileWriter(GRFFile grfFile)
{
if (grfFile.IsWorld)
throw new NotImplementedException("World grf saving is currently unsupported");
_grfFile = grfFile;
LUT = new List<string>();
PrepareLookUpTable(_grfFile.RootTag, LUT);
}
private void write(Stream stream)
{
BuildHeader(stream);
WriteTagNames(stream);
WriteHeader(stream);
using (var uncompressed_stream = new MemoryStream())
{
WriteBody(uncompressed_stream);
HandleCompression(stream, uncompressed_stream);
}
}
private void BuildHeader(Stream stream)
private void HandleCompression(Stream destinationStream, MemoryStream sourceStream)
{
WriteShort(stream, 1); // (x >> 31 | x) == 1
byte[] _buffer = sourceStream.ToArray();
int _original_length = _buffer.Length;
if (_grfFile.CompressionType >= GRFFile.eCompressionType.ZlibRle)
_buffer = CompressRle(_buffer);
if (_grfFile.CompressionType >= GRFFile.eCompressionType.Zlib)
{
_buffer = CompressZib(_buffer);
WriteInt(destinationStream, _original_length);
WriteInt(destinationStream, _buffer.Length);
}
if (_grfFile.CompressionType >= GRFFile.eCompressionType.ZlibRleCrc)
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;
WriteInt(stream, (int)crc);
stream.Seek(0, SeekOrigin.End); // reset to the end of the stream
}
}
private void WriteHeader(Stream stream)
{
WriteShort(stream, 1);
if (_grfFile.CompressionType < GRFFile.eCompressionType.None ||
_grfFile.CompressionType > GRFFile.eCompressionType.ZlibRleCrc)
throw new ArgumentException(nameof(_grfFile.CompressionType));
stream.WriteByte((byte)_grfFile.CompressionType);
WriteInt(stream, _grfFile.Crc);
stream.WriteByte(0);
stream.WriteByte(0);
stream.WriteByte(0);
stream.WriteByte(0);
stream.WriteByte(0); // <- used in world grf
}
private void WriteTagNames(Stream stream)
private void WriteBody(Stream stream)
{
List<string> tagNames = new List<string>();
GatherTagNames(_grfFile.RootTag, tagNames);
WriteInt(stream, tagNames.Count);
foreach (var s in tagNames)
WriteTagLookUpTable(stream);
WriteRuleNameAndCount(stream, _grfFile.RootTag.Name, _grfFile.RootTag.Tags.Count);
WriteGameRules(stream, _grfFile.RootTag.Tags);
}
private void WriteTagLookUpTable(Stream stream)
{
WriteInt(stream, LUT.Count);
LUT.ForEach( s => WriteString(stream, s) );
}
private void PrepareLookUpTable(GRFFile.GRFTag tag, List<string> LUT)
{
if (!LUT.Contains(tag.Name)) LUT.Add(tag.Name);
tag.Tags.ForEach( tag => PrepareLookUpTable(tag, LUT));
foreach (var param in tag.Parameters)
if (!LUT.Contains(param.Key)) LUT.Add(param.Key);
}
private void WriteGameRules(Stream stream, List<GRFFile.GRFTag> tags)
{
foreach(var tag in tags)
{
WriteString(stream, s);
Console.WriteLine(s);
WriteRuleNameAndCount(stream, tag.Name, tag.Parameters.Count);
foreach (var param in tag.Parameters) WriteParameter(stream, param);
WriteInt(stream, tag.Tags.Count);
WriteGameRules(stream, tag.Tags);
}
}
private void GatherTagNames(GRFFile.GRFTag tag, List<string> l)
private void WriteRuleNameAndCount(Stream stream, string name, int count)
{
if (!l.Contains(tag.Name)) l.Add(tag.Name);
foreach (var subTag in tag.Tags)
GatherTagNames(subTag, l);
foreach (var subTag in tag.Parameters)
if (!l.Contains(subTag.Key)) l.Add(subTag.Key);
WriteRuleName(stream, name);
WriteInt(stream, count);
}
internal void WriteInt(Stream stream, int value)
private void WriteParameter(Stream stream, KeyValuePair<string, string> param)
{
WriteRuleName(stream, param.Key);
WriteString(stream, param.Value);
}
private void WriteRuleName(Stream stream, string name)
{
int i = LUT.IndexOf(name);
if (i == -1) throw new Exception("No index found for: " + name);
WriteInt(stream, i);
}
static internal void WriteInt(Stream stream, int value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
@@ -68,7 +159,7 @@ namespace PckStudio.Classes.IO.GRF
WriteBytes(stream, bytes);
}
internal void WriteShort(Stream stream, short value)
static internal void WriteShort(Stream stream, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
@@ -76,17 +167,15 @@ namespace PckStudio.Classes.IO.GRF
WriteBytes(stream, bytes);
}
internal void WriteString(Stream stream, string s)
static internal void WriteString(Stream stream, string s)
{
WriteShort(stream, (short)s.Length);
WriteBytes(stream, Encoding.UTF8.GetBytes(s));
WriteBytes(stream, Encoding.ASCII.GetBytes(s));
}
internal void WriteBytes(Stream stream, byte[] bytes)
static internal void WriteBytes(Stream stream, byte[] bytes)
{
stream.Write(bytes, 0, bytes.Length);
}
}
}

View File

@@ -122,18 +122,16 @@ static class RLE<T> where T : struct, IConvertible
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)
for (ulong i = 0; i < length; i++)
{
if (value.Equals(rleMarker))
yield return rleMarker;
yield return value;
yield return value.Equals(rleMarker) ? rleMarker : value;
}
}
else
{
//compressed run
yield return rleMarker;
yield return (T)(dynamic)length;
yield return (T)(dynamic)(length-1);
yield return value;
}
}
@@ -141,7 +139,6 @@ static class RLE<T> where T : struct, IConvertible
private static void GetMaxValues()
{
object maxValue = default(T);
TypeCode typeCode = Type.GetTypeCode(typeof(T));
switch (typeCode)
{

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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

@@ -0,0 +1,181 @@
namespace PckStudio.Forms.Utilities.Grf
{
partial class AddParameter
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddParameter));
this.metroLabel1 = new MetroFramework.Controls.MetroLabel();
this.metroLabel2 = new MetroFramework.Controls.MetroLabel();
this.NameTextBox = new MetroFramework.Controls.MetroTextBox();
this.ValueTextBox = new MetroFramework.Controls.MetroTextBox();
this.CancelButton = new MetroFramework.Controls.MetroButton();
this.ConfirmButton = new MetroFramework.Controls.MetroButton();
this.SuspendLayout();
//
// metroLabel1
//
this.metroLabel1.AutoSize = true;
this.metroLabel1.Location = new System.Drawing.Point(18, 27);
this.metroLabel1.Name = "metroLabel1";
this.metroLabel1.Size = new System.Drawing.Size(48, 19);
this.metroLabel1.TabIndex = 0;
this.metroLabel1.Text = "Name:";
this.metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// metroLabel2
//
this.metroLabel2.AutoSize = true;
this.metroLabel2.Location = new System.Drawing.Point(17, 56);
this.metroLabel2.Name = "metroLabel2";
this.metroLabel2.Size = new System.Drawing.Size(42, 19);
this.metroLabel2.TabIndex = 1;
this.metroLabel2.Text = "Value:";
this.metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// NameTextBox
//
//
//
//
this.NameTextBox.CustomButton.Image = null;
this.NameTextBox.CustomButton.Location = new System.Drawing.Point(143, 1);
this.NameTextBox.CustomButton.Name = "";
this.NameTextBox.CustomButton.Size = new System.Drawing.Size(21, 21);
this.NameTextBox.CustomButton.Style = MetroFramework.MetroColorStyle.Blue;
this.NameTextBox.CustomButton.TabIndex = 1;
this.NameTextBox.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light;
this.NameTextBox.CustomButton.UseSelectable = true;
this.NameTextBox.CustomButton.Visible = false;
this.NameTextBox.Lines = new string[0];
this.NameTextBox.Location = new System.Drawing.Point(72, 27);
this.NameTextBox.MaxLength = 32767;
this.NameTextBox.Name = "NameTextBox";
this.NameTextBox.PasswordChar = '\0';
this.NameTextBox.ScrollBars = System.Windows.Forms.ScrollBars.None;
this.NameTextBox.SelectedText = "";
this.NameTextBox.SelectionLength = 0;
this.NameTextBox.SelectionStart = 0;
this.NameTextBox.ShortcutsEnabled = true;
this.NameTextBox.Size = new System.Drawing.Size(165, 23);
this.NameTextBox.Style = MetroFramework.MetroColorStyle.White;
this.NameTextBox.TabIndex = 2;
this.NameTextBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.NameTextBox.UseSelectable = true;
this.NameTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
this.NameTextBox.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel);
//
// ValueTextBox
//
//
//
//
this.ValueTextBox.CustomButton.Image = null;
this.ValueTextBox.CustomButton.Location = new System.Drawing.Point(143, 1);
this.ValueTextBox.CustomButton.Name = "";
this.ValueTextBox.CustomButton.Size = new System.Drawing.Size(21, 21);
this.ValueTextBox.CustomButton.Style = MetroFramework.MetroColorStyle.Blue;
this.ValueTextBox.CustomButton.TabIndex = 1;
this.ValueTextBox.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light;
this.ValueTextBox.CustomButton.UseSelectable = true;
this.ValueTextBox.CustomButton.Visible = false;
this.ValueTextBox.Lines = new string[0];
this.ValueTextBox.Location = new System.Drawing.Point(72, 56);
this.ValueTextBox.MaxLength = 32767;
this.ValueTextBox.Name = "ValueTextBox";
this.ValueTextBox.PasswordChar = '\0';
this.ValueTextBox.ScrollBars = System.Windows.Forms.ScrollBars.None;
this.ValueTextBox.SelectedText = "";
this.ValueTextBox.SelectionLength = 0;
this.ValueTextBox.SelectionStart = 0;
this.ValueTextBox.ShortcutsEnabled = true;
this.ValueTextBox.Size = new System.Drawing.Size(165, 23);
this.ValueTextBox.Style = MetroFramework.MetroColorStyle.White;
this.ValueTextBox.TabIndex = 3;
this.ValueTextBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.ValueTextBox.UseSelectable = true;
this.ValueTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
this.ValueTextBox.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel);
//
// CancelButton
//
this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.CancelButton.Location = new System.Drawing.Point(23, 85);
this.CancelButton.Name = "CancelButton";
this.CancelButton.Size = new System.Drawing.Size(95, 23);
this.CancelButton.Style = MetroFramework.MetroColorStyle.White;
this.CancelButton.TabIndex = 4;
this.CancelButton.Text = "Cancel";
this.CancelButton.Theme = MetroFramework.MetroThemeStyle.Dark;
this.CancelButton.UseSelectable = true;
//
// ConfirmButton
//
this.ConfirmButton.Location = new System.Drawing.Point(141, 85);
this.ConfirmButton.Name = "ConfirmButton";
this.ConfirmButton.Size = new System.Drawing.Size(96, 23);
this.ConfirmButton.Style = MetroFramework.MetroColorStyle.White;
this.ConfirmButton.TabIndex = 5;
this.ConfirmButton.Text = "Confirm";
this.ConfirmButton.Theme = MetroFramework.MetroThemeStyle.Dark;
this.ConfirmButton.UseSelectable = true;
this.ConfirmButton.Click += new System.EventHandler(this.ConfirmButton_Click);
//
// AddParameter
//
this.AcceptButton = this.ConfirmButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(257, 126);
this.Controls.Add(this.ConfirmButton);
this.Controls.Add(this.CancelButton);
this.Controls.Add(this.ValueTextBox);
this.Controls.Add(this.NameTextBox);
this.Controls.Add(this.metroLabel2);
this.Controls.Add(this.metroLabel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AddParameter";
this.Resizable = false;
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private MetroFramework.Controls.MetroLabel metroLabel1;
private MetroFramework.Controls.MetroLabel metroLabel2;
private MetroFramework.Controls.MetroTextBox ValueTextBox;
private MetroFramework.Controls.MetroButton CancelButton;
private MetroFramework.Controls.MetroButton ConfirmButton;
private MetroFramework.Controls.MetroTextBox NameTextBox;
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PckStudio.Forms.Utilities.Grf
{
public partial class AddParameter : MetroFramework.Forms.MetroForm
{
public string ParameterName => NameTextBox.Text;
public string ParameterValue => ValueTextBox.Text;
public AddParameter()
{
InitializeComponent();
}
public AddParameter(string parameterName, string parameterValue) : this()
{
NameTextBox.Text = parameterName;
ValueTextBox.Text = parameterValue;
}
public AddParameter(string parameterName, string parameterValue, bool parameterNameBoxEnabled = true) : this(parameterName, parameterValue)
{
NameTextBox.Enabled = parameterNameBoxEnabled;
}
private void ConfirmButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(ParameterName) || string.IsNullOrWhiteSpace(ParameterValue))
{
MessageBox.Show("Name and Value need valid values");
return;
}
DialogResult = DialogResult.OK;
Close();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,254 @@
namespace PckStudio.Forms.Utilities
{
partial class GRFEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GRFEditor));
this.GrfTreeView = new System.Windows.Forms.TreeView();
this.MessageContextMenu = new MetroFramework.Controls.MetroContextMenu(this.components);
this.addGameRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeGameRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GrfParametersTreeView = new System.Windows.Forms.TreeView();
this.DetailContextMenu = new MetroFramework.Controls.MetroContextMenu(this.components);
this.addToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.metroLabel1 = new MetroFramework.Controls.MetroLabel();
this.metroLabel2 = new MetroFramework.Controls.MetroLabel();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
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.MessageContextMenu.SuspendLayout();
this.DetailContextMenu.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.metroPanel1.SuspendLayout();
this.SuspendLayout();
//
// GrfTreeView
//
this.GrfTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.GrfTreeView.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.GrfTreeView.ContextMenuStrip = this.MessageContextMenu;
this.GrfTreeView.Dock = System.Windows.Forms.DockStyle.Left;
this.GrfTreeView.ForeColor = System.Drawing.SystemColors.MenuBar;
this.GrfTreeView.Location = new System.Drawing.Point(0, 0);
this.GrfTreeView.Name = "GrfTreeView";
this.GrfTreeView.Size = new System.Drawing.Size(223, 312);
this.GrfTreeView.TabIndex = 0;
this.GrfTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.GrfTreeView_AfterSelect);
this.GrfTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GrfTreeView_KeyDown);
//
// MessageContextMenu
//
this.MessageContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addGameRuleToolStripMenuItem,
this.removeGameRuleToolStripMenuItem});
this.MessageContextMenu.Name = "MessageContextMenu";
this.MessageContextMenu.Size = new System.Drawing.Size(178, 48);
//
// addGameRuleToolStripMenuItem
//
this.addGameRuleToolStripMenuItem.Name = "addGameRuleToolStripMenuItem";
this.addGameRuleToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
this.addGameRuleToolStripMenuItem.Text = "Add Game Rule";
this.addGameRuleToolStripMenuItem.Click += new System.EventHandler(this.addGameRuleToolStripMenuItem_Click);
//
// removeGameRuleToolStripMenuItem
//
this.removeGameRuleToolStripMenuItem.Name = "removeGameRuleToolStripMenuItem";
this.removeGameRuleToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
this.removeGameRuleToolStripMenuItem.Text = "Remove Game Rule";
this.removeGameRuleToolStripMenuItem.Click += new System.EventHandler(this.removeGameRuleToolStripMenuItem_Click);
//
// GrfParametersTreeView
//
this.GrfParametersTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.GrfParametersTreeView.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.GrfParametersTreeView.ContextMenuStrip = this.DetailContextMenu;
this.GrfParametersTreeView.Dock = System.Windows.Forms.DockStyle.Right;
this.GrfParametersTreeView.ForeColor = System.Drawing.SystemColors.MenuBar;
this.GrfParametersTreeView.Location = new System.Drawing.Point(227, 0);
this.GrfParametersTreeView.Name = "GrfParametersTreeView";
this.GrfParametersTreeView.Size = new System.Drawing.Size(223, 312);
this.GrfParametersTreeView.TabIndex = 1;
this.GrfParametersTreeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.GrfDetailsTreeView_NodeMouseDoubleClick);
this.GrfParametersTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.GrfDetailsTreeView_KeyDown);
//
// DetailContextMenu
//
this.DetailContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addToolStripMenuItem1,
this.removeToolStripMenuItem});
this.DetailContextMenu.Name = "DetailContextMenu";
this.DetailContextMenu.Size = new System.Drawing.Size(118, 48);
//
// addToolStripMenuItem1
//
this.addToolStripMenuItem1.Name = "addToolStripMenuItem1";
this.addToolStripMenuItem1.Size = new System.Drawing.Size(117, 22);
this.addToolStripMenuItem1.Text = "Add";
this.addToolStripMenuItem1.Click += new System.EventHandler(this.addDetailContextMenuItem_Click);
//
// removeToolStripMenuItem
//
this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
this.removeToolStripMenuItem.Size = new System.Drawing.Size(117, 22);
this.removeToolStripMenuItem.Text = "Remove";
this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
//
// metroLabel1
//
this.metroLabel1.AutoSize = true;
this.metroLabel1.Location = new System.Drawing.Point(25, 88);
this.metroLabel1.Name = "metroLabel1";
this.metroLabel1.Size = new System.Drawing.Size(73, 19);
this.metroLabel1.TabIndex = 2;
this.metroLabel1.Text = "Game Rule";
this.metroLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// metroLabel2
//
this.metroLabel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.metroLabel2.AutoSize = true;
this.metroLabel2.Location = new System.Drawing.Point(252, 88);
this.metroLabel2.Name = "metroLabel2";
this.metroLabel2.Size = new System.Drawing.Size(75, 19);
this.metroLabel2.TabIndex = 0;
this.metroLabel2.Text = "Parameters";
this.metroLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// menuStrip1
//
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.menuStrip1.Location = new System.Drawing.Point(25, 60);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(450, 24);
this.menuStrip1.TabIndex = 3;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openToolStripMenuItem,
this.saveToolStripMenuItem});
this.fileToolStripMenuItem.ForeColor = System.Drawing.SystemColors.Menu;
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// openToolStripMenuItem
//
this.openToolStripMenuItem.Enabled = false;
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
this.openToolStripMenuItem.Text = "Open";
//
// saveToolStripMenuItem
//
this.saveToolStripMenuItem.BackColor = System.Drawing.Color.Transparent;
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
//
// metroPanel1
//
this.metroPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.metroPanel1.Controls.Add(this.GrfParametersTreeView);
this.metroPanel1.Controls.Add(this.GrfTreeView);
this.metroPanel1.HorizontalScrollbarBarColor = true;
this.metroPanel1.HorizontalScrollbarHighlightOnWheel = false;
this.metroPanel1.HorizontalScrollbarSize = 10;
this.metroPanel1.Location = new System.Drawing.Point(25, 110);
this.metroPanel1.Name = "metroPanel1";
this.metroPanel1.Size = new System.Drawing.Size(450, 312);
this.metroPanel1.TabIndex = 4;
this.metroPanel1.Theme = MetroFramework.MetroThemeStyle.Dark;
this.metroPanel1.VerticalScrollbarBarColor = true;
this.metroPanel1.VerticalScrollbarHighlightOnWheel = false;
this.metroPanel1.VerticalScrollbarSize = 10;
this.metroPanel1.Resize += new System.EventHandler(this.metroPanel1_Resize);
//
// GRFEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 450);
this.Controls.Add(this.metroPanel1);
this.Controls.Add(this.menuStrip1);
this.Controls.Add(this.metroLabel2);
this.Controls.Add(this.metroLabel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.menuStrip1;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(500, 450);
this.Name = "GRFEditor";
this.Padding = new System.Windows.Forms.Padding(25, 60, 25, 25);
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Text = "GRF Editor";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnExit);
this.Load += new System.EventHandler(this.OnLoad);
this.MessageContextMenu.ResumeLayout(false);
this.DetailContextMenu.ResumeLayout(false);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.metroPanel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TreeView GrfTreeView;
private System.Windows.Forms.TreeView GrfParametersTreeView;
private MetroFramework.Controls.MetroLabel metroLabel1;
private MetroFramework.Controls.MetroLabel metroLabel2;
private MetroFramework.Controls.MetroContextMenu MessageContextMenu;
private MetroFramework.Controls.MetroContextMenu DetailContextMenu;
private System.Windows.Forms.ToolStripMenuItem addGameRuleToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addToolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeGameRuleToolStripMenuItem;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
private MetroFramework.Controls.MetroPanel metroPanel1;
}
}

View File

@@ -0,0 +1,223 @@
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.GRF;
using PckStudio.Forms.Utilities.Grf;
using RichPresenceClient;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PckStudio.Forms.Utilities
{
public partial class GRFEditor : MetroFramework.Forms.MetroForm
{
private PCKFile.FileData _pckfile;
private GRFFile _file;
private GRFEditor()
{
InitializeComponent();
}
public GRFEditor(PCKFile.FileData file) : this()
{
_pckfile = file;
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");
}
}
}
public GRFEditor(Stream stream) : this()
{
try
{
_file = GRFFileReader.Read(stream);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show("Faild to open .grf/.grh file");
}
}
private void OnLoad(object sender, EventArgs e)
{
RPC.SetPresence("GRF Editor", "Editing a GRF File");
loadGRFTreeView(GrfTreeView.Nodes, _file.RootTag);
}
private void OnExit(object sender, FormClosingEventArgs e)
{
RPC.SetPresence("Sitting alone", "Program by PhoenixARC");
Dispose();
}
private void loadGRFTreeView(TreeNodeCollection root, GRFFile.GRFTag parentTag)
{
foreach (var tag in parentTag.Tags)
{
TreeNode node = new TreeNode(tag.Name);
node.Tag = tag;
root.Add(node);
loadGRFTreeView(node.Nodes, tag);
}
}
private void GrfTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node == null || !(e.Node.Tag is GRFFile.GRFTag)) return;
ReloadParameterTreeView();
}
private void ReloadParameterTreeView()
{
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
GrfParametersTreeView.Nodes.Clear();
foreach (var Pair in grfTag.Parameters)
{
GrfParametersTreeView.Nodes.Add(new TreeNode($"{Pair.Key}: {Pair.Value}") { Tag = Pair});
}
}
private void addDetailContextMenuItem_Click(object sender, EventArgs e)
{
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
AddParameter prompt = new AddParameter();
if (prompt.ShowDialog() == DialogResult.OK)
{
if (grfTag.Parameters.ContainsKey(prompt.ParameterName))
{
MessageBox.Show("Can't add detail that already exists.", "Error");
return;
}
grfTag.Parameters.Add(prompt.ParameterName, prompt.ParameterValue);
ReloadParameterTreeView();
}
}
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag) ||
GrfParametersTreeView.SelectedNode == null || !(GrfParametersTreeView.SelectedNode.Tag is KeyValuePair<string, string>))
{
MessageBox.Show("No Rule selected");
return;
}
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
var pair = (KeyValuePair<string, string>)GrfParametersTreeView.SelectedNode.Tag;
if (grfTag.Parameters.ContainsKey(pair.Key) && grfTag.Parameters.Remove(pair.Key))
ReloadParameterTreeView();
}
private void GrfDetailsTreeView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
removeToolStripMenuItem_Click(sender, e);
}
private void GrfDetailsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (GrfTreeView.SelectedNode == null ||
!(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag) ||
GrfParametersTreeView.SelectedNode == null ||
!(GrfParametersTreeView.SelectedNode.Tag is KeyValuePair<string, string>)) return;
var grfTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
var param = (KeyValuePair<string, string>)GrfParametersTreeView.SelectedNode.Tag;
AddParameter prompt = new AddParameter(param.Key, param.Value, false);
if (prompt.ShowDialog() == DialogResult.OK)
{
grfTag.Parameters[prompt.ParameterName] = prompt.ParameterValue;
ReloadParameterTreeView();
}
}
private void addGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
{
if(GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
var parentTag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
using (RenamePrompt prompt = new RenamePrompt(""))
{
prompt.OKButton.Text = "Add";
if (MessageBox.Show($"Add Game Rule to {parentTag.Name}", "Attention",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes &&
prompt.ShowDialog() == DialogResult.OK &&
!string.IsNullOrWhiteSpace(prompt.NewText))
{
var tag = new GRFFile.GRFTag(prompt.NewText, parentTag);
parentTag.Tags.Add(tag);
TreeNode node = new TreeNode(tag.Name);
node.Tag = tag;
GrfTreeView.SelectedNode.Nodes.Add(node);
}
}
}
private void removeGameRuleToolStripMenuItem_Click(object sender, EventArgs e)
{
if (GrfTreeView.SelectedNode == null || !(GrfTreeView.SelectedNode.Tag is GRFFile.GRFTag)) return;
var tag = GrfTreeView.SelectedNode.Tag as GRFFile.GRFTag;
if (removeTag(tag))
GrfTreeView.SelectedNode.Remove();
}
private bool removeTag(GRFFile.GRFTag tag)
{
foreach (var subTag in tag.Tags.ToList())
return removeTag(subTag);
return tag.Parent.Tags.Remove(tag);
}
private void GrfTreeView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
removeGameRuleToolStripMenuItem_Click(sender, e);
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_file.IsWorld)
{
MessageBox.Show("World grf saving is currently unsupported");
return;
}
using (var stream = new MemoryStream())
{
try
{
GRFFileWriter.Write(stream, _file);
_pckfile?.SetData(stream.ToArray());
MessageBox.Show("Saved!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show("Failed to save grf file", "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void metroPanel1_Resize(object sender, EventArgs e)
{
int padding = 2;
GrfTreeView.Size = new Size(metroPanel1.Size.Width / 2 - padding, metroPanel1.Size.Height);
GrfParametersTreeView.Size = new Size(metroPanel1.Size.Width / 2 - padding, metroPanel1.Size.Height);
// good enough
metroLabel2.Location = new Point(metroPanel1.Size.Width / 2 + 25, metroLabel2.Location.Y);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -96,8 +96,13 @@
this.DBGLabel = new MetroFramework.Controls.MetroLabel();
this.tabControl = new MetroFramework.Controls.MetroTabControl();
this.openTab = new System.Windows.Forms.TabPage();
this.myTablePanelStartScreen = new PckStudio.Forms.MyTablePanel();
this.richTextBoxChangelog = new System.Windows.Forms.RichTextBox();
this.label5 = new MetroFramework.Controls.MetroLabel();
this.pckOpen = new System.Windows.Forms.PictureBox();
this.editorTab = new MetroFramework.Controls.MetroTabPage();
this.labelImageSize = new MetroFramework.Controls.MetroLabel();
this.pictureBoxImagePreview = new PckStudio.PictureBoxWithInterpolationMode();
this.fileEntryCountLabel = new MetroFramework.Controls.MetroLabel();
this.tabControl1 = new MetroFramework.Controls.MetroTabControl();
this.MetaTab = new MetroFramework.Controls.MetroTabPage();
@@ -111,23 +116,18 @@
this.treeViewMain = new System.Windows.Forms.TreeView();
this.imageList = new System.Windows.Forms.ImageList(this.components);
this.LittleEndianCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.myTablePanelStartScreen = new PckStudio.Forms.MyTablePanel();
this.richTextBoxChangelog = new System.Windows.Forms.RichTextBox();
this.label5 = new MetroFramework.Controls.MetroLabel();
this.pckOpen = new System.Windows.Forms.PictureBox();
this.pictureBoxImagePreview = new PckStudio.PictureBoxWithInterpolationMode();
this.contextMenuPCKEntries.SuspendLayout();
this.menuStrip.SuspendLayout();
this.contextMenuMetaTree.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.tabControl.SuspendLayout();
this.openTab.SuspendLayout();
this.editorTab.SuspendLayout();
this.tabControl1.SuspendLayout();
this.MetaTab.SuspendLayout();
this.myTablePanelStartScreen.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pckOpen)).BeginInit();
this.editorTab.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxImagePreview)).BeginInit();
this.tabControl1.SuspendLayout();
this.MetaTab.SuspendLayout();
this.SuspendLayout();
//
// contextMenuPCKEntries
@@ -600,6 +600,45 @@
resources.ApplyResources(this.openTab, "openTab");
this.openTab.Name = "openTab";
//
// myTablePanelStartScreen
//
this.myTablePanelStartScreen.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
resources.ApplyResources(this.myTablePanelStartScreen, "myTablePanelStartScreen");
this.myTablePanelStartScreen.Controls.Add(this.richTextBoxChangelog, 1, 1);
this.myTablePanelStartScreen.Controls.Add(this.label5, 1, 0);
this.myTablePanelStartScreen.Controls.Add(this.pckOpen, 0, 0);
this.myTablePanelStartScreen.Name = "myTablePanelStartScreen";
//
// richTextBoxChangelog
//
this.richTextBoxChangelog.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(28)))), ((int)(((byte)(28)))), ((int)(((byte)(28)))));
this.richTextBoxChangelog.BorderStyle = System.Windows.Forms.BorderStyle.None;
resources.ApplyResources(this.richTextBoxChangelog, "richTextBoxChangelog");
this.richTextBoxChangelog.ForeColor = System.Drawing.Color.White;
this.richTextBoxChangelog.Name = "richTextBoxChangelog";
this.richTextBoxChangelog.ReadOnly = true;
//
// label5
//
resources.ApplyResources(this.label5, "label5");
this.label5.ForeColor = System.Drawing.Color.White;
this.label5.Name = "label5";
this.label5.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// pckOpen
//
this.pckOpen.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
resources.ApplyResources(this.pckOpen, "pckOpen");
this.pckOpen.Name = "pckOpen";
this.myTablePanelStartScreen.SetRowSpan(this.pckOpen, 2);
this.pckOpen.TabStop = false;
this.pckOpen.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
this.pckOpen.DragDrop += new System.Windows.Forms.DragEventHandler(this.OpenPck_DragDrop);
this.pckOpen.DragEnter += new System.Windows.Forms.DragEventHandler(this.OpenPck_DragEnter);
this.pckOpen.DragLeave += new System.EventHandler(this.OpenPck_DragLeave);
this.pckOpen.MouseEnter += new System.EventHandler(this.OpenPck_MouseEnter);
this.pckOpen.MouseLeave += new System.EventHandler(this.OpenPck_MouseLeave);
//
// editorTab
//
this.editorTab.BackColor = System.Drawing.Color.Transparent;
@@ -626,6 +665,14 @@
this.labelImageSize.Name = "labelImageSize";
this.labelImageSize.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// pictureBoxImagePreview
//
resources.ApplyResources(this.pictureBoxImagePreview, "pictureBoxImagePreview");
this.pictureBoxImagePreview.Image = global::PckStudio.Properties.Resources.NoImageFound;
this.pictureBoxImagePreview.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.pictureBoxImagePreview.Name = "pictureBoxImagePreview";
this.pictureBoxImagePreview.TabStop = false;
//
// fileEntryCountLabel
//
resources.ApplyResources(this.fileEntryCountLabel, "fileEntryCountLabel");
@@ -787,53 +834,6 @@
this.LittleEndianCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.LittleEndianCheckBox.UseSelectable = true;
//
// myTablePanelStartScreen
//
this.myTablePanelStartScreen.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
resources.ApplyResources(this.myTablePanelStartScreen, "myTablePanelStartScreen");
this.myTablePanelStartScreen.Controls.Add(this.richTextBoxChangelog, 1, 1);
this.myTablePanelStartScreen.Controls.Add(this.label5, 1, 0);
this.myTablePanelStartScreen.Controls.Add(this.pckOpen, 0, 0);
this.myTablePanelStartScreen.Name = "myTablePanelStartScreen";
//
// richTextBoxChangelog
//
this.richTextBoxChangelog.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(28)))), ((int)(((byte)(28)))), ((int)(((byte)(28)))));
this.richTextBoxChangelog.BorderStyle = System.Windows.Forms.BorderStyle.None;
resources.ApplyResources(this.richTextBoxChangelog, "richTextBoxChangelog");
this.richTextBoxChangelog.ForeColor = System.Drawing.Color.White;
this.richTextBoxChangelog.Name = "richTextBoxChangelog";
this.richTextBoxChangelog.ReadOnly = true;
//
// label5
//
resources.ApplyResources(this.label5, "label5");
this.label5.ForeColor = System.Drawing.Color.White;
this.label5.Name = "label5";
this.label5.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// pckOpen
//
this.pckOpen.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
resources.ApplyResources(this.pckOpen, "pckOpen");
this.pckOpen.Name = "pckOpen";
this.myTablePanelStartScreen.SetRowSpan(this.pckOpen, 2);
this.pckOpen.TabStop = false;
this.pckOpen.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
this.pckOpen.DragDrop += new System.Windows.Forms.DragEventHandler(this.OpenPck_DragDrop);
this.pckOpen.DragEnter += new System.Windows.Forms.DragEventHandler(this.OpenPck_DragEnter);
this.pckOpen.DragLeave += new System.EventHandler(this.OpenPck_DragLeave);
this.pckOpen.MouseEnter += new System.EventHandler(this.OpenPck_MouseEnter);
this.pckOpen.MouseLeave += new System.EventHandler(this.OpenPck_MouseLeave);
//
// pictureBoxImagePreview
//
resources.ApplyResources(this.pictureBoxImagePreview, "pictureBoxImagePreview");
this.pictureBoxImagePreview.Image = global::PckStudio.Properties.Resources.NoImageFound;
this.pictureBoxImagePreview.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.pictureBoxImagePreview.Name = "pictureBoxImagePreview";
this.pictureBoxImagePreview.TabStop = false;
//
// MainForm
//
this.ApplyImageInvert = true;
@@ -850,8 +850,6 @@
this.ShadowType = MetroFramework.Forms.MetroFormShadowType.DropShadow;
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.Activated += new System.EventHandler(this.FormMain_Activated);
this.Deactivate += new System.EventHandler(this.FormMain_Deactivate);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormMain_FormClosing);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormMain_FormClosed);
this.Load += new System.EventHandler(this.Form1_Load);
@@ -862,15 +860,15 @@
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.tabControl.ResumeLayout(false);
this.openTab.ResumeLayout(false);
this.editorTab.ResumeLayout(false);
this.editorTab.PerformLayout();
this.tabControl1.ResumeLayout(false);
this.MetaTab.ResumeLayout(false);
this.MetaTab.PerformLayout();
this.myTablePanelStartScreen.ResumeLayout(false);
this.myTablePanelStartScreen.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pckOpen)).EndInit();
this.editorTab.ResumeLayout(false);
this.editorTab.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxImagePreview)).EndInit();
this.tabControl1.ResumeLayout(false);
this.MetaTab.ResumeLayout(false);
this.MetaTab.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();

File diff suppressed because one or more lines are too long

View File

@@ -539,7 +539,7 @@
</value>
</data>
<data name="advancedMetaAddingToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>176, 22</value>
<value>180, 22</value>
</data>
<data name="advancedMetaAddingToolStripMenuItem.Text" xml:space="preserve">
<value>Advanced Bulk</value>
@@ -565,7 +565,7 @@
</value>
</data>
<data name="convertToBedrockToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>176, 22</value>
<value>180, 22</value>
</data>
<data name="convertToBedrockToolStripMenuItem.Text" xml:space="preserve">
<value>Convert to Bedrock</value>
@@ -29858,7 +29858,7 @@
<value>Bottom, Right</value>
</data>
<data name="buttonEdit.Location" type="System.Drawing.Point, System.Drawing">
<value>214, 223</value>
<value>213, 229</value>
</data>
<data name="buttonEdit.Size" type="System.Drawing.Size, System.Drawing">
<value>324, 60</value>
@@ -32630,9 +32630,6 @@
AP//AAA=
</value>
</data>
<data name="$this.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="$this.MinimumSize" type="System.Drawing.Size, System.Drawing">
<value>843, 658</value>
</data>

View File

@@ -143,9 +143,12 @@
<Compile Include="Classes\FileTypes\Bink.cs" />
<Compile Include="Classes\FileTypes\COLFile.cs" />
<Compile Include="Classes\FileTypes\CSM.cs" />
<Compile Include="Classes\FileTypes\GRFFile.cs" />
<Compile Include="Classes\FileTypes\LCESkin.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\PCKCollectionsLocal.cs" />
@@ -181,6 +184,8 @@
<Compile Include="Classes\Networking\PCKCollections.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\FakeProgressBar.cs">
<SubType>Form</SubType>
</Compile>
@@ -253,6 +258,18 @@
<Compile Include="Forms\Skins-And-Textures\EntryEditor.Designer.cs">
<DependentUpon>EntryEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editor\GRFEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Editor\GRFEditor.Designer.cs">
<DependentUpon>GRFEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Additional-Popups\Grf\AddParameter.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Additional-Popups\Grf\AddParameter.Designer.cs">
<DependentUpon>AddParameter.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -467,6 +484,12 @@
<DependentUpon>EntryEditor.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Editor\GRFEditor.resx">
<DependentUpon>GRFEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Additional-Popups\Grf\AddParameter.resx">
<DependentUpon>AddParameter.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.ja.resx">
<DependentUpon>MainForm.cs</DependentUpon>
<SubType>Designer</SubType>
@@ -675,6 +698,9 @@
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
</PackageReference>
<PackageReference Include="SharpZipLib">
<Version>1.3.3</Version>
</PackageReference>
<PackageReference Include="System.ValueTuple">
<Version>4.5.0</Version>
</PackageReference>