mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
core, groundwork for chd support
still needs some scrutiny, and build integration is missing
This commit is contained in:
parent
4da84f9454
commit
15ca715228
18 changed files with 411 additions and 100 deletions
5
Makefile
5
Makefile
|
@ -236,6 +236,11 @@ OBJS += platform/common/mp3_minimp3.o
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(HAVE_LIBCHDR))
|
||||||
|
CFLAGS += -DUSE_LIBCHDR -Iplatform/common/libchdr/include
|
||||||
|
LDFLAGS += -Lplatform/common/libchdr -lchdr
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq "$(PLATFORM_ZLIB)" "1"
|
ifeq "$(PLATFORM_ZLIB)" "1"
|
||||||
# zlib
|
# zlib
|
||||||
OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
|
OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
|
||||||
|
|
|
@ -564,6 +564,8 @@ asm_32xdraw = 0
|
||||||
asm_32xmemory = 0
|
asm_32xmemory = 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
#HAVE_LIBCHDR = 1
|
||||||
|
|
||||||
CFLAGS += $(fpic)
|
CFLAGS += $(fpic)
|
||||||
|
|
||||||
ifeq ($(findstring Haiku,$(shell uname -a)),)
|
ifeq ($(findstring Haiku,$(shell uname -a)),)
|
||||||
|
|
200
pico/cart.c
200
pico/cart.c
|
@ -16,6 +16,11 @@
|
||||||
#include "file_stream_transforms.h"
|
#include "file_stream_transforms.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
#include "libchdr/chd.h"
|
||||||
|
#include "libchdr/cdrom.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rom_alloc_size;
|
static int rom_alloc_size;
|
||||||
static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };
|
static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };
|
||||||
|
|
||||||
|
@ -102,6 +107,19 @@ struct zip_file {
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
struct chd_struct {
|
||||||
|
pm_file file;
|
||||||
|
int fpos;
|
||||||
|
int sectorsize;
|
||||||
|
chd_file *chd;
|
||||||
|
int unitbytes;
|
||||||
|
int hunkunits;
|
||||||
|
u8 *hunk;
|
||||||
|
int hunknum;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
pm_file *pm_open(const char *path)
|
pm_file *pm_open(const char *path)
|
||||||
{
|
{
|
||||||
pm_file *file = NULL;
|
pm_file *file = NULL;
|
||||||
|
@ -228,6 +246,50 @@ cso_failed:
|
||||||
if (f != NULL) fclose(f);
|
if (f != NULL) fclose(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
else if (strcasecmp(ext, "chd") == 0)
|
||||||
|
{
|
||||||
|
struct chd_struct *chd = NULL;
|
||||||
|
chd_file *cf = NULL;
|
||||||
|
const chd_header *head;
|
||||||
|
|
||||||
|
if (chd_open(path, CHD_OPEN_READ, NULL, &cf) != CHDERR_NONE)
|
||||||
|
goto chd_failed;
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
head = chd_get_header(cf);
|
||||||
|
if ((head->hunkbytes == 0) || (head->hunkbytes % CD_FRAME_SIZE))
|
||||||
|
goto chd_failed;
|
||||||
|
|
||||||
|
chd = calloc(1, sizeof(*chd));
|
||||||
|
if (chd == NULL)
|
||||||
|
goto chd_failed;
|
||||||
|
chd->hunk = (u8 *)malloc(head->hunkbytes);
|
||||||
|
if (!chd->hunk)
|
||||||
|
goto chd_failed;
|
||||||
|
|
||||||
|
chd->chd = cf;
|
||||||
|
chd->unitbytes = head->unitbytes;
|
||||||
|
chd->hunkunits = head->hunkbytes / head->unitbytes;
|
||||||
|
chd->sectorsize = CD_MAX_SECTOR_DATA; // default to RAW mode
|
||||||
|
|
||||||
|
chd->fpos = 0;
|
||||||
|
chd->hunknum = -1;
|
||||||
|
|
||||||
|
chd->file.file = chd;
|
||||||
|
chd->file.type = PMT_CHD;
|
||||||
|
// subchannel data is skipped, remove it from total size
|
||||||
|
chd->file.size = chd_get_header(cf)->logicalbytes / CD_FRAME_SIZE * CD_MAX_SECTOR_DATA;
|
||||||
|
strncpy(chd->file.ext, ext, sizeof(chd->file.ext) - 1);
|
||||||
|
return &chd->file;
|
||||||
|
|
||||||
|
chd_failed:
|
||||||
|
/* invalid CHD file */
|
||||||
|
if (chd != NULL) free(chd);
|
||||||
|
if (cf != NULL) chd_close(cf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* not a zip, treat as uncompressed file */
|
/* not a zip, treat as uncompressed file */
|
||||||
f = fopen(path, "rb");
|
f = fopen(path, "rb");
|
||||||
|
@ -255,6 +317,88 @@ cso_failed:
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pm_sectorsize(int length, pm_file *stream)
|
||||||
|
{
|
||||||
|
// CHD reading needs to know how much binary data is in one data sector(=unit)
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
if (stream->type == PMT_CHD) {
|
||||||
|
struct chd_struct *chd = stream->file;
|
||||||
|
chd->sectorsize = length;
|
||||||
|
if (chd->sectorsize > chd->unitbytes)
|
||||||
|
elprintf(EL_STATUS|EL_ANOMALY, "cd: sector size %d too large for unit %d", chd->sectorsize, chd->unitbytes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
static size_t _pm_read_chd(void *ptr, size_t bytes, pm_file *stream, int is_audio)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (stream->type == PMT_CHD) {
|
||||||
|
struct chd_struct *chd = stream->file;
|
||||||
|
// calculate sector and offset in sector
|
||||||
|
int sectsz = is_audio ? CD_MAX_SECTOR_DATA : chd->sectorsize;
|
||||||
|
int sector = chd->fpos / sectsz;
|
||||||
|
int offset = chd->fpos - (sector * sectsz);
|
||||||
|
// calculate hunk and sector offset in hunk
|
||||||
|
int hunknum = sector / chd->hunkunits;
|
||||||
|
int hunksec = sector - (hunknum * chd->hunkunits);
|
||||||
|
int hunkofs = hunksec * chd->unitbytes;
|
||||||
|
|
||||||
|
while (bytes != 0) {
|
||||||
|
// data left in current sector
|
||||||
|
int len = sectsz - offset;
|
||||||
|
|
||||||
|
// update hunk cache if needed
|
||||||
|
if (hunknum != chd->hunknum) {
|
||||||
|
chd_read(chd->chd, hunknum, chd->hunk);
|
||||||
|
chd->hunknum = hunknum;
|
||||||
|
}
|
||||||
|
if (len > bytes)
|
||||||
|
len = bytes;
|
||||||
|
|
||||||
|
#ifdef CPU_IS_LE
|
||||||
|
if (is_audio) {
|
||||||
|
// convert big endian audio samples
|
||||||
|
u16 *dst = ptr, v;
|
||||||
|
u8 *src = chd->hunk + hunkofs + offset;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 4) {
|
||||||
|
v = *src++ << 8; *dst++ = v | *src++;
|
||||||
|
v = *src++ << 8; *dst++ = v | *src++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
memcpy(ptr, chd->hunk + hunkofs + offset, len);
|
||||||
|
|
||||||
|
// house keeping
|
||||||
|
ret += len;
|
||||||
|
chd->fpos += len;
|
||||||
|
bytes -= len;
|
||||||
|
|
||||||
|
// no need to advance internals if there's no more data to read
|
||||||
|
if (bytes) {
|
||||||
|
ptr += len;
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
sector ++;
|
||||||
|
hunksec ++;
|
||||||
|
hunkofs += chd->unitbytes;
|
||||||
|
if (hunksec >= chd->hunkunits) {
|
||||||
|
hunksec = 0;
|
||||||
|
hunkofs = 0;
|
||||||
|
hunknum ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
|
size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -355,12 +499,46 @@ size_t pm_read(void *ptr, size_t bytes, pm_file *stream)
|
||||||
index_end = cso->index[block+1];
|
index_end = cso->index[block+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
else if (stream->type == PMT_CHD)
|
||||||
|
{
|
||||||
|
ret = _pm_read_chd(ptr, bytes, stream, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream)
|
||||||
|
{
|
||||||
|
#if !(CPU_IS_LE)
|
||||||
|
if (stream->type == PMT_UNCOMPRESSED)
|
||||||
|
{
|
||||||
|
// convert little endian audio samples from WAV file
|
||||||
|
int ret = pm_read(ptr, bytes, stream);
|
||||||
|
u16 *dst = ptr, v;
|
||||||
|
u8 *src = ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ret; i += 4) {
|
||||||
|
v = *src++; *dst++ = v | (*src++ << 8);
|
||||||
|
v = *src++; *dst++ = v | (*src++ << 8);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
if (stream->type == PMT_CHD)
|
||||||
|
{
|
||||||
|
return _pm_read_chd(ptr, bytes, stream, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return pm_read(ptr, bytes, stream);
|
||||||
|
}
|
||||||
|
|
||||||
int pm_seek(pm_file *stream, long offset, int whence)
|
int pm_seek(pm_file *stream, long offset, int whence)
|
||||||
{
|
{
|
||||||
if (stream->type == PMT_UNCOMPRESSED)
|
if (stream->type == PMT_UNCOMPRESSED)
|
||||||
|
@ -421,6 +599,19 @@ int pm_seek(pm_file *stream, long offset, int whence)
|
||||||
}
|
}
|
||||||
return cso->fpos_out;
|
return cso->fpos_out;
|
||||||
}
|
}
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
else if (stream->type == PMT_CHD)
|
||||||
|
{
|
||||||
|
struct chd_struct *chd = stream->file;
|
||||||
|
switch (whence)
|
||||||
|
{
|
||||||
|
case SEEK_CUR: chd->fpos += offset; break;
|
||||||
|
case SEEK_SET: chd->fpos = offset; break;
|
||||||
|
case SEEK_END: chd->fpos = stream->size - offset; break;
|
||||||
|
}
|
||||||
|
return chd->fpos;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -446,6 +637,15 @@ int pm_close(pm_file *fp)
|
||||||
free(fp->param);
|
free(fp->param);
|
||||||
fclose(fp->file);
|
fclose(fp->file);
|
||||||
}
|
}
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
else if (fp->type == PMT_CHD)
|
||||||
|
{
|
||||||
|
struct chd_struct *chd = fp->file;
|
||||||
|
chd_close(chd->chd);
|
||||||
|
if (chd->hunk)
|
||||||
|
free(chd->hunk);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
ret = EOF;
|
ret = EOF;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "../pico_int.h"
|
#include "../pico_int.h"
|
||||||
#include "genplus_macros.h"
|
#include "genplus_macros.h"
|
||||||
#include "cdd.h"
|
#include "cdd.h"
|
||||||
#include "cue.h"
|
#include "cd_parse.h"
|
||||||
|
|
||||||
#ifdef USE_LIBRETRO_VFS
|
#ifdef USE_LIBRETRO_VFS
|
||||||
#include "file_stream_transforms.h"
|
#include "file_stream_transforms.h"
|
||||||
|
@ -90,7 +90,7 @@ int load_cd_image(const char *cd_img_name, int *type)
|
||||||
int iso_name_len, missed, cd_img_sectors;
|
int iso_name_len, missed, cd_img_sectors;
|
||||||
char tmp_name[256], tmp_ext[10], tmp_ext_u[10];
|
char tmp_name[256], tmp_ext[10], tmp_ext_u[10];
|
||||||
track_t *tracks = cdd.toc.tracks;
|
track_t *tracks = cdd.toc.tracks;
|
||||||
cue_data_t *cue_data = NULL;
|
cd_data_t *cue_data = NULL;
|
||||||
pm_file *pmf;
|
pm_file *pmf;
|
||||||
|
|
||||||
if (PicoCDLoadProgressCB != NULL)
|
if (PicoCDLoadProgressCB != NULL)
|
||||||
|
@ -103,16 +103,21 @@ int load_cd_image(const char *cd_img_name, int *type)
|
||||||
if (cue_data != NULL) {
|
if (cue_data != NULL) {
|
||||||
cd_img_name = cue_data->tracks[1].fname;
|
cd_img_name = cue_data->tracks[1].fname;
|
||||||
*type = cue_data->tracks[1].type;
|
*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);
|
pmf = pm_open(cd_img_name);
|
||||||
if (pmf == NULL)
|
if (pmf == NULL)
|
||||||
{
|
{
|
||||||
if (cue_data != NULL)
|
if (cue_data != NULL)
|
||||||
cue_destroy(cue_data);
|
cdparse_destroy(cue_data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tracks[0].fd = pmf;
|
tracks[0].fd = pmf;
|
||||||
|
tracks[0].fname = strdup(cd_img_name);
|
||||||
|
|
||||||
if (*type == CT_ISO)
|
if (*type == CT_ISO)
|
||||||
cd_img_sectors = pmf->size >>= 11; // size in sectors
|
cd_img_sectors = pmf->size >>= 11; // size in sectors
|
||||||
|
@ -131,7 +136,7 @@ int load_cd_image(const char *cd_img_name, int *type)
|
||||||
|
|
||||||
if (cue_data != NULL)
|
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
|
// NULL fname means track2 is in same file as track1
|
||||||
lba = tracks[0].end = cue_data->tracks[2].sector_offset;
|
lba = tracks[0].end = cue_data->tracks[2].sector_offset;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +162,7 @@ int load_cd_image(const char *cd_img_name, int *type)
|
||||||
{
|
{
|
||||||
// assume raw, ignore header for wav..
|
// assume raw, ignore header for wav..
|
||||||
tracks[index].fd = f;
|
tracks[index].fd = f;
|
||||||
|
tracks[index].fname = strdup(cue_data->tracks[n].fname);
|
||||||
tracks[index].offset = cue_data->tracks[n].sector_offset;
|
tracks[index].offset = cue_data->tracks[n].sector_offset;
|
||||||
length = f->size / 2352;
|
length = f->size / 2352;
|
||||||
}
|
}
|
||||||
|
@ -189,8 +195,8 @@ int load_cd_image(const char *cd_img_name, int *type)
|
||||||
tracks[index].end = lba;
|
tracks[index].end = lba;
|
||||||
|
|
||||||
sprintf_lba(tmp_ext, sizeof(tmp_ext), tracks[index].start);
|
sprintf_lba(tmp_ext, sizeof(tmp_ext), tracks[index].start);
|
||||||
elprintf(EL_STATUS, "Track %2i: %s %9i AUDIO %s",
|
elprintf(EL_STATUS, "Track %2i: %s %9i AUDIO %s", n, tmp_ext, length,
|
||||||
n, tmp_ext, length, cue_data->tracks[n].fname);
|
cue_data->tracks[n].fname ? cue_data->tracks[n].fname : "");
|
||||||
}
|
}
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +275,7 @@ finish:
|
||||||
PicoCDLoadProgressCB(cd_img_name, 100);
|
PicoCDLoadProgressCB(cd_img_name, 100);
|
||||||
|
|
||||||
if (cue_data != NULL)
|
if (cue_data != NULL)
|
||||||
cue_destroy(cue_data);
|
cdparse_destroy(cue_data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,20 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "cue.h"
|
|
||||||
|
|
||||||
#include "../pico_int.h"
|
#include "../pico_int.h"
|
||||||
|
#include "cd_parse.h"
|
||||||
// #define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
|
// #define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
|
||||||
|
|
||||||
#ifdef USE_LIBRETRO_VFS
|
#ifdef USE_LIBRETRO_VFS
|
||||||
#include "file_stream_transforms.h"
|
#include "file_stream_transforms.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_LIBCHDR)
|
||||||
|
#include "libchdr/chd.h"
|
||||||
|
#include "libchdr/cdrom.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,7 +80,8 @@ static int get_ext(const char *fname, char ext[4],
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
pos = len;
|
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 (base != NULL) {
|
||||||
if (pos + 1 < base_size)
|
if (pos + 1 < base_size)
|
||||||
|
@ -111,15 +117,110 @@ static int file_openable(const char *fname)
|
||||||
#define BEGINS(buff,str) (strncmp(buff,str,sizeof(str)-1) == 0)
|
#define BEGINS(buff,str) (strncmp(buff,str,sizeof(str)-1) == 0)
|
||||||
|
|
||||||
/* note: tracks[0] is not used */
|
/* 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 current_file[256], *current_filep, cue_base[256];
|
||||||
char buff[256], buff2[32], ext[4], *p;
|
char buff[256], buff2[32], ext[4], *p;
|
||||||
int ret, count = 0, count_alloc = 2, pending_pregap = 0;
|
int ret, count = 0, count_alloc = 2, pending_pregap = 0;
|
||||||
size_t current_filep_size, fname_len;
|
size_t current_filep_size, fname_len;
|
||||||
cue_data_t *data = NULL;
|
cd_data_t *data = NULL, *tmp;
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
if (fname == NULL || (fname_len = strlen(fname)) == 0)
|
if (fname == NULL || (fname_len = strlen(fname)) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -156,14 +257,13 @@ cue_data_t *cue_parse(const char *fname)
|
||||||
p = strrchr(cue_base, '.');
|
p = strrchr(cue_base, '.');
|
||||||
if (p) p[1] = '\0';
|
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)
|
if (data == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
while (!feof(f))
|
while (!feof(f))
|
||||||
{
|
{
|
||||||
tmp = fgets(buff, sizeof(buff), f);
|
if (fgets(buff, sizeof(buff), f) == NULL)
|
||||||
if (tmp == NULL)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mystrip(buff);
|
mystrip(buff);
|
||||||
|
@ -180,7 +280,7 @@ cue_data_t *cue_parse(const char *fname)
|
||||||
count++;
|
count++;
|
||||||
if (count >= count_alloc) {
|
if (count >= count_alloc) {
|
||||||
count_alloc *= 2;
|
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) {
|
if (tmp == NULL) {
|
||||||
count--;
|
count--;
|
||||||
break;
|
break;
|
||||||
|
@ -344,7 +444,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cue_destroy(cue_data_t *data)
|
void cdparse_destroy(cd_data_t *data)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
@ -360,7 +460,7 @@ void cue_destroy(cue_data_t *data)
|
||||||
#if 0
|
#if 0
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
cue_data_t *data = cue_parse(argv[1]);
|
cd_data_t *data = cue_parse(argv[1]);
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return 1;
|
||||||
|
@ -370,7 +470,7 @@ int main(int argc, char *argv[])
|
||||||
data->tracks[c].sector_offset / (75*60), data->tracks[c].sector_offset / 75 % 60,
|
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);
|
data->tracks[c].sector_offset % 75, data->tracks[c].pregap, data->tracks[c].fname);
|
||||||
|
|
||||||
cue_destroy(data);
|
cdparse_destroy(data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
5
pico/cd/cd_parse.h
Normal file
5
pico/cd/cd_parse.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
cd_data_t *chd_parse(const char *fname);
|
||||||
|
cd_data_t *cue_parse(const char *fname);
|
||||||
|
void cdparse_destroy(cd_data_t *data);
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
#include "../pico_int.h"
|
#include "../pico_int.h"
|
||||||
#include "genplus_macros.h"
|
#include "genplus_macros.h"
|
||||||
#include "cue.h"
|
#include "cd_parse.h"
|
||||||
#include "cdd.h"
|
#include "cdd.h"
|
||||||
|
|
||||||
#ifdef USE_LIBTREMOR
|
#ifdef USE_LIBTREMOR
|
||||||
|
@ -321,6 +321,7 @@ int cdd_load(const char *filename, int type)
|
||||||
ret = (type == CT_BIN) ? 2352 : 2048;
|
ret = (type == CT_BIN) ? 2352 : 2048;
|
||||||
if (ret != cdd.sectorSize)
|
if (ret != cdd.sectorSize)
|
||||||
elprintf(EL_STATUS|EL_ANOMALY, "cd: type detection mismatch");
|
elprintf(EL_STATUS|EL_ANOMALY, "cd: type detection mismatch");
|
||||||
|
pm_sectorsize(cdd.sectorSize, cdd.toc.tracks[0].fd);
|
||||||
|
|
||||||
/* read CD image header + security code */
|
/* read CD image header + security code */
|
||||||
pm_read(header + 0x10, 0x200, cdd.toc.tracks[0].fd);
|
pm_read(header + 0x10, 0x200, cdd.toc.tracks[0].fd);
|
||||||
|
@ -448,6 +449,9 @@ int cdd_unload(void)
|
||||||
{
|
{
|
||||||
pm_close(cdd.toc.tracks[0].fd);
|
pm_close(cdd.toc.tracks[0].fd);
|
||||||
cdd.toc.tracks[0].fd = NULL;
|
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++)
|
for (i = 1; i < cdd.toc.last; i++)
|
||||||
|
@ -466,7 +470,11 @@ int cdd_unload(void)
|
||||||
if (Pico_mcd->cdda_type == CT_MP3)
|
if (Pico_mcd->cdda_type == CT_MP3)
|
||||||
fclose(cdd.toc.tracks[i].fd);
|
fclose(cdd.toc.tracks[i].fd);
|
||||||
else
|
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 */
|
/* detect single file images */
|
||||||
if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
|
if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
/* CD track */
|
/* CD track */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
char *fname;
|
||||||
void *fd;
|
void *fd;
|
||||||
#ifdef USE_LIBTREMOR
|
#ifdef USE_LIBTREMOR
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
39
pico/media.c
39
pico/media.c
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "pico_int.h"
|
#include "pico_int.h"
|
||||||
#include "cd/cue.h"
|
#include "cd/cd_parse.h"
|
||||||
|
|
||||||
unsigned char media_id_header[0x100];
|
unsigned char media_id_header[0x100];
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ static int detect_media(const char *fname)
|
||||||
return PM_BAD_DETECT;
|
return PM_BAD_DETECT;
|
||||||
|
|
||||||
/* don't believe in extensions, except .cue */
|
/* don't believe in extensions, except .cue */
|
||||||
if (strcasecmp(ext, ".cue") == 0)
|
if (strcasecmp(ext, ".cue") == 0 || strcasecmp(ext, ".chd") == 0)
|
||||||
return PM_CD;
|
return PM_CD;
|
||||||
|
|
||||||
pmf = pm_open(fname);
|
pmf = pm_open(fname);
|
||||||
|
@ -129,26 +129,31 @@ int PicoCdCheck(const char *fname_in, int *pregion)
|
||||||
pm_file *cd_f;
|
pm_file *cd_f;
|
||||||
int region = 4; // 1: Japan, 4: US, 8: Europe
|
int region = 4; // 1: Japan, 4: US, 8: Europe
|
||||||
char ext[5];
|
char ext[5];
|
||||||
cue_track_type type = CT_UNKNOWN;
|
enum cd_track_type type = CT_UNKNOWN;
|
||||||
cue_data_t *cue_data = NULL;
|
cd_data_t *cd_data = NULL;
|
||||||
|
|
||||||
// opens a cue, or searches for one
|
// opens a cue, or searches for one
|
||||||
cue_data = cue_parse(fname_in);
|
if (!cd_data && (cd_data = cue_parse(fname_in)) == NULL) {
|
||||||
if (cue_data != NULL) {
|
|
||||||
fname = cue_data->tracks[1].fname;
|
|
||||||
type = cue_data->tracks[1].type;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
get_ext(fname_in, ext);
|
get_ext(fname_in, ext);
|
||||||
if (strcasecmp(ext, ".cue") == 0)
|
if (strcasecmp(ext, ".cue") == 0)
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cd_data != NULL) {
|
||||||
|
// 1st track contains the code
|
||||||
|
fname = cd_data->tracks[1].fname;
|
||||||
|
type = cd_data->tracks[1].type;
|
||||||
|
}
|
||||||
|
|
||||||
cd_f = pm_open(fname);
|
cd_f = pm_open(fname);
|
||||||
if (cue_data != NULL)
|
cdparse_destroy(cd_data);
|
||||||
cue_destroy(cue_data);
|
if (cd_f == NULL) return CT_UNKNOWN; // let the upper level handle this
|
||||||
|
|
||||||
if (cd_f == NULL) return 0; // let the upper level handle this
|
|
||||||
|
|
||||||
if (pm_read(buf, 32, cd_f) != 32) {
|
if (pm_read(buf, 32, cd_f) != 32) {
|
||||||
pm_close(cd_f);
|
pm_close(cd_f);
|
||||||
|
@ -198,7 +203,7 @@ enum media_type_e PicoLoadMedia(const char *filename,
|
||||||
{
|
{
|
||||||
const char *rom_fname = filename;
|
const char *rom_fname = filename;
|
||||||
enum media_type_e media_type;
|
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 char *rom_data = NULL;
|
||||||
unsigned int rom_size = 0;
|
unsigned int rom_size = 0;
|
||||||
pm_file *rom = NULL;
|
pm_file *rom = NULL;
|
||||||
|
@ -219,7 +224,7 @@ enum media_type_e PicoLoadMedia(const char *filename,
|
||||||
{
|
{
|
||||||
// check for MegaCD image
|
// check for MegaCD image
|
||||||
cd_img_type = PicoCdCheck(filename, &cd_region);
|
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..
|
// valid CD image, ask frontend for BIOS..
|
||||||
rom_fname = NULL;
|
rom_fname = NULL;
|
||||||
|
@ -290,7 +295,7 @@ enum media_type_e PicoLoadMedia(const char *filename,
|
||||||
Pico.m.ncart_in = 0;
|
Pico.m.ncart_in = 0;
|
||||||
|
|
||||||
// insert CD if it was detected
|
// 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);
|
ret = cdd_load(filename, cd_img_type);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
PicoCartUnload();
|
PicoCartUnload();
|
||||||
|
|
35
pico/pico.h
35
pico/pico.h
|
@ -161,7 +161,8 @@ typedef enum
|
||||||
{
|
{
|
||||||
PMT_UNCOMPRESSED = 0,
|
PMT_UNCOMPRESSED = 0,
|
||||||
PMT_ZIP,
|
PMT_ZIP,
|
||||||
PMT_CSO
|
PMT_CSO,
|
||||||
|
PMT_CHD
|
||||||
} pm_type;
|
} pm_type;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -172,7 +173,9 @@ typedef struct
|
||||||
char ext[4];
|
char ext[4];
|
||||||
} pm_file;
|
} pm_file;
|
||||||
pm_file *pm_open(const char *path);
|
pm_file *pm_open(const char *path);
|
||||||
|
void pm_sectorsize(int length, pm_file *stream);
|
||||||
size_t pm_read(void *ptr, size_t bytes, pm_file *stream);
|
size_t pm_read(void *ptr, size_t bytes, pm_file *stream);
|
||||||
|
size_t pm_read_audio(void *ptr, size_t bytes, pm_file *stream);
|
||||||
int pm_seek(pm_file *stream, long offset, int whence);
|
int pm_seek(pm_file *stream, long offset, int whence);
|
||||||
int pm_close(pm_file *fp);
|
int pm_close(pm_file *fp);
|
||||||
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);
|
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);
|
||||||
|
@ -255,14 +258,34 @@ enum media_type_e {
|
||||||
PM_CD,
|
PM_CD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum cd_img_type
|
enum cd_track_type
|
||||||
{
|
{
|
||||||
CIT_NOT_CD = 0,
|
CT_UNKNOWN = 0,
|
||||||
CIT_ISO,
|
// data tracks
|
||||||
CIT_BIN,
|
CT_ISO = 1, /* 2048 B/sector */
|
||||||
CIT_CUE
|
CT_BIN = 2, /* 2352 B/sector */
|
||||||
|
// audio tracks
|
||||||
|
CT_MP3 = 3,
|
||||||
|
CT_WAV = 4,
|
||||||
|
CT_CHD = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *fname;
|
||||||
|
int pregap; /* pregap for current track */
|
||||||
|
int sector_offset; /* in current file */
|
||||||
|
int sector_xlength;
|
||||||
|
enum cd_track_type type;
|
||||||
|
} cd_track_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int track_count;
|
||||||
|
cd_track_t tracks[0];
|
||||||
|
} cd_data_t;
|
||||||
|
|
||||||
|
|
||||||
enum media_type_e PicoLoadMedia(const char *filename,
|
enum media_type_e PicoLoadMedia(const char *filename,
|
||||||
const char *carthw_cfg_fname,
|
const char *carthw_cfg_fname,
|
||||||
const char *(*get_bios_filename)(int *region, const char *cd_fname),
|
const char *(*get_bios_filename)(int *region, const char *cd_fname),
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include "ym2612.h"
|
#include "ym2612.h"
|
||||||
#include "sn76496.h"
|
#include "sn76496.h"
|
||||||
#include "../pico_int.h"
|
#include "../pico_int.h"
|
||||||
#include "../cd/cue.h"
|
|
||||||
#include "mix.h"
|
#include "mix.h"
|
||||||
#include "emu2413/emu2413.h"
|
#include "emu2413/emu2413.h"
|
||||||
|
|
||||||
|
@ -266,7 +265,7 @@ static void cdda_raw_update(int *buffer, int length)
|
||||||
if (PicoIn.sndRate < 22050 - 100) mult = 4;
|
if (PicoIn.sndRate < 22050 - 100) mult = 4;
|
||||||
cdda_bytes *= mult;
|
cdda_bytes *= mult;
|
||||||
|
|
||||||
ret = pm_read(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);
|
ret = pm_read_audio(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);
|
||||||
if (ret < cdda_bytes) {
|
if (ret < cdda_bytes) {
|
||||||
memset((char *)cdda_out_buffer + ret, 0, cdda_bytes - ret);
|
memset((char *)cdda_out_buffer + ret, 0, cdda_bytes - ret);
|
||||||
Pico_mcd->cdda_stream = NULL;
|
Pico_mcd->cdda_stream = NULL;
|
||||||
|
|
|
@ -99,7 +99,7 @@ endif
|
||||||
# CD
|
# CD
|
||||||
SRCS_COMMON += $(R)pico/cd/mcd.c $(R)pico/cd/memory.c $(R)pico/cd/sek.c \
|
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/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
|
$(R)pico/cd/misc.c $(R)pico/cd/pcm.c
|
||||||
# 32X
|
# 32X
|
||||||
ifneq "$(no_32x)" "1"
|
ifneq "$(no_32x)" "1"
|
||||||
|
|
|
@ -539,11 +539,11 @@ out:
|
||||||
|
|
||||||
int emu_swap_cd(const char *fname)
|
int emu_swap_cd(const char *fname)
|
||||||
{
|
{
|
||||||
enum cd_img_type cd_type;
|
enum cd_track_type cd_type;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
cd_type = PicoCdCheck(fname, NULL);
|
cd_type = PicoCdCheck(fname, NULL);
|
||||||
if (cd_type != CIT_NOT_CD)
|
if (cd_type != CT_UNKNOWN)
|
||||||
ret = cdd_load(fname, cd_type);
|
ret = cdd_load(fname, cd_type);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
menu_update_msg("Load failed, invalid CD image?");
|
menu_update_msg("Load failed, invalid CD image?");
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
static const char *rom_exts[] = {
|
static const char *rom_exts[] = {
|
||||||
"zip",
|
"zip",
|
||||||
"bin", "smd", "gen", "md",
|
"bin", "smd", "gen", "md",
|
||||||
"iso", "cso", "cue",
|
"iso", "cso", "cue", "chd",
|
||||||
"32x",
|
"32x",
|
||||||
"sms",
|
"sms",
|
||||||
NULL
|
NULL
|
||||||
|
|
|
@ -1577,9 +1577,9 @@ int menu_loop_tray(void)
|
||||||
selfname = romsel_loop(curr_path);
|
selfname = romsel_loop(curr_path);
|
||||||
if (selfname) {
|
if (selfname) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
cd_img_type cd_type;
|
cd_track_type cd_type;
|
||||||
cd_type = emu_cdCheck(NULL, romFileName);
|
cd_type = emu_cdCheck(NULL, romFileName);
|
||||||
if (cd_type != CIT_NOT_CD)
|
if (cd_type >= 0 && cd_type != CT_UNKNOWN)
|
||||||
ret = Insert_CD(romFileName, cd_type);
|
ret = Insert_CD(romFileName, cd_type);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
sprintf(menuErrorMsg, "Load failed, invalid CD image?");
|
sprintf(menuErrorMsg, "Load failed, invalid CD image?");
|
||||||
|
|
|
@ -749,7 +749,7 @@ void retro_get_system_info(struct retro_system_info *info)
|
||||||
#define _GIT_VERSION "-" GIT_VERSION
|
#define _GIT_VERSION "-" GIT_VERSION
|
||||||
#endif
|
#endif
|
||||||
info->library_version = VERSION _GIT_VERSION;
|
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;
|
info->need_fullpath = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1002,7 +1002,7 @@ static unsigned int disk_get_image_index(void)
|
||||||
|
|
||||||
static bool disk_set_image_index(unsigned int index)
|
static bool disk_set_image_index(unsigned int index)
|
||||||
{
|
{
|
||||||
enum cd_img_type cd_type;
|
enum cd_track_type cd_type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (index >= sizeof(disks) / sizeof(disks[0]))
|
if (index >= sizeof(disks) / sizeof(disks[0]))
|
||||||
|
@ -1024,7 +1024,7 @@ static bool disk_set_image_index(unsigned int index)
|
||||||
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
cd_type = PicoCdCheck(disks[index].fname, NULL);
|
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);
|
ret = cdd_load(disks[index].fname, cd_type);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
if (log_cb)
|
if (log_cb)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <pico/pico_int.h>
|
#include <pico/pico_int.h>
|
||||||
#include <pico/cd/genplus_macros.h>
|
#include <pico/cd/genplus_macros.h>
|
||||||
#include <pico/cd/cdd.h>
|
#include <pico/cd/cdd.h>
|
||||||
#include <pico/cd/cue.h>
|
|
||||||
|
|
||||||
#define OSD_FPS_X 432
|
#define OSD_FPS_X 432
|
||||||
|
|
||||||
|
@ -744,23 +743,10 @@ void emu_handle_resume(void)
|
||||||
// reopen first CD track
|
// reopen first CD track
|
||||||
if (cdd.toc.tracks[0].fd != NULL)
|
if (cdd.toc.tracks[0].fd != NULL)
|
||||||
{
|
{
|
||||||
const char *fname = rom_fname_reload;
|
lprintf("emu_HandleResume: reopen %s\n", cdd.toc.tracks[0].fname);
|
||||||
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);
|
|
||||||
pm_close(cdd.toc.tracks[0].fd);
|
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");
|
lprintf("reopen %s\n", cdd.toc.tracks[0].fd != NULL ? "ok" : "failed");
|
||||||
|
|
||||||
if (cue_data != NULL) cue_destroy(cue_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp3_reopen_file();
|
mp3_reopen_file();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue