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