Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
 static void parseRatings(ROMInfo info, XElement doc)
 {
     foreach (var kv in RATING_TAGS)
     {
         var ratingElement = doc.Element(kv.Key);
         if (ratingElement != null)
         {
             int    ratingValue = int.Parse(ratingElement.Value);
             string ratingName  = kv.Value.Item1;
             var    ratingDict  = kv.Value.Item2;
             NintendoCommon.parseRating(info, ratingValue, ratingName, ratingDict, false);
         }
     }
 }
Ejemplo n.º 3
0
        public static void parseTMD(ROMInfo info, byte[] tmd)
        {
            WrappedInputStream s = new WrappedInputStream(new System.IO.MemoryStream(tmd))
            {
                Position = 0x184
            };

            byte[] iosVersion = s.read(8);
            info.addInfo("IOS version", iosVersion, true);

            byte[] titleID = s.read(4);
            //The one and only documentation says this is 8 bytes, but that doesn't seem to work as there's 4 weird bytes at the front
            //This might be the type actually (game = 0x10000, channel = 0x10001, etc)
            info.addInfo("Title ID unknown", titleID, true);

            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);

            int titleFlags = s.readIntBE();

            info.addInfo("Title flags", titleFlags, true);
            info.addInfo("Is official", (titleFlags & 1) == 1);   //Hmmmmmm

            string maker = s.read(2, Encoding.ASCII);             //Documentation calls this "Group ID" for some reason

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

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

            short regionCode = s.readShortBE();

            info.addInfo("Region", regionCode, NintendoCommon.REGIONS);

            byte[] ratings = s.read(16);
            NintendoCommon.parseRatings(info, ratings, false);

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

            byte[] ipcMask = s.read(12);             //The heck is that
            info.addInfo("IPC mask", ipcMask, true);

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

            byte[] accessRights = s.read(4);
            info.addInfo("Access rights", accessRights, true);             //How do I interpret these?

            short version = s.readShortBE();

            info.addInfo("Version", version);
        }
