protected void SynthSubchannelAsNeed(SectorSynthJob job) { //synth P if needed if ((job.Parts & ESectorSynthPart.SubchannelP) != 0) { SynthUtils.SubP(job.DestBuffer2448, job.DestOffset + 2352, Pause); } //synth Q if needed //TODO - why not already have it serialized? Into a disc resource, even. if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0) { SynthUtils.SubQ_Serialize(job.DestBuffer2448, job.DestOffset + 2352 + 12, ref sq); } //clear R-W if needed if ((job.Parts & ESectorSynthPart.Subchannel_RSTUVW) != 0) { Array.Clear(job.DestBuffer2448, job.DestOffset + 2352 + 12 + 12, (12 * 6)); } //subcode has been generated deinterleaved; we may still need to interleave it if ((job.Parts & ESectorSynthPart.SubcodeAny) != 0) { if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0) { SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352); } } }
public void Synth(SectorSynthJob job) { //CCD is always containing everything we'd need (unless a .sub is missing?) so don't worry about flags var imgBlob = job.Disc.DisposableResources[0] as IBlob; var subBlob = job.Disc.DisposableResources[1] as IBlob; //Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset); //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) { long ofs = job.LBA * 96; subBlob.Read(ofs, job.DestBuffer2448, 2352, 96); //subcode comes to us deinterleved; we may still need to interleave it if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0) { SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352); } } }
public void Synth(SectorSynthJob job) { //mednafen is always synthesizing everything, no need to worry about flags.. mostly./ job.Params.MednaDisc.Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset); //we may still need to deinterleave it if subcode was requested and it needs deinterleaving if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave | ESectorSynthPart.SubcodeAny)) != 0) { SynthUtils.DeinterleaveSubcodeInplace(job.DestBuffer2448, 2352); } }
/// <summary> /// applies an SBI file to the disc /// </summary> public void Run(Disc disc, SBI.SubQPatchData sbi, bool asMednafen) { //TODO - could implement as a blob, to avoid allocating so many byte buffers //save this, it's small, and we'll want it for disc processing a/b checks disc.Memos["sbi"] = sbi; DiscSectorReader dsr = new DiscSectorReader(disc); int n = sbi.ABAs.Count; int b = 0; for (int i = 0; i < n; i++) { int lba = sbi.ABAs[i] - 150; //create a synthesizer which can return the patched data var ss_patchq = new SS_PatchQ { Original = disc._Sectors[lba + 150] }; byte[] subQbuf = ss_patchq.Buffer_SubQ; //read the old subcode dsr.ReadLBA_SubQ(lba, subQbuf, 0); //insert patch disc._Sectors[lba + 150] = ss_patchq; //apply SBI patch for (int j = 0; j < 12; j++) { short patch = sbi.subq[b++]; if (patch == -1) { continue; } else { subQbuf[j] = (byte)patch; } } //Apply mednafen hacks //The reasoning here is that we know we expect these sectors to have a wrong checksum. therefore, generate a checksum, and make it wrong //However, this seems senseless to me. The whole point of the SBI data is that it stores the patches needed to generate an acceptable subQ, right? if (asMednafen) { SynthUtils.SubQ_SynthChecksum(subQbuf, 0); subQbuf[10] ^= 0xFF; subQbuf[11] ^= 0xFF; } } }
public override void Synth(SectorSynthJob job) { //read the sector user data if ((job.Parts & ESectorSynthPart.User2048) != 0) { Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset + 16, 2048); } if ((job.Parts & ESectorSynthPart.Header16) != 0) { SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, 1); } if ((job.Parts & ESectorSynthPart.ECMAny) != 0) { SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA); } SynthSubchannelAsNeed(job); }
public override void Synth(SectorSynthJob job) { //this isn't fully analyzed/optimized Array.Clear(job.DestBuffer2448, job.DestOffset, 2352); byte mode = 255; int form = -1; switch (TrackType) { case CueTrackType.Audio: mode = 0; break; case CueTrackType.CDI_2352: case CueTrackType.Mode1_2352: mode = 1; break; case CueTrackType.Mode2_2352: mode = 2; if (Policy.CUE_PregapMode2_As_XA_Form2) { job.DestBuffer2448[job.DestOffset + 12 + 6] = 0x20; job.DestBuffer2448[job.DestOffset + 12 + 10] = 0x20; } form = 2; //no other choice right now really break; case CueTrackType.Mode1_2048: mode = 1; Pause = true; break; case CueTrackType.Mode2_2336: default: throw new InvalidOperationException("Not supported: " + TrackType); } //audio has no sector header but the others do if (mode != 0) { if ((job.Parts & ESectorSynthPart.Header16) != 0) { SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, mode); } } if (mode == 1) { if ((job.Parts & ESectorSynthPart.ECMAny) != 0) { SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA); } } if (mode == 2 && form == 2) { SynthUtils.EDC_Mode2_Form2(job.DestBuffer2448, job.DestOffset); } SynthSubchannelAsNeed(job); }