Send CDROM subcode data to MegaCD core. Supports subcode data in CHD and bin/cue/sub format (#426)

Co-authored-by: Zakk <zakk@rsdio.com>
This commit is contained in:
zakk4223
2021-07-15 04:30:16 -04:00
committed by GitHub
parent f97a5318b0
commit 6cbe7a112f
3 changed files with 52 additions and 21 deletions

9
cd.h
View File

@@ -4,6 +4,12 @@
#include <libchdr/chd.h>
#include "file_io.h"
typedef enum
{
SUBCODE_NONE = 0, SUBCODE_RW, SUBCODE_RW_RAW
} cd_subcode_types_t;
typedef struct
{
fileTYPE f;
@@ -12,6 +18,7 @@ typedef struct
int end;
int type;
int sector_size;
cd_subcode_types_t sbc_type;
} cd_track_t;
typedef struct
@@ -21,7 +28,7 @@ typedef struct
int sectorSize;
chd_file *chd_f;
cd_track_t tracks[100];
// fileTYPE sub;
fileTYPE sub;
} toc_t;
typedef struct

View File

@@ -124,6 +124,13 @@ chd_error mister_load_chd(const char *filename, toc_t *cd_toc)
cd_toc->tracks[cd_toc->last].type = 0;
}
cd_toc->tracks[cd_toc->last].sbc_type = SUBCODE_NONE;
if (!strcmp(subtype, "RW")) {
cd_toc->tracks[cd_toc->last].sbc_type = SUBCODE_RW;
} else if (!strcmp(subtype, "RW_RAW")) {
cd_toc->tracks[cd_toc->last].sbc_type = SUBCODE_RW_RAW;
}
//CHD pads tracks to a multiple of 4 sectors, keep track of the overall sector count and calculate the difference between the cdrom lba and the effective chd lba
cd_toc->tracks[cd_toc->last].offset = (sector_cnt + pregap - cd_toc->tracks[cd_toc->last].start);
cd_toc->tracks[cd_toc->last].end = cd_toc->tracks[cd_toc->last].start + frames - pregap;

View File

@@ -232,6 +232,9 @@ int cdd_t::LoadCUE(const char* filename) {
this->toc.tracks[this->toc.last - 1].end = this->toc.end;
}
memcpy(&fname[strlen(fname) - 4], ".sub", 4);
FileOpen(&this->toc.sub, getFullPath(fname));
FileClose(&this->toc.tracks[this->toc.last].f);
return 0;
}
@@ -296,9 +299,6 @@ int cdd_t::Load(const char *filename)
this->toc.tracks[this->toc.last].start = this->toc.end;
this->loaded = 1;
//memcpy(&fname[strlen(fname) - 4], ".sub", 4);
//this->toc.sub = fopen(getFullPath(fname), "r");
printf("\x1b[32mMCD: CD mounted , last track = %u\n\x1b[0m", this->toc.last);
return 1;
@@ -330,7 +330,7 @@ void cdd_t::Unload()
}
}
//if (this->toc.sub) fclose(this->toc.sub);
if (this->toc.sub.opened()) FileClose(&this->toc.sub);
this->loaded = 0;
}
@@ -395,7 +395,6 @@ void cdd_t::Update() {
return;
}
//if (this->toc.sub) mcd_sub_send();
if (this->toc.tracks[this->index].type)
{
@@ -469,7 +468,7 @@ void cdd_t::Update() {
this->isData = this->toc.tracks[this->index].type;
//if (this->toc.sub) fseek(this->toc.sub, this->lba * 96, SEEK_SET);
if (this->toc.sub.opened()) FileSeek(&this->toc.sub, this->lba * 96, SEEK_SET);
if (this->toc.tracks[this->index].type)
{
@@ -709,7 +708,7 @@ void cdd_t::CommandExec() {
this->chd_audio_read_lba = this->lba;
this->audioOffset = 0;
//if (this->toc.sub) fseek(this->toc.sub, lba_ * 96, SEEK_SET);
if (this->toc.sub.opened()) FileSeek(&this->toc.sub, lba_ * 96, SEEK_SET);
this->isData = 1;
@@ -758,7 +757,7 @@ void cdd_t::CommandExec() {
FileSeek(&this->toc.tracks[index].f, (lba_ * 2352) - this->toc.tracks[index].offset, SEEK_SET);
}
//if (this->toc.sub) fseek(this->toc.sub, lba_ * 96, SEEK_SET);
if (this->toc.sub.opened()) FileSeek(&this->toc.sub, lba_ * 96, SEEK_SET);
this->isData = 1;
@@ -951,30 +950,47 @@ int cdd_t::ReadCDDA(uint8_t *buf)
return this->audioLength;
}
void cdd_t::ReadSubcode(uint16_t* buf)
void InterleaveSubcode(uint8_t *subc_data, uint16_t *buf)
{
(void)buf;
/*
uint8_t subc[96];
uint8_t dsub[8][12];
int i, j, n;
fread(subc, 96, 1, this->toc.sub);
for (i = 0, n = 0; i < 96; i += 2, n++)
for(i = 0, n=0; i < 96; i+=2,n++)
{
int code = 0;
for (j = 0; j < 8; j++)
{
int bits = (subc[(j * 12) + (i / 8)] >> (6 - (i & 6))) & 3;
code |= ((bits & 1) << (7 - j));
code |= ((bits >> 1) << (15 - j));
int bits = (subc_data[(j * 12) + (i / 8)] >> (6 - (i&6))) & 3;
code |= ((bits & 1) << (15 - j));
code |= ((bits >> 1) << (7 - j));
}
buf[n] = code;
}
*/
}
void cdd_t::ReadSubcode(uint16_t* buf)
{
uint8_t dsub[8][12];
uint8_t subc[96];
if (this->toc.chd_f)
{
//Just use the read sector call with an offset, since we previously read that sector, it is already in the hunk cache
if (this->toc.tracks[this->index].sbc_type == SUBCODE_RW_RAW) {
mister_chd_read_sector(this->toc.chd_f, this->chd_audio_read_lba + this->toc.tracks[this->index].offset, 0, CD_MAX_SECTOR_DATA, 96, (uint8_t *)buf, this->chd_hunkbuf, &this->chd_hunknum);
} else if (this->toc.tracks[this->index].sbc_type == SUBCODE_RW) {
mister_chd_read_sector(this->toc.chd_f, this->chd_audio_read_lba + this->toc.tracks[this->index].offset, 0, CD_MAX_SECTOR_DATA, 96, subc, this->chd_hunkbuf, &this->chd_hunknum);
InterleaveSubcode(subc, buf);
}
} else if (this->toc.sub.opened()) {
FileReadAdv(&this->toc.sub, subc, 96);
InterleaveSubcode(subc, buf);
}
}
int cdd_t::SectorSend(uint8_t* header)
{
uint8_t buf[2352 + 2352];
@@ -988,6 +1004,7 @@ int cdd_t::SectorSend(uint8_t* header)
len = ReadCDDA(buf);
}
SubcodeSend();
if (SendData)
return SendData(buf, len, CD_DATA_IO_INDEX);