Beispiel #1
0
        public SFOData Build()
        {
            SFOData sfo = new SFOData();

            sfo.Magic   = 0x46535000; // _PSF
            sfo.Version = 0x00000101;
            sfo.Entries = new List <SFODir>();

            var headerSize     = 20;
            var indexTableSize = entries.Count * 16;

            var keyTableSize = entries.Sum(x => x.Key.Length + 1);

            if (keyTableSize % 4 != 0)
            {
                sfo.Padding = (uint)(4 - keyTableSize % 4);
            }

            sfo.KeyTableOffset = (uint)(headerSize + indexTableSize);

            sfo.DataTableOffset = sfo.KeyTableOffset + (uint)keyTableSize + sfo.Padding;

            ushort keyOffset  = 0;
            uint   dataOffset = 0;

            for (var i = 0; i < entries.Count; i++)
            {
                var entry       = entries[i];
                var entryLength = GetEntryLength(entry.Key, entry.Value);
                var maxLength   = GetMaxLength(entry.Key);

                if (entryLength > maxLength)
                {
                    throw new Exception("Value for {entry.Key} exceeds maximum allowed length");
                }

                sfo.Entries.Add(new SFODir()
                {
                    KeyOffset  = keyOffset,
                    Format     = GetEntryType(entry.Key),
                    Length     = entryLength,
                    MaxLength  = maxLength,
                    DataOffset = dataOffset,
                    Key        = entry.Key,
                    Value      = entry.Value,
                });

                dataOffset += maxLength;
                keyOffset  += (ushort)(entries[i].Key.Length + 1);
            }

            sfo.Size = sfo.DataTableOffset + dataOffset;

            return(sfo);
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sfo"></param>
        /// <returns></returns>
        private uint[] BuildHeader(SFOData sfo)
        {
            // point to the end of the header
            uint currentOffset = 0x28;

            uint[] header = new uint[0x28 / 4];

            header[0] = PBPMAGIC;  // Header: PBP<null>
            header[1] = 0x10000;

            header[2] = currentOffset; // Start of SFO

            currentOffset += sfo.Size;
            header[3]      = currentOffset; // Start of ICON0

            currentOffset += convertInfo.Icon0.Size;
            header[4]      = currentOffset; // Start of ICON1

            currentOffset += convertInfo.Icon1.Size;
            header[5]      = currentOffset; // Start of PIC0

            currentOffset += convertInfo.Pic0.Size;
            header[6]      = currentOffset; // Start of PIC1

            currentOffset += convertInfo.Pic1.Size;
            header[7]      = currentOffset; // Start of SND0

            currentOffset += convertInfo.Snd0.Size;
            header[8]      = currentOffset; // Start of DATA.PSP

            var psarOffset = header[8] + convertInfo.DataPsp.Size;

            if ((psarOffset % 0x10000) != 0)
            {
                psarOffset = psarOffset + (0x10000 - (psarOffset % 0x10000));
            }

            header[9] = psarOffset;  // Start of DATA.PSAR

            return(header);
        }