Ejemplo n.º 1
0
        public static uint ComputeCueCrc(CueSheet cue)
        {
            if (!cue.HasDataTrack())
            {
                throw new Exception("Audio only CDs are not supported for hashing");
            }

            var track = cue.FindFirstDataTrack();

            FileStream   fs     = new FileStream(track.FileName, FileMode.Open, FileAccess.Read);
            BinaryReader reader = new BinaryReader(fs);

            fs.Seek(track.FileOffset, SeekOrigin.Begin);

            int  numsects = 20;
            uint crcAccum = 0xFFFFFFFF;

            for (int i = 0; i < numsects; ++i)
            {
                byte[] data;
                if (track.SectorSize == CueSheet.SectorSize._2352)
                {
                    reader.ReadBytes(16);
                    data = reader.ReadBytes(2048);
                    reader.ReadBytes(288);
                }
                else
                {
                    data = reader.ReadBytes(2048);
                }

                if (i == 0)                  //check signature
                {
                    if (data[0] != 0x82 || data[1] != 0xB1 || data[2] != 0x82 || data[3] != 0xCC || data[4] != 0x83 || data[5] != 0x76 || data[6] != 0x83 || data[7] != 0x8D)
                    {
                        //Debug.Assert(false);
                        //Console.WriteLine("Err\n");
                    }
                }

                crcAccum = Crc32.ComputeStep(crcAccum, data);
            }

            crcAccum = Crc32.Finalize(crcAccum);

            reader.Close();
            fs.Close();

            return(crcAccum);
        }
Ejemplo n.º 2
0
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofn = new OpenFileDialog();

            ofn.CheckPathExists = true;
            ofn.Multiselect     = false;
            ofn.Filter          = "HuCard Files (*.pce)|*.pce|CDRom cuesheets (*.cue)|*.cue";

            if (ofn.ShowDialog() == DialogResult.OK)
            {
                uint crc;
                if (ofn.FileName.EndsWith(".pce", StringComparison.InvariantCultureIgnoreCase))
                {
                    var data = File.ReadAllBytes(ofn.FileName);

                    if ((data.Length & 0xFFF) != 0)
                    {
                        uint l = (uint)data.Length & 0xFFFFF000;

                        var dat = new byte[l];
                        Array.Copy(data, data.Length & 0xFFF, dat, 0, l);

                        data = dat;

                        crc = Crc32.Compute(data);
                    }
                    else
                    {
                        crc = Crc32.Compute(data);
                    }
                }
                else if (ofn.FileName.EndsWith(".cue", StringComparison.InvariantCultureIgnoreCase))
                {
                    var cue = new CueSheet(ofn.FileName);
                    crc = GameDBMgr.ComputeCueCrc(cue);
                }
                else
                {
                    MessageBox.Show("Invalid file extension");
                    return;
                }

                //Check if the crc already exists
                String crcstr = crc.ToString("X8");
                var    ck     = gameDB.GameCk.FirstOrDefault(x => x.Checksum == crcstr);
                if (ck != null)
                {
                    if (ck.GameID == gameID)
                    {
                        MessageBox.Show("This checksum already exists for this game");
                    }
                    else
                    {
                        MessageBox.Show("This checksum already exists for a different game!!");
                    }
                }
                else
                {
                    ck          = gameDB.GameCk.NewGameCkRow();
                    ck.GameID   = gameID;
                    ck.Checksum = crcstr;

                    gameDB.GameCk.AddGameCkRow(ck);
                }
            }
        }
