void InitializeBspTags(IO.EndianReader s, Blam.CacheFile cache)
        {
            // Seek to the scenario's scenario_structure_bsps_block tag_block field
            s.Seek(items[0].Offset + 1444, System.IO.SeekOrigin.Begin);
            bspTags = new Item[s.ReadInt32()];
            uint sbsp_offset = s.ReadPointer();

            // Seek to the scenario_structure_bsps_block definitions
            s.Seek(sbsp_offset, System.IO.SeekOrigin.Begin);
            DatumIndex    di   = new DatumIndex();
            CacheItemBase item = null;

            // Process each definition's runtime data
            for (int x = 0; x < bspTags.Length; x++)
            {
                s.Seek(28, System.IO.SeekOrigin.Current);
                di.Read(s);
                item       = items[di.Index];
                bspTags[x] = item as CacheItemBase;
                // Seek back to the beginning of the definition so the following stream code works
                s.Seek(-Halo1.Tags.scenario_structure_bsps_block.kSizeOf, System.IO.SeekOrigin.Current);

                // We're actually selectively reading scenario_structure_bsps_block fields here

                // The offset actually points to the bsp header, and the bsp comes after that header
                item.Offset = s.ReadInt32() + Halo1.Tags.scenario_structure_bsps_header.kSizeOf;
                item.Size   = s.ReadInt32();
                cache.BspAddressMasks.Add(s.ReadUInt32() - (uint)item.Offset);                 // won't count the header
                item.BspIndex = bspCount++;
                // Seek to the end of this definition, and thus, the start of the next definition
                s.Seek(20, System.IO.SeekOrigin.Current);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Stream the field from a buffer
        /// </summary>
        /// <param name="input"></param>
        public override void Read(IO.EndianReader input)
        {
#if false//DEBUG
            if (Value < 5)
            {
                input.Seek(Value, System.IO.SeekOrigin.Current);
            }
            else
            {
                byte[] data = input.ReadBytes(Value);
                for (int x = 0, y = 0, z = 0; x < data.Length; x++)
                {
                    if (data[x] != 0)
                    {
                        if (y == 0 || x == 0)
                        {
                            y = x;
                        }
                        z++;
                    }
                    else if (x != 0 && data[x - 1] != 0)
                    {
                        trace.WriteLine("Found data at offset 0x{0:X} covering 0x{1:X} bytes, in a pad field with a count of {1}", y, z, Value);
                    }
                }
                data = null;
            }
#else
            input.Seek(Value, System.IO.SeekOrigin.Current);
#endif
        }
Exemplo n.º 3
0
        /// <summary>
        /// Takes the input stream and does any version specific
        /// data operations to get the tag manager ready for reading
        /// </summary>
        void CalculateVersion()
        {
            InputStream.Seek(60);
            InputStream.State = BlamLib.IO.EndianState.Little;
            uint      group_tag = InputStream.ReadTagUInt();
            BlamBuild bb        = FromSignature(group_tag);

            #region Endian handling
            if (bb == BlamBuild.Halo1)
            {
                endianState = BlamLib.IO.EndianState.Big;
            }
            else
            {
                endianState = BlamLib.IO.EndianState.Little;
            }

            if (InputStream != null)
            {
                InputStream.State = endianState;
            }
            if (OutputStream != null)
            {
                OutputStream.State = endianState;
            }
            #endregion

            if (engine == BlamVersion.Unknown)
            {
                engine = bb.ToVersion();

                ManageSetupTagGroup();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Validates the cache's header for proper signatures
        /// </summary>
        /// <param name="s">cache stream</param>
        /// <param name="header_sizes">size of a single header</param>
        /// <remarks>Assumes the header is at the start of the stream</remarks>
        /// <returns>The header size entry that matches this cache or -1 if no matches</returns>
        internal static int ValidateHeader(IO.EndianReader s, params int[] header_sizes)
        {
            bool invalid = true;
            int  result  = -1;

            foreach (int header_size in header_sizes)
            {
                s.Seek(0);
                if (s.ReadTagUInt() == MiscGroups.head.ID && s.Length >= header_size)                 // it HAS to be more than the size of a header...
                {
                    s.Seek(header_size - sizeof(uint));
                    if (s.ReadTagUInt() == MiscGroups.foot.ID)
                    {
                        invalid = false;
                        result  = header_size;
                    }
                }

                if (!invalid)
                {
                    break;
                }
            }

            if (invalid)
            {
                throw new InvalidCacheFileException(s.FileName);
            }

            return(result);
        }
Exemplo n.º 5
0
 public void Read(IO.EndianReader s)
 {
     mWidthType = (StringStorageWidthType)s.ReadByte();
     mType      = (StringStorageType)s.ReadByte();
     mByteOrder = (Shell.EndianFormat)s.ReadByte();
     s.Seek(sizeof(byte));
     mFixedLength = s.ReadInt16();
     s.Seek(sizeof(ushort));
 }
Exemplo n.º 6
0
        static void Read(IO.EndianReader s, bool decrypt, IO.IEndianStreamable obj,
                         long size = 0, ulong userKey = 0, Action <IO.EndianReader> readLeftovers = null)
        {
            if (!decrypt)
            {
                obj.Read(s);
            }
            else
            {
                using (var ms = new System.IO.MemoryStream())
                    using (var sout = new IO.EndianWriter(ms, Shell.EndianFormat.Big))
                        using (var decrypted = new IO.EndianReader(ms, Shell.EndianFormat.Big))
                        {
                            long position = s.BaseStream.Position;

                            var tea = new Security.Cryptography.PhxTEA(s, sout);
                            tea.InitializeKey(Security.Cryptography.PhxTEA.kKeyGameFile, userKey);
                            tea.Decrypt(size);

                            decrypted.Seek(0);
                            obj.Read(decrypted);

                            if (readLeftovers != null)
                            {
                                readLeftovers(decrypted);
                            }
                        }
            }
        }
Exemplo n.º 7
0
        static void Write(IO.EndianWriter s, bool encrypt, IO.IEndianStreamable obj,
                          long size = 0, ulong userKey = 0, Action <IO.EndianWriter> writeLeftovers = null)
        {
            if (!encrypt)
            {
                obj.Write(s);

                if (writeLeftovers != null)
                {
                    writeLeftovers(s);
                }
            }
            else
            {
                using (var ms = new System.IO.MemoryStream())
                    using (var sin = new IO.EndianWriter(ms, Shell.EndianFormat.Big))
                        using (var encrypted = new IO.EndianReader(ms, Shell.EndianFormat.Big))
                        {
                            obj.Write(sin);

                            if (writeLeftovers != null)
                            {
                                writeLeftovers(sin);
                            }

                            encrypted.Seek(0);

                            var tea = new Security.Cryptography.PhxTEA(encrypted, s);
                            tea.InitializeKey(Security.Cryptography.PhxTEA.kKeyGameFile, userKey);
                            tea.Encrypt(size);
                        }
            }
        }
        /// <summary>
        /// Read and preprocess header information
        /// </summary>
        private void ReadPreprocess()
        {
            char[] gtag;
            #region Endian Switch
            ushort us_temp = InputStream.ReadUInt16();
            if (us_temp == HeaderEndian)
            {
                SetEndianState(IO.EndianState.Little);
            }
            else if (us_temp == HeaderEndianSwap)
            {
                SetEndianState(IO.EndianState.Big);
            }
            else
            {
                throw new Debug.ExceptionLog("File: Invalid switch! {0:X4}", us_temp);
            }
            #endregion

            #region Version
            us_temp = InputStream.ReadUInt16();
            Debug.Assert.If(us_temp == HeaderVersion,
                            "File: mismatching file version! [{0}, !{1}",
                            HeaderVersion, us_temp);
            #endregion
            #region Signature
            gtag = InputStream.ReadTag();
            Debug.Assert.If(TagGroup.Test(gtag, (char[])IO.TagGroups.BlamLib),
                            "File: invalid signature! [{0} !{1}]",
                            IO.TagGroups.BlamLib.TagToString(), new string(gtag));
            #endregion
            flags.Reset((uint)(InputStream.ReadUInt16() << 16) | flags);

            #region Data Version
            us_temp = InputStream.ReadUInt16();
            Debug.Assert.If(us_temp == data.Attribute.Version,
                            "File: mismatching data version! [{0}, !{1}",
                            data.Attribute.Version, us_temp);
            #endregion
            #region Data Signature
            gtag = InputStream.ReadTag();
            Debug.Assert.If(TagGroup.Test(gtag, (char[])data.GroupTag),
                            "File: invalid data signature! [{0} !{1}]",
                            data.GroupTag.TagToString(), new string(gtag));
            #endregion

            #region Data Directories
            InputStream.ReadInt32();
            InputStream.ReadInt32();
            #endregion
            #region Data
            InputStream.ReadInt32();
            int data_offset = InputStream.ReadInt32();
            #endregion

            Debug.Assert.If(InputStream.Position == HeaderSize,
                            "File: Update header size! [{0}, !{1}]", HeaderSize, InputStream.Position);

            InputStream.Seek(data_offset);
        }
        /// <summary></summary>
        /// <param name="offsets">Buffer containing the offsets of the string values in <paramref name="buffer"/></param>
        /// <param name="buffer">Buffer containing the string values</param>
        /// <param name="is_packed">If true, reads the strings as null terminated strings, else as 128 character strings</param>
        /// <param name="count">Number of dynamic strings for <paramref name="set_index"/></param>
        /// <remarks>
        /// Doesn't use <paramref name="offsets"/> for reading the strings, assumes the strings are in sequential order in <paramref name="buffer"/>.
        ///
        /// Ignores <see cref="IsReadOnly"/>; will always add new IDs.
        /// </remarks>
        public void FromDebugStream(IO.EndianReader offsets, IO.EndianReader buffer,
                                    bool is_packed, int count)
        {
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException("count", count, "Must be greater than zero");
            }

            // Assume the strings are in sequential order in [buffer]
            offsets.Seek(sizeof(uint) * count, System.IO.SeekOrigin.Current);

            int set_index = InitialId.Set, initial_index = InitialId.Index;

            InitializeSet(count);
            for (int x = 0; x < count; x++)
            {
                var str = is_packed ? buffer.ReadCString() : buffer.ReadAsciiString(128);
                var sid = mOwner.Definition.Description.Generate(initial_index + x, str.Length, set_index);

                m_set.Set.Add(sid, str);

                int      hc = str.GetHashCode();
                StringId first_sid;
                if (m_set.SetLookup.TryGetValue(hc, out first_sid))
                {
                    Debug.Warn.If(false, "Hash collision! '{0}' ({1}) collides with '{2}' ({3})",
                                  m_set.Set[first_sid], first_sid.ToString(),
                                  str, sid.ToString());
                }
                else
                {
                    m_set.SetLookup.Add(str.GetHashCode(), sid);
                }
            }
        }
        /// <summary></summary>
        /// <param name="offsets">Buffer containing the offsets of the string values in <paramref name="buffer"/></param>
        /// <param name="buffer">Buffer containing the string values</param>
        /// <param name="is_packed">If true, reads the strings as null terminated strings, else as 128 character strings</param>
        /// <remarks>
        /// Doesn't actually populate the collection from a debug stream. Instead it seeks the streams to directly after this set's
        /// data, assuming the streams have data which matches this collection. Also assumes the streams aren't filled with just static
        /// strings, but also contain dynamic string data as well (or else the seek operations this performs will exception)
        /// </remarks>
        public void FromDebugStream(IO.EndianReader offsets, IO.EndianReader buffer, bool is_packed)
        {
            int last_offset = sizeof(uint) * Count;

            offsets.Seek(last_offset);
            int last_offset_buffer = offsets.ReadInt32();

            buffer.Seek(last_offset_buffer);
        }
Exemplo n.º 11
0
        public string ReadName(int nameOffset)
        {
            if (NameData == null || nameOffset >= NameData.Length)
            {
                throw new InvalidOperationException(nameOffset.ToString("X8"));
            }

            NameDataReader.Seek(nameOffset);
            return(NameDataReader.ReadString(Memory.Strings.StringStorage.CStringAscii));
        }
Exemplo n.º 12
0
        internal static int ValidateHeaderAdjustEndian(IO.EndianReader s, params int[] header_sizes)
        {
            bool invalid = true;
            int  result  = -1;

            foreach (int header_size in header_sizes)
            {
                if (s.Length < header_size)
                {
                    continue;                                         // it HAS to be more than the size of a header...
                }
                s.Seek(0);
                uint head = s.ReadTagUInt();

                if (head != MiscGroups.head.ID)
                {
                    if (IO.ByteSwap.SwapUDWord(head) == MiscGroups.head.ID)
                    {
                        s.State = s.State.Invert();
                    }
                }

                s.Seek(header_size - sizeof(uint));
                if (s.ReadTagUInt() == MiscGroups.foot.ID)
                {
                    invalid = false;
                    result  = header_size;
                }

                if (!invalid)
                {
                    break;
                }
            }

            if (invalid)
            {
                throw new InvalidCacheFileException(s.FileName);
            }

            return(result);
        }
Exemplo n.º 13
0
            public void ReadChildren(IO.EndianReader s)
            {
                if (mChildrenOffset.IsInvalidHandle)
                {
                    return;
                }

                s.Seek((long)mChildrenOffset);
                for (int x = 0; x < ChildrenIndices.Capacity; x++)
                {
                    ChildrenIndices.Add(s.ReadInt32());
                }
            }
Exemplo n.º 14
0
                public void Build(IO.EndianReader stream, int offset,
                                  int count, int total_size)
                {
                    stream.Seek(offset);
                    int[] indicies = new int[count];
                    for (int x = 0; x < indicies.Length; x++)
                    {
                        indicies[x] = stream.ReadInt32();
                    }

                    ValueLengths = new byte[count];
                    for (int x = count - 1, prev_offset = total_size; x >= 0; x--)
                    {
                        ValueLengths[x] = (byte)((prev_offset - indicies[x]) - 1);
                        prev_offset     = indicies[x];
                    }

                    Count = count;
                }
Exemplo n.º 15
0
Arquivo: test.cs Projeto: mloc/scc
        public override void Read(IO.EndianReader s)
        {
            BlamVersion ver = (BlamVersion)s.ReadUInt16();

            // HACK: this is a hack
            if (ver == BlamVersion.Halo1)
            {
                ver = BlamVersion.Halo1_CE;
            }
            Debug.Assert.If(ver == engine, "Engine version mismatch: expected {0}, but got {1}", engine, ver);
            s.Seek(2, System.IO.SeekOrigin.Current);
            #region FileNames
            int file_count = s.ReadInt32();
            for (int x = 0; x < file_count; x++)
            {
                files.Add(s.ReadCString());
            }
            #endregion
        }
Exemplo n.º 16
0
            public void ReadAttributes(XmbFile xmb, IO.EndianReader s)
            {
                if (mAttributesOffset.IsInvalidHandle)
                {
                    return;
                }

                s.Seek((long)mAttributesOffset);
                for (int x = 0; x < Attributes.Capacity; x++)
                {
                    XmbVariant k; XmbVariantSerialization.Read(s, out k);
                    XmbVariant v; XmbVariantSerialization.Read(s, out v);

                    var kv = new KeyValuePair <XmbVariant, XmbVariant>(k, v);
                    Attributes.Add(kv);

                    if (k.HasUnicodeData || v.HasUnicodeData)
                    {
                        xmb.mHasUnicodeStrings = true;
                    }
                }
            }
Exemplo n.º 17
0
        /// <summary>Read a CString from an endian stream</summary>
        /// <param name="s">Endian stream to read from</param>
        /// <param name="length">Optional length specification</param>
        /// <param name="actualCount">On return, the actual character byte count, or -1 if all bytes are valid</param>
        /// <returns>The character's bytes for the string we're reading</returns>
        byte[] ReadStrCString(IO.EndianReader s, int length, out int actualCount)
        {
            byte[] bytes;

            actualCount = TypeExtensions.kNone;             // complete string case

            // the user was nice and saved us some CPU trying to feel around for the null
            // because we don't have a fixed length to speed things up
            if (!mStorage.IsFixedLength && length > 0)
            {
                bytes = s.ReadBytes(GetMaxCleanByteCount(length));
                s.Seek(mNullCharacterSize, System.IO.SeekOrigin.Current);
            }
            // F**K: figure out the length ourselves. Or maybe we're a fixed length CString...
            // in which case we'll ignore anything the user tried to tell us about the length
            else
            {
                using (var ms = new System.IO.MemoryStream(!mStorage.IsFixedLength ? 512 : mStorage.FixedLength))
                {
                    // The N-byte methods take care of reading past the
                    // null character, no need to do it in this case.
                    if (mNullCharacterSize == 1)
                    {
                        ReadCStringSingleByte(s, ms);
                    }
                    else
                    {
                        ReadCStringMultiByte(s, ms);
                    }

                    // We use ToArray instead of GetArray so all of [ms] can theoretically be disposed of
                    bytes = ms.ToArray();
                }
            }

            return(bytes);
        }
        internal void ReadLanguageStrings(IO.EndianReader buffer, uint langBitmask = uint.MaxValue)
        {
            Contract.Assert(LanguageRegistry.NumberOfLanguages <= Bits.kInt32BitCount,
                            nameof(langBitmask) + " is too small to actually be a language bitvector");
            Contract.Assert(mLanguageOffsets != null);

            for (int x = 0; x < mLanguageOffsets.Length; x++)
            {
                int offset = mLanguageOffsets[x];
                if (offset.IsNone())
                {
                    continue;
                }
                else if (!Bitwise.Flags.Test(langBitmask, 1U << x))
                {
                    continue;
                }

                buffer.Seek(offset);
                mLanguageStrings[x] = buffer.ReadString(Memory.Strings.StringStorage.CStringUtf8);
            }

            LanguageOffsetsDispose();
        }
Exemplo n.º 19
0
            bool CacheRead(BlamLib.Blam.CacheFile c, out byte[] data)
            {
                data = null;

                ResourcePtr offset = GetOffset(0);
                int         size   = GetSize(0);

                var rsrc_cache = Program.Halo2.FromLocation(c as Halo2.CacheFile, offset);

                // the shared cache isn't loaded, break
                if (rsrc_cache == null)
                {
                    return(false);
                }

                // get the input stream we need
                IO.EndianReader er = rsrc_cache.InputStream;

                // read the bitmap
                er.Seek(offset.Offset);
                data = er.ReadBytes(size);

                return(true);
            }
Exemplo n.º 20
0
 /// <summary>Moves the stream ahead by the sizeof a four character code (4 bytes)</summary>
 /// <param name="s"></param>
 /// <remarks>Doesn't actually read any data from the stream, only seeks forward</remarks>
 public override void Read(IO.EndianReader s) => s.Seek(sizeof(TagWord), System.IO.SeekOrigin.Current);
        public override void Read(IO.EndianReader s)
        {
            int k_local_sizeof = Blam.CacheFile.ValidateHeader(s, kSizeOf);

            s.Seek(4);
            version = s.ReadInt32();
            if (version != 11 && version != 12)
            {
                throw new InvalidCacheFileException(s.FileName);
            }
            fileLength = s.ReadInt32();
            s.ReadInt32();
            tagIndexAddress    = s.ReadUInt32();
            memoryBufferOffset = s.ReadInt32();
            memoryBufferSize   = s.ReadInt32();

            sourceFile = s.ReadAsciiString(256);
            build      = s.ReadTagString();
            cacheType  = (Blam.CacheType)s.ReadInt16();
            sharedType = (Cache.SharedType)s.ReadInt16();

            s.ReadBool();
            s.ReadBool();             // false if it belongs to a untracked build
            s.ReadBool();
            // PATCH: this is '3' in main menu patches
            s.ReadByte();             // appears to be an ODST-only field

            s.ReadInt32(); s.ReadInt32();
            s.ReadInt32(); s.ReadInt32(); s.ReadInt32();

            #region string id table
            // 0x158
            stringIdsCount        = s.ReadInt32();
            stringIdsBufferSize   = s.ReadInt32();
            stringIdIndicesOffset = s.ReadInt32();
            stringIdsBufferOffset = s.ReadInt32();
            #endregion

            #region filetimes?
            // pretty sure this is a flags field
            // used to tell which of the following 64bit values
            // are used. Damn sure this are FILETIME structures, but
            // hex workshop doesn't like them so I can't be for sure...
            needsShared             = s.ReadInt32() != 0; // just a little 'hack' if you will. if zero, the map is self reliant, so no worries
            Filetime.dwHighDateTime = s.ReadInt32();
            Filetime.dwLowDateTime  = s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnMainMenu);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnShared);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnCampaign);
            }
            s.ReadInt32();
            #endregion

            name = s.ReadTagString();
            s.ReadInt32();
            scenarioPath = s.ReadAsciiString(256);
            // PATCH: this is -1 in main menu patches
            s.ReadInt32();             // minor version, normally not used

            #region tag paths
            tagNamesCount        = s.ReadInt32();
            tagNamesBufferOffset = s.ReadInt32();           // cstring buffer
            tagNamesBufferSize   = s.ReadInt32();           // cstring buffer total size in bytes
            tagNameIndicesOffset = s.ReadInt32();

            TagsUnknown1Count  = s.ReadInt32();
            TagsUnknown1Offset = s.ReadInt32();
            // PATCH: zero for non-patch data
            TagsUnknown2Count  = s.ReadInt32();
            TagsUnknown2Offset = s.ReadInt32();
            #endregion

            checksum = s.ReadUInt32();                // 0x2D4
            s.Seek(32, System.IO.SeekOrigin.Current); // these bytes are always the same. first 8 changed in Halo4

            baseAddress = s.ReadUInt32();             // expected base address
            xdkVersion  = s.ReadInt32();              // xdk version

            #region memory partitions
            // 0x300

            // memory partitions
            memoryPartitions = new Partition[6];
            memoryPartitions[0].BaseAddress = s.ReadUInt32();             // cache resource buffer
            memoryPartitions[0].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[1].BaseAddress = s.ReadUInt32();             // cache gestalt resource buffer
            memoryPartitions[1].Size        = s.ReadInt32();

            memoryPartitions[2].BaseAddress = s.ReadUInt32();             // global tags buffer (cache sound tags likes this memory space too)
            memoryPartitions[2].Size        = s.ReadInt32();
            memoryPartitions[3].BaseAddress = s.ReadUInt32();             // shared tag blocks? (havok data likes this memory space too)
            memoryPartitions[3].Size        = s.ReadInt32();
            memoryPartitions[4].BaseAddress = s.ReadUInt32();             // address
            memoryPartitions[4].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[5].BaseAddress = s.ReadUInt32();             // map tags buffer
            memoryPartitions[5].Size        = s.ReadInt32();
            #endregion

            int count = s.ReadInt32();
            s.Seek(4 + 8, System.IO.SeekOrigin.Current);             // these bytes are always the same
            // if there is a hash in the header, this is the ONLY
            // place where it can be
            s.Seek(20 /*SHA1*/ + 40 + 256 /*RSA*/, System.IO.SeekOrigin.Current);             // ???

            // 0x47C
            cacheInterop.Read(s);
            cacheInterop.PostprocessForCacheRead(k_local_sizeof);

            s.Seek(16, System.IO.SeekOrigin.Current);             // GUID?, these bytes are always the same. ODST is different from Halo 3

            // PATCH: main menu patches have a single entry (where stock has none)
            #region blah 1
            // 0x4AC

            // campaign has a shit load of these
            // but shared doesn't nor mainmenu
            // I compared the sc110 french and english and both have the SAME counts and element data. So
            // I don't think this is a hash or something. At least, if it is, it's not runtime relative so
            // nothing we have to worry about

            s.ReadInt16();             // I've only seen this be two different values (besides zero).
            count = s.ReadInt16();     // I think the above specifies the size of the structure this count represents?
            s.ReadInt32();             // seems to always be zero
            CompressionGuid = new Guid(s.ReadBytes(16));

            s.Seek(count * 28, System.IO.SeekOrigin.Current);             // seek past the elements
            // dword
            // long
            // buffer [0x14] (probably a sha1 hash)
            s.Seek((3600 - count) * 28, System.IO.SeekOrigin.Current);             // seek past the unused elements
            #endregion

            // PATCH: main menu patches have a count of '1' but doesn't appear to have
            #region blah 2
            s.Seek(sizeof(uint) + 0x4E9C, System.IO.SeekOrigin.Current);
