Esempio n. 1
0
        public static void parseT64(ROMInfo info, WrappedInputStream s)
        {
            info.addInfo("Platform", "Commodore 64");
            s.Position = 32;

            short version = s.readShortLE();

            info.addInfo("Version", version);

            short dirEntries = s.readShortLE();

            info.addInfo("Number of files", dirEntries);

            short usedEntries = s.readShortLE();

            info.addInfo("Number of used entries", usedEntries);

            short reserved = s.readShortLE();

            info.addInfo("Reserved", reserved, true);

            string name = s.read(24, Encoding.ASCII).TrimEnd(' ');

            info.addInfo("Internal name", name);
        }
Esempio n. 2
0
        public static WrappedInputStream decodeSMD(WrappedInputStream s)
        {
            s.Seek(512, SeekOrigin.Current);
            //Should only need this much to read the header. If I was actually converting
            //the ROM I'd need to use the SMD header to know how many blocks there are
            //and read multiple blocks and whatnot
            byte[] block = s.read(16384);

            byte[] buf = new byte[16386];
            //Yes, the below starting points are correct. It makes no goddamned
            //sense but if I use even = 0 and odd = 1 as the starting points
            //it goes off by one so I don't know anymore
            int buf_even = 1;
            int buf_odd  = 2;

            int midpoint = 8192;

            for (int i = 0; i < block.Length; ++i)
            {
                if (i <= midpoint)
                {
                    buf[buf_even] = block[i];
                    buf_even     += 2;
                }
                else
                {
                    buf[buf_odd] = block[i];
                    buf_odd     += 2;
                }
            }

            byte[] buf2 = new byte[buf_odd];
            Array.Copy(buf, buf2, buf_odd);
            return(new WrappedInputStream(new MemoryStream(buf2)));
        }
Esempio n. 3
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            if ("dol".Equals(file.extension))
            {
                //TODO Parse what little info there is out of dol (could use this for boot .dol and Wii homebrew .dol too I guess)
                info.addInfo("Platform", "GameCube");
                return;
            }

            WrappedInputStream s = file.stream;

            byte[] magic = s.read(4);
            if (isTGCMagic(magic))
            {
                s.Position = 8;
                int tgcHeaderSize = s.readIntBE();
                info.addInfo("TGC header size", tgcHeaderSize, ROMInfo.FormatMode.SIZE);

                //What the f**k? What does Dolphin know that YAGD doesn't and didn't decide to tell the rest of the class?
                s.Position = 0x24;
                int realOffset = s.readIntBE();
                s.Position = 0x34;
                int virtualOffset = s.readIntBE();
                int fileOffset    = realOffset - virtualOffset;
                parseGamecubeDisc(info, s, tgcHeaderSize, fileOffset, true);
            }
            else
            {
                parseGamecubeDisc(info, s, 0, 0, false);
            }
        }
Esempio n. 4
0
        public static void parseBAMArea(ROMInfo info, WrappedInputStream s, long offset)
        {
            s.Position = offset;

            int firstTrack  = s.read();
            int firstSector = s.read();

            info.addInfo("First directory track", firstTrack);
            info.addInfo("First directory sector", firstSector);

            int diskType = s.read();

            info.addInfo("Disk type", diskType);

            int unused = s.read();

            info.addInfo("Unused", unused, true);

            //TODO Individual BAM entries

            s.Position = offset + 0x90;
            //Official documentation says it goes up to 16 bytes, and the rest are 2-byte 0xa0 padding, 2-byte disk ID, 1 byte unused 0xa0, and "2A" for DOS type. Howevevr, that seems to not actually be the case half the time, as people just put whatever they want here, especially cracking groups
            string diskLabel = Encoding.ASCII.GetString(s.read(27).Select(b => b == 0xa0 ? (byte)0x20 : b).ToArray()).TrimEnd(' ');

            info.addInfo("Internal name", diskLabel);
        }
