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