예제 #1
0
        public override bool OnInitialize()
        {
            ModuleSectionNode section = Location;

            if (section == null || !Header)
            {
                return(false);
            }

            //Don't make a copy buffer here.
            //Use the original buffer to save memory

            buint * sPtr = (buint *)Header;
            VoidPtr ceil = section.Header + section._dataSize;

            while (!(PowerPC.Disassemble(*sPtr++) is PPCblr) && (int)sPtr < (int)ceil)
            {
                ;
            }

            _codeStart = (int)Header - (int)section.Header;
            _codeLen   = (int)sPtr - (int)Header;

            _manager = new RelocationManager(null);
            _manager.UseReference(section, _codeStart);

            if (_codeLen > 0)
            {
                _manager.AddTag(0, FullName + " Start");
                _manager.AddTag(_codeLen / 4 - 1, FullName + " End");
            }

            return(false);
        }
예제 #2
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            WAVEHeader *header = (WAVEHeader *)address;

            header->_tag        = WAVEHeader.Tag;
            header->_numEntries = Children.Count;
            header->_length     = length;
            buint * table    = (buint *)header + 3;
            VoidPtr addr     = table + Children.Count;
            VoidPtr baseAddr = _audioAddr;

            foreach (WAVESoundNode r in Children)
            {
                table[r.Index] = (uint)(addr - address);

                r.MoveRawUncompressed(addr, r.WorkingUncompressed.Length);

                WaveInfo *wave = (WaveInfo *)addr;
                wave->_dataLocation = (uint)(_audioAddr - baseAddr);

                Memory.Move(_audioAddr, r._streamBuffer.Address, (uint)r._streamBuffer.Length);

                _audioAddr += (uint)r._streamBuffer.Length;
                addr       += r.WorkingUncompressed.Length;
            }
        }
예제 #3
0
        private AttributeInterpretation GenerateDefaultInterpretation()
        {
            AttributeInfo[] arr   = new AttributeInfo[NumEntries];
            buint *         pIn   = (buint *)AttributeAddress;
            int             index = 0x10;

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = new AttributeInfo()
                {
                    _name = "0x" + index.ToString("X3")
                };
                //Guess if the value is a an integer or float
                uint  u = (uint)*((buint *)pIn);
                float f = (float)*((bfloat *)pIn);
                if (*pIn == 0)
                {
                    arr[i]._type        = 0;
                    arr[i]._description = "Default: 0 (could be int or float - be careful)";
                }
                else if (((u >> 24) & 0xFF) != 0 && *((bint *)pIn) != -1 && !float.IsNaN(f))
                {
                    float abs = Math.Abs(f);
                    if (abs > 0.0000001 && abs < 10000000)
                    {
                        arr[i]._type        = 0;
                        arr[i]._description = "Default (float): " + f + " (" + u.ToString("X8") + ")";
                    }
                    else
                    {
                        arr[i]._type        = 1;
                        arr[i]._description = "Default (unknown type): " + u + " (" + u.ToString("X8") + ")";
                        arr[i]._name        = "~" + arr[i]._name;
                    }
                }
                else
                {
                    arr[i]._type        = 1;
                    arr[i]._description = "Default (int): " + u + " (" + u.ToString("X8") + ")";
                    arr[i]._name        = "*" + arr[i]._name;
                }
                index += 4;
                pIn++;
            }

            ResourceNode root = this;

            while (root.Parent != null)
            {
                root = root.Parent;
            }
            string filename = "TBLV/" + root.Name.Replace("STG", "") + ".txt";

            return(new AttributeInterpretation(arr, filename));
        }
예제 #4
0
        public uint GetSize()
        {
            buint *offsets = TextOffset;
            buint *sizes   = TextSize;
            uint   maxLen  = 0;

            for (int i = 0; i < 18; ++i)
            {
                maxLen = Math.Max(offsets[i] + sizes[i], maxLen);
            }
            return(maxLen + 0x100);
        }
예제 #5
0
 public unsafe void ExportInitialized(string outPath)
 {
     using (FileStream stream = new FileStream(outPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 8, FileOptions.RandomAccess))
     {
         stream.SetLength(_dataBuffer.Length);
         using (FileMap map = FileMap.FromStream(stream))
         {
             buint *addr = (buint *)map.Address;
             foreach (Relocation loc in Relocations)
             {
                 *addr++ = loc.SectionOffset;
             }
         }
     }
 }