#if false
            {
                // 0x18E94

                // going to punt and just assume there is a max count of 13 of these possible

                // maybe related to bsp\'zones'?
                const int blah2_sizeof = 0x60C;

                count = (int)(s.ReadUInt32() >> 24);                               // did someone forget to f*****g byte swap something?
                s.Seek(count * blah2_sizeof, System.IO.SeekOrigin.Current);        // seek past the elements
                s.Seek((13 - count) * blah2_sizeof, System.IO.SeekOrigin.Current); // seek past the unused elements
            }
#endif
            #endregion

            s.Seek(712 + sizeof(uint), System.IO.SeekOrigin.Current);


            ReadPostprocessForInterop();

            if (!cacheInterop.IsNull)
            {
                int debug_mask = (int)cacheInterop[CacheSectionType.Debug].AddressMask;
                if (TagsUnknown1Offset != 0)
                {
                    TagsUnknown1Offset -= debug_mask;
                }
                if (TagsUnknown2Offset != 0)
                {
                    TagsUnknown2Offset -= debug_mask;
                }
            }

            ReadPostprocessForBaseAddresses(s);
        }
Exemplo n.º 22
0
 static void FixupTagInstanceHeaderName(CacheFile cache, CacheItem instance, int name_offset, IO.EndianReader s)
 {
     s.Seek(name_offset);
     instance.TagNameOffset = s.PositionUnsigned;
     instance.ReferenceName = cache.References.AddOptimized(instance.GroupTag, s.ReadCString());
 }
