release r24
[pcsx_rearmed.git] / libpcsxcore / database.c
... / ...
CommitLineData
1#include "misc.h"
2#include "sio.h"
3#include "ppf.h"
4#include "new_dynarec/new_dynarec.h"
5#include "lightrec/plugin.h"
6
7/* It's duplicated from emu_if.c */
8#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
9
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
15static const char * const MemorycardHack_db[] =
16{
17 /* Lifeforce Tenka, also known as Codename Tenka */
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
28static const char * const gpu_slow_llist_db[] =
29{
30 /* Bomberman Fantasy Race */
31 "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823",
32 /* Crash Bash */
33 "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654",
34 /* Final Fantasy IV */
35 "SCES03840", "SLPM86028", "SLUS01360",
36 /* Point Blank - calibration cursor */
37 "SCED00287", "SCES00886", "SLUS00481",
38 /* Simple 1500 Series Vol. 57: The Meiro */
39 "SLPM86715",
40 /* Spot Goes to Hollywood */
41 "SLES00330", "SLPS00394", "SLUS00014",
42 /* Tiny Tank */
43 "SCES01338", "SCES02072", "SCES02072", "SCES02072", "SCES02072", "SCUS94427",
44 /* Vampire Hunter D */
45 "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138",
46};
47
48static const char * const gpu_centering_hack_db[] =
49{
50 /* Gradius Gaiden */
51 "SLPM86042", "SLPM86103", "SLPM87323",
52 /* Sexy Parodius */
53 "SLPM86009",
54};
55
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
62static const char * const dualshock_init_analog_hack_db[] =
63{
64 /* Formula 1 Championship Edition */
65 "SLUS00546",
66};
67
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),
81 HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
82 HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
83 HACK_ENTRY(gpu_timing1024, dualshock_timing1024_hack_db),
84 HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
85};
86
87static const struct
88{
89 int mult;
90 const char * const id[4];
91}
92cycle_multiplier_overrides[] =
93{
94 /* note: values are = (10000 / gui_option) */
95 /* Internal Section - fussy about timings */
96 { 202, { "SLPS01868" } },
97 /* Super Robot Taisen Alpha - on the edge with 175,
98 * changing memcard settings is enough to break/unbreak it */
99 { 190, { "SLPS02528", "SLPS02636" } },
100 /* Brave Fencer Musashi - cd sectors arrive too fast */
101 { 170, { "SLUS00726", "SLPS01490" } },
102#if defined(DRC_DISABLE) || defined(LIGHTREC) /* new_dynarec has a hack for this game */
103 /* Parasite Eve II - internal timer checks */
104 { 125, { "SLUS01042", "SLUS01055", "SLES02558", "SLES12558" } },
105#endif
106 /* Discworld Noir - audio skips if CPU runs too fast */
107 { 222, { "SLES01549", "SLES02063", "SLES02064" } },
108 /* Digimon World */
109 { 153, { "SLUS01032", "SLES02914" } },
110 /* Syphon Filter - reportedly hangs under unknown conditions */
111 { 169, { "SCUS94240" } },
112 /* Psychic Detective - some weird race condition in the game's cdrom code */
113 { 222, { "SLUS00165", "SLUS00166", "SLUS00167" } },
114 { 222, { "SLES00070", "SLES10070", "SLES20070" } },
115 /* Vib-Ribbon - cd timing issues (PAL+ari64drc only?) */
116 { 200, { "SCES02873" } },
117 /* Zero Divide - sometimes too fast */
118 { 200, { "SLUS00183", "SLES00159", "SLPS00083", "SLPM80008" } },
119};
120
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
150/* Function for automatic patching according to GameID. */
151void Apply_Hacks_Cdrom(void)
152{
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
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
175 /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
176 for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
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;
184 break;
185 }
186 }
187
188 /* Dynarec game-specific hacks */
189 new_dynarec_hacks_pergame = 0;
190 Config.cycle_multiplier_override = 0;
191
192 for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
193 {
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))
199 {
200 Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
201 new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
202 SysPrintf("using cycle_multiplier_override: %d\n",
203 Config.cycle_multiplier_override);
204 break;
205 }
206 }
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 }
218}
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}