Exemplo n.º 1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="path">File path to the SID file.</param>
        public SidReader(string path)
        {
            using (var sid = new EndianBinaryReader(File.OpenRead(path), Endian.Big))
            {
                // Get some flag values beforehand
                // Video standard/chip model/BASIC flag
                sid.BaseStream.Seek(0x76, SeekOrigin.Begin);
                short flag = sid.ReadInt16();
                VideoStandard = GetVideoStandard(flag);
                ChipModel = GetChipModel(flag);
                IsBasicFlagSet = BasicFlagIsSet(flag);
                sid.BaseStream.Seek(0x00, SeekOrigin.Begin);

                // Header
                HeaderID = new string(sid.ReadChars(4));

                // Version number (Shift because big-endian)
                Version = sid.ReadInt16();

                // Offset to C64 binary data
                DataOffset = sid.ReadInt16();

                // Addresses
                LoadAddress = GetLoadAddress(sid);
                InitAddress = GetInitAddress(sid);
                PlayAddress = GetPlayAddress(sid);

                // Songs
                Songs = sid.ReadInt16();
                StartSong = sid.ReadInt16();

                // Speed integer
                Speed = sid.ReadInt32();

                // Song, Artist and Copyright
                SongTitle = new string(sid.ReadChars(32));
                Artist = new string(sid.ReadChars(32));
                Copyright = new string(sid.ReadChars(32));
            }
        }
Exemplo n.º 2
0
        public VirtualFilesystemDirectory ReadFile(EndianBinaryReader reader)
        {
            if (reader.ReadUInt32() != 0x52415243) // "RARC"
                throw new InvalidDataException("Invalid Magic, not a RARC File");

            uint fileSize = reader.ReadUInt32();
            reader.SkipUInt32(); // Unknown
            uint dataOffset = reader.ReadUInt32() + 0x20;
            reader.Skip(16); // Unknown - 4 unsigned ints
            uint numNodes = reader.ReadUInt32();
            reader.Skip(8); // Unknown - 2 unsigned ints
            uint fileEntryOffset = reader.ReadUInt32() + 0x20;
            reader.SkipUInt32(); // Unknown
            uint stringTableOffset = reader.ReadUInt32() + 0x20;
            reader.Skip(8); // Unknown - 2 unsigned ints.

            // Read all of the node headers.
            Node[] nodes = new Node[numNodes];

            for (int i = 0; i < numNodes; i++)
            {
                nodes[i] = new Node
                {
                    Type = new string(reader.ReadChars(4)),
                    Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt32()),
                    NameHashcode = reader.ReadUInt16(),
                    Entries = new FileEntry[reader.ReadUInt16()],
                    FirstFileOffset = reader.ReadUInt32()
                };
            }

            // Create a virtual directory for every folder within the ARC before we process any of them.
            List<VirtualFilesystemDirectory> allDirs = new List<VirtualFilesystemDirectory>(nodes.Length);
            foreach (Node node in nodes)
            {
                VirtualFilesystemDirectory vfDir = new VirtualFilesystemDirectory(node.Name);
                allDirs.Add(vfDir);
            }

            for (int k = 0; k < nodes.Length; k++)
            {
                Node node = nodes[k];
                VirtualFilesystemDirectory curDir = allDirs[k];

                for (int i = 0; i < node.Entries.Length; i++)
                {
                    // Jump to the entry's offset in the file.
                    reader.BaseStream.Position = fileEntryOffset + ((node.FirstFileOffset + i) * 0x14); // 0x14 is the size of a File Entry in bytes
                    node.Entries[i] = new FileEntry();
                    node.Entries[i].ID = reader.ReadUInt16();
                    node.Entries[i].NameHashcode = reader.ReadUInt16();
                    node.Entries[i].Type = reader.ReadByte();
                    reader.SkipByte(); // Padding
                    node.Entries[i].Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt16());

                    // Skip these ones cause I don't know how computers work.
                    if (node.Entries[i].Name == "." || node.Entries[i].Name == "..")
                        continue;

                    uint entryDataOffset = reader.ReadUInt32();
                    uint dataSize = reader.ReadUInt32();

                    // If it's a directory, then entryDataOffset contains the index of the parent node
                    if (node.Entries[i].IsDirectory)
                    {
                        node.Entries[i].SubDirIndex = entryDataOffset;
                        var newSubDir = allDirs[(int)entryDataOffset];
                        curDir.Children.Add(newSubDir);
                    }
                    else
                    {
                        node.Entries[i].Data = reader.ReadBytesAt(dataOffset + entryDataOffset, (int)dataSize);

                        string fileName = Path.GetFileNameWithoutExtension(node.Entries[i].Name);
                        string extension = Path.GetExtension(node.Entries[i].Name);

                        var vfFileContents = new VirtualFileContents(node.Entries[i].Data);
                        VirtualFilesystemFile vfFile = new VirtualFilesystemFile(fileName, extension, vfFileContents);
                        curDir.Children.Add(vfFile);
                    }

                    reader.SkipInt32(); // Padding
                }
            }

            // The ROOT directory should always be the first node. We don't have access to the node's TYPE anymore
            // so we're going to assume its always the first one listed.
            return allDirs.Count > 0 ? allDirs[0] : null;
        }
Exemplo n.º 3
0
        // Public Methods (1)
        /// <summary>
        /// Read string in file.
        /// </summary>
        /// <param name="reader">Binary reader to use.</param>
        /// <returns>Trimmed string.</returns>
        public static string ReadNSBMDString(EndianBinaryReader reader)
        {
            var str = new String(reader.ReadChars(System.Text.Encoding.ASCII, 16));
            str = str.Replace("\0", "");

            return str;
        }