Ejemplo n.º 4
0
        public static void parseSMDH(ROMInfo info, WrappedInputStream s, string prefix, long offset = 0)
        {
            s.Position = offset + 4;
            short version = s.readShortLE();

            info.addInfo("SMDH version", version);

            s.Position = offset + 8;

            for (int i = 0; i < 16; ++i)
            {
                byte[] shortNameBytes = s.read(0x80);
                if (shortNameBytes.All(b => b == 0))
                {
                    s.Seek(0x180, SeekOrigin.Current);
                    continue;
                }

                string shortName     = Encoding.Unicode.GetString(shortNameBytes).TrimEnd('\0').Replace("\n", Environment.NewLine);
                string longName      = s.read(0x100, Encoding.Unicode).TrimEnd('\0').Replace("\n", Environment.NewLine);
                string publisherName = s.read(0x80, Encoding.Unicode).TrimEnd('\0').Replace("\n", Environment.NewLine);

                string key = combinePrefix(prefix, titleLanguages[i], true);
                info.addInfo(key + " short name", shortName);
                info.addInfo(key + " long name", longName);
                info.addInfo(key + " publisher name", publisherName);
            }

            byte[] ratings = s.read(16);
            NintendoCommon.parseRatings(info, ratings, true);

            int region = s.readIntLE();

            if (region == 0x7fffffff)
            {
                info.addInfo(combinePrefix(prefix, "Region"), "Region free");
            }
            else
            {
                info.addInfo(combinePrefix(prefix, "Region"), Enum.ToObject(typeof(RegionFlags), region).ToString());
            }

            //Stuff used in online connectivity
            byte[] matchMakerID    = s.read(4);
            byte[] matchMakerBitID = s.read(8);
            info.addInfo(combinePrefix(prefix, "Match maker ID"), matchMakerID, true);
            info.addInfo(combinePrefix(prefix, "Match maker BIT ID"), matchMakerBitID, true);

            int flags = s.readIntLE();

            info.addInfo(combinePrefix(prefix, "Visible on Home Menu"), (flags & 1) > 0);
            info.addInfo(combinePrefix(prefix, "Auto-boot"), (flags & 2) > 0);
            info.addInfo(combinePrefix(prefix, "Uses 3D"), (flags & 4) > 0);             //For parental controls use, doesn't actually stop an application using 3D
            info.addInfo(combinePrefix(prefix, "Requires EULA"), (flags & 8) > 0);
            info.addInfo(combinePrefix(prefix, "Autosave on exit"), (flags & 16) > 0);
            info.addInfo(combinePrefix(prefix, "Uses extended banner"), (flags & 32) > 0);
            info.addInfo(combinePrefix(prefix, "Region rating required"), (flags & 64) > 0);            //weh
            info.addInfo(combinePrefix(prefix, "Warn about save data"), (flags & 128) > 0);             //Just changes the warning when closing an application to "Do you want to close blah (Unsaved data will be lost.)"
            info.addInfo(combinePrefix(prefix, "Record application usage"), (flags & 256) > 0);         //This is unset on developer/customer service tools to stop them showing up in the activity log, apparently
            info.addInfo(combinePrefix(prefix, "Disable SD card save backup"), (flags & 1024) > 0);
            info.addInfo(combinePrefix(prefix, "New 3DS exclusive"), (flags & 4096) > 0);

            int eulaMajorVersion = s.read();
            int eulaMinorVersion = s.read();

            info.addInfo("EULA version", eulaMajorVersion + "." + eulaMinorVersion);

            s.Position = offset + 0x2034;
            byte[] cecID = s.read(4);
            info.addInfo("CEC (StreetPass) ID", cecID);

            s.Position = offset + 0x2040;
            byte[] iconData      = s.read(0x480);
            byte[] largeIconData = s.read(0x1200);
            info.addInfo("Small icon", decodeIcon(iconData, 24, 24));
            info.addInfo("Icon", decodeIcon(largeIconData, 48, 48));
        }
Ejemplo n.º 5
0
        public override void addROMInfo(ROMInfo info, ROMFile file)
        {
            WrappedInputStream s = file.stream;

            Gamecube.parseGamecubeHeader(info, s);

            s.Position = 0x40000;

            int  totalPartitions = 0;
            bool containsUpdate  = false;
            int  partitionIndex  = 0;

            for (int partitionGroup = 0; partitionGroup < 4; ++partitionGroup)
            {
                int partitions = s.readIntBE();
                totalPartitions += partitions;

                int partitionInfoOffset = s.readIntBE() << 2;
                for (int i = 0; i < partitions; ++i)
                {
                    long pos = s.Position;
                    try {
                        s.Position = partitionInfoOffset + (i * 8) + 4;

                        byte[] partitionType = s.read(4);
                        string type;
                        if (partitionType[0] == 0)
                        {
                            if (partitionType[3] == 0)
                            {
                                type = "Game data";
                            }
                            else if (partitionType[3] == 1)
                            {
                                containsUpdate = true;
                                type           = "Update";
                            }
                            else if (partitionType[3] == 2)
                            {
                                type = "Channel";
                            }
                            else
                            {
                                type = String.Format("Unknown ({0})", partitionType[3]);
                            }
                        }
                        else
                        {
                            type = Encoding.ASCII.GetString(partitionType);
                        }
                        info.addInfo(String.Format("Partition {0} type", partitionIndex), type, true);
                        //TODO: Read TMD from partition
                    } finally {
                        s.Position = pos;
                    }
                    ++partitionIndex;
                }
            }
            info.addInfo("Number of partitions", totalPartitions);
            info.addInfo("Contains update partition", containsUpdate);

            s.Position = 0x4e000;
            int region = s.readIntBE();

            info.addInfo("Region", region, NintendoCommon.REGIONS);

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

            byte[] ratings = s.read(16);
            NintendoCommon.parseRatings(info, ratings, false);
        }