Esempio n. 5
0
        public static void parseCCS64Cart(ROMInfo info, WrappedInputStream s)
        {
            s.Position = 0x10;
            int headerLength = s.readIntBE();

            info.addInfo("Header size", headerLength);

            short version = s.readShortBE();

            info.addInfo("Version", version);             //Is this actually the kind of version I'm thinking of, or is it more like the header version?

            short cartType = s.readShortBE();

            info.addInfo("Type", cartType, CARTRIDGE_TYPES);
            info.addInfo("Platform", cartType == 15 ? "Commodore 64GS" : "Commodore 64");

            int exromLineStatus = s.read();

            info.addInfo("EXROM line status", exromLineStatus == 0 ? "Active" : "Inactive");

            int gameLineStatus = s.read();

            info.addInfo("Game line status", gameLineStatus == 0 ? "Active" : "Inactive");

            byte[] reserved = s.read(6);
            info.addInfo("Reserved", reserved, true);

            string name = s.read(32, Encoding.ASCII).TrimEnd('\0');

            info.addInfo("Internal name", name);
            //TODO Read CHIP packets (not entirely trivial as there can be more than one)
        }
Esempio n. 6
0
        public static void parsePlainRegion(ROMInfo info, WrappedInputStream s, string prefix, long offset = 0)
        {
            s.Position = offset;

            //TODO: Only read up to plainRegionSize bytes
            List <string> libs = new List <string>();

            while (true)
            {
                int c = s.read();
                if (c == -1 | c == 0)
                {
                    break;
                }

                StringBuilder sb = new StringBuilder();
                sb.Append((char)c);
                while (true)
                {
                    int cc = s.read();
                    if (cc == -1 | cc == 0)
                    {
                        break;
                    }
                    sb.Append((char)cc);
                }
                libs.Add(sb.ToString());
            }
            info.addInfo(combinePrefix(prefix, "Libraries used"), String.Join(", ", libs));
        }
Esempio n. 7
0
        public static Tuple <int, byte[], byte[]> hash(WrappedInputStream s, long offset)
        {
            long originalPos = s.Position;

            try {
                MD5  md5   = MD5.Create();
                SHA1 sha1  = SHA1.Create();
                int  crc32 = 0;

                s.Position = offset;

                byte[] buf;
                while ((buf = s.read(1024 * 1024 * 10)).Length > 0)
                {
                    md5.TransformBlock(buf, 0, buf.Length, buf, 0);
                    sha1.TransformBlock(buf, 0, buf.Length, buf, 0);
                    crc32 = CRC32.crc32(buf, crc32);
                }
                md5.TransformFinalBlock(new byte[0], 0, 0);
                sha1.TransformFinalBlock(new byte[0], 0, 0);

                //TODO: Should make new class/struct to hold sets of hashes instead of using weird tuple
                return(new Tuple <int, byte[], byte[]>(crc32, md5.Hash, sha1.Hash));
            } finally {
                s.Position = originalPos;
            }
        }
Esempio n. 8
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", "Nintendo 64");

            WrappedInputStream s = file.stream;

            byte[]       header = s.read(4);
            N64ROMFormat format = detectFormat(header);

            info.addInfo("Detected format", detectFormat(header));

            if (!isDiskFormat(format) && isDiskExtension(file.extension))
            {
                //Some kind of 64DD disk with an unknown format (might be a dev disk or something, or a bad dump with no system area)
                return;
            }
            else if (isDiskFormat(format))
            {
                parse64DDDiskInfo(info, s);
            }
            else if (format == N64ROMFormat.V64)
            {
                ByteSwappedInputStream swappedInputStream = new ByteSwappedInputStream(s);
                parseN64ROM(swappedInputStream, info);
            }
            else
            {
                parseN64ROM(s, info);
            }
            //Haha I'm sure word swapping will be a lot of fun
        }
Esempio n. 9
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            WrappedInputStream s = file.stream;

            string copyrightInfo = s.read(28, Encoding.ASCII);

            info.addInfo("Copyright", copyrightInfo, true);
            //For first party games this should say that, and for third party games it should say " LICENSED BY SNK CORPORATION"
            info.addInfo("First party", "COPYRIGHT BY SNK CORPORATION".Equals(copyrightInfo));

            byte[] entryPoint = s.read(4);
            info.addInfo("Entry point", entryPoint, ROMInfo.FormatMode.HEX, true);

            short gameNumber = s.readShortLE();

            info.addInfo("Product code", gameNumber.ToString("X2"));

            int version = s.read();

            info.addInfo("Version", version);

            bool isColor = s.read() == 0x10;

            info.addInfo("Is colour", isColor);
            info.addInfo("Platform", isColor ? "Neo Geo Pocket Color" : "Neo Geo Pocket");


            string internalName = s.read(12, Encoding.ASCII);

            info.addInfo("Internal name", internalName);

            byte[] reserved = s.read(16);
            info.addInfo("Reserved", reserved, true);             //Should be 0 filled
        }
