Add CHD image support for PSX (#549)
This commit is contained in:
@@ -86,6 +86,7 @@ chd_error mister_load_chd(const char *filename, toc_t *cd_toc)
|
||||
cd_toc->tracks[cd_toc->last].start += pregap;
|
||||
}
|
||||
|
||||
cd_toc->tracks[cd_toc->last].index1 = pregap;
|
||||
} else {
|
||||
if (pregap_valid)
|
||||
{
|
||||
@@ -93,6 +94,7 @@ chd_error mister_load_chd(const char *filename, toc_t *cd_toc)
|
||||
} else {
|
||||
cd_toc->tracks[cd_toc->last].start = 0;
|
||||
}
|
||||
cd_toc->tracks[cd_toc->last].index1 = pregap;
|
||||
}
|
||||
|
||||
if (!pregap_valid)
|
||||
|
||||
@@ -12,8 +12,13 @@
|
||||
#include "psx.h"
|
||||
#include "mcdheader.h"
|
||||
#include "../../cd.h"
|
||||
#include "../chd/mister_chd.h"
|
||||
#include <libchdr/chd.h>
|
||||
|
||||
static char buf[1024];
|
||||
static uint8_t chd_hunkbuf[CD_FRAME_SIZE * CD_FRAMES_PER_HUNK];
|
||||
static int chd_hunknum;
|
||||
|
||||
|
||||
static int sgets(char *out, int sz, char **in)
|
||||
{
|
||||
@@ -98,6 +103,19 @@ static uint16_t libCryptMask(const char *sbifile)
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void unload_chd(toc_t *table)
|
||||
{
|
||||
if (table->chd_f)
|
||||
{
|
||||
chd_close(table->chd_f);
|
||||
}
|
||||
memset(chd_hunkbuf, 0, sizeof(chd_hunkbuf));
|
||||
memset(table, 0, sizeof(toc_t));
|
||||
chd_hunknum = -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void unload_cue(toc_t *table)
|
||||
{
|
||||
for (int i = 0; i < table->last; i++)
|
||||
@@ -107,6 +125,37 @@ static void unload_cue(toc_t *table)
|
||||
memset(table, 0, sizeof(toc_t));
|
||||
}
|
||||
|
||||
static int load_chd(const char *filename, toc_t *table)
|
||||
{
|
||||
|
||||
unload_chd(table);
|
||||
chd_error err = mister_load_chd(filename, table);
|
||||
if (err != CHDERR_NONE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < table->last; i++)
|
||||
{
|
||||
if (i == 0) //First track fakes a pregap even if it doesn't exist
|
||||
{
|
||||
table->tracks[i].index1 = 150;
|
||||
table->tracks[i].start = 150;
|
||||
}
|
||||
table->tracks[i].end += (table->tracks[i].index1 - 1);
|
||||
}
|
||||
table->end = table->tracks[table->last-1].end+1;
|
||||
|
||||
memset(chd_hunkbuf, 0, sizeof(chd_hunkbuf));
|
||||
chd_hunknum = -1;
|
||||
|
||||
return 1;
|
||||
|
||||
//Need to store hunkbuf, hunknum and chd_f
|
||||
|
||||
|
||||
|
||||
}
|
||||
static int load_cue(const char* filename, toc_t *table)
|
||||
{
|
||||
static char fname[1024 + 10];
|
||||
@@ -284,6 +333,23 @@ static int load_cue(const char* filename, toc_t *table)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int load_cd_image(const char *filename, toc_t *table)
|
||||
{
|
||||
|
||||
const char *ext = strrchr(filename, '.');
|
||||
if (!ext) return 0;
|
||||
|
||||
if (!strncasecmp(".chd", ext, 4))
|
||||
{
|
||||
return load_chd(filename, table);
|
||||
} else if (!strncasecmp(".cue", ext, 4)) {
|
||||
return load_cue(filename,table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct track_t
|
||||
{
|
||||
uint32_t start_lba;
|
||||
@@ -328,8 +394,6 @@ void send_cue(toc_t *table)
|
||||
user_io_set_download(1);
|
||||
user_io_file_tx_data((uint8_t *)disk, sizeof(disk_t));
|
||||
user_io_set_download(0);
|
||||
|
||||
hexdump(disk, 256);
|
||||
delete(disk);
|
||||
}
|
||||
}
|
||||
@@ -387,17 +451,37 @@ void psx_read_cd(uint8_t *buffer, int lba, int cnt)
|
||||
{
|
||||
if (lba >= toc.tracks[i].start && lba <= toc.tracks[i].end)
|
||||
{
|
||||
if(toc.tracks[i].offset)
|
||||
FileSeek(&toc.tracks[0].f, ((lba * CD_SECTOR_LEN) - toc.tracks[i].offset), SEEK_SET);
|
||||
else
|
||||
FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start) * CD_SECTOR_LEN, SEEK_SET);
|
||||
|
||||
if (!toc.chd_f)
|
||||
{
|
||||
if(toc.tracks[i].offset)
|
||||
FileSeek(&toc.tracks[0].f, ((lba * CD_SECTOR_LEN) - toc.tracks[i].offset), SEEK_SET);
|
||||
else
|
||||
FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start) * CD_SECTOR_LEN, SEEK_SET);
|
||||
}
|
||||
while (cnt)
|
||||
{
|
||||
if (toc.tracks[i].offset)
|
||||
FileReadAdv(&toc.tracks[0].f, buffer, CD_SECTOR_LEN);
|
||||
else
|
||||
FileReadAdv(&toc.tracks[i].f, buffer, CD_SECTOR_LEN);
|
||||
if (toc.chd_f)
|
||||
{
|
||||
if (mister_chd_read_sector(toc.chd_f, (lba - toc.tracks[i].index1) + toc.tracks[i].offset, 0, 0, CD_SECTOR_LEN, buffer, chd_hunkbuf, &chd_hunknum) == CHDERR_NONE)
|
||||
{
|
||||
if (!toc.tracks[i].type) //CHD requires byteswap of audio data
|
||||
{
|
||||
for (int swapidx = 0; swapidx < CD_SECTOR_LEN; swapidx += 2)
|
||||
{
|
||||
uint8_t temp = buffer[swapidx];
|
||||
buffer[swapidx] = buffer[swapidx+1];
|
||||
buffer[swapidx+1] = temp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("\x1b[32mPSX: CHD read error: %d\n\x1b[0m", lba);
|
||||
}
|
||||
} else {
|
||||
if (toc.tracks[i].offset)
|
||||
FileReadAdv(&toc.tracks[0].f, buffer, CD_SECTOR_LEN);
|
||||
else
|
||||
FileReadAdv(&toc.tracks[i].f, buffer, CD_SECTOR_LEN);
|
||||
}
|
||||
if ((lba + 1) > toc.tracks[i].end) break;
|
||||
buffer += CD_SECTOR_LEN;
|
||||
cnt--;
|
||||
@@ -438,7 +522,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename)
|
||||
|
||||
if (strlen(filename))
|
||||
{
|
||||
if (load_cue(filename, &toc) && toc.last)
|
||||
if (load_cd_image(filename, &toc) && toc.last)
|
||||
{
|
||||
int name_len = strlen(filename);
|
||||
|
||||
@@ -511,6 +595,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename)
|
||||
{
|
||||
printf("Unmount CD\n");
|
||||
unload_cue(&toc);
|
||||
unload_chd(&toc);
|
||||
mount_cd(0, s_index);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user