Ejemplo n.º 3
0
        static void ScanDir(String dir, GameDB db, GameDBMgr form)
        {
            Game[] games;
            byte[] scshots;
            ushort sccnt;
            ushort gamecnt;
            int    crptBlock;

            gamecnt   = 0;
            sccnt     = 0;
            crptBlock = 0;
            games     = new Game[1024];
            scshots   = new Byte[1024 * 3072];

            if (form != null)
            {
                form.Invoke(new Action(() =>
                {
                    form.label1.Text = Path.GetFileName(dir);
                }));
            }
            else
            {
                Console.WriteLine("Processing directory " + Path.GetFileName(dir));
            }


            foreach (var f in Directory.GetFiles(dir, "*.pce"))
            {
                var data = File.ReadAllBytes(f);

                var crc = Crc32.Compute(data);

                var ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));

                if (ck == null && (data.Length & 0xFFF) != 0)
                {
                    uint l = (uint)data.Length & 0xFFFFF000;

                    var dat = new byte[l];
                    Array.Copy(data, data.Length & 0xFFF, dat, 0, l);

                    data = dat;

                    crc = Crc32.Compute(data);

                    ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));
                }

                if (ck != null)
                {
                    //var namecrc = Crc32.Compute(Encoding.ASCII.GetBytes(f.Substring(f.LastIndexOf('\\') + 1)));
                    var nn = f.Substring(f.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                    nn = nn.Substring(0, nn.LastIndexOf('.'));

                    var    name    = Encoding.ASCII.GetBytes(nn);
                    byte[] namecnv = new byte[56];

                    if (name.Length > 56)
                    {
                        Array.Copy(name, namecnv, 56);
                    }
                    else
                    {
                        Array.Copy(name, namecnv, name.Length);
                    }

                    for (int i = 0; i < namecnv.Length; ++i)
                    {
                        namecnv[i] = ProcessChar(namecnv[i]);
                    }

                    var namecrc = Crc32.update_crc(0xFFFFFFFF, namecnv, 56);

                    var existing = games.Take(gamecnt).FirstOrDefault(x => x.checksum != 0 && x.GameID == ck.GameID);

                    if (existing != null)
                    {
                        var g = new Game();
                        g.checksum   = namecrc;
                        g.remap      = existing.remap;
                        g.GameID     = existing.GameID;
                        g.TextName   = existing.TextName;
                        g.ScreenName = existing.ScreenName;

                        games[gamecnt] = g;
                        ++gamecnt;
                    }
                    else
                    {
                        var gg = db.Game.FirstOrDefault(x => x.ID == ck.GameID);

                        if (gg != null && !gg.IsScreenshotNull())
                        {
                            //String dst = "TileCache/" + gg.Screenshot.Substring(gg.Screenshot.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                            string dst = "TileCache/" + gg.Screenshot.Replace("\\", "_").Replace("/", "_").Replace(":", "_");

                            dst = dst.Replace(".png", ".tile");

                            if (File.Exists(dst))
                            {
                                var g = new Game();
                                g.checksum   = namecrc;
                                g.remap      = sccnt;
                                g.GameID     = ck.GameID;
                                g.TextName   = gg.Name;
                                g.ScreenName = gg.Screenshot;

                                games[gamecnt] = g;
                                ++gamecnt;

                                //copy screenshot to the scshot block
                                byte[] scshot = File.ReadAllBytes(dst);

                                byte[] scshot2 = new byte[3072];
                                Array.Copy(scshot, scshot2, scshot.Length);

                                //add year, genre...
                                scshot2[0xA00] = 0x0;                                   //version
                                if (!gg.IsGenreNull())
                                {
                                    scshot2[0xA01] = (byte)gg.Genre;
                                }

                                if (!gg.IsYearNull())
                                {
                                    scshot2[0xA02] = (byte)(gg.Year & 0xFF);
                                    scshot2[0xA03] = (byte)((gg.Year >> 8) & 0xFF);
                                }

                                Debug.Assert(scshot2.Length == 3072);
                                Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                // The issue is there is a sequence of screenshot indexes that the lookup fails to
                                // resolve to the right location displaying junk data as the screenshot
                                // This is the sequence
                                // Index:  0  21  42  64  85  106  128  149  170  192
                                // Spacing: 21  21  22  21  21   22   21   21   22   ...
                                //
                                // A repeating pattern of 21, 21, 22...
                                if (((sccnt - crptBlock) % 21 == 0) && ((sccnt + 1) % 64 != 0))
                                {
                                    // true
                                    Console.WriteLine("Corrupted Index Skipped: {0}", sccnt);

                                    sccnt++;
                                    games[gamecnt - 1].remap = sccnt;
                                    Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);
                                }
                                else if (sccnt % 64 == 0)
                                {
                                    // true
                                    Console.WriteLine("Corrupted Index Skipped: {0}", sccnt);

                                    sccnt++;
                                    games[gamecnt - 1].remap = sccnt;
                                    Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                    crptBlock++;
                                }
                                else
                                {
                                    // false. do nothing
                                }

                                sccnt++;
                            }
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("Missing crc " + f);
                }
            }

            //scan dirs for cds
            foreach (var d in Directory.GetDirectories(dir))
            {
                var cues = Directory.GetFiles(d, "*.cue");
                if (cues.Length == 1)
                {
                    try
                    {
                        var cue = new CueSheet(cues[0]);
                        var crc = ComputeCueCrc(cue);


                        var ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));

                        if (ck != null)
                        {
                            //var namecrc = Crc32.Compute(Encoding.ASCII.GetBytes(f.Substring(f.LastIndexOf('\\') + 1)));
                            var nn = d.Substring(d.LastIndexOfAny(new char[] { '\\', '/' }) + 1);

                            var    name    = Encoding.ASCII.GetBytes(nn);
                            byte[] namecnv = new byte[56];

                            if (name.Length > 56)
                            {
                                Array.Copy(name, namecnv, 56);
                            }
                            else
                            {
                                Array.Copy(name, namecnv, name.Length);
                            }

                            for (int i = 0; i < namecnv.Length; ++i)
                            {
                                namecnv[i] = ProcessChar(namecnv[i]);
                            }

                            var namecrc = Crc32.update_crc(0xFFFFFFFF, namecnv, 56);

                            var existing = games.Take(gamecnt).FirstOrDefault(x => x.checksum != 0 && x.GameID == ck.GameID);

                            if (existing != null)
                            {
                                var g = new Game();
                                g.checksum   = namecrc;
                                g.remap      = existing.remap;
                                g.GameID     = existing.GameID;
                                g.TextName   = existing.TextName;
                                g.ScreenName = existing.ScreenName;

                                games[gamecnt] = g;
                                ++gamecnt;
                            }
                            else
                            {
                                var gg = db.Game.FirstOrDefault(x => x.ID == ck.GameID);

                                if (gg != null && !gg.IsScreenshotNull())
                                {
                                    //String dst = "TileCache/" + gg.Screenshot.Substring(gg.Screenshot.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                                    string dst = "TileCache/" + gg.Screenshot.Replace("\\", "_").Replace("/", "_").Replace(":", "_");

                                    dst = dst.Replace(".png", ".tile");

                                    if (File.Exists(dst))
                                    {
                                        var g = new Game();
                                        g.checksum   = namecrc;
                                        g.remap      = sccnt;
                                        g.GameID     = ck.GameID;
                                        g.TextName   = gg.Name;
                                        g.ScreenName = gg.Screenshot;

                                        games[gamecnt] = g;
                                        ++gamecnt;

                                        //copy screenshot to the scshot block
                                        byte[] scshot = File.ReadAllBytes(dst);

                                        byte[] scshot2 = new byte[3072];
                                        Array.Copy(scshot, scshot2, scshot.Length);

                                        //add year, genre...
                                        scshot2[0xA00] = 0x0;                                           //version
                                        if (!gg.IsGenreNull())
                                        {
                                            scshot2[0xA01] = (byte)gg.Genre;
                                        }

                                        if (!gg.IsYearNull())
                                        {
                                            scshot2[0xA02] = (byte)(gg.Year & 0xFF);
                                            scshot2[0xA03] = (byte)((gg.Year >> 8) & 0xFF);
                                        }

                                        Debug.Assert(scshot2.Length == 3072);
                                        Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                        // Bad index patch
                                        if (((sccnt - crptBlock) % 21 == 0) && ((sccnt + 1) % 64 != 0))
                                        {
                                            // true
                                            Console.WriteLine("Corrupted Index Skipped: {0}", sccnt);

                                            sccnt++;
                                            games[gamecnt - 1].remap = sccnt;
                                            Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);
                                        }
                                        else if (sccnt % 64 == 0)
                                        {
                                            // true
                                            Console.WriteLine("Corrupted Index Skipped: {0}", sccnt);

                                            sccnt++;
                                            games[gamecnt - 1].remap = sccnt;
                                            Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                            crptBlock++;
                                        }
                                        else
                                        {
                                            // false. do nothing
                                        }

                                        sccnt++;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Console.WriteLine("Missing crc " + f);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error processing " + cues[0] + " . Skipped");
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            if (gamecnt != 0)
            {
                games = games.Take(gamecnt).OrderBy(x => x.checksum).ToArray();

                //Console.WriteLine("Writting game.db");
                List <string> debugOutput = new List <string>();

                //Console.WriteLine("{0,8} {1,8} {2,10} {3,4} {4,-32} {5,-32}", "Little", "Big", "Int", "Indx", "DB Text Name", "Screenshot");
                debugOutput.Add(String.Format("{0,8},{1,8},{2,10},{3,4},{4,-32},{5,-32}", "Little", "Big", "Int", "Indx", "DB Text Name", "Screenshot"));

                FileStream   fs = new FileStream(dir + "/games.db", FileMode.Create, FileAccess.Write);
                BinaryWriter bw = new BinaryWriter(fs);

                foreach (var g in games)
                {
                    bw.Write(g.checksum);

                    // TODO: Add Debug Check
                    string shortName = g.TextName.Length > 31 ? g.TextName.Substring(0, 31) : g.TextName;
                    //Console.WriteLine("{0,8} {1,8} {2,10} {3,4} {4,-32} {5,-32}", LittleEndian(g.checksum.ToString("X8")), g.checksum.ToString("X8"), g.checksum, g.remap, shortName, g.ScreenName);
                    debugOutput.Add(String.Format("{0,8},{1,8},{2,10},{3,4},{4,-32},{5,-32}", LittleEndian(g.checksum.ToString("X8")), g.checksum.ToString("X8"), g.checksum, g.remap, shortName, g.ScreenName));
                }

                if (form.debugToolStripMenuItem.Checked)
                {
                    foreach (string d in debugOutput)
                    {
                        Console.WriteLine(d.Replace(',', ' '));
                    }

                    System.IO.File.WriteAllLines(dir + "/debug.csv", debugOutput.ToArray());
                }


                for (int i = 0; i < 1024 - games.Length; ++i)
                {
                    bw.Write(0xFFFFFFFF);
                }

                foreach (var g in games)
                {
                    bw.Write(g.remap);
                }

                for (int i = 0; i < 1024 - games.Length; ++i)
                {
                    bw.Write((ushort)0xFFFF);
                }

                bw.Write(scshots, 0, 3072 * sccnt);

                bw.Close();
                fs.Close();
            }

            foreach (var d in Directory.GetDirectories(dir))
            {
                ScanDir(d, db, form);
            }
        }
Ejemplo n.º 4
0
        static void ScanDir(String dir, GameDB db, GameDBMgr form)
        {
            Game[] games;
            byte[] scshots;
            ushort sccnt;
            ushort gamecnt;

            gamecnt = 0;
            sccnt   = 0;
            games   = new Game[1024];
            scshots = new Byte[1024 * 3072];

            if (form != null)
            {
                form.Invoke(new Action(() =>
                {
                    form.label1.Text = Path.GetFileName(dir);
                }));
            }
            else
            {
                Console.WriteLine("Processing directory " + Path.GetFileName(dir));
            }


            foreach (var f in Directory.GetFiles(dir, "*.pce"))
            {
                var data = File.ReadAllBytes(f);

                var crc = Crc32.Compute(data);

                var ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));

                if (ck == null && (data.Length & 0xFFF) != 0)
                {
                    uint l = (uint)data.Length & 0xFFFFF000;

                    var dat = new byte[l];
                    Array.Copy(data, data.Length & 0xFFF, dat, 0, l);

                    data = dat;

                    crc = Crc32.Compute(data);

                    ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));
                }

                if (ck != null)
                {
                    //var namecrc = Crc32.Compute(Encoding.ASCII.GetBytes(f.Substring(f.LastIndexOf('\\') + 1)));
                    var nn = f.Substring(f.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                    nn = nn.Substring(0, nn.LastIndexOf('.'));

                    var    name    = Encoding.ASCII.GetBytes(nn);
                    byte[] namecnv = new byte[56];

                    if (name.Length > 56)
                    {
                        Array.Copy(name, namecnv, 56);
                    }
                    else
                    {
                        Array.Copy(name, namecnv, name.Length);
                    }

                    for (int i = 0; i < namecnv.Length; ++i)
                    {
                        namecnv[i] = ProcessChar(namecnv[i]);
                    }

                    var namecrc = Crc32.update_crc(0xFFFFFFFF, namecnv, 56);

                    var existing = games.Take(gamecnt).FirstOrDefault(x => x.checksum != 0 && x.GameID == ck.GameID);

                    if (existing != null)
                    {
                        var g = new Game();
                        g.checksum = namecrc;
                        g.remap    = existing.remap;
                        g.GameID   = existing.GameID;

                        games[gamecnt] = g;
                        ++gamecnt;
                    }
                    else
                    {
                        var gg = db.Game.FirstOrDefault(x => x.ID == ck.GameID);

                        if (gg != null && !gg.IsScreenshotNull())
                        {
                            //String dst = "TileCache/" + gg.Screenshot.Substring(gg.Screenshot.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                            string dst = "TileCache/" + gg.Screenshot.Replace("\\", "_").Replace("/", "_").Replace(":", "_");

                            dst = dst.Replace(".png", ".tile");

                            if (File.Exists(dst))
                            {
                                var g = new Game();
                                g.checksum = namecrc;
                                g.remap    = sccnt;
                                g.GameID   = ck.GameID;

                                games[gamecnt] = g;
                                ++gamecnt;

                                //copy screenshot to the scshot block
                                byte[] scshot = File.ReadAllBytes(dst);

                                byte[] scshot2 = new byte[3072];
                                Array.Copy(scshot, scshot2, scshot.Length);

                                //add year, genre...
                                scshot2[0xA00] = 0x0;                                   //version
                                if (!gg.IsGenreNull())
                                {
                                    scshot2[0xA01] = (byte)gg.Genre;
                                }

                                if (!gg.IsYearNull())
                                {
                                    scshot2[0xA02] = (byte)(gg.Year & 0xFF);
                                    scshot2[0xA03] = (byte)((gg.Year >> 8) & 0xFF);
                                }

                                Debug.Assert(scshot2.Length == 3072);
                                Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                sccnt++;
                            }
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("Missing crc " + f);
                }
            }

            //scan dirs for cds
            foreach (var d in Directory.GetDirectories(dir))
            {
                var cues = Directory.GetFiles(d, "*.cue");
                if (cues.Length == 1)
                {
                    try
                    {
                        var cue = new CueSheet(cues[0]);
                        var crc = ComputeCueCrc(cue);


                        var ck = db.GameCk.FirstOrDefault(w => w.Checksum == crc.ToString("X8"));

                        if (ck != null)
                        {
                            //var namecrc = Crc32.Compute(Encoding.ASCII.GetBytes(f.Substring(f.LastIndexOf('\\') + 1)));
                            var nn = d.Substring(d.LastIndexOfAny(new char[] { '\\', '/' }) + 1);

                            var    name    = Encoding.ASCII.GetBytes(nn);
                            byte[] namecnv = new byte[56];

                            if (name.Length > 56)
                            {
                                Array.Copy(name, namecnv, 56);
                            }
                            else
                            {
                                Array.Copy(name, namecnv, name.Length);
                            }

                            for (int i = 0; i < namecnv.Length; ++i)
                            {
                                namecnv[i] = ProcessChar(namecnv[i]);
                            }

                            var namecrc = Crc32.update_crc(0xFFFFFFFF, namecnv, 56);

                            var existing = games.Take(gamecnt).FirstOrDefault(x => x.checksum != 0 && x.GameID == ck.GameID);

                            if (existing != null)
                            {
                                var g = new Game();
                                g.checksum = namecrc;
                                g.remap    = existing.remap;
                                g.GameID   = existing.GameID;

                                games[gamecnt] = g;
                                ++gamecnt;
                            }
                            else
                            {
                                var gg = db.Game.FirstOrDefault(x => x.ID == ck.GameID);

                                if (gg != null && !gg.IsScreenshotNull())
                                {
                                    //String dst = "TileCache/" + gg.Screenshot.Substring(gg.Screenshot.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
                                    string dst = "TileCache/" + gg.Screenshot.Replace("\\", "_").Replace("/", "_").Replace(":", "_");

                                    dst = dst.Replace(".png", ".tile");

                                    if (File.Exists(dst))
                                    {
                                        var g = new Game();
                                        g.checksum = namecrc;
                                        g.remap    = sccnt;
                                        g.GameID   = ck.GameID;

                                        games[gamecnt] = g;
                                        ++gamecnt;

                                        //copy screenshot to the scshot block
                                        byte[] scshot = File.ReadAllBytes(dst);

                                        byte[] scshot2 = new byte[3072];
                                        Array.Copy(scshot, scshot2, scshot.Length);

                                        //add year, genre...
                                        scshot2[0xA00] = 0x0;                                           //version
                                        if (!gg.IsGenreNull())
                                        {
                                            scshot2[0xA01] = (byte)gg.Genre;
                                        }

                                        if (!gg.IsYearNull())
                                        {
                                            scshot2[0xA02] = (byte)(gg.Year & 0xFF);
                                            scshot2[0xA03] = (byte)((gg.Year >> 8) & 0xFF);
                                        }

                                        Debug.Assert(scshot2.Length == 3072);
                                        Array.Copy(scshot2, 0, scshots, 3072 * sccnt, scshot2.Length);

                                        sccnt++;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Console.WriteLine("Missing crc " + f);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error processing " + cues[0] + " . Skipped");
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            if (gamecnt != 0)
            {
                games = games.Take(gamecnt).OrderBy(x => x.checksum).ToArray();

                //Console.WriteLine("Writting game.db");

                FileStream   fs = new FileStream(dir + "/games.db", FileMode.Create, FileAccess.Write);
                BinaryWriter bw = new BinaryWriter(fs);

                foreach (var g in games)
                {
                    bw.Write(g.checksum);
                }

                for (int i = 0; i < 1024 - games.Length; ++i)
                {
                    bw.Write(0xFFFFFFFF);
                }

                foreach (var g in games)
                {
                    bw.Write(g.remap);
                }

                for (int i = 0; i < 1024 - games.Length; ++i)
                {
                    bw.Write((ushort)0xFFFF);
                }

                bw.Write(scshots, 0, 3072 * sccnt);

                bw.Close();
                fs.Close();
            }

            foreach (var d in Directory.GetDirectories(dir))
            {
                ScanDir(d, db, form);
            }
        }