Esempio n. 10
0
        public static void readRootFST(FilesystemDirectory fs, WrappedInputStream s, int fstOffset, int fstSize, int virtualOffset)
        {
            //TODO: Check against FST max size in header, and also Wii RAM limit (since this is also used on Wii I think, otherwise I'd say GameCube RAM limit) (88MB for Wii, 24MB system / 43MB total for GameCube) as it would be impossible for real hardware to read a bigger filesystem
            //TODO: Wii shifts offset by one
            long origPos = s.Position;
            Dictionary <int, FilesystemDirectory> parentDirectories = new Dictionary <int, FilesystemDirectory> {
                { 0, fs }
            };

            try {
                s.Position = fstOffset + 8;
                //1 byte flag at fstOffset + 0: Filesystem root _must_ be a directory
                //Name offset is irrelevant since the root doesn't really have a name (I think it's just set to 0 anyway)
                //Parent index would also be irrelevant because it doesn't have a parent by definition
                //TODO: Throw error or something if not a directory
                //TODO: Throw error if number of entries * 12 > fstSize
                int numberOfEntries = s.readIntBE();
                int fntOffset       = fstOffset + (numberOfEntries * 12);
                int fntSize         = fstSize - ((numberOfEntries) * 12);
                s.Position = fntOffset;
                byte[] fnt = s.read(fntSize);
                s.Position = fstOffset + 12;

                //Due to weirdness, we need to figure out which directories these files go in afterwards. It's really weird. I just hope it makes enough sense for whatever purpose you're reading this code for.
                Dictionary <int, FilesystemFile> filesToAdd           = new Dictionary <int, FilesystemFile>();
                Dictionary <int, int>            directoryNextIndexes = new Dictionary <int, int> {
                    { 0, numberOfEntries }
                };

                for (int i = 0; i < numberOfEntries - 1; ++i)
                {
                    byte[] entry = s.read(12);
                    readFileEntry(entry, fnt, virtualOffset, parentDirectories, i + 1, filesToAdd, directoryNextIndexes);
                }

                //Now that we have the directory structure, add the files to them
                //This sucks, by the way
                //Like it's not that my code sucks (although it probably kinda does), it's like... I hate the GameCube filesystem
                foreach (var fileToAdd in filesToAdd)
                {
                    int            fileIndex = fileToAdd.Key;
                    FilesystemFile file      = fileToAdd.Value;

                    for (int potentialParentIndex = fileIndex - 1; potentialParentIndex >= 0; potentialParentIndex--)
                    {
                        if (directoryNextIndexes.ContainsKey(potentialParentIndex))
                        {
                            if (directoryNextIndexes[potentialParentIndex] > fileIndex)
                            {
                                var parentDir = parentDirectories[potentialParentIndex];
                                parentDir.addChild(file);
                                break;
                            }
                        }
                    }
                }
            } finally {
                s.Position = origPos;
            }
        }
Esempio n. 11
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", name);
            WrappedInputStream s = file.stream;

            s.Seek(-544, System.IO.SeekOrigin.End);             //Yeah, this one's a bit weird

            string title = s.read(20, MainProgram.shiftJIS).TrimEnd(' ');

            info.addInfo("Internal name", title);
            byte[] reserved = s.read(5);
            info.addInfo("Reserved", reserved, true);
            string makerCode = s.read(2, Encoding.ASCII);

            info.addInfo("Publisher", makerCode, NintendoCommon.LICENSEE_CODES);
            string productCode = s.read(4, Encoding.ASCII);

            info.addInfo("Product code", productCode);
            //I don't know what to do about the game type, since it's all V so far
            info.addInfo("Type", productCode[0], true);
            string shortTitle = productCode.Substring(1, 2);

            info.addInfo("Short title", shortTitle);
            char country = productCode[3];

            info.addInfo("Country", country, NintendoCommon.COUNTRIES);
            int version = s.read();

            info.addInfo("Version", version);
        }
Esempio n. 12
0
        public static void parseSMSROM(ROMInfo info, ROMFile file)
        {
            WrappedInputStream s = file.stream;

            long headerOffset = -1;

            //Supposedly the header _could_ be at 0x1ff0 or 0x3ff0 but no known software does that. But let's check it anyway just for something to do
            s.Position = 0x1ff0;
            string magic = "TMR SEGA";

            if (s.read(8, Encoding.ASCII).Equals(magic))
            {
                headerOffset = s.Position;
            }
            else
            {
                s.Position = 0x3ff0;
                if (s.read(8, Encoding.ASCII).Equals(magic))
                {
                    headerOffset = s.Position;
                }
                else
                {
                    s.Position = 0x7ff0;
                    if (s.read(8, Encoding.ASCII).Equals(magic))
                    {
                        headerOffset = s.Position;
                    }
                }
            }

            if (headerOffset != -1)
            {
                //It's entirely possible this header isn't there, since Japanese Master Systems don't check for it
                //and therefore Japanese Master System games aren't required to have it
                info.addInfo("Header position", headerOffset, true);
                info.addInfo("Has standard header", true);
                bool isGameGear = "gg".Equals(file.extension);
                parseSegaHeader(info, s, headerOffset, isGameGear);
            }
            else
            {
                info.addInfo("Has standard header", false);
            }

            s.Position = 0x7fe0;
            if (s.read(4, Encoding.ASCII).Equals("SDSC"))
            {
                info.addInfo("Has SDSC header", true);

                parseSDSCHeader(info, s);
            }
            else
            {
                info.addInfo("Has SDSC header", false);
            }

            //TODO Codemasters header (tricky to detect presence, and I don't have any Codemasters games anyway)
        }
Esempio n. 13
0
        public static void parseDSiHeader(ROMInfo info, WrappedInputStream s)
        {
            s.Position = 0x1b0;
            int regionFlags = s.readIntLE();

            //There's only 6 bits used, everything else is reserved. What a good use of 5 bytes!
            if (regionFlags == -1)
            {
                //Hmm... Pokemon gen 5 games (I sure do talk about them a lot, huh? Well, they're weird. And they're good games) use 0xffffffef / -17 here, actually; explain that one nerd (bit 27 I guess? But then what the heck)
                info.addInfo("Region", "Region free");
            }
            else
            {
                info.addInfo("Region", Enum.ToObject(typeof(DSiRegionFlags), regionFlags).ToString());
            }

            s.Position = 0x210;
            int usedROMSize = s.readIntLE();

            info.addInfo("Used ROM size", usedROMSize, ROMInfo.FormatMode.SIZE);

            info.addInfo("DSi reserved", s.read(4), true);
            info.addInfo("DSi reserved 2", s.read(4), true);
            info.addInfo("DSi reserved 3", s.read(4), true);

            int modcryptOffset = s.readIntLE();

            info.addInfo("Modcrypt area 1 offset", modcryptOffset, ROMInfo.FormatMode.HEX, true);
            int modcryptSize = s.readIntLE();

            info.addInfo("Modcrypt area 1 size", modcryptSize, ROMInfo.FormatMode.SIZE, true);
            int modcryptOffset2 = s.readIntLE();

            info.addInfo("Modcrypt area 2 offset", modcryptOffset2, ROMInfo.FormatMode.HEX, true);
            int modcryptSize2 = s.readIntLE();

            info.addInfo("Modcrypt area 2 size", modcryptSize2, ROMInfo.FormatMode.SIZE, true);

            string emagCode = s.read(4, Encoding.ASCII);

            info.addInfo("Game code backwards", emagCode, true);
            int dsiType = s.read();

            info.addInfo("Filetype", dsiType, DSI_TYPES);
            byte[] titleIDReserved = s.read(3);             //Usually 00 03 00 for some reason
            info.addInfo("DSi title ID reserved", titleIDReserved, true);

            int publicSaveSize = s.readIntLE();

            info.addInfo("DSiWare public.sav filesize", publicSaveSize, ROMInfo.FormatMode.SIZE);
            int privateSaveSize = s.readIntLE();

            info.addInfo("DSiWare private.sav filesize", publicSaveSize, ROMInfo.FormatMode.SIZE);

            info.addInfo("DSi reserved 4", s.read(176), true);

            byte[] ratings = s.read(16);
            NintendoCommon.parseRatings(info, ratings, true);
        }
Esempio n. 14
0
        public static Dictionary <string, object> convertParamSFO(WrappedInputStream s)
        {
            var d = new Dictionary <string, object>();

            s.Position = 0x08;
            int keyTableStart   = s.readIntLE();
            int dataTableStart  = s.readIntLE();
            int numberOfEntries = s.readIntLE();

            for (int i = 0; i < numberOfEntries; ++i)
            {
                short keyRelativeOffset = s.readShortLE();
                int   keyOffset         = keyTableStart + keyRelativeOffset;

                short dataFormat      = s.readShortLE();
                int   dataUsedLength  = s.readIntLE();
                int   dataTotalLength = s.readIntLE();

                int dataRelativeOffset = s.readIntLE();
                int dataOffset         = dataTableStart + dataRelativeOffset;

                long originalPos = s.Position;

                s.Position = keyOffset;
                string key = s.readNullTerminatedString(Encoding.UTF8);

                s.Position = dataOffset;
                object value = null;
                switch (dataFormat)
                {
                case 0x0004:                         //utf8 special mode (not null terminated)
                    value = s.read(dataUsedLength, Encoding.UTF8);
                    break;

                case 0x0204:                         //utf8 (null terminated)
                    value = s.readNullTerminatedString(Encoding.UTF8, dataUsedLength);
                    break;

                case 0x0404:                         //int32
                    value = s.readIntLE();
                    break;

                default:
                    value = String.Format("Unknown format!!! 0x{0:X2}", dataFormat);
                    break;
                }
                if (!d.ContainsKey(key))
                {
                    d.Add(key, value);
                }
                //I guess I should report if there's a duplicate key but that shouldn't happen

                s.Position = originalPos;
            }

            return(d);
        }
Esempio n. 15
0
 public override void addROMInfo(ROMInfo info, ROMFile file, WrappedInputStream stream)
 {
     Megadrive.parseMegadriveROM(info, stream, true);
     //There's also a "MAIN SEGAOS" at 0x3000 followed by what appears to be some kind of title. Does that mean anything? I don't know
     //Some more info:
     //https://forums.sonicretro.org/index.php?showtopic=30588
     //https://segaretro.org/Sega_CD_programming_FAQ_(1998-12-06)
     //So 0x200 and beyond may have some kind of boot code which could then be checksummed to determine region, perhaps...
 }
Esempio n. 16
0
        public static FilesystemDirectory readGamecubeFS(WrappedInputStream s, int fstOffset, int fstSize, int virtualOffset)
        {
            FilesystemDirectory fs = new FilesystemDirectory {
                name = "GameCube Filesystem"
            };

            readRootFST(fs, s, fstOffset, fstSize, virtualOffset);
            return(fs);
        }
Esempio n. 17
0
        public static FilesystemDirectory readNitroFS(WrappedInputStream s, uint fatOffset, uint fatSize, uint fntOffset, uint fntSize)
        {
            //Number of directories = fnt[6], but we don't need that info
            FilesystemDirectory fs = new FilesystemDirectory {
                name = "NitroFS"
            };

            readNitroMainFNT(fs, s, fatOffset, fatSize, fntOffset, fntSize, 0);
            return(fs);
        }
