db: Override cycle multiplier for Colin McRae PAL
[pcsx_rearmed.git] / libpcsxcore / database.c
CommitLineData
630b122b 1#include "misc.h"
2#include "sio.h"
cdee2d81 3#include "ppf.h"
630b122b 4#include "new_dynarec/new_dynarec.h"
8bccdd17 5#include "lightrec/plugin.h"
630b122b 6
7/* It's duplicated from emu_if.c */
8#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
9
8bccdd17
PC
10/* Corresponds to LIGHTREC_OPT_INV_DMA_ONLY of lightrec.h */
11#define LIGHTREC_HACK_INV_DMA_ONLY (1 << 0)
12
13u32 lightrec_hacks;
14
d0d2939d 15static const char * const MemorycardHack_db[] =
630b122b 16{
17 /* Lifeforce Tenka, also known as Codename Tenka */
d0d2939d 18 "SLES00613", "SLED00690", "SLES00614", "SLES00615",
19 "SLES00616", "SLES00617", "SCUS94409"
20};
21
22static const char * const cdr_read_hack_db[] =
23{
24 /* T'ai Fu - Wrath of the Tiger */
25 "SLUS00787",
26};
27
fae38d7a 28static const char * const gpu_slow_llist_db[] =
29{
fe564285
WVP
30 /* Bomberman Fantasy Race */
31 "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823",
fae38d7a 32 /* Crash Bash */
33 "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654",
34 /* Final Fantasy IV */
35 "SCES03840", "SLPM86028", "SLUS01360",
d28e9a2e 36 /* Point Blank - calibration cursor */
37 "SCED00287", "SCES00886", "SLUS00481",
5fdfbd00 38 /* Simple 1500 Series Vol. 57: The Meiro */
39 "SLPM86715",
fae38d7a 40 /* Spot Goes to Hollywood */
41 "SLES00330", "SLPS00394", "SLUS00014",
5fdfbd00 42 /* Tiny Tank */
43 "SCES01338", "SCES02072", "SCES02072", "SCES02072", "SCES02072", "SCUS94427",
fae38d7a 44 /* Vampire Hunter D */
45 "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138",
46};
47
b3ff74ba 48static const char * const gpu_centering_hack_db[] =
49{
50 /* Gradius Gaiden */
51 "SLPM86042", "SLPM86103", "SLPM87323",
52 /* Sexy Parodius */
53 "SLPM86009",
54};
55
6a3b3d86 56static const char * const dualshock_timing1024_hack_db[] =
57{
58 /* Judge Dredd - could also be poor cdrom+mdec+dma timing */
59 "SLUS00630", "SLES00755",
60};
61
26e9c4f1 62static const char * const dualshock_init_analog_hack_db[] =
63{
64 /* Formula 1 Championship Edition */
65 "SLUS00546",
66};
67
d0d2939d 68#define HACK_ENTRY(var, list) \
69 { #var, &Config.hacks.var, list, ARRAY_SIZE(list) }
70
71static const struct
72{
73 const char *name;
74 boolean *var;
75 const char * const * id_list;
76 size_t id_list_len;
77}
78hack_db[] =
79{
80 HACK_ENTRY(cdr_read_timing, cdr_read_hack_db),
fae38d7a 81 HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
b3ff74ba 82 HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
6a3b3d86 83 HACK_ENTRY(gpu_timing1024, dualshock_timing1024_hack_db),
26e9c4f1 84 HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
630b122b 85};
86
d7907215 87static const struct
88{
d7907215 89 int mult;
353119c2 90 const char * const id[4];
d7907215 91}
1562ed57 92cycle_multiplier_overrides[] =
d7907215 93{
9170c48e 94 /* note: values are = (10000 / gui_option) */
d7907215 95 /* Internal Section - fussy about timings */
353119c2 96 { 202, { "SLPS01868" } },
d7907215 97 /* Super Robot Taisen Alpha - on the edge with 175,
98 * changing memcard settings is enough to break/unbreak it */
353119c2 99 { 190, { "SLPS02528", "SLPS02636" } },
4cc48a6b
PC
100 /* Colin McRae Rally - language selection menu does not work with 175 */
101 { 174, { "SLES00477" } },
b8f3d43d 102 /* Brave Fencer Musashi - cd sectors arrive too fast */
353119c2 103 { 170, { "SLUS00726", "SLPS01490" } },
86be2515 104#if defined(DRC_DISABLE) || defined(LIGHTREC) /* new_dynarec has a hack for this game */
1562ed57 105 /* Parasite Eve II - internal timer checks */
353119c2 106 { 125, { "SLUS01042", "SLUS01055", "SLES02558", "SLES12558" } },
1562ed57 107#endif
b99a48f2 108 /* Discworld Noir - audio skips if CPU runs too fast */
353119c2 109 { 222, { "SLES01549", "SLES02063", "SLES02064" } },
9170c48e 110 /* Digimon World */
353119c2 111 { 153, { "SLUS01032", "SLES02914" } },
8f3fa1e8 112 /* Syphon Filter - reportedly hangs under unknown conditions */
353119c2 113 { 169, { "SCUS94240" } },
9159f799 114 /* Psychic Detective - some weird race condition in the game's cdrom code */
115 { 222, { "SLUS00165", "SLUS00166", "SLUS00167" } },
116 { 222, { "SLES00070", "SLES10070", "SLES20070" } },
d28e9a2e 117 /* Vib-Ribbon - cd timing issues (PAL+ari64drc only?) */
118 { 200, { "SCES02873" } },
b2abce3b 119 /* Zero Divide - sometimes too fast */
120 { 200, { "SLUS00183", "SLES00159", "SLPS00083", "SLPM80008" } },
d7907215 121};
122
8bccdd17
PC
123static const struct
124{
125 const char * const id;
126 u32 hacks;
127}
128lightrec_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
630b122b 152/* Function for automatic patching according to GameID. */
cdee2d81 153void Apply_Hacks_Cdrom(void)
630b122b 154{
d0d2939d 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
26e9c4f1 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
630b122b 177 /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
d0d2939d 178 for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
630b122b 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;
d0d2939d 186 break;
630b122b 187 }
188 }
189
190 /* Dynarec game-specific hacks */
191 new_dynarec_hacks_pergame = 0;
1562ed57 192 Config.cycle_multiplier_override = 0;
630b122b 193
1562ed57 194 for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
630b122b 195 {
353119c2 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))
d7907215 201 {
1562ed57 202 Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
d7907215 203 new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
1562ed57 204 SysPrintf("using cycle_multiplier_override: %d\n",
205 Config.cycle_multiplier_override);
d7907215 206 break;
207 }
630b122b 208 }
8bccdd17
PC
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 }
630b122b 220}
cdee2d81 221
222// from duckstation's gamedb.json
223static 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
250static 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
255int 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}