More object reader refactoring, fixed issues with text objects, advanced object viewer(still called image viewer)

master
1987kostya 4 years ago
parent 24853e3da3
commit 496cab002f

@ -159,6 +159,7 @@
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="MMFParser\EXE\Loaders\Objects\Movements.cs" />
<Compile Include="MMFParser\EXE\Loaders\Objects\Text.cs" />
<Compile Include="MMFParser\Translation\MFAGenerator.cs" />
<Compile Include="MMFParser\Translation\PAME2MFA.cs" />
<Compile Include="MMFParser\EXE\ChunkList.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";
//

@ -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,16 +662,21 @@ 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)
{
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 img = (ImageItem) ((ChunkNode) node).loader;
var loader = ((ChunkNode) node).loader;
string text=String.Empty;
imageViewPictureBox.Image = null;
if (loader is ImageItem img)
{
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;
}

@ -24,6 +24,7 @@ namespace CTFAK.MMFParser.EXE
if (chunk.Id == 26214)
{
if(!Settings.twofiveplus) chunk.Loader = LoadChunk(chunk);
//LoadChunk(chunk);
}
else
{

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

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

@ -126,6 +126,21 @@ namespace CTFAK.MMFParser.EXE.Loaders
return bmp;
}
public List<ObjectInstance> GetInstances()
{
var list = new List<ObjectInstance>();
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);

@ -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<short>();
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);

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

@ -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)
@ -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.ReadUInt16();
_end = Reader.Tell() + (8+1) * 2;
Flags.flag = Reader.ReadUInt32();
var end = Reader.Tell() + 16;
//Ignoring qualifiers
Reader.Seek(end);
if (Settings.Build == 284)
{
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);
NewFlags.flag = Reader.ReadUInt16();
preferences.flag = Reader.ReadUInt16();
Identifier = Reader.ReadInt32();
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");
_fadeinOffset = Reader.ReadUInt32();
_fadeoutOffset = Reader.ReadUInt32();
}
if (_valuesOffset != 0)
if (_animationsOffset > 0)
{
Reader.Seek(currentPosition + _valuesOffset);
Values = new AlterableValues(Reader);
Values.Read();
// Console.WriteLine("Values done");
Reader.Seek(currentPosition+_animationsOffset);
Animations=new Animations(Reader);
Animations.Read();
}
if (_stringsOffset != 0)
if (_systemObjectOffset > 0)
{
Reader.Seek(currentPosition + _stringsOffset);
Strings = new AlterableStrings(Reader);
Strings.Read();
// Console.WriteLine("Strings done");
}
if (_animationsOffset != 0&& Parent.ObjectType==2)
Reader.Seek(currentPosition+_systemObjectOffset);
if (Parent.ObjectType == 7) //Counter
{
Reader.Seek(currentPosition + _animationsOffset);
Animations = new Animations(Reader);
Animations.Read();
// Console.WriteLine("Animations done");
}
/*if (_counterOffset != 0)
{
Reader.Seek(currentPosition + _counterOffset);
var counter = new Counter(Reader);
counter.Read();
Console.WriteLine("Counters done");
Counters=new Counters(Reader);
Counters.Read();
}
if (_extensionOffset != 0)
else if(Parent.ObjectType==3)//Text
{
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");
}*/
Text = new Text(Reader);
Text.Read();
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))
{
//TODO; Text.read();
}
else if (Parent.ObjectType == ((int) Constants.ObjectType.Score) ||
Parent.ObjectType == ((int) Constants.ObjectType.Lives)||
Parent.ObjectType == ((int) Constants.ObjectType.Counter))
{
Logger.Log("Counter: "+Parent.Name);
Counters = new Counters(Reader);
Counters.Read();
}
}
// Logger.Log("anims: "+_animationsOffset);
// Logger.Log("fadeIn: "+_fadeinOffset);
// Logger.Log("fadeOut: "+_fadeoutOffset);

@ -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<Paragraph> 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<int> itemOffsets = new List<int>();
var offCount = Reader.ReadInt32();
for (int i = 0; i < offCount; i++)
{
itemOffsets.Add(Reader.ReadInt32());
}
Items = new List<Paragraph>();
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();
}
}
}

@ -19,12 +19,15 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public override void Read()
{
Items = new List<int>();
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<string>();
var count = Reader.ReadUInt16();
Logger.Log("Alterable string count "+count);
for (int i = 0; i < count; i++)
{

@ -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 x = 0; x < width; x++)
{
position += 3;
}
position += pad * 3;
}
}
catch
{
return (Array.Empty<byte>(), position);
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;
}
position += pad * 6;
}
return (Array.Empty<byte>(), position);
return (colorArray, position);

Loading…
Cancel
Save