Esempio n. 18
0
        private static void iterateRomFSEntry(WrappedInputStream s, FilesystemDirectory currentDirectory, byte[] metadataEntry, long directoryMetadataOffset, long fileMetadataOffset, long fileOffset)
        {
            uint firstChildDirectoryOffset = BitConverter.ToUInt32(metadataEntry, 8);
            uint firstFileOffset           = BitConverter.ToUInt32(metadataEntry, 12);

            if (firstChildDirectoryOffset != 0xffffffff)
            {
                s.Position = directoryMetadataOffset + firstChildDirectoryOffset;
                while (true)
                {
                    byte[] childDirectoryMetadata = s.read(24);
                    uint   nextSiblingDirectory   = BitConverter.ToUInt32(childDirectoryMetadata, 4);

                    uint   nameLength = BitConverter.ToUInt32(childDirectoryMetadata, 20);
                    string name       = s.read((int)nameLength, Encoding.Unicode);

                    FilesystemDirectory childDir = new FilesystemDirectory()
                    {
                        name = name
                    };
                    currentDirectory.addChild(childDir);
                    iterateRomFSEntry(s, childDir, childDirectoryMetadata, directoryMetadataOffset, fileMetadataOffset, fileOffset);

                    if (nextSiblingDirectory == 0xffffffff)
                    {
                        break;
                    }
                    s.Position = directoryMetadataOffset + nextSiblingDirectory;
                }
            }

            if (firstFileOffset != 0xffffffff)
            {
                s.Position = fileMetadataOffset + firstFileOffset;
                while (true)
                {
                    byte[] childFileMetadata = s.read(32);
                    uint   nextSiblingFile   = BitConverter.ToUInt32(childFileMetadata, 4);
                    ulong  childFileOffset   = BitConverter.ToUInt64(childFileMetadata, 8);
                    ulong  childFileSize     = BitConverter.ToUInt64(childFileMetadata, 16);

                    uint   nameLength = BitConverter.ToUInt32(childFileMetadata, 28);
                    string name       = s.read((int)nameLength, Encoding.Unicode);

                    currentDirectory.addChild(name, (long)childFileOffset + fileOffset, (long)childFileSize);

                    if (nextSiblingFile == 0xffffffff)
                    {
                        break;
                    }
                    s.Position = fileMetadataOffset + nextSiblingFile;
                }
            }
        }
Esempio n. 19
0
        static bool isD64Magic(WrappedInputStream stream)
        {
            if (stream.Length < 0x16500)
            {
                return(false);
            }
            stream.Position = 0x16500;
            byte[] magic = stream.read(4);

            //Actually, what we're really doing is checking that track and sector of first directory sector is 18 and 1 respectively and that Disk DOS version is 0x41. There's not really any magic here since it's a raw dump
            return(magic[0] == 18 && magic[1] == 01 && magic[2] == 0x41 && magic[3] == 00);
        }
Esempio n. 20
0
        public static void readWonderswanROM(ROMInfo info, ROMFile file)
        {
            WrappedInputStream s = file.stream;

            s.Seek(-10, System.IO.SeekOrigin.End);

            int publisher = s.read();

            info.addInfo("Publisher", publisher, PUBLISHERS);

            int  deviceFlag = s.read();
            bool isColor    = deviceFlag == 1;

            info.addInfo("Is colour", isColor);
            info.addInfo("Device type", deviceFlag, true); //This might have more to it, but probably not

            int cartID = s.read();                         //Last 2 digits of SKU

            info.addInfo("Product code", cartID);

            int version = s.read();

            info.addInfo("Version", version);

            int romSize = s.read();

            info.addInfo("ROM size", romSize, ROM_SIZES, ROMInfo.FormatMode.SIZE);

            int ramSize = s.read();

            info.addInfo("Save size", ramSize, RAM_SIZES, ROMInfo.FormatMode.SIZE);
            info.addInfo("Save type", ramSize >= 10 ? "EEPROM" : ramSize == 0 ? "None" : "SRAM");

            int flags = s.read();

            info.addInfo("Flags", flags, true);             //Maybe there are more flags than these three, probably not
            info.addInfo("ROM speed", (flags & 4) > 0 ? "3 speed" : "1 speed");
            info.addInfo("Bus width (bits)", (flags & 2) > 0 ? 16 : 8);
            info.addInfo("Screen orientation", (flags & 1) == 1 ? "Vertical" : "Horizontal");

            bool hasRTC = s.read() == 1;

            info.addInfo("Has RTC", hasRTC);

            ushort checksum = (ushort)s.readShortLE();

            info.addInfo("Checksum", checksum, ROMInfo.FormatMode.HEX, true);
            int calculatedChecksum = calcChecksum(s);

            info.addInfo("Calculated checksum", calculatedChecksum, ROMInfo.FormatMode.HEX, true);
            info.addInfo("Checksum valid?", checksum == calculatedChecksum);
        }
