diff --git a/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs b/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
index 5896851ba9..064fe25d99 100644
--- a/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
+++ b/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
@@ -46,6 +46,13 @@ namespace BizHawk.Emulation.DiscSystem
/// How about .sub files? Can't remember right now.
///
public bool DeinterleavedSubcode = true;
+
+ ///
+ /// Indicates whether the output buffer should be cleared before returning any data.
+ /// This will involve clearing sections you didn't ask for, and clearing sections about to be filled with data from the disc.
+ /// It is a waste of performance, but it will ensure reliability.
+ ///
+ public bool DeterministicClearBuffer = true;
}
@@ -71,6 +78,11 @@ namespace BizHawk.Emulation.DiscSystem
job.Disc = disc;
}
+ void PrepareBuffer(byte[] buffer, int offset, int size)
+ {
+ if (Policy.DeterministicClearBuffer) Array.Clear(buffer, offset, size);
+ }
+
//todo - methods to read only subcode
///
@@ -80,6 +92,7 @@ namespace BizHawk.Emulation.DiscSystem
{
var sector = disc.Sectors[lba + 150];
+ PrepareBuffer(buffer, offset, 2352);
PrepareJob(lba);
job.DestBuffer2448 = buf2442;
job.DestOffset = 0;
@@ -100,6 +113,7 @@ namespace BizHawk.Emulation.DiscSystem
{
var sector = disc.Sectors[lba + 150];
+ PrepareBuffer(buffer, offset, 2352);
PrepareJob(lba);
job.DestBuffer2448 = buffer; //go straight to the caller's buffer
job.DestOffset = offset; //go straight to the caller's buffer
@@ -118,6 +132,7 @@ namespace BizHawk.Emulation.DiscSystem
//we can read the 2048 bytes directly
var sector = disc.Sectors[lba + 150];
+ PrepareBuffer(buffer, offset, 2352);
PrepareJob(lba);
job.DestBuffer2448 = buf2442;
job.DestOffset = 0;
@@ -134,6 +149,7 @@ namespace BizHawk.Emulation.DiscSystem
//we can read the 2048 bytes directly but we have to get them from the mode 2 data
var sector = disc.Sectors[lba + 150];
+ PrepareBuffer(buffer, offset, 2352);
PrepareJob(lba);
job.DestBuffer2448 = buf2442;
job.DestOffset = 0;
@@ -160,6 +176,7 @@ namespace BizHawk.Emulation.DiscSystem
//in no case do we need the ECC so build special flags here
var sector = disc.Sectors[lba + 150];
+ PrepareBuffer(buffer, offset, 2352);
PrepareJob(lba);
job.DestBuffer2448 = buf2442;
job.DestOffset = 0;
diff --git a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj
index 5de64f69f4..0ba54147c1 100644
--- a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj
+++ b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj
@@ -75,6 +75,7 @@
+
diff --git a/BizHawk.Emulation.DiscSystem/Blobs/Blob_ZeroPadAdapter.cs b/BizHawk.Emulation.DiscSystem/Blobs/Blob_ZeroPadAdapter.cs
index 9c1a5a4bfd..ca2cd1c362 100644
--- a/BizHawk.Emulation.DiscSystem/Blobs/Blob_ZeroPadAdapter.cs
+++ b/BizHawk.Emulation.DiscSystem/Blobs/Blob_ZeroPadAdapter.cs
@@ -1,6 +1,8 @@
using System;
using System.IO;
+//I have an ff9 disc which is truncated
+
namespace BizHawk.Emulation.DiscSystem
{
public partial class Disc : IDisposable
@@ -13,10 +15,13 @@ namespace BizHawk.Emulation.DiscSystem
public static Blob_ZeroPadBuffer MakeBufferFrom(IBlob baseBlob, long start, int bufferLength)
{
var ret = new Blob_ZeroPadBuffer();
+
//allocate the entire buffer we'll need, and it will already be zero-padded
ret.buffer = new byte[bufferLength];
+
//read as much as is left
baseBlob.Read(start, ret.buffer, 0, bufferLength);
+
//if any less got read, well, there were already zeroes there
return ret;
}
@@ -39,66 +44,6 @@ namespace BizHawk.Emulation.DiscSystem
}
}
- public sealed class Blob_ZeroPadAdapter : IBlob
- {
- public Blob_ZeroPadAdapter(IBlob baseBlob, long padFrom, long padLen)
- {
- this.baseBlob = baseBlob;
- this.padFrom = padFrom;
- this.padLen = padLen;
- }
-
- public int Read(long byte_pos, byte[] buffer, int offset, int count)
- {
- //I have an ff9 disc which can demo this
- throw new NotImplementedException("Blob_ZeroPadAdapter hasnt been tested yet! please report this!");
-
- //something about this seems unnecessarily complex, but... i dunno.
- /*
- //figure out how much remains until the zero-padding begins
- long remain = byte_pos - padFrom;
- int todo;
- if (remain < count)
- todo = (int)remain;
- else todo = count;
-
- //read up until the zero-padding
- int totalRead = 0;
- int readed = baseBlob.Read(byte_pos, buffer, offset, todo);
- totalRead += readed;
- offset += todo;
-
- //if we didnt read enough, we certainly shouldnt try to read any more
- if (readed < todo)
- return readed;
-
- //if that was all we needed, then we're done
- count -= todo;
- if (count == 0)
- return totalRead;
-
- //if we need more, it must come from zero-padding
- remain = padLen;
- if (remain < count)
- todo = (int)remain;
- else todo = count;
-
- Array.Clear(buffer, offset, todo);
- totalRead += todo;
-
- return totalRead;
- */
- }
-
- public void Dispose()
- {
- baseBlob.Dispose();
- }
-
- private readonly IBlob baseBlob;
- private long padFrom;
- private long padLen;
- }
-
+
}
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.DiscSystem/CCD_format.cs b/BizHawk.Emulation.DiscSystem/CCD_format.cs
index 51da7f1d50..0deac090cf 100644
--- a/BizHawk.Emulation.DiscSystem/CCD_format.cs
+++ b/BizHawk.Emulation.DiscSystem/CCD_format.cs
@@ -449,14 +449,17 @@ namespace BizHawk.Emulation.DiscSystem
var subBlob = job.Disc.DisposableResources[1] as Disc.Blob_RawFile;
//Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset);
- //read the IMG data
- long ofs = job.LBA * 2352;
- imgBlob.Read(ofs, job.DestBuffer2448, 0, 2352);
+ //read the IMG data if needed
+ if ((job.Parts & ESectorSynthPart.UserAny) != 0)
+ {
+ long ofs = job.LBA * 2352;
+ imgBlob.Read(ofs, job.DestBuffer2448, 0, 2352);
+ }
//if subcode is needed, read it
if ((job.Parts & (ESectorSynthPart.SubcodeAny)) != 0)
{
- ofs = job.LBA * 96;
+ long ofs = job.LBA * 96;
subBlob.Read(ofs, job.DestBuffer2448, 2352, 96);
//sub data comes to us deinterleved; we may still need to interleave it
@@ -576,6 +579,7 @@ namespace BizHawk.Emulation.DiscSystem
}
//add sectors for the "mandatory track 1 pregap", which isn't stored in the CCD file
+ //THIS IS JUNK. MORE CORRECTLY SYNTHESIZE IT
var leadin_sector_zero = new Sector_Zero();
var leadin_subcode_zero = new ZeroSubcodeSector();
for (int i = 0; i < 150; i++)
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
index 80d04e4987..d3fc01cd82 100644
--- a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
@@ -302,9 +302,8 @@ namespace BizHawk.Emulation.DiscSystem
var zero_sector = new Sector_Zero();
var zero_subSector = new ZeroSubcodeSector();
- //generate lead-in gap
- //TODO - shouldnt this have proper subcode? dunno
- //mednafen will probably be testing this in the next release
+ //add sectors for the "mandatory track 1 pregap", which isn't stored in the CCD file
+ //THIS IS JUNK. MORE CORRECTLY SYNTHESIZE IT
for(int i=0;i<150;i++)
{
var se_leadin = new SectorEntry(zero_sector);
@@ -351,17 +350,16 @@ namespace BizHawk.Emulation.DiscSystem
TOCMiscInfo.IN_Session1Format = DiscTOCRaw.SessionFormat.Type00_CDROM_CDDA;
//a little subroutine to wrap a sector if the blob is out of space
- Func eatBlobAndWrap = (required) =>
+ Func> eatBlobAndWrap = (required) =>
{
IBlob blob = file_blob;
- var ret = new Sector_RawBlob { Blob = file_blob, Offset = file_ofs };
+ var ret = new Tuple(file_blob, file_ofs);
if (file_ofs + required > file_len)
{
job.Warn("Zero-padding mis-sized file: " + Path.GetFileName(file_command.Path));
blob = Disc.Blob_ZeroPadBuffer.MakeBufferFrom(file_blob,file_ofs,required);
resources.Add(blob);
- ret.Blob = blob;
- ret.Offset = 0;
+ ret = new Tuple(blob,0);
}
file_ofs += required;
return ret;
@@ -395,6 +393,7 @@ namespace BizHawk.Emulation.DiscSystem
Action writeSector = (SectorWriteType type) =>
{
ISector siface = null;
+ SS_Base ss = null;
if (type == SectorWriteType.Normal)
{
@@ -406,22 +405,32 @@ namespace BizHawk.Emulation.DiscSystem
case CueFile.TrackType.CDI_2352:
case CueFile.TrackType.Mode1_2352:
- case CueFile.TrackType.Mode2_2352:
- case CueFile.TrackType.Audio:
- //these cases are all 2352 bytes.
- //in all these cases, either no ECM is present or ECM is provided. so we just emit a Sector_RawBlob
- siface = eatBlobAndWrap(2352);
break;
+ case CueFile.TrackType.Mode2_2352:
+ {
+ var t = eatBlobAndWrap(2352);
+ ss = new SS_2352() { Blob = t.Item1, BlobOffset = t.Item2 };
+ break;
+ }
+
+ case CueFile.TrackType.Audio:
+ {
+ var t = eatBlobAndWrap(2352);
+ ss = new SS_2352() { Blob = t.Item1, BlobOffset = t.Item2 };
+ break;
+ }
+
case CueFile.TrackType.Mode1_2048:
{
//2048 bytes are present. ECM needs to be generated to create a full raw sector
- var raw = eatBlobAndWrap(2048);
- siface = new Sector_Mode1_2048(LBA + 150) //pass the ABA I guess
- {
- Blob = new ECMCacheBlob(raw.Blob), //archaic
- Offset = raw.Offset
- };
+ //var raw = eatBlobAndWrap(2048);
+ //siface = new Sector_Mode1_2048(LBA + 150) //pass the ABA I guess
+ //{
+ // Blob = new ECMCacheBlob(raw.Blob), //archaic
+ // Offset = raw.Offset
+ //};
+ //TODO
break;
}
@@ -433,13 +442,13 @@ namespace BizHawk.Emulation.DiscSystem
}
else if (type == SectorWriteType.Postgap)
{
- //TODO - does subchannel need to get written differently?
- siface = zero_sector;
+ //TODO
+ //siface = zero_sector;
+ throw new InvalidOperationException("cue postgap broken right now");
}
else if (type == SectorWriteType.Pregap)
{
- //TODO - does subchannel need to get written differently?
- siface = zero_sector;
+ ss = new SS_Pregap();
}
//make the subcode
@@ -483,7 +492,6 @@ namespace BizHawk.Emulation.DiscSystem
//second interval: at least 150 sectors coded as user data track.
//so... we ASSUME the 150 sector pregap is more important. so if thats all there is, theres no 75 sector pregap like the old track
//if theres a longer pregap, then we generate weird old track pregap to contain the rest.
- //TODO - GENERATE P SUBCHANNEL
if (track_relative_msf > 150)
{
//only if we're burning a data track now
@@ -501,8 +509,9 @@ namespace BizHawk.Emulation.DiscSystem
priorSubchannelQ = sq;
//now we have the ISector and subcode; make the SectorEntry
- var se = new SectorEntry(siface);
- se.SubcodeSector = subcode;
+ var se = new SectorEntry(null);
+ se.SectorSynth = ss;
+ ss.sq = sq;
disc.Sectors.Add(se);
LBA++;
file_ownmsf++;
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
new file mode 100644
index 0000000000..0dcb4dd240
--- /dev/null
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
@@ -0,0 +1,84 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace BizHawk.Emulation.DiscSystem
+{
+ partial class CUE_Format2
+ {
+ abstract class SS_Base : ISectorSynthJob2448
+ {
+ public SubchannelQ sq;
+
+ public abstract void Synth(SectorSynthJob job);
+ }
+
+ class SS_Mode1_2048 : SS_Base
+ {
+ public override void Synth(SectorSynthJob job)
+ {
+ }
+ }
+
+
+ static class SubSynth
+ {
+ public static void P(byte[] buffer, int offset, bool pause)
+ {
+ byte val = (byte)(pause?0xFF:0x00);
+ for (int i = 0; i < 12; i++)
+ buffer[offset + i] = val;
+ }
+ }
+
+ ///
+ /// Represents a pregap sector
+ ///
+ class SS_Pregap : SS_Base
+ {
+ public override void Synth(SectorSynthJob job)
+ {
+ if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
+ {
+ SubSynth.P(job.DestBuffer2448, job.DestOffset + 2352, false); //for now....
+ }
+
+ if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
+ {
+ var subcode = new BufferedSubcodeSector();
+ subcode.Synthesize_SubchannelQ(ref sq, true);
+ Buffer.BlockCopy(subcode.SubcodeDeinterleaved, 12, job.DestBuffer2448, job.DestOffset + 2352 + 12, 12);
+ }
+ }
+ }
+
+ ///
+ /// Represents a Mode1 or Mode2 2352-byte sector
+ ///
+ class SS_2352 : SS_Base
+ {
+ public IBlob Blob;
+ public long BlobOffset;
+ public override void Synth(SectorSynthJob job)
+ {
+ //read the sector user data
+ Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset, 2352);
+
+ //if subcode is needed, synthesize it
+
+ if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
+ {
+ SubSynth.P(job.DestBuffer2448, job.DestOffset + 2352, false); //for now....
+ }
+
+ if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
+ {
+ var subcode = new BufferedSubcodeSector();
+ subcode.Synthesize_SubchannelQ(ref sq, true);
+ Buffer.BlockCopy(subcode.SubcodeDeinterleaved, 12, job.DestBuffer2448, job.DestOffset + 2352 + 12, 12);
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs b/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
index 507df7761e..876c4b030d 100644
--- a/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
+++ b/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
@@ -53,9 +53,20 @@ namespace BizHawk.Emulation.DiscSystem
User2336 = (User2048|ECC276|EDC12),
///
- /// The entirety of the sector userdata is required
+ /// The complete sector userdata (2352 bytes) is required
///
- User2352 = 15,
+ UserComplete = 15,
+
+ ///
+ /// An alias for UserComplete
+ ///
+ UserAny = UserComplete,
+
+ ///
+ /// An alias for UserComplete
+ ///
+ User2352 = UserComplete,
+
///
/// SubP is required
@@ -134,7 +145,7 @@ namespace BizHawk.Emulation.DiscSystem
///
/// this ISector is dumb and only knows how to drag chunks off a source blob
- /// TODO - actually make it that way!
+ /// TODO - garbage, delete me
///
public class Sector_RawBlob : ISector
{