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