Esempio n. 21
0
        static short calcCRC16(WrappedInputStream s, long start, long end)
        {
            long pos = s.Position;

            try {
                s.Position = start;
                int    length = (int)((end - start) + 1);
                byte[] data   = s.read(length);
                return(CRC16.crc16(data));
            } finally {
                s.Position = pos;
            }
        }
Esempio n. 22
0
        public override bool shouldSkipHeader(ROMFile rom)
        {
            WrappedInputStream s = rom.stream;
            long pos             = s.Position;

            try {
                //I hope this doesn't result in false positives. Might be worth checking the file size modulo 64 or something clever like that? Not sure if that works
                string magic = s.read(4, Encoding.ASCII);
                return("LYNX".Equals(magic));
            } finally {
                s.Position = pos;
            }
        }
Esempio n. 23
0
        public override bool shouldSkipHeader(ROMFile rom)
        {
            WrappedInputStream s = rom.stream;
            long pos             = s.Position;

            try {
                s.Position = 1;
                string atari7800Magic = s.read(16, Encoding.ASCII);
                return("ATARI7800\0\0\0\0\0\0\0".Equals(atari7800Magic));
            } finally {
                s.Position = pos;
            }
        }
Esempio n. 24
0
        public static void parseGamecubeHeader(ROMInfo info, WrappedInputStream s)
        {
            string productCode = s.read(4, Encoding.ASCII);

            info.addInfo("Product code", productCode);
            char gameType = productCode[0];

            info.addInfo("Type", gameType, NintendoCommon.DISC_TYPES);
            string shortTitle = productCode.Substring(1, 2);

            info.addInfo("Short title", shortTitle);
            char country = productCode[3];

            info.addInfo("Country", country, NintendoCommon.COUNTRIES);

            string maker = s.read(2, Encoding.ASCII);

            info.addInfo("Publisher", maker, NintendoCommon.LICENSEE_CODES);

            int discNumber = s.read() + 1;             //Used for multi-disc games, but otherwise 0

            info.addInfo("Disc number", discNumber);

            int version = s.read();

            info.addInfo("Version", version);

            bool audioStreaming = s.read() > 0;

            info.addInfo("Audio streaming?", audioStreaming, true);

            int streamBufferSize = s.read();

            info.addInfo("Streaming buffer size", streamBufferSize, ROMInfo.FormatMode.SIZE, true);

            byte[] unused = s.read(14);
            info.addInfo("Unused", unused, true);

            byte[] wiiMagic = s.read(4);
            info.addInfo("Wii magic", wiiMagic, true);

            byte[] magic = s.read(4);
            info.addInfo("Magic", magic, true);

            info.addInfo("Platform", isGamecubeMagic(magic) ? "GameCube" : isWiiMagic(wiiMagic) ? "Wii" : "Unknown Nintendo optical disc-based system");

            string gameName = s.read(0x60, Encoding.ASCII).TrimEnd('\0');

            info.addInfo("Internal name", gameName);
        }
Esempio n. 25
0
        public static void parse64DDDiskInfo(ROMInfo info, WrappedInputStream s)
        {
            //The naming of this function is a solid argument for snake_case everywhere
            s.Position = 0x43670;             //I don't know why here, but it is

            string gameCode = s.read(4, Encoding.ASCII);

            info.addInfo("Product code", gameCode);
            char mediaType = gameCode[0];

            info.addInfo("Type", mediaType, N64_MEDIA_TYPES);
            string shortTitle = gameCode.Substring(1, 2);

            info.addInfo("Short title", shortTitle);
            char country = gameCode[3];

            info.addInfo("Country", country, NintendoCommon.COUNTRIES);

            int version = s.read();

            info.addInfo("Version", version);

            int diskNumber = s.read();

            info.addInfo("Disk number", diskNumber);

            int usesMFS = s.read();

            info.addInfo("Uses MFS", usesMFS != 0);

            int diskUse = s.read();

            info.addInfo("Disk use", diskUse);

            byte[] factoryLineNumber = s.read(8);
            //In BCD apparently
            info.addInfo("Factory line number", factoryLineNumber);

            byte[] productionTime = s.read(8);
            //BCD, but what format is it in even then? Is it a big ol' 64 bit timestamp?
            info.addInfo("Production time", productionTime);

            string companyCode = s.read(2, Encoding.ASCII);

            info.addInfo("Publisher", companyCode, NintendoCommon.LICENSEE_CODES);

            string freeArea = s.read(6, MainProgram.shiftJIS);

            info.addInfo("Memo", freeArea);
        }
