Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- typedef struct {
- bool isAudio; // If true, the track was CD-DA and not DATA
- uint8_t track_start[3]; // MSF Format
- uint8_t track_length[3];// MSF Format
- FILE* handle; // Each track needs to be associated with a file handle
- uint32_t offset; // Byte Offset to the track within the binary file
- } cd_track_info_t;
- void CDController::MountDiscImage(std::string filename)
- {
- discImageMounted = false;
- std::string current = "";
- std::string currentFilePath = "";
- FILE* currentFileHandle = nullptr;
- trackCount = 0;
- int currentTrack = 0;
- uint32_t currentFileSize = 0;
- uint32_t currentFileFrameCount = 0;
- uint32_t currentFrameOffset = 2 * CD_FRAMES_PER_SECOND; // All CD-ROM images have an unspecified 2 second pregap
- uint32_t fileCount = 0;
- std::ifstream cueFile(filename);
- for (std::string line; std::getline(cueFile, line);) {
- std::stringstream lineStream(line);
- std::string command; lineStream >> command;
- // TODO: Support Pregap/postgap
- if (command == "FILE") {
- size_t first = line.find_first_of('"') + 1;
- size_t last = line.find_last_of('"');
- currentFilePath = line.substr(first, last - first);
- currentFileHandle = nullptr;
- fileCount++;
- }
- if (command == "TRACK") {
- lineStream >> currentTrack;
- // TODO : Warn user about unvalid or out-of-range TRACK numbers?
- currentTrack--;
- // We got a track using the current file, so open a handle to it, if we don't already have one
- if (!currentFileHandle) {
- // If this was NOT the first file in the track, increment the current Frame Offset based on the previous file
- if (fileCount > 1) {
- currentFrameOffset += currentFileFrameCount;
- }
- currentFileHandle = fopen(currentFilePath.c_str(), "rb");
- if (currentFileHandle) {
- fseek(currentFileHandle, 0, SEEK_END);
- currentFileSize = ftell(currentFileHandle);
- fseek(currentFileHandle, 0, SEEK_SET);
- currentFileFrameCount = currentFileSize / CD_RAW_BYTES_PER_FRAME;
- }
- }
- // Store the current file handle in the current track metadata
- tracks[currentTrack].handle = currentFileHandle;
- // Parse the track type
- std::string type; lineStream >> type;
- if (type == "AUDIO") {
- tracks[currentTrack].isAudio = true;
- } else {
- tracks[currentTrack].isAudio = false;
- }
- if (trackCount <= currentTrack) {
- trackCount = currentTrack + 1;
- }
- }
- if (command == "INDEX") {
- uint32_t temp; std::string msfStr;
- lineStream >> temp;
- lineStream >> msfStr;
- GetMsfFromString(tracks[currentTrack].track_start, msfStr);
- // Parse the start MSF from the cuesheet, and apply it to be relative to the overall image
- // rather than per-file
- temp = GetSectorFromMsf(tracks[currentTrack].track_start);
- tracks[currentTrack].offset = temp * CD_RAW_BYTES_PER_FRAME;
- temp += currentFrameOffset;
- GetMsfFromSector(tracks[currentTrack].track_start, temp);
- // Set the track length to the remaining length of the input file
- temp = currentFileFrameCount - (tracks[currentTrack].offset / CD_RAW_BYTES_PER_FRAME);
- GetMsfFromSector(tracks[currentTrack].track_length, temp);
- // TODO: Support the case when multiple tracks use the same file index
- }
- }
- discImageMounted = true;
- }
- uint32_t CDController::GetSectorFromMsf(uint8_t *msf)
- {
- return ((msf[0] * CD_FRAMES_PER_MINUTE + msf[1]) * CD_FRAMES_PER_SECOND) + msf[2];
- }
- void CDController::GetMsfFromSector(uint8_t* msf, uint32_t sector)
- {
- msf[0] = sector / CD_FRAMES_PER_SECOND / CD_FRAMES_PER_MINUTE;
- sector = sector - msf[0] * CD_FRAMES_PER_SECOND * CD_FRAMES_PER_MINUTE;
- msf[1] = sector / CD_FRAMES_PER_SECOND;
- sector = sector - msf[1] * CD_FRAMES_PER_SECOND;
- msf[2] = sector;
- }
- void CDController::GetMsfFromString(uint8_t* msf, std::string str)
- {
- std::replace(str.begin(), str.end(), ':', '\n');
- std::stringstream msfStr(str);
- int m, s, f;
- msfStr >> m;
- msfStr >> s;
- msfStr >> f;
- msf[0] = m;
- msf[1] = s;
- msf[2] = f;
- }
- uint8_t CDController::BcdToUint8(uint8_t value)
- {
- return value - 6 * (value >> 4);
- }
- uint8_t CDController::Uint8ToBcd(uint8_t value)
- {
- return value + 6 * (value / 10);
- }
- void CDController::ProcessReadOperation()
- {
- uint32_t trackStartSector = 0;
- int track = 0;
- for (track = trackCount - 1; ; track--) {
- trackStartSector = GetSectorFromMsf(tracks[track].track_start);
- if (trackStartSector <= CurrentSector) {
- break;
- }
- // Prevent overflow
- if (track == 0) {
- break;
- }
- }
- // TODO: Handle the case when we read past the end of a disc
- // We only support raw bin images, 2352 bytes per sector, this is because the PS1 hardware
- // interleaves data into the extra bytes on-top of the user-data region
- uint32_t frameStart = ((CurrentSector - trackStartSector) * (CD_RAW_BYTES_PER_FRAME));
- fseek(tracks[track].handle, tracks[track].offset + frameStart, SEEK_SET);
- fread(readBuffer, 1, CD_RAW_BYTES_PER_FRAME, tracks[track].handle);
- // Processing code goes here
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement