From 0c2871a7e649ef1ce966d5a9a7c1aa359beaf601 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 30 Oct 2011 23:37:53 +0200 Subject: [PATCH] cdriso: support multidisk eboots --- frontend/menu.c | 33 +++++++++++++++++++++--- libpcsxcore/cdriso.c | 60 ++++++++++++++++++++++++++++++++++++++------ libpcsxcore/cdriso.h | 3 +++ 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/frontend/menu.c b/frontend/menu.c index cfdc62d8..25c476da 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -28,6 +28,7 @@ #include "linux/in_evdev.h" #include "../libpcsxcore/misc.h" #include "../libpcsxcore/cdrom.h" +#include "../libpcsxcore/cdriso.h" #include "../libpcsxcore/psemu_plugin_defs.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../plugins/dfinput/main.h" @@ -44,6 +45,7 @@ typedef enum MA_MAIN_RESET_GAME, MA_MAIN_LOAD_ROM, MA_MAIN_SWAP_CD, + MA_MAIN_SWAP_CD_MULTI, MA_MAIN_RUN_BIOS, MA_MAIN_RUN_EXE, MA_MAIN_CONTROLS, @@ -1577,6 +1579,7 @@ static int reload_plugins(const char *cdimg) } plugin_call_rearmed_cbs(); + cdrIsoMultidiskCount = 1; CdromId[0] = '\0'; CdromLabel[0] = '\0'; @@ -1714,6 +1717,24 @@ static int swap_cd_image(void) return 0; } +static int swap_cd_multidisk(void) +{ + cdrIsoMultidiskSelect++; + CdromId[0] = '\0'; + CdromLabel[0] = '\0'; + + CDR_close(); + if (CDR_open() < 0) { + me_update_msg("failed to open cdr plugin"); + return -1; + } + + SetCdOpenCaseTime(time(NULL) + 2); + LidInterrupt(); + + return 0; +} + static int main_menu_handler(int id, int keys) { switch (id) @@ -1742,6 +1763,10 @@ static int main_menu_handler(int id, int keys) if (swap_cd_image() == 0) return 1; break; + case MA_MAIN_SWAP_CD_MULTI: + if (swap_cd_multidisk() == 0) + return 1; + break; case MA_MAIN_RUN_BIOS: if (run_bios() == 0) return 1; @@ -1767,9 +1792,10 @@ static int main_menu_handler(int id, int keys) static menu_entry e_menu_main2[] = { - mee_handler_id("Change CD image", MA_MAIN_SWAP_CD, main_menu_handler), - mee_handler_id("Run BIOS", MA_MAIN_RUN_BIOS, main_menu_handler), - mee_handler_id("Run EXE", MA_MAIN_RUN_EXE, main_menu_handler), + mee_handler_id("Change CD image", MA_MAIN_SWAP_CD, main_menu_handler), + mee_handler_id("Next multidisk CD", MA_MAIN_SWAP_CD_MULTI, main_menu_handler), + mee_handler_id("Run BIOS", MA_MAIN_RUN_BIOS, main_menu_handler), + mee_handler_id("Run EXE", MA_MAIN_RUN_EXE, main_menu_handler), mee_handler ("Memcard manager", menu_loop_memcards), mee_end, }; @@ -1779,6 +1805,7 @@ static int main_menu2_handler(int id, int keys) static int sel = 0; me_enable(e_menu_main2, MA_MAIN_SWAP_CD, ready_to_go); + me_enable(e_menu_main2, MA_MAIN_SWAP_CD_MULTI, ready_to_go && cdrIsoMultidiskCount > 1); me_enable(e_menu_main2, MA_MAIN_RUN_BIOS, bios_sel != 0); return me_loop_d(e_menu_main2, &sel, NULL, draw_frame_main); diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 6bf58095..0089cfea 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -33,6 +33,9 @@ #endif #include +unsigned int cdrIsoMultidiskCount; +unsigned int cdrIsoMultidiskSelect; + static FILE *cdHandle = NULL; static FILE *cddaHandle = NULL; static FILE *subHandle = NULL; @@ -724,8 +727,9 @@ static int handlepbp(const char *isofile) { unsigned int size; unsigned int dontcare[6]; } index_entry; - char psar_sig[9]; + char psar_sig[11]; unsigned int t, cd_length, cdimg_base; + unsigned int offsettab[8], psisoimg_offs; const char *ext = NULL; int i, ret; @@ -748,17 +752,56 @@ static int handlepbp(const char *isofile) { goto fail_io; } + psisoimg_offs = pbp_hdr.psar_offs; fread(psar_sig, 1, sizeof(psar_sig), cdHandle); - psar_sig[8] = 0; - if (strcmp(psar_sig, "PSISOIMG") != 0) { + psar_sig[10] = 0; + if (strcmp(psar_sig, "PSTITLEIMG") == 0) { + // multidisk image? + ret = fseek(cdHandle, pbp_hdr.psar_offs + 0x200, SEEK_SET); + if (ret != 0) { + fprintf(stderr, "failed to seek to %x\n", pbp_hdr.psar_offs + 0x200); + goto fail_io; + } + + if (fread(&offsettab, 1, sizeof(offsettab), cdHandle) != sizeof(offsettab)) { + fprintf(stderr, "failed to read offsettab\n"); + goto fail_io; + } + + for (i = 0; i < sizeof(offsettab) / sizeof(offsettab[0]); i++) { + if (offsettab[i] == 0) + break; + } + cdrIsoMultidiskCount = i; + if (cdrIsoMultidiskCount == 0) { + fprintf(stderr, "multidisk eboot has 0 images?\n"); + goto fail_io; + } + + if (cdrIsoMultidiskSelect >= cdrIsoMultidiskCount) + cdrIsoMultidiskSelect = 0; + + psisoimg_offs += offsettab[cdrIsoMultidiskSelect]; + + ret = fseek(cdHandle, psisoimg_offs, SEEK_SET); + if (ret != 0) { + fprintf(stderr, "failed to seek to %x\n", psisoimg_offs); + goto fail_io; + } + + fread(psar_sig, 1, sizeof(psar_sig), cdHandle); + psar_sig[10] = 0; + } + + if (strcmp(psar_sig, "PSISOIMG00") != 0) { fprintf(stderr, "bad psar_sig: %s\n", psar_sig); goto fail_io; } // seek to TOC - ret = fseek(cdHandle, pbp_hdr.psar_offs + 0x800, SEEK_SET); + ret = fseek(cdHandle, psisoimg_offs + 0x800, SEEK_SET); if (ret != 0) { - fprintf(stderr, "failed to seek to %x\n", pbp_hdr.psar_offs); + fprintf(stderr, "failed to seek to %x\n", psisoimg_offs + 0x800); goto fail_io; } @@ -791,7 +834,7 @@ static int handlepbp(const char *isofile) { sec2msf(t, ti[numtracks].length); // seek to ISO index - ret = fseek(cdHandle, pbp_hdr.psar_offs + 0x4000, SEEK_SET); + ret = fseek(cdHandle, psisoimg_offs + 0x4000, SEEK_SET); if (ret != 0) { fprintf(stderr, "failed to seek to ISO index\n"); goto fail_io; @@ -809,7 +852,7 @@ static int handlepbp(const char *isofile) { if (compr_img->index_table == NULL) goto fail_io; - cdimg_base = pbp_hdr.psar_offs + 0x100000; + cdimg_base = psisoimg_offs + 0x100000; for (i = 0; i < compr_img->index_len; i++) { ret = fread(&index_entry, 1, sizeof(index_entry), cdHandle); if (ret != sizeof(index_entry)) { @@ -849,7 +892,7 @@ static int handlecbin(const char *isofile) { unsigned char rsv_06[2]; } ciso_hdr; const char *ext = NULL; - unsigned int index, plain; + unsigned int index = 0, plain; int i, ret; if (strlen(isofile) >= 5) @@ -1126,6 +1169,7 @@ static long CALLBACK ISOopen(void) { subChanMixed = FALSE; subChanRaw = FALSE; pregapOffset = 0; + cdrIsoMultidiskCount = 1; CDR_getBuffer = ISOgetBuffer; cdimg_read_func = cdread_normal; diff --git a/libpcsxcore/cdriso.h b/libpcsxcore/cdriso.h index 27d1ecd0..16ad52ff 100644 --- a/libpcsxcore/cdriso.h +++ b/libpcsxcore/cdriso.h @@ -28,6 +28,9 @@ extern "C" { void cdrIsoInit(void); int cdrIsoActive(void); +extern unsigned int cdrIsoMultidiskCount; +extern unsigned int cdrIsoMultidiskSelect; + #ifdef __cplusplus } #endif -- 2.39.5