work on bringing back cue loading
This commit is contained in:
parent
4b8d3cfa79
commit
d698bb8059
|
@ -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;
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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++)
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue