Beispiel #1
0
        private void addArchiveException(object sender, ROMScanner.ExceptionEventArgs args)
        {
            var     row  = new ROMScanner.HaveRowEventArgs();
            ROMInfo info = new ROMInfo();

            row.info = info;

            try {
                info.addInfo("Filename", args.path.Name);
            } catch (Exception ex) {
                info.addInfo("Filename", "Exception: " + ex.ToString());
            }
            try {
                info.addInfo("Folder", args.path.DirectoryName);
            } catch (Exception ex) {
                //F**k you .NET these methods should not throw exceptions at all, let alone because a path dares to be longer than
                //260 characters. No seriously f**k you, that's f*****g stupid, f**k you and your stupid f*****g asinine operating
                //system and its f*****g idiotic limitations. F**k off I am not going to make all my users upgrade to Windows 10 and
                //tweak some group policy just so they can do things. F**k you, things clearly work with a f*****g network drive that
                //has paths that long so clearly Windows works with that shit anyway and you just f****d everything up because you're
                //a f*****g incompetent fuckload of assclowns and I hate you
                info.addInfo("Folder", "Exception: " + ex.ToString());
            }
            info.addInfo("Exception", args.ex);

            addRow(this, row);
        }
Beispiel #2
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", name);

            var s = file.stream;

            s.Position = 0x100;
            byte[] magic = s.read(4);
            if (isNCSDMagic(magic))
            {
                info.addInfo("Detected format", "NCSD");
                parseNCSD(info, file, true);
            }
            else if (isNCCHMagic(magic))
            {
                info.addInfo("Detected format", "NCCH");
                parseNCCH(info, file.stream, null);
            }
            else
            {
                s.Position = 0;
                magic      = s.read(4);
                if (is3DSXMagic(magic))
                {
                    info.addInfo("Detected format", "3DSX");
                    parse3DSX(info, file);
                }
            }
            //TODO CIA https://www.3dbrew.org/wiki/CIA
        }
Beispiel #3
0
 public override void addROMInfo(ROMInfo info, ROMFile file)
 {
     if ("bin".Equals(file.extension) || "rom".Equals(file.extension) || "car".Equals(file.extension))
     {
         byte[] magic = file.stream.read(4);
         if (isCARTMagic(magic))
         {
             info.addInfo("Detected format", "CART header");
             parseCART(info, file.stream);
         }
         else
         {
             //Well, nothing we can really do here, then
             info.addInfo("Platform", "Atari 8-bit");
             info.addInfo("Detected format", "Unheadered");
         }
     }
     else if ("atr".Equals(file.extension))
     {
         addATRInfo(info, file);
     }
     else
     {
         //TODO: Floppy images
         info.addInfo("Platform", "Atari 8-bit");
     }
 }
Beispiel #4
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);
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", "Atari 5200");
            var s = file.stream;

            s.Position = file.length - 3;

            bool skipLogo = s.read() == 0xff;             //Frogger does this, maybe some others. I guess this is the second digit of the year being set to 0xff?

            info.addInfo("Skip BIOS", skipLogo);
            short entryPoint = s.readShortLE();

            info.addInfo("Entry point", entryPoint, ROMInfo.FormatMode.HEX);

            if (!skipLogo)
            {
                s.Position = file.length - 24;
                //Copyright info is usually displayed on the screen, the BIOS displays a graphic from its own ROM and something like "TITLE\nCOPYRIGHT YEAR ATARI"
                //This can be used to get the name for our purposes, though it will be padded with @ (displays as blank I guess?) or null char to make it centred on screen
                string name = decodeAtari5200String(s.read(20));
                info.addInfo("Internal name", name);

                int yearFirstDigit  = s.read() - 0x50;
                int yearSecondDigit = s.read() - 0x50;

                //Nice Y2K bug m8
                info.addInfo("Year", 1900 + (yearFirstDigit * 10) + yearSecondDigit);
            }

            //TODO: BIOS disassemby also mentions something about PAL carts? I wasn't aware of any PAL carts or even PAL 5200 systems, so that's interesting if that actually exists; it seems that PAL carts have something different at xFE7
        }
