+ rewind(cdHandle);
+ return -1;
+}
+
+#ifdef HAVE_CHD
+static int handlechd(const char *isofile) {
+ int frame_offset = 150;
+ int file_offset = 0;
+
+ chd_img = calloc(1, sizeof(*chd_img));
+ if (chd_img == NULL)
+ goto fail_io;
+
+ if(chd_open(isofile, CHD_OPEN_READ, NULL, &chd_img->chd) != CHDERR_NONE)
+ goto fail_io;
+
+ if (Config.CHD_Precache && (chd_precache(chd_img->chd) != CHDERR_NONE))
+ goto fail_io;
+
+ chd_img->header = chd_get_header(chd_img->chd);
+
+ chd_img->buffer = malloc(chd_img->header->hunkbytes * 2);
+ if (chd_img->buffer == NULL)
+ goto fail_io;
+
+ chd_img->sectors_per_hunk = chd_img->header->hunkbytes / (CD_FRAMESIZE_RAW + SUB_FRAMESIZE);
+ chd_img->current_hunk[0] = (unsigned int)-1;
+ chd_img->current_hunk[1] = (unsigned int)-1;
+
+ cddaBigEndian = TRUE;
+
+ numtracks = 0;
+ memset(ti, 0, sizeof(ti));
+
+ while (1)
+ {
+ struct {
+ char type[64];
+ char subtype[32];
+ char pgtype[32];
+ char pgsub[32];
+ uint32_t track;
+ uint32_t frames;
+ uint32_t pregap;
+ uint32_t postgap;
+ } md = {};
+ char meta[256];
+ uint32_t meta_size = 0;
+
+ if (chd_get_metadata(chd_img->chd, CDROM_TRACK_METADATA2_TAG, numtracks, meta, sizeof(meta), &meta_size, NULL, NULL) == CHDERR_NONE)
+ sscanf(meta, CDROM_TRACK_METADATA2_FORMAT, &md.track, md.type, md.subtype, &md.frames, &md.pregap, md.pgtype, md.pgsub, &md.postgap);
+ else if (chd_get_metadata(chd_img->chd, CDROM_TRACK_METADATA_TAG, numtracks, meta, sizeof(meta), &meta_size, NULL, NULL) == CHDERR_NONE)
+ sscanf(meta, CDROM_TRACK_METADATA_FORMAT, &md.track, md.type, md.subtype, &md.frames);
+ else
+ break;
+
+ SysPrintf("chd: %s\n", meta);
+
+ if (md.track == 1) {
+ if (!strncmp(md.subtype, "RW", 2)) {
+ subChanMixed = TRUE;
+ if (!strcmp(md.subtype, "RW_RAW"))
+ subChanRaw = TRUE;
+ }
+ }
+
+ ti[md.track].type = !strncmp(md.type, "AUDIO", 5) ? CDDA : DATA;
+
+ sec2msf(frame_offset + md.pregap, ti[md.track].start);
+ sec2msf(md.frames, ti[md.track].length);
+
+ ti[md.track].start_offset = file_offset + md.pregap;
+
+ // XXX: what about postgap?
+ frame_offset += md.frames;
+ file_offset += md.frames;
+ numtracks++;
+ }
+
+ if (numtracks)
+ return 0;
+
+fail_io:
+ if (chd_img != NULL) {
+ free(chd_img->buffer);
+ free(chd_img);
+ chd_img = NULL;
+ }