예제 #6
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            buint *addr = (buint *)address;

            ((bushort *)addr)[0] = ptcl;
            ((bushort *)addr)[1] = _ptclInitTrackCount;
            addr += ptcl + 1;
            foreach (REFFAnimationNode e in Children)
            {
                if (e._isPtcl)
                {
                    *addr++ = (uint)e._calcSize;
                }
            }

            ((bushort *)addr)[0] = emit;
            ((bushort *)addr)[1] = _emitInitTrackCount;
            addr += emit + 1;
            foreach (REFFAnimationNode e in Children)
            {
                if (!e._isPtcl)
                {
                    *addr++ = (uint)e._calcSize;
                }
            }

            VoidPtr ptr = addr;

            foreach (REFFAnimationNode e in Children)
            {
                if (e._isPtcl)
                {
                    e.Rebuild(ptr, e._calcSize, true);
                    ptr += e._calcSize;
                }
            }

            foreach (REFFAnimationNode e in Children)
            {
                if (!e._isPtcl)
                {
                    e.Rebuild(ptr, e._calcSize, true);
                    ptr += e._calcSize;
                }
            }
        }
예제 #7
0
        public override bool OnInitialize()
        {
            ModuleSectionNode section = Location;

            if ((TargetSection == 1 || TargetModule.Equals("main.dol")) && ModuleMapLoader.MapFiles.ContainsKey(TargetModule))
            {
                if (ModuleMapLoader.MapFiles[TargetModule].ContainsKey(TargetOffset))
                {
                    _name = ModuleMapLoader.MapFiles[TargetModule][TargetOffset];
                }
            }

            if (section == null || !Header)
            {
                return(false);
            }

            //Don't make a copy buffer here.
            //Use the original buffer to save memory

            buint * sPtr = (buint *)Header;
            VoidPtr ceil = section.Header + section._dataSize;

            while (!(PowerPC.Disassemble(*sPtr++) is PPCblr) && (int)sPtr < (int)ceil)
            {
                ;
            }

            _codeStart = (int)Header - (int)section.Header;
            _codeLen   = (int)sPtr - (int)Header;

            _manager = new RelocationManager(null);
            _manager.UseReference(section, _codeStart);

            if (_codeLen > 0)
            {
                _manager.AddTag(0, FullName + " Start");
                _manager.AddTag(_codeLen / 4 - 1, FullName + " End");
            }

            return(false);
        }
        public override void OnPopulate()
        {
            int    offset = 0;
            buint *addr   = _ptclTrackAddr;

            addr += PtclTrackCount; //skip nulled pointers to size list
            for (int i = 0; i < PtclTrackCount; i++)
            {
                new REFFAnimationNode()
                {
                    _isPtcl = true
                }.Initialize(this, First + offset, (int)*addr);
                offset += (int)*addr++;
            }
            addr  = _emitTrackAddr;
            addr += EmitTrackCount; //skip nulled pointers to size list
            for (int i = 0; i < EmitTrackCount; i++)
            {
                new REFFAnimationNode().Initialize(this, First + offset, (int)*addr);
                offset += (int)*addr++;
            }
        }
