work on bringing back cue loading

This commit is contained in:
zeromus 2015-06-28 03:51:45 -05:00
parent 4b8d3cfa79
commit d698bb8059
7 changed files with 164 additions and 93 deletions

View File

@ -46,6 +46,13 @@ namespace BizHawk.Emulation.DiscSystem
/// How about .sub files? Can't remember right now.
/// </summary>
public bool DeinterleavedSubcode = true;
/// <summary>
/// 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.
/// </summary>
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
/// <summary>
@ -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;

View File

@ -75,6 +75,7 @@
<Compile Include="CUE\CUE_Format.cs" />
<Compile Include="CUE\CUE_Load.cs" />
<Compile Include="CUE\CUE_Parse.cs" />
<Compile Include="CUE\CUE_Synths.cs" />
<Compile Include="Decoding.cs" />
<Compile Include="Disc.cs" />
<Compile Include="DiscTypes.cs" />

View File

@ -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;
}
}
}

View File

@ -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++)

View File

@ -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<int,Sector_RawBlob> eatBlobAndWrap = (required) =>
Func<int,Tuple<IBlob,long>> eatBlobAndWrap = (required) =>
{
IBlob blob = file_blob;
var ret = new Sector_RawBlob { Blob = file_blob, Offset = file_ofs };
var ret = new Tuple<IBlob,long>(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<IBlob,long>(blob,0);
}
file_ofs += required;
return ret;
@ -395,6 +393,7 @@ namespace BizHawk.Emulation.DiscSystem
Action<SectorWriteType> 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++;

View File

@ -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;
}
}
/// <summary>
/// Represents a pregap sector
/// </summary>
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);
}
}
}
/// <summary>
/// Represents a Mode1 or Mode2 2352-byte sector
/// </summary>
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);
}
}
}
}
}

View File

@ -53,9 +53,20 @@ namespace BizHawk.Emulation.DiscSystem
User2336 = (User2048|ECC276|EDC12),
/// <summary>
/// The entirety of the sector userdata is required
/// The complete sector userdata (2352 bytes) is required
/// </summary>
User2352 = 15,
UserComplete = 15,
/// <summary>
/// An alias for UserComplete
/// </summary>
UserAny = UserComplete,
/// <summary>
/// An alias for UserComplete
/// </summary>
User2352 = UserComplete,
/// <summary>
/// SubP is required
@ -134,7 +145,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// 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
/// </summary>
public class Sector_RawBlob : ISector
{