public RelocationPointerList GetListForPart(byte module, byte block)
 {
     for (int i = 0; i < pointerBlocks.Length; i++)
     {
         RelocationPointerList e = pointerBlocks[i];
         if (e.module == module && e.id == block)
         {
             return(e);
         }
     }
     return(null);
 }
 private void ReadPointerBlock(Reader reader, RelocationPointerList pointerBlock)
 {
     for (int j = 0; j < pointerBlock.count; j++)
     {
         // One pointer info struct contains the address where the pointer is located and the module & block of the part it points to.
         // The address that it points to is to be read at address offsetInMemory.
         // The part's baseInMemory should be subtracted from it to get the offset relative to the part.
         pointerBlock.pointers[j] = new RelocationPointerInfo();
         pointerBlock.pointers[j].offsetInMemory = reader.ReadUInt32();
         pointerBlock.pointers[j].module         = reader.ReadByte();
         pointerBlock.pointers[j].id             = reader.ReadByte();
         if (Settings.s.engineVersion > Settings.EngineVersion.TT && Settings.s.game != Settings.Game.PlaymobilLaura)
         {
             pointerBlock.pointers[j].byte6 = reader.ReadByte();
             pointerBlock.pointers[j].byte7 = reader.ReadByte();
         }
     }
 }
 // Used for Tonic Trouble's Fixlvl.rtb, which contains a list of fix->lvl pointers that should be loaded along with the fix.rtb file
 public void Add(RelocationTable rt)
 {
     if (rt == null)
     {
         return;
     }
     for (int i = 0; i < rt.pointerBlocks.Length; i++)
     {
         RelocationPointerList ptrList = GetListForPart(rt.pointerBlocks[i].module, rt.pointerBlocks[i].id);
         if (ptrList == null)
         {
             Array.Resize(ref pointerBlocks, pointerBlocks.Length + 1);
             pointerBlocks[pointerBlocks.Length - 1] = rt.pointerBlocks[i];
         }
         else
         {
             ptrList.count += rt.pointerBlocks[i].count;
             Array.Resize(ref ptrList.pointers, (int)ptrList.count);
             Array.Copy(rt.pointerBlocks[i].pointers, 0, ptrList.pointers, ptrList.count - rt.pointerBlocks[i].count, rt.pointerBlocks[i].count);
         }
     }
 }
Exemple #4
0
        void Read(EndianBinaryReader reader)
        {
            MapLoader l = MapLoader.Loader;

            byte count = reader.ReadByte();

            reader.ReadUInt32();
            pointerBlocks = new RelocationPointerList[count];
            for (int i = 0; i < count; i++)
            {
                // A pointer list contains pointers located in SNA part with matching module & block
                pointerBlocks[i]        = new RelocationPointerList();
                pointerBlocks[i].module = reader.ReadByte();
                pointerBlocks[i].id     = reader.ReadByte();
                l.print("Parsing pointer block for (" + pointerBlocks[i].module + "," + pointerBlocks[i].id + ")");
                //l.print("Module: " + parts[i].module + " - Block: " + parts[i].block);
                pointerBlocks[i].count    = reader.ReadUInt32();
                pointerBlocks[i].pointers = new RelocationPointerInfo[pointerBlocks[i].count];
                for (int j = 0; j < pointerBlocks[i].count; j++)
                {
                    // One pointer info struct contains the address where the pointer is located and the module & block of the part it points to.
                    // The address that it points to is to be read at address offsetInMemory.
                    // The part's baseInMemory should be subtracted from it to get the offset relative to the part.
                    pointerBlocks[i].pointers[j] = new RelocationPointerInfo();
                    pointerBlocks[i].pointers[j].offsetInMemory = reader.ReadUInt32();
                    if (pointerBlocks[i].pointers[j].offsetInMemory == 1824756 || pointerBlocks[i].pointers[j].offsetInMemory == 1824748)
                    {
                        l.print("Found! It's (" + pointerBlocks[i].module + "," + pointerBlocks[i].id + ")");
                    }
                    pointerBlocks[i].pointers[j].module = reader.ReadByte();
                    pointerBlocks[i].pointers[j].id     = reader.ReadByte();
                    pointerBlocks[i].pointers[j].byte6  = reader.ReadByte();
                    pointerBlocks[i].pointers[j].byte7  = reader.ReadByte();
                }
            }
        }
        async Task Read(Reader reader)
        {
            MapLoader         l          = MapLoader.Loader;
            PartialHttpStream httpStream = reader.BaseStream as PartialHttpStream;

            if (httpStream != null)
            {
                await httpStream.FillCacheForRead(5);
            }
            byte count = reader.ReadByte();

            if (Settings.s.game != Settings.Game.R2Demo &&
                Settings.s.engineVersion > Settings.EngineVersion.Montreal)
            {
                reader.ReadUInt32();
            }
            pointerBlocks = new RelocationPointerList[count];
            for (int i = 0; i < count; i++)
            {
                if (reader.BaseStream.Position >= reader.BaseStream.Length)
                {
                    Array.Resize(ref pointerBlocks, i);
                    break;
                }
                if (httpStream != null)
                {
                    await httpStream.FillCacheForRead(6);
                }
                // A pointer list contains pointers located in SNA part with matching module & block
                pointerBlocks[i]        = new RelocationPointerList();
                pointerBlocks[i].module = reader.ReadByte();
                pointerBlocks[i].id     = reader.ReadByte();
                l.print("Parsing pointer block for (" + pointerBlocks[i].module + "," + pointerBlocks[i].id + ")");
                //l.print("Module: " + parts[i].module + " - Block: " + parts[i].block);
                pointerBlocks[i].count    = reader.ReadUInt32();
                pointerBlocks[i].pointers = new RelocationPointerInfo[pointerBlocks[i].count];
                if (pointerBlocks[i].count > 0)
                {
                    if (Settings.s.snaCompression)
                    {
                        if (httpStream != null)
                        {
                            await httpStream.FillCacheForRead(5 *4);
                        }
                        uint isCompressed         = reader.ReadUInt32();
                        uint compressedSize       = reader.ReadUInt32();
                        uint compressedChecksum   = reader.ReadUInt32();
                        uint decompressedSize     = reader.ReadUInt32();
                        uint decompressedChecksum = reader.ReadUInt32();
                        if (httpStream != null)
                        {
                            await httpStream.FillCacheForRead((int)compressedSize);
                        }
                        byte[] compressedData = reader.ReadBytes((int)compressedSize);
                        if (isCompressed != 0)
                        {
                            using (var compressedStream = new MemoryStream(compressedData))
                                using (var lzo = new LzoStream(compressedStream, CompressionMode.Decompress))
                                    using (Reader lzoReader = new Reader(lzo, Settings.s.IsLittleEndian)) {
                                        ReadPointerBlock(lzoReader, pointerBlocks[i]);
                                    }
                        }
                        else
                        {
                            using (var uncompressedStream = new MemoryStream(compressedData))
                                using (Reader unCompressedReader = new Reader(uncompressedStream, Settings.s.IsLittleEndian)) {
                                    ReadPointerBlock(unCompressedReader, pointerBlocks[i]);
                                }
                        }
                    }
                    else
                    {
                        if (httpStream != null)
                        {
                            await httpStream.FillCacheForRead((int)pointerBlocks[i].count * 8);
                        }
                        ReadPointerBlock(reader, pointerBlocks[i]);
                    }
                }
            }
        }
Exemple #6
0
 ushort GetRelocationKey(RelocationPointerList list)   // The list of pointers for a certain SNA block
 {
     return(GetRelocationKey(list.module, list.id));
 }