예제 #9
0
        public override void OnPopulate()
        {
            //Enumerate entries, attaching them to the files.
            RSARHeader *rsar          = Header;
            SYMBHeader *symb          = rsar->SYMBBlock;
            sbyte *     offset        = (sbyte *)symb + 8;
            buint *     stringOffsets = symb->StringOffsets;

            VoidPtr baseAddr = (VoidPtr)rsar->INFOBlock + 8;
            ruint * typeList = (ruint *)baseAddr;

            //Iterate through group types
            for (int i = 0; i < 5; i++)
            {
                _infoCache[i] = new List <RSAREntryNode>();
                Type t = null;

                RuintList *list = (RuintList *)((uint)baseAddr + typeList[i]);
                sbyte *    str, end;

                switch (i)
                {
                case 0: t = typeof(RSARSoundNode); break;

                case 1: t = typeof(RSARBankNode); break;

                case 2: t = typeof(RSARPlayerInfoNode); break;

                case 3: continue;                         //Files

                case 4: t = typeof(RSARGroupNode); break; //Last group entry is null
                }

                for (int x = 0; x < list->_numEntries; x++)
                {
                    VoidPtr addr = list->Get(baseAddr, x);

                    ResourceNode  parent = this;
                    RSAREntryNode n      = Activator.CreateInstance(t) as RSAREntryNode;
                    n._origSource = n._uncompSource = new DataSource(addr, 0);
                    n._infoIndex  = x;

                    if (i == 4 && x == list->_numEntries - 1)
                    {
                        n._name    = "<null>";
                        n._parent  = this;
                        _nullGroup = n as RSARGroupNode;
                    }
                    else
                    {
                        str = offset + stringOffsets[n.StringId];

                        for (end = str; *end != 0; end++)
                        {
                            ;
                        }
                        while ((--end > str) && (*end != '_'))
                        {
                            ;
                        }

                        if (end > str)
                        {
                            parent  = CreatePath(parent, str, (int)end - (int)str);
                            n._name = new String(end + 1);
                        }
                        else
                        {
                            n._name = new String(str);
                        }
                    }

                    n.Initialize(parent, addr, 0);
                    _infoCache[i].Add(n);
                }
            }
            ftr = *(INFOFooter *)((uint)baseAddr + typeList[5]);

            foreach (RSARFileNode n in Files)
            {
                if (!(n is RSARExtFileNode))
                {
                    n.GetName();
                }
            }

            _rootIds   = new int[4];
            _symbCache = new List <SYMBMaskEntry> [4];
            bint *offsets = (bint *)((VoidPtr)symb + 12);

            for (int i = 0; i < 4; i++)
            {
                _symbCache[i] = new List <SYMBMaskEntry>();
                SYMBMaskHeader *hdr = (SYMBMaskHeader *)((VoidPtr)symb + 8 + offsets[i]);
                //Console.WriteLine("Root Index = " + hdr->_rootId);
                _rootIds[i] = hdr->_rootId;
                for (int x = 0; x < hdr->_numEntries; x++)
                {
                    SYMBMaskEntry *e = &hdr->Entries[x];
                    _symbCache[i].Add(*e);
                    //Console.WriteLine(String.Format("[{5}] {0}, {1}, {2} - {4}", e->_bit != -1 ? e->_bit.ToString().PadLeft(3) : "   ", e->_leftId != -1 ? e->_leftId.ToString().PadLeft(3) : "   ", e->_rightId != -1 ? e->_rightId.ToString().PadLeft(3) : "   ", e->_index != -1 ? e->_index.ToString().PadLeft(3) : "   ", new string(offset + stringOffsets[e->_stringId]), x.ToString().PadLeft(3)));
                }
            }
            //Sort(true);
        }
        public static unsafe FileMap Encode(IAudioStream stream, IProgressTracker progress)
        {
            int  tmp;
            bool looped   = stream.IsLooping;
            int  channels = stream.Channels;
            int  samples;
            int  blocks;
            int  sampleRate = stream.Frequency;
            int  lbSamples, lbSize, lbTotal;
            int /*loopPadding, */ loopStart, totalSamples;
            short *tPtr;

            int blockLen, samplesPerBlock;

            if (looped)
            {
                loopStart = stream.LoopStartSample;
                samples   = stream.LoopEndSample; //Set sample size to end sample. That way the audio gets cut off when encoding.

                blockLen        = (samples.Align(14) / 14 * 8);
                samplesPerBlock = blockLen / 8 * 14;

                //If loop point doesn't land on a block, pad the stream so that it does.
                //if ((tmp = loopStart % samplesPerBlock) != 0)
                //{
                //    loopPadding = samplesPerBlock - tmp;
                //    loopStart += loopPadding;
                //}
                //else
                //    loopPadding = 0;

                totalSamples = /*loopPadding + */ samples;
            }
            else
            {
                //loopPadding = 0;
                loopStart    = 0;
                totalSamples = samples = stream.Samples;

                blockLen        = (samples.Align(14) / 14 * 8);
                samplesPerBlock = blockLen / 8 * 14;
            }

            if (progress != null)
            {
                progress.Begin(0, totalSamples * channels * 3, 0);
            }

            blocks = (totalSamples + (samplesPerBlock - 1)) / samplesPerBlock;

            //Initialize stream info
            if ((tmp = totalSamples % samplesPerBlock) != 0)
            {
                lbSamples = tmp;
                lbSize    = (lbSamples + 13) / 14 * 8;
                lbTotal   = lbSize.Align(0x20);
            }
            else
            {
                lbSamples = samplesPerBlock;
                lbTotal   = lbSize = blockLen;
            }

            //Get section sizes
            int headerSize    = RWAV.Size,
                infoSize      = 8,
                waveSize      = 0x1C,
                tableSize     = channels * 4,
                channelSize   = channels * 0x1C,
                adpcmInfoSize = channels * 0x30,
                entrySize     = (infoSize + waveSize + tableSize + channelSize + adpcmInfoSize).Align(0x20) - 8,
                dataSize      = (((blocks - 1) * blockLen + lbTotal) * channels) + 8;

            //Create file map
            FileMap map = FileMap.FromTempFile(headerSize + entrySize + 8 + dataSize);

            //Get section pointers
            RWAV *header = (RWAV *)map.Address;

            header->_header._tag         = RWAV.Tag;
            header->_header.Endian       = Endian.Big;
            header->_header._version     = 0x102;
            header->_header._length      = map.Length;
            header->_header._firstOffset = 0x20;
            header->_header._numEntries  = 2;

            header->_infoOffset = 0x20;
            header->_infoLength = entrySize + 8;
            header->_dataOffset = 0x20 + entrySize + 8;
            header->_dataLength = dataSize;

            RWAVInfo *infoBlock = header->Info;

            infoBlock->_header._tag    = RWAVInfo.Tag;
            infoBlock->_header._length = entrySize + 8;

            WaveInfo *wave = &infoBlock->_info;

            wave->_format                 = new AudioFormatInfo(2, (byte)(looped ? 1 : 0), (byte)channels, 0);
            wave->_sampleRate             = (ushort)sampleRate;
            wave->_channelInfoTableOffset = 0x1C;
            wave->_dataLocation           = (uint)(header->Data->Data - map.Address);

            wave->LoopSample = loopStart;
            wave->NumSamples = totalSamples;

            RWAVData *dataBlock = header->Data;

            dataBlock->_header._tag    = RWAVData.Tag;
            dataBlock->_header._length = dataSize;

            //Create one ChannelInfo for each channel
            buint *      table       = (buint *)((VoidPtr)wave + 0x1C);
            ChannelInfo *channelInfo = (ChannelInfo *)((VoidPtr)wave + waveSize + tableSize);

            for (int i = 0; i < channels; i++)
            {
                table[i]       = (uint)&channelInfo[i] - (uint)wave;
                channelInfo[i] = new ChannelInfo()
                {
                    _volBackLeft     = 1,
                    _volBackRight    = 1,
                    _volFrontLeft    = 1,
                    _volFrontRight   = 1,
                    _adpcmInfoOffset = waveSize + tableSize + channelSize + i * 0x30
                };
            }

            //Create one ADPCMInfo for each channel
            int *       adpcData = stackalloc int[channels];
            ADPCMInfo **pAdpcm   = (ADPCMInfo **)adpcData;

            for (int i = 0; i < channels; i++)
            {
                *(pAdpcm[i] = wave->GetADPCMInfo(i)) = new ADPCMInfo();
            }

            //Create buffer for each channel
            int *   bufferData     = stackalloc int[channels];
            short **channelBuffers = (short **)bufferData;
            int     bufferSamples  = totalSamples + 2; //Add two samples for initial yn values

            for (int i = 0; i < channels; i++)
            {
                channelBuffers[i] = tPtr = (short *)Marshal.AllocHGlobal(bufferSamples * 2); //Two bytes per sample

                //Zero padding samples and initial yn values
                //for (int x = 0; x < (loopPadding + 2); x++)
                //    *tPtr++ = 0;
            }

            //Fill buffers
            stream.SamplePosition = 0;
            short *sampleBuffer = stackalloc short[channels];

            for (int i = 2; i < bufferSamples; i++)
            {
                //if (stream.SamplePosition == stream.LoopEndSample && looped)
                //    stream.SamplePosition = stream.LoopStartSample;

                stream.ReadSamples(sampleBuffer, 1);
                for (int x = 0; x < channels; x++)
                {
                    channelBuffers[x][i] = sampleBuffer[x];
                }
            }

            //Calculate coefs
            for (int i = 0; i < channels; i++)
            {
                AudioConverter.CalcCoefs(channelBuffers[i] + 2, totalSamples, (short *)pAdpcm[i], progress);
            }

            //Encode blocks
            byte *dPtr = (byte *)dataBlock->Data;

            for (int sIndex = 0, bIndex = 1; sIndex < totalSamples; sIndex += samplesPerBlock, bIndex++)
            {
                int blockSamples = Math.Min(totalSamples - sIndex, samplesPerBlock);
                for (int x = 0; x < channels; x++)
                {
                    channelInfo[x]._channelDataOffset = (int)(dPtr - (byte *)dataBlock->Data);
                    short *sPtr = channelBuffers[x] + sIndex;

                    //Set block yn values
                    if (bIndex != blocks)
                    {
                        pAdpcm[x]->_yn1 = sPtr[samplesPerBlock + 1];
                        pAdpcm[x]->_yn2 = sPtr[samplesPerBlock];
                    }

                    //Encode block (include yn in sPtr)
                    AudioConverter.EncodeBlock(sPtr, blockSamples, dPtr, (short *)pAdpcm[x]);

                    //Set initial ps
                    if (bIndex == 1)
                    {
                        pAdpcm[x]->_ps = *dPtr;
                    }

                    //Advance output pointer
                    if (bIndex == blocks)
                    {
                        //Fill remaining
                        dPtr += lbSize;
                        for (int i = lbSize; i < lbTotal; i++)
                        {
                            *dPtr++ = 0;
                        }
                    }
                    else
                    {
                        dPtr += blockLen;
                    }
                }

                if (progress != null && (sIndex % samplesPerBlock) == 0)
                {
                    progress.Update(progress.CurrentValue + (samplesPerBlock * 2 * channels));
                }
            }

            //Reverse coefs
            for (int i = 0; i < channels; i++)
            {
                short *p = pAdpcm[i]->_coefs;
                for (int x = 0; x < 16; x++, p++)
                {
                    *p = p->Reverse();
                }
            }

            //Write loop states
            if (looped)
            {
                //Can't we just use block states?
                int loopBlock = loopStart / samplesPerBlock;
                int loopChunk = (loopStart - (loopBlock * samplesPerBlock)) / 14;
                dPtr = (byte *)dataBlock->Data + (loopBlock * blockLen * channels) + (loopChunk * 8);
                tmp  = (loopBlock == blocks - 1) ? lbTotal : blockLen;

                for (int i = 0; i < channels; i++, dPtr += tmp)
                {
                    //Use adjusted samples for yn values
                    tPtr             = channelBuffers[i] + loopStart;
                    pAdpcm[i]->_lps  = *dPtr;
                    pAdpcm[i]->_lyn2 = *tPtr++;
                    pAdpcm[i]->_lyn1 = *tPtr;
                }
            }

            //Free memory
            for (int i = 0; i < channels; i++)
            {
                Marshal.FreeHGlobal((IntPtr)channelBuffers[i]);
            }

            if (progress != null)
            {
                progress.Finish();
            }

            return(map);
        }
