an alt hack for Judge Dredd
[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
6/* It's duplicated from emu_if.c */
7#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
8
9static 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
16static const char * const cdr_read_hack_db[] =
17{
18 /* T'ai Fu - Wrath of the Tiger */
19 "SLUS00787",
20};
21
22static 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
40static const char * const gpu_busy_hack_db[] =
41{
42 /* ToHeart (Japan) */
43 "SLPS01919", "SLPS01920",
44};
45
46static const char * const gpu_centering_hack_db[] =
47{
48 /* Gradius Gaiden */
49 "SLPM86042", "SLPM86103", "SLPM87323",
50 /* Sexy Parodius */
51 "SLPM86009",
52};
53
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
60static const char * const dualshock_init_analog_hack_db[] =
61{
62 /* Formula 1 Championship Edition */
63 "SLUS00546",
64};
65
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),
79 HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
80 HACK_ENTRY(gpu_busy, gpu_busy_hack_db),
81 HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
82 HACK_ENTRY(gpu_timing1024, dualshock_timing1024_hack_db),
83 HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
84};
85
86static const struct
87{
88 int mult;
89 const char * const id[4];
90}
91cycle_multiplier_overrides[] =
92{
93 /* note: values are = (10000 / gui_option) */
94 /* Internal Section - fussy about timings */
95 { 202, { "SLPS01868" } },
96 /* Super Robot Taisen Alpha - on the edge with 175,
97 * changing memcard settings is enough to break/unbreak it */
98 { 190, { "SLPS02528", "SLPS02636" } },
99 /* Brave Fencer Musashi - cd sectors arrive too fast */
100 { 170, { "SLUS00726", "SLPS01490" } },
101#if defined(DRC_DISABLE) || defined(LIGHTREC) /* new_dynarec has a hack for this game */
102 /* Parasite Eve II - internal timer checks */
103 { 125, { "SLUS01042", "SLUS01055", "SLES02558", "SLES12558" } },
104#endif
105 /* Discworld Noir - audio skips if CPU runs too fast */
106 { 222, { "SLES01549", "SLES02063", "SLES02064" } },
107 /* Digimon World */
108 { 153, { "SLUS01032", "SLES02914" } },
109 /* Syphon Filter - reportedly hangs under unknown conditions */
110 { 169, { "SCUS94240" } },
111 /* Psychic Detective - some weird race condition in the game's cdrom code */
112 { 222, { "SLUS00165", "SLUS00166", "SLUS00167" } },
113 { 222, { "SLES00070", "SLES10070", "SLES20070" } },
114 /* Zero Divide - sometimes too fast */
115 { 200, { "SLUS00183", "SLES00159", "SLPS00083", "SLPM80008" } },
116};
117
118/* Function for automatic patching according to GameID. */
119void Apply_Hacks_Cdrom(void)
120{
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
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
143 /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
144 for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
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;
152 break;
153 }
154 }
155
156 /* Dynarec game-specific hacks */
157 new_dynarec_hacks_pergame = 0;
158 Config.cycle_multiplier_override = 0;
159
160 for (i = 0; i < ARRAY_SIZE(cycle_multiplier_overrides); i++)
161 {
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))
167 {
168 Config.cycle_multiplier_override = cycle_multiplier_overrides[i].mult;
169 new_dynarec_hacks_pergame |= NDHACK_OVERRIDE_CYCLE_M;
170 SysPrintf("using cycle_multiplier_override: %d\n",
171 Config.cycle_multiplier_override);
172 break;
173 }
174 }
175}
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}