endif
endif
+ifneq (,$(HAVE_LIBCHDR))
+CFLAGS += -DUSE_LIBCHDR -Iplatform/common/libchdr/include
+LDFLAGS += -Lplatform/common/libchdr -lchdr
+endif
+
ifeq "$(PLATFORM_ZLIB)" "1"
# zlib
OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
asm_32xmemory = 0
endif
+#HAVE_LIBCHDR = 1
+
CFLAGS += $(fpic)
ifeq ($(findstring Haiku,$(shell uname -a)),)
#include "file_stream_transforms.h"\r
#endif\r
\r
+#if defined(USE_LIBCHDR)\r
+#include "libchdr/chd.h"\r
+#include "libchdr/cdrom.h"\r
+#endif\r
+\r
static int rom_alloc_size;\r
static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };\r
\r
unsigned int pos;\r
};\r
\r
+#if defined(USE_LIBCHDR)\r
+struct chd_struct {\r
+ pm_file file;\r
+ int fpos;\r
+ int sectorsize;\r
+ chd_file *chd;\r
+ int unitbytes;\r
+ int hunkunits;\r
+ u8 *hunk;\r
+ int hunknum;\r
+};\r
+#endif\r
+\r
pm_file *pm_open(const char *path)\r
{\r
pm_file *file = NULL;\r
if (f != NULL) fclose(f);\r
return NULL;\r
}\r
+#if defined(USE_LIBCHDR)\r
+ else if (strcasecmp(ext, "chd") == 0)\r
+ {\r
+ struct chd_struct *chd = NULL;\r
+ chd_file *cf = NULL;\r
+ const chd_header *head;\r
+\r
+ if (chd_open(path, CHD_OPEN_READ, NULL, &cf) != CHDERR_NONE)\r
+ goto chd_failed;\r
+\r
+ // sanity check\r
+ head = chd_get_header(cf);\r
+ if ((head->hunkbytes == 0) || (head->hunkbytes % CD_FRAME_SIZE))\r
+ goto chd_failed;\r
+\r
+ chd = calloc(1, sizeof(*chd));\r
+ if (chd == NULL)\r
+ goto chd_failed;\r
+ chd->hunk = (u8 *)malloc(head->hunkbytes);\r
+ if (!chd->hunk)\r
+ goto chd_failed;\r
+\r
+ chd->chd = cf;\r
+ chd->unitbytes = head->unitbytes;\r
+ chd->hunkunits = head->hunkbytes / head->unitbytes;\r
+ chd->sectorsize = CD_MAX_SECTOR_DATA; // default to RAW mode\r
+\r
+ chd->fpos = 0;\r
+ chd->hunknum = -1;\r
+\r
+ chd->file.file = chd;\r
+ chd->file.type = PMT_CHD;\r
+ // subchannel data is skipped, remove it from total size\r
+ chd->file.size = chd_get_header(cf)->logicalbytes / CD_FRAME_SIZE * CD_MAX_SECTOR_DATA;\r
+ strncpy(chd->file.ext, ext, sizeof(chd->file.ext) - 1);\r
+ return &chd->file;\r
+\r
+chd_failed:\r
+ /* invalid CHD file */\r
+ if (chd != NULL) free(chd);\r
+ if (cf != NULL) chd_close(cf);\r
+ return NULL;\r
+ }\r
+#endif\r
\r
/* not a zip, treat as uncompressed file */\r
f = fopen(path, "rb");\r
return file;\r
}\r
\r
+void pm_sectorsize(int length, pm_file *stream)\r
+{\r
+ // CHD reading needs to know how much binary data is in one data sector(=unit)\r
+#if defined(USE_LIBCHDR)\r
+ if (stream->type == PMT_CHD) {\r
+ struct chd_struct *chd = stream->file;\r
+ chd->sectorsize = length;\r
+ if (chd->sectorsize > chd->unitbytes)\r
+ elprintf(EL_STATUS|EL_ANOMALY, "cd: sector size %d too large for unit %d", chd->sectorsize, chd->unitbytes);\r
+ }\r
+#endif\r
+}\r
+\r
+#if defined(USE_LIBCHDR)\r
+static size_t _pm_read_chd(void *ptr, size_t bytes, pm_file *stream, int is_audio)\r
+{\r
+ int ret = 0;\r
+\r
+ if (stream->type == PMT_CHD) {\r
+ struct chd_struct *chd = stream->file;\r
+ // calculate sector and offset in sector\r
+ int sectsz = is_audio ? CD_MAX_SECTOR_DATA : chd->sectorsize;\r
+ int sector = chd->fpos / sectsz;\r
+ int offset = chd->fpos - (sector * sectsz);\r
+ // calculate hunk and sector offset in hunk\r
+ int hunknum = sector / chd->hunkunits;\r
+ int hunksec = sector - (hunknum * chd->hunkunits);\r
+ int hunkofs = hunksec * chd->unitbytes;\r
+\r
+ while (bytes != 0) {\r
+ // data left in current sector\r
+ int len = sectsz - offset;\r
+\r
+ // update hunk cache if needed\r
+ if (hunknum != chd->hunknum) {\r
+ chd_read(chd->chd, hunknum, chd->hunk);\r
+ chd->hunknum = hunknum;\r
+ }\r
+ if (len > bytes)\r
+ len = bytes;\r
+\r
+#ifdef CPU_IS_LE\r
+ if (is_audio) {\r
+ // convert big endian audio samples\r
+ u16 *dst = ptr, v;\r
+ u8 *src = chd->hunk + hunkofs + offset;\r
+ int i;\r
+\r
+ for (i = 0; i < len; i += 4) {\r
+ v = *src++ << 8; *dst++ = v | *src++;\r
+ v = *src++ << 8; *dst++ = v | *src++;\r
+ }\r
+ } else\r
+#endif\r
+ memcpy(ptr, chd->hunk + hunkofs + offset, len);\r
+\r
+ // house keeping\r
+ ret += len;\r
+ chd->fpos += len;\r
+ bytes -= len;\r
+\r
+ // no need to advance internals if there's no more data to read\r
+ if (bytes) {\r
+ ptr += len;\r
+ offset = 0;\r
+\r
+ sector ++;\r
+ hunksec ++;\r
+ hunkofs += chd->unitbytes;\r
+ if (hunksec >= chd->hunkunits) {\r
+ hunksec = 0;\r
+ hunkofs = 0;\r
+ hunknum ++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
size_t pm_read(void *ptr, size_t bytes, pm_file *stream)\r
{\r
int ret;\r
index_end = cso->index[block+1];\r
}\r
}\r
+#if defined(USE_LIBCHDR)\r
+ else if (stream->type == PMT_CHD)\r
+ {\r
+ ret = _pm_read_chd(ptr, bytes, stream, 0);\r
+ }\r
+#endif\r
else\r
ret = 0;\r
\r
return ret;\r
}\r
\r
+size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream)\r
+{\r
+#if !(CPU_IS_LE)\r
+ if (stream->type == PMT_UNCOMPRESSED)\r
+ {\r
+ // convert little endian audio samples from WAV file\r
+ int ret = pm_read(ptr, bytes, stream);\r
+ u16 *dst = ptr, v;\r
+ u8 *src = ptr;\r
+ int i;\r
+\r
+ for (i = 0; i < ret; i += 4) {\r
+ v = *src++; *dst++ = v | (*src++ << 8);\r
+ v = *src++; *dst++ = v | (*src++ << 8);\r
+ }\r
+ return ret;\r
+ }\r
+ else\r
+#endif\r
+#if defined(USE_LIBCHDR)\r
+ if (stream->type == PMT_CHD)\r
+ {\r
+ return _pm_read_chd(ptr, bytes, stream, 1);\r
+ }\r
+#endif\r
+ return pm_read(ptr, bytes, stream);\r
+}\r
+\r
int pm_seek(pm_file *stream, long offset, int whence)\r
{\r
if (stream->type == PMT_UNCOMPRESSED)\r
}\r
return cso->fpos_out;\r
}\r
+#if defined(USE_LIBCHDR)\r
+ else if (stream->type == PMT_CHD)\r
+ {\r
+ struct chd_struct *chd = stream->file;\r
+ switch (whence)\r
+ {\r
+ case SEEK_CUR: chd->fpos += offset; break;\r
+ case SEEK_SET: chd->fpos = offset; break;\r
+ case SEEK_END: chd->fpos = stream->size - offset; break;\r
+ }\r
+ return chd->fpos;\r
+ }\r
+#endif\r
else\r
return -1;\r
}\r
free(fp->param);\r
fclose(fp->file);\r
}\r
+#if defined(USE_LIBCHDR)\r
+ else if (fp->type == PMT_CHD)\r
+ {\r
+ struct chd_struct *chd = fp->file;\r
+ chd_close(chd->chd);\r
+ if (chd->hunk)\r
+ free(chd->hunk);\r
+ }\r
+#endif\r
else\r
ret = EOF;\r
\r
#include "../pico_int.h"
#include "genplus_macros.h"
#include "cdd.h"
-#include "cue.h"
+#include "cd_parse.h"
#ifdef USE_LIBRETRO_VFS
#include "file_stream_transforms.h"
int iso_name_len, missed, cd_img_sectors;
char tmp_name[256], tmp_ext[10], tmp_ext_u[10];
track_t *tracks = cdd.toc.tracks;
- cue_data_t *cue_data = NULL;
+ cd_data_t *cue_data = NULL;
pm_file *pmf;
if (PicoCDLoadProgressCB != NULL)
if (cue_data != NULL) {
cd_img_name = cue_data->tracks[1].fname;
*type = cue_data->tracks[1].type;
+ } else {
+ cue_data = chd_parse(cd_img_name);
+ if (cue_data != NULL)
+ *type = cue_data->tracks[1].type;
}
pmf = pm_open(cd_img_name);
if (pmf == NULL)
{
if (cue_data != NULL)
- cue_destroy(cue_data);
+ cdparse_destroy(cue_data);
return -1;
}
tracks[0].fd = pmf;
+ tracks[0].fname = strdup(cd_img_name);
if (*type == CT_ISO)
cd_img_sectors = pmf->size >>= 11; // size in sectors
if (cue_data != NULL)
{
- if (cue_data->tracks[2].fname == NULL) {
+ if (cue_data->track_count > 1 && cue_data->tracks[2].fname == NULL) {
// NULL fname means track2 is in same file as track1
lba = tracks[0].end = cue_data->tracks[2].sector_offset;
}
{
// assume raw, ignore header for wav..
tracks[index].fd = f;
+ tracks[index].fname = strdup(cue_data->tracks[n].fname);
tracks[index].offset = cue_data->tracks[n].sector_offset;
length = f->size / 2352;
}
tracks[index].end = lba;
sprintf_lba(tmp_ext, sizeof(tmp_ext), tracks[index].start);
- elprintf(EL_STATUS, "Track %2i: %s %9i AUDIO %s",
- n, tmp_ext, length, cue_data->tracks[n].fname);
+ elprintf(EL_STATUS, "Track %2i: %s %9i AUDIO %s", n, tmp_ext, length,
+ cue_data->tracks[n].fname ? cue_data->tracks[n].fname : "");
}
goto finish;
}
PicoCDLoadProgressCB(cd_img_name, 100);
if (cue_data != NULL)
- cue_destroy(cue_data);
+ cdparse_destroy(cue_data);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "cue.h"
#include "../pico_int.h"
+#include "cd_parse.h"
// #define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
#ifdef USE_LIBRETRO_VFS
#include "file_stream_transforms.h"
#endif
+#if defined(USE_LIBCHDR)
+#include "libchdr/chd.h"
+#include "libchdr/cdrom.h"
+#endif
+
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
if (len > 0)
pos = len;
- strcpy(ext, fname + pos + 1);
+ strncpy(ext, fname + pos + 1, 4/*sizeof(ext)*/-1);
+ ext[4/*sizeof(ext)*/-1] = '\0';
if (base != NULL) {
if (pos + 1 < base_size)
#define BEGINS(buff,str) (strncmp(buff,str,sizeof(str)-1) == 0)
/* note: tracks[0] is not used */
-cue_data_t *cue_parse(const char *fname)
+cd_data_t *chd_parse(const char *fname)
+{
+ cd_data_t *data = NULL;
+#if defined(USE_LIBCHDR)
+ cd_data_t *tmp;
+ int count = 0, count_alloc = 2;
+ int sectors = 0;
+ char metadata[256];
+ chd_file *cf = NULL;
+
+ if (fname == NULL || *fname == '\0')
+ return NULL;
+
+ if (chd_open(fname, CHD_OPEN_READ, NULL, &cf) != CHDERR_NONE)
+ goto out;
+
+ data = calloc(1, sizeof(*data) + count_alloc * sizeof(cd_track_t));
+ if (data == NULL)
+ goto out;
+
+ // get track info
+ while (count < CD_MAX_TRACKS) {
+ int track = 0, frames = 0, pregap = 0, postgap = 0;
+ char type[16], subtype[16], pgtype[16], pgsub[16];
+ type[0] = subtype[0] = pgtype[0] = pgsub[0] = 0;
+
+ // get metadata for track
+ if (chd_get_metadata(cf, CDROM_TRACK_METADATA2_TAG, count,
+ metadata, sizeof(metadata), 0, 0, 0) == CHDERR_NONE) {
+ if (sscanf(metadata, CDROM_TRACK_METADATA2_FORMAT,
+ &track, &type[0], &subtype[0], &frames,
+ &pregap, &pgtype[0], &pgsub[0], &postgap) != 8)
+ break;
+ }
+ else if (chd_get_metadata(cf, CDROM_TRACK_METADATA_TAG, count,
+ metadata, sizeof(metadata), 0, 0, 0) == CHDERR_NONE) {
+ if (sscanf(metadata, CDROM_TRACK_METADATA_FORMAT,
+ &track, &type[0], &subtype[0], &frames) != 4)
+ break;
+ }
+ else break; // all tracks completed
+
+ // metadata sanity check
+ if (track != count + 1 || frames < 0 || pregap < 0)
+ break;
+
+ // allocate track structure
+ count ++;
+ if (count >= count_alloc) {
+ count_alloc *= 2;
+ tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cd_track_t));
+ if (tmp == NULL) {
+ count--;
+ break;
+ }
+ data = tmp;
+ }
+ memset(&data->tracks[count], 0, sizeof(data->tracks[0]));
+
+ if (count == 1) { // binary code
+ data->tracks[count].fname = strdup(fname);
+ if (!strcmp(type, "MODE1_RAW") || !strcmp(type, "MODE2_RAW")) {
+ data->tracks[count].type = CT_BIN;
+ } else if (!strcmp(type, "MODE1") || !strcmp(type, "MODE2_FORM1")) {
+ data->tracks[count].type = CT_ISO;
+ } else
+ break;
+ } else { // audio
+ if (strcmp(type, "AUDIO"))
+ break;
+ data->tracks[count].type = CT_CHD;
+ }
+
+ data->tracks[count].pregap = pregap;
+ if (pgtype[0] != 'V') // VAUDIO includes pregap in file
+ pregap = 0;
+ data->tracks[count].sector_offset = sectors + pregap;
+ data->tracks[count].sector_xlength = frames - pregap;
+ sectors += (((frames + CD_TRACK_PADDING - 1) / CD_TRACK_PADDING) * CD_TRACK_PADDING);
+ }
+
+ // check if image id OK, i.e. there are tracks, and length <= 80 min
+ if (count && sectors < (80*60*75)) {
+ data->track_count = count;
+ } else {
+ free(data);
+ data = NULL;
+ }
+
+out:
+ if (cf)
+ chd_close(cf);
+#endif
+ return data;
+}
+
+cd_data_t *cue_parse(const char *fname)
{
char current_file[256], *current_filep, cue_base[256];
char buff[256], buff2[32], ext[4], *p;
int ret, count = 0, count_alloc = 2, pending_pregap = 0;
size_t current_filep_size, fname_len;
- cue_data_t *data = NULL;
+ cd_data_t *data = NULL, *tmp;
FILE *f = NULL;
- void *tmp;
if (fname == NULL || (fname_len = strlen(fname)) == 0)
return NULL;
p = strrchr(cue_base, '.');
if (p) p[1] = '\0';
- data = calloc(1, sizeof(*data) + count_alloc * sizeof(cue_track));
+ data = calloc(1, sizeof(*data) + count_alloc * sizeof(cd_track_t));
if (data == NULL)
goto out;
while (!feof(f))
{
- tmp = fgets(buff, sizeof(buff), f);
- if (tmp == NULL)
+ if (fgets(buff, sizeof(buff), f) == NULL)
break;
mystrip(buff);
count++;
if (count >= count_alloc) {
count_alloc *= 2;
- tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cue_track));
+ tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cd_track_t));
if (tmp == NULL) {
count--;
break;
}
-void cue_destroy(cue_data_t *data)
+void cdparse_destroy(cd_data_t *data)
{
int c;
#if 0
int main(int argc, char *argv[])
{
- cue_data_t *data = cue_parse(argv[1]);
+ cd_data_t *data = cue_parse(argv[1]);
int c;
if (data == NULL) return 1;
data->tracks[c].sector_offset / (75*60), data->tracks[c].sector_offset / 75 % 60,
data->tracks[c].sector_offset % 75, data->tracks[c].pregap, data->tracks[c].fname);
- cue_destroy(data);
+ cdparse_destroy(data);
return 0;
}
--- /dev/null
+
+cd_data_t *chd_parse(const char *fname);
+cd_data_t *cue_parse(const char *fname);
+void cdparse_destroy(cd_data_t *data);
+
#include "../pico_int.h"
#include "genplus_macros.h"
-#include "cue.h"
+#include "cd_parse.h"
#include "cdd.h"
#ifdef USE_LIBTREMOR
ret = (type == CT_BIN) ? 2352 : 2048;
if (ret != cdd.sectorSize)
elprintf(EL_STATUS|EL_ANOMALY, "cd: type detection mismatch");
+ pm_sectorsize(cdd.sectorSize, cdd.toc.tracks[0].fd);
/* read CD image header + security code */
pm_read(header + 0x10, 0x200, cdd.toc.tracks[0].fd);
{
pm_close(cdd.toc.tracks[0].fd);
cdd.toc.tracks[0].fd = NULL;
+ if (cdd.toc.tracks[0].fname)
+ free(cdd.toc.tracks[0].fd);
+ cdd.toc.tracks[0].fname = NULL;
}
for (i = 1; i < cdd.toc.last; i++)
if (Pico_mcd->cdda_type == CT_MP3)
fclose(cdd.toc.tracks[i].fd);
else
- pm_close(cdd.toc.tracks[0].fd);
+ pm_close(cdd.toc.tracks[i].fd);
+ cdd.toc.tracks[i].fd = NULL;
+ if (cdd.toc.tracks[i].fname)
+ free(cdd.toc.tracks[i].fd);
+ cdd.toc.tracks[i].fname = NULL;
/* detect single file images */
if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
/* CD track */
typedef struct
{
+ char *fname;
void *fd;
#ifdef USE_LIBTREMOR
OggVorbis_File vf;
+++ /dev/null
-
-typedef enum
-{
- CT_UNKNOWN = 0,
- CT_ISO = 1, /* 2048 B/sector */
- CT_BIN = 2, /* 2352 B/sector */
- CT_MP3 = 3,
- CT_WAV = 4
-} cue_track_type;
-
-typedef struct
-{
- char *fname;
- int pregap; /* pregap for current track */
- int sector_offset; /* in current file */
- int sector_xlength;
- cue_track_type type;
-} cue_track;
-
-typedef struct
-{
- int track_count;
- cue_track tracks[0];
-} cue_data_t;
-
-
-cue_data_t *cue_parse(const char *fname);
-void cue_destroy(cue_data_t *data);
-
#include <string.h>
#include "pico_int.h"
-#include "cd/cue.h"
+#include "cd/cd_parse.h"
unsigned char media_id_header[0x100];
return PM_BAD_DETECT;
/* don't believe in extensions, except .cue */
- if (strcasecmp(ext, ".cue") == 0)
+ if (strcasecmp(ext, ".cue") == 0 || strcasecmp(ext, ".chd") == 0)
return PM_CD;
pmf = pm_open(fname);
pm_file *cd_f;
int region = 4; // 1: Japan, 4: US, 8: Europe
char ext[5];
- cue_track_type type = CT_UNKNOWN;
- cue_data_t *cue_data = NULL;
+ enum cd_track_type type = CT_UNKNOWN;
+ cd_data_t *cd_data = NULL;
// opens a cue, or searches for one
- cue_data = cue_parse(fname_in);
- if (cue_data != NULL) {
- fname = cue_data->tracks[1].fname;
- type = cue_data->tracks[1].type;
- }
- else {
+ if (!cd_data && (cd_data = cue_parse(fname_in)) == NULL) {
get_ext(fname_in, ext);
if (strcasecmp(ext, ".cue") == 0)
return -1;
}
+ // opens a chd
+ if (!cd_data && (cd_data = chd_parse(fname_in)) == NULL) {
+ get_ext(fname_in, ext);
+ if (strcasecmp(ext, ".chd") == 0)
+ return -1;
+ }
- cd_f = pm_open(fname);
- if (cue_data != NULL)
- cue_destroy(cue_data);
+ if (cd_data != NULL) {
+ // 1st track contains the code
+ fname = cd_data->tracks[1].fname;
+ type = cd_data->tracks[1].type;
+ }
- if (cd_f == NULL) return 0; // let the upper level handle this
+ cd_f = pm_open(fname);
+ cdparse_destroy(cd_data);
+ if (cd_f == NULL) return CT_UNKNOWN; // let the upper level handle this
if (pm_read(buf, 32, cd_f) != 32) {
pm_close(cd_f);
{
const char *rom_fname = filename;
enum media_type_e media_type;
- enum cd_img_type cd_img_type = CIT_NOT_CD;
+ enum cd_track_type cd_img_type = CT_UNKNOWN;
unsigned char *rom_data = NULL;
unsigned int rom_size = 0;
pm_file *rom = NULL;
{
// check for MegaCD image
cd_img_type = PicoCdCheck(filename, &cd_region);
- if ((int)cd_img_type >= 0 && cd_img_type != CIT_NOT_CD)
+ if ((int)cd_img_type >= 0 && cd_img_type != CT_UNKNOWN)
{
// valid CD image, ask frontend for BIOS..
rom_fname = NULL;
Pico.m.ncart_in = 0;
// insert CD if it was detected
- if (cd_img_type != CIT_NOT_CD) {
+ if (cd_img_type != CT_UNKNOWN) {
ret = cdd_load(filename, cd_img_type);
if (ret != 0) {
PicoCartUnload();
{\r
PMT_UNCOMPRESSED = 0,\r
PMT_ZIP,\r
- PMT_CSO\r
+ PMT_CSO,\r
+ PMT_CHD\r
} pm_type;\r
typedef struct\r
{\r
char ext[4];\r
} pm_file;\r
pm_file *pm_open(const char *path);\r
+void pm_sectorsize(int length, pm_file *stream);\r
size_t pm_read(void *ptr, size_t bytes, pm_file *stream);\r
+size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream);\r
int pm_seek(pm_file *stream, long offset, int whence);\r
int pm_close(pm_file *fp);\r
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);\r
PM_CD,\r
};\r
\r
-enum cd_img_type\r
+enum cd_track_type\r
{\r
- CIT_NOT_CD = 0,\r
- CIT_ISO,\r
- CIT_BIN,\r
- CIT_CUE\r
+ CT_UNKNOWN = 0,\r
+ // data tracks\r
+ CT_ISO = 1, /* 2048 B/sector */\r
+ CT_BIN = 2, /* 2352 B/sector */\r
+ // audio tracks\r
+ CT_MP3 = 3,\r
+ CT_WAV = 4,\r
+ CT_CHD = 5,\r
};\r
\r
+typedef struct\r
+{\r
+ char *fname;\r
+ int pregap; /* pregap for current track */\r
+ int sector_offset; /* in current file */\r
+ int sector_xlength;\r
+ enum cd_track_type type;\r
+} cd_track_t;\r
+\r
+typedef struct\r
+{\r
+ int track_count;\r
+ cd_track_t tracks[0];\r
+} cd_data_t;\r
+\r
+\r
enum media_type_e PicoLoadMedia(const char *filename,\r
const char *carthw_cfg_fname,\r
const char *(*get_bios_filename)(int *region, const char *cd_fname),\r
#include "ym2612.h"\r
#include "sn76496.h"\r
#include "../pico_int.h"\r
-#include "../cd/cue.h"\r
#include "mix.h"\r
#include "emu2413/emu2413.h"\r
\r
if (PicoIn.sndRate < 22050 - 100) mult = 4;\r
cdda_bytes *= mult;\r
\r
- ret = pm_read(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);\r
+ ret = pm_read_audio(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);\r
if (ret < cdda_bytes) {\r
memset((char *)cdda_out_buffer + ret, 0, cdda_bytes - ret);\r
Pico_mcd->cdda_stream = NULL;\r
# CD
SRCS_COMMON += $(R)pico/cd/mcd.c $(R)pico/cd/memory.c $(R)pico/cd/sek.c \
$(R)pico/cd/cdc.c $(R)pico/cd/cdd.c $(R)pico/cd/cd_image.c \
- $(R)pico/cd/cue.c $(R)pico/cd/gfx.c $(R)pico/cd/gfx_dma.c \
+ $(R)pico/cd/cd_parse.c $(R)pico/cd/gfx.c $(R)pico/cd/gfx_dma.c \
$(R)pico/cd/misc.c $(R)pico/cd/pcm.c
# 32X
ifneq "$(no_32x)" "1"
\r
int emu_swap_cd(const char *fname)\r
{\r
- enum cd_img_type cd_type;\r
+ enum cd_track_type cd_type;\r
int ret = -1;\r
\r
cd_type = PicoCdCheck(fname, NULL);\r
- if (cd_type != CIT_NOT_CD)\r
+ if (cd_type != CT_UNKNOWN)\r
ret = cdd_load(fname, cd_type);\r
if (ret != 0) {\r
menu_update_msg("Load failed, invalid CD image?");\r
static const char *rom_exts[] = {
"zip",
"bin", "smd", "gen", "md",
- "iso", "cso", "cue",
+ "iso", "cso", "cue", "chd",
"32x",
"sms",
NULL
selfname = romsel_loop(curr_path);\r
if (selfname) {\r
int ret = -1;\r
- cd_img_type cd_type;\r
+ cd_track_type cd_type;\r
cd_type = emu_cdCheck(NULL, romFileName);\r
- if (cd_type != CIT_NOT_CD)\r
+ if (cd_type >= 0 && cd_type != CT_UNKNOWN)\r
ret = Insert_CD(romFileName, cd_type);\r
if (ret != 0) {\r
sprintf(menuErrorMsg, "Load failed, invalid CD image?");\r
#define _GIT_VERSION "-" GIT_VERSION
#endif
info->library_version = VERSION _GIT_VERSION;
- info->valid_extensions = "bin|gen|smd|md|32x|cue|iso|sms";
+ info->valid_extensions = "bin|gen|smd|md|32x|cue|iso|chd|sms";
info->need_fullpath = true;
}
static bool disk_set_image_index(unsigned int index)
{
- enum cd_img_type cd_type;
+ enum cd_track_type cd_type;
int ret;
if (index >= sizeof(disks) / sizeof(disks[0]))
ret = -1;
cd_type = PicoCdCheck(disks[index].fname, NULL);
- if (cd_type != CIT_NOT_CD)
+ if (cd_type >= 0 && cd_type != CT_UNKNOWN)
ret = cdd_load(disks[index].fname, cd_type);
if (ret != 0) {
if (log_cb)
#include <pico/pico_int.h>
#include <pico/cd/genplus_macros.h>
#include <pico/cd/cdd.h>
-#include <pico/cd/cue.h>
#define OSD_FPS_X 432
// reopen first CD track
if (cdd.toc.tracks[0].fd != NULL)
{
- const char *fname = rom_fname_reload;
- int len = strlen(rom_fname_reload);
- cue_data_t *cue_data = NULL;
-
- if (len > 4 && strcasecmp(fname + len - 4, ".cue") == 0)
- {
- cue_data = cue_parse(rom_fname_reload);
- if (cue_data != NULL)
- fname = cue_data->tracks[1].fname;
- }
-
- lprintf("emu_HandleResume: reopen %s\n", fname);
+ lprintf("emu_HandleResume: reopen %s\n", cdd.toc.tracks[0].fname);
pm_close(cdd.toc.tracks[0].fd);
- cdd.toc.tracks[0].fd = pm_open(fname);
+ cdd.toc.tracks[0].fd = pm_open(cdd.toc.tracks[0].fname);
lprintf("reopen %s\n", cdd.toc.tracks[0].fd != NULL ? "ok" : "failed");
-
- if (cue_data != NULL) cue_destroy(cue_data);
}
mp3_reopen_file();