Exemple #1
0
        /// <summary>
        /// Attempts to determine the type of the disc.
        /// In the future, we might return a struct or a class with more detailed information
        /// </summary>
        public DiscType DetectDiscType()
        {
            //check track 1's data type. if it's an audio track, further data-track testing is useless
            //furthermore, it's probably senseless (no binary data there to read)
            //however a sector could mark itself as audio without actually being.. we'll just wait for that one.
            if (dsr.ReadLBA_Mode(disc.TOC.TOCItems[1].LBA) == 0)
            {
                return(DiscType.AudioDisc);
            }

            //sega doesnt put anything identifying in the cdfs volume info. but its consistent about putting its own header here in sector 0
            if (DetectSegaSaturn())
            {
                return(DiscType.SegaSaturn);
            }

            // not fully tested yet
            if (DetectMegaCD())
            {
                return(DiscType.MegaCD);
            }

            // not fully tested yet
            if (DetectPSX())
            {
                return(DiscType.SonyPSX);
            }

            //we dont know how to detect TurboCD.
            //an emulator frontend will likely just guess TurboCD if the disc is UnknownFormat
            //(we can also have a gameDB!)

            var discView = EDiscStreamView.DiscStreamView_Mode1_2048;

            if (disc.TOC.Session1Format == SessionFormat.Type20_CDXA)
            {
                discView = EDiscStreamView.DiscStreamView_Mode2_Form1_2048;
            }

            var  iso   = new ISOFile();
            bool isIso = iso.Parse(new DiscStream(disc, discView, 0));

            if (isIso)
            {
                var appId = System.Text.Encoding.ASCII.GetString(iso.VolumeDescriptors[0].ApplicationIdentifier).TrimEnd('\0', ' ');

                //for example: PSX magical drop F (JP SLPS_02337) doesn't have the correct iso PVD fields
                //but, some PSX games (junky rips) don't have the 'licensed by string' so we'll hope they get caught here
                if (appId == "PLAYSTATION")
                {
                    return(DiscType.SonyPSX);
                }

                if (appId == "PSP GAME")
                {
                    return(DiscType.SonyPSP);
                }

                return(DiscType.UnknownCDFS);
            }

            return(DiscType.UnknownFormat);
        }
Exemple #2
0
        /// <exception cref="InvalidOperationException">first track of <see cref="TOCRaw"/> is not <c>1</c></exception>
        public void Run()
        {
            var dsr = new DiscSectorReader(IN_Disc)
            {
                Policy = { DeterministicClearBuffer = false }
            };

            Result = new DiscStructure();
            var session = new DiscStructure.Session();

            Result.Sessions.Add(null);             //placeholder session for reindexing
            Result.Sessions.Add(session);

            session.Number = 1;

            if (TOCRaw.FirstRecordedTrackNumber != 1)
            {
                throw new InvalidOperationException($"Unsupported: {nameof(TOCRaw.FirstRecordedTrackNumber)} != 1");
            }

            //add a lead-in track
            session.Tracks.Add(new DiscStructure.Track
            {
                Number  = 0,
                Control = EControlQ.None,                   //we'll set this later
                LBA     = -new Timestamp(99, 99, 99).Sector //obvious garbage
            });

            int ntracks = TOCRaw.LastRecordedTrackNumber - TOCRaw.FirstRecordedTrackNumber + 1;

            for (int i = 0; i < ntracks; i++)
            {
                var item  = TOCRaw.TOCItems[i + 1];
                var track = new DiscStructure.Track
                {
                    Number  = i + 1,
                    Control = item.Control,
                    LBA     = item.LBA
                };
                session.Tracks.Add(track);

                if (!item.IsData)
                {
                    track.Mode = 0;
                }
                else
                {
                    //determine the mode by a hardcoded heuristic: check mode of first sector
                    track.Mode = dsr.ReadLBA_Mode(track.LBA);
                }

                //determine track length according to... how? It isn't clear.
                //Let's not do this until it's needed.
                //if (i == ntracks - 1)
                //  track.Length = TOCRaw.LeadoutLBA.Sector - track.LBA;
                //else track.Length = (TOCRaw.TOCItems[i + 2].LBATimestamp.Sector - track.LBA);
            }

            //add lead-out track
            session.Tracks.Add(new DiscStructure.Track
            {
                Number = 0xA0,                 //right?
                //kind of a guess, but not completely
                Control = session.Tracks[session.Tracks.Count - 1].Control,
                Mode    = session.Tracks[session.Tracks.Count - 1].Mode,
                LBA     = TOCRaw.LeadoutLBA
            });

            //link track list
            for (int i = 0; i < session.Tracks.Count - 1; i++)
            {
                session.Tracks[i].NextTrack = session.Tracks[i + 1];
            }

            //fix lead-in track type
            //guesses:
            session.Tracks[0].Control = session.Tracks[1].Control;
            session.Tracks[0].Mode    = session.Tracks[1].Mode;
        }
		public void Run()
		{
			var dsr = new DiscSectorReader(IN_Disc);
			dsr.Policy.DeterministicClearBuffer = false;

			Result = new DiscStructure();
			var session = new DiscStructure.Session();
			Result.Sessions.Add(null); //placeholder session for reindexing
			Result.Sessions.Add(session);

			session.Number = 1;

			if (TOCRaw.FirstRecordedTrackNumber != 1)
				throw new InvalidOperationException("Unsupported: FirstRecordedTrackNumber != 1");

			//add a lead-in track
			session.Tracks.Add(new DiscStructure.Track()
			{
				Number = 0,
				Control = EControlQ.None, //we'll set this later
				LBA = -new Timestamp(99,99,99).Sector //obvious garbage
			});

			int ntracks = TOCRaw.LastRecordedTrackNumber - TOCRaw.FirstRecordedTrackNumber + 1;
			for (int i = 0; i < ntracks; i++)
			{
				var item = TOCRaw.TOCItems[i + 1];
				var track = new DiscStructure.Track()
				{
					Number = i + 1,
					Control = item.Control,
					LBA = item.LBA
				};
				session.Tracks.Add(track);

				if (!item.IsData)
					track.Mode = 0;
				else
				{
					//determine the mode by a hardcoded heuristic: check mode of first sector
					track.Mode = dsr.ReadLBA_Mode(track.LBA);
				}

				//determine track length according to... how? It isn't clear.
				//Let's not do this until it's needed.
				//if (i == ntracks - 1)
				//  track.Length = TOCRaw.LeadoutLBA.Sector - track.LBA;
				//else track.Length = (TOCRaw.TOCItems[i + 2].LBATimestamp.Sector - track.LBA);
			}

			//add lead-out track
			session.Tracks.Add(new DiscStructure.Track()
			{
				Number = 0xA0, //right?
				//kind of a guess, but not completely
				Control = session.Tracks[session.Tracks.Count -1 ].Control,
				Mode = session.Tracks[session.Tracks.Count - 1].Mode,
				LBA = TOCRaw.LeadoutLBA
			});

			//link track list 
			for (int i = 0; i < session.Tracks.Count - 1; i++)
			{
				session.Tracks[i].NextTrack = session.Tracks[i + 1];
			}

			//fix lead-in track type
			//guesses:
			session.Tracks[0].Control = session.Tracks[1].Control;
			session.Tracks[0].Mode = session.Tracks[1].Mode;
		}