예제 #11
0
        protected override void OnPopulate()
        {
            RSARFolderNode g = new RSARFolderNode();

            g.Name   = "Info";
            g.Parent = this;
            g        = new RSARFolderNode();
            g.Name   = "Files";
            g.Parent = this;

            //Retrieve all files to attach to entries
            GetFiles();

            //Enumerate entries, attaching them to the files.
            RSARHeader *rsar          = Header;
            SYMBHeader *symb          = rsar->SYMBBlock;
            sbyte *     offset        = (sbyte *)symb + 8;
            buint *     stringOffsets = symb->StringOffsets;

            VoidPtr types    = (VoidPtr)rsar->INFOBlock + 8;
            ruint * typeList = (ruint *)types;

            //Iterate through group types
            for (int i = 0; i < 5; i++)
            {
                Type t = null;

                ruint *entryList = (ruint *)((uint)types + typeList[i] + 4);
                int    entryCount = *((bint *)entryList - 1);
                sbyte *str, end;

                switch (i)
                {
                case 0: t = typeof(RSARSoundNode); break;

                case 1: t = typeof(RSARBankNode); break;

                case 2: t = typeof(RSARTypeNode); break;

                case 3: continue;

                case 4: t = typeof(RSARGroupNode); break;
                }

                for (int x = 0; x < entryCount; x++)
                {
                    ResourceNode  parent = Children[0];
                    RSAREntryNode n      = Activator.CreateInstance(t) as RSAREntryNode;
                    n._origSource = n._uncompSource = new DataSource(types + entryList[x], 0);

                    str = offset + stringOffsets[n.StringId];

                    for (end = str; *end != 0; end++)
                    {
                        ;
                    }
                    while ((--end > str) && (*end != '_'))
                    {
                        ;
                    }

                    if (end > str)
                    {
                        parent  = CreatePath(parent, str, (int)end - (int)str);
                        n._name = new String(end + 1);
                    }
                    else
                    {
                        n._name = new String(str);
                    }
                    n.Initialize(parent, types + entryList[x], 0);
                    //n.Populate();
                }
            }
            //Sort(true);
        }
