add a libcrypt warning
authornotaz <notasas@gmail.com>
Sat, 21 Oct 2023 21:09:16 +0000 (00:09 +0300)
committernotaz <notasas@gmail.com>
Sat, 21 Oct 2023 21:19:32 +0000 (00:19 +0300)
gives a hint instead of silently not working

frontend/libretro.c
frontend/main.c
libpcsxcore/cdrom.c
libpcsxcore/database.c
libpcsxcore/database.h
libpcsxcore/ppf.c
libpcsxcore/ppf.h
libpcsxcore/psxinterpreter.c

index 8a2447a..a30a1ab 100644 (file)
@@ -28,6 +28,7 @@
 #include "../libpcsxcore/cheat.h"
 #include "../libpcsxcore/r3000a.h"
 #include "../libpcsxcore/gpu.h"
+#include "../libpcsxcore/database.h"
 #include "../plugins/dfsound/out.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "cspace.h"
@@ -1502,6 +1503,32 @@ static void set_retro_memmap(void)
 #endif
 }
 
+static void show_notification(const char *msg_str,
+      unsigned duration_ms, unsigned priority)
+{
+   if (msg_interface_version >= 1)
+   {
+      struct retro_message_ext msg = {
+         msg_str,
+         duration_ms,
+         3,
+         RETRO_LOG_WARN,
+         RETRO_MESSAGE_TARGET_ALL,
+         RETRO_MESSAGE_TYPE_NOTIFICATION,
+         -1
+      };
+      environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg);
+   }
+   else
+   {
+      struct retro_message msg = {
+         msg_str,
+         180
+      };
+      environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
+   }
+}
+
 static void retro_audio_buff_status_cb(
    bool active, unsigned occupancy, bool underrun_likely)
 {
@@ -1781,6 +1808,9 @@ bool retro_load_game(const struct retro_game_info *info)
    set_retro_memmap();
    retro_set_audio_buff_status_cb();
 
+   if (check_unsatisfied_libcrypt())
+      show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
+
    return true;
 }
 
@@ -3181,38 +3211,21 @@ static void loadPSXBios(void)
    if (!found_bios)
    {
       const char *msg_str;
+      unsigned duration;
       if (useHLE)
       {
-         msg_str = "BIOS set to \'hle\' in core options - real BIOS will be ignored";
+         msg_str = "BIOS set to \'hle\'";
          SysPrintf("Using HLE BIOS.\n");
+         // shorter as the user probably intentionally wants to use HLE
+         duration = 700;
       }
       else
       {
          msg_str = "No PlayStation BIOS file found - add for better compatibility";
          SysPrintf("No BIOS files found.\n");
+         duration = 3000;
       }
-
-      if (msg_interface_version >= 1)
-      {
-         struct retro_message_ext msg = {
-            msg_str,
-            3000,
-            3,
-            RETRO_LOG_WARN,
-            RETRO_MESSAGE_TARGET_ALL,
-            RETRO_MESSAGE_TYPE_NOTIFICATION,
-            -1
-         };
-         environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg);
-      }
-      else
-      {
-         struct retro_message msg = {
-            msg_str,
-            180
-         };
-         environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
-      }
+      show_notification(msg_str, duration, 2);
    }
 }
 
index 05e4d55..18ca6e5 100644 (file)
@@ -24,6 +24,7 @@
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cheat.h"
 #include "../libpcsxcore/sio.h"
+#include "../libpcsxcore/database.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/cdrcimg/cdrcimg.h"
 #include "../plugins/dfsound/spu_config.h"
@@ -413,7 +414,11 @@ void emu_on_new_cd(int show_hud_msg)
        }
 
        if (show_hud_msg) {
-               snprintf(hud_msg, sizeof(hud_msg), BOOT_MSG);
+               if (check_unsatisfied_libcrypt())
+                       snprintf(hud_msg, sizeof(hud_msg),
+                               "LibCrypt protected game with missing SBI detected");
+               else
+                       snprintf(hud_msg, sizeof(hud_msg), BOOT_MSG);
                hud_new_msg = 3;
        }
 }