Beispiel #7
0
        public static void addSupercardDS2PluginInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", "Supercard DSTwo");
            string iconFilename = System.IO.Path.ChangeExtension(file.name, "bmp");
            //The icon is actually pointed to in the .ini file, but it's in a native DS format (starts with fat1:/) so it won't be of any use unless running on an actual DSTwo. Luckily, the filename is always the same as the .plg but with a .bmp extension; and this is the kind of convention that nobody would dare break
            var icon = Image.FromStream(file.getSiblingFile(iconFilename));

            info.addInfo("Icon", icon);

            string iniFilename = System.IO.Path.ChangeExtension(file.name, "ini");

            using (var sr = new System.IO.StreamReader(file.getSiblingFile(iniFilename))) {
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    if (line.ToLowerInvariant().StartsWith("name="))
                    {
                        //Once again, not really internal. I kinda want to rename this column globally, it's already kinda wordy and a mouthful and I don't like that
                        info.addInfo("Internal name", line.Split('=')[1]);
                        break;
                    }
                }
            }
        }
Beispiel #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
        }
Beispiel #9
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)
        }
Beispiel #10
0
        static void addCartHardwareInfo(ROMInfo info, CartAdditionalHardware hardware, bool isOriginalFromGBX)
        {
            string prefix = isOriginalFromGBX ? "Original cart header claims to have " : "Has ";             //I should word that better, but whatevs

            info.addInfo(prefix + "RAM", hardware.HasFlag(CartAdditionalHardware.RAM), isOriginalFromGBX);
            info.addInfo(prefix + "battery", hardware.HasFlag(CartAdditionalHardware.Battery), isOriginalFromGBX);
            info.addInfo(prefix + "RTC", hardware.HasFlag(CartAdditionalHardware.RTC), isOriginalFromGBX);
            info.addInfo(prefix + "rumble", hardware.HasFlag(CartAdditionalHardware.Rumble), isOriginalFromGBX);
            info.addInfo(prefix + "accelerometer", hardware.HasFlag(CartAdditionalHardware.Accelerometer), isOriginalFromGBX);
        }
Beispiel #11
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
        }
Beispiel #12
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);
        }
Beispiel #13
0
        public static void parseArcadeInfo(ROMInfo info, ROMFile file, Stream xmlFile)
        {
            var xml        = XDocument.Load(xmlFile);
            var arcadeInfo = xml.Element("ArcadeInfo");

            info.addInfo("XDK version", arcadeInfo.Attribute("xdkVersion")?.Value);
            info.addInfo("Project version", arcadeInfo.Attribute("projectVersion")?.Value);

            foreach (var titleInfo in arcadeInfo.Elements("TitleInfo"))
            {
                parseTitleInfo(info, file, titleInfo);
            }
        }
Beispiel #14
0
 public override void addROMInfo(ROMInfo info, ROMFile file)
 {
     if (isSMD(file.stream))
     {
         info.addInfo("Detected format", "Super Magic Drive interleaved");
         parseMegadriveROM(info, decodeSMD(file.stream));
     }
     else
     {
         info.addInfo("Detected format", "Plain");
         parseMegadriveROM(info, file.stream);
     }
 }
Beispiel #15
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)
        }