예제 #12
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            ItmFreqHeader *header = (ItmFreqHeader *)address;

            *header = new ItmFreqHeader();
            header->_Length = length;
            int offCount = 0; // save for later;

            //header->_OffCount;
            header->_DataTable = 1;
            header->_pad0      = 0;
            header->_pad1      = 0;
            header->_pad2      = 0;
            header->_pad3      = 0;

            List <uint> groupOffsets = new List <uint>();
            List <uint> tableOffsets = new List <uint>();

            uint offset = ItmFreqHeader.Size;

            // First, rebuild the items themselves, updating the group offset to the proper value (also reset both sets of offsets)
            foreach (ItmTableNode table in Children)
            {
                table._offset   = 0;
                table._dataSize = 0;
                if (table.HasChildren)
                {
                    offCount++;
                    foreach (ItmTableGroupNode group in table.Children)
                    {
                        group._offset = 0;
                        if (group.HasChildren)
                        {
                            offCount++;
                            group._offset = offset - ItmFreqHeader.Size;
                            foreach (ResourceNode item in group.Children)
                            {
                                int size = item.OnCalculateSize(true);
                                item.OnRebuild(address + offset, size, true);
                                offset          += (uint)size;
                                table._dataSize += (uint)size;
                            }
                        }
                    }
                    // Rebuild the table's groups
                    table._offset = offset - ItmFreqHeader.Size;
                    foreach (ResourceNode group in table.Children)
                    {
                        int size = group.OnCalculateSize(true);
                        group.OnRebuild(address + offset, size, true);
                        if (group.HasChildren)
                        {
                            groupOffsets.Add(offset - 0x14);
                        }
                        offset          += (uint)size;
                        table._dataSize += (uint)size;
                    }
                }

                // Add padding to match vBrawl
                if (table.HasChildren && (table.NextSibling()?.HasChildren ?? true))
                {
                    buint *ptr = (buint *)(address + offset);
                    ptr[0]  = 0;
                    offset += 4;
                }
            }

            header->_OffCount   = offCount;
            header->_DataLength = length - (ItmFreqHeader.Size + (offCount + 2) * 0x04 + "genParamSet".UTF8Length() + 1);

            // Finally, rebuild tables
            foreach (ResourceNode table in Children)
            {
                int size = table.OnCalculateSize(true);
                table.OnRebuild(address + offset, size, true);
                if (table.HasChildren)
                {
                    tableOffsets.Add(offset - 0x14 - 0x0C);
                }
                offset += (uint)size;
            }

            foreach (uint i in groupOffsets)
            {
                buint *ptr = (buint *)(address + offset);
                ptr[0]  = i;
                offset += 4;
            }

            foreach (uint i in tableOffsets)
            {
                buint *ptr = (buint *)(address + offset);
                ptr[0]  = i;
                offset += 4;
            }

            if (tableOffsets.Count > 0)
            {
                buint *ptr = (buint *)(address + offset);
                ptr[0]  = tableOffsets[0];
                offset += 4;
            }

            buint *clear = (buint *)(address + offset);

            clear[0] = 0;
            offset  += 4;

            (address + offset).WriteUTF8String("genParamSet", true);
        }
