From c9abec7cbed3e6200de9597bb2d8e9008a0085c9 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Tue, 10 Oct 2017 21:19:22 +0100 Subject: [PATCH] cdvdgigaherz: Always read 2352 bytes from CD sectors For some CDs (i.e. Suikoden), trying to read a 2048 byte "cooked" sector does not work. However, reading the raw sector and then extracting the required 2048 bytes works fine, so let's do that. This also makes it easier to port CD/DVD disk reading to operating systems that don't provide CD/DVD interface conveniences. --- plugins/cdvdGigaherz/src/CDVD.cpp | 2 +- plugins/cdvdGigaherz/src/ReadThread.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/cdvdGigaherz/src/CDVD.cpp b/plugins/cdvdGigaherz/src/CDVD.cpp index 942d1e0496..a97e3b4634 100644 --- a/plugins/cdvdGigaherz/src/CDVD.cpp +++ b/plugins/cdvdGigaherz/src/CDVD.cpp @@ -126,7 +126,7 @@ void keepAliveThread() []() { return !s_keepalive_is_open; })) { //printf(" * keepAliveThread: polling drive.\n"); - if (g_last_sector_block.mode == CDVD_MODE_2048) + if (src->GetMediaType() >= 0) src->ReadSectors2048(g_last_sector_block.lsn, 1, throwaway); else src->ReadSectors2352(g_last_sector_block.lsn, 1, throwaway); diff --git a/plugins/cdvdGigaherz/src/ReadThread.cpp b/plugins/cdvdGigaherz/src/ReadThread.cpp index 6c10ad99f9..09c57e5385 100644 --- a/plugins/cdvdGigaherz/src/ReadThread.cpp +++ b/plugins/cdvdGigaherz/src/ReadThread.cpp @@ -111,11 +111,12 @@ void cdvdCacheReset() bool cdvdReadBlockOfSectors(u32 sector, s32 mode, u8 *data) { u32 count = std::min(sectors_per_read, src->GetSectorCount() - sector); + const s32 media = src->GetMediaType(); // TODO: Is it really necessary to retry if it fails? I'm not sure the // second time is really going to be any better. for (int tries = 0; tries < 2; ++tries) { - if (mode == CDVD_MODE_2048) { + if (media >= 0) { if (src->ReadSectors2048(sector, count, data)) return true; } else { @@ -292,7 +293,7 @@ u8 *cdvdGetSector(u32 sector, s32 mode) if (cdvdReadBlockOfSectors(sector_block, mode, buffer)) cdvdCacheUpdate(sector_block, mode, buffer); - if (mode == CDVD_MODE_2048) { + if (src->GetMediaType() >= 0) { u32 offset = 2048 * (sector - sector_block); return buffer + offset; } @@ -301,6 +302,9 @@ u8 *cdvdGetSector(u32 sector, s32 mode) u8 *data = buffer + offset; switch (mode) { + case CDVD_MODE_2048: + // Data location depends on CD mode + return (data[15] & 3) == 2 ? data + 24 : data + 16; case CDVD_MODE_2328: return data + 24; case CDVD_MODE_2340: @@ -324,7 +328,7 @@ s32 cdvdDirectReadSector(u32 sector, s32 mode, u8 *buffer) cdvdCacheUpdate(sector_block, mode, data); } - if (mode == CDVD_MODE_2048) { + if (src->GetMediaType() >= 0) { u32 offset = 2048 * (sector - sector_block); memcpy(buffer, data + offset, 2048); return 0; @@ -334,6 +338,10 @@ s32 cdvdDirectReadSector(u32 sector, s32 mode, u8 *buffer) u8 *bfr = data + offset; switch (mode) { + case CDVD_MODE_2048: + // Data location depends on CD mode + std::memcpy(buffer, (bfr[15] & 3) == 2 ? bfr + 24 : bfr + 16, 2048); + return 0; case CDVD_MODE_2328: memcpy(buffer, bfr + 24, 2328); return 0;