예제 #1
0
 public static DTBFile FromFile(string path, DTBEncoding encoding)
 {
     using (FileStream fs = File.OpenRead(path))
     {
         using (AwesomeReader ar = new AwesomeReader(fs))
         {
             return(FromStream(ar, encoding));
         }
     }
 }
예제 #2
0
        public static DTBFile FromStream(AwesomeReader ar, DTBEncoding encoding)
        {
            byte firstByte = ar.ReadByte();

            if (firstByte != 1)
            {
                throw new Exception("Invalid first DTB byte. Expected 1.");
            }

            short itemCount;
            int   version;

            DTBFile dtb = new DTBFile();

            dtb.Encoding = encoding;

            if (encoding == DTBEncoding.FME)
            {
                ar.ReadInt32(); // Always 0
            }
            if (encoding != DTBEncoding.RBVR)
            {
                itemCount = ar.ReadInt16();
                version   = ar.ReadInt32(); // Reads version. Should be either 0 or 1
            }
            else
            {
                version   = ar.ReadInt32(); // Reads version. Should be either 0 or 1
                itemCount = ar.ReadInt16();
                ar.ReadInt16();             // Unknown, always 1?
            }

            if (version == 0)
            {
                dtb.Embedded = true;
            }
            else if (version == 1)
            {
                dtb.Embedded = false;                    // Much more common
            }
            //else throw new Exception("Invalid DTB version. Expected 0 or 1.");

            for (int i = 0; i < itemCount; i++)
            {
                ParseItem(ar, dtb.Items, encoding);
            }

            return(dtb);
        }
예제 #3
0
        private static void ParseItem(AwesomeReader ar, ParentItem parent, DTBEncoding encoding)
        {
            int itemID = ar.ReadInt32();

            DTBItem item;

            switch (itemID)
            {
            // Integer
            case 0x00:
                item = new IntegerItem(ar.ReadInt32());
                break;

            // Float
            case 0x01:
                item = new FloatItem(ar.ReadSingle());
                break;

            // String
            case 0x02:     // Variable
            case 0x04:     // MiloEmbedded
            case 0x05:     // Keyword
            case 0x06:     // KDataUnhandled
            case 0x07:     // IfNDef
            case 0x08:     // Else
            case 0x09:     // EndIf
            case 0x12:     // Default
            case 0x20:     // Define
            case 0x21:     // Include
            case 0x22:     // Merge
            case 0x23:     // IfNDef
            case 0x24:     // Mysterious24
                item = new StringItem((StringType)itemID, ar.ReadString());
                break;

            case 0x10:     // Default
            case 0x11:     // Script
            case 0x13:     // Property
                item = new ParentItem((ParentType)itemID);

                short itemCount;

                if (encoding == DTBEncoding.Classic)
                {
                    itemCount = ar.ReadInt16();
                    ar.ReadInt32(); // Reads line number
                }
                else                // Fantasia / RBVR
                {
                    ar.ReadInt32(); // Unknown (RBVR - Always 1)
                    itemCount = (encoding == DTBEncoding.RBVR) ? ar.ReadInt16() : (short)ar.ReadInt32();
                    ar.ReadInt16();
                }

                for (int i = 0; i < itemCount; i++)
                {
                    // Recursion: Like a boss
                    ParseItem(ar, item as ParentItem, encoding);
                }

                break;

            default:
                throw new Exception(string.Format("Unknown chunk: {0} at {1}", itemID, ar.BaseStream.Position));
            }

            parent.Add(item);
        }