Esempio n. 26
0
        public static void parseSDSCHeader(ROMInfo info, WrappedInputStream s)
        {
            int majorVersion = s.read();

            info.addInfo("Major version", decodeBCD(majorVersion));
            int minorVersion = s.read();

            info.addInfo("Minor version", decodeBCD(minorVersion));

            int day = decodeBCD(s.read());

            info.addInfo("Day", day);
            int month = decodeBCD(s.read());

            info.addInfo("Month", (month != 0 && month < 13) ? System.Globalization.DateTimeFormatInfo.CurrentInfo.GetMonthName(month) : String.Format("Unknown ({0})", month));
            int year = decodeBCD(s.read(2));

            info.addInfo("Year", year);

            try {
                info.addInfo("Date", new DateTime(year, month, day));
            } catch (ArgumentOutOfRangeException) {
                //Ignore
            }

            ushort authorNameOffset  = (ushort)s.readShortLE();
            ushort nameOffset        = (ushort)s.readShortLE();
            ushort descriptionOffset = (ushort)s.readShortLE();

            info.addInfo("Author offset", authorNameOffset, ROMInfo.FormatMode.HEX, true);
            info.addInfo("Name offset", nameOffset, ROMInfo.FormatMode.HEX, true);
            info.addInfo("Description offset", descriptionOffset, ROMInfo.FormatMode.HEX, true);

            if (authorNameOffset != 0xfff && authorNameOffset != 0)
            {
                s.Position = authorNameOffset;
                info.addInfo("Author", readNullTerminatedString(s));
            }
            if (nameOffset != 0xffff)
            {
                s.Position = nameOffset;
                info.addInfo("Internal name", readNullTerminatedString(s));
            }
            if (descriptionOffset != 0xffff)
            {
                s.Position = descriptionOffset;
                info.addInfo("Description", readNullTerminatedString(s));
            }
        }
Esempio n. 27
0
        public static Tuple <uint, uint> getFatInfo(WrappedInputStream s, uint fatOffset, ushort fileID)
        {
            long origPos = s.Position;

            try {
                s.Position = fatOffset + (fileID * 8);

                uint startOffset = (uint)s.readIntLE();
                uint endOffset   = (uint)s.readIntLE();
                uint size        = endOffset - startOffset;
                return(new Tuple <uint, uint>(startOffset, size));
            } finally {
                s.Position = origPos;
            }
        }
Esempio n. 28
0
        int calculateChecksum(WrappedInputStream f)
        {
            long origPos = f.Position;

            try {
                int x = 0;
                f.Position = 0xa0;
                while (f.Position <= 0xbc)
                {
                    x = (x - f.read()) & 0xff;
                }
                return((x - 0x19) & 0xff);
            } finally {
                f.Position = origPos;
            }
        }
Esempio n. 29
0
        public int calcChecksum(WrappedInputStream f)
        {
            int  x           = 0;
            long originalPos = f.Position;

            try {
                f.Position = 0x134;
                while (f.Position <= 0x14c)
                {
                    x = (((x - f.read()) & 0xff) - 1) & 0xff;
                }
            } finally {
                f.Position = originalPos;
            }
            return(x);
        }
Esempio n. 30
0
        public static int calcChecksum(WrappedInputStream s)
        {
            long pos = s.Position;
            long len = s.Length;

            try {
                s.Position = 0x200;
                int checksum = 0;
                while (s.Position < len)
                {
                    checksum = (checksum + s.readShortBE()) & 0xffff;
                }
                return(checksum);
            } finally {
                s.Position = pos;
            }
        }