Beispiel #16
0
        public static void parseRating(ROMInfo info, int rating, string name, IDictionary <int, string> dict, bool isDSi)
        {
            //Bit 5 is set for ESRB on Super Smash Bros Brawl (USA v1.01), Bomberman Blast (USA), and
            //Mario Strikers Charged
            //Possibly indicates online interactivity, e.g. the specific label "Online Interactions Not Rated by the ESRB" / "Game Experience May Change During Online Play"

            //Bit 6 is set for USK in Madworld (PAL), so it possibly indicates something
            //like "banned in this country" or "refused classification"; otherwise Madworld is parsed as being all ages in Germany which is absolutely not the case
            //It's also set on Gnubox GX, VBA GX and USBLoaderCFG channel forwarders, but those are homebrew, so it might be just invalid (they also set bit 5, and without those two
            //bits the rating is read as 10, which isn't a rating category for USK)

            //On 3DS, bit 6 indicates "Rating Pending" and bit 5 indicates No Age Restriction but that can't be right for Wii and probably not DSi

            //Wii U seems to set bit 6 on every single BBFC and reserved rating so maybe it's like "not used"

            if ((rating & 0x40) > 0)
            {
                info.addInfo(name + " bit 6", true);
            }
            if ((rating & 0x20) > 0)
            {
                info.addInfo(name + " bit 5", true);
            }

            bool ratingExists;

            if (isDSi)
            {
                ratingExists = (rating & 0x80) != 0;
            }
            else
            {
                ratingExists = (rating & 0x80) == 0;
            }

            if (ratingExists)
            {
                //Actual rating is bits 0-4
                int ratingValue = rating & 0x1f;
                if (dict != null)
                {
                    info.addInfo(name, ratingValue, dict);
                }
                else
                {
                    info.addInfo(name, ratingValue);
                }
            }
        }
Beispiel #17
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            //FIXME: Damn nothing matters anymore just refactor everything on the planet

            //.iso files are 2048 sectors, and since they're read as normal ROM files without any special handling in ROMScanner, we'll specify that sector size here; for cue sheets we've already read that so we just do the thing
            int sectorSize = 2048;

            if (file.cdSectorSize != 0)
            {
                sectorSize = file.cdSectorSize;
            }
            if (file.extension.Equals("img"))
            {
                sectorSize = 2352;
            }

            info.addInfo("Sector size", sectorSize);

            if (sectorSize == 2352)
            {
                addROMInfo(info, file, new CDInputStream(file.stream));
            }
            else
            {
                addROMInfo(info, file, file.stream);
            }
        }
Beispiel #18
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", "Konami Picno");

            var s = file.stream;

            //This is different than what you'd see on the box art and hence what is considered the "serial" as far as the software list is concerned. But similar, though. These start with ZPJ and the actual serials start with RX, but other than that, if the number is less than 100 you add 100 to it to get the actual serial, e.g. ZPJ006 (Anime Enikki) -> RX106, but ZPJ116 (Kanji Club) -> RX116.
            //The weird exception is Montage, which has ZPJ001 internally, but RX102 externally (RX101 is the undumped save card)
            string productCode = s.read(6, Encoding.ASCII);

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

            string name = s.read(10, Encoding.ASCII).TrimEnd('+');             //Yeah, plus signs. I don't make the rules

            info.addInfo("Internal name", name);
        }
Beispiel #19
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));
        }
Beispiel #20
0
 public override void addROMInfo(ROMInfo info, ROMFile file)
 {
     info.addInfo("Platform", "Xbox");
     if ("xbe".Equals(file.extension))
     {
         parseXBE(info, file.stream);
     }
 }
Beispiel #21
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", name);

            WrappedInputStream s = file.stream;

            int headerSize = s.readIntBE();

            info.addInfo("Header size", headerSize, ROMInfo.FormatMode.SIZE, true);

            byte[] wadType = s.read(4);
            info.addInfo("WAD type", wadType, true);             //Can be either Is, ib or Bk with by two nulls, but what does it mean?
            info.addInfo("WAD type ASCII", Encoding.ASCII.GetString(wadType), true);

            int certChainSize = s.readIntBE();

            info.addInfo("Certificate chain size", certChainSize, true);

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

            int ticketSize = s.readIntBE();

            info.addInfo("Ticket size", ticketSize, ROMInfo.FormatMode.SIZE, true);

            int tmdSize = s.readIntBE();

            info.addInfo("TMD size", tmdSize, ROMInfo.FormatMode.SIZE, true);

            int dataSize = s.readIntBE();

            info.addInfo("Data size", dataSize, ROMInfo.FormatMode.SIZE, true);

            int footerSize = s.readIntBE();

            info.addInfo("Footer size", footerSize, ROMInfo.FormatMode.SIZE, true);

            s.Position = 0x40;             //All blocks are stored in the order of their sizes in the header, and aligned to 0x40 bytes, we've just read the header of course

            //TODO: Read certificate chain and ticket
            s.Seek(roundUpToMultiple(certChainSize, 0x40), System.IO.SeekOrigin.Current);
            s.Seek(roundUpToMultiple(ticketSize, 0x40), System.IO.SeekOrigin.Current);

            byte[] tmd = s.read(roundUpToMultiple(tmdSize, 0x40));
            parseTMD(info, tmd);
        }
