示例#1
0
        // gathered enough data, let's go
        static bool BuildROMS()
        {
            // how big is our output array?
            uint finalSize = HEADER_SIZE;              //8kb

            // add the ROM files too..
            for (int i = 0; i < roms.Count; i++)
            {
                finalSize += roms[i].paddedLength;
            }

            Console.WriteLine("\nBuilding index...\n");

                        #if DEBUG_ARGS
            Console.WriteLine("\n Final Size: " + finalSize + " (0x" + finalSize.ToString("X8") + ")\n");
                        #endif

            // Not going to use a binary writer here to keep the code as portable as possible

            byte[] writeBytes = new byte[finalSize];

            // Better keeping separate vars for both than inlining it
            // for debugging
            uint headerOffset = 0;
            uint dataOffset   = 0;

            for (int i = 0; i < roms.Count; i++)
            {
                ROMEntry rom = roms[i];

                // 0x00 to 0x10 -> Header
                headerOffset = WriteLittleEndian(rom.actualLength, writeBytes, headerOffset);
                headerOffset = WriteLittleEndian(rom.offset, writeBytes, headerOffset);
                headerOffset = WriteLittleEndian(rom.checkSum, writeBytes, headerOffset);
                headerOffset = WriteLittleEndian(0, writeBytes, headerOffset);

                // name stored in the rom?
                string nameSource = useInternalNameSort ? rom.internalName : rom.fileName;

                // 45 chars for description, pad with 0's after we read past the length
                for (int b = 0; b < FILENAME_LIMIT; b++)
                {
                    writeBytes[headerOffset++] = (b < nameSource.Length) ? (byte)nameSource[b] : (byte)0;
                }
                // 3 final zeros
                writeBytes[headerOffset++] = 0;
                writeBytes[headerOffset++] = 0;
                writeBytes[headerOffset++] = 0;

                dataOffset = rom.offset;
                // and write the file
                for (int b = 0; b < rom.paddedLength; b++)
                {
                    if (b < rom.actualLength)
                    {
                        writeBytes[dataOffset + b] = rom.paddedData[b];
                    }
                    else
                    {
                        // could write zero, but c# inits to 0 anyway
                    }
                }
            }

            // this is not time-traveller-proof
            TimeSpan startSpan    = (DateTime.UtcNow - new DateTime(1970, 1, 1));          // shortest way to represent the epoch?
            double   lastReadTime = startSpan.TotalSeconds;

            if (File.Exists(targetFilename))
            {
                PrintWarning("Filename already exists: " + targetFilename);

                try{
                    if (File.Exists(targetFilename + "_BACKUP"))
                    {
                        File.Delete(targetFilename + "_BACKUP");
                    }

                    File.Move(targetFilename, targetFilename + "_BACKUP");
                    PrintWarning("Renamed " + targetFilename + " to " + targetFilename + "_BACKUP");
                } catch (System.Exception e) {
                    PrintWarning("Could not rename the existing file... " + e);
                    targetFilename += lastReadTime + ".DAT";
                    PrintWarning("Using alternate filename: " + targetFilename);
                }
            }

            try{
                File.WriteAllBytes(targetFilename, writeBytes);
            } catch (Exception e) {
                PrintError("Error writing to disk: " + e);
                return(false);
            }

            if (numWarnings > 0)
            {
                Console.Write("\n\n Build completed successfully with warnings!\n\n");
                WaitKey();
            }
            else
            {
                Console.Write("\n\n Build completed successfully with no warnings!\n\n");
            }

            return(true);
        }
示例#2
0
        static bool VerifyROMS()
        {
            // Get a list of .ROM files + Verify
            string currentDirectory = "";

            try{
                currentDirectory = Directory.GetCurrentDirectory();
            } catch (Exception e) {
                // UnathorisedAccessException or NotSupportedException officially
                // but best to print it anyway.
                PrintError("Exception: " + e);
                return(false);
            }

            // instead of maintaining separate arrays, let's stick it in a list
            // and cross them off one by one
            romFileNames = new List <string>();

            try{
                // C# really spoils us sometimes...
                romFileNames = Directory.GetFiles(currentDirectory).OrderByDescending(f => f).ToList <string>();
            } catch (Exception e) {
                // Again, a bunch of possible errors, but given
                // the low importance, let's just print it and move on.
                PrintError("Exception " + e);
                return(false);
            }

            // Filter by extension
            // Todo: add .bin?

            for (int i = romFileNames.Count - 1; i >= 0; i--)
            {
                if (!romFileNames[i].ToUpperInvariant().EndsWith(".ROM"))
                {
                    romFileNames.RemoveAt(i);
                    continue;
                }

                Console.WriteLine("Found: " + Path.GetFileNameWithoutExtension(romFileNames[i]));
            }

            if (romFileNames.Count == 0)
            {
                PrintError("Didn't find any ROMs!");
                return(false);
            }
            if (romFileNames.Count > 128)
            {
                PrintError("Sorry, the limit is 128 ROM files!");
                return(false);
            }

            // Init the list of byte arrays
            roms = new List <ROMEntry>();

            // we can keep a running tally of this now
            UInt32 romOffset = HEADER_SIZE;

            // Filter by what is actually a ROM
            // since we're already opening them to check, hold them in RAM
            for (int i = romFileNames.Count - 1; i >= 0; i--)
            {
                Console.WriteLine("\nChecking: " + romFileNames[i]);

                byte[] romData;

                try{
                    romData = File.ReadAllBytes(romFileNames[i]);
                } catch (Exception e) {
                    PrintError("Exception reading file: " + romFileNames[i]);
                    PrintError("The exception returned was: " + e);
                    PrintError("Skipping that file...");
                    continue;
                }

                // let's verify the header
                // the first header is optional at 0x04, the original romfile.exe did not take account of this
                // instead we'll be using the second header at 0x84 - 0xB0 (exclusive)
                // which should read "Licensed by Sony Computer Entertainment Inc."
                // checksum it.

                // technically there could be code in just the header gaps
                // nocash has put code there, paul, and smartcart patches like Ahoy too
                if (romData.Length < 0xB0)
                {
                    PrintError("Not a valid rom! " + romFileNames[i]);
                    continue;
                }

                UInt32 paddedLength = (uint)romData.Length;
                if (romData.Length % SECTOR_SIZE > 0)
                {
                    paddedLength += SECTOR_SIZE - (paddedLength % SECTOR_SIZE);
                    Console.WriteLine("padding size from " + romData.Length.ToString("X") + " to " + paddedLength.ToString("X"));
                }

                UInt32 licenseChecksum = 0;
                UInt32 romChecksum     = 0;
                for (int b = 0; b < romData.Length; b++)
                {
                    if (b >= 0x84 && b < 0xB0)
                    {
                        licenseChecksum += romData[b];
                    }
                    romChecksum += romData[b];;
                }

                bool normalByteOrder  = (licenseChecksum == 0x1040);
                bool reverseByteOrder = (licenseChecksum == 0x1498);

                if (normalByteOrder || reverseByteOrder)
                {
                    Console.WriteLine("Checksum " + licenseChecksum.ToString("X") + " reversed?=" + reverseByteOrder);
                }
                else
                {
                    PrintWarning("Could not find the license string!");
                    continue;
                }



                                #if DEBUG_ARGS
                Console.WriteLine("    File checksum is 0x" + licenseChecksum.ToString("X8"));
                                #endif

                // So not portable,but look how neat it is.
                string fileName = Path.GetFileNameWithoutExtension(romFileNames[i]);
                fileName = fileName.Replace("[!]", "");                         // For SquareSoft74's sanity
                fileName = fileName.Substring(0, Math.Min(FILENAME_LIMIT, fileName.Length));


                string internalName = GetInternalName(fileName, romData, reverseByteOrder);
                internalName = internalName.Substring(0, Math.Min(FILENAME_LIMIT, internalName.Length));

                // not a fan of this setup as it makes searching for ".fileName" a little
                // awkward, but equally I hate huge constructors. Thoughts?
                ROMEntry rom = new ROMEntry()
                {
                    actualLength = (UInt32)romData.Length,
                    offset       = romOffset,                // haven't sorted the list so we don't know this yet
                    checkSum     = romChecksum,

                    paddedData   = romData,
                    paddedLength = paddedLength,

                    fileName     = fileName,
                    internalName = internalName
                };

                romOffset += paddedLength;
                roms.Add(rom);
            }

            if (roms.Count == 0)
            {
                PrintError("None of those ROMs were valid!");
                return(false);
            }

            return(true);
        }