예제 #13
0
        public override void OnPopulate()
        {
            _sections = new ModuleSectionNode[_numSections];
            int prevOffset = RELHeader.Size + RELSectionEntry.Size * (int)_numSections;

            for (int i = 0; i < _numSections; i++)
            {
                RELSectionEntry   entry   = Header->SectionInfo[i];
                ModuleSectionNode section = _sections[i] = new ModuleSectionNode();

                int dataOffset = entry.Offset, dataSize = (int)(uint)entry._size;

                section._isCodeSection = entry.IsCodeSection;
                section._dataOffset    = dataOffset;
                section._dataSize      = entry._size;

                section.Initialize(this, WorkingUncompressed.Address + dataOffset, dataSize);

                if (dataOffset > 0)
                {
                    section._dataAlign = dataOffset - prevOffset;
                    prevOffset         = dataOffset + dataSize;
                }
            }

            //Larger modules may take slightly longer to relocate
            //Use a background worker so the UI thread isn't suspended
            Action <object, DoWorkEventArgs> work = (object sender, DoWorkEventArgs e) =>
            {
                Stopwatch watch = Stopwatch.StartNew();

                ApplyRelocations();

                //Scan for branches, add extra tags
                foreach (ModuleSectionNode s in Sections)
                {
                    if (s.HasCode)
                    {
                        PPCOpCode code;
                        buint *   opPtr = s.BufferAddress;
                        for (int i = 0; i < s._dataBuffer.Length / 4; i++)
                        {
                            if ((code = (uint)*opPtr++) is PPCBranch && !(code is PPCblr || code is PPCbctr))
                            {
                                s._manager.LinkBranch(i, true);
                            }
                        }

                        var cmds = s._manager.GetCommands();
                        foreach (var x in cmds)
                        {
                            RelocationTarget target = x.Value.GetTargetRelocation();
                            string           value  = null;
                            if (target.Section != null && target._sectionID == 5 && !String.IsNullOrEmpty(value = target.Section._manager.GetString(target._index)))
                            {
                                s._manager.AddTag(x.Key, value);
                            }
                        }
                    }
                }

                Sections[5].Populate();

                watch.Stop();
                Console.WriteLine("Took {0} seconds to relocate {1} module", (double)watch.ElapsedMilliseconds / 1000d, Name);
            };

            using (BackgroundWorker b = new BackgroundWorker())
            {
                b.DoWork += new DoWorkEventHandler(work);
                b.RunWorkerAsync();
            }

            // Stage module conversion
            byte *bptr   = (byte *)WorkingUncompressed.Address;
            int   offset = findStageIDOffset();

            _stageID = offset < 0 ? (byte?)null : bptr[offset];

            if (nodeContainsString("stOnlineTrainning"))
            {
                // File must be online training room .rel file
                _itemIDs = new byte[OTrainItemOffsets.Length];
                for (int i = 0; i < OTrainItemOffsets.Length; i++)
                {
                    _itemIDs[i] = bptr[OTrainItemOffsets[i]];
                }
            }
        }