Beispiel #22
0
 public override void addROMInfo(ROMInfo info, ROMFile file)
 {
     info.addInfo("Platform", "Wii U");
     if ("rpx".Equals(file.extension))
     {
         addRPXInfo(info, file);
     }
 }
Beispiel #23
0
        public static void parseSegaHeader(ROMInfo info, WrappedInputStream s, long offset, bool isGameGear)
        {
            s.Position = offset;

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

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

            info.addInfo("Checksum", checksum, ROMInfo.FormatMode.HEX, true);

            byte[] productCodeHi         = s.read(2);
            int    productCodeAndVersion = s.read();
            int    productCodeLo         = (productCodeAndVersion & 0xf0) >> 4;
            int    version = productCodeAndVersion & 0x0f;

            string productCode = String.Format("{0}{1:0000}", productCodeLo == 0 ? "" : productCodeLo.ToString(), decodeBCD(productCodeHi));

            info.addInfo("Product code", productCode);
            if (isGameGear)
            {
                if (productCode.Length >= 5)
                {
                    string makerCode = "T-" + productCode.Substring(0, productCode.Length - 3);
                    info.addInfo("Publisher", makerCode, SegaCommon.LICENSEES);
                }
                else
                {
                    info.addInfo("Publisher", "Sega");
                }
            }
            info.addInfo("Version", version);

            int regionCodeAndROMSize = s.read();
            int regionCode           = (regionCodeAndROMSize & 0xf0) >> 4;
            int romSize = regionCodeAndROMSize & 0x0f;

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

            ushort calculatedChecksum = calculateChecksum(s, romSize);

            info.addInfo("Calculated checksum", calculatedChecksum, ROMInfo.FormatMode.HEX, true);
            info.addInfo("Checksum valid?", checksum == calculatedChecksum);
        }
Beispiel #24
0
 public override void addROMInfo(ROMInfo info, ROMFile file)
 {
     info.addInfo("Platform", "PlayStation Portable");
     if ("pbp".Equals(file.extension))
     {
         parsePBP(info, file.stream);
     }
     //.iso will be done later
 }
Beispiel #25
0
        static void addCartTypeInfo(ROMInfo info, int cartType, bool isOriginalFromGBX)
        {
            //isOriginalFromGBX = is this info we're adding from the original header of a GBX dump, where it is likely inaccurate and
            //the info in the GBX footer is what should actually be looked at, as such, we adjust the key we're adding
            //Anyway, I suck at wording things, so I'm just gonna make this up as I go along
            string mapperKey = isOriginalFromGBX ? "Original header mapper" : "Mapper";

            if (CART_TYPES.ContainsKey(cartType))
            {
                CartInfo cart = CART_TYPES[cartType];
                info.addInfo(mapperKey, cart.mapper, isOriginalFromGBX);
                addCartHardwareInfo(info, cart.flags, isOriginalFromGBX);
            }
            else
            {
                info.addInfo(mapperKey, String.Format("Unknown (0x{0:X2})", cartType), isOriginalFromGBX);
            }
        }
Beispiel #26
0
 public static void parseXEXFlags(ROMInfo info, uint flags)
 {
     info.addInfo("Title module", (flags & 1) > 0);
     info.addInfo("Exports to title", (flags & 2) > 0);
     info.addInfo("System debugger", (flags & 4) > 0);
     info.addInfo("DLL module", (flags & 8) > 0);
     info.addInfo("Module patch", (flags & 16) > 0);
     info.addInfo("Full patch", (flags & 32) > 0);
     info.addInfo("Delta patch", (flags & 64) > 0);
     info.addInfo("User mode", (flags & 128) > 0);
 }
