nulldc-360/plugins/ImgReader/chd.cpp

123 lines
No EOL
2.6 KiB
C++

#include "chd.h"
#include "deps/chd.h"
struct CHDDisc : Disc
{
chd_file* chd;
u8* hunk_mem;
u32 old_hunk;
u32 hunkbytes;
u32 sph;
bool TryOpen(char* file);
};
struct CHDTrack:TrackFile
{
CHDDisc* disc;
u32 StartFAD;
u32 StartHunk;
CHDTrack(CHDDisc* disc, u32 StartFAD,u32 StartHunk)
{
this->disc=disc;
this->StartFAD=StartFAD;
this->StartHunk=StartHunk;
}
virtual void Read(u32 FAD,u8* dst,SectorFormat* sector_type,u8* subcode,SubcodeFormat* subcode_type)
{
u32 fad_offs=FAD-StartFAD;
u32 hunk=(fad_offs)/disc->sph + StartHunk;
if (disc->old_hunk!=hunk)
{
chd_read(disc->chd,hunk,disc->hunk_mem); //CHDERR_NONE
}
u32 hunk_ofs=fad_offs%disc->sph;
memcpy(dst,disc->hunk_mem+hunk_ofs*(2352+96),2352);
*sector_type=SECFMT_2352;
//While space is reserved for it, the images contain no actual subcodes
//memcpy(subcode,disc->hunk_mem+hunk_ofs*(2352+96)+2352,96);
*subcode_type=SUBFMT_NONE;
}
};
bool CHDDisc::TryOpen(char* file)
{
chd_error err=chd_open(file,CHD_OPEN_READ,0,&chd);
if (err!=CHDERR_NONE)
return false;
const chd_header* head = chd_get_header(chd);
hunkbytes = head->hunkbytes;
hunk_mem = new u8[hunkbytes];
old_hunk=0xFFFFFFF;
sph = hunkbytes/(2352+96);
if (hunkbytes%(2352+96)!=0)
return false;
u32 tag;
u8 flags;
char temp[512];
u32 temp_len;
u32 total_frames=150;
u32 total_hunks=0;
for(;;)
{
err=chd_get_metadata(chd,CDROM_TRACK_METADATA2_TAG,tracks.size(),temp,sizeof(temp),&temp_len,&tag,&flags);
if (err!=CHDERR_NONE)
break;
//"TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"
char type[64],subtype[32],pgtype[32],pgsub[32];
u32 tkid,frames,pregap,postgap;
sscanf(temp,CDROM_TRACK_METADATA2_FORMAT,&tkid,type,subtype,&frames,&pregap,pgtype,pgsub,&postgap);
if (tkid!=(tracks.size()+1) || (strcmp(type,"MODE1_RAW")!=0 && strcmp(type,"AUDIO")!=0) || strcmp(subtype,"NONE")!=0 || pregap!=0 || postgap!=0)
return false;
printf("%s\n",temp);
Track t;
t.StartFAD=total_frames;
total_frames+=frames;
t.EndFAD=total_frames-1;
t.ADDR=0;
t.CTRL=strcmp(type,"AUDIO")==0?0:4;
t.file = new CHDTrack(this,t.StartFAD,total_hunks);
total_hunks+=frames/sph;
if (frames%sph)
total_hunks++;
tracks.push_back(t);
}
if (total_frames!=549300 || tracks.size()<3)
return false;
FillGDSession();
return true;
}
Disc* chd_parse(char* file)
{
CHDDisc* rv = new CHDDisc();
if (rv->TryOpen(file))
return rv;
else
{
delete rv;
return 0;
}
}