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