Beispiel #27
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            var s = file.stream;

            info.addInfo("Platform", name);

            byte[] cartCheck = s.read(2);
            bool   skipBIOS  = cartCheck[0] != 0xAA && cartCheck[1] != 0x55;

            if (!skipBIOS)
            {
                s.Position = 0x24;
                string   title      = s.read(60, Encoding.ASCII);
                string[] titleLines = title.Split('/');

                titleLines[0] = truncate(titleLines[0], 28);
                titleLines[1] = truncate(titleLines[1], 28);
                titleLines[2] = truncate(titleLines[2], 4);

                if (Regex.IsMatch(titleLines[0], @"^\x1d\s?\d+"))
                {
                    //According to the manual you are supposed to not do this, but you dang bet companies did it
                    //Sometimes, anyway
                    //This heuristic doesn't always work and such you end up with the two lines being... well, not swapped around, but I end up parsing them as meaning what they don't actually mean, if that makes sense
                    //I guess I shouldn't really do this
                    info.addInfo("Internal name", titleLines[1].Replace('\x1d', '©'));
                    info.addInfo("Copyright", titleLines[0].Replace('\x1d', '©'));
                }
                else
                {
                    info.addInfo("Internal name", titleLines[0].Replace('\x1d', '©'));
                    info.addInfo("Copyright", titleLines[1].Replace('\x1d', '©'));

                    var matches = Regex.Match(titleLines[1], @"^PRESENTS (.+)'S$");
                    if (matches.Success)
                    {
                        //This seems ugly, but it's not really wrong
                        info.addInfo("Publisher", matches.Groups[1]);
                    }
                }

                if (int.TryParse(titleLines[2], out int year))
                {
                    info.addInfo("Year", year);                     //Add it as an int if we can, just in case one day I decide to do something where type matters
                }
                else
                {
                    info.addInfo("Year", titleLines[2]);
                }
            }
        }
Beispiel #28
0
        public static void addAtariDOS2(ROMInfo info, List <byte[]> sectors)
        {
            var fs = new FilesystemDirectory()
            {
                name = "Atari DOS2",
            };

            //Sectors 1 and 3 have boot record but nobody tells me what that does
            if (sectors.Count <= 359)
            {
                info.addInfo("Has files", false);
                return;
            }
            byte[] vtoc = sectors[359];             //#TODO: VTOC2 if disk is big enough
            info.addInfo("Number of free sectors", vtoc[3]);

            bool hasFiles = false;

            for (int i = 360; i < 368; ++i)
            {
                byte[] sector = sectors[i];
                //Flags = sector[0]
                for (int j = 0; j < 8; ++j)
                {
                    byte[] fileHeader = sector.Skip(16 * j).Take(16).ToArray();
                    if (fileHeader.All(b => b == 0))
                    {
                        continue;
                    }
                    hasFiles = true;
                    short  sectorsInFile  = (short)(fileHeader[1] | (fileHeader[2] << 8));
                    short  startingSector = (short)(fileHeader[3] | (fileHeader[4] << 8));
                    string filename       = Encoding.ASCII.GetString(fileHeader.Skip(5).Take(8).ToArray()).TrimEnd();
                    string extension      = Encoding.ASCII.GetString(fileHeader.Skip(13).Take(3).ToArray()).TrimEnd();
                    //TODO: Actually get the offset and size of the file
                    fs.addChild(filename + "." + extension, 0, 0);
                }
            }
            info.addInfo("Has files", hasFiles);
            info.addFilesystem(fs);
        }
Beispiel #29
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            info.addInfo("Platform", "e-Reader");
            if ("raw".Equals(file.extension))
            {
                byte[] data = uninterleaveRawFile(info, file);
                parseUninterleavedData(info, data);
                return;
            }

            //Not sure how we'd handle .bin yet. However, most dumps are .raw instead, so it should be fine
        }
Beispiel #30
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);
        }