You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
13 KiB
C#
382 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Numerics;
|
|
using DotNetCTFDumper.MMFParser.ChunkLoaders;
|
|
using DotNetCTFDumper.MMFParser.ChunkLoaders.Banks;
|
|
using DotNetCTFDumper.MMFParser.MFALoaders;
|
|
using DotNetCTFDumper.Utils;
|
|
using Controls = DotNetCTFDumper.MMFParser.MFALoaders.Controls;
|
|
using Frame = DotNetCTFDumper.MMFParser.MFALoaders.Frame;
|
|
|
|
namespace DotNetCTFDumper.MMFParser.Data
|
|
{
|
|
public class MFA : DataLoader
|
|
{
|
|
public static readonly string FontBankId = "ATNF";
|
|
public static readonly string ImageBankId = "AGMI";
|
|
public static readonly string MusicBankId = "ASUM";
|
|
public static readonly string SoundBankId = "APMS";
|
|
|
|
public int MfaBuild;
|
|
public int Product;
|
|
public int BuildVersion;
|
|
public int LangId;
|
|
|
|
public string Name;
|
|
public string Description;
|
|
public string Path;
|
|
|
|
public List<byte[]> BinaryFiles = new List<byte[]>();
|
|
|
|
public FontBank Fonts;
|
|
public SoundBank Sounds;
|
|
public MusicBank Music;
|
|
public AgmiBank Icons;
|
|
public AgmiBank Images;
|
|
|
|
|
|
public string Author;
|
|
public string Copyright;
|
|
public string Company;
|
|
public string Version;
|
|
|
|
public byte[] Stamp;
|
|
|
|
public int WindowX;
|
|
public int WindowY;
|
|
|
|
public ValueList GlobalValues;
|
|
public ValueList GlobalStrings;
|
|
public Color BorderColor;
|
|
|
|
public BitDict DisplayFlags = new BitDict(new string[]
|
|
{
|
|
"MaximizedOnBoot",
|
|
"ResizeDisplay",
|
|
"FullscreenAtStart",
|
|
"AllowFullscreen",
|
|
"Heading",
|
|
"HeadingWhenMaximized",
|
|
"MenuBar",
|
|
"MenuOnBoot",
|
|
"NoMinimize",
|
|
"NoMaximize",
|
|
"NoThickFrame",
|
|
"NoCenter",
|
|
"DisableClose",
|
|
"HiddenAtStart",
|
|
"MDI"
|
|
});
|
|
|
|
public BitDict GraphicFlags = new BitDict(new string[]
|
|
{
|
|
"MultiSamples",
|
|
"SpeedIndependent",
|
|
"SoundsOverFrames",
|
|
"PlaySamplesWhenUnfocused",
|
|
"IgnoreInputOnScreensaver",
|
|
"DirectX",
|
|
"VRAM",
|
|
"EnableVisualThemes",
|
|
"VSync",
|
|
"RunWhenMinimized",
|
|
"RunWhenResizing",
|
|
"EnableDebuggerShortcuts",
|
|
"NoDebugger",
|
|
"NoSubappSharing"
|
|
});
|
|
|
|
public string HelpFile;
|
|
public string unknown_string; //Found in original mfa build 283 after help file
|
|
public string unknown_string_2; //Found in original mfa build 283 after build path
|
|
public byte[] VitalizePreview;
|
|
public int InitialScore;
|
|
public int InitialLifes;
|
|
public int FrameRate;
|
|
public int BuildType;
|
|
public string BuildPath;
|
|
public string CommandLine;
|
|
public string Aboutbox;
|
|
public uint MenuSize;
|
|
public AppMenu Menu;
|
|
private int windowMenuIndex;
|
|
private Dictionary<Int32, Int32> menuImages;
|
|
private byte[] GlobalEvents;
|
|
private int GraphicMode;
|
|
private int IcoCount;
|
|
private int QualCount;
|
|
public Controls Controls;
|
|
public List<int> IconImages;
|
|
public List<Tuple<int, string, string, int, byte[]>> Extensions;
|
|
public List<Tuple<string, int>> CustomQuals;
|
|
public List<Frame> Frames;
|
|
|
|
|
|
public override void Print()
|
|
{
|
|
//Logger.Log($"MFA Product:{product}");
|
|
//Logger.Log($"MFA Build:{mfaBuild}");
|
|
//Logger.Log($"MFA Product:{buildVersion}");
|
|
}
|
|
|
|
public override void Write(ByteWriter Writer)
|
|
{
|
|
Writer.WriteAscii("MFU2");
|
|
Writer.WriteInt32(MfaBuild);
|
|
Writer.WriteInt32(Product);
|
|
Writer.WriteInt32(BuildVersion);
|
|
Writer.WriteInt32(LangId);
|
|
Writer.AutoWriteUnicode(Name);
|
|
Writer.AutoWriteUnicode(Description);
|
|
Writer.AutoWriteUnicode(Path);
|
|
|
|
Writer.WriteUInt32((uint) Stamp.Length);
|
|
Writer.WriteBytes(Stamp);
|
|
Writer.WriteAscii(FontBankId);
|
|
Fonts.Write(Writer);
|
|
Writer.WriteAscii(SoundBankId);
|
|
Sounds.Write(Writer);
|
|
|
|
Writer.WriteAscii(MusicBankId);
|
|
// music.Write();
|
|
Writer.WriteInt32(0); //someone is using musics lol?
|
|
//TODO: Do music
|
|
|
|
Writer.WriteAscii(ImageBankId);
|
|
Icons.Write(Writer);
|
|
|
|
Writer.WriteAscii(ImageBankId);
|
|
Images.Write(Writer);
|
|
|
|
|
|
Writer.AutoWriteUnicode(Name);
|
|
Writer.AutoWriteUnicode(Author);
|
|
Writer.AutoWriteUnicode(Description);
|
|
Writer.AutoWriteUnicode(Copyright);
|
|
Writer.AutoWriteUnicode(Company);
|
|
Writer.AutoWriteUnicode(Version);
|
|
Writer.WriteInt32(WindowX);
|
|
Writer.WriteInt32(WindowY);
|
|
Writer.WriteColor(Color.White);
|
|
Writer.WriteInt32((int) DisplayFlags.flag);
|
|
Writer.WriteInt32((int) GraphicFlags.flag);
|
|
Writer.AutoWriteUnicode(HelpFile);
|
|
Writer.AutoWriteUnicode(unknown_string);
|
|
Writer.WriteUInt32((uint) InitialScore);
|
|
Writer.WriteUInt32((uint) InitialLifes);
|
|
Writer.WriteInt32(FrameRate);
|
|
Writer.WriteInt32(BuildType);
|
|
Writer.AutoWriteUnicode(BuildPath);
|
|
Writer.AutoWriteUnicode(unknown_string_2);
|
|
Writer.AutoWriteUnicode(CommandLine);
|
|
Writer.AutoWriteUnicode(Aboutbox);
|
|
Writer.WriteInt32(0);
|
|
|
|
Writer.WriteInt32(BinaryFiles.Count);
|
|
foreach (byte[] binaryFile in BinaryFiles)
|
|
{
|
|
Writer.WriteInt32(binaryFile.Length);
|
|
Writer.WriteBytes(binaryFile);
|
|
}
|
|
|
|
Controls.Write(Writer);
|
|
|
|
|
|
if (Menu != null)
|
|
{
|
|
using (ByteWriter menuWriter = new ByteWriter(new MemoryStream()))
|
|
{
|
|
Menu.Write(menuWriter);
|
|
|
|
Writer.WriteUInt32((uint) menuWriter.BaseStream.Position);
|
|
Writer.WriteWriter(menuWriter);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Writer.WriteInt32(0);
|
|
}
|
|
|
|
Writer.WriteInt32(windowMenuIndex);
|
|
Writer.WriteInt32(menuImages.Count);
|
|
foreach (KeyValuePair<int, int> valuePair in menuImages)
|
|
{
|
|
Writer.WriteInt32(valuePair.Key);
|
|
Writer.WriteInt32(valuePair.Value);
|
|
}
|
|
GlobalValues.Write(Writer);
|
|
GlobalStrings.Write(Writer);
|
|
Writer.WriteInt32(GlobalEvents.Length);
|
|
Writer.WriteBytes(GlobalEvents);
|
|
Writer.WriteInt32(GraphicMode);
|
|
Writer.WriteUInt32((uint) IconImages.Count);
|
|
foreach (int iconImage in IconImages)
|
|
{
|
|
Writer.WriteInt32(iconImage);
|
|
}
|
|
Writer.WriteInt32(0);//custom qualifiers
|
|
Writer.WriteInt32(0); //extensions
|
|
Writer.WriteInt32(0); //frame
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
public override void Read()
|
|
{
|
|
Logger.Log($"MFA HEADER:{Reader.ReadAscii(4)}\n");
|
|
MfaBuild = Reader.ReadInt32();
|
|
Product = Reader.ReadInt32();
|
|
BuildVersion = Reader.ReadInt32();
|
|
LangId = Reader.ReadInt32();
|
|
Name = Helper.AutoReadUnicode(Reader);
|
|
Description = Helper.AutoReadUnicode(Reader);
|
|
Path = Helper.AutoReadUnicode(Reader);
|
|
Stamp = Reader.ReadBytes(Reader.ReadInt32());
|
|
|
|
if (Reader.ReadAscii(4) != FontBankId) throw new Exception("Invalid Font Bank");
|
|
Fonts = new FontBank(Reader);
|
|
Fonts.Read();
|
|
|
|
if (Reader.ReadAscii(4) != SoundBankId) throw new Exception("Invalid Sound Bank");
|
|
Sounds = new SoundBank(Reader);
|
|
Sounds.IsCompressed = false;
|
|
Sounds.Read();
|
|
|
|
if (Reader.ReadAscii(4) != MusicBankId) throw new Exception("Invalid Music Bank");
|
|
Music = new MusicBank(Reader);
|
|
Music.Read();
|
|
|
|
if (Reader.ReadAscii(4) != "AGMI") throw new Exception("Invalid Icon Bank");
|
|
Icons = new AgmiBank(Reader);
|
|
Icons.Read();
|
|
|
|
if (Reader.ReadAscii(4) != "AGMI") throw new Exception("Invalid Image Bank");
|
|
Images = new AgmiBank(Reader);
|
|
Images.Read();
|
|
|
|
Helper.CheckPattern(Helper.AutoReadUnicode(Reader), Name);
|
|
Author = Helper.AutoReadUnicode(Reader);
|
|
Helper.CheckPattern(Helper.AutoReadUnicode(Reader), Description);
|
|
Copyright = Helper.AutoReadUnicode(Reader);
|
|
Company = Helper.AutoReadUnicode(Reader);
|
|
Version = Helper.AutoReadUnicode(Reader);
|
|
WindowX = Reader.ReadInt32();
|
|
WindowY = Reader.ReadInt32();
|
|
BorderColor = Reader.ReadColor();
|
|
DisplayFlags.flag = Reader.ReadUInt32();
|
|
GraphicFlags.flag = Reader.ReadUInt32();
|
|
HelpFile = Helper.AutoReadUnicode(Reader);
|
|
unknown_string = Helper.AutoReadUnicode(Reader);
|
|
//Int32 vit_size = Reader.ReadInt32();
|
|
//VitalizePreview = Reader.ReadBytes(vit_size);
|
|
|
|
InitialScore = Reader.ReadInt32();
|
|
InitialLifes = Reader.ReadInt32();
|
|
FrameRate = Reader.ReadInt32();
|
|
BuildType = Reader.ReadInt32();
|
|
BuildPath = Helper.AutoReadUnicode(Reader);
|
|
unknown_string_2 = Helper.AutoReadUnicode(Reader);
|
|
CommandLine = Helper.AutoReadUnicode(Reader);
|
|
Aboutbox = Helper.AutoReadUnicode(Reader);
|
|
|
|
|
|
var binCount = Reader.ReadInt32(); //wtf i cant put it in loop fuck shit
|
|
|
|
for (int i = 0; i < binCount; i++)
|
|
{
|
|
BinaryFiles.Add(Reader.ReadBytes(Reader.ReadInt32()));
|
|
}
|
|
|
|
Controls = new Controls(Reader);
|
|
Controls.Read();
|
|
|
|
MenuSize = Reader.ReadUInt32();
|
|
var currentPosition = Reader.Tell();
|
|
Menu = new AppMenu(Reader);
|
|
Menu.Read();
|
|
Reader.Seek(MenuSize + currentPosition);
|
|
|
|
windowMenuIndex = Reader.ReadInt32();
|
|
menuImages = new Dictionary<Int32, Int32>();
|
|
int miCount = Reader.ReadInt32();
|
|
for (int i = 0; i < miCount; i++)
|
|
{
|
|
int id = Reader.ReadInt32();
|
|
menuImages[id] = Reader.ReadInt32();
|
|
}
|
|
|
|
|
|
GlobalValues = new ValueList(Reader);
|
|
GlobalValues.Read();
|
|
GlobalStrings = new ValueList(Reader);
|
|
GlobalStrings.Read();
|
|
GlobalEvents = Reader.ReadBytes(Reader.ReadInt32());
|
|
GraphicMode = Reader.ReadInt32();
|
|
|
|
|
|
|
|
IcoCount = Reader.ReadInt32();
|
|
IconImages = new List<int>();
|
|
for (int i = 0; i < IcoCount; i++)
|
|
{
|
|
IconImages.Add(Reader.ReadInt32());
|
|
}
|
|
|
|
//I STUCK HERE
|
|
QualCount = Reader.ReadInt32();
|
|
CustomQuals = new List<Tuple<string, int>>();
|
|
for (int i = 0; i < QualCount; i++) //qualifiers
|
|
{
|
|
var name = Reader.ReadAscii(Reader.ReadInt32());
|
|
var handle = Reader.ReadInt32();
|
|
CustomQuals.Add(new Tuple<string, int>(name, handle));
|
|
}
|
|
|
|
var extCount = Reader.ReadInt32();
|
|
Extensions = new List<Tuple<int, string, string, int, byte[]>>();
|
|
for (int i = 0; i < extCount; i++) //extensions
|
|
{
|
|
var handle = Reader.ReadInt32();
|
|
var filename = Helper.AutoReadUnicode(Reader);
|
|
var name = Helper.AutoReadUnicode(Reader);
|
|
var magic = Reader.ReadInt32();
|
|
var data = Reader.ReadBytes(Reader.ReadInt32());
|
|
var tuple = new Tuple<int, string, string, int, byte[]>(handle, filename, name, magic, data);
|
|
Extensions.Add(tuple);
|
|
}
|
|
|
|
List<int> frameOffsets = new List<int>();
|
|
var offCount = Reader.ReadInt32();
|
|
for (int i = 0; i < offCount; i++)
|
|
{
|
|
frameOffsets.Add(Reader.ReadInt32());
|
|
}
|
|
|
|
|
|
var nextOffset = Reader.ReadInt32();
|
|
Frames = new List<Frame>();
|
|
foreach (var item in frameOffsets)
|
|
{
|
|
Reader.Seek(item);
|
|
var testframe = new Frame(Reader);
|
|
testframe.Read();
|
|
Frames.Add(testframe);
|
|
}
|
|
|
|
Reader.Seek(nextOffset);
|
|
var chunks = new MFALoaders.ChunkList(Reader);
|
|
chunks.Read();
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
public MFA(ByteReader reader) : base(reader)
|
|
{
|
|
}
|
|
}
|
|
} |