dev-release: try to make it work
[pcsx_rearmed.git] / libpcsxcore / database.c
CommitLineData
eedfe806 1#include "misc.h"
eedfe806 2#include "sio.h"
f3746eea 3#include "ppf.h"
08d9d257 4#include "cdrom-async.h"
a3203cf4 5#include "new_dynarec/new_dynarec.h"
a3c46b7f 6#include "lightrec/plugin.h"
eedfe806 7
8/* It's duplicated from emu_if.c */
9#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
10
a3c46b7f 11/* Corresponds to LIGHTREC_OPT_INV_DMA_ONLY of lightrec.h */
12#define LIGHTREC_HACK_INV_DMA_ONLY (1 << 0)
13
14u32 lightrec_hacks;
15
688bdb95 16static const char * const MemorycardHack_db[] =
eedfe806 17{
18 /* Lifeforce Tenka, also known as Codename Tenka */
688bdb95 19 "SLES00613", "SLED00690", "SLES00614", "SLES00615",
20 "SLES00616", "SLES00617", "SCUS94409"
21};
22
23static const char * const cdr_read_hack_db[] =
24{
25 /* T'ai Fu - Wrath of the Tiger */
26 "SLUS00787",
27};
28
8c84ba5f 29static const char * const gpu_slow_llist_db[] =
30{
e189515f
WVP
31 /* Bomberman Fantasy Race */
32 "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823",
8c84ba5f 33 /* Crash Bash */
34 "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654",
78c8d214 35 /* F1 2000 - aborting/resuming dma in menus */
36 "SLUS01120", "SLES02722", "SLES02723", "SLES02724", "SLPS02758", "SLPM80564",
8c84ba5f 37 /* Final Fantasy IV */
38 "SCES03840", "SLPM86028", "SLUS01360",
7f2a91d0 39 /* Point Blank - calibration cursor */
40 "SCED00287", "SCES00886", "SLUS00481",
1cff67e5 41 /* Simple 1500 Series Vol. 57: The Meiro */
42 "SLPM86715",
8c84ba5f 43 /* Spot Goes to Hollywood */
44 "SLES00330", "SLPS00394", "SLUS00014",
1cff67e5 45 /* Tiny Tank */
46 "SCES01338", "SCES02072", "SCES02072", "SCES02072", "SCES02072", "SCUS94427",
8c84ba5f 47 /* Vampire Hunter D */
48 "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138",
49};
50
9ed80467 51static const char * const gpu_centering_hack_db[] =
52{
53 /* Gradius Gaiden */
54 "SLPM86042", "SLPM86103", "SLPM87323",
51315a0f 55 /* Salamander Deluxe Pack Plus */
56 "SLPM86037",
9ed80467 57 /* Sexy Parodius */
58 "SLPM86009",
59};
60
e5241564 61static const char * const dualshock_init_analog_hack_db[] =
62{
63 /* Formula 1 Championship Edition */
64 "SLUS00546",
65};
66
4c8f1c25 67static const char * const fractional_Framerate_hack_db[] =
68{
323497d5 69 /* Contra - Legacy of War - weird char select hang */
70 "SLUS00288", "SLES00608",
4c8f1c25 71 /* Dance Dance Revolution */
72 "SLPM86503", // 3rd Mix
73 "SLPM86752", // 4th Mix
74 "SLPM86266", // 4thMix: The Beat Goes On
75 "SLPM86831", // Extra Mix
76 "SLUS01446", // Konamix
77 /* Dancing Stage Fever */
78 "SLES04097",
79 /* Dancing Stage Fusion */
80 "SLES04163",
81 /* Spyro 2 */
82 "SCUS94425", "SCES02104",
83};
84
6baeda45 85static const char * const f1_hack_db[] =
86{
87 /* Formula One Arcade */
88 "SCES03886",
89 /* Formula One '99 */
90 "SLUS00870", "SCPS10101", "SCES01979", "SLES01979",
91 /* Formula One 2000 */
92 "SLUS01134", "SCES02777", "SCES02778", "SCES02779",
93 /* Formula One 2001 */
94 "SCES03404", "SCES03423", "SCES03424", "SCES03524",
95};
96
688bdb95 97#define HACK_ENTRY(var, list) \
98 { #var, &Config.hacks.var, list, ARRAY_SIZE(list) }
99
100static const struct
101{
102 const char *name;
103 boolean *var;
104 const char * const * id_list;
105 size_t id_list_len;
106}
107hack_db[] =
108{
109 HACK_ENTRY(cdr_read_timing, cdr_read_hack_db),
8c84ba5f 110 HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
9ed80467 111 HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
e5241564 112 HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
4c8f1c25 113 HACK_ENTRY(fractional_Framerate, fractional_Framerate_hack_db),
6baeda45 114 HACK_ENTRY(f1, f1_hack_db),
eedfe806 115};
116
4a02afab 117static const struct
118{
4a02afab 119 int mult;
1d94bceb 120 const char * const id[4];
4a02afab 121}
d5aeda23 122cycle_multiplier_overrides[] =
4a02afab 123{
bd9ad3d8 124 /* note: values are = (10000 / gui_option) */
4a02afab 125 /* Internal Section - fussy about timings */
1d94bceb 126 { 202, { "SLPS01868" } },
4a02afab 127 /* Super Robot Taisen Alpha - on the edge with 175,
128 * changing memcard settings is enough to break/unbreak it */
1d94bceb 129 { 190, { "SLPS02528", "SLPS02636" } },
642638a3
PC
130 /* Colin McRae Rally - language selection menu does not work with 175 */
131 { 174, { "SLES00477" } },
54c4acac 132 /* Brave Fencer Musashi - cd sectors arrive too fast */
1d94bceb 133 { 170, { "SLUS00726", "SLPS01490" } },
b43acfe5 134#if defined(DRC_DISABLE) || defined(LIGHTREC) /* ari64 drc has a hack for this game */
d5aeda23 135 /* Parasite Eve II - internal timer checks */
1d94bceb 136 { 125, { "SLUS01042", "SLUS01055", "SLES02558", "SLES12558" } },
b43acfe5 137 { 125, { "SLES02559", "SLES12559", "SLES02560", "SLES12560" } },
138 { 125, { "SLES02561", "SLES12561", "SLES02562", "SLES12562" } },
139 { 125, { "SCPS45467", "SCPS45468", "SLPS02480", "SLPS02481" } },
d5aeda23 140#endif
7b9a83e8 141 /* Discworld Noir - audio skips if CPU runs too fast */
1d94bceb 142 { 222, { "SLES01549", "SLES02063", "SLES02064" } },
bd9ad3d8 143 /* Digimon World */
1d94bceb 144 { 153, { "SLUS01032", "SLES02914" } },
77d753f4
WVP
145 /* Power Rangers: Lightspeed Rescue - jumping fails if FPS is over 30 */
146 { 310, { "SLUS01114", "SLES03286" } },
8392bff9 147 /* Syphon Filter - reportedly hangs under unknown conditions */
1d94bceb 148 { 169, { "SCUS94240" } },
9d701f80 149#ifndef DRC_DISABLE
3de08a09 150 /* Psychic Detective - some weird race condition in the game's cdrom code */
9d701f80 151 { 181, { "SLUS00165", "SLUS00166", "SLUS00167" } },
152 { 181, { "SLES00070", "SLES10070", "SLES20070" } },
153#endif
7f2a91d0 154 /* Vib-Ribbon - cd timing issues (PAL+ari64drc only?) */
155 { 200, { "SCES02873" } },
548cdef9 156 /* Zero Divide - sometimes too fast */
157 { 200, { "SLUS00183", "SLES00159", "SLPS00083", "SLPM80008" } },
0ed2889a 158 /* Eagle One: Harrier Attack - hangs (but not in standalone build?) */
159 { 153, { "SLUS00943" } },
9cbce417 160 /* Sol Divide: FMV timing */
161 { 200, { "SLUS01519", "SCPS45260", "SLPS01463" } },
e45d2bc4 162 /* Legend of Legaia - some attack moves lag and cause a/v desync */
163 { 160, { "SCUS94254", "SCUS94366", "SCES01752" } },
164 { 160, { "SCES01944", "SCES01945", "SCES01946", "SCES01947" } },
4a02afab 165};
166
78c8d214 167static const struct
168{
169 int cycles;
170 const char * const id[4];
171}
172gpu_timing_hack_db[] =
173{
174 /* Judge Dredd - poor cdrom+mdec+dma+gpu timing */
175 { 1024, { "SLUS00630", "SLES00755" } },
176 /* F1 2000 - flooding the GPU in menus */
177 { 300*1024, { "SLUS01120", "SLES02722", "SLES02723", "SLES02724" } },
178 { 300*1024, { "SLPS02758", "SLPM80564" } },
179 /* Soul Blade - same as above */
180 { 512*1024, { "SLUS00240", "SCES00577" } },
181};
182
0de3bab4 183static const char * const lightrec_hack_db[] =
184{
185 /* Tomb Raider (Rev 2) - boot menu clears over itself */
186 "SLUS00152",
187};
188
eedfe806 189/* Function for automatic patching according to GameID. */
f3746eea 190void Apply_Hacks_Cdrom(void)
eedfe806 191{
688bdb95 192 size_t i, j;
193
194 memset(&Config.hacks, 0, sizeof(Config.hacks));
195
196 for (i = 0; i < ARRAY_SIZE(hack_db); i++)
197 {
198 for (j = 0; j < hack_db[i].id_list_len; j++)
199 {
200 if (strncmp(CdromId, hack_db[i].id_list[j], 9))
201 continue;
202 *hack_db[i].var = 1;
203 SysPrintf("using hack: %s\n", hack_db[i].name);
204 break;
205 }
206 }
207
e5241564 208 if (Config.hacks.dualshock_init_analog) {
209 // assume the default is off, see LoadPAD1plugin()
210 for (i = 0; i < 8; i++)
211 padToggleAnalog(i);
212 }
213
eedfe806 214 /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
688bdb95 215 for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
eedfe806 216 {
217 if (strncmp(CdromId, MemorycardHack_db[i], 9) == 0)
218 {
219 /* Disable the second memory card slot for the game */
220 Config.Mcd2[0] = 0;
221 /* This also needs to be done because in sio.c, they don't use Config.Mcd2 for that purpose */
222 McdDisable[1] = 1;
688bdb95 223 break;
eedfe806 224 }
225 }
a3203cf4 226
227 /* Dynarec game-specific hacks */
0b1633d7 228 ndrc_g.hacks_pergame = 0;
6baeda45 229 if (Config.hacks.f1)
230 ndrc_g.hacks_pergame |= NDHACK_THREAD_FORCE; // force without *_ON -> off
d5aeda23 231 Config.cycle_multiplier_override = 0;
a3203cf4 232
d5aeda23 233 for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
a3203cf4 234 {
1d94bceb 235 const char * const * const ids = cycle_multiplier_overrides[i].id;
236 for (j = 0; j < ARRAY_SIZE(cycle_multiplier_overrides[i].id); j++)
237 if (ids[j] && strcmp(ids[j], CdromId) == 0)
238 break;
239 if (j < ARRAY_SIZE(cycle_multiplier_overrides[i].id))
4a02afab 240 {
d5aeda23 241 Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
0b1633d7 242 ndrc_g.hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
d5aeda23 243 SysPrintf("using cycle_multiplier_override: %d\n",
244 Config.cycle_multiplier_override);
4a02afab 245 break;
246 }
a3203cf4 247 }
a3c46b7f 248
78c8d214 249 Config.gpu_timing_override = 0;
250 for (i = 0; i < ARRAY_SIZE(gpu_timing_hack_db); i++)
251 {
252 const char * const * const ids = gpu_timing_hack_db[i].id;
253 for (j = 0; j < ARRAY_SIZE(gpu_timing_hack_db[i].id); j++)
254 if (ids[j] && strcmp(ids[j], CdromId) == 0)
255 break;
256 if (j < ARRAY_SIZE(gpu_timing_hack_db[i].id))
257 {
258 Config.gpu_timing_override = gpu_timing_hack_db[i].cycles;
259 SysPrintf("using gpu_timing_override: %d\n",
260 Config.gpu_timing_override);
261 break;
262 }
263 }
264
6baeda45 265 if (drc_is_lightrec()) {
266 lightrec_hacks = 0;
267 if (Config.hacks.f1)
268 lightrec_hacks |= LIGHTREC_HACK_INV_DMA_ONLY;
0de3bab4 269 for (i = 0; i < ARRAY_SIZE(lightrec_hack_db); i++)
270 if (strcmp(lightrec_hack_db[i], CdromId) == 0)
271 lightrec_hacks |= LIGHTREC_HACK_INV_DMA_ONLY;
6baeda45 272 if (lightrec_hacks)
a3c46b7f 273 SysPrintf("using lightrec_hacks: 0x%x\n", lightrec_hacks);
a3c46b7f 274 }
eedfe806 275}
f3746eea 276
277// from duckstation's gamedb.json
278static const u16 libcrypt_ids[] = {
279 17, 311, 995, 1041, 1226, 1241, 1301, 1362, 1431, 1444,
280 1492, 1493, 1494, 1495, 1516, 1517, 1518, 1519, 1545, 1564,
281 1695, 1700, 1701, 1702, 1703, 1704, 1715, 1733, 1763, 1882,
282 1906, 1907, 1909, 1943, 1979, 2004, 2005, 2006, 2007, 2024,
283 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2061, 2071, 2080,
284 2081, 2082, 2083, 2084, 2086, 2104, 2105, 2112, 2113, 2118,
285 2181, 2182, 2184, 2185, 2207, 2208, 2209, 2210, 2211, 2222,
286 2264, 2290, 2292, 2293, 2328, 2329, 2330, 2354, 2355, 2365,
287 2366, 2367, 2368, 2369, 2395, 2396, 2402, 2430, 2431, 2432,
288 2433, 2487, 2488, 2489, 2490, 2491, 2529, 2530, 2531, 2532,
289 2533, 2538, 2544, 2545, 2546, 2558, 2559, 2560, 2561, 2562,
290 2563, 2572, 2573, 2681, 2688, 2689, 2698, 2700, 2704, 2705,
291 2706, 2707, 2708, 2722, 2723, 2724, 2733, 2754, 2755, 2756,
292 2763, 2766, 2767, 2768, 2769, 2824, 2830, 2831, 2834, 2835,
293 2839, 2857, 2858, 2859, 2860, 2861, 2862, 2965, 2966, 2967,
294 2968, 2969, 2975, 2976, 2977, 2978, 2979, 3061, 3062, 3189,
295 3190, 3191, 3241, 3242, 3243, 3244, 3245, 3324, 3489, 3519,
296 3520, 3521, 3522, 3523, 3530, 3603, 3604, 3605, 3606, 3607,
297 3626, 3648, 12080, 12081, 12082, 12083, 12084, 12328, 12329, 12330,
298 12558, 12559, 12560, 12561, 12562, 12965, 12966, 12967, 12968, 12969,
299 22080, 22081, 22082, 22083, 22084, 22328, 22329, 22330, 22965, 22966,
300 22967, 22968, 22969, 32080, 32081, 32082, 32083, 32084, 32965, 32966,
301 32967, 32968, 32969
302};
303
304// as documented by nocash
305static const u16 libcrypt_sectors[16] = {
306 14105, 14231, 14485, 14579, 14649, 14899, 15056, 15130,
307 15242, 15312, 15378, 15628, 15919, 16031, 16101, 16167
308};
309
310int check_unsatisfied_libcrypt(void)
311{
312 const char *p = CdromId + 4;
08d9d257 313 u8 buf_sub[SUB_FRAMESIZE];
f3746eea 314 u16 id, key = 0;
08d9d257 315 u8 msf[3];
f3746eea 316 size_t i;
317
318 if (strncmp(CdromId, "SCE", 3) && strncmp(CdromId, "SLE", 3))
319 return 0;
320 while (*p == '0')
321 p++;
322 id = (u16)atoi(p);
323 for (i = 0; i < ARRAY_SIZE(libcrypt_ids); i++)
324 if (id == libcrypt_ids[i])
325 break;
326 if (i == ARRAY_SIZE(libcrypt_ids))
327 return 0;
328
329 // detected a protected game
08d9d257 330 lba2msf(libcrypt_sectors[0] + 150, &msf[0], &msf[1], &msf[2]);
331 if (!sbi_sectors && cdra_readSub(msf, buf_sub) != 0) {
f3746eea 332 SysPrintf("==================================================\n");
333 SysPrintf("LibCrypt game detected with missing SBI/subchannel\n");
334 SysPrintf("==================================================\n");
335 return 1;
336 }
337
338 if (sbi_sectors) {
339 // calculate key just for fun (we don't really need it)
340 for (i = 0; i < 16; i++)
341 if (CheckSBI(libcrypt_sectors[i] - 2*75))
342 key |= 1u << (15 - i);
343 }
344 if (key)
345 SysPrintf("%s, possible key=%04X\n", "LibCrypt detected", key);
346 else
347 SysPrintf("%s\n", "LibCrypt detected");
348 return 0;
349}