예제 #14
0
        //public RSARGroupNode _nullGroup;
        public override void OnPopulate()
        {
            //Enumerate entries, attaching them to the files.
            RSARHeader *rsar          = Header;
            SYMBHeader *symb          = rsar->SYMBBlock;
            sbyte *     offset        = (sbyte *)symb + 8;
            buint *     stringOffsets = symb->StringOffsets;

            VoidPtr baseAddr = (VoidPtr)rsar->INFOBlock + 8;
            ruint * typeList = (ruint *)baseAddr;

            //Iterate through group types
            for (int i = 0; i < 5; i++)
            {
                Type t = null;
                switch (i)
                {
                case 0: t = typeof(RSARSoundNode); break;

                case 1: t = typeof(RSARBankNode); break;

                case 2: t = typeof(RSARPlayerInfoNode); break;

                case 3: continue;                         //Files

                case 4: t = typeof(RSARGroupNode); break; //Last group entry has no name
                }

                _infoCache[i] = new List <RSAREntryNode>();
                RuintList *list = (RuintList *)((uint)baseAddr + typeList[i]);
                sbyte *    str, end;

                for (int x = 0; x < list->_numEntries; x++)
                {
                    VoidPtr addr = list->Get(baseAddr, x);

                    ResourceNode  parent = this;
                    RSAREntryNode n      = Activator.CreateInstance(t) as RSAREntryNode;
                    n._origSource = n._uncompSource = new DataSource(addr, 0);

                    if (n.StringId >= 0)
                    {
                        str = offset + stringOffsets[n.StringId];

                        for (end = str; *end != 0; end++)
                        {
                            ;
                        }
                        while ((--end > str) && (*end != '_'))
                        {
                            ;
                        }

                        if (end > str)
                        {
                            parent  = CreatePath(parent, str, (int)end - (int)str);
                            n._name = new String(end + 1);
                        }
                        else
                        {
                            n._name = new String(str);
                        }
                    }
                    else
                    {
                        n._name = null;
                    }

                    n._infoIndex = x;
                    n.Initialize(parent, addr, 0);
                    _infoCache[i].Add(n);
                }
                _ftr = *(INFOFooter *)((uint)baseAddr + typeList[5]);

                foreach (RSARFileNode n in Files)
                {
                    if (!(n is RSARExtFileNode))
                    {
                        n.GetName();
                    }
                }
            }
        }
