2013-12-19 17:10:14 +00:00
|
|
|
#include "common.h"
|
2021-08-03 08:05:09 +00:00
|
|
|
#include "stdclass.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
#include "deps/chdpsr/cdipsr.h"
|
|
|
|
|
2021-10-16 15:56:21 +00:00
|
|
|
Disc* cdi_parse(const char* file, std::vector<u8> *digest)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2021-08-03 08:05:09 +00:00
|
|
|
if (get_file_extension(file) != "cdi")
|
2020-01-31 09:35:10 +00:00
|
|
|
return nullptr;
|
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
FILE *fsource = nowide::fopen(file, "rb");
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2021-08-03 08:05:09 +00:00
|
|
|
if (fsource == nullptr)
|
2021-12-15 16:55:42 +00:00
|
|
|
{
|
2023-02-11 13:09:22 +00:00
|
|
|
WARN_LOG(GDROM, "Cannot open file '%s' errno %d", file, errno);
|
2021-08-03 08:05:09 +00:00
|
|
|
throw FlycastException(std::string("Cannot open CDI file ") + file);
|
2021-12-15 16:55:42 +00:00
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
image_s image = { 0 };
|
|
|
|
track_s track = { 0 };
|
2019-01-02 15:43:36 +00:00
|
|
|
if (!CDI_init(fsource, &image, file))
|
|
|
|
{
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(fsource);
|
2021-08-03 08:05:09 +00:00
|
|
|
throw FlycastException(std::string("Invalid CDI file ") + file);
|
2019-01-02 15:43:36 +00:00
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
CDI_get_sessions(fsource,&image);
|
|
|
|
|
2019-01-02 15:43:36 +00:00
|
|
|
Disc* rv= new Disc();
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
image.remaining_sessions = image.sessions;
|
|
|
|
|
2013-12-24 00:56:44 +00:00
|
|
|
/////////////////////////////////////////////////////////////// Loop sessions
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
bool ft=true, CD_M2=false,CD_M1=false,CD_DA=false;
|
|
|
|
|
|
|
|
while(image.remaining_sessions > 0)
|
|
|
|
{
|
|
|
|
ft=true;
|
|
|
|
image.global_current_session++;
|
|
|
|
|
|
|
|
CDI_get_tracks (fsource, &image);
|
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
image.header_position = std::ftell(fsource);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
if (image.tracks == 0)
|
2019-07-01 14:10:28 +00:00
|
|
|
INFO_LOG(GDROM, "Open session");
|
2013-12-19 17:10:14 +00:00
|
|
|
else
|
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
// Clear cuesheet
|
2013-12-19 17:10:14 +00:00
|
|
|
image.remaining_tracks = image.tracks;
|
|
|
|
|
2013-12-24 00:56:44 +00:00
|
|
|
///////////////////////////////////////////////////////////////// Loop tracks
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
while(image.remaining_tracks > 0)
|
|
|
|
{
|
|
|
|
track.global_current_track++;
|
|
|
|
track.number = image.tracks - image.remaining_tracks + 1;
|
|
|
|
|
|
|
|
CDI_read_track (fsource, &image, &track);
|
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
image.header_position = std::ftell(fsource);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2013-12-24 00:56:44 +00:00
|
|
|
// Show info
|
2019-01-02 15:43:36 +00:00
|
|
|
#if 0
|
2013-12-19 17:10:14 +00:00
|
|
|
printf("Saving ");
|
|
|
|
printf("Track: %2d ",track.global_current_track);
|
|
|
|
printf("Type: ");
|
|
|
|
switch(track.mode)
|
|
|
|
{
|
|
|
|
case 0 : printf("Audio/"); break;
|
|
|
|
case 1 : printf("Mode1/"); break;
|
|
|
|
case 2 :
|
|
|
|
default: printf("Mode2/"); break;
|
|
|
|
}
|
2018-08-19 01:28:44 +00:00
|
|
|
printf("%lu ",track.sector_size);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
printf("Pregap: %-3ld ",track.pregap_length);
|
|
|
|
printf("Size: %-6ld ",track.length);
|
|
|
|
printf("LBA: %-6ld ",track.start_lba);
|
2019-01-02 15:43:36 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
if (ft)
|
|
|
|
{
|
2021-12-15 16:55:42 +00:00
|
|
|
ft = false;
|
2013-12-19 17:10:14 +00:00
|
|
|
Session s;
|
2021-12-15 16:55:42 +00:00
|
|
|
s.StartFAD = track.pregap_length + track.start_lba;
|
|
|
|
s.FirstTrack = (u8)track.global_current_track;
|
2013-12-19 17:10:14 +00:00
|
|
|
rv->sessions.push_back(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
Track t;
|
|
|
|
if (track.mode==2)
|
|
|
|
CD_M2=true;
|
|
|
|
if (track.mode==1)
|
|
|
|
CD_M1=true;
|
|
|
|
if (track.mode==0)
|
|
|
|
CD_DA=true;
|
|
|
|
|
|
|
|
t.ADDR=1;//hmm is that ok ?
|
|
|
|
|
|
|
|
t.CTRL=track.mode==0?0:4;
|
|
|
|
t.StartFAD=track.start_lba+track.pregap_length;
|
|
|
|
t.EndFAD=t.StartFAD+track.length-1;
|
2023-02-11 13:09:22 +00:00
|
|
|
FILE *trackFile = nowide::fopen(file, "rb");
|
|
|
|
if (trackFile == nullptr)
|
|
|
|
{
|
|
|
|
delete rv;
|
|
|
|
std::fclose(fsource);
|
|
|
|
WARN_LOG(GDROM, "Cannot re-open file '%s' errno %d", file, errno);
|
|
|
|
throw FlycastException("Cannot re-open CDI file");
|
|
|
|
}
|
|
|
|
t.file = new RawTrackFile(trackFile, track.position + track.pregap_length * track.sector_size, t.StartFAD, track.sector_size);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
rv->tracks.push_back(t);
|
|
|
|
|
|
|
|
if (track.length < 0)
|
2019-07-01 14:10:28 +00:00
|
|
|
WARN_LOG(GDROM, "Negative track size found. You must extract image with /pregap option");
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2021-08-03 08:05:09 +00:00
|
|
|
std::fseek(fsource, track.position, SEEK_SET);
|
|
|
|
if (track.total_length < track.length + track.pregap_length)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2021-08-03 08:05:09 +00:00
|
|
|
WARN_LOG(GDROM, "This track seems truncated. Skipping...");
|
|
|
|
// FIXME that can't be right
|
|
|
|
std::fseek(fsource, track.total_length, SEEK_CUR);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2021-08-03 08:05:09 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::fseek(fsource, track.total_length * track.sector_size, SEEK_CUR);
|
|
|
|
rv->EndFAD=track.start_lba +track.total_length;
|
|
|
|
}
|
|
|
|
track.position = std::ftell(fsource);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fseek(fsource, image.header_position, SEEK_SET);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
image.remaining_tracks--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-03 08:05:09 +00:00
|
|
|
CDI_skip_next_session(fsource, &image);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
image.remaining_sessions--;
|
|
|
|
}
|
2021-10-16 15:56:21 +00:00
|
|
|
if (digest != nullptr)
|
|
|
|
*digest = MD5Sum().add(fsource).getDigest();
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(fsource);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
rv->type=GuessDiscType(CD_M1,CD_M2,CD_DA);
|
|
|
|
|
|
|
|
rv->LeadOut.StartFAD=rv->EndFAD;
|
|
|
|
rv->LeadOut.ADDR=0;
|
|
|
|
rv->LeadOut.CTRL=0;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|