refactor discstructure mightily
This commit is contained in:
parent
5e71224eda
commit
cc31331bc0
|
@ -19,15 +19,16 @@ namespace BizHawk.Client.DiscoHawk
|
|||
var dsr = new DiscSectorReader(disc);
|
||||
|
||||
bool confirmed = false;
|
||||
var tracks = disc.Structure.Sessions[0].Tracks;
|
||||
var tracks = disc.Session1.Tracks;
|
||||
foreach (var track in tracks)
|
||||
{
|
||||
if (!track.IsAudio)
|
||||
continue;
|
||||
|
||||
var waveData = new byte[track.Length * 2352];
|
||||
int trackLength = track.NextTrack.LBA - track.LBA;
|
||||
var waveData = new byte[trackLength * 2352];
|
||||
int startLba = track.LBA;
|
||||
for (int sector = 0; sector < track.Length; sector++)
|
||||
for (int sector = 0; sector < trackLength; sector++)
|
||||
dsr.ReadLBA_2352(startLba + sector, waveData, sector * 2352);
|
||||
|
||||
string mp3Path = string.Format("{0} - Track {1:D2}.mp3", Path.Combine(path, filebase), track.Number);
|
||||
|
|
|
@ -379,9 +379,9 @@ namespace BizHawk.Client.DiscoHawk
|
|||
};
|
||||
|
||||
//verify sector count
|
||||
if (src_disc.LBACount != dst_disc.LBACount)
|
||||
if (src_disc.Session1.LeadoutLBA != dst_disc.Session1.LeadoutLBA)
|
||||
{
|
||||
sw.Write("LBACount count {0} vs {1}\n", src_disc.LBACount, dst_disc.LBACount);
|
||||
sw.Write("LeadoutTrack.LBA {0} vs {1}\n", src_disc.Session1.LeadoutTrack.LBA, dst_disc.Session1.LeadoutTrack.LBA);
|
||||
goto SKIPPO;
|
||||
}
|
||||
|
||||
|
@ -442,12 +442,12 @@ namespace BizHawk.Client.DiscoHawk
|
|||
};
|
||||
|
||||
//verify each sector contents
|
||||
int nSectors = src_disc.LBACount;
|
||||
int nSectors = src_disc.Session1.LeadoutLBA;
|
||||
for (int lba = -150; lba < nSectors; lba++)
|
||||
{
|
||||
if (verbose)
|
||||
if (lba % 1000 == 0)
|
||||
Console.WriteLine("LBA {0} of {1}", lba, src_disc.LBACount);
|
||||
Console.WriteLine("LBA {0} of {1}", lba, nSectors);
|
||||
|
||||
if (cancelToken != null)
|
||||
if (cancelToken.Token.IsCancellationRequested)
|
||||
|
|
|
@ -422,7 +422,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
|
||||
case 0x80: // Set start offset in track units
|
||||
byte trackNo = CommandBuffer[2].BCDtoBin();
|
||||
audioStartLBA = disc.Structure.Sessions[0].Tracks[trackNo - 1].LBA;
|
||||
audioStartLBA = disc.Session1.Tracks[trackNo].LBA;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -457,10 +457,10 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
|
||||
case 0x80: // Set end offset in track units
|
||||
byte trackNo = CommandBuffer[2].BCDtoBin();
|
||||
if (trackNo - 1 >= disc.Structure.Sessions[0].Tracks.Count)
|
||||
audioEndLBA = disc.LBACount;
|
||||
if (trackNo - 1 >= disc.Session1.Tracks.Count)
|
||||
audioEndLBA = disc.Session1.LeadoutLBA;
|
||||
else
|
||||
audioEndLBA = disc.Structure.Sessions[0].Tracks[trackNo - 1].LBA;
|
||||
audioEndLBA = disc.Session1.Tracks[trackNo].LBA;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -530,13 +530,14 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
{
|
||||
DataIn.Clear();
|
||||
DataIn.Enqueue(0x01);
|
||||
DataIn.Enqueue(((byte)disc.Structure.Sessions[0].Tracks.Count).BinToBCD());
|
||||
DataIn.Enqueue(((byte)disc.Session1.Tracks.Count).BinToBCD());
|
||||
SetPhase(BusPhase_DataIn);
|
||||
break;
|
||||
}
|
||||
case 1: // return total disc length in minutes/seconds/frames
|
||||
{
|
||||
int totalLbaLength = disc.LBACount;
|
||||
//zero 07-jul-2015 - I may have broken this
|
||||
int totalLbaLength = disc.Session1.LeadoutLBA;
|
||||
|
||||
byte m, s, f;
|
||||
Disc.ConvertLBAtoMSF(totalLbaLength, out m, out s, out f);
|
||||
|
@ -548,20 +549,18 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
SetPhase(BusPhase_DataIn);
|
||||
break;
|
||||
}
|
||||
case 2: // Return starting position of specified track in MSF format
|
||||
case 2: // Return starting position of specified track in MSF format. TODO - did zero adapt this right? track indexing might be off
|
||||
{
|
||||
int track = CommandBuffer[2].BCDtoBin();
|
||||
var tracks = disc.Structure.Sessions[0].Tracks;
|
||||
var tracks = disc.Session1.Tracks;
|
||||
if (CommandBuffer[2] > 0x99)
|
||||
throw new Exception("invalid track number BCD request... is something I need to handle?");
|
||||
if (track == 0) track = 1;
|
||||
track--;
|
||||
|
||||
|
||||
int lbaPos;
|
||||
|
||||
if (track > tracks.Count)
|
||||
lbaPos = disc.TOCRaw.LeadoutLBA.Sector; //zero 03-jul-2015 - did I adapt this right?
|
||||
if (track > disc.Session1.InformationTrackCount)
|
||||
lbaPos = disc.Session1.LeadoutLBA; //zero 03-jul-2015 - did I adapt this right?
|
||||
else
|
||||
lbaPos = tracks[track].LBA;
|
||||
|
||||
|
@ -573,7 +572,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
DataIn.Enqueue(s.BinToBCD());
|
||||
DataIn.Enqueue(f.BinToBCD());
|
||||
|
||||
if (track > tracks.Count || disc.Structure.Sessions[0].Tracks[track].IsAudio)
|
||||
if (track > tracks.Count || disc.Session1.Tracks[track].IsAudio)
|
||||
DataIn.Enqueue(0);
|
||||
else
|
||||
DataIn.Enqueue(4);
|
||||
|
|
|
@ -392,13 +392,13 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
|
|||
int CD_ReadTOC(IntPtr dest)
|
||||
{
|
||||
// this stuff from yabause's cdbase.c. don't ask me to explain it
|
||||
//TODO - we could just get this out of the actual TOC, it's the same thing
|
||||
|
||||
var TOC = CD.Structure;
|
||||
int[] rTOC = new int[102];
|
||||
var ses = TOC.Sessions[0];
|
||||
var ses = CD.Session1;
|
||||
int ntrk = ses.Tracks.Count;
|
||||
|
||||
for (int i = 0; i < 99; i++)
|
||||
for (int i = 1; i <= 99; i++)
|
||||
{
|
||||
if (i < ntrk)
|
||||
{
|
||||
|
|
|
@ -292,7 +292,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
if (audio)
|
||||
{
|
||||
byte[] data = new byte[2352];
|
||||
if (lba < CD.LBACount)
|
||||
if (lba < CD.Session1.LeadoutLBA)
|
||||
{
|
||||
DiscSectorReader.ReadLBA_2352(lba, data, 0);
|
||||
}
|
||||
|
@ -322,16 +322,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
ret.readcallback = cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
|
||||
|
||||
var ses = CD.Structure.Sessions[0];
|
||||
var ses = CD.Session1;
|
||||
int ntrack = ses.Tracks.Count;
|
||||
|
||||
// bet you a dollar this is all wrong
|
||||
//zero 07-jul-2015 - throws a dollar in the pile, since he probably messed it up worse
|
||||
for (int i = 0; i < LibGPGX.CD_MAX_TRACKS; i++)
|
||||
{
|
||||
if (i < ntrack)
|
||||
{
|
||||
ret.tracks[i].start = ses.Tracks[i].LBA;
|
||||
ret.tracks[i].end = ses.Tracks[i].Length + ret.tracks[i].start;
|
||||
ret.tracks[i].end = ses.Tracks[i + 1].LBA;
|
||||
if (i == ntrack - 1)
|
||||
{
|
||||
ret.end = ret.tracks[i].end;
|
||||
|
|
|
@ -291,7 +291,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
if (audio)
|
||||
{
|
||||
byte[] data = new byte[2352];
|
||||
if (lba < CD.LBACount)
|
||||
if (lba < CD.Session1.LeadoutLBA)
|
||||
{
|
||||
CDReader.ReadLBA_2352(lba, data, 0);
|
||||
}
|
||||
|
@ -321,16 +321,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
ret.readcallback = cd_callback_handle = new LibGPGXDynamic.cd_read_cb(CDRead);
|
||||
|
||||
var ses = CD.Structure.Sessions[0];
|
||||
var ses = CD.Session1;
|
||||
int ntrack = ses.Tracks.Count;
|
||||
|
||||
// bet you a dollar this is all wrong
|
||||
//zero 07-jul-2015 - throws a dollar in the pile, since he probably messed it up worse
|
||||
for (int i = 0; i < LibGPGXDynamic.CD_MAX_TRACKS; i++)
|
||||
{
|
||||
if (i < ntrack)
|
||||
{
|
||||
ret.tracks[i].start = ses.Tracks[i].LBA;
|
||||
ret.tracks[i].end = ses.Tracks[i].Length + ret.tracks[i].start;
|
||||
ret.tracks[i].end = ses.Tracks[i + 1].LBA;
|
||||
if (i == ntrack - 1)
|
||||
{
|
||||
ret.end = ret.tracks[i].end;
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
cbReadTOC = ShockDisc_ReadTOC;
|
||||
cbReadLBA = ShockDisc_ReadLBA2448;
|
||||
this.cbActivity = cbActivity;
|
||||
OctoshockDll.shock_CreateDisc(out OctoshockHandle, IntPtr.Zero, disc.LBACount, cbReadTOC, cbReadLBA, true);
|
||||
OctoshockDll.shock_CreateDisc(out OctoshockHandle, IntPtr.Zero, disc.Session1.LeadoutLBA, cbReadTOC, cbReadLBA, true);
|
||||
}
|
||||
|
||||
OctoshockDll.ShockDisc_ReadTOC cbReadTOC;
|
||||
|
|
|
@ -7,37 +7,10 @@ using BizHawk.Common.BufferExtensions;
|
|||
|
||||
namespace BizHawk.Emulation.DiscSystem
|
||||
{
|
||||
[Serializable]
|
||||
public class DiscReferenceException : Exception
|
||||
{
|
||||
public DiscReferenceException(string fname, Exception inner)
|
||||
: base(string.Format("A disc attempted to reference a file which could not be accessed or loaded: {0}", fname), inner)
|
||||
{
|
||||
}
|
||||
public DiscReferenceException(string fname, string extrainfo)
|
||||
: base(string.Format("A disc attempted to reference a file which could not be accessed or loaded:\n\n{0}\n\n{1}", fname, extrainfo))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sealed public partial class Disc
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Main API to determine how many LBAs are available on the disc.
|
||||
/// This counts from LBA 0 to the final sector available.
|
||||
/// THIS IS DUMB. Like everything else here.
|
||||
/// Fetch it from a toc or disc structure
|
||||
/// </summary>
|
||||
public int LBACount { get { return ABACount - 150; } }
|
||||
|
||||
/// <summary>
|
||||
/// Main API to determine how many ABAs (sectors) are available on the disc.
|
||||
/// This counts from ABA 0 to the final sector available.
|
||||
/// </summary>
|
||||
public int ABACount { get { return Sectors.Count; } }
|
||||
|
||||
|
||||
// converts LBA to minute:second:frame format.
|
||||
//TODO - somewhat redundant with Timestamp, which is due for refactoring into something not cue-related
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
|
||||
//some old junk
|
||||
|
||||
namespace BizHawk.Emulation.DiscSystem
|
||||
{
|
||||
[Serializable]
|
||||
public class DiscReferenceException : Exception
|
||||
{
|
||||
public DiscReferenceException(string fname, Exception inner)
|
||||
: base(string.Format("A disc attempted to reference a file which could not be accessed or loaded: {0}", fname), inner)
|
||||
{
|
||||
}
|
||||
public DiscReferenceException(string fname, string extrainfo)
|
||||
: base(string.Format("A disc attempted to reference a file which could not be accessed or loaded:\n\n{0}\n\n{1}", fname, extrainfo))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -20,13 +20,13 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
{
|
||||
byte[] buffer = new byte[512 * 2352];
|
||||
DiscSectorReader dsr = new DiscSectorReader(disc);
|
||||
foreach (var track in disc.Structure.Sessions[0].Tracks)
|
||||
foreach (var track in disc.Session1.Tracks)
|
||||
{
|
||||
if (track.IsAudio)
|
||||
continue;
|
||||
|
||||
int lba_len = Math.Min(track.Length, 512);
|
||||
for (int s = 0; s < 512 && s < track.Length; s++)
|
||||
int lba_len = Math.Min(track.NextTrack.LBA, 512);
|
||||
for (int s = 0; s < 512 && s < lba_len; s++)
|
||||
dsr.ReadLBA_2352(track.LBA + s, buffer, s * 2352);
|
||||
|
||||
return buffer.HashMD5(0, lba_len * 2352);
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
|
||||
SectorSize = 2048;
|
||||
Disc = disc;
|
||||
NumSectors = disc.LBACount;
|
||||
NumSectors = disc.Session1.LeadoutLBA;
|
||||
dsr = new DiscSectorReader(disc);
|
||||
|
||||
//following the provided view
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
</Compile>
|
||||
<Compile Include="API\Disc.API.cs" />
|
||||
<Compile Include="API\Disc.ID.cs" />
|
||||
<Compile Include="API\DiscExceptions.cs" />
|
||||
<Compile Include="API\DiscHasher.cs" />
|
||||
<Compile Include="API\DiscSectorReader.cs" />
|
||||
<Compile Include="API\DiscStream.cs" />
|
||||
|
|
|
@ -50,11 +50,14 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
|
||||
public void PlayTrack(int track)
|
||||
{
|
||||
if (track < 1 || track > Disc.Structure.Sessions[0].Tracks.Count)
|
||||
if (track < 1 || track > Disc.Session1.InformationTrackCount)
|
||||
return;
|
||||
|
||||
StartLBA = Disc.Structure.Sessions[0].Tracks[track - 1].LBA;
|
||||
EndLBA = StartLBA + Disc.Structure.Sessions[0].Tracks[track - 1].Length;
|
||||
StartLBA = Disc.Session1.Tracks[track].LBA;
|
||||
|
||||
//play until the beginning of the next track (?)
|
||||
EndLBA = Disc.Session1.Tracks[track + 1].LBA;
|
||||
|
||||
PlayingTrack = track;
|
||||
CurrentSector = StartLBA;
|
||||
SectorOffset = 0;
|
||||
|
@ -71,7 +74,9 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
|
||||
PlayingTrack = track.Number;
|
||||
StartLBA = lba;
|
||||
EndLBA = track.LBA + track.Length;
|
||||
|
||||
//play until the beginning of the next track (?)
|
||||
EndLBA = Disc.Session1.Tracks[track.Number + 1].LBA;
|
||||
|
||||
CurrentSector = StartLBA;
|
||||
SectorOffset = 0;
|
||||
|
@ -123,7 +128,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
{
|
||||
if (CachedSector != CurrentSector)
|
||||
{
|
||||
if (CurrentSector >= Disc.LBACount)
|
||||
if (CurrentSector >= Disc.Session1.LeadoutLBA)
|
||||
Array.Clear(SectorCache, 0, 2352); // request reading past end of available disc
|
||||
else
|
||||
DiscSectorReader.ReadLBA_2352(CurrentSector, SectorCache, 0);
|
||||
|
|
|
@ -82,12 +82,6 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
|
||||
public partial class Disc : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The DiscMountPolicy used to mount the disc. Consider this read-only.
|
||||
/// NOT SURE WE NEED THIS
|
||||
/// </summary>
|
||||
//public DiscMountPolicy DiscMountPolicy;
|
||||
|
||||
/// <summary>
|
||||
/// Free-form optional memos about the disc
|
||||
/// </summary>
|
||||
|
@ -102,6 +96,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// <summary>
|
||||
/// The DiscTOCRaw corresponding to the RawTOCEntries.
|
||||
/// TODO - rename to TOC
|
||||
/// TODO - there's one of these for every session, so... having one here doesnt make sense
|
||||
/// </summary>
|
||||
public DiscTOCRaw TOCRaw;
|
||||
|
||||
|
@ -110,6 +105,11 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// </summary>
|
||||
public DiscStructure Structure;
|
||||
|
||||
/// <summary>
|
||||
/// DiscStructure.Session 1 of the disc, since that's all thats needed most of the time.
|
||||
/// </summary>
|
||||
public DiscStructure.Session Session1 { get { return Structure.Sessions[1]; } }
|
||||
|
||||
/// <summary>
|
||||
/// Disposable resources (blobs, mostly) referenced by this disc
|
||||
/// </summary>
|
||||
|
@ -120,8 +120,17 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// </summary>
|
||||
internal List<ISectorSynthJob2448> Sectors = new List<ISectorSynthJob2448>();
|
||||
|
||||
/// <summary>
|
||||
/// Parameters set during disc loading which can be referenced by the sector synthesizers
|
||||
/// </summary>
|
||||
internal SectorSynthParams SynthParams = new SectorSynthParams();
|
||||
|
||||
/// <summary>
|
||||
/// The DiscMountPolicy used to mount the disc. Consider this read-only.
|
||||
/// NOT SURE WE NEED THIS
|
||||
/// </summary>
|
||||
//public DiscMountPolicy DiscMountPolicy;
|
||||
|
||||
public Disc()
|
||||
{
|
||||
}
|
||||
|
@ -134,7 +143,6 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// generates lead-out sectors according to very crude approximations
|
||||
/// TODO - this isnt being used right now
|
||||
|
|
|
@ -88,6 +88,20 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
RunMednaDisc();
|
||||
break;
|
||||
}
|
||||
|
||||
if (OUT_Disc != null)
|
||||
{
|
||||
//generate toc and structure:
|
||||
//1. TOCRaw from RawTOCEntries
|
||||
var tocSynth = new DiscTOCRaw.SynthesizeFromRawTOCEntriesJob() { Entries = OUT_Disc.RawTOCEntries };
|
||||
tocSynth.Run();
|
||||
OUT_Disc.TOCRaw = tocSynth.Result;
|
||||
//2. Structure frmo TOCRaw
|
||||
var structureSynth = new DiscStructure.SynthesizeFromTOCRawJob() { IN_Disc = OUT_Disc, TOCRaw = OUT_Disc.TOCRaw };
|
||||
structureSynth.Run();
|
||||
OUT_Disc.Structure = structureSynth.Result;
|
||||
}
|
||||
|
||||
FinishLog();
|
||||
}
|
||||
|
||||
|
@ -178,20 +192,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
OUT_Disc = ccdLoader.LoadCCDToDisc(IN_FromPath);
|
||||
}
|
||||
|
||||
DONE:
|
||||
if (OUT_Disc != null)
|
||||
{
|
||||
//generate toc and structure:
|
||||
//1. TOCRaw from RawTOCEntries
|
||||
var tocSynth = new DiscTOCRaw.SynthesizeFromRawTOCEntriesJob() { Entries = OUT_Disc.RawTOCEntries };
|
||||
tocSynth.Run();
|
||||
OUT_Disc.TOCRaw = tocSynth.Result;
|
||||
//2. Structure frmo TOCRaw
|
||||
var structureSynth = new DiscStructure.SynthesizeFromTOCRawJob() { IN_Disc = OUT_Disc, TOCRaw = OUT_Disc.TOCRaw };
|
||||
structureSynth.Run();
|
||||
OUT_Disc.Structure = structureSynth.Result;
|
||||
}
|
||||
|
||||
DONE: ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,50 +7,34 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// <summary>
|
||||
/// Contains structural information for the disc broken down into c# data structures for easy interrogation.
|
||||
/// This represents a best-effort interpretation of the raw disc image.
|
||||
/// NOTE: Since this ended up really just having the list of sessions.. maybe it isn't needed and can just float on up into Disc
|
||||
/// </summary>
|
||||
public class DiscStructure
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a 0-indexed list of sessions (session 1 is at [0])
|
||||
/// Support for multiple sessions is thoroughly not working yet
|
||||
/// TODO - make re-index me with a null session 0
|
||||
/// </summary>
|
||||
public List<Session> Sessions = new List<Session>();
|
||||
|
||||
/// <summary>
|
||||
/// How many sectors in the disc, including the 150 lead-in sectors, up to the end of the last track (before the lead-out track)
|
||||
/// TODO - does anyone ever need this as the ABA Count? Rename it LBACount or ABACount
|
||||
/// </summary>
|
||||
public int LengthInSectors;
|
||||
|
||||
/// <summary>
|
||||
/// Length (including lead-in) of the disc as a timestamp
|
||||
/// TODO - does anyone ever need this as the ABA Count? Rename it LBACount or ABACount
|
||||
/// </summary>
|
||||
public Timestamp FriendlyLength { get { return new Timestamp(LengthInSectors); } }
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes of data in the disc (including lead-in). Disc sectors are really 2352 bytes each, so this is LengthInSectors * 2352
|
||||
/// TODO - this is garbage
|
||||
/// </summary>
|
||||
public long BinarySize
|
||||
{
|
||||
get { return LengthInSectors * 2352; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines which track of session 0 is at the specified LBA.
|
||||
/// Determines which track of session 1 is at the specified LBA.
|
||||
/// Returns null if it's before track 1
|
||||
/// </summary>
|
||||
public Track SeekTrack(int lba)
|
||||
{
|
||||
var ses = Sessions[0];
|
||||
for (int i = 0; i < ses.Tracks.Count; i++)
|
||||
|
||||
//take care with this loop bounds:
|
||||
for (int i = 1; i <= ses.InformationTrackCount; i++)
|
||||
{
|
||||
var track = ses.Tracks[i];
|
||||
if (track.LBA > lba)
|
||||
return (i==0)?null:ses.Tracks[i - 1];
|
||||
return (i==1)?null:ses.Tracks[i];
|
||||
}
|
||||
return ses.Tracks[ses.Tracks.Count - 1];
|
||||
return ses.Tracks[ses.Tracks.Count];
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
|
@ -94,6 +78,7 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
|
||||
Result = new DiscStructure();
|
||||
var session = new Session();
|
||||
Result.Sessions.Add(null); //placeholder session for reindexing
|
||||
Result.Sessions.Add(session);
|
||||
|
||||
session.Number = 1;
|
||||
|
@ -101,6 +86,13 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
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, //TODO - not accurate (take from track 1?)
|
||||
LBA = -150 //TODO - not accurate
|
||||
});
|
||||
|
||||
int ntracks = TOCRaw.LastRecordedTrackNumber - TOCRaw.FirstRecordedTrackNumber + 1;
|
||||
for(int i=0;i<ntracks;i++)
|
||||
{
|
||||
|
@ -120,35 +112,72 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
track.Mode = dsr.ReadLBA_Mode(track.LBA);
|
||||
}
|
||||
|
||||
//determine track length according to law specified in comments for track length
|
||||
if (i == ntracks - 1)
|
||||
track.Length = TOCRaw.LeadoutLBA.Sector - track.LBA;
|
||||
else track.Length = (TOCRaw.TOCItems[i + 2].LBATimestamp.Sector - 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?
|
||||
Control = EControlQ.None, //TODO - not accurate (take from track 1?)
|
||||
LBA = TOCRaw.LeadoutLBA.Sector
|
||||
});
|
||||
|
||||
//link track list
|
||||
for (int i = 0; i < session.Tracks.Count - 1; i++)
|
||||
{
|
||||
session.Tracks[i].NextTrack = session.Tracks[i + 1];
|
||||
}
|
||||
|
||||
//other misc fields
|
||||
session.InformationTrackCount = session.Tracks.Count - 2;
|
||||
}
|
||||
}
|
||||
|
||||
public class Session
|
||||
{
|
||||
//Notable omission:
|
||||
//Length of the session
|
||||
//How should this be defined? It's even harder than determining a track length
|
||||
|
||||
/// <summary>
|
||||
/// The LBA of the session's leadout. In other words, for all intents and purposes, the end of the session
|
||||
/// </summary>
|
||||
public int LeadoutLBA { get { return LeadoutTrack.LBA; } }
|
||||
|
||||
/// <summary>
|
||||
/// The session number
|
||||
/// </summary>
|
||||
public int Number;
|
||||
|
||||
/// <summary>
|
||||
/// All the tracks in the session.. but... Tracks[0] should be "Track 1". So beware of this.
|
||||
/// Tracks.Count will be good for counting the useful user information tracks on the disc.
|
||||
/// The number of user information tracks in the session.
|
||||
/// This excludes track 0 and the lead-out track.
|
||||
/// Use this instead of Tracks.Count
|
||||
/// </summary>
|
||||
public int InformationTrackCount;
|
||||
|
||||
/// <summary>
|
||||
/// All the tracks in the session.. but... Tracks[0] is the lead-in track placeholder. Tracks[1] should be "Track 1". So beware of this.
|
||||
/// For a disc with "3 tracks", Tracks.Count will be 5: it includes that lead-in track as well as the leadout track.
|
||||
/// Perhaps we should turn this into a special collection type with no Count or Length, or a method to GetTrack()
|
||||
/// </summary>
|
||||
public List<Track> Tracks = new List<Track>();
|
||||
//I've thought about how to solve this, but it's not easy.
|
||||
//At some point we may need to add a true track 0, too.
|
||||
//Ideas: Dictionary, or a separate PhysicalTracks and UserTracks list, or add a null and make all loops just cope with that
|
||||
//But, the DiscStructure is kind of weak. It might be better to just optimize it for end-users
|
||||
//It seems that the current end-users are happy with tracks being implemented the way it is
|
||||
|
||||
//removed:
|
||||
////the length of the session (should be the sum of all track lengths)
|
||||
//public int length_aba;
|
||||
/// <summary>
|
||||
/// A reference to the first information track (Track 1)
|
||||
/// </summary>
|
||||
public Track FirstInformationTrack { get { return Tracks[1]; } }
|
||||
|
||||
/// <summary>
|
||||
/// A reference to the lead-out track.
|
||||
/// Effectively, the end of the user area of the disc.
|
||||
/// </summary>
|
||||
public Track LeadoutTrack { get { return Tracks[Tracks.Count - 1]; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -184,11 +213,10 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
//Indices may need scanning sector by sector.
|
||||
//It's unlikely that any software would be needing indices anyway.
|
||||
//We should add another index scanning service if that's ever needed.
|
||||
//(note: a CCD should contain indices, but it's not clear whether it's required. logically it wshouldnt be)
|
||||
//(note: a CCD should contain indices, but it's not clear whether it's required. logically it shouldnt be)
|
||||
//Notable omission:
|
||||
//Mode (0,1,2)
|
||||
//Modes 1 and 2 can't be generally distinguished.
|
||||
//It's a relatively easy heuristic, though: just read the first sector of each track.
|
||||
//Length of the track.
|
||||
//How should this be defined? Between which indices? It's really hard.
|
||||
|
||||
//These omissions could be handled by ReadStructure() policies which permit the scanning of the entire disc.
|
||||
//After that, they could be cached in here.
|
||||
|
@ -228,17 +256,9 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
public int LBA;
|
||||
|
||||
/// <summary>
|
||||
/// The length of the track, counted from its index 1 to the next track.
|
||||
/// TODO - Shouldn't it exclude the post-gap?
|
||||
/// NO - in at least one place (CDAudio) this is used.. and.. it should probably play through the post-gap
|
||||
/// That just goes to show how ill-defined this concept is
|
||||
/// The next track in the session. null for the leadout track of a session.
|
||||
/// </summary>
|
||||
public int Length;
|
||||
|
||||
///// <summary>
|
||||
///// The length as a timestamp (for accessing as a MM:SS:FF)
|
||||
///// </summary>
|
||||
//public Timestamp FriendlyLength { get { return new Timestamp(Length); } }
|
||||
public Track NextTrack;
|
||||
}
|
||||
|
||||
public class Index
|
||||
|
@ -247,19 +267,6 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
public int LBA;
|
||||
}
|
||||
|
||||
//public void AnalyzeLengthsFromIndexLengths()
|
||||
//{
|
||||
// //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
|
||||
// LengthInSectors = 0;
|
||||
// foreach (var session in Sessions)
|
||||
// {
|
||||
// var firstTrack = session.Tracks[0];
|
||||
// var lastTrack = session.Tracks[session.Tracks.Count - 1];
|
||||
// session.length_aba = lastTrack.Indexes[0].aba + lastTrack.Length - firstTrack.Indexes[0].aba;
|
||||
// LengthInSectors += session.length_aba;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue