1cf430a5a68739bc81a6e076d3c52c410fb1bb2c
[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 #include "lightrec/plugin.h"
6
7 /* It's duplicated from emu_if.c */
8 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
9
10 /* Corresponds to LIGHTREC_OPT_INV_DMA_ONLY of lightrec.h */
11 #define LIGHTREC_HACK_INV_DMA_ONLY (1 << 0)
12
13 u32 lightrec_hacks;
14
15 static const char * const MemorycardHack_db[] =
16 {
17         /* Lifeforce Tenka, also known as Codename Tenka */
18         "SLES00613", "SLED00690", "SLES00614", "SLES00615",
19         "SLES00616", "SLES00617", "SCUS94409"
20 };
21
22 static const char * const cdr_read_hack_db[] =
23 {
24         /* T'ai Fu - Wrath of the Tiger */
25         "SLUS00787",
26 };
27
28 static const char * const gpu_slow_llist_db[] =
29 {
30         /* Bomberman Fantasy Race */
31         "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823",
32         /* Crash Bash */
33         "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654",
34         /* Final Fantasy IV */
35         "SCES03840", "SLPM86028", "SLUS01360",
36         /* Point Blank - calibration cursor */
37         "SCED00287", "SCES00886", "SLUS00481",
38         /* Simple 1500 Series Vol. 57: The Meiro */
39         "SLPM86715",
40         /* Spot Goes to Hollywood */
41         "SLES00330", "SLPS00394", "SLUS00014",
42         /* Tiny Tank */
43         "SCES01338", "SCES02072", "SCES02072", "SCES02072", "SCES02072", "SCUS94427",
44         /* Vampire Hunter D */
45         "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138",
46 };
47
48 static const char * const gpu_centering_hack_db[] =
49 {
50         /* Gradius Gaiden */
51         "SLPM86042", "SLPM86103", "SLPM87323",
52         /* Sexy Parodius */
53         "SLPM86009",
54 };
55
56 static const char * const dualshock_timing1024_hack_db[] =
57 {
58         /* Judge Dredd - could also be poor cdrom+mdec+dma timing */
59         "SLUS00630", "SLES00755",
60 };
61
62 static const char * const dualshock_init_analog_hack_db[] =
63 {
64         /* Formula 1 Championship Edition */
65         "SLUS00546",
66 };
67
68 #define HACK_ENTRY(var, list) \
69         { #var, &Config.hacks.var, list, ARRAY_SIZE(list) }
70
71 static const struct
72 {
73         const char *name;
74         boolean *var;
75         const char * const * id_list;
76         size_t id_list_len;
77 }
78 hack_db[] =
79 {
80         HACK_ENTRY(cdr_read_timing, cdr_read_hack_db),
81         HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
82         HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
83         HACK_ENTRY(gpu_timing1024, dualshock_timing1024_hack_db),
84         HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
85 };
86
87 static const struct
88 {
89         int mult;
90         const char * const id[4];
91 }
92 cycle_multiplier_overrides[] =
93 {
94         /* note: values are = (10000 / gui_option) */
95         /* Internal Section - fussy about timings */
96         { 202, { "SLPS01868" } },
97         /* Super Robot Taisen Alpha - on the edge with 175,
98          * changing memcard settings is enough to break/unbreak it */
99         { 190, { "SLPS02528", "SLPS02636" } },
100         /* Colin McRae Rally - language selection menu does not work with 175 */
101         { 174, { "SLES00477" } },
102         /* Brave Fencer Musashi - cd sectors arrive too fast */
103         { 170, { "SLUS00726", "SLPS01490" } },
104 #if defined(DRC_DISABLE) || defined(LIGHTREC) /* new_dynarec has a hack for this game */
105         /* Parasite Eve II - internal timer checks */
106         { 125, { "SLUS01042", "SLUS01055", "SLES02558", "SLES12558" } },
107 #endif
108         /* Discworld Noir - audio skips if CPU runs too fast */
109         { 222, { "SLES01549", "SLES02063", "SLES02064" } },
110         /* Digimon World */
111         { 153, { "SLUS01032", "SLES02914" } },
112         /* Syphon Filter - reportedly hangs under unknown conditions */
113         { 169, { "SCUS94240" } },
114         /* Psychic Detective - some weird race condition in the game's cdrom code */
115         { 222, { "SLUS00165", "SLUS00166", "SLUS00167" } },
116         { 222, { "SLES00070", "SLES10070", "SLES20070" } },
117         /* Vib-Ribbon - cd timing issues (PAL+ari64drc only?) */
118         { 200, { "SCES02873" } },
119         /* Zero Divide - sometimes too fast */
120         { 200, { "SLUS00183", "SLES00159", "SLPS00083", "SLPM80008" } },
121 };
122
123 static const struct
124 {
125         const char * const id;
126         u32 hacks;
127 }
128 lightrec_hacks_db[] =
129 {
130         /* Formula One Arcade */
131         { "SCES03886", LIGHTREC_HACK_INV_DMA_ONLY },
132
133         /* Formula One '99 */
134         { "SLUS00870", LIGHTREC_HACK_INV_DMA_ONLY },
135         { "SCPS10101", LIGHTREC_HACK_INV_DMA_ONLY },
136         { "SCES01979", LIGHTREC_HACK_INV_DMA_ONLY },
137         { "SLES01979", LIGHTREC_HACK_INV_DMA_ONLY },
138
139         /* Formula One 2000 */
140         { "SLUS01134", LIGHTREC_HACK_INV_DMA_ONLY },
141         { "SCES02777", LIGHTREC_HACK_INV_DMA_ONLY },
142         { "SCES02778", LIGHTREC_HACK_INV_DMA_ONLY },
143         { "SCES02779", LIGHTREC_HACK_INV_DMA_ONLY },
144
145         /* Formula One 2001 */
146         { "SCES03404", LIGHTREC_HACK_INV_DMA_ONLY },
147         { "SCES03423", LIGHTREC_HACK_INV_DMA_ONLY },
148         { "SCES03424", LIGHTREC_HACK_INV_DMA_ONLY },
149         { "SCES03524", LIGHTREC_HACK_INV_DMA_ONLY },
150 };
151
152 /* Function for automatic patching according to GameID. */
153 void Apply_Hacks_Cdrom(void)
154 {
155         size_t i, j;
156
157         memset(&Config.hacks, 0, sizeof(Config.hacks));
158
159         for (i = 0; i < ARRAY_SIZE(hack_db); i++)
160         {
161                 for (j = 0; j < hack_db[i].id_list_len; j++)
162                 {
163                         if (strncmp(CdromId, hack_db[i].id_list[j], 9))
164                                 continue;
165                         *hack_db[i].var = 1;
166                         SysPrintf("using hack: %s\n", hack_db[i].name);
167                         break;
168                 }
169         }
170
171         if (Config.hacks.dualshock_init_analog) {
172                 // assume the default is off, see LoadPAD1plugin()
173                 for (i = 0; i < 8; i++)
174                         padToggleAnalog(i);
175         }
176
177         /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
178         for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
179         {
180                 if (strncmp(CdromId, MemorycardHack_db[i], 9) == 0)
181                 {
182                         /* Disable the second memory card slot for the game */
183                         Config.Mcd2[0] = 0;
184                         /* This also needs to be done because in sio.c, they don't use Config.Mcd2 for that purpose */
185                         McdDisable[1] = 1;
186                         break;
187                 }
188         }
189
190         /* Dynarec game-specific hacks */
191         new_dynarec_hacks_pergame = 0;
192         Config.cycle_multiplier_override = 0;
193
194         for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
195         {
196                 const char * const * const ids = cycle_multiplier_overrides[i].id;
197                 for (j = 0; j < ARRAY_SIZE(cycle_multiplier_overrides[i].id); j++)
198                         if (ids[j] && strcmp(ids[j], CdromId) == 0)
199                                 break;
200                 if (j < ARRAY_SIZE(cycle_multiplier_overrides[i].id))
201                 {
202                         Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
203                         new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
204                         SysPrintf("using cycle_multiplier_override: %d\n",
205                                 Config.cycle_multiplier_override);
206                         break;
207                 }
208         }
209
210         lightrec_hacks = 0;
211
212         for (i = 0; drc_is_lightrec() && i < ARRAY_SIZE(lightrec_hacks_db); i++) {
213                 if (strcmp(CdromId, lightrec_hacks_db[i].id) == 0)
214                 {
215                         lightrec_hacks = lightrec_hacks_db[i].hacks;
216                         SysPrintf("using lightrec_hacks: 0x%x\n", lightrec_hacks);
217                         break;
218                 }
219         }
220 }
221
222 // from duckstation's gamedb.json
223 static const u16 libcrypt_ids[] = {
224            17,   311,   995,  1041,  1226,  1241,  1301,  1362,  1431,  1444,
225          1492,  1493,  1494,  1495,  1516,  1517,  1518,  1519,  1545,  1564,
226          1695,  1700,  1701,  1702,  1703,  1704,  1715,  1733,  1763,  1882,
227          1906,  1907,  1909,  1943,  1979,  2004,  2005,  2006,  2007,  2024,
228          2025,  2026,  2027,  2028,  2029,  2030,  2031,  2061,  2071,  2080,
229          2081,  2082,  2083,  2084,  2086,  2104,  2105,  2112,  2113,  2118,
230          2181,  2182,  2184,  2185,  2207,  2208,  2209,  2210,  2211,  2222,
231          2264,  2290,  2292,  2293,  2328,  2329,  2330,  2354,  2355,  2365,
232          2366,  2367,  2368,  2369,  2395,  2396,  2402,  2430,  2431,  2432,
233          2433,  2487,  2488,  2489,  2490,  2491,  2529,  2530,  2531,  2532,
234          2533,  2538,  2544,  2545,  2546,  2558,  2559,  2560,  2561,  2562,
235          2563,  2572,  2573,  2681,  2688,  2689,  2698,  2700,  2704,  2705,
236          2706,  2707,  2708,  2722,  2723,  2724,  2733,  2754,  2755,  2756,
237          2763,  2766,  2767,  2768,  2769,  2824,  2830,  2831,  2834,  2835,
238          2839,  2857,  2858,  2859,  2860,  2861,  2862,  2965,  2966,  2967,
239          2968,  2969,  2975,  2976,  2977,  2978,  2979,  3061,  3062,  3189,
240          3190,  3191,  3241,  3242,  3243,  3244,  3245,  3324,  3489,  3519,
241          3520,  3521,  3522,  3523,  3530,  3603,  3604,  3605,  3606,  3607,
242          3626,  3648, 12080, 12081, 12082, 12083, 12084, 12328, 12329, 12330,
243         12558, 12559, 12560, 12561, 12562, 12965, 12966, 12967, 12968, 12969,
244         22080, 22081, 22082, 22083, 22084, 22328, 22329, 22330, 22965, 22966,
245         22967, 22968, 22969, 32080, 32081, 32082, 32083, 32084, 32965, 32966,
246         32967, 32968, 32969
247 };
248
249 // as documented by nocash
250 static const u16 libcrypt_sectors[16] = {
251         14105, 14231, 14485, 14579, 14649, 14899, 15056, 15130,
252         15242, 15312, 15378, 15628, 15919, 16031, 16101, 16167
253 };
254
255 int check_unsatisfied_libcrypt(void)
256 {
257         const char *p = CdromId + 4;
258         u16 id, key = 0;
259         size_t i;
260
261         if (strncmp(CdromId, "SCE", 3) && strncmp(CdromId, "SLE", 3))
262                 return 0;
263         while (*p == '0')
264                 p++;
265         id = (u16)atoi(p);
266         for (i = 0; i < ARRAY_SIZE(libcrypt_ids); i++)
267                 if (id == libcrypt_ids[i])
268                         break;
269         if (i == ARRAY_SIZE(libcrypt_ids))
270                 return 0;
271
272         // detected a protected game
273         if (!CDR_getBufferSub(libcrypt_sectors[0]) && !sbi_sectors) {
274                 SysPrintf("==================================================\n");
275                 SysPrintf("LibCrypt game detected with missing SBI/subchannel\n");
276                 SysPrintf("==================================================\n");
277                 return 1;
278         }
279
280         if (sbi_sectors) {
281                 // calculate key just for fun (we don't really need it)
282                 for (i = 0; i < 16; i++)
283                         if (CheckSBI(libcrypt_sectors[i] - 2*75))
284                                 key |= 1u << (15 - i);
285         }
286         if (key)
287                 SysPrintf("%s, possible key=%04X\n", "LibCrypt detected", key);
288         else
289                 SysPrintf("%s\n", "LibCrypt detected");
290         return 0;
291 }