index 2ce7fe9..bc973e9 100644 (file)
@@ -462,12 +462,13 @@ static int ReadTrack(const u8 *time)
 static void UpdateSubq(const u8 *time)
 {
        const struct SubQ *subq;
+       int s = MSF2SECT(time[0], time[1], time[2]);
        u16 crc;
 
-       if (CheckSBI(time))
+       if (CheckSBI(s))
                return;
 
-       subq = (struct SubQ *)CDR_getBufferSub(MSF2SECT(time[0], time[1], time[2]));
+       subq = (struct SubQ *)CDR_getBufferSub(s);
        if (subq != NULL && cdr.CurTrack == 1) {
                crc = calcCrc((u8 *)subq + 12, 10);
                if (crc == (((u16)subq->CRC[0] << 8) | subq->CRC[1])) {
index 568bba2..2d9a2ea 100644 (file)
@@ -1,5 +1,6 @@
 #include "misc.h"
 #include "sio.h"
+#include "ppf.h"
 #include "new_dynarec/new_dynarec.h"
 
 /* It's duplicated from emu_if.c */
@@ -92,7 +93,7 @@ cycle_multiplier_overrides[] =
 };
 
 /* Function for automatic patching according to GameID. */
-void Apply_Hacks_Cdrom()
+void Apply_Hacks_Cdrom(void)
 {
        size_t i, j;
 
@@ -139,3 +140,74 @@ void Apply_Hacks_Cdrom()
                }
        }
 }
+
+// from duckstation's gamedb.json
+static const u16 libcrypt_ids[] = {
+          17,   311,   995,  1041,  1226,  1241,  1301,  1362,  1431,  1444,
+        1492,  1493,  1494,  1495,  1516,  1517,  1518,  1519,  1545,  1564,
+        1695,  1700,  1701,  1702,  1703,  1704,  1715,  1733,  1763,  1882,
+        1906,  1907,  1909,  1943,  1979,  2004,  2005,  2006,  2007,  2024,
+        2025,  2026,  2027,  2028,  2029,  2030,  2031,  2061,  2071,  2080,
+        2081,  2082,  2083,  2084,  2086,  2104,  2105,  2112,  2113,  2118,
+        2181,  2182,  2184,  2185,  2207,  2208,  2209,  2210,  2211,  2222,
+        2264,  2290,  2292,  2293,  2328,  2329,  2330,  2354,  2355,  2365,
+        2366,  2367,  2368,  2369,  2395,  2396,  2402,  2430,  2431,  2432,
+        2433,  2487,  2488,  2489,  2490,  2491,  2529,  2530,  2531,  2532,
+        2533,  2538,  2544,  2545,  2546,  2558,  2559,  2560,  2561,  2562,
+        2563,  2572,  2573,  2681,  2688,  2689,  2698,  2700,  2704,  2705,
+        2706,  2707,  2708,  2722,  2723,  2724,  2733,  2754,  2755,  2756,
+        2763,  2766,  2767,  2768,  2769,  2824,  2830,  2831,  2834,  2835,
+        2839,  2857,  2858,  2859,  2860,  2861,  2862,  2965,  2966,  2967,
+        2968,  2969,  2975,  2976,  2977,  2978,  2979,  3061,  3062,  3189,
+        3190,  3191,  3241,  3242,  3243,  3244,  3245,  3324,  3489,  3519,
+        3520,  3521,  3522,  3523,  3530,  3603,  3604,  3605,  3606,  3607,
+        3626,  3648, 12080, 12081, 12082, 12083, 12084, 12328, 12329, 12330,
+       12558, 12559, 12560, 12561, 12562, 12965, 12966, 12967, 12968, 12969,
+       22080, 22081, 22082, 22083, 22084, 22328, 22329, 22330, 22965, 22966,
+       22967, 22968, 22969, 32080, 32081, 32082, 32083, 32084, 32965, 32966,
+       32967, 32968, 32969
+};
+
+// as documented by nocash
+static const u16 libcrypt_sectors[16] = {
+       14105, 14231, 14485, 14579, 14649, 14899, 15056, 15130,
+       15242, 15312, 15378, 15628, 15919, 16031, 16101, 16167
+};
+
+int check_unsatisfied_libcrypt(void)
+{
+       const char *p = CdromId + 4;
+       u16 id, key = 0;
+       size_t i;
+
+       if (strncmp(CdromId, "SCE", 3) && strncmp(CdromId, "SLE", 3))
+               return 0;
+       while (*p == '0')
+               p++;
+       id = (u16)atoi(p);
+       for (i = 0; i < ARRAY_SIZE(libcrypt_ids); i++)
+               if (id == libcrypt_ids[i])
+                       break;
+       if (i == ARRAY_SIZE(libcrypt_ids))
+               return 0;
+
+       // detected a protected game
+       if (!CDR_getBufferSub(libcrypt_sectors[0]) && !sbi_sectors) {
+               SysPrintf("==================================================\n");
+               SysPrintf("LibCrypt game detected with missing SBI/subchannel\n");
+               SysPrintf("==================================================\n");
+               return 1;
+       }
+
+       if (sbi_sectors) {
+               // calculate key just for fun (we don't really need it)
+               for (i = 0; i < 16; i++)
+                       if (CheckSBI(libcrypt_sectors[i] - 2*75))
+                               key |= 1u << (15 - i);
+       }
+       if (key)
+               SysPrintf("%s, possible key=%04X\n", "LibCrypt detected", key);
+       else
+               SysPrintf("%s\n", "LibCrypt detected");
+       return 0;
+}
index fbb564d..1ec8875 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef DATABASE_H
 #define DATABASE_H
 