Exemplo n.º 23
0
        public void Read(IO.EndianReader s)
        {
            var context = s.UserData as XmbFileContext;

            using (s.ReadSignatureWithByteSwapSupport(kSignature))
            {
                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    // #HACK to deal with xmb files which weren't updated with new tools
                    if (s.ByteOrder == Shell.EndianFormat.Big)
                    {
                        context.PointerSize = Shell.ProcessorSize.x32;
                    }
                }

                s.VirtualAddressTranslationInitialize(context.PointerSize);

                Values.PtrHandle elements_offset_pos;

                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    s.Pad32();
                }
                #region Initialize elements
                {
                    int count = s.ReadInt32();
                    if (context.PointerSize == Shell.ProcessorSize.x64)
                    {
                        s.Pad32();
                    }
                    s.ReadVirtualAddress(out elements_offset_pos);

                    mElements = new List <Element>(count);
                }
                #endregion
                #region Initialize and read pool
                {
                    int size = s.ReadInt32();
                    if (context.PointerSize == Shell.ProcessorSize.x64)
                    {
                        s.Pad32();
                    }
                    Values.PtrHandle pool_offset_pos = s.ReadVirtualAddress();

                    s.Seek((long)pool_offset_pos);
                    byte[] buffer = s.ReadBytes(size);

                    mPool = new XmbVariantMemoryPool(buffer, s.ByteOrder);
                }
                #endregion

                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    s.Pad64();
                }

                s.Seek((long)elements_offset_pos);
                for (int x = 0; x < mElements.Capacity; x++)
                {
                    var e = new Element();
                    mElements.Add(e);

                    e.Index = x;
                    e.Read(this, context, s);
                }

                foreach (var e in mElements)
                {
                    e.ReadAttributes(this, s);
                    e.ReadChildren(s);
                }
            }
        }
