bugfixes, new config system and messed code for it
[libpicofe.git] / common / emu.c
index 71f6716..936665b 100644 (file)
@@ -14,6 +14,7 @@
 #include "menu.h"\r
 #include "fonts.h"\r
 #include "lprintf.h"\r
+#include "config.h"\r
 \r
 #include <Pico/PicoInt.h>\r
 #include <Pico/Patch.h>\r
  #define SCREEN_BUFFER psp_screen\r
 #endif\r
 \r
-char *PicoConfigFile = "picoconfig.bin";\r
-currentConfig_t currentConfig;\r
-unsigned char *rom_data = NULL;\r
+char *PicoConfigFile = "config.cfg";\r
+currentConfig_t currentConfig, defaultConfig;\r
+int rom_loaded = 0;\r
 char noticeMsg[64];\r
 int state_slot = 0;\r
 int config_slot = 0, config_slot_current = 0;\r
+char lastRomFile[512];\r
 \r
 unsigned char *movie_data = NULL;\r
 static int movie_size = 0;\r
@@ -138,6 +140,7 @@ int emu_findBios(int region, char **bios_file)
 }\r
 \r
 /* check if the name begins with BIOS name */\r
+/*\r
 static int emu_isBios(const char *name)\r
 {\r
        int i;\r
@@ -149,6 +152,9 @@ static int emu_isBios(const char *name)
                if (strstr(name, biosfiles_jp[i]) != NULL) return 1;\r
        return 0;\r
 }\r
+*/\r
+\r
+static unsigned char id_header[0x100];\r
 \r
 /* checks if romFileName points to valid MegaCD image\r
  * if so, checks for suitable BIOS */\r
@@ -173,6 +179,9 @@ int emu_cdCheck(int *pregion)
                return 0;\r
        }\r
 \r
+       pm_seek(cd_f, (type == 1) ? 0x100 : 0x110, SEEK_SET);\r
+       pm_read(id_header, sizeof(id_header), cd_f);\r
+\r
        /* it seems we have a CD image here. Try to detect region now.. */\r
        pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);\r
        pm_read(buf, 1, cd_f);\r
@@ -189,10 +198,62 @@ int emu_cdCheck(int *pregion)
        return type;\r
 }\r
 \r
+static int extract_text(char *dest, unsigned char *src, int len, int swab)\r
+{\r
+       char *p = dest;\r
+       int i;\r
+\r
+       if (swab) swab = 1;\r
+\r
+       for (i = len - 1; i >= 0; i--)\r
+       {\r
+               if (src[i^swab] != ' ') break;\r
+       }\r
+       len = i + 1;\r
+\r
+       for (i = 0; i < len; i++)\r
+       {\r
+               unsigned char s = src[i^swab];\r
+               if (s >= 0x20 && s < 0x7f && s != '#' && s != '|' &&\r
+                       s != '[' && s != ']' && s != '\\')\r
+               {\r
+                       *p++ = s;\r
+               }\r
+               else\r
+               {\r
+                       sprintf(p, "\\%02x", s);\r
+                       p += 3;\r
+               }\r
+       }\r
+\r
+       return p - dest;\r
+}\r
+\r
+char *emu_makeRomId(void)\r
+{\r
+       static char id_string[3+0x11+0x11+0x30+16];\r
+       int pos;\r
+\r
+       if (PicoMCD & 1)\r
+            strcpy(id_string, "CD|");\r
+       else strcpy(id_string, "MD|");\r
+       pos = 3;\r
+\r
+       pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, 1); // serial\r
+       id_string[pos] = '|'; pos++;\r
+       pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, 1); // region\r
+       id_string[pos] = '|'; pos++;\r
+       pos += extract_text(id_string + pos, id_header + 0x50, 0x30, 1); // overseas name\r
+       id_string[pos] = 0;\r
+\r
+       return id_string;\r
+}\r
+\r
 int emu_ReloadRom(void)\r
 {\r
        unsigned int rom_size = 0;\r
        char *used_rom_name = romFileName;\r
+       unsigned char *rom_data = NULL;\r
        char ext[5];\r
        pm_file *rom;\r
        int ret, cd_state, cd_region, cfg_loaded = 0;\r
@@ -202,7 +263,7 @@ int emu_ReloadRom(void)
        get_ext(romFileName, ext);\r
 \r
        // detect wrong extensions\r
-       if(!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz\r
+       if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz\r
                sprintf(menuErrorMsg, "Not a ROM selected.");\r
                return 0;\r
        }\r
@@ -210,11 +271,11 @@ int emu_ReloadRom(void)
        PicoPatchUnload();\r
 \r
        // check for movie file\r
-       if(movie_data) {\r
+       if (movie_data) {\r
                free(movie_data);\r
                movie_data = 0;\r
        }\r
-       if(!strcmp(ext, ".gmv")) {\r
+       if (!strcmp(ext, ".gmv")) {\r
                // check for both gmv and rom\r
                int dummy;\r
                FILE *movie_file = fopen(romFileName, "rb");\r
@@ -293,20 +354,17 @@ int emu_ReloadRom(void)
        }\r
 \r
        rom = pm_open(used_rom_name);\r
-       if(!rom) {\r
+       if (!rom) {\r
                sprintf(menuErrorMsg, "Failed to open rom.");\r
                return 0;\r
        }\r
 \r
        menu_romload_prepare(used_rom_name); // also CD load\r
 \r
-       if(rom_data) {\r
-               free(rom_data);\r
-               rom_data = 0;\r
-               rom_size = 0;\r
-       }\r
+       PicoCartUnload();\r
+       rom_loaded = 0;\r
 \r
-       if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
+       if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
                sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
                lprintf("%s\n", menuErrorMsg);\r
                pm_close(rom);\r
@@ -316,23 +374,24 @@ int emu_ReloadRom(void)
        pm_close(rom);\r
 \r
        // detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
-       if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
+       if (rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
          ((*(unsigned char *)(rom_data+4)<<16)|(*(unsigned short *)(rom_data+6))) >= (int)rom_size) {\r
                if (rom_data) free(rom_data);\r
-               rom_data = 0;\r
                sprintf(menuErrorMsg, "Not a ROM selected.");\r
                menu_romload_end();\r
                return 0;\r
        }\r
 \r
        // load config for this ROM (do this before insert to get correct region)\r
+       if (!(PicoMCD&1))\r
+               memcpy(id_header, rom_data + 0x100, sizeof(id_header));\r
        if (!cfg_loaded) {\r
                ret = emu_ReadConfig(1, 1);\r
                if (!ret) emu_ReadConfig(0, 1);\r
        }\r
 \r
        lprintf("PicoCartInsert(%p, %d);\n", rom_data, rom_size);\r
-       if(PicoCartInsert(rom_data, rom_size)) {\r
+       if (PicoCartInsert(rom_data, rom_size)) {\r
                sprintf(menuErrorMsg, "Failed to load ROM.");\r
                menu_romload_end();\r
                return 0;\r
@@ -353,13 +412,6 @@ int emu_ReloadRom(void)
 \r
        menu_romload_end();\r
 \r
-       if (!emu_isBios(romFileName))\r
-       {\r
-               // emu_ReadConfig() might have messed currentConfig.lastRomFile\r
-               strncpy(currentConfig.lastRomFile, romFileName, sizeof(currentConfig.lastRomFile)-1);\r
-               currentConfig.lastRomFile[sizeof(currentConfig.lastRomFile)-1] = 0;\r
-       }\r
-\r
        if (PicoPatches) {\r
                PicoPatchPrepare();\r
                PicoPatchApply();\r
@@ -395,9 +447,12 @@ int emu_ReloadRom(void)
        emu_noticeMsgUpdated();\r
 \r
        // load SRAM for this ROM\r
-       if(currentConfig.EmuOpt & 1)\r
+       if (currentConfig.EmuOpt & 1)\r
                emu_SaveLoadGame(1, 1);\r
 \r
+       strncpy(lastRomFile, romFileName, sizeof(lastRomFile)-1);\r
+       lastRomFile[sizeof(lastRomFile)-1] = 0;\r
+       rom_loaded = 1;\r
        return 1;\r
 }\r
 \r
@@ -423,49 +478,75 @@ static void romfname_ext(char *dst, const char *prefix, const char *ext)
 \r
 int emu_ReadConfig(int game, int no_defaults)\r
 {\r
+       char cfg[512];\r
        FILE *f;\r
-       char cfg[512], extbuf[16];\r
-       int bread = 0;\r
+       int ret;\r
 \r
        if (!game)\r
        {\r
                if (!no_defaults)\r
-               {\r
                        emu_setDefaultConfig();\r
-               }\r
                strncpy(cfg, PicoConfigFile, 511);\r
                if (config_slot != 0)\r
                {\r
                        char *p = strrchr(cfg, '.');\r
                        if (p == NULL) p = cfg + strlen(cfg);\r
-                       sprintf(extbuf, ".%i.pbcfg", config_slot);\r
-                       strncpy(p, extbuf, 511 - (p - cfg));\r
+                       sprintf(p, ".%i.cfg", config_slot);\r
                }\r
                cfg[511] = 0;\r
-       } else {\r
-               if (config_slot != 0)\r
-                    sprintf(extbuf, ".%i.pbcfg", config_slot);\r
-               else strcpy(extbuf, ".pbcfg");\r
-               romfname_ext(cfg, "cfg/", extbuf);\r
-               f = fopen(cfg, "rb");\r
-               if (!f) romfname_ext(cfg, NULL, ".pbcfg");\r
-               else fclose(f);\r
+               ret = config_readsect(cfg, NULL);\r
        }\r
+       else\r
+       {\r
+               char *sect = emu_makeRomId();\r
 \r
-       lprintf("emu_ReadConfig: %s ", cfg);\r
-       f = fopen(cfg, "rb");\r
-       if (f) {\r
-               bread = fread(&currentConfig, 1, sizeof(currentConfig), f);\r
-               fclose(f);\r
+               // try new .cfg way\r
+               if (config_slot != 0)\r
+                    sprintf(cfg, "game.%i.cfg", config_slot);\r
+               else strcpy(cfg,  "game.cfg");\r
+\r
+               ret = -1;\r
+               if (config_havesect(cfg, sect)) {\r
+                       emu_setDefaultConfig();\r
+                       ret = config_readsect(cfg, sect);\r
+               }\r
+\r
+               if (ret != 0)\r
+               {\r
+                       // fall back to old\r
+                       char extbuf[16];\r
+                       if (config_slot != 0)\r
+                               sprintf(extbuf, ".%i.pbcfg", config_slot);\r
+                       else strcpy(extbuf, ".pbcfg");\r
+                       romfname_ext(cfg, "cfg/", extbuf);\r
+                       f = fopen(cfg, "rb");\r
+                       if (!f) {\r
+                               romfname_ext(cfg, NULL, ".pbcfg");\r
+                               f = fopen(cfg, "rb");\r
+                       }\r
+                       if (f) {\r
+                               int bread;\r
+                               fseek(f, 512, SEEK_SET); // skip unused lrom buffer\r
+                               bread = fread(&currentConfig, 1, sizeof(currentConfig), f);\r
+                               lprintf("emu_ReadConfig: %s %s\n", cfg, bread > 0 ? "(ok)" : "(failed)");\r
+                               fclose(f);\r
+                               ret = 0;\r
+                       }\r
+\r
+                       if (ret == 0) {\r
+                               PicoOpt = currentConfig.s_PicoOpt;\r
+                               PsndRate = currentConfig.s_PsndRate;\r
+                               PicoRegionOverride = currentConfig.s_PicoRegion;\r
+                               PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;\r
+                               PicoCDBuffers = currentConfig.s_PicoCDBuffers;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       lprintf("loaded cfg from sect \"%s\"\n", sect);\r
+               }\r
        }\r
-       lprintf(bread > 0 ? "(ok)\n" : "(failed)\n");\r
 \r
-       PicoOpt = currentConfig.PicoOpt;\r
-       PsndRate = currentConfig.PsndRate;\r
-       PicoRegionOverride = currentConfig.PicoRegion;\r
-       PicoAutoRgnOrder = currentConfig.PicoAutoRgnOrder;\r
-       PicoCDBuffers = currentConfig.PicoCDBuffers;\r
-       //scaling_update();\r
        // some sanity checks\r
        if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;\r
 #ifdef PSP\r
@@ -481,54 +562,45 @@ int emu_ReadConfig(int game, int no_defaults)
                currentConfig.KeyBinds[22] = 1<<30; // vol down\r
        }\r
 #endif\r
-       if (bread > 0) config_slot_current = config_slot;\r
-       return (bread > 0); // == sizeof(currentConfig));\r
+       if (ret == 0) config_slot_current = config_slot;\r
+       return (ret == 0);\r
 }\r
 \r
 \r
-int emu_WriteConfig(int game)\r
+int emu_WriteConfig(int is_game)\r
 {\r
-       FILE *f;\r
-       char cfg[512], extbuf[16];\r
-       int bwrite = 0;\r
+       char cfg[512], *game_sect = NULL;\r
+       int ret, write_lrom = 0;\r
 \r
-       if (!game)\r
+       if (!is_game)\r
        {\r
                strncpy(cfg, PicoConfigFile, 511);\r
                if (config_slot != 0)\r
                {\r
                        char *p = strrchr(cfg, '.');\r
                        if (p == NULL) p = cfg + strlen(cfg);\r
-                       sprintf(extbuf, ".%i.pbcfg", config_slot);\r
-                       strncpy(p, extbuf, 511 - (p - cfg));\r
+                       sprintf(p, ".%i.cfg", config_slot);\r
                }\r
                cfg[511] = 0;\r
+               write_lrom = 1;\r
        } else {\r
                if (config_slot != 0)\r
-                    sprintf(extbuf, ".%i.pbcfg", config_slot);\r
-               else strcpy(extbuf, ".pbcfg");\r
-               romfname_ext(cfg, "cfg/", extbuf);\r
+                    sprintf(cfg, "game.%i.cfg", config_slot);\r
+               else strcpy(cfg,  "game.cfg");\r
+               game_sect = emu_makeRomId();\r
+               lprintf("emu_WriteConfig: sect \"%s\"\n", game_sect);\r
        }\r
 \r
        lprintf("emu_WriteConfig: %s ", cfg);\r
-       f = fopen(cfg, "wb");\r
-       if (f) {\r
-               currentConfig.PicoOpt = PicoOpt;\r
-               currentConfig.PsndRate = PsndRate;\r
-               currentConfig.PicoRegion = PicoRegionOverride;\r
-               currentConfig.PicoAutoRgnOrder = PicoAutoRgnOrder;\r
-               currentConfig.PicoCDBuffers = PicoCDBuffers;\r
-               bwrite = fwrite(&currentConfig, 1, sizeof(currentConfig), f);\r
-               fflush(f);\r
-               fclose(f);\r
+       ret = config_writesect(cfg, game_sect);\r
+       if (write_lrom) config_writelrom(cfg);\r
 #ifndef NO_SYNC\r
-               sync();\r
+       sync();\r
 #endif\r
-       }\r
-       lprintf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");\r
+       lprintf((ret == 0) ? "(ok)\n" : "(failed)\n");\r
 \r
-       if (bwrite == sizeof(currentConfig)) config_slot_current = config_slot;\r
-       return (bwrite == sizeof(currentConfig));\r
+       if (ret == 0) config_slot_current = config_slot;\r
+       return ret == 0;\r
 }\r
 \r
 \r