-extern void Apply_Hacks_Cdrom();
+void Apply_Hacks_Cdrom(void);
+int check_unsatisfied_libcrypt(void);
 
 #endif
index a7f6aef..f37687c 100644 (file)
@@ -357,6 +357,7 @@ fail_io:
 
 // redump.org SBI files, slightly different handling from PCSX-Reloaded
 unsigned char *sbi_sectors;
+int sbi_len;
 
 int LoadSBI(const char *fname, int sector_count) {
        int good_sectors = 0;
@@ -370,7 +371,8 @@ int LoadSBI(const char *fname, int sector_count) {
        if (sbihandle == NULL)
                return -1;
 
-       sbi_sectors = calloc(1, sector_count / 8);
+       sbi_len = (sector_count + 7) / 8;
+       sbi_sectors = calloc(1, sbi_len);
        if (sbi_sectors == NULL)
                goto end;
 
@@ -414,15 +416,13 @@ int LoadSBI(const char *fname, int sector_count) {
                        break;
        }
 
-       fclose(sbihandle);
-       return 0;
-
 end:
        if (!clean_eof)
                SysPrintf(_("SBI: parse failure at 0x%lx\n"), ftell(sbihandle));
        if (!good_sectors) {
                free(sbi_sectors);
                sbi_sectors = NULL;
+               sbi_len = 0;
        }
        fclose(sbihandle);
        return sbi_sectors ? 0 : -1;
@@ -432,5 +432,6 @@ void UnloadSBI(void) {
        if (sbi_sectors) {
                free(sbi_sectors);
                sbi_sectors = NULL;
+               sbi_len = 0;
        }
 }
index fb0a377..a1b1475 100644 (file)
@@ -31,16 +31,17 @@ int LoadSBI(const char *fname, int sector_count);
 void UnloadSBI(void);
 
 extern unsigned char *sbi_sectors;
+extern int sbi_len;
 
 #include "cdrom.h"
 
-static inline int CheckSBI(const u8 *t)
+static inline int CheckSBI(int s)
 {
-       int s;
        if (sbi_sectors == NULL)
                return 0;
+       if ((unsigned int)(s >> 3) >= (unsigned int)sbi_len)
+               return 0;
 
-       s = MSF2SECT(t[0], t[1], t[2]);
        return (sbi_sectors[s >> 3] >> (s & 7)) & 1;
 }
 
index f6ff2e8..5f6971d 100644 (file)
@@ -958,8 +958,14 @@ void MTC0(psxRegisters *regs_, int reg, u32 val) {
                case 7:
                        if ((regs_->CP0.n.DCIC ^ val) & 0xff800000)
                                log_unhandled("DCIC: %08x->%08x\n", regs_->CP0.n.DCIC, val);
-                       // fallthrough
+                       goto default_;
+               case 3:
+                       if (regs_->CP0.n.BPC != val)
+                               log_unhandled("BPC: %08x->%08x\n", regs_->CP0.n.BPC, val);
+                       goto default_;
+
                default:
+               default_:
                        regs_->CP0.r[reg] = val;
                        break;
        }