예제 #15
0
        protected override void OnPopulate()
        {
            //Get files
            GetFiles();

            //Enumerate entries, attaching them to the files.


            RSARHeader *rsar          = Header;
            SYMBHeader *symb          = rsar->SYMBBlock;
            sbyte *     offset        = (sbyte *)symb + 8;
            buint *     stringOffsets = symb->StringOffsets;

            VoidPtr gOffset = (VoidPtr)rsar->INFOBlock + 8;
            ruint * groups  = (ruint *)gOffset;

            for (int i = 0; i < 5; i++)
            {
                Type t = null;

                ruint *list = (ruint *)((uint)groups + groups[i] + 4);
                int    count = *((bint *)list - 1);
                sbyte *str, end;

                switch (i)
                {
                case 0: t = typeof(RSARSoundNode); break;

                case 1: t = typeof(RSARBankNode); break;

                case 2: t = typeof(RSARTypeNode); break;

                case 3:
                {
                    //Get files
                    //INFOFileHeader* fileHeader;
                    //INFOFileEntry* fileEntry;
                    //RuintList* entryList;
                    //INFOGroupHeader* group;
                    //INFOGroupEntry* gEntry;
                    //RuintList* groupList = rsar->INFOBlock->Groups;
                    //RSARFileNode n;
                    //DataSource source;

                    //for (int x = 0; x < count; x++)
                    //{
                    //    fileHeader = (INFOFileHeader*)(gOffset + list[x]);
                    //    entryList = fileHeader->GetList(gOffset);
                    //    if (entryList->_numEntries == 0)
                    //    {
                    //        //Must be external file.
                    //        n = new RSARExtFileNode();
                    //        source = new DataSource(fileHeader, 0);
                    //    }
                    //    else
                    //    {
                    //        //use first entry
                    //        fileEntry = (INFOFileEntry*)entryList->Get(gOffset, 0);
                    //        //Find group with matching ID
                    //        group = (INFOGroupHeader*)groupList->Get(gOffset, fileEntry->_groupId);
                    //        //Find group entry with matching index
                    //        gEntry = (INFOGroupEntry*)group->GetCollection(gOffset)->Get(gOffset, fileEntry->_index);

                    //        //Create node and parse
                    //        source = new DataSource((int)rsar + group->_headerOffset + gEntry->_headerOffset, gEntry->_headerLength);
                    //        if ((n = NodeFactory.GetRaw(source) as RSARFileNode) == null)
                    //            n = new RSARFileNode();
                    //        n._audioSource = new DataSource((int)rsar + group->_dataOffset + gEntry->_dataOffset, gEntry->_dataLength);
                    //    }
                    //    n._fileIndex = x;
                    //    n._parent = this; //This is so that the node won't add itself to the child list.
                    //    n.Initialize(this, source);
                    //    _files.Add(n);
                    //}
                    continue;
                }

                case 4: t = typeof(RSARGroupNode); break;
                }

                for (int x = 0; x < count; x++)
                {
                    ResourceNode  parent = this;
                    RSAREntryNode n      = Activator.CreateInstance(t) as RSAREntryNode;
                    n._origSource = n._uncompSource = new DataSource(gOffset + list[x], 0);

                    str = offset + stringOffsets[n.StringId];

                    for (end = str; *end != 0; end++)
                    {
                        ;
                    }
                    while ((--end > str) && (*end != '_'))
                    {
                        ;
                    }

                    if (end > str)
                    {
                        parent  = CreatePath(parent, str, (int)end - (int)str);
                        n._name = new String(end + 1);
                    }
                    else
                    {
                        n._name = new String(str);
                    }
                    n.Initialize(parent, gOffset + list[x], 0);
                }
            }
            Sort(true);
        }