Rework how track map is built from TOC.

This commit is contained in:
2018-02-04 22:06:14 +00:00
parent a0ebde3b38
commit a14476671f

View File

@@ -233,12 +233,6 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
if(toc == null)
{
DicConsole.ErrorWriteLine("Error trying to decode TOC...");
return;
}
MmcSubchannel supportedSubchannel = MmcSubchannel.Raw; MmcSubchannel supportedSubchannel = MmcSubchannel.Raw;
dumpLog.WriteLine("Checking if drive supports full raw subchannel reading..."); dumpLog.WriteLine("Checking if drive supports full raw subchannel reading...");
DicConsole.WriteLine("Checking if drive supports full raw subchannel reading..."); DicConsole.WriteLine("Checking if drive supports full raw subchannel reading...");
@@ -292,11 +286,6 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
} }
FullTOC.TrackDataDescriptor[] sortedTracks =
toc.Value.TrackDescriptors.OrderBy(track => track.POINT).ToArray();
List<Track> trackList = new List<Track>();
long lastSector = 0;
// Check if output format supports subchannels // Check if output format supports subchannels
if(!outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) && if(!outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
supportedSubchannel != MmcSubchannel.None) supportedSubchannel != MmcSubchannel.None)
@@ -335,8 +324,20 @@ namespace DiscImageChef.Core.Devices.Dumping
DicConsole.WriteLine("Building track map..."); DicConsole.WriteLine("Building track map...");
dumpLog.WriteLine("Building track map..."); dumpLog.WriteLine("Building track map...");
List<Track> trackList = new List<Track>();
long lastSector = 0;
Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>();
TrackType firstTrackType = TrackType.Audio;
if(toc.HasValue)
{
FullTOC.TrackDataDescriptor[] sortedTracks =
toc.Value.TrackDescriptors.OrderBy(track => track.POINT).ToArray();
foreach(FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => trk.ADR == 1 || trk.ADR == 4)) foreach(FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => trk.ADR == 1 || trk.ADR == 4))
if(trk.POINT >= 0x01 && trk.POINT <= 0x63) if(trk.POINT >= 0x01 &&
trk.POINT <= 0x63)
{
trackList.Add(new Track trackList.Add(new Track
{ {
TrackSequence = trk.POINT, TrackSequence = trk.POINT,
@@ -352,6 +353,8 @@ namespace DiscImageChef.Core.Devices.Dumping
TrackRawBytesPerSector = (int)SECTOR_SIZE, TrackRawBytesPerSector = (int)SECTOR_SIZE,
TrackSubchannelType = subType TrackSubchannelType = subType
}); });
trackFlags.Add(trk.POINT, trk.CONTROL);
}
else if(trk.POINT == 0xA2) else if(trk.POINT == 0xA2)
{ {
int phour, pmin, psec, pframe; int phour, pmin, psec, pframe;
@@ -402,27 +405,34 @@ namespace DiscImageChef.Core.Devices.Dumping
dskType = MediaType.CDROMXA; dskType = MediaType.CDROMXA;
break; break;
} }
}
if(trackList.Count == 0) firstTrackType =
(TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
(TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental
? TrackType.Data
: TrackType.Audio;
}
}
else
{ {
DicConsole.WriteLine("TOC with no tracks found, trying old method..."); DicConsole.WriteLine("Cannot read RAW TOC, requesting processed one...");
dumpLog.WriteLine("TOC with no tracks found, trying old method..."); dumpLog.WriteLine("Cannot read RAW TOC, requesting processed one...");
dumpLog.WriteLine("Reading old TOC");
tocSense = dev.ReadToc(out cmdBuf, out senseBuf, false, 0, dev.Timeout, out _); tocSense = dev.ReadToc(out cmdBuf, out senseBuf, false, 0, dev.Timeout, out _);
TOC.CDTOC? oldToc = Decoders.CD.TOC.Decode(cmdBuf); TOC.CDTOC? oldToc = TOC.Decode(cmdBuf);
if(tocSense ||!oldToc.HasValue) if((tocSense || !oldToc.HasValue) && !force)
{ {
DicConsole.WriteLine("Could not read TOC, cannot continue..."); DicConsole
dumpLog.WriteLine("Could not read TOC, cannot continue..."); .WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
dumpLog.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
return; return;
} }
lastSector = 0; foreach(TOC.CDTOCTrackDataDescriptor trk in oldToc
.Value.TrackDescriptors.OrderBy(t => t.TrackNumber)
foreach(TOC.CDTOCTrackDataDescriptor trk in oldToc.Value.TrackDescriptors.OrderBy(t=>t.TrackNumber).Where(trk => trk.ADR == 1 || trk.ADR == 4)) .Where(trk => trk.ADR == 1 || trk.ADR == 4))
if(trk.TrackNumber >= 0x01 && trk.TrackNumber <= 0x63) if(trk.TrackNumber >= 0x01 && trk.TrackNumber <= 0x63)
{
trackList.Add(new Track trackList.Add(new Track
{ {
TrackSequence = trk.TrackNumber, TrackSequence = trk.TrackNumber,
@@ -437,12 +447,47 @@ namespace DiscImageChef.Core.Devices.Dumping
TrackRawBytesPerSector = (int)SECTOR_SIZE, TrackRawBytesPerSector = (int)SECTOR_SIZE,
TrackSubchannelType = subType TrackSubchannelType = subType
}); });
trackFlags.Add(trk.TrackNumber, trk.CONTROL);
}
else if(trk.TrackNumber == 0xAA) else if(trk.TrackNumber == 0xAA)
{
firstTrackType =
(TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrack ||
(TocControl)(trk.CONTROL & 0x0D) == TocControl.DataTrackIncremental
? TrackType.Data
: TrackType.Audio;
lastSector = trk.TrackStartAddress - 1; lastSector = trk.TrackStartAddress - 1;
} }
}
if(trackList.Count == 0)
{
DicConsole.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");
dumpLog.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");
trackList.Add(new Track
{
TrackSequence = 1,
TrackSession = 1,
TrackType = firstTrackType,
TrackStartSector = 0,
TrackBytesPerSector = (int)SECTOR_SIZE,
TrackRawBytesPerSector = (int)SECTOR_SIZE,
TrackSubchannelType = subType
});
trackFlags.Add(1, (byte)(firstTrackType == TrackType.Audio ? 0 : 4));
}
if(lastSector == 0) if(lastSector == 0)
{ {
if(!force)
{
DicConsole
.WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
dumpLog.WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
return;
}
DicConsole.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); DicConsole.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
lastSector = 360000; lastSector = 360000;
@@ -701,17 +746,15 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
// Set track flags // Set track flags
foreach(FullTOC.TrackDataDescriptor trk in sortedTracks.Where(trk => (trk.ADR == 1 || trk.ADR == 4) && foreach(KeyValuePair<byte, byte> kvp in trackFlags)
trk.POINT >= 0x01 &&
trk.POINT <= 0x63))
{ {
Track track = tracks.FirstOrDefault(t => t.TrackSequence == trk.POINT); Track track = tracks.FirstOrDefault(t => t.TrackSequence == kvp.Key);
if(track.TrackSequence == 0) continue; if(track.TrackSequence == 0) continue;
dumpLog.WriteLine("Setting flags for track {0}...", track.TrackSequence); dumpLog.WriteLine("Setting flags for track {0}...", track.TrackSequence);
DicConsole.WriteLine("Setting flags for track {0}...", track.TrackSequence); DicConsole.WriteLine("Setting flags for track {0}...", track.TrackSequence);
outputPlugin.WriteSectorTag(new[] {trk.CONTROL}, track.TrackStartSector, SectorTagType.CdTrackFlags); outputPlugin.WriteSectorTag(new[] {kvp.Value}, track.TrackStartSector, SectorTagType.CdTrackFlags);
} }
if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock); if(resume.NextBlock > 0) dumpLog.WriteLine("Resuming from block {0}.", resume.NextBlock);