Exemplo n.º 24
0
 /// <summary>Moves the stream ahead by the sizeof a eight character code (8 bytes) times the count of the <see cref="GroupTags"/></summary>
 /// <param name="s"></param>
 /// <remarks>Doesn't actually read any data from the stream, only seeks forward</remarks>
 public override void Read(IO.EndianReader s)
 {
     s.Seek(GroupTags.Count * sizeof(TagWord), System.IO.SeekOrigin.Current);
 }
Exemplo n.º 25
0
 /// <summary>
 /// Moves the stream ahead by the sizeof a four character code (4 bytes) times the count of the group tags
 /// </summary>
 /// <param name="s"></param>
 /// <remarks>Doesn't actually read any data from the stream, only seeks forward</remarks>
 public void Read(IO.EndianReader s)
 {
     s.Seek(groupTags.Length * 4, System.IO.SeekOrigin.Current);
 }
Exemplo n.º 26
0
 /// <summary>
 /// Moves the stream ahead by the sizeof
 /// a four character code (4 bytes)
 /// </summary>
 /// <param name="s"></param>
 /// <remarks>Doesn't actually read any data from the stream, only seeks forward</remarks>
 public void Read(IO.EndianReader s)
 {
     s.Seek(4, System.IO.SeekOrigin.Current);
 }
        public void ExtractSounds(string path, System.IO.StreamWriter towav, IO.EndianReader pckReader,
                                  bool overwriteExisting = false)
        {
            Dictionary <uint, SoundBank.AkSoundBankHierarchyObjectBase> sounds;

            if (!mObjects.TryGetValue(SoundBank.HircType.Sound, out sounds))
            {
                Debug.Trace.FilePackage.TraceInformation("{0} - No sounds to extract?",
                                                         PackageFileName);
                return;
            }

            foreach (var kv in sounds)
            {
                var snd = kv.Value as SoundBank.AkSoundBankHierarchySound;
                if (snd.Name == null && mDupObjects.Contains(kv.Key))
                {
                    continue;
                }

                uint src_id = snd.Source.MediaInfo.SourceID;
                mUntouched.Remove(src_id);

                if (snd.Source.MediaInfo.FileID == 0)
                {
                    towav.WriteLine("REM NoData {0}", snd.Name);
                    continue;
                }

                string dir      = null;
                string filename = (snd.Name ?? ("unknown_" + kv.Key.ToString("X8"))) + ".xma";

                uint   bank_id = snd.BankId;
                string bank_name;
                if (!Package.IdToName.TryGetValue(bank_id, out bank_name))
                {
                    bank_name = bank_id.ToString("X8");
                }

                SoundBank.AkSoundBankData bank_data = null;
                bool streamed = snd.Source.StreamType != SoundBank.AkBankSourceData.SourceType.Data;
                if (!streamed)
                {
                    bank_data = mIdToBank[bank_id].mData;
                }

                dir = System.IO.Path.Combine(path, bank_name);
                System.IO.Directory.CreateDirectory(dir);

                string full_path = System.IO.Path.Combine(dir, filename);
                towav.WriteLine("towav.exe {0}", full_path);

                if (System.IO.File.Exists(full_path) && !overwriteExisting)
                {
                    continue;
                }

                using (var fs = System.IO.File.Create(full_path))
                {
                    if (streamed)
                    {
                        var file = Package.FindStreamedFileById(snd.Source.MediaInfo.FileID);
                        pckReader.Seek(file.FileOffset);
                        byte[] data = pckReader.ReadBytes((int)file.FileSize32);

                        fs.Write(data, 0, data.Length);
                    }
                    else
                    {
                        fs.Write(bank_data.Buffer, (int)snd.Source.MediaInfo.FileOffset, (int)snd.Source.MediaInfo.MediaSize);
                    }
                }
            }
            //////////////////////////////////////////////////////////////////////////
            foreach (var kv in mUntouched)
            {
                var mr = kv.Value;

                string name = "unknown2_" + mr.Media.ID.ToString("X8");
                if (mr.Media.Size == 0)
                {
                    towav.WriteLine("REM NoData2 {0}", name);
                    continue;
                }

                string filename = name + ".xma";

                uint   bank_id = mr.BankId;
                string bank_name;
                if (!Package.IdToName.TryGetValue(bank_id, out bank_name))
                {
                    bank_name = bank_id.ToString("X8");
                }

                SoundBank.AkSoundBankData bank_data = mIdToBank[bank_id].mData;

                string dir = System.IO.Path.Combine(path, bank_name);
                System.IO.Directory.CreateDirectory(dir);

                string full_path = System.IO.Path.Combine(dir, filename);
                towav.WriteLine("towav.exe {0}", full_path);

                if (System.IO.File.Exists(full_path))
                {
                    continue;
                }

                using (var fs = System.IO.File.Create(full_path))
                {
                    fs.Write(bank_data.Buffer, (int)mr.Media.Offset, (int)mr.Media.Size);
                }
            }
        }
            internal TI.Definition LoadResources(CacheFileGen3 c, cache_file_resource_gestalt_group owner, cache_file_resource_layout_table cache_layout, bool mega_hack)
            {
                if (Reference.Datum == DatumIndex.Null)
                {
                    return(null);                                                    // this is a null entry
                }
                if (loadedResources != null)
                {
                    return(loadedResources);                                         // data already loaded, return
                }
                var rdf = c.GetCacheFileResourceDefinitionFactory();

                // pre-process cache for resource loading
                cache_layout.BuildInteropData();
                owner.BuildInteropData();

                int resource_stream_definition_size = BlockSize.Value;

                // sound resource case hack
                bool use_sound_resource_hack = false;

                if (resource_stream_definition_size == 0)
                {
                    Debug.Assert.If(ResourceType.Value == owner.resource_index_sound_resource_definition);
                    resource_stream_definition_size = sound_resource_definition.kSizeOf;
                    use_sound_resource_hack         = true;
                }

                int resource_stream_size_required = resource_stream_definition_size;
                // base address to use on cache fixups, cache data will be appended
                // later on
                uint cache_required_base_address = 0, cache_optional_base_address = 0;

                byte[] resource_stream_data;

                #region create resource buffer
                {                // Get our page segment data so we can build our resource buffer for loading
                    int seg_index = SegmentIndex.Value;
                    cache_file_resource_layout_table.page_segment_block page_segment = cache_layout.PageSegments[seg_index];
                    int required_size = page_segment.GetRequiredSize();
                    int optional_size = page_segment.GetOptionalSize();

                    cache_required_base_address = (uint)resource_stream_size_required;
                    if (required_size > 0)
                    {
                        resource_stream_size_required += required_size;
                    }

                    if (optional_size > 0)                     // optional isn't always used so don't set the base address if it isn't
                    {
                        cache_optional_base_address    = (uint)resource_stream_size_required;
                        resource_stream_size_required += optional_size;
                    }

                    // get our definition data buffer
                    resource_stream_data = new byte[resource_stream_size_required];
                    if (use_sound_resource_hack)                     // sound_resources don't occupy space in the resource-definition-data, so we have to create faux def data
                    {
                        int data_size = 0;
                        if (required_size > 0)
                        {
                            data_size += required_size;
                        }
                        if (optional_size > 0)
                        {
                            data_size += optional_size;
                        }
                        if (data_size > 0)
                        {
                            rdf.InsertDataSizeIntoFauxDefinitionData(resource_stream_data, (uint)data_size);
                        }
                    }
                    else
                    {
                        Array.Copy(owner.ResourceDefinitionData.Value, BlockOffset.Value, resource_stream_data, 0, resource_stream_definition_size);
                    }

                    {                     // get cache data and append it
                        byte[] page_data =
                            cache_layout.Pages[page_segment.RequiredPageIndex.Value].GetSegmentData(c, cache_layout, page_segment.RequiredSegmentOffset.Value);

                        Array.Copy(page_data, 0, resource_stream_data, (int)cache_required_base_address, required_size);

                        if (page_segment.OptionalPageIndex.Value >= 0 && cache_optional_base_address > 0)
                        {
                            page_data = cache_layout.Pages[page_segment.OptionalPageIndex.Value].GetSegmentData(c, cache_layout, page_segment.OptionalSegmentOffset.Value);
                            Array.Copy(page_data, 0, resource_stream_data, (int)cache_optional_base_address, optional_size);
                        }
                    }
                }
                #endregion

                Util.OptionalValue optv = new Util.OptionalValue((byte)resource_fixup_type.Count);

                #region perform fixups
                using (var ms = new System.IO.MemoryStream(resource_stream_data, true))
                {
                    foreach (resource_fixup_block def in ResourceFixups)
                    {
                        uint address        = (uint)def.Address.Value;
                        uint address_offset = optv.GetValue(address);
                        ms.Seek(def.BlockOffset.Value, System.IO.SeekOrigin.Begin);
                        resource_fixup_type rft = (resource_fixup_type)optv.GetOption(address);

                        switch (rft)
                        {
                        case resource_fixup_type.Data: break;

                        case resource_fixup_type.CacheRequired: address_offset += cache_required_base_address; break;

                        case resource_fixup_type.CacheOptional: address_offset += cache_optional_base_address; break;

                        default: throw new Debug.Exceptions.UnreachableException();
                        }

                        IO.ByteSwap.SwapUDWordAndWrite(address_offset, ms);

                        // hack identifier for StructReference fields when the definition is at offset '0'
                        // as that f***s with the init code
                        //if (address_offset == 0) IO.ByteSwap.SwapUDWordAndWrite(1, ms);
                    }

//					foreach (resource_definition_fixup_block def in ResourceDefinitionFixups)
//					{
//					}
                }
                #endregion

                #region create and stream definition
                using (var s = new IO.EndianReader(resource_stream_data, IO.EndianState.Big, null))
                {
                    int res_type = ResourceType.Value;
                    if (res_type == owner.resource_index_render_geometry_api_resource_definition)
                    {
                        loadedResources = rdf.GenerateRenderGeometryApiResource();
                    }
                    else if (res_type == owner.resource_index_bitmap_texture_interop_resource)
                    {
                        loadedResources = rdf.GenerateBitmapTextureInteropResource();
                    }
                    else if (res_type == owner.resource_index_model_animation_tag_resource)
                    {
                        loadedResources = rdf.GenerateModelAnimationTagResource();
                    }
                    // TODO: haven't quite figured this one out yet. Currently using hacked up code (see [use_sound_resource_hack])
                    else if (res_type == owner.resource_index_sound_resource_definition)
                    {
                        loadedResources = rdf.GenerateSoundResourceResource();
                    }
                    else if (res_type == owner.resource_index_bitmap_texture_interleaved_interop_resource)
                    {
                        loadedResources = rdf.GenerateBitmapTextureInterleavedInteropResource();
                    }
                    else if (res_type == owner.resource_index_structure_bsp_tag_resources)
                    {
                        loadedResources = rdf.GenerateStructureBspTagResource();
                    }
                    // TODO: haven't figured this one out yet
                    else if (res_type == owner.resource_index_structure_bsp_cache_file_tag_resources)
                    {
                        loadedResources = rdf.GenerateStructureBspCacheFileTagResource();
                    }
                    else
                    {
                        throw new Debug.Exceptions.UnreachableException();
                    }

                    s.Seek(optv.GetValue((uint)DefinitionOffset.Value));
                    IO.ITagStream ts = new resource_tag_stream(c, Reference.Datum, s);

                    ts.Flags.Add(
                        IO.ITagStreamFlags.UseStreamPositions |
                        IO.ITagStreamFlags.DontStreamStringData |
                        IO.ITagStreamFlags.DontStreamFieldSetHeader |
                        IO.ITagStreamFlags.DontPostprocess);
                    if (mega_hack)
                    {
                        ts.Flags.Add(IO.ITagStreamFlags.Halo3VertexBufferMegaHack);
                    }
                    loadedResources.Read(ts);
                }
                #endregion

                return(loadedResources);
            }