Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.95 KB | None | 0 0
  1. typedef struct {
  2.     bool isAudio;           // If true, the track was CD-DA and not DATA
  3.     uint8_t track_start[3]; // MSF Format
  4.     uint8_t track_length[3];// MSF Format
  5.     FILE* handle;           // Each track needs to be associated with a file handle
  6.     uint32_t offset;        // Byte Offset to the track within the binary file
  7. } cd_track_info_t;
  8.  
  9. void CDController::MountDiscImage(std::string filename)
  10. {
  11.     discImageMounted = false;
  12.     std::string current = "";
  13.     std::string currentFilePath = "";
  14.     FILE* currentFileHandle = nullptr;
  15.     trackCount = 0;
  16.     int currentTrack = 0;
  17.     uint32_t currentFileSize = 0;
  18.     uint32_t currentFileFrameCount = 0;
  19.     uint32_t currentFrameOffset = 2 * CD_FRAMES_PER_SECOND; // All CD-ROM images have an unspecified 2 second pregap
  20.     uint32_t fileCount = 0;
  21.  
  22.  
  23.     std::ifstream cueFile(filename);
  24.     for (std::string line; std::getline(cueFile, line);) {
  25.         std::stringstream lineStream(line);
  26.         std::string command; lineStream >> command;
  27.  
  28.         // TODO: Support Pregap/postgap
  29.         if (command == "FILE") {
  30.             size_t first = line.find_first_of('"') + 1;
  31.             size_t last = line.find_last_of('"');
  32.             currentFilePath = line.substr(first, last - first);
  33.             currentFileHandle = nullptr;
  34.             fileCount++;
  35.         }
  36.  
  37.         if (command == "TRACK") {
  38.             lineStream >> currentTrack;
  39.             // TODO : Warn user about unvalid or out-of-range TRACK numbers?
  40.             currentTrack--;
  41.  
  42.             // We got a track using the current file, so open a handle to it, if we don't already have one
  43.             if (!currentFileHandle) {
  44.                 // If this was NOT the first file in the track, increment the current Frame Offset based on the previous file
  45.                 if (fileCount > 1) {
  46.                     currentFrameOffset += currentFileFrameCount;
  47.                 }
  48.  
  49.                 currentFileHandle = fopen(currentFilePath.c_str(), "rb");
  50.                 if (currentFileHandle) {
  51.                     fseek(currentFileHandle, 0, SEEK_END);
  52.                     currentFileSize = ftell(currentFileHandle);
  53.                     fseek(currentFileHandle, 0, SEEK_SET);
  54.                     currentFileFrameCount = currentFileSize / CD_RAW_BYTES_PER_FRAME;
  55.                 }
  56.             }
  57.  
  58.             // Store the current file handle in the current track metadata
  59.             tracks[currentTrack].handle = currentFileHandle;
  60.  
  61.             // Parse the track type
  62.             std::string type; lineStream >> type;
  63.             if (type == "AUDIO") {
  64.                 tracks[currentTrack].isAudio = true;
  65.             } else {
  66.                 tracks[currentTrack].isAudio = false;
  67.             }
  68.  
  69.             if (trackCount <= currentTrack) {
  70.                 trackCount = currentTrack + 1;
  71.             }
  72.         }
  73.  
  74.         if (command == "INDEX") {
  75.             uint32_t temp; std::string msfStr;
  76.             lineStream >> temp;
  77.             lineStream >> msfStr;
  78.             GetMsfFromString(tracks[currentTrack].track_start, msfStr);
  79.  
  80.             // Parse the start MSF from the cuesheet, and apply it to be relative to the overall image
  81.             // rather than per-file
  82.             temp = GetSectorFromMsf(tracks[currentTrack].track_start);
  83.             tracks[currentTrack].offset = temp * CD_RAW_BYTES_PER_FRAME;
  84.             temp += currentFrameOffset;
  85.             GetMsfFromSector(tracks[currentTrack].track_start, temp);
  86.  
  87.             // Set the track length to the remaining length of the input file
  88.             temp = currentFileFrameCount - (tracks[currentTrack].offset / CD_RAW_BYTES_PER_FRAME);
  89.             GetMsfFromSector(tracks[currentTrack].track_length, temp);
  90.  
  91.             // TODO: Support the case when multiple tracks use the same file index
  92.         }
  93.     }
  94.  
  95.     discImageMounted = true;
  96. }
  97.  
  98. uint32_t CDController::GetSectorFromMsf(uint8_t *msf)
  99. {
  100.     return ((msf[0] * CD_FRAMES_PER_MINUTE + msf[1]) * CD_FRAMES_PER_SECOND) + msf[2];
  101. }
  102.  
  103. void CDController::GetMsfFromSector(uint8_t* msf, uint32_t sector)
  104. {
  105.     msf[0] = sector / CD_FRAMES_PER_SECOND / CD_FRAMES_PER_MINUTE;
  106.     sector = sector - msf[0] * CD_FRAMES_PER_SECOND * CD_FRAMES_PER_MINUTE;
  107.     msf[1] = sector / CD_FRAMES_PER_SECOND;
  108.     sector = sector - msf[1] * CD_FRAMES_PER_SECOND;
  109.     msf[2] = sector;
  110. }
  111.  
  112. void CDController::GetMsfFromString(uint8_t* msf, std::string str)
  113. {
  114.     std::replace(str.begin(), str.end(), ':', '\n');
  115.     std::stringstream msfStr(str);
  116.     int m, s, f;
  117.     msfStr >> m;
  118.     msfStr >> s;
  119.     msfStr >> f;
  120.  
  121.     msf[0] = m;
  122.     msf[1] = s;
  123.     msf[2] = f;
  124. }
  125.  
  126. uint8_t CDController::BcdToUint8(uint8_t value)
  127. {
  128.     return value - 6 * (value >> 4);
  129. }
  130.  
  131. uint8_t CDController::Uint8ToBcd(uint8_t value)
  132. {
  133.     return value + 6 * (value / 10);
  134. }
  135.  
  136. void CDController::ProcessReadOperation()
  137. {
  138.     uint32_t trackStartSector = 0;
  139.     int track = 0;
  140.     for (track = trackCount - 1; ; track--) {
  141.         trackStartSector = GetSectorFromMsf(tracks[track].track_start);
  142.         if (trackStartSector <= CurrentSector) {
  143.             break;
  144.         }
  145.  
  146.         // Prevent overflow
  147.         if (track == 0) {
  148.             break;
  149.         }
  150.     }
  151.  
  152.     // TODO: Handle the case when we read past the end of a disc
  153.  
  154.     // We only support raw bin images, 2352 bytes per sector, this is because the PS1 hardware
  155.     // interleaves data into the extra bytes on-top of the user-data region
  156.     uint32_t frameStart = ((CurrentSector - trackStartSector) * (CD_RAW_BYTES_PER_FRAME));
  157.     fseek(tracks[track].handle, tracks[track].offset + frameStart, SEEK_SET);
  158.     fread(readBuffer, 1, CD_RAW_BYTES_PER_FRAME, tracks[track].handle);
  159.  
  160.     // Processing code goes here
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement