예제 #1
0
 SimisFile(string fileName, bool streamIsBinary, bool streamIsCompressed, bool jinxStreamIsBinary, SimisJinxFormat jinxStreamFormat, SimisTreeNode tree, SimisAce ace, SimisProvider simisProvider)
 {
     FileName           = fileName;
     StreamIsBinary     = streamIsBinary;
     StreamIsCompressed = streamIsCompressed;
     JinxStreamIsBinary = jinxStreamIsBinary;
     JinxStreamFormat   = jinxStreamFormat;
     Tree          = tree;
     Ace           = ace;
     SimisProvider = simisProvider;
 }
예제 #2
0
        public virtual void Read(Stream stream)
        {
            var simisFile = new SimisFile(stream, SimisProvider);

            StreamIsBinary     = simisFile.StreamIsBinary;
            StreamIsCompressed = simisFile.StreamIsCompressed;
            JinxStreamIsBinary = simisFile.JinxStreamIsBinary;
            JinxStreamFormat   = simisFile.JinxStreamFormat;
            Tree = simisFile.Tree;
            Ace  = simisFile.Ace;
        }
예제 #3
0
 void ResetUndo(SimisTreeNode newTree, SimisAce newAce)
 {
     ResetUndo();
     base.Tree = newTree;
     base.Ace  = newAce;
 }
예제 #4
0
 public SimisFileState(SimisTreeNode tree, SimisAce ace)
 {
     Tree = tree;
     Ace  = ace;
 }
예제 #5
0
        void ReadStream(Stream stream, out bool streamIsBinary, out bool streamIsCompressed, out bool jinxStreamIsBinary, out SimisJinxFormat jinxStreamFormat, out SimisTreeNode tree, out SimisAce ace)
        {
            using (var reader = SimisReader.FromStream(stream, SimisProvider, JinxStreamFormat)) {
                streamIsBinary     = reader.StreamIsBinary;
                streamIsCompressed = reader.StreamIsCompressed;
                switch (reader.GetType().Name)
                {
                case "SimisJinxReader":
                    var readerJinx = (SimisJinxReader)reader;
                    var blockStack = new Stack <KeyValuePair <SimisToken, List <SimisTreeNode> > >();
                    blockStack.Push(new KeyValuePair <SimisToken, List <SimisTreeNode> >(null, new List <SimisTreeNode>()));
                    while (!readerJinx.EndOfStream)
                    {
                        var token = readerJinx.ReadToken();

                        switch (token.Kind)
                        {
                        case SimisTokenKind.Block:
                            blockStack.Push(new KeyValuePair <SimisToken, List <SimisTreeNode> >(token, new List <SimisTreeNode>()));
                            break;

                        case SimisTokenKind.BlockBegin:
                            break;

                        case SimisTokenKind.BlockEnd:
                            if (blockStack.Peek().Key != null)
                            {
                                var block = blockStack.Pop();
                                var node  = new SimisTreeNode(block.Key.Type, block.Key.Name, block.Value);
                                blockStack.Peek().Value.Add(node);
                            }
                            break;

                        case SimisTokenKind.IntegerUnsigned:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerUnsigned(token.Type, token.Name, token.IntegerUnsigned));
                            break;

                        case SimisTokenKind.IntegerSigned:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerSigned(token.Type, token.Name, token.IntegerSigned));
                            break;

                        case SimisTokenKind.IntegerDWord:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerDWord(token.Type, token.Name, token.IntegerDWord));
                            break;

                        case SimisTokenKind.IntegerWord:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerWord(token.Type, token.Name, (ushort)token.IntegerDWord));
                            break;

                        case SimisTokenKind.IntegerByte:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerByte(token.Type, token.Name, (byte)token.IntegerDWord));
                            break;

                        case SimisTokenKind.Float:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueFloat(token.Type, token.Name, token.Float));
                            break;

                        case SimisTokenKind.String:
                            blockStack.Peek().Value.Add(new SimisTreeNodeValueString(token.Type, token.Name, token.String));
                            break;
                        }
                    }

                    var rootBlock = blockStack.Pop();
                    jinxStreamIsBinary = readerJinx.JinxStreamIsBinary;
                    jinxStreamFormat   = readerJinx.JinxStreamFormat;
                    tree = new SimisTreeNode("<root>", "", rootBlock.Value);
                    ace  = null;
                    break;

                case "SimisAceReader":
                    var readerAce = (SimisAceReader)reader;
                    jinxStreamIsBinary = false;
                    jinxStreamFormat   = null;
                    tree = null;
                    ace  = readerAce.Read();
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
예제 #6
0
 /// <summary>
 /// Creates a <see cref="SimisFile"/> from the component parts (ACE type).
 /// </summary>
 /// <param name="fileName">The file to write to.</param>
 /// <param name="streamIsBinary">The <see cref="bool"/> indicating whether the stream should use binary/ASCII or Unicode text (UTF-16) when written from this <see cref="SimisFile"/>.</param>
 /// <param name="streamIsCompressed">The <see cref="bool"/> indicating whether the stream should be compressed when written from this <see cref="SimisFile"/>.</param>
 /// <param name="ace">The <see cref="SimisAce"/> image for this <see cref="SimisFile"/>.</param>
 public SimisFile(string fileName, bool streamIsBinary, bool streamIsCompressed, SimisAce ace)
     : this(fileName, streamIsBinary, streamIsCompressed, false, null, null, ace, null)
 {
 }
