mirror of
https://github.com/PSI-Rockin/DobieStation.git
synced 2024-05-20 13:08:11 -04:00
CHD: Fix CD by detecting sector offset
Kind of annoying to do this here, but our current CD/DVD detection requires us to know what the media is unless I misunderstand
This commit is contained in:
parent
8e4d8cc709
commit
1b7377330d
|
@ -1,6 +1,6 @@
|
|||
#include "chd_reader.hpp"
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
bool CHD_Reader::open(std::string name)
|
||||
{
|
||||
|
@ -21,6 +21,8 @@ bool CHD_Reader::open(std::string name)
|
|||
printf("chd: hunk size %d\n", m_header->hunkbytes);
|
||||
printf("chd: unitbytes %d\n", m_header->unitbytes);
|
||||
|
||||
find_offset();
|
||||
|
||||
// read first hunk
|
||||
err = chd_read(m_file, 0, m_buf.get());
|
||||
if (err != CHDERR_NONE)
|
||||
|
@ -32,14 +34,52 @@ bool CHD_Reader::open(std::string name)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CHD_Reader::find_offset()
|
||||
{
|
||||
// TODO: If we want to eventually read multiple tracks they each have separate metadata.
|
||||
char metadata_str[256];
|
||||
uint32_t metadata_len;
|
||||
chd_error err = chd_get_metadata(m_file, CDROM_TRACK_METADATA2_TAG, 0, metadata_str, sizeof(metadata_str), &metadata_len, nullptr, nullptr);
|
||||
if (err != CHDERR_NONE)
|
||||
{
|
||||
fprintf(stderr, "chd: read_metadata: %s\n", chd_error_string(err));
|
||||
}
|
||||
|
||||
char type_str[256];
|
||||
char subtype_str[256];
|
||||
char pgtype_str[256];
|
||||
char pgsub_str[256];
|
||||
int track_num = 0, frames = 0, pregap_frames = 0, postgap_frames = 0;
|
||||
|
||||
std::sscanf(metadata_str, CDROM_TRACK_METADATA2_FORMAT, &track_num, type_str, subtype_str, &frames,
|
||||
&pregap_frames, pgtype_str, pgsub_str, &postgap_frames);
|
||||
|
||||
if (std::strncmp(type_str, "MODE2_FORM_MIX", 14) == 0)
|
||||
m_sector_offset = 8;
|
||||
else if (std::strncmp(type_str, "MODE2_FORM1", 10) == 0)
|
||||
m_sector_offset = 0;
|
||||
else if (std::strncmp(type_str, "MODE2_FORM2", 10) == 0)
|
||||
m_sector_offset = 0;
|
||||
else if (std::strncmp(type_str, "MODE2_RAW", 9) == 0)
|
||||
m_sector_offset = 24;
|
||||
else if (std::strncmp(type_str, "MODE1_RAW", 9) == 0)
|
||||
m_sector_offset = 16;
|
||||
else if (std::strncmp(type_str, "MODE1", 5) == 0)
|
||||
m_sector_offset = 0;
|
||||
else if (std::strncmp(type_str, "MODE2", 5) == 0)
|
||||
m_sector_offset = 0; // IDK
|
||||
else if (std::strncmp(type_str, "AUDIO", 5) == 0)
|
||||
m_sector_offset = 0; // IDK
|
||||
}
|
||||
|
||||
void CHD_Reader::close()
|
||||
{
|
||||
printf("chd: close");
|
||||
chd_close(m_file);
|
||||
delete(m_header);
|
||||
delete (m_header);
|
||||
}
|
||||
|
||||
size_t CHD_Reader::read(uint8_t *buff, size_t bytes)
|
||||
size_t CHD_Reader::read(uint8_t* buff, size_t bytes)
|
||||
{
|
||||
assert(bytes);
|
||||
assert(m_virtptr + bytes <= m_size);
|
||||
|
@ -60,14 +100,13 @@ size_t CHD_Reader::read(uint8_t *buff, size_t bytes)
|
|||
|
||||
for (uint32_t i = (uint32_t)start_hunk; i <= end_hunk; i++)
|
||||
{
|
||||
//printf("chd: in the loop\n");
|
||||
if (i != m_current_hunk)
|
||||
{
|
||||
printf("chd: grabbing new hunk %d\n", i);
|
||||
chd_error err = chd_read(m_file, i, m_buf.get());
|
||||
if (err != CHDERR_NONE)
|
||||
{
|
||||
printf("chd: read %s\n", chd_error_string(err));
|
||||
fprintf(stderr, "chd: read %s\n", chd_error_string(err));
|
||||
return total_read;
|
||||
}
|
||||
|
||||
|
@ -88,9 +127,13 @@ size_t CHD_Reader::read(uint8_t *buff, size_t bytes)
|
|||
|
||||
assert(readlen <= bytes);
|
||||
|
||||
memcpy(buff, m_buf.get() + local_ofs, readlen);
|
||||
memcpy(buff, m_buf.get() + local_ofs + m_sector_offset, readlen);
|
||||
total_read += readlen;
|
||||
|
||||
//m_virtptr += readlen;
|
||||
// Need to advance the full sector here to not get misaligned
|
||||
// other cdvd containers behave inconsistently anyway regarding seek
|
||||
// by read,
|
||||
m_virtptr += m_header->unitbytes;
|
||||
buff += readlen;
|
||||
}
|
||||
|
@ -102,21 +145,19 @@ size_t CHD_Reader::read(uint8_t *buff, size_t bytes)
|
|||
|
||||
void CHD_Reader::seek(size_t ofs, std::ios::seekdir whence)
|
||||
{
|
||||
printf("chd: seek to sector %zd, bytes %lu\n", ofs, ofs*m_header->unitbytes);
|
||||
printf("chd: seek to sector %zd, bytes %lu\n", ofs, ofs * m_header->unitbytes);
|
||||
ofs *= m_header->unitbytes;
|
||||
if (whence == std::ios::beg)
|
||||
{
|
||||
if ((uint64_t)ofs < m_size)
|
||||
m_virtptr = (uint64_t)ofs;
|
||||
}
|
||||
else
|
||||
if (whence == std::ios::cur)
|
||||
else if (whence == std::ios::cur)
|
||||
{
|
||||
if (m_virtptr + ofs < m_size)
|
||||
m_virtptr = m_virtptr + ofs;
|
||||
}
|
||||
else
|
||||
if (whence == std::ios::end)
|
||||
else if (whence == std::ios::end)
|
||||
{
|
||||
if (m_size - ofs < m_size)
|
||||
m_virtptr = m_size - ofs;
|
||||
|
@ -125,7 +166,7 @@ void CHD_Reader::seek(size_t ofs, std::ios::seekdir whence)
|
|||
|
||||
bool CHD_Reader::is_open()
|
||||
{
|
||||
if(m_file)
|
||||
if (m_file)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
|
||||
class CHD_Reader : public CDVD_Container
|
||||
{
|
||||
private:
|
||||
chd_file *m_file {nullptr};
|
||||
const chd_header *m_header {nullptr};
|
||||
|
||||
|
||||
uint64_t m_virtptr {0};
|
||||
size_t m_size {0};
|
||||
uint32_t m_current_hunk {0};
|
||||
std::unique_ptr<uint8_t[]> m_buf;
|
||||
|
||||
public:
|
||||
bool open(std::string name);
|
||||
void close();
|
||||
|
@ -25,6 +15,18 @@ class CHD_Reader : public CDVD_Container
|
|||
|
||||
bool is_open();
|
||||
size_t get_size();
|
||||
|
||||
private:
|
||||
chd_file *m_file {nullptr};
|
||||
const chd_header *m_header {nullptr};
|
||||
|
||||
uint32_t m_sector_offset {0};
|
||||
uint64_t m_virtptr {0};
|
||||
size_t m_size {0};
|
||||
uint32_t m_current_hunk {0};
|
||||
std::unique_ptr<uint8_t[]> m_buf;
|
||||
|
||||
void find_offset();
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue