a68fe4f38d4466d131537fdab7cf71dc6ec46fd7
[pcsx_rearmed.git] / libpcsxcore / database.c
1 #include "misc.h"
2 #include "sio.h"
3 #include "ppf.h"
4 #include "new_dynarec/new_dynarec.h"
5
6 /* It's duplicated from emu_if.c */
7 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
8
9 static const char * const MemorycardHack_db[] =
10 {
11         /* Lifeforce Tenka, also known as Codename Tenka */
12         "SLES00613", "SLED00690", "SLES00614", "SLES00615",
13         "SLES00616", "SLES00617", "SCUS94409"
14 };
15
16 static const char * const cdr_read_hack_db[] =
17 {
18         /* T'ai Fu - Wrath of the Tiger */
19         "SLUS00787",
20 };
21
22 static const char * const gpu_slow_llist_db[] =
23 {
24         /* Bomberman Fantasy Race */
25         "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823",
26         /* Crash Bash */
27         "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654",
28         /* Final Fantasy IV */
29         "SCES03840", "SLPM86028", "SLUS01360",
30         /* Spot Goes to Hollywood */
31         "SLES00330", "SLPS00394", "SLUS00014",
32         /* Vampire Hunter D */
33         "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138",
34 };
35
36 static const char * const gpu_busy_hack_db[] =
37 {
38         /* ToHeart (Japan) */
39         "SLPS01919", "SLPS01920",
40 };
41
42 #define HACK_ENTRY(var, list) \
43         { #var, &Config.hacks.var, list, ARRAY_SIZE(list) }
44
45 static const struct
46 {
47         const char *name;
48         boolean *var;
49         const char * const * id_list;
50         size_t id_list_len;
51 }
52 hack_db[] =
53 {
54         HACK_ENTRY(cdr_read_timing, cdr_read_hack_db),
55         HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
56         HACK_ENTRY(gpu_busy_hack, gpu_busy_hack_db),
57 };
58
59 static const struct
60 {
61         const char * const id;
62         int mult;
63 }
64 cycle_multiplier_overrides[] =
65 {
66         /* note: values are = (10000 / gui_option) */
67         /* Internal Section - fussy about timings */
68         { "SLPS01868", 202 },
69         /* Super Robot Taisen Alpha - on the edge with 175,
70          * changing memcard settings is enough to break/unbreak it */
71         { "SLPS02528", 190 },
72         { "SLPS02636", 190 },
73         /* Brave Fencer Musashi - cd sectors arrive too fast */
74         { "SLUS00726", 170 },
75         { "SLPS01490", 170 },
76 #if defined(DRC_DISABLE) || defined(LIGHTREC) /* new_dynarec has a hack for this game */
77         /* Parasite Eve II - internal timer checks */
78         { "SLUS01042", 125 },
79         { "SLUS01055", 125 },
80         { "SLES02558", 125 },
81         { "SLES12558", 125 },
82 #endif
83         /* Discworld Noir - audio skips if CPU runs too fast */
84         { "SLES01549", 222 },
85         { "SLES02063", 222 },
86         { "SLES02064", 222 },
87         /* Judge Dredd - could also be poor MDEC timing */
88         { "SLUS00630", 128 },
89         { "SLES00755", 128 },
90         /* Digimon World */
91         { "SLUS01032", 153 },
92         { "SLES02914", 153 },
93         /* Syphon Filter - reportedly hangs under unknown conditions */
94         { "SCUS94240", 169 },
95 };
96
97 /* Function for automatic patching according to GameID. */
98 void Apply_Hacks_Cdrom(void)
99 {
100         size_t i, j;
101
102         memset(&Config.hacks, 0, sizeof(Config.hacks));
103
104         for (i = 0; i < ARRAY_SIZE(hack_db); i++)
105         {
106                 for (j = 0; j < hack_db[i].id_list_len; j++)
107                 {
108                         if (strncmp(CdromId, hack_db[i].id_list[j], 9))
109                                 continue;
110                         *hack_db[i].var = 1;
111                         SysPrintf("using hack: %s\n", hack_db[i].name);
112                         break;
113                 }
114         }
115
116         /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
117         for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
118         {
119                 if (strncmp(CdromId, MemorycardHack_db[i], 9) == 0)
120                 {
121                         /* Disable the second memory card slot for the game */
122                         Config.Mcd2[0] = 0;
123                         /* This also needs to be done because in sio.c, they don't use Config.Mcd2 for that purpose */
124                         McdDisable[1] = 1;
125                         break;
126                 }
127         }
128
129         /* Dynarec game-specific hacks */
130         new_dynarec_hacks_pergame = 0;
131         Config.cycle_multiplier_override = 0;
132
133         for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
134         {
135                 if (strcmp(CdromId, cycle_multiplier_overrides[i].id) == 0)
136                 {
137                         Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
138                         new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
139                         SysPrintf("using cycle_multiplier_override: %d\n",
140                                 Config.cycle_multiplier_override);
141                         break;
142                 }
143         }
144 }
145
146 // from duckstation's gamedb.json
147 static const u16 libcrypt_ids[] = {
148            17,   311,   995,  1041,  1226,  1241,  1301,  1362,  1431,  1444,
149          1492,  1493,  1494,  1495,  1516,  1517,  1518,  1519,  1545,  1564,
150          1695,  1700,  1701,  1702,  1703,  1704,  1715,  1733,  1763,  1882,
151          1906,  1907,  1909,  1943,  1979,  2004,  2005,  2006,  2007,  2024,
152          2025,  2026,  2027,  2028,  2029,  2030,  2031,  2061,  2071,  2080,
153          2081,  2082,  2083,  2084,  2086,  2104,  2105,  2112,  2113,  2118,
154          2181,  2182,  2184,  2185,  2207,  2208,  2209,  2210,  2211,  2222,
155          2264,  2290,  2292,  2293,  2328,  2329,  2330,  2354,  2355,  2365,
156          2366,  2367,  2368,  2369,  2395,  2396,  2402,  2430,  2431,  2432,
157          2433,  2487,  2488,  2489,  2490,  2491,  2529,  2530,  2531,  2532,
158          2533,  2538,  2544,  2545,  2546,  2558,  2559,  2560,  2561,  2562,
159          2563,  2572,  2573,  2681,  2688,  2689,  2698,  2700,  2704,  2705,
160          2706,  2707,  2708,  2722,  2723,  2724,  2733,  2754,  2755,  2756,
161          2763,  2766,  2767,  2768,  2769,  2824,  2830,  2831,  2834,  2835,
162          2839,  2857,  2858,  2859,  2860,  2861,  2862,  2965,  2966,  2967,
163          2968,  2969,  2975,  2976,  2977,  2978,  2979,  3061,  3062,  3189,
164          3190,  3191,  3241,  3242,  3243,  3244,  3245,  3324,  3489,  3519,
165          3520,  3521,  3522,  3523,  3530,  3603,  3604,  3605,  3606,  3607,
166          3626,  3648, 12080, 12081, 12082, 12083, 12084, 12328, 12329, 12330,
167         12558, 12559, 12560, 12561, 12562, 12965, 12966, 12967, 12968, 12969,
168         22080, 22081, 22082, 22083, 22084, 22328, 22329, 22330, 22965, 22966,
169         22967, 22968, 22969, 32080, 32081, 32082, 32083, 32084, 32965, 32966,
170         32967, 32968, 32969
171 };
172
173 // as documented by nocash
174 static const u16 libcrypt_sectors[16] = {
175         14105, 14231, 14485, 14579, 14649, 14899, 15056, 15130,
176         15242, 15312, 15378, 15628, 15919, 16031, 16101, 16167
177 };
178
179 int check_unsatisfied_libcrypt(void)
180 {
181         const char *p = CdromId + 4;
182         u16 id, key = 0;
183         size_t i;
184
185         if (strncmp(CdromId, "SCE", 3) && strncmp(CdromId, "SLE", 3))
186                 return 0;
187         while (*p == '0')
188                 p++;
189         id = (u16)atoi(p);
190         for (i = 0; i < ARRAY_SIZE(libcrypt_ids); i++)
191                 if (id == libcrypt_ids[i])
192                         break;
193         if (i == ARRAY_SIZE(libcrypt_ids))
194                 return 0;
195
196         // detected a protected game
197         if (!CDR_getBufferSub(libcrypt_sectors[0]) && !sbi_sectors) {
198                 SysPrintf("==================================================\n");
199                 SysPrintf("LibCrypt game detected with missing SBI/subchannel\n");
200                 SysPrintf("==================================================\n");
201                 return 1;
202         }
203
204         if (sbi_sectors) {
205                 // calculate key just for fun (we don't really need it)
206                 for (i = 0; i < 16; i++)
207                         if (CheckSBI(libcrypt_sectors[i] - 2*75))
208                                 key |= 1u << (15 - i);
209         }
210         if (key)
211                 SysPrintf("%s, possible key=%04X\n", "LibCrypt detected", key);
212         else
213                 SysPrintf("%s\n", "LibCrypt detected");
214         return 0;
215 }