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