예제 #7
0
        public void Write(SimisAce ace)
        {
            Writer.Write((int)1);
            Writer.Write(ace.Format);
            Writer.Write(ace.Width);
            Writer.Write(ace.Height);
            Writer.Write(ace.Unknown4);
            Writer.Write(ace.Channel.Count);
            Writer.Write(ace.Unknown6);
            Writer.Write(ace.Unknown7.PadRight(16, '\0').Substring(0, 16).ToCharArray());
            Writer.Write(ace.Creator.PadRight(64, '\0').Substring(0, 64).ToCharArray());
            Writer.Write(ace.Unknown9);

            foreach (var channel in ace.Channel)
            {
                Writer.Write((long)channel.Size);
                Writer.Write((long)channel.Type);
            }

            if ((ace.Format & 0x10) == 0x10)
            {
                // DXT format.
                // TODO: Check width/height are a power-of-2 dimension.
                switch (ace.Unknown4)
                {
                case 0x12:
                    // DXT1
                    if (ace.HasAlpha)
                    {
                        throw new InvalidDataException("Alpha channel not supported with DXT1 ACE files (use a mask instead).");
                    }

                    // Jump table: offsets to start of each image.
                    var dataSize = 152 + 16 * ace.Channel.Count + 4 * ace.Image.Count;
                    foreach (var image in ace.Image)
                    {
                        Writer.Write(dataSize);
                        dataSize += GetImageDataBlockSize(ace.Channel, true, image);
                    }

                    foreach (var image in ace.Image)
                    {
                        var colorData = CreateDataFromBitmap(image.Width, image.Height, image.ImageColor);
                        var maskData  = CreateDataFromBitmap(image.Width, image.Height, image.ImageMask);
                        if ((image.Width >= 4) && (image.Height >= 4))
                        {
                            Writer.Write(GetImageDataBlockSize(ace.Channel, true, image));
                            WriteDXT1ImageData(image.Width, image.Height, ace.Channel, colorData, maskData);
                        }
                        else
                        {
                            WriteARGBImageData(image.Width, image.Height, ace.Channel, colorData, maskData);
                        }
                    }
                    break;

                default:
                    throw new NotSupportedException("ACE DXT format unknown4=" + ace.Unknown4 + " is not supported.");
                }
            }
            else
            {
                // RGB format.

                // Jump table: offsets to start of each scanline of each image.
                var dataSize = 152 + 16 * ace.Channel.Count + 4 * ace.Image.Sum(i => i.Height);
                foreach (var image in ace.Image)
                {
                    for (var y = 0; y < image.Height; y++)
                    {
                        Writer.Write(dataSize);
                        dataSize += GetImageDataBlockSize(ace.Channel, false, image);
                    }
                }

                foreach (var image in ace.Image)
                {
                    var colorData = CreateDataFromBitmap(image.Width, image.Height, image.ImageColor);
                    var maskData  = CreateDataFromBitmap(image.Width, image.Height, image.ImageMask);
                    WriteARGBImageData(image.Width, image.Height, ace.Channel, colorData, maskData);
                }
            }
            Writer.Write(ace.UnknownTrail1);
            Writer.Write(ace.UnknownTrail2);
        }