diff --git a/CTFAK/CTFAK.csproj b/CTFAK/CTFAK.csproj
index d6eded8..8c206c3 100644
--- a/CTFAK/CTFAK.csproj
+++ b/CTFAK/CTFAK.csproj
@@ -159,6 +159,7 @@
MainForm.cs
+
diff --git a/CTFAK/GUI/MainForm.Designer.cs b/CTFAK/GUI/MainForm.Designer.cs
index b6be12d..323cd3b 100644
--- a/CTFAK/GUI/MainForm.Designer.cs
+++ b/CTFAK/GUI/MainForm.Designer.cs
@@ -566,9 +566,11 @@
//
this.imageViewerInfo.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.imageViewerInfo.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64)))));
- this.imageViewerInfo.Location = new System.Drawing.Point(777, 3);
+ this.imageViewerInfo.Font = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (204)));
+ this.imageViewerInfo.Location = new System.Drawing.Point(696, 3);
this.imageViewerInfo.Name = "imageViewerInfo";
- this.imageViewerInfo.Size = new System.Drawing.Size(155, 63);
+ this.imageViewerInfo.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
+ this.imageViewerInfo.Size = new System.Drawing.Size(236, 63);
this.imageViewerInfo.TabIndex = 3;
this.imageViewerInfo.Text = "DEBUG";
//
diff --git a/CTFAK/GUI/MainForm.cs b/CTFAK/GUI/MainForm.cs
index 4b4b74c..fae9365 100644
--- a/CTFAK/GUI/MainForm.cs
+++ b/CTFAK/GUI/MainForm.cs
@@ -42,6 +42,7 @@ namespace CTFAK.GUI
private bool _isAudioPlaying;
private SoundPlayer _soundPlayer;
+ public Label ObjectViewerLabel;
public MainForm(Color color)
@@ -110,6 +111,12 @@ namespace CTFAK.GUI
if (dlg == DialogResult.Yes) Environment.Exit(0);
else e.Cancel = true;
};
+ imageViewerInfo.Parent = imageViewPictureBox;
+ imageViewerInfo.BackColor=Color.Transparent;
+ imageViewerInfo.Dock = DockStyle.Right;
+
+
+
KeyPreview = true;
tabControl1.Selecting += tabControl1_Selecting;
}
@@ -158,6 +165,9 @@ namespace CTFAK.GUI
console.Show();
console.Location = new Point(Location.X + Size.Width - 15, 0);
console.Size = new Size(console.Size.Width, Size.Height);
+
+
+
}
@@ -652,15 +662,20 @@ namespace CTFAK.GUI
}
else if(common.Parent.ObjectType==7)//Counter
{
- for (var a = 0; a < common.Counters?.Frames?.Count; a++)
+
+ var count = common.Counters?.Frames?.Count??0;
+
+ for (var a = 0; a < count; a++)
{
var animFrame = common.Counters.Frames[a];
bank.Images.TryGetValue(animFrame, out var img);
- if (img != null)
+ if (img == null)
{
- var animFrameNode = new ChunkNode(a.ToString(), img);
- objInstNode.Nodes.Add(animFrameNode);
+
+ continue;
}
+ var animFrameNode = new ChunkNode(a.ToString(), img);
+ objInstNode.Nodes.Add(animFrameNode);
}
@@ -771,12 +786,57 @@ namespace CTFAK.GUI
private void advancedTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
+ ObjectViewerLabel?.Dispose();
var node = e.Node;
- if (((ChunkNode) node).loader is ImageItem)
+ var loader = ((ChunkNode) node).loader;
+ string text=String.Empty;
+ imageViewPictureBox.Image = null;
+ if (loader is ImageItem img)
{
- var img = (ImageItem) ((ChunkNode) node).loader;
+ text += $"Size: {img.Bitmap.Width}x{img.Bitmap.Height}\r\n";
+ text += $"Action Point: {img.ActionX}x{img.ActionY}\r\n";
+ text += $"Hotspot: {img.XHotspot}x{img.YHotspot}\r\n";
imageViewPictureBox.Image = img.Bitmap;
}
+ else if (loader is ObjectInstance instance)
+ {
+
+ text += $"Name: {instance.FrameItem.Name}\r\n";
+ text += $"Type: {(Constants.ObjectType)instance.FrameItem.ObjectType}\r\n";
+ text += $"Position: {instance?.X}x{instance?.Y}\r\n";
+ text += $"Size: {instance.FrameItem.GetPreview()?.Bitmap.Width}x{instance.FrameItem.GetPreview()?.Bitmap.Width}\r\n";
+ if (instance.FrameItem.Properties.IsCommon)
+ {
+ var common = ((ObjectCommon) instance.FrameItem.Properties.Loader);
+ switch (instance.FrameItem.ObjectType)
+ {
+ case 3:
+ ObjectViewerLabel = new Label();
+ var content = string.Empty;
+ foreach (var par in common.Text.Items)
+ {
+ content += $"{par.Value}\r\n";
+ content += $"\r\n\r\n\r\n";
+ }
+ ObjectViewerLabel.Text = content;
+ ObjectViewerLabel.Parent = imageViewPictureBox;
+ ObjectViewerLabel.Dock = DockStyle.Fill;
+ ObjectViewerLabel.TextAlign = ContentAlignment.MiddleCenter;
+
+ imageViewPictureBox.Controls.Add(ObjectViewerLabel);
+ break;
+ default:
+ text += "No additional info";
+ break;
+
+ }
+ }
+
+
+
+
+ }
+ imageViewerInfo.Text = text;
}
diff --git a/CTFAK/MMFParser/EXE/ChunkList.cs b/CTFAK/MMFParser/EXE/ChunkList.cs
index 742c02c..d952e7d 100644
--- a/CTFAK/MMFParser/EXE/ChunkList.cs
+++ b/CTFAK/MMFParser/EXE/ChunkList.cs
@@ -24,6 +24,7 @@ namespace CTFAK.MMFParser.EXE
if (chunk.Id == 26214)
{
if(!Settings.twofiveplus) chunk.Loader = LoadChunk(chunk);
+ //LoadChunk(chunk);
}
else
{
diff --git a/CTFAK/MMFParser/EXE/Loaders/Banks/FontBank.cs b/CTFAK/MMFParser/EXE/Loaders/Banks/FontBank.cs
index 8b0dab7..62f14ed 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Banks/FontBank.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Banks/FontBank.cs
@@ -34,5 +34,30 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks
{
}
}
+ public class FontItem:ChunkLoader
+ {
+ public FontItem(ByteReader reader) : base(reader)
+ {
+ }
+
+ public FontItem(Chunk chunk) : base(chunk)
+ {
+ }
+
+ public override void Read()
+ {
+ var handle = Reader.ReadUInt32();
+
+ }
+ public override void Print(bool ext)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override string[] GetReadableData()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
}
diff --git a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
index 4f76332..bd7c832 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
@@ -301,7 +301,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks
}
case 8:
{
- imageReader.Seek(start+Size);
+ Logger.Log("Reading 32-bit color");
(_colorArray, bytesRead) = ImageHelper.Read32(imageData, _width, _height);
break;
}
diff --git a/CTFAK/MMFParser/EXE/Loaders/ObjectInfo.cs b/CTFAK/MMFParser/EXE/Loaders/ObjectInfo.cs
index 0bc4cb7..d6d5e62 100644
--- a/CTFAK/MMFParser/EXE/Loaders/ObjectInfo.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/ObjectInfo.cs
@@ -126,6 +126,21 @@ namespace CTFAK.MMFParser.EXE.Loaders
return bmp;
}
+
+ public List GetInstances()
+ {
+ var list = new List();
+ var frames = Exe.Instance.GameData.Frames;
+ foreach (var frame in frames)
+ {
+ foreach (ObjectInstance instance in frame.Objects.Items)
+ {
+ if(instance.ObjectInfo==this.Handle)list.Add(instance);
+ }
+ }
+
+ return list;
+ }
}
public class ObjectName : StringChunk
@@ -165,7 +180,7 @@ namespace CTFAK.MMFParser.EXE.Loaders
{
Loader = new Backdrop(Reader);
}
- else if(ObjectType==2|| ObjectType==7)
+ else
{
IsCommon = true;
Loader = new ObjectCommon(Reader,parent);
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/Animations.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Animations.cs
index c8cb0c1..6cf1594 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Objects/Animations.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Animations.cs
@@ -20,6 +20,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
var currentPosition = Reader.Tell();
var size = Reader.ReadInt16();
var count = Reader.ReadInt16();
+
var offsets = new List();
for (int i = 0; i < count; i++)
{
@@ -33,6 +34,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
{
Reader.Seek(currentPosition+offset);
var anim = new Animation(Reader);
+
anim.Read();
AnimationDict.Add(i,anim);
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs
index bd54888..8283114 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs
@@ -60,6 +60,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public override void Read()
{
+
var size = Reader.ReadUInt32();
var width = Reader.ReadUInt32();
var height = Reader.ReadUInt32();
@@ -77,8 +78,9 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
var inverse = ByteFlag.GetFlag(flags, 8);
var font = Reader.ReadUInt16();
if (displayType == 0) return;
- else if (displayType == 1 || displayType == 4)
+ else if (displayType == 1 || displayType == 4|| displayType==50)
{
+
Frames = new List();
var count = Reader.ReadInt16();
for (int i = 0; i < count; i++)
@@ -89,7 +91,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
else if (displayType == 2 || displayType == 3 || displayType == 5)
{
//TODO: Shapes
- throw new NotImplementedException();
+ Logger.Log("Ignoring unsupported counter type");
}
}
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
index 889f93f..3d50987 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
@@ -8,9 +8,9 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
{
private ushort _valuesOffset;
private ushort _stringsOffset;
- private byte[] Identifier;
- private ushort _fadeinOffset;
- private ushort _fadeoutOffset;
+ private int Identifier;
+ private uint _fadeinOffset;
+ private uint _fadeoutOffset;
private ushort _movementsOffset;
private ushort _animationsOffset;
private ushort _systemObjectOffset;
@@ -83,6 +83,8 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public AlterableValues Values;
public AlterableStrings Strings;
public Movements Movements;
+ private ushort _unk;
+ public Text Text;
public ObjectCommon(ByteReader reader) : base(reader)
@@ -95,7 +97,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public ObjectCommon(ChunkList.Chunk chunk) : base(chunk)
{
}
-
+
public override void Read()
{
@@ -107,115 +109,76 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
_animationsOffset = Reader.ReadUInt16();
_movementsOffset = Reader.ReadUInt16();
var version = Reader.ReadUInt16();
- Reader.Skip(2); //TODO: Find out
+ _unk = Reader.ReadUInt16();
+ _extensionOffset = Reader.ReadUInt16();
_counterOffset = Reader.ReadUInt16();
+ Flags.flag = Reader.ReadUInt16();
+ _end = Reader.Tell() + (8+1) * 2;
+
+ Reader.Seek(_end);
_systemObjectOffset = Reader.ReadUInt16();
+
+
+ _valuesOffset = Reader.ReadUInt16();
+ _stringsOffset = Reader.ReadUInt16();
+ NewFlags.flag = Reader.ReadUInt16();
+ preferences.flag = Reader.ReadUInt16();
+ Identifier = Reader.ReadInt32();
+ BackColor = Reader.ReadColor();
+ _fadeinOffset = Reader.ReadUInt32();
+ _fadeoutOffset = Reader.ReadUInt32();
}
else
{
_movementsOffset = Reader.ReadUInt16();
_animationsOffset = Reader.ReadUInt16();
var version = Reader.ReadUInt16();
+ //_unk = Reader.ReadUInt16();
+ _extensionOffset = Reader.ReadUInt16();
_counterOffset = Reader.ReadUInt16();
- _systemObjectOffset = Reader.ReadUInt16();
- }
-
- Flags.flag = Reader.ReadUInt32();
- var end = Reader.Tell() + 16;
- //Ignoring qualifiers
- Reader.Seek(end);
- if (Settings.Build == 284)
- {
+ Flags.flag = Reader.ReadUInt16();
+ _end = Reader.Tell() + (8+1) * 2;
+
+ Reader.Seek(_end);
_systemObjectOffset = Reader.ReadUInt16();
- }
- else
- {
- _extensionOffset = Reader.PeekUInt16();
- }
+
- _valuesOffset = Reader.ReadUInt16();
- _stringsOffset = Reader.ReadUInt16();
- NewFlags.flag = Reader.ReadUInt32();
- preferences.flag = Reader.ReadUInt32();
- Identifier = Reader.ReadBytes(4);
- BackColor = Reader.ReadColor();
- _fadeinOffset = (ushort) Reader.ReadUInt32();
- _fadeoutOffset = (ushort) Reader.ReadUInt32();
-
- if (_movementsOffset != 0)
- {
- Reader.Seek(currentPosition+_movementsOffset);
- Movements = new Movements(Reader);
- Movements.Read();
- //Console.WriteLine("Movements done");
- }
-
-
- if (_valuesOffset != 0)
- {
- Reader.Seek(currentPosition + _valuesOffset);
- Values = new AlterableValues(Reader);
- Values.Read();
- // Console.WriteLine("Values done");
- }
-
-
- if (_stringsOffset != 0)
- {
- Reader.Seek(currentPosition + _stringsOffset);
- Strings = new AlterableStrings(Reader);
- Strings.Read();
- // Console.WriteLine("Strings done");
- }
-
-
- if (_animationsOffset != 0&& Parent.ObjectType==2)
- {
- Reader.Seek(currentPosition + _animationsOffset);
- Animations = new Animations(Reader);
- Animations.Read();
- // Console.WriteLine("Animations done");
+ _valuesOffset = Reader.ReadUInt16();
+ _stringsOffset = Reader.ReadUInt16();
+ NewFlags.flag = Reader.ReadUInt16();
+ preferences.flag = Reader.ReadUInt16();
+ Identifier = Reader.ReadInt32();
+ BackColor = Reader.ReadColor();
+ _fadeinOffset = Reader.ReadUInt32();
+ _fadeoutOffset = Reader.ReadUInt32();
}
- /*if (_counterOffset != 0)
+ if (_animationsOffset > 0)
{
- Reader.Seek(currentPosition + _counterOffset);
- var counter = new Counter(Reader);
- counter.Read();
- Console.WriteLine("Counters done");
+ Reader.Seek(currentPosition+_animationsOffset);
+ Animations=new Animations(Reader);
+ Animations.Read();
}
-
- if (_extensionOffset != 0)
- {
- var dataSize = Reader.ReadInt32() - 20;
- ExtensionVersion = Reader.ReadInt32();
- ExtensionId = Reader.ReadInt32();
- ExtensionPrivate = Reader.ReadInt32();
- if (dataSize != 0)
- ExtensionData = Reader.ReadBytes(dataSize);
- Console.WriteLine("Extensions Done");
-
- }*/
-
- if (_systemObjectOffset != 0)
+
+ if (_systemObjectOffset > 0)
{
- Logger.Log("Reading System Object: "+_systemObjectOffset);
Reader.Seek(currentPosition+_systemObjectOffset);
- if (Parent.ObjectType == ((int) Constants.ObjectType.Text) ||
- Parent.ObjectType == ((int) Constants.ObjectType.Question))
+ if (Parent.ObjectType == 7) //Counter
{
- //TODO; Text.read();
+
+ Counters=new Counters(Reader);
+ Counters.Read();
}
- else if (Parent.ObjectType == ((int) Constants.ObjectType.Score) ||
- Parent.ObjectType == ((int) Constants.ObjectType.Lives)||
- Parent.ObjectType == ((int) Constants.ObjectType.Counter))
+ else if(Parent.ObjectType==3)//Text
{
- Logger.Log("Counter: "+Parent.Name);
- Counters = new Counters(Reader);
- Counters.Read();
+
+ Text = new Text(Reader);
+ Text.Read();
+
}
}
+
// Logger.Log("anims: "+_animationsOffset);
// Logger.Log("fadeIn: "+_fadeinOffset);
// Logger.Log("fadeOut: "+_fadeoutOffset);
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/Text.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Text.cs
new file mode 100644
index 0000000..8ebb7a4
--- /dev/null
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Text.cs
@@ -0,0 +1,97 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms.VisualStyles;
+using System.Xml.Schema;
+using CTFAK.Utils;
+
+namespace CTFAK.MMFParser.EXE.Loaders.Objects
+{
+ public class Text:ChunkLoader
+ {
+ public int Width;
+ public int Height;
+ public List Items;
+
+ public Text(ByteReader reader) : base(reader)
+ {
+ }
+
+ public Text(ChunkList.Chunk chunk) : base(chunk)
+ {
+ }
+
+ public override void Read()
+ {
+ var currentPos = Reader.Tell();
+ var size = Reader.ReadInt32();
+ Width = Reader.ReadInt32();
+ Height = Reader.ReadInt32();
+ List itemOffsets = new List();
+ var offCount = Reader.ReadInt32();
+ for (int i = 0; i < offCount; i++)
+ {
+ itemOffsets.Add(Reader.ReadInt32());
+ }
+ Items = new List();
+ foreach (int itemOffset in itemOffsets)
+ {
+ Reader.Seek(currentPos+itemOffset);
+ var par = new Paragraph(Reader);
+ par.Read();
+ Items.Add(par);
+ }
+
+ }
+
+ public override void Print(bool ext)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override string[] GetReadableData()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+
+ public class Paragraph : ChunkLoader
+ {
+ public ushort FontHandle;
+ public BitDict Flags = new BitDict(new string[]{
+ "HorizontalCenter",
+ "RightAligned",
+ "VerticalCenter",
+ "BottomAligned",
+ "None", "None", "None", "None",
+ "Correct",
+ "Relief"});
+ public string Value;
+ public Color Color;
+
+ public Paragraph(ByteReader reader) : base(reader)
+ {
+ }
+
+ public Paragraph(ChunkList.Chunk chunk) : base(chunk)
+ {
+ }
+
+ public override void Read()
+ {
+ FontHandle = Reader.ReadUInt16();
+ Flags.flag = Reader.ReadUInt16();
+ Color = Reader.ReadColor();
+ Value = Reader.ReadWideString();
+ }
+
+ public override void Print(bool ext)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override string[] GetReadableData()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/Value.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Value.cs
index 1163858..cc65995 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Objects/Value.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Value.cs
@@ -19,12 +19,15 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public override void Read()
{
Items = new List();
-
+ Reader.ReadUInt16();
var count = Reader.ReadUInt16();
+ Logger.Log("Alterable value count "+count);
Console.WriteLine(count);
for (int i = 0; i < count; i++)
{
+
var item = Reader.ReadInt32();
+ Logger.Log($"{i} - {item}");
Items.Add(item);
@@ -58,6 +61,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
Items = new List();
var count = Reader.ReadUInt16();
+ Logger.Log("Alterable string count "+count);
for (int i = 0; i < count; i++)
{
diff --git a/CTFAK/Utils/ImageHelper.cs b/CTFAK/Utils/ImageHelper.cs
index 2cf3d11..6488e75 100644
--- a/CTFAK/Utils/ImageHelper.cs
+++ b/CTFAK/Utils/ImageHelper.cs
@@ -59,28 +59,27 @@ namespace CTFAK.Utils
}
public static (byte[], int) Read32(byte[] data, int width, int height)
{
- byte[] colorArray = new byte[width * height * 4];
+ byte[] colorArray = new byte[width * height * 8];
int stride = width * 4;
- int pad = GetPadding(width, 3);
+ int pad = GetPadding(width, 6);
int position = 0;
- try
+ for (int y = 0; y < height; y++)
{
- for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
{
- for (int x = 0; x < width; x++)
- {
- position += 3;
- }
- position += pad * 3;
+
+
+ colorArray[(y * stride) + (x * 4) + 0] = data[position];//+1
+ colorArray[(y * stride) + (x * 4) + 1] = data[position + 2];//+3
+ colorArray[(y * stride) + (x * 4) + 2] = data[position + 4];//+5
+ colorArray[(y * stride) + (x * 4) + 3] = 255;
+ position += 6;
}
- }
- catch
- {
- return (Array.Empty(), position);
- }
+ position += pad * 6;
+ }
- return (Array.Empty(), position);
+ return (colorArray, position);