cdriso: support multidisk eboots
authornotaz <notasas@gmail.com>
Sun, 30 Oct 2011 21:37:53 +0000 (23:37 +0200)
committernotaz <notasas@gmail.com>
Sun, 30 Oct 2011 21:57:12 +0000 (23:57 +0200)
frontend/menu.c
libpcsxcore/cdriso.c
libpcsxcore/cdriso.h

index cfdc62d..25c476d 100644 (file)
@@ -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);
index 6bf5809..0089cfe 100644 (file)
@@ -33,6 +33,9 @@
 #endif
 #include <zlib.h>
 
+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;
index 27d1ecd..16ad52f 100644 (file)
@@ -28,6 +28,9 @@ extern "C" {
 void cdrIsoInit(void);
 int cdrIsoActive(void);
 
+extern unsigned int cdrIsoMultidiskCount;
+extern unsigned int cdrIsoMultidiskSelect;
+
 #ifdef __cplusplus
 }
 #endif