/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2014 David Quintana [gigaherz] * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCSX2. * If not, see . */ #include "CDVD.h" toc_data cdtoc; s32 cdvdParseTOC() { memset(&cdtoc, 0, sizeof(cdtoc)); s32 len = src->GetSectorCount(); tracks[0].length = len; tracks[0].start_lba = 0; tracks[0].type = 0; tracks[1].start_lba = 0; if (len <= 0) { curDiskType = CDVD_TYPE_NODISC; tracks[0].length = 0; strack = 1; etrack = 0; return 0; } s32 mt = src->GetMediaType(); if (mt >= 0) { tracks[1].length = tracks[0].length; tracks[1].type = 0; strack = 1; etrack = 1; } else { u8 min, sec, frm; if (src->ReadTOC((char *)&cdtoc, sizeof(cdtoc)) < 0) { /* printf(" * CDVD: WARNING ReadTOC() failed, trying to use MCI instead...\n"); delete src; int status = MCI_CDGetTOC(source_drive); src=new SOURCECLASS(csrc); if(status<0)*/ return -1; //return 0; } int length = (cdtoc.Length[0] << 8) | cdtoc.Length[1]; int descriptors = length / sizeof(cdtoc.Descriptors[0]); for (int i = 0; i < descriptors; i++) { switch (cdtoc.Descriptors[i].Point) { case 0xa0: if (cdtoc.Descriptors[i].SessionNumber == cdtoc.FirstCompleteSession) { strack = cdtoc.Descriptors[i].Msf[0]; } break; case 0xa1: if (cdtoc.Descriptors[i].SessionNumber == cdtoc.LastCompleteSession) { etrack = cdtoc.Descriptors[i].Msf[0]; } break; case 0xa2: // session size if (cdtoc.Descriptors[i].SessionNumber == cdtoc.LastCompleteSession) { min = cdtoc.Descriptors[i].Msf[0]; sec = cdtoc.Descriptors[i].Msf[1]; frm = cdtoc.Descriptors[i].Msf[2]; tracks[0].length = MSF_TO_LBA(min, sec, frm); tracks[0].type = 0; } break; case 0xb0: break; case 0xb1: break; case 0xb2: break; case 0xc0: break; default: if ((cdtoc.Descriptors[i].Point < 100) && (cdtoc.Descriptors[i].Point > 0)) { int tn = cdtoc.Descriptors[i].Point; min = cdtoc.Descriptors[i].Msf[0]; sec = cdtoc.Descriptors[i].Msf[1]; frm = cdtoc.Descriptors[i].Msf[2]; tracks[tn].start_lba = MSF_TO_LBA(min, sec, frm); if (tn > 1) tracks[tn - 1].length = tracks[tn].start_lba - tracks[tn - 1].start_lba; if ((cdtoc.Descriptors[i].Control & 4) == 0) { tracks[tn].type = CDVD_AUDIO_TRACK; } else if ((cdtoc.Descriptors[i].Control & 0xE) == 4) { tracks[tn].type = CDVD_MODE1_TRACK; } else { tracks[tn].type = CDVD_MODE1_TRACK; } fprintf(stderr, "Track %d: %u mins %u secs %u frames\n", tn, min, sec, frm); } else if (cdtoc.Descriptors[i].Point > 0) { printf("Found code 0x%02x\n", cdtoc.Descriptors[i].Point); } break; } } tracks[etrack].length = tracks[0].length - tracks[etrack].start_lba; } return 0; }