refine disc system

This commit is contained in:
zeromus 2011-08-06 21:40:52 +00:00
parent 9826e26a4b
commit adb06ab36a
4 changed files with 52 additions and 41 deletions

View File

@ -100,12 +100,14 @@ namespace BizHawk.DiscSystem
{ {
var cue_track = cue_file.Tracks[t]; var cue_track = cue_file.Tracks[t];
//record the disc LBA that this sector started on //record the disc LBA that this track started on
int track_disc_lba_start = Sectors.Count; int track_disc_lba_start = Sectors.Count;
//record the pregap location. it will default to the start of the track unless we supplied a pregap command //record the pregap location. it will default to the start of the track unless we supplied a pregap command
int track_disc_pregap_lba = track_disc_lba_start; int track_disc_pregap_lba = track_disc_lba_start;
int blob_track_start = blob_timestamp;
//enforce a rule of our own: every track within the file must have the same sector size //enforce a rule of our own: every track within the file must have the same sector size
//we do know that files can change between track types within a file, but we're not sure what to do if the sector size changes //we do know that files can change between track types within a file, but we're not sure what to do if the sector size changes
if (Cue.BINSectorSizeForTrackType(cue_track.TrackType) != blob_sectorsize) throw new Cue.CueBrokenException("Found different sector sizes within a cue blob. We don't know how to handle that."); if (Cue.BINSectorSizeForTrackType(cue_track.TrackType) != blob_sectorsize) throw new Cue.CueBrokenException("Found different sector sizes within a cue blob. We don't know how to handle that.");
@ -118,25 +120,30 @@ namespace BizHawk.DiscSystem
toc_track.TrackType = cue_track.TrackType; toc_track.TrackType = cue_track.TrackType;
session.Tracks.Add(toc_track); session.Tracks.Add(toc_track);
if (curr_track == 1)
{
if (cue_track.PreGap.LBA != 0)
throw new InvalidOperationException("not supported: cue files with track 1 pregaps");
//but now we add one anyway
cue_track.PreGap = new Cue.CueTimestamp(150);
}
//check whether a pregap is requested. //check whether a pregap is requested.
//when this happens for the first track in a file, some empty sectors are generated //this causes empty sectors to get generated without consuming data from the blob
//when it happens for any other track, its just another way of specifying index 0 LBA
if (cue_track.PreGap.LBA > 0) if (cue_track.PreGap.LBA > 0)
{ {
if (t == 0)
for (int i = 0; i < cue_track.PreGap.LBA; i++) for (int i = 0; i < cue_track.PreGap.LBA; i++)
{ {
Sectors.Add(new SectorEntry(pregap_sector)); Sectors.Add(new SectorEntry(pregap_sector));
} }
else track_disc_pregap_lba -= cue_track.PreGap.LBA;
} }
//look ahead to the next track's index 0 so we can see how long this track's last index is //look ahead to the next track's index 1 so we can see how long this track's last index is
//or, for the last track, use the length of the file //or, for the last track, use the length of the file
int track_length_lba; int track_length_lba;
if (t == cue_file.Tracks.Count - 1) if (t == cue_file.Tracks.Count - 1)
track_length_lba = blob_length_lba - blob_timestamp; track_length_lba = blob_length_lba - blob_timestamp;
else track_length_lba = cue_file.Tracks[t + 1].Indexes[0].Timestamp.LBA - blob_timestamp; else track_length_lba = cue_file.Tracks[t + 1].Indexes[1].Timestamp.LBA - blob_timestamp;
//toc_track.length_lba = track_length_lba; //xxx //toc_track.length_lba = track_length_lba; //xxx
//find out how many indexes we have //find out how many indexes we have
@ -156,13 +163,11 @@ namespace BizHawk.DiscSystem
if (index == 0) toc_index.lba = track_disc_pregap_lba; if (index == 0) toc_index.lba = track_disc_pregap_lba;
else toc_index.lba = Sectors.Count; else toc_index.lba = Sectors.Count;
//toc_index.lba += 150; //TODO - consider whether to add 150 here
//calculate length of the index //calculate length of the index
//if it is the last index then we use our calculation from before, otherwise we check the next index //if it is the last index then we use our calculation from before, otherwise we check the next index
int index_length_lba; int index_length_lba;
if (is_last_index) if (is_last_index)
index_length_lba = track_disc_lba_start + track_length_lba - blob_timestamp - blob_disc_lba_start; index_length_lba = track_length_lba - (blob_timestamp - blob_track_start);
else index_length_lba = cue_track.Indexes[index + 1].Timestamp.LBA - blob_timestamp; else index_length_lba = cue_track.Indexes[index + 1].Timestamp.LBA - blob_timestamp;
//emit sectors //emit sectors
@ -232,7 +237,6 @@ namespace BizHawk.DiscSystem
} //track loop } //track loop
} //file loop } //file loop
//finally, analyze the length of the sessions and the entire disc by summing the lengths of the tracks //finally, analyze the length of the sessions and the entire disc by summing the lengths of the tracks
//this is a little more complex than it looks, because the length of a thing is not determined by summing it //this is a little more complex than it looks, because the length of a thing is not determined by summing it
//but rather by the difference in lbas between start and end //but rather by the difference in lbas between start and end
@ -240,6 +244,10 @@ namespace BizHawk.DiscSystem
foreach (var toc_session in TOC.Sessions) foreach (var toc_session in TOC.Sessions)
{ {
var firstTrack = toc_session.Tracks[0]; var firstTrack = toc_session.Tracks[0];
//track 0, index 0 is actually -150. but cue sheets will never say that
//firstTrack.Indexes[0].lba -= 150;
var lastTrack = toc_session.Tracks[toc_session.Tracks.Count - 1]; var lastTrack = toc_session.Tracks[toc_session.Tracks.Count - 1];
session.length_lba = lastTrack.Indexes[0].lba + lastTrack.length_lba - firstTrack.Indexes[0].lba; session.length_lba = lastTrack.Indexes[0].lba + lastTrack.length_lba - firstTrack.Indexes[0].lba;
TOC.length_lba += toc_session.length_lba; TOC.length_lba += toc_session.length_lba;

View File

@ -49,35 +49,19 @@ namespace BizHawk.DiscSystem
{ {
//main API to read a 2352-byte LBA from a disc. //main API to read a 2352-byte LBA from a disc.
//this starts at the beginning of the disc (at the lead-in) //this starts at the beginning of the disc (at the lead-in)
//so add 150 to get to a FAD-address in the user data area //so add 150 to get to get an address in the user data area
public void ReadLBA_2352(int lba, byte[] buffer, int offset) public void ReadLBA_2352(int lba, byte[] buffer, int offset)
{ {
if (lba < 150) Sectors[lba].Sector.Read(buffer, offset);
{
//lead-in area not supported yet
//in the future it will return something to mate with the
//subchannel data which we will load or calculate from the TOC
return;
}
Sectors[lba - 150].Sector.Read(buffer, offset);
} }
//main API to read a 2048-byte LBA from a disc. //main API to read a 2048-byte LBA from a disc.
//this starts at the beginning of the disc (at the lead-in) //this starts at the beginning of the disc (at the lead-in)
//so add 150 to get to a FAD-address in the user data area //so add 150 to get to get an address in the user data area
public void ReadLBA_2048(int lba, byte[] buffer, int offset) public void ReadLBA_2048(int lba, byte[] buffer, int offset)
{ {
if (lba < 150)
{
//lead-in area not supported yet
//in the future it will return something to mate with the
//subchannel data which we will load or calculate from the TOC
return;
}
byte[] temp = new byte[2352]; byte[] temp = new byte[2352];
Sectors[lba - 150].Sector.Read(temp, offset); Sectors[lba].Sector.Read(temp, offset);
Array.Copy(temp, 16, buffer, offset, 2048); Array.Copy(temp, 16, buffer, offset, 2048);
} }

View File

@ -318,15 +318,17 @@ namespace BizHawk.DiscSystem
if (!prefs.OneBinPerTrack) if (!prefs.OneBinPerTrack)
{ {
//this is the preferred mode of dumping things. we will always write full sectors.
string cue = TOC.GenerateCUE(prefs); string cue = TOC.GenerateCUE(prefs);
var bfd = new CueBin.BinFileDescriptor(); var bfd = new CueBin.BinFileDescriptor();
bfd.name = baseName + ".bin"; bfd.name = baseName + ".bin";
ret.cue = string.Format("FILE \"{0}\" BINARY\n", bfd.name) + cue; ret.cue = string.Format("FILE \"{0}\" BINARY\n", bfd.name) + cue;
ret.bins.Add(bfd); ret.bins.Add(bfd);
bfd.SectorSize = 2352; bfd.SectorSize = 2352;
for (int i = 0; i < TOC.length_lba; i++) //skip the lead-in!
for (int i = 150; i < TOC.length_lba; i++)
{ {
bfd.lbas.Add(i+150); bfd.lbas.Add(i);
bfd.lba_zeros.Add(false); bfd.lba_zeros.Add(false);
} }
} }
@ -351,6 +353,7 @@ namespace BizHawk.DiscSystem
} }
sbCue.AppendFormat("FILE \"{0}\" BINARY\n", bfd.name); sbCue.AppendFormat("FILE \"{0}\" BINARY\n", bfd.name);
//bool dropIndex0 = track.Indexes[0].num
sbCue.AppendFormat(" TRACK {0:D2} {1}\n", track.num, Cue.TrackTypeStringForTrackType(track.TrackType)); sbCue.AppendFormat(" TRACK {0:D2} {1}\n", track.num, Cue.TrackTypeStringForTrackType(track.TrackType));
foreach (var index in track.Indexes) foreach (var index in track.Indexes)
{ {

View File

@ -42,7 +42,10 @@ namespace BizHawk.DiscSystem
public string GenerateCUE(CueBinPrefs prefs) public string GenerateCUE(CueBinPrefs prefs)
{ {
//this generates a single-file cue!!!!!!! dont expect it to generate bin-per-track!
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
bool leadin = true;
foreach (var session in Sessions) foreach (var session in Sessions)
{ {
if (!prefs.SingleSession) if (!prefs.SingleSession)
@ -51,6 +54,7 @@ namespace BizHawk.DiscSystem
if (prefs.AnnotateCue) sb.AppendFormat("SESSION {0:D2} (length={1})\n", session.num, session.length_lba); if (prefs.AnnotateCue) sb.AppendFormat("SESSION {0:D2} (length={1})\n", session.num, session.length_lba);
else sb.AppendFormat("SESSION {0:D2}\n", session.num); else sb.AppendFormat("SESSION {0:D2}\n", session.num);
} }
foreach (var track in session.Tracks) foreach (var track in session.Tracks)
{ {
ETrackType trackType = track.TrackType; ETrackType trackType = track.TrackType;
@ -62,10 +66,22 @@ namespace BizHawk.DiscSystem
else sb.AppendFormat(" TRACK {0:D2} {1}\n", track.num, Cue.TrackTypeStringForTrackType(trackType)); else sb.AppendFormat(" TRACK {0:D2} {1}\n", track.num, Cue.TrackTypeStringForTrackType(trackType));
foreach (var index in track.Indexes) foreach (var index in track.Indexes)
{ {
//we no longer want to generate pregaps here. bloated bin FTW! maybe this can be an optimization later so i'll leave it.
//if (prefs.PreferPregapCommand && index.num == 0) //if (prefs.PreferPregapCommand && index.num == 0)
// sb.AppendFormat(" PREGAP {0}\n", new Cue.CueTimestamp(index.length_lba).Value); // sb.AppendFormat(" PREGAP {0}\n", new Cue.CueTimestamp(index.length_lba).Value);
//else
sb.AppendFormat(" INDEX {0:D2} {1}\n", index.num, new Cue.CueTimestamp(index.lba).Value); if (leadin)
{
//don't generate the first index, it is illogical
}
else
{
//subtract leadin
int lba = index.lba - 150;
sb.AppendFormat(" INDEX {0:D2} {1}\n", index.num, new Cue.CueTimestamp(lba).Value);
}
leadin = false;
} }
} }
} }