Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
disc: added Subchannel Q support - LibCrypt games are playable
- Loading branch information
Showing
with
248 additions
and 40 deletions.
- +4 −0 README.md
- +4 −0 src/device/cdrom/cdrom.cpp
- +1 −0 src/device/cdrom/cdrom.h
- +25 −29 src/device/cdrom/commands.cpp
- +105 −0 src/disc/disc.cpp
- +10 −0 src/disc/disc.h
- +2 −0 src/disc/format/chd_format.cpp
- +7 −7 src/disc/format/cue.cpp
- +6 −3 src/disc/format/cue_parser.cpp
- +11 −1 src/disc/position.h
- +43 −0 src/disc/subchannel_q.cpp
- +30 −0 src/disc/subchannel_q.h
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -183,6 +183,7 @@ class CDROM { | ||
|
||
disc::TrackType trackType; | ||
std::unique_ptr<disc::Disc> disc; | ||
disc::SubchannelQ lastQ; | ||
bool mute = false; | ||
|
||
CDROM(System* sys); | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,105 @@ | ||
#include "disc.h" | ||
#include "utils/file.h" | ||
|
||
namespace disc { | ||
SubchannelQ Disc::getSubQ(Position pos) { | ||
if (modifiedQ.find(pos) != modifiedQ.end()) { | ||
return modifiedQ[pos]; | ||
} | ||
|
||
TrackType type = read(pos).second; | ||
int track = getTrackByPosition(pos); | ||
auto posInTrack = pos - getTrackStart(track); | ||
|
||
return SubchannelQ::generateForPosition(track, pos, posInTrack, type == TrackType::AUDIO); | ||
} | ||
|
||
bool Disc::loadSubchannel(const std::string& path) { | ||
std::string basePath = getPath(path) + getFilename(path); | ||
|
||
if (auto f = getFileContents(basePath + ".lsd"); !f.empty()) { | ||
return loadLsd(f); | ||
} | ||
if (auto f = getFileContents(basePath + ".sbi"); !f.empty()) { | ||
return loadSbi(f); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool Disc::loadLsd(const std::vector<uint8_t>& lsd) { | ||
if (lsd.empty()) { | ||
printf("[DISC] LSD file is empty\n"); | ||
return false; | ||
} | ||
|
||
const int bytesPerEntry = 15; | ||
const int count = lsd.size() / bytesPerEntry; | ||
|
||
for (int i = 0; i < count; i++) { | ||
int p = bytesPerEntry * i; | ||
|
||
int mm = bcd::toBinary(lsd[p + 0]); | ||
int ss = bcd::toBinary(lsd[p + 1]); | ||
int ff = bcd::toBinary(lsd[p + 2]); | ||
|
||
Position pos(mm, ss, ff); | ||
|
||
SubchannelQ q; | ||
q.control._ = lsd[p + 3]; | ||
for (int j = 0; j < 9; j++) { | ||
q.data[j] = lsd[p + 4 + j]; | ||
} | ||
q.crc16 = (lsd[p + 12] << 8) | lsd[p + 13]; | ||
|
||
modifiedQ[pos] = q; | ||
} | ||
|
||
printf("[DISC] Loaded LSD file\n"); | ||
return true; | ||
} | ||
|
||
bool Disc::loadSbi(const std::vector<uint8_t>& sbi) { | ||
if (sbi.empty()) { | ||
printf("[DISC] SBI file is empty\n"); | ||
return false; | ||
} | ||
|
||
if (sbi[0] != 'S' || sbi[1] != 'B' || sbi[2] != 'I' || sbi[3] != '\0') { | ||
printf("[DISC] Invalid sbi header\n"); | ||
return false; | ||
} | ||
|
||
const int headerSize = 4; | ||
const int bytesPerEntry = 14; | ||
const int count = (sbi.size() - headerSize) / bytesPerEntry; | ||
|
||
for (int i = 0; i < count; i++) { | ||
int p = headerSize + bytesPerEntry * i; | ||
|
||
int mm = bcd::toBinary(sbi[p + 0]); | ||
int ss = bcd::toBinary(sbi[p + 1]); | ||
int ff = bcd::toBinary(sbi[p + 2]); | ||
int dummy = sbi[p + 3]; | ||
if (dummy != 1) { | ||
printf("[DISC] Unsupported .sbi file, please create an issue on Github and attach this .sbi\n"); | ||
return false; | ||
} | ||
|
||
Position pos(mm, ss, ff); | ||
|
||
SubchannelQ q; | ||
q.control._ = sbi[p + 4]; | ||
for (int j = 0; j < 9; j++) { | ||
q.data[j] = sbi[p + 5 + j]; | ||
} | ||
// Sbi does not include CRC-16, LibCrypt checks only if crc is broken | ||
q.crc16 = ~q.calculateCrc(); | ||
|
||
modifiedQ[pos] = q; | ||
} | ||
|
||
printf("[DISC] Loaded SBI file\n"); | ||
return true; | ||
} | ||
} // namespace disc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -76,6 +76,8 @@ std::unique_ptr<Chd> Chd::open(const std::string& path) { | ||
chd->tracks.push_back(track); | ||
} | ||
|
||
chd->loadSubchannel(path); | ||
|
||
return chd; | ||
} | ||
|
||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,43 @@ | ||
#include "subchannel_q.h" | ||
|
||
namespace disc { | ||
|
||
SubchannelQ SubchannelQ::generateForPosition(int track, disc::Position pos, disc::Position posInTrack, bool isAudio) { | ||
SubchannelQ q; | ||
q.control.adr = 1; | ||
q.control.data = !isAudio; | ||
|
||
q.data[0] = bcd::toBcd(track + 1); // Track | ||
q.data[1] = bcd::toBcd(1); // Index | ||
q.data[2] = bcd::toBcd(posInTrack.mm); // M - Track | ||
q.data[3] = bcd::toBcd(posInTrack.ss); // S - Track | ||
q.data[4] = bcd::toBcd(posInTrack.ff); // F - Track | ||
q.data[5] = 0; // Reserved | ||
q.data[6] = bcd::toBcd(pos.mm); // M - Disc | ||
q.data[7] = bcd::toBcd(pos.ss); // S - Disc | ||
q.data[8] = bcd::toBcd(pos.ff); // F - Disc | ||
q.crc16 = q.calculateCrc(); | ||
|
||
return q; | ||
} | ||
|
||
uint16_t SubchannelQ::calculateCrc() { | ||
uint8_t lsb = 0; | ||
uint8_t msb = 0; | ||
for (int i = 0; i < 0x0a; i++) { | ||
uint8_t x; | ||
if (i == 0) { | ||
x = control._; | ||
} else { | ||
x = data[i - 1]; | ||
} | ||
x ^= msb; | ||
x = x ^ (x >> 4); | ||
msb = lsb ^ (x >> 3) ^ (x << 4); | ||
lsb = x ^ (x << 5); | ||
} | ||
return msb << 8 | lsb; | ||
} | ||
|
||
bool SubchannelQ::validCrc() { return crc16 == calculateCrc(); } | ||
}; // namespace disc |
Oops, something went wrong.