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