mirror of https://github.com/inolen/redream.git
initial widescreen patching support
This commit is contained in:
parent
583c2d35b5
commit
d37dc725c6
|
@ -197,6 +197,7 @@ set(RELIB_SOURCES
|
|||
src/guest/gdrom/disc.c
|
||||
src/guest/gdrom/gdi.c
|
||||
src/guest/gdrom/gdrom.c
|
||||
src/guest/gdrom/patch.c
|
||||
src/guest/holly/holly.c
|
||||
src/guest/maple/controller.c
|
||||
src/guest/maple/maple.c
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
DEFINE_AGGREGATE_COUNTER(frames);
|
||||
|
||||
DEFINE_PERSISTENT_OPTION_STRING(aspect_ratio, "stretch", "Video aspect ratio");
|
||||
DEFINE_PERSISTENT_OPTION_INT(widescreen_hack, 1, "Enable widescreen hacks");
|
||||
|
||||
static const char *aspect_ratios[] = {
|
||||
"stretch", "4:3",
|
||||
|
@ -554,13 +553,6 @@ static void emu_debug_menu(struct emu *emu) {
|
|||
}
|
||||
}
|
||||
|
||||
igSeparator();
|
||||
|
||||
if (igMenuItem("widescreen hack", NULL, OPTION_widescreen_hack, 1)) {
|
||||
OPTION_widescreen_hack = !OPTION_widescreen_hack;
|
||||
LOG_WARNING("widescreen hack settings changed, restart to apply");
|
||||
}
|
||||
|
||||
igEndMenu();
|
||||
}
|
||||
igEndMenu();
|
||||
|
@ -570,6 +562,7 @@ static void emu_debug_menu(struct emu *emu) {
|
|||
}
|
||||
|
||||
bios_debug_menu(emu->dc->bios);
|
||||
gdrom_debug_menu(emu->dc->gdrom);
|
||||
holly_debug_menu(emu->dc->holly);
|
||||
aica_debug_menu(emu->dc->aica);
|
||||
sh4_debug_menu(emu->dc->sh4);
|
||||
|
|
|
@ -799,7 +799,7 @@ static void aica_toggle_recording(struct aica *aica) {
|
|||
static int aica_init(struct device *dev) {
|
||||
struct aica *aica = (struct aica *)dev;
|
||||
|
||||
aica->wave_ram = memory_translate(aica->memory, "aica wave ram", 0x00000000);
|
||||
aica->wave_ram = memory_translate(aica->memory, "aica wave ram", 0x0);
|
||||
|
||||
/* init channels */
|
||||
{
|
||||
|
|
|
@ -213,7 +213,7 @@ static int arm7_init(struct device *dev) {
|
|||
arm->jit = jit_create("arm7", arm->frontend, arm->backend,
|
||||
(struct jit_guest *)arm->guest);
|
||||
|
||||
arm->wave_ram = memory_translate(dc->memory, "aica wave ram", 0x00000000);
|
||||
arm->wave_ram = memory_translate(dc->memory, "aica wave ram", 0x0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ static int bios_boot(struct bios *bios) {
|
|||
|
||||
LOG_INFO("bios_boot using hle bootstrap");
|
||||
|
||||
/* load ip.bin bootstrap */
|
||||
/* load IP.BIN bootstrap */
|
||||
{
|
||||
/* bootstrap occupies the first 16 sectors of the data track */
|
||||
struct gd_spi_session data_session;
|
||||
|
@ -234,31 +234,22 @@ static int bios_boot(struct bios *bios) {
|
|||
as_memcpy_to_guest(space, BOOT1_ADDR, tmp, read);
|
||||
}
|
||||
|
||||
/* load 1st_read.bin into ram */
|
||||
/* load 1ST_READ.BIN into ram */
|
||||
{
|
||||
const char *bootfile = "1ST_READ.BIN";
|
||||
|
||||
int fad;
|
||||
int len;
|
||||
int found = gdrom_find_file(gd, bootfile, &fad, &len);
|
||||
if (!found) {
|
||||
LOG_WARNING("bios_boot failed to find %s", bootfile);
|
||||
return 0;
|
||||
}
|
||||
int fad, len;
|
||||
gdrom_get_bootfile(gd, &fad, &len);
|
||||
|
||||
/* copy the bootfile into ram */
|
||||
uint8_t *tmp = malloc(len);
|
||||
int read = gdrom_read_bytes(gd, fad, len, tmp, len);
|
||||
if (read != len) {
|
||||
LOG_WARNING("bios_boot failed to copied %s", bootfile);
|
||||
LOG_WARNING("bios_boot failed to copy bootfile");
|
||||
free(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
as_memcpy_to_guest(space, BOOT2_ADDR, tmp, read);
|
||||
free(tmp);
|
||||
|
||||
LOG_INFO("bios_boot found '%s' at fad=%d size=%d", bootfile, fad, len);
|
||||
}
|
||||
|
||||
/* write system info */
|
||||
|
|
|
@ -140,6 +140,7 @@ int dc_init(struct dreamcast *dc) {
|
|||
}
|
||||
}
|
||||
|
||||
/* initialize after devices in order to manipulate the boot and flash roms */
|
||||
if (!bios_init(dc->bios)) {
|
||||
LOG_WARNING("failed to initialize bios");
|
||||
return 0;
|
||||
|
|
|
@ -34,54 +34,24 @@ struct cdi {
|
|||
int num_tracks;
|
||||
};
|
||||
|
||||
static int cdi_read_sectors(struct disc *disc, int fad, int num_sectors,
|
||||
int sector_fmt, int sector_mask, void *dst,
|
||||
int dst_size) {
|
||||
static void cdi_read_sector(struct disc *disc, struct track *track, int fad,
|
||||
void *dst) {
|
||||
struct cdi *cdi = (struct cdi *)disc;
|
||||
|
||||
struct track *track = disc_lookup_track(disc, fad);
|
||||
CHECK_NOTNULL(track);
|
||||
CHECK(sector_fmt == GD_SECTOR_ANY || sector_fmt == track->sector_fmt);
|
||||
CHECK(sector_mask == GD_MASK_DATA);
|
||||
|
||||
/* seek the to the starting fad */
|
||||
int offset = track->file_offset + fad * track->sector_size;
|
||||
int res = fseek(cdi->fp, offset, SEEK_SET);
|
||||
CHECK_EQ(res, 0);
|
||||
|
||||
/* only read the data portion of the track */
|
||||
int header_size, error_size, data_size;
|
||||
res = fseek(cdi->fp, track->header_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
|
||||
if (track->sector_fmt == GD_SECTOR_CDDA) {
|
||||
header_size = 0;
|
||||
error_size = 0;
|
||||
data_size = track->sector_size - header_size - error_size;
|
||||
CHECK_EQ(data_size, 2352);
|
||||
} else if (track->sector_fmt == GD_SECTOR_M2F1) {
|
||||
header_size = 8;
|
||||
error_size = 280;
|
||||
data_size = track->sector_size - header_size - error_size;
|
||||
CHECK_EQ(data_size, 2048);
|
||||
} else {
|
||||
CHECK(0);
|
||||
}
|
||||
res = (int)fread(dst, 1, track->data_size, cdi->fp);
|
||||
CHECK_EQ(res, track->data_size);
|
||||
|
||||
int read = 0;
|
||||
|
||||
for (int i = 0; i < num_sectors; i++) {
|
||||
res = fseek(cdi->fp, header_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
|
||||
CHECK_LE(read + data_size, dst_size);
|
||||
res = (int)fread(dst + read, 1, data_size, cdi->fp);
|
||||
CHECK_EQ(res, data_size);
|
||||
read += res;
|
||||
|
||||
res = fseek(cdi->fp, error_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
}
|
||||
|
||||
return read;
|
||||
res = fseek(cdi->fp, track->error_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
}
|
||||
|
||||
static void cdi_get_toc(struct disc *disc, int area, struct track **first_track,
|
||||
|
@ -224,8 +194,25 @@ static int cdi_parse_track(struct disc *disc, uint32_t version,
|
|||
track->fad = pregap_length + lba;
|
||||
track->adr = 0;
|
||||
track->ctrl = sector_fmt == GD_SECTOR_CDDA ? 0 : 4;
|
||||
|
||||
track->sector_fmt = cdi_sector_formats[mode];
|
||||
track->sector_size = sector_size;
|
||||
if (track->sector_fmt == GD_SECTOR_CDDA) {
|
||||
track->header_size = 0;
|
||||
track->error_size = 0;
|
||||
track->data_size =
|
||||
track->sector_size - track->header_size - track->error_size;
|
||||
CHECK_EQ(track->data_size, 2352);
|
||||
} else if (track->sector_fmt == GD_SECTOR_M2F1) {
|
||||
track->header_size = 8;
|
||||
track->error_size = 280;
|
||||
track->data_size =
|
||||
track->sector_size - track->header_size - track->error_size;
|
||||
CHECK_EQ(track->data_size, 2048);
|
||||
} else {
|
||||
LOG_FATAL("unexpected sector format %d", track->sector_fmt);
|
||||
}
|
||||
|
||||
track->file_offset = data_offset - track->fad * track->sector_size;
|
||||
|
||||
LOG_INFO("cdi_parse_track track=%d fad=%d off=%d mode=%s/%d", track->num,
|
||||
|
@ -379,7 +366,7 @@ struct disc *cdi_create(const char *filename) {
|
|||
cdi->get_num_tracks = &cdi_get_num_tracks;
|
||||
cdi->get_track = &cdi_get_track;
|
||||
cdi->get_toc = &cdi_get_toc;
|
||||
cdi->read_sectors = &cdi_read_sectors;
|
||||
cdi->read_sector = &cdi_read_sector;
|
||||
|
||||
struct disc *disc = (struct disc *)cdi;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "guest/gdrom/cdi.h"
|
||||
#include "guest/gdrom/gdi.h"
|
||||
#include "guest/gdrom/iso.h"
|
||||
#include "guest/gdrom/patch.h"
|
||||
|
||||
/* meta information found in the ip.bin */
|
||||
struct disc_meta {
|
||||
|
@ -38,8 +39,8 @@ int disc_read_bytes(struct disc *disc, int fad, int len, void *dst,
|
|||
int rem = len;
|
||||
|
||||
while (rem) {
|
||||
int n = disc->read_sectors(disc, fad, 1, GD_SECTOR_ANY, GD_MASK_DATA, tmp,
|
||||
sizeof(tmp));
|
||||
int n = disc_read_sectors(disc, fad, 1, GD_SECTOR_ANY, GD_MASK_DATA, tmp,
|
||||
sizeof(tmp));
|
||||
CHECK(n);
|
||||
|
||||
/* don't overrun */
|
||||
|
@ -57,8 +58,29 @@ int disc_read_bytes(struct disc *disc, int fad, int len, void *dst,
|
|||
int disc_read_sectors(struct disc *disc, int fad, int num_sectors,
|
||||
int sector_fmt, int sector_mask, void *dst,
|
||||
int dst_size) {
|
||||
return disc->read_sectors(disc, fad, num_sectors, sector_fmt, sector_mask,
|
||||
dst, dst_size);
|
||||
struct track *track = disc_lookup_track(disc, fad);
|
||||
CHECK_NOTNULL(track);
|
||||
CHECK(sector_fmt == GD_SECTOR_ANY || sector_fmt == track->sector_fmt);
|
||||
CHECK(sector_mask == GD_MASK_DATA);
|
||||
|
||||
int read = 0;
|
||||
int endfad = fad + num_sectors;
|
||||
int bootstart = disc->bootfad;
|
||||
int bootend = disc->bootfad + (disc->bootlen / track->data_size);
|
||||
|
||||
for (int i = fad; i < endfad; i++) {
|
||||
CHECK_LE(read + track->data_size, dst_size);
|
||||
disc->read_sector(disc, track, i, dst + read);
|
||||
read += track->data_size;
|
||||
}
|
||||
|
||||
/* apply bootfile patches */
|
||||
if (bootstart <= endfad && fad <= bootend) {
|
||||
int offset = (fad - bootstart) * track->data_size;
|
||||
patch_bootfile(disc->id, dst, offset, read);
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
int disc_find_file(struct disc *disc, const char *filename, int *fad,
|
||||
|
@ -67,10 +89,10 @@ int disc_find_file(struct disc *disc, const char *filename, int *fad,
|
|||
|
||||
/* get the session for the main data track */
|
||||
struct session *session = disc_get_session(disc, 1);
|
||||
struct track *data_track = disc_get_track(disc, session->first_track);
|
||||
struct track *track = disc_get_track(disc, session->first_track);
|
||||
|
||||
/* read primary volume descriptor */
|
||||
int read = disc_read_sectors(disc, data_track->fad + ISO_PVD_SECTOR, 1,
|
||||
int read = disc_read_sectors(disc, track->fad + ISO_PVD_SECTOR, 1,
|
||||
GD_SECTOR_ANY, GD_MASK_DATA, tmp, sizeof(tmp));
|
||||
if (!read) {
|
||||
return 0;
|
||||
|
@ -164,31 +186,12 @@ int disc_get_num_sessions(struct disc *disc) {
|
|||
return disc->get_num_sessions(disc);
|
||||
}
|
||||
|
||||
void disc_destroy(struct disc *disc) {
|
||||
disc->destroy(disc);
|
||||
}
|
||||
|
||||
int disc_get_format(struct disc *disc) {
|
||||
return disc->get_format(disc);
|
||||
}
|
||||
|
||||
void disc_get_id(struct disc *disc, char *id, int size) {
|
||||
struct disc_meta meta;
|
||||
disc_get_meta(disc, &meta);
|
||||
|
||||
char device_info[17];
|
||||
char product_number[11];
|
||||
char product_version[7];
|
||||
char name[129];
|
||||
strncpy_trim_spaces(device_info, meta.device_info, sizeof(meta.device_info));
|
||||
strncpy_trim_spaces(product_number, meta.product_number,
|
||||
sizeof(meta.product_number));
|
||||
strncpy_trim_spaces(product_version, meta.product_version,
|
||||
sizeof(meta.product_version));
|
||||
strncpy_trim_spaces(name, meta.name, sizeof(meta.name));
|
||||
|
||||
snprintf(id, size, "%s %s %s %s", name, product_number, product_version,
|
||||
device_info);
|
||||
void disc_destroy(struct disc *disc) {
|
||||
disc->destroy(disc);
|
||||
}
|
||||
|
||||
struct disc *disc_create(const char *filename) {
|
||||
|
@ -200,11 +203,36 @@ struct disc *disc_create(const char *filename) {
|
|||
disc = gdi_create(filename);
|
||||
}
|
||||
|
||||
if (disc) {
|
||||
char id[DISC_MAX_ID_SIZE];
|
||||
disc_get_id(disc, id, sizeof(id));
|
||||
LOG_INFO("disc_create %s", id);
|
||||
if (!disc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* generate a unique id for the disc, and cache off info about the bootfile */
|
||||
struct disc_meta meta;
|
||||
disc_get_meta(disc, &meta);
|
||||
|
||||
char device_info[17];
|
||||
char product_number[11];
|
||||
char product_version[7];
|
||||
char bootname[17];
|
||||
char name[129];
|
||||
|
||||
strncpy_trim_spaces(device_info, meta.device_info, sizeof(meta.device_info));
|
||||
strncpy_trim_spaces(product_number, meta.product_number,
|
||||
sizeof(meta.product_number));
|
||||
strncpy_trim_spaces(product_version, meta.product_version,
|
||||
sizeof(meta.product_version));
|
||||
strncpy_trim_spaces(bootname, meta.bootname, sizeof(meta.bootname));
|
||||
strncpy_trim_spaces(name, meta.name, sizeof(meta.name));
|
||||
|
||||
snprintf(disc->id, sizeof(disc->id), "%s %s %s %s", name, product_number,
|
||||
product_version, device_info);
|
||||
|
||||
int found = disc_find_file(disc, bootname, &disc->bootfad, &disc->bootlen);
|
||||
CHECK(found);
|
||||
|
||||
LOG_INFO("disc_create %s bootfad=%d bootlen=%d", disc->id, disc->bootfad,
|
||||
disc->bootlen);
|
||||
|
||||
return disc;
|
||||
}
|
||||
|
|
|
@ -11,11 +11,19 @@
|
|||
|
||||
struct track {
|
||||
int num;
|
||||
/* frame adddress, equal to lba + 150 */
|
||||
int fad;
|
||||
/* type of information encoded in the sub q channel */
|
||||
int adr;
|
||||
/* type of track */
|
||||
int ctrl;
|
||||
/* sector info */
|
||||
int sector_fmt;
|
||||
int sector_size;
|
||||
int header_size;
|
||||
int error_size;
|
||||
int data_size;
|
||||
/* backing file */
|
||||
char filename[PATH_MAX];
|
||||
int file_offset;
|
||||
};
|
||||
|
@ -28,6 +36,10 @@ struct session {
|
|||
};
|
||||
|
||||
struct disc {
|
||||
char id[DISC_MAX_ID_SIZE];
|
||||
int bootfad;
|
||||
int bootlen;
|
||||
|
||||
void (*destroy)(struct disc *);
|
||||
|
||||
int (*get_format)(struct disc *);
|
||||
|
@ -40,22 +52,22 @@ struct disc {
|
|||
|
||||
void (*get_toc)(struct disc *, int, struct track **, struct track **, int *,
|
||||
int *);
|
||||
int (*read_sectors)(struct disc *, int, int, int, int, void *, int);
|
||||
void (*read_sector)(struct disc *, struct track *, int, void *);
|
||||
};
|
||||
|
||||
struct disc *disc_create(const char *filename);
|
||||
void disc_destroy(struct disc *disc);
|
||||
|
||||
void disc_get_id(struct disc *disc, char *id, int size);
|
||||
int disc_get_format(struct disc *disc);
|
||||
int disc_get_num_sessions(struct disc *disc);
|
||||
struct session *disc_get_session(struct disc *disc, int n);
|
||||
int disc_get_num_tracks(struct disc *disc);
|
||||
struct track *disc_get_track(struct disc *disc, int n);
|
||||
struct track *disc_lookup_track(struct disc *disc, int fad);
|
||||
int disc_find_file(struct disc *disc, const char *filename, int *fad, int *len);
|
||||
void disc_get_toc(struct disc *disc, int area, struct track **first_track,
|
||||
struct track **last_track, int *leadin_fad, int *leadout_fad);
|
||||
|
||||
int disc_find_file(struct disc *disc, const char *filename, int *fad, int *len);
|
||||
int disc_read_sectors(struct disc *disc, int fad, int num_sectors,
|
||||
int sector_fmt, int sector_mask, void *dst, int dst_size);
|
||||
int disc_read_bytes(struct disc *disc, int fad, int len, void *dst,
|
||||
|
|
|
@ -11,16 +11,10 @@ struct gdi {
|
|||
int num_tracks;
|
||||
};
|
||||
|
||||
static int gdi_read_sectors(struct disc *disc, int fad, int num_sectors,
|
||||
int sector_fmt, int sector_mask, void *dst,
|
||||
int dst_size) {
|
||||
static void gdi_read_sector(struct disc *disc, struct track *track, int fad,
|
||||
void *dst) {
|
||||
struct gdi *gdi = (struct gdi *)disc;
|
||||
|
||||
struct track *track = disc_lookup_track(disc, fad);
|
||||
CHECK_NOTNULL(track);
|
||||
CHECK(sector_fmt == GD_SECTOR_ANY || sector_fmt == track->sector_fmt);
|
||||
CHECK(sector_mask == GD_MASK_DATA);
|
||||
|
||||
/* open the file backing the track */
|
||||
int n = (int)(track - gdi->tracks);
|
||||
FILE *fp = gdi->files[n];
|
||||
|
@ -36,27 +30,14 @@ static int gdi_read_sectors(struct disc *disc, int fad, int num_sectors,
|
|||
CHECK_EQ(res, 0);
|
||||
|
||||
/* only read the data portion of the track */
|
||||
int header_size = 16;
|
||||
int error_size = 288;
|
||||
int data_size = track->sector_size - header_size - error_size;
|
||||
CHECK_EQ(data_size, 2048);
|
||||
res = fseek(fp, track->header_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
|
||||
int read = 0;
|
||||
res = (int)fread(dst, 1, track->data_size, fp);
|
||||
CHECK_EQ(res, track->data_size);
|
||||
|
||||
for (int i = 0; i < num_sectors; i++) {
|
||||
res = fseek(fp, header_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
|
||||
CHECK_LE(read + data_size, dst_size);
|
||||
res = (int)fread(dst + read, 1, data_size, fp);
|
||||
CHECK_EQ(res, data_size);
|
||||
read += res;
|
||||
|
||||
res = fseek(fp, error_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
}
|
||||
|
||||
return read;
|
||||
res = fseek(fp, track->error_size, SEEK_CUR);
|
||||
CHECK_EQ(res, 0);
|
||||
}
|
||||
|
||||
static void gdi_get_toc(struct disc *disc, int area, struct track **first_track,
|
||||
|
@ -167,8 +148,14 @@ static int gdi_parse(struct disc *disc, const char *filename) {
|
|||
track->num = gdi->num_tracks;
|
||||
track->fad = lba + GDROM_PREGAP;
|
||||
track->ctrl = ctrl;
|
||||
|
||||
track->sector_fmt = GD_SECTOR_M1;
|
||||
track->sector_size = sector_size;
|
||||
track->header_size = 16;
|
||||
track->error_size = 288;
|
||||
track->data_size =
|
||||
track->sector_size - track->header_size - track->error_size;
|
||||
|
||||
track->file_offset = file_offset - track->fad * track->sector_size;
|
||||
snprintf(track->filename, sizeof(track->filename), "%s" PATH_SEPARATOR "%s",
|
||||
dirname, filename);
|
||||
|
@ -215,7 +202,7 @@ struct disc *gdi_create(const char *filename) {
|
|||
gdi->get_num_tracks = &gdi_get_num_tracks;
|
||||
gdi->get_track = &gdi_get_track;
|
||||
gdi->get_toc = &gdi_get_toc;
|
||||
gdi->read_sectors = &gdi_read_sectors;
|
||||
gdi->read_sector = &gdi_read_sector;
|
||||
|
||||
struct disc *disc = (struct disc *)gdi;
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#include "guest/dreamcast.h"
|
||||
#include "guest/gdrom/gdrom_replies.inc"
|
||||
#include "guest/gdrom/gdrom_types.h"
|
||||
#include "guest/gdrom/patch.h"
|
||||
#include "guest/holly/holly.h"
|
||||
#include "render/imgui.h"
|
||||
|
||||
#if 0
|
||||
#define LOG_GDROM LOG_INFO
|
||||
|
@ -490,16 +492,6 @@ int gdrom_read_sectors(struct gdrom *gd, int fad, int num_sectors, int fmt,
|
|||
dst_size);
|
||||
}
|
||||
|
||||
int gdrom_find_file(struct gdrom *gd, const char *filename, int *fad,
|
||||
int *len) {
|
||||
if (!gd->disc) {
|
||||
LOG_WARNING("gdrom_find_file failed, no disc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return disc_find_file(gd->disc, filename, fad, len);
|
||||
}
|
||||
|
||||
void gdrom_get_subcode(struct gdrom *gd, int format, uint8_t *data, int size) {
|
||||
CHECK_NOTNULL(gd->disc);
|
||||
CHECK_GE(size, GD_SPI_SCD_SIZE);
|
||||
|
@ -640,12 +632,6 @@ void gdrom_get_drive_mode(struct gdrom *gd, struct gd_hw_info *info) {
|
|||
*info = gd->hw_info;
|
||||
}
|
||||
|
||||
void gdrom_get_disc_id(struct gdrom *gd, char *id, int size) {
|
||||
CHECK_NOTNULL(gd->disc);
|
||||
|
||||
disc_get_id(gd->disc, id, size);
|
||||
}
|
||||
|
||||
void gdrom_dma_end(struct gdrom *gd) {
|
||||
LOG_GDROM("gd_dma_end");
|
||||
}
|
||||
|
@ -680,6 +666,20 @@ void gdrom_dma_begin(struct gdrom *gd) {
|
|||
LOG_GDROM("gd_dma_begin");
|
||||
}
|
||||
|
||||
int gdrom_find_file(struct gdrom *gd, const char *filename, int *fad,
|
||||
int *len) {
|
||||
CHECK_NOTNULL(gd->disc);
|
||||
|
||||
return disc_find_file(gd->disc, filename, fad, len);
|
||||
}
|
||||
|
||||
void gdrom_get_bootfile(struct gdrom *gd, int *fad, int *len) {
|
||||
CHECK_NOTNULL(gd->disc);
|
||||
|
||||
*fad = gd->disc->bootfad;
|
||||
*len = gd->disc->bootlen;
|
||||
}
|
||||
|
||||
void gdrom_set_disc(struct gdrom *gd, struct disc *disc) {
|
||||
if (gd->disc != disc) {
|
||||
if (gd->disc) {
|
||||
|
@ -707,6 +707,20 @@ void gdrom_set_disc(struct gdrom *gd, struct disc *disc) {
|
|||
/* TODO how do GD_FEATURES, GD_INTREASON, GD_BYCTLLO and GD_BYCTLHI behave */
|
||||
}
|
||||
|
||||
#ifdef HAVE_IMGUI
|
||||
void gdrom_debug_menu(struct gdrom *gd) {
|
||||
if (igBeginMainMenuBar()) {
|
||||
if (igBeginMenu("GDROM", 1)) {
|
||||
patch_debug_menu();
|
||||
|
||||
igEndMenu();
|
||||
}
|
||||
|
||||
igEndMainMenuBar();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void gdrom_destroy(struct gdrom *gd) {
|
||||
if (gd->disc) {
|
||||
disc_destroy(gd->disc);
|
||||
|
|
|
@ -10,12 +10,16 @@ struct gdrom;
|
|||
struct gdrom *gdrom_create(struct dreamcast *dc);
|
||||
void gdrom_destroy(struct gdrom *gd);
|
||||
|
||||
void gdrom_debug_menu(struct gdrom *gd);
|
||||
|
||||
void gdrom_set_disc(struct gdrom *gd, struct disc *disc);
|
||||
void gdrom_get_bootfile(struct gdrom *gd, int *fad, int *len);
|
||||
int gdrom_find_file(struct gdrom *gd, const char *filename, int *fad, int *len);
|
||||
|
||||
void gdrom_dma_begin(struct gdrom *gd);
|
||||
int gdrom_dma_read(struct gdrom *gd, uint8_t *data, int n);
|
||||
void gdrom_dma_end(struct gdrom *gd);
|
||||
|
||||
void gdrom_get_disc_id(struct gdrom *gd, char *id, int size);
|
||||
void gdrom_get_drive_mode(struct gdrom *gd, struct gd_hw_info *info);
|
||||
void gdrom_set_drive_mode(struct gdrom *gd, struct gd_hw_info *info);
|
||||
void gdrom_get_status(struct gdrom *gd, struct gd_spi_status *stat);
|
||||
|
@ -24,7 +28,6 @@ void gdrom_get_toc(struct gdrom *gd, int area, struct gd_spi_toc *toc);
|
|||
void gdrom_get_session(struct gdrom *gd, int session,
|
||||
struct gd_spi_session *ses);
|
||||
void gdrom_get_subcode(struct gdrom *gd, int format, uint8_t *data, int size);
|
||||
int gdrom_find_file(struct gdrom *gd, const char *filename, int *fad, int *len);
|
||||
int gdrom_read_sectors(struct gdrom *gd, int fad, int num_sectors, int fmt,
|
||||
int mask, uint8_t *dst, int dst_size);
|
||||
int gdrom_read_bytes(struct gdrom *gd, int fad, int len, uint8_t *dst,
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
#include "guest/gdrom/patch.h"
|
||||
#include "core/assert.h"
|
||||
#include "core/string.h"
|
||||
#include "guest/memory.h"
|
||||
#include "render/imgui.h"
|
||||
|
||||
DEFINE_PERSISTENT_OPTION_INT(patch_widescreen, 1, "Apply widescreen patches");
|
||||
|
||||
#if 0
|
||||
#define LOG_PATCH LOG_INFO
|
||||
#else
|
||||
#define LOG_PATCH(...)
|
||||
#endif
|
||||
|
||||
#define DATA(...) \
|
||||
(uint8_t[]) { \
|
||||
__VA_ARGS__ \
|
||||
}
|
||||
|
||||
#define HUNKS(...) \
|
||||
(struct patch_hunk[]) { \
|
||||
__VA_ARGS__ \
|
||||
}
|
||||
|
||||
#define NUM_HUNKS(...) (sizeof(HUNKS(__VA_ARGS__)) / sizeof(struct patch_hunk))
|
||||
|
||||
#define HUNK(offset, ...) \
|
||||
{ offset, DATA(__VA_ARGS__), sizeof(DATA(__VA_ARGS__)) }
|
||||
|
||||
#define PATCH(game, desc, flags, ...) \
|
||||
{game, desc, flags, HUNKS(__VA_ARGS__), NUM_HUNKS(__VA_ARGS__)},
|
||||
|
||||
static struct patch patches[] = {
|
||||
#include "guest/gdrom/patch.inc"
|
||||
};
|
||||
static int num_patches = sizeof(patches) / sizeof(patches[0]);
|
||||
|
||||
void patch_bootfile(const char *game, uint8_t *buffer, int offset, int size) {
|
||||
for (int i = 0; i < num_patches; i++) {
|
||||
struct patch *patch = &patches[i];
|
||||
|
||||
/* only apply patches for the current game */
|
||||
if (strcmp(patch->game, game)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(patch->flags & PATCH_BOOTFILE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((patch->flags & PATCH_WIDESCREEN) && !OPTION_patch_widescreen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_PATCH("patches_apply %s at 0x%x", patch->desc, offset);
|
||||
|
||||
for (int j = 0; j < patch->num_hunks; j++) {
|
||||
struct patch_hunk *hunk = &patch->hunks[j];
|
||||
|
||||
for (int k = 0; k < hunk->len; k++) {
|
||||
int index = hunk->offset + k;
|
||||
|
||||
if (index < offset || index >= offset + size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer[index - offset] = hunk->data[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IMGUI
|
||||
void patch_debug_menu() {
|
||||
if (igBeginMenu("patches", 1)) {
|
||||
if (igMenuItem("widescreen", NULL, OPTION_patch_widescreen, 1)) {
|
||||
OPTION_patch_widescreen = !OPTION_patch_widescreen;
|
||||
}
|
||||
|
||||
igEndMenu();
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef PATCH_H
|
||||
#define PATCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct address_space;
|
||||
|
||||
enum {
|
||||
PATCH_BOOTFILE = 0x1,
|
||||
PATCH_WIDESCREEN = 0x2,
|
||||
};
|
||||
|
||||
struct patch_hunk {
|
||||
int offset;
|
||||
uint8_t *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct patch {
|
||||
char *game;
|
||||
char *desc;
|
||||
int flags;
|
||||
struct patch_hunk *hunks;
|
||||
int num_hunks;
|
||||
};
|
||||
|
||||
void patch_debug_menu();
|
||||
void patch_bootfile(const char *game, uint8_t *data, int offset, int size);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
PATCH("DYNAMITE COP MK-51013 V1.005 7996 GD-ROM1/1",
|
||||
"widescreen hack",
|
||||
PATCH_BOOTFILE | PATCH_WIDESCREEN,
|
||||
HUNK(0x00048eb0,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x00048fb8,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x00049100,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0004b590,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0006b93c,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0006bce0,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0006c0d0,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0006c21c,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0006eec4,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x000723c0,0x39,0x8E,0xE3,0x3F),
|
||||
HUNK(0x0007d568,0x39,0x8E,0xE3,0x3F))
|
||||
|
||||
PATCH("SONIC ADVENTURE MK-51000 V1.005 3B97 GD-ROM1/1",
|
||||
"widescreen hack",
|
||||
PATCH_BOOTFILE | PATCH_WIDESCREEN,
|
||||
HUNK(0x00026fb8,0xF0,0xF5,0x88,0x8C,0xF4,0xF5,0x88,0x8C,0x94,0x3A,0x01,0x8C),
|
||||
HUNK(0x00026fc4,0x80,0xEF,0x0A,0x8C,0x10,0xF6,0x88,0x8C,0x18,0xF6,0x88,0x8C),
|
||||
HUNK(0x00600d70,0x80,0xEF,0x0A,0x8C,0xA8,0x35,0x67,0x8C,0xE6,0x2F,0x43,0x6E),
|
||||
HUNK(0x00612200,0x80,0xEF,0x0A,0x8C,0x18,0x03,0x89,0x8C,0x59,0xF0,0x59,0xF1))
|
|
@ -233,7 +233,7 @@ static int pvr_init(struct device *dev) {
|
|||
#undef PVR_REG
|
||||
|
||||
pvr->palette_ram = (uint8_t *)pvr->PALETTE_RAM000;
|
||||
pvr->video_ram = memory_translate(dc->memory, "video ram", 0x00000000);
|
||||
pvr->video_ram = memory_translate(dc->memory, "video ram", 0x0);
|
||||
|
||||
/* configure initial vsync interval */
|
||||
pvr_reconfigure_spg(pvr);
|
||||
|
|
|
@ -625,7 +625,7 @@ static int ta_init(struct device *dev) {
|
|||
struct ta *ta = (struct ta *)dev;
|
||||
struct dreamcast *dc = ta->dc;
|
||||
|
||||
ta->video_ram = memory_translate(dc->memory, "video ram", 0x00000000);
|
||||
ta->video_ram = memory_translate(dc->memory, "video ram", 0x0);
|
||||
|
||||
for (int i = 0; i < array_size(ta->contexts); i++) {
|
||||
struct tile_context *ctx = &ta->contexts[i];
|
||||
|
|
Loading…
Reference in New Issue