mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Rework how track map is built from TOC.
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user