diff --git a/CTFAK/CTFAK.csproj b/CTFAK/CTFAK.csproj index 196323a..11c7928 100644 --- a/CTFAK/CTFAK.csproj +++ b/CTFAK/CTFAK.csproj @@ -176,6 +176,7 @@ <Compile Include="MMFParser\EXE\Loaders\Events\Parameters\TwoShorts.cs" /> <Compile Include="MMFParser\EXE\Loaders\Events\Parameters\Zone.cs" /> <Compile Include="MMFParser\EXE\Loaders\Extensions.cs" /> + <Compile Include="MMFParser\EXE\Loaders\FrameHandles.cs" /> <Compile Include="MMFParser\EXE\Loaders\Objects\Movements.cs" /> <Compile Include="MMFParser\EXE\Loaders\Objects\Text.cs" /> <Compile Include="MMFParser\MFA\Loaders\mfachunks\Backdrop.cs" /> diff --git a/CTFAK/MMFParser/EXE/ChunkList.cs b/CTFAK/MMFParser/EXE/ChunkList.cs index 5c48a6f..2c15e2f 100644 --- a/CTFAK/MMFParser/EXE/ChunkList.cs +++ b/CTFAK/MMFParser/EXE/ChunkList.cs @@ -209,6 +209,9 @@ namespace CTFAK.MMFParser.EXE case 8743: loader = new ExtPath(chunk); break; + case 8747: + loader=new FrameHandles(chunk); + break; case 8750: loader = new EditorFilename(chunk); break; diff --git a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs index 4026df9..fba08f1 100644 --- a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs +++ b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs @@ -17,7 +17,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks public bool SaveImages = false; public Dictionary<int, ImageItem> Images = new Dictionary<int, ImageItem>(); public uint NumberOfItems; - public bool PreloadOnly=false; + public bool PreloadOnly = false; public ImageBank(ByteReader reader) : base(reader) { @@ -51,64 +51,57 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks public ImageItem FromHandle(int handle) { Images.TryGetValue(handle, out var img); - if (handle == -1) return Images[Images.Count-1]; + if (handle == -1) return Images[Images.Count - 1]; if (img == null) return null; else return img; } - + public void LoadByHandle(int handle) { - + Images[handle].Load(); } - - + + public event MainForm.SaveHandler OnImageSaved; - - + + public override void Read() { - + if (!Settings.DoMFA) Reader.Seek(0); //Reset the reader to avoid bugs when dumping more than once var tempImages = new Dictionary<int, ImageItem>(); NumberOfItems = (uint) Reader.ReadInt32(); - Logger.Log($"Found {NumberOfItems} images",true,ConsoleColor.Green); - + Logger.Log($"Found {NumberOfItems} images", true, ConsoleColor.Green); + //if (!Settings.DumpImages) return; - Logger.Log("Reading Images",true,ConsoleColor.Green); + Logger.Log("Reading Images", true, ConsoleColor.Green); for (int i = 0; i < NumberOfItems; i++) { - if (MainForm.BreakImages) + if (MainForm.BreakImages) break; { - - break; - } - - var item = new ImageItem(Reader); - - item.Read(!PreloadOnly); - tempImages.Add(item.Handle, item); - if (SaveImages) item.Save($"{Settings.ImagePath}\\" + item.Handle.ToString() + ".png"); - OnImageSaved?.Invoke(i,(int) NumberOfItems); + var item = new ImageItem(Reader); - //if (Settings.Build >= 284) - // item.Handle -= 1; + item.Read(!PreloadOnly); + tempImages.Add(item.Handle, item); + if (SaveImages) item.Save($"{Settings.ImagePath}\\" + item.Handle.ToString() + ".png"); + OnImageSaved?.Invoke(i, (int) NumberOfItems); - //images[item.handle] = item; + } + } - Logger.Log("Images success",true,ConsoleColor.Green); + Logger.Log("Images success", true, ConsoleColor.Green); if (!MainForm.BreakImages) Images = tempImages; MainForm.BreakImages = false; - } } diff --git a/CTFAK/MMFParser/EXE/Loaders/Events/Parameters/Group.cs b/CTFAK/MMFParser/EXE/Loaders/Events/Parameters/Group.cs index c402e4f..db1000d 100644 --- a/CTFAK/MMFParser/EXE/Loaders/Events/Parameters/Group.cs +++ b/CTFAK/MMFParser/EXE/Loaders/Events/Parameters/Group.cs @@ -27,10 +27,10 @@ namespace CTFAK.MMFParser.EXE.Loaders.Events.Parameters public override void Write(ByteWriter Writer) { - Writer.WriteUInt16(0); + Writer.WriteUInt16(Flags); Writer.WriteUInt16(Id); Writer.WriteUnicode(Name,true); - if(true)//decrypt password + if(true) { Password = Checksum.MakeGroupChecksum("", Name); } diff --git a/CTFAK/MMFParser/EXE/Loaders/FrameHandles.cs b/CTFAK/MMFParser/EXE/Loaders/FrameHandles.cs new file mode 100644 index 0000000..ab8986a --- /dev/null +++ b/CTFAK/MMFParser/EXE/Loaders/FrameHandles.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; +using CTFAK.Utils; + +namespace CTFAK.MMFParser.EXE.Loaders +{ + public class FrameHandles:ChunkLoader + { + public Dictionary<int,int> Items; + + public FrameHandles(ByteReader reader) : base(reader) + { + } + + public FrameHandles(ChunkList.Chunk chunk) : base(chunk) + { + } + + public override void Read() + { + + var len = Reader.Size() / 2; + Items = new Dictionary<int,int>(); + for (int i = 0; i < len; i++) + { + var handle = Reader.ReadInt16(); + Logger.Log("Frame Handle: "+handle); + Items.Add(i,handle); + } + + } + + 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/Counters.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs index 94a7f41..95d4d19 100644 --- a/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs +++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Counters.cs @@ -62,6 +62,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects public ushort DisplayType; public ushort Flags; public ushort Player; + public Shape Shape; public Counters(ByteReader reader) : base(reader) { @@ -103,8 +104,8 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects } else if (DisplayType == 2 || DisplayType == 3 || DisplayType == 5) { - //TODO: Shapes - Logger.Log("Ignoring unsupported counter type"); + Shape = new Shape(Reader); + Shape.Read(); } } diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/Movements.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/Movements.cs index 592568b..31ed7f5 100644 --- a/CTFAK/MMFParser/EXE/Loaders/Objects/Movements.cs +++ b/CTFAK/MMFParser/EXE/Loaders/Objects/Movements.cs @@ -88,12 +88,13 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects case 3: Loader=new EightDirections(Reader); break; - case 5: - Loader=new MovementPath(Reader); - break; case 4: Loader=new Ball(Reader); break; + case 5: + Loader=new MovementPath(Reader); + break; + } if(Loader==null&&Type!=0) throw new Exception("Unsupported movement: "+Type); @@ -388,4 +389,42 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects Writer.WriteInt16(ReverseEnabled); } } + public class PlatformMovement:MovementLoader + { + public short Speed; + public short Acceleration; + public short Deceleration; + public short Control; + public short Gravity; + public short JumpStrength; + + public PlatformMovement(ByteReader reader) : base(reader) + { + } + + public PlatformMovement(ChunkList.Chunk chunk) : base(chunk) + { + } + + public override void Read() + { + Speed = Reader.ReadInt16(); + Acceleration = Reader.ReadInt16(); + Deceleration = Reader.ReadInt16(); + Control = Reader.ReadInt16(); + Gravity = Reader.ReadInt16(); + JumpStrength = Reader.ReadInt16(); + } + + public override void Write(ByteWriter Writer) + { + Writer.WriteInt16(Speed); + Writer.WriteInt16(Acceleration); + Writer.WriteInt16(Deceleration); + Writer.WriteInt16(Control); + Writer.WriteInt16(Gravity); + Writer.WriteInt16(JumpStrength); + + } + } } \ No newline at end of file diff --git a/CTFAK/MMFParser/Translation/MFAGenerator.cs b/CTFAK/MMFParser/Translation/MFAGenerator.cs index a58140b..aeae949 100644 --- a/CTFAK/MMFParser/Translation/MFAGenerator.cs +++ b/CTFAK/MMFParser/Translation/MFAGenerator.cs @@ -45,7 +45,7 @@ namespace CTFAK.MMFParser.Translation else mfaReader = new ByteReader(TemplatePath, FileMode.Open); Logger.Log("Loading images"); Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().PreloadOnly = false; - Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().Read(true,false); + // Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().Read(true,false); // Exe.Instance.GameData.GameChunks.GetChunk<SoundBank>().Read(); Settings.DoMFA = true; diff --git a/CTFAK/MMFParser/Translation/PAME2MFA.cs b/CTFAK/MMFParser/Translation/PAME2MFA.cs index 71c84cf..1e6d2c4 100644 --- a/CTFAK/MMFParser/Translation/PAME2MFA.cs +++ b/CTFAK/MMFParser/Translation/PAME2MFA.cs @@ -57,6 +57,8 @@ namespace CTFAK.MMFParser.Translation mfa.Images.Items[key].Debug = true; } + // game.Images.Images.Clear(); + mfa.Author = game.Author ?? ""; mfa.Copyright = game.Copyright ?? ""; mfa.Company = ""; @@ -102,29 +104,34 @@ namespace CTFAK.MMFParser.Translation // var reference = mfa.Frames.FirstOrDefault(); mfa.Frames.Clear(); - foreach (Frame frame in game.Frames) + Dictionary<int,int> indexHandles = new Dictionary<int, int>(); + foreach (var pair in Program.CleanData.GameChunks.GetChunk<FrameHandles>().Items) + { + var key = pair.Key; + var handle = pair.Value; + if (!indexHandles.ContainsKey(handle)) indexHandles.Add(handle, key); + else indexHandles[handle] = key; + } + + + for (int a=0;a<game.Frames.Count;a++) { - if(frame.Palette==null|| frame.Events==null|| frame.Objects==null) continue; - Message("Translating frame: " + frame.Name); + var frame = game.Frames[a]; + // if(frame.Palette==null|| frame.Events==null|| frame.Objects==null) continue; + var newFrame = new MFA.Loaders.Frame(null); newFrame.Chunks = new ChunkList(null);//MFA.MFA.emptyFrameChunks; - newFrame.Handle = game.Frames.IndexOf(frame); + newFrame.Handle = indexHandles[a]; + Message($"Translating frame: {frame.Name} - {newFrame.Handle}" ); newFrame.Name = frame.Name; newFrame.SizeX = frame.Width; newFrame.SizeY = frame.Height; - // var newRectLoader = newFrame.Chunks.GetChunk<FrameVirtualRect>(); - // newRectLoader.Right = frame.Width; - // newRectLoader.Bottom = frame.Height; - - newFrame.Background = frame.Background; newFrame.FadeIn = null; newFrame.FadeOut = null; var mfaFlags = newFrame.Flags; var originalFlags = frame.Flags; - - mfaFlags["GrabDesktop"] = originalFlags["GrabDesktop"]; mfaFlags["KeepDisplay"] = originalFlags["KeepDisplay"]; @@ -147,21 +154,17 @@ namespace CTFAK.MMFParser.Translation for (int i=0;i<count;i++) { var layer = frame.Layers[i]; - var newLayer = new MFA.Loaders.Layer(null); + var newLayer = new Layer(null); newLayer.Name = layer.Name; newLayer.Flags["HideAtStart"] = layer.Flags["ToHide"]; newLayer.Flags["Visible"] = true; newLayer.Flags["NoBackground"] = layer.Flags["DoNotSaveBackground"]; newLayer.Flags["WrapHorizontally"] = layer.Flags["WrapHorizontally"]; - newLayer.Flags["WrapVertically"] = layer.Flags["WrapVertically"]; - // newLayer.Flags.flag = 0; newLayer.XCoefficient = layer.XCoeff; newLayer.YCoefficient = layer.YCoeff; - newLayer.RGBCoeff = Color.FromArgb(255,0,0,255); newFrame.Layers.Add(newLayer); - // break; - // + } @@ -191,8 +194,6 @@ namespace CTFAK.MMFParser.Translation newInstance.ParentHandle = (uint) instance.ParentHandle; newInstance.Layer = (uint) (instance.Layer); newInstances.Add(newInstance); - // Logger.Log($"{instance.FrameItem.Name} - {i}"); - } } } @@ -211,15 +212,13 @@ namespace CTFAK.MMFParser.Translation } - // if (frame.Events != null) + if (frame.Events != null) { - newFrame.Events = new Events((ByteReader) null); //MFA.MFA.emptyEvents; + newFrame.Events = new Events((ByteReader) null); newFrame.Events.Items = new List<EventGroup>(); newFrame.Events.Objects = new List<EventObject>(); - newFrame.Events._cache = MFA.MFA.emptyEvents._cache; newFrame.Events._ifMFA = true; newFrame.Events.Version = 1028; - // if (frame.Name == "jopajopaher") { foreach (var item in newFrame.Items) { @@ -235,43 +234,7 @@ namespace CTFAK.MMFParser.Translation newObject.InstanceHandle = 0xFFFFFFFF; newFrame.Events.Objects.Add(newObject); } - - foreach (EventGroup item in frame.Events.Items) - { - /*foreach (Action itemAction in item.Actions) - { - for (int a=0;a<itemAction.Items.Count;a++) - { - if (itemAction.Items[a].Loader is ExpressionParameter exp) - { - // itemAction.Items.Remove(itemAction.Items[a]); - - } - else if (itemAction.Items[a].Loader is Sample) - { - itemAction.Items.Remove(itemAction.Items[a]); - } - } - } - foreach (Condition itemAction in item.Conditions) - { - for (int a=0;a<itemAction.Items.Count;a++) - { - if (itemAction.Items[a].Loader is ExpressionParameter exp) - { - // itemAction.Items.Remove(itemAction.Items[a]); - - } - else if (itemAction.Items[a].Loader is Sample) - { - itemAction.Items.Remove(itemAction.Items[a]); - } - } - }*/ - newFrame.Events.Items.Add(item); - - } - + newFrame.Events.Items = frame.Events.Items; } } mfa.Frames.Add(newFrame); @@ -586,6 +549,17 @@ namespace CTFAK.MMFParser.Translation newCount.Maximum = itemLoader.Counter.Maximum; newCount.Minimum = itemLoader.Counter.Minimum; newCount.Images = new List<int>() {0}; + var shape = counter?.Shape; + + + if (counter != null) + { + if(counter.DisplayType==2||counter.DisplayType==3) + { + counter = null; + shape = null; + } + } if (counter == null) { newCount.DisplayType = 0; @@ -596,6 +570,7 @@ namespace CTFAK.MMFParser.Translation } else { + newCount.DisplayType = counter.DisplayType; newCount.CountType = counter.Inverse ? 1 : 0; newCount.Width = (int) counter.Width; @@ -603,11 +578,22 @@ namespace CTFAK.MMFParser.Translation newCount.Images = counter.Frames; newCount.Font = counter.Font; } - - newCount.Color1 = Color.White; - newCount.Color2 = Color.White; - newCount.Flags = 0; - newCount.VerticalGradient = 0; + + if (shape == null) + { + newCount.Color1=Color.Black; + newCount.Color2=Color.Black; + newCount.VerticalGradient = 0; + newCount.Flags = 0; + } + else + { + newCount.Color1 = Color.Green; + newCount.Color2 = Color.Red; + newCount.VerticalGradient = (uint) shape.GradFlags; + newCount.Flags = (uint) shape.FillType; + + } newItem.Loader = newCount; } diff --git a/CTFAK/Settings.cs b/CTFAK/Settings.cs index fc07472..7490bb7 100644 --- a/CTFAK/Settings.cs +++ b/CTFAK/Settings.cs @@ -38,7 +38,7 @@ namespace CTFAK - public static string DumperVersion = true ? "CTFAK 0.3.5 Alpha" : "CTFAK 0.2.1-a Debug"; + public static string DumperVersion = true ? "CTFAK 0.5 BETA" : "CTFAK 0.2.1-a Debug"; } public class LoadableSettings diff --git a/CTFAK/Utils/Checksum.cs b/CTFAK/Utils/Checksum.cs index 44c7883..fcb20a1 100644 --- a/CTFAK/Utils/Checksum.cs +++ b/CTFAK/Utils/Checksum.cs @@ -24,7 +24,7 @@ namespace CTFAK.Utils } var v5 = 0; - foreach (char c in groupWords) + foreach (char c in pass) { v4 += WrapSingleChar(groupWords[v5] + (c & 0xC3)) ^ 0xF3; v5++;