Tracks[index].F = tmp_file;
// MP3 File
- Tracks[index].ftype = TYPE_MP3;
+ Tracks[index].ftype = CT_MP3;
fs *= 75;
fs /= Tracks[index].KBtps * 1000;
Tracks[index].Length = fs;
PICO_INTERNAL int Load_CD_Image(const char *cd_img_name, cd_img_type type)
{
- int i, j, num_track, Cur_LBA, index, ret, iso_name_len, missed, cd_img_sectors;
+ int i, j, num_track, Cur_LBA, index, ret;
+ int iso_name_len, missed, cd_img_sectors;
_scd_track *Tracks = Pico_mcd->TOC.Tracks;
- char tmp_name[1024], tmp_ext[10], tmp_ext_u[10];
+ char tmp_name[256], tmp_ext[10], tmp_ext_u[10];
cue_data_t *cue_data = NULL;
pm_file *pmf;
static const char *exts[] = {
Unload_ISO();
- /* is this .cue? */
- ret = strlen(cd_img_name);
- if (ret >= 3 && strcasecmp(cd_img_name + ret - 3, "cue") == 0)
- cue_data = cue_parse(cd_img_name);
- if (cue_data != NULL)
+ /* is this a .cue? */
+ cue_data = cue_parse(cd_img_name);
+ if (cue_data != NULL) {
cd_img_name = cue_data->tracks[1].fname;
-
- Tracks[0].ftype = type == CIT_BIN ? TYPE_BIN : TYPE_ISO;
+ Tracks[0].ftype = cue_data->tracks[1].type;
+ }
+ else
+ Tracks[0].ftype = type == CIT_BIN ? CT_BIN : CT_ISO;
Tracks[0].F = pmf = pm_open(cd_img_name);
if (Tracks[0].F == NULL)
return -1;
}
- if (Tracks[0].ftype == TYPE_ISO)
+ if (Tracks[0].ftype == CT_ISO)
cd_img_sectors = pmf->size >>= 11; // size in sectors
else cd_img_sectors = pmf->size /= 2352;
Tracks[0].Offset = 0;
Tracks[0].MSF.S = 2; // seconds
Tracks[0].MSF.F = 0; // frames
- elprintf(EL_STATUS, "Track 1: %02d:%02d:%02d %9i DATA",
- Tracks[0].MSF.M, Tracks[0].MSF.S, Tracks[0].MSF.F, Tracks[0].Length);
+ elprintf(EL_STATUS, "Track 1: %02d:%02d:%02d %9i DATA %s",
+ Tracks[0].MSF.M, Tracks[0].MSF.S, Tracks[0].MSF.F,
+ Tracks[0].Length, cd_img_name);
Cur_LBA = Tracks[0].Length = cd_img_sectors;
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
Cur_LBA += Tracks[index].Length;
- elprintf(EL_STATUS, "Track %2i: %02d:%02d:%02d %9i AUDIO - %s", num_track, Tracks[index].MSF.M,
+ elprintf(EL_STATUS, "Track %2i: %02d:%02d:%02d %9i AUDIO %s", num_track, Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F, Tracks[index].Length,
cue_data->tracks[num_track].fname);
}
{
if (Pico_mcd->TOC.Tracks[i].F != NULL)
{
- if (Pico_mcd->TOC.Tracks[i].ftype == TYPE_MP3)
+ if (Pico_mcd->TOC.Tracks[i].ftype == CT_MP3)
#ifdef _PSP_FW_VERSION
free(Pico_mcd->TOC.Tracks[i].F);
#else
return d + skip;
}
-static char *get_ext(char *fname)
+static int get_ext(const char *fname, char ext[4],
+ char *base, size_t base_size)
{
- int len = strlen(fname);
- return (len >= 3) ? (fname + len - 3) : fname;
+ int len, pos = 0;
+
+ len = strlen(fname);
+ if (len >= 3)
+ pos = len - 3;
+
+ strcpy(ext, fname + pos);
+
+ if (base != NULL) {
+ len = pos;
+ if (len + 1 < base_size)
+ len = base_size - 1;
+ memcpy(base, fname, len);
+ base[len] = 0;
+ }
+ return pos;
+}
+
+static void change_case(char *p, int to_upper)
+{
+ for (; *p != 0; p++) {
+ if (to_upper && 'a' <= *p && *p <= 'z')
+ *p += 'A' - 'a';
+ else if (!to_upper && 'A' <= *p && *p <= 'Z')
+ *p += 'a' - 'A';
+ }
}
+static int file_openable(const char *fname)
+{
+ FILE *f = fopen(fname, "rb");
+ if (f == NULL)
+ return 0;
+ fclose(f);
+ return 1;
+}
#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)
{
- char buff[256], current_file[256], buff2[32], *current_filep;
- FILE *f, *tmpf;
+ 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;
- cue_data_t *data;
+ size_t current_filep_size, fname_len;
+ cue_data_t *data = NULL;
+ FILE *f = NULL;
void *tmp;
- f = fopen(fname, "r");
- if (f == NULL) return NULL;
+ if (fname == NULL || (fname_len = strlen(fname)) == 0)
+ return NULL;
+
+ ret = get_ext(fname, ext, cue_base, sizeof(cue_base));
+ if (strcasecmp(ext, "cue") == 0) {
+ f = fopen(fname, "r");
+ }
+ else {
+ // not a .cue, try one with the same base name
+ if (ret + 3 < sizeof(cue_base)) {
+ strcpy(cue_base + ret, "cue");
+ f = fopen(cue_base, "r");
+ if (f == NULL) {
+ strcpy(cue_base + ret, "CUE");
+ f = fopen(cue_base, "r");
+ }
+ }
+ }
+
+ if (f == NULL)
+ return NULL;
snprintf(current_file, sizeof(current_file), "%s", fname);
- for (current_filep = current_file + strlen(current_file); current_filep > current_file; current_filep--)
- if (current_filep[-1] == '/' || current_filep[-1] == '\\') break;
+ current_filep = current_file + strlen(current_file);
+ for (; current_filep > current_file; current_filep--)
+ if (current_filep[-1] == '/' || current_filep[-1] == '\\')
+ break;
+
+ current_filep_size = sizeof(current_file) - (current_filep - current_file);
+
+ // the basename of cuefile, no path
+ snprintf(cue_base, sizeof(cue_base), "%s", current_filep);
+ p = cue_base + strlen(cue_base);
+ if (p - 3 >= cue_base)
+ p[-3] = 0;
data = calloc(1, sizeof(*data) + count_alloc * sizeof(cue_track));
- if (data == NULL) {
- fclose(f);
- return NULL;
- }
+ if (data == NULL)
+ goto out;
while (!feof(f))
{
tmp = fgets(buff, sizeof(buff), f);
- if (tmp == NULL) break;
+ if (tmp == NULL)
+ break;
mystrip(buff);
- if (buff[0] == 0) continue;
+ if (buff[0] == 0)
+ continue;
if (BEGINS(buff, "TITLE ") || BEGINS(buff, "PERFORMER ") || BEGINS(buff, "SONGWRITER "))
continue; /* who would put those here? Ignore! */
else if (BEGINS(buff, "FILE "))
{
- get_token(buff+5, current_filep, sizeof(current_file) - (current_filep - current_file));
+ get_token(buff + 5, current_filep, current_filep_size);
}
else if (BEGINS(buff, "TRACK "))
{
if (count >= count_alloc) {
count_alloc *= 2;
tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cue_track));
- if (tmp == NULL) { count--; break; }
+ if (tmp == NULL) {
+ count--;
+ break;
+ }
data = tmp;
}
memset(&data->tracks[count], 0, sizeof(data->tracks[0]));
+
if (count == 1 || strcmp(data->tracks[1].fname, current_file) != 0)
{
- data->tracks[count].fname = strdup(current_file);
- if (data->tracks[count].fname == NULL) break;
-
- tmpf = fopen(current_file, "rb");
- if (tmpf == NULL) {
- elprintf(EL_STATUS, "cue: bad/missing file: \"%s\"", current_file);
- count--; break;
+ if (file_openable(current_file))
+ goto file_ok;
+
+ elprintf(EL_STATUS, "cue: bad/missing file: \"%s\"", current_file);
+ if (count == 1) {
+ int cue_ucase;
+ char v;
+
+ get_ext(current_file, ext, NULL, 0);
+ snprintf(current_filep, current_filep_size,
+ "%s%s", cue_base, ext);
+ if (file_openable(current_file))
+ goto file_ok;
+
+ // try with the same case (for unix)
+ v = fname[fname_len - 1];
+ cue_ucase = ('A' <= v && v <= 'Z');
+ change_case(ext, cue_ucase);
+
+ snprintf(current_filep, current_filep_size,
+ "%s%s", cue_base, ext);
+ if (file_openable(current_file))
+ goto file_ok;
}
- fclose(tmpf);
+
+ count--;
+ break;
+
+file_ok:
+ data->tracks[count].fname = strdup(current_file);
+ if (data->tracks[count].fname == NULL)
+ break;
}
data->tracks[count].pregap = pending_pregap;
pending_pregap = 0;
if (data->tracks[count].fname != NULL)
{
// rely on extension, not type in cue..
- char *ext = get_ext(data->tracks[count].fname);
+ get_ext(data->tracks[count].fname, ext, NULL, 0);
if (strcasecmp(ext, "mp3") == 0)
data->tracks[count].type = CT_MP3;
else if (strcasecmp(ext, "wav") == 0)
if (data->tracks[count].fname != NULL)
free(data->tracks[count].fname);
free(data);
- return NULL;
+ data = NULL;
+ goto out;
}
data->track_count = count;
+
+out:
+ if (f != NULL)
+ fclose(f);
return data;
}