Add CHD image support for PSX (#549)

This commit is contained in:
zakk4223
2022-02-20 10:12:06 -05:00
committed by GitHub
parent e509b8ec83
commit efe27ea77e
2 changed files with 99 additions and 12 deletions

View File

@@ -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)

View File

@@ -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);
}
}