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