cdvdgigaherz: Use a formatted TOC instead of a raw TOC

It's simpler and provides almost the same information. The only
information that might be lost is the first track specific track type.
This commit is contained in:
Jonathan Li 2016-10-22 21:17:39 +01:00
parent 327515366f
commit 95b98c5a38
4 changed files with 48 additions and 125 deletions

View File

@ -390,9 +390,6 @@ s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer)
s32 CALLBACK CDVDgetTOC(u8 *tocBuff)
{
//return src->ReadTOC((char*)toc,2048);
//that didn't work too well...
if (curDiskType == CDVD_TYPE_NODISC)
return -1;

View File

@ -23,6 +23,7 @@
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#define CDVDdefs
#include <PS2Edefs.h>
@ -40,28 +41,13 @@ extern track tracks[100];
extern int curDiskType;
extern int curTrayStatus;
typedef struct _toc_entry
struct toc_entry
{
UCHAR SessionNumber;
UCHAR Control : 4;
UCHAR Adr : 4;
UCHAR Reserved1;
UCHAR Point;
UCHAR MsfExtra[3];
UCHAR Zero;
UCHAR Msf[3];
} toc_entry;
typedef struct _toc_data
{
UCHAR Length[2];
UCHAR FirstCompleteSession;
UCHAR LastCompleteSession;
toc_entry Descriptors[255];
} toc_data;
extern toc_data cdtoc;
u32 lba;
u8 track;
u8 adr : 4;
u8 control : 4;
};
class IOCtlSrc
{
@ -76,7 +62,7 @@ class IOCtlSrc
s32 m_media_type = 0;
u32 m_sectors = 0;
u32 m_layer_break = 0;
char tocCacheData[2048];
std::vector<toc_entry> m_toc;
bool ReadDVDInfo();
bool ReadCDInfo();
@ -87,7 +73,7 @@ public:
~IOCtlSrc();
u32 GetSectorCount();
s32 ReadTOC(char *toc, size_t size);
const std::vector<toc_entry> &ReadTOC();
s32 ReadSectors2048(u32 sector, u32 count, char *buffer);
s32 ReadSectors2352(u32 sector, u32 count, char *buffer);
u32 GetLayerBreakAddress();
@ -109,8 +95,6 @@ extern char source_drive;
extern HINSTANCE hinst;
#define MSF_TO_LBA(m, s, f) ((m * 60 + s) * 75 + f - 150)
void ReadSettings();
void WriteSettings();
void CfgSetSettingsDir(const char *dir);
@ -130,6 +114,6 @@ char *cdvdGetSector(s32 sector, s32 mode);
s32 cdvdDirectReadSector(s32 first, s32 mode, char *buffer);
s32 cdvdGetMediaType();
s32 cdvdRefreshData();
s32 cdvdParseTOC();
void cdvdParseTOC();
#endif /* __CDVD_H__ */

View File

@ -15,104 +15,40 @@
#include "CDVD.h"
toc_data cdtoc;
#include <algorithm>
s32 cdvdParseTOC()
void cdvdParseTOC()
{
memset(&cdtoc, 0, sizeof(cdtoc));
tracks[0].start_lba = 0;
tracks[0].type = 0;
tracks[1].start_lba = 0;
if (!src->GetSectorCount()) {
curDiskType = CDVD_TYPE_NODISC;
strack = 1;
etrack = 0;
return 0;
return;
}
s32 mt = src->GetMediaType();
if (mt >= 0) {
tracks[1].type = 0;
if (src->GetMediaType() >= 0) {
tracks[1].type = CDVD_MODE1_TRACK;
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].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 ((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;
}
}
return;
}
return 0;
strack = 0xFF;
etrack = 0;
for (auto &entry : src->ReadTOC()) {
if (entry.track < 1 || entry.track > 99)
continue;
strack = std::min(strack, entry.track);
etrack = std::max(etrack, entry.track);
tracks[entry.track].start_lba = entry.lba;
if (!(entry.control & 0x04))
tracks[entry.track].type = CDVD_AUDIO_TRACK;
else
tracks[entry.track].type = CDVD_MODE1_TRACK;
fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba);
}
}

View File

@ -27,7 +27,6 @@
#include <cstddef>
#include <cstdlib>
#include <algorithm>
#include <array>
IOCtlSrc::IOCtlSrc(const char *filename)
@ -140,17 +139,12 @@ s32 IOCtlSrc::GetMediaType()
return m_media_type;
}
s32 IOCtlSrc::ReadTOC(char *toc, size_t size)
const std::vector<toc_entry> &IOCtlSrc::ReadTOC()
{
if (!m_disc_ready)
RefreshDiscInfo();
if (GetMediaType() >= 0)
return -1;
memcpy(toc, tocCacheData, std::min(size, sizeof(tocCacheData)));
return 0;
return m_toc;
}
s32 IOCtlSrc::ReadSectors2048(u32 sector, u32 count, char *buffer)
@ -307,14 +301,26 @@ bool IOCtlSrc::ReadCDInfo()
{
DWORD unused;
CDROM_READ_TOC_EX toc_ex{};
toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
toc_ex.Msf = 1;
toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
toc_ex.Msf = 0;
toc_ex.SessionTrack = 1;
CDROM_TOC toc;
if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &toc_ex,
sizeof(toc_ex), tocCacheData, sizeof(tocCacheData), &unused, nullptr))
sizeof(toc_ex), &toc, sizeof(toc), &unused, nullptr))
return false;
m_toc.clear();
size_t track_count = ((toc.Length[0] << 8) + toc.Length[1] - 2) / sizeof(TRACK_DATA);
for (size_t n = 0; n < track_count; ++n) {
TRACK_DATA &track = toc.TrackData[n];
// Exclude the lead-out track descriptor.
if (track.TrackNumber == 0xAA)
continue;
u32 lba = (track.Address[1] << 16) + (track.Address[2] << 8) + track.Address[3];
m_toc.push_back({lba, track.TrackNumber, track.Adr, track.Control});
}
GET_LENGTH_INFORMATION info;
if (!DeviceIoControl(m_device, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &info,
sizeof(info), &unused, nullptr))