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