|
| 1 | +/* |
| 2 | +# |
| 3 | +# DECKARD Configs |
| 4 | +#-------------------------- |
| 5 | +# Copyright 2023 krat0s. |
| 6 | +# |
| 7 | +*/ |
| 8 | + |
| 9 | +#include "include/opl.h" |
| 10 | +#include "include/xparam.h" |
| 11 | + |
| 12 | +char params_DCACHE_OFF[] = {'0', 'x', '1', '0', 0, '0', 0}; |
| 13 | +char params_CPU_DELAY[] = {'0', 'x', '6', 0, '0', 'x', '7', '8', '0', 0}; |
| 14 | + |
| 15 | + |
| 16 | +int CheckSpecialDiscXParamTitle(const char *title) |
| 17 | +{ |
| 18 | + /* |
| 19 | + See if we are dealing with any of the special titles so far. |
| 20 | + Special titles are the ones that have the param specified in the SYSTEM.CNF. |
| 21 | + To get that value one needs to get XPARAM entry from system.cnf and then verify its integrity. |
| 22 | + Since all special games are known already and to avoid the whole MD5 checking and everything let's just go the easy way and apply it. |
| 23 | + Param from the disc always overrides the internal ones so let's do it. |
| 24 | + PS2 special params from the disc do not apply on PS3/PS4. They instead look for XPARAM4 entry (no game ever found with that one). |
| 25 | + */ |
| 26 | + |
| 27 | + int result = 0; |
| 28 | + |
| 29 | + // Another Century's Episode 2 (Japan) |
| 30 | + result |= !strncmp("SLPS_256.23", title, 11); |
| 31 | + |
| 32 | + // Critical Velocity (Japan) |
| 33 | + result |= !strncmp("SLPS_255.32", title, 11); |
| 34 | + |
| 35 | + // Hissatsu Pachinko Station V11 (Japan) |
| 36 | + // Hissatsu Pachinko Station V11 - CR Gyaatoruzu (Japan) |
| 37 | + result |= !strncmp("SLPS_255.56", title, 11); |
| 38 | + |
| 39 | + // Matantei Loki Ragnarok - Mayouga - Ushinawareta Bishou (Japan) |
| 40 | + // NOTE: this game has same XPARAM values and hash as the game Ibara. |
| 41 | + // The md5 check for this does match but for Ibara does not. For sure that Ibara is just a user error due to it being leftover from this game. Both games are from Taito and Ibara came much later. |
| 42 | + result |= !strncmp("SLPM_661.41", title, 11); |
| 43 | + |
| 44 | + // Sega Ages 2500 Series Vol. 23 - Sega Memorial Selection (Japan) |
| 45 | + result |= !strncmp("SLPM_627.09", title, 11); |
| 46 | + |
| 47 | + // Shin Bakusou Dekotora Densetsu - Tenka Touitsu Choujou Kessen (Japan) (Spike the Best) |
| 48 | + result |= !strncmp("SLPM_663.87", title, 11); |
| 49 | + |
| 50 | + return result; |
| 51 | +} |
| 52 | + |
| 53 | + |
| 54 | +void ApplyExtraXParamTitle(const char *title, char *params) |
| 55 | +{ |
| 56 | + int result = 0; |
| 57 | + |
| 58 | + // Kaidou: Touge no Densetsu (Japan) |
| 59 | + // This config was added twice in newer XPARAM. |
| 60 | + result |= !strncmp("SLPM_660.22", title, 11); |
| 61 | + |
| 62 | + // Duel Masters: Birth of Super Dragon (Japan) |
| 63 | + result |= !strncmp("SLPM_658.82", title, 11); |
| 64 | + |
| 65 | + // Shin Bakusou Dekotora Densetsu: Tenka Touitsu Choujou Kessen (Japan) |
| 66 | + result |= !strncmp("SLPM_658.16", title, 11); |
| 67 | + |
| 68 | + // Shutokou Battle 01 (Japan) |
| 69 | + result |= !strncmp("SLPM_653.08", title, 11); |
| 70 | + |
| 71 | + // Initial D: Special Stage (Japan) |
| 72 | + result |= !strncmp("SLPM_653.08", title, 11); |
| 73 | + |
| 74 | + // Bakusou Dekotora Densetsu: Otoko Hanamichi Yume Roman (Japan) |
| 75 | + result |= !strncmp("SLPM_652.34", title, 11); |
| 76 | + |
| 77 | + if (result) { |
| 78 | + // All of them are new added ones and all use 0x10 0 (DCACHE OFF ) |
| 79 | + memcpy(¶ms[12], params_DCACHE_OFF, 7); |
| 80 | + SifLoadModule("rom0:XPARAM", 19, params); |
| 81 | + return; |
| 82 | + } |
| 83 | + |
| 84 | + |
| 85 | + result = 0; |
| 86 | + |
| 87 | + // This new one was for entries already there that had DCACHE off but now even have a CPU_DELAY param added to it. |
| 88 | + |
| 89 | + // Tekken 5 |
| 90 | + result |= !strncmp("SCAJ_201.25", title, 11); |
| 91 | + result |= !strncmp("SCAJ_201.26", title, 11); |
| 92 | + result |= !strncmp("SCKA_200.49", title, 11); |
| 93 | + result |= !strncmp("SLPS_255.10", title, 11); |
| 94 | + result |= !strncmp("SLUS_210.59", title, 11); |
| 95 | + |
| 96 | + if (result) { |
| 97 | + memcpy(¶ms[12], params_CPU_DELAY, 10); |
| 98 | + SifLoadModule("rom0:XPARAM", 22, params); |
| 99 | + return; |
| 100 | + } |
| 101 | + |
| 102 | + // One single game was then added both cache off and CPU delay. |
| 103 | + if (!strncmp("SCES_532.02", title, 11)) { |
| 104 | + |
| 105 | + /* |
| 106 | + Tekken 5 (Australia) |
| 107 | + Tekken 5 would have the cache off but not the CPU delay, however, this regional release for the first bios of 750xx had neither the cache nor the delay making it run worse. |
| 108 | + */ |
| 109 | + memcpy(¶ms[12], params_DCACHE_OFF, 7); |
| 110 | + SifLoadModule("rom0:XPARAM", 19, params); |
| 111 | + |
| 112 | + memcpy(¶ms[12], params_CPU_DELAY, 10); |
| 113 | + SifLoadModule("rom0:XPARAM", 22, params); |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +void ResetDeckardXParams() |
| 118 | +{ |
| 119 | + /* |
| 120 | + This is needed in the case of IGR because the previous game might have changed XPARAMS and the new game might need the default one. |
| 121 | + */ |
| 122 | + |
| 123 | + /* |
| 124 | + Check to see if this is a DECKARD machine or not. |
| 125 | + Bit 31 of GM_IF is for the IOP type. |
| 126 | + 0 Regular IOP |
| 127 | + 1 DECKARD IOP |
| 128 | + */ |
| 129 | + if ((*GM_IF & GM_IOP_TYPE) == 0) |
| 130 | + return; |
| 131 | + |
| 132 | + int fd; |
| 133 | + char params[30]; |
| 134 | + memset(params, 0, 30); |
| 135 | + strncpy(params, "SLPS_123.45", 11); |
| 136 | + params[11] = 0; // Terminate param string. |
| 137 | + |
| 138 | + // For PS3/4 emu we skip default. |
| 139 | + fd = open("rom0:XPARAM2", O_RDONLY); |
| 140 | + if (fd >= 0) { |
| 141 | + close(fd); |
| 142 | + return; |
| 143 | + } |
| 144 | + |
| 145 | + u32 default_values[] = { |
| 146 | + 0x01F4, // PARAM_MDEC_DELAY_CYCLE |
| 147 | + 0x07D0, // PARAM_SPU_INT_DELAY_LIMIT |
| 148 | + 0x0023, // PARAM_SPU_INT_DELAY_PPC_COEFF |
| 149 | + 0x07D0, // PARAM_SPU2_INT_DELAY_LIMIT |
| 150 | + 0x0014, // PARAM_SPU2_INT_DELAY_PPC_COEFF |
| 151 | + 0x0000, // PARAM_DMAC_CH10_INT_DELAY |
| 152 | + 0x0001, // PARAM_CPU_DELAY |
| 153 | + 0x0020, // PARAM_SPU_DMA_WAIT_LIMIT |
| 154 | + 0x0000, // PARAM_GPU_DMA_WAIT_LIMIT |
| 155 | + 0x0000, // PARAM_DMAC_CH10_INT_DELAY_DPC |
| 156 | + 0x0000, // PARAM_CPU_DELAY_DPC |
| 157 | + 0x0000, // PARAM_USB_DELAYED_INT_ENABLE |
| 158 | + 0x0000, // PARAM_TIMER_LOAD_DELAY |
| 159 | + 0x229C, // PARAM_SIO0_DTR_SCK_DELAY |
| 160 | + 0x06EC, // PARAM_SIO0_DSR_SCK_DELAY_C |
| 161 | + 0x06EC, // PARAM_SIO0_DSR_SCK_DELAY_M |
| 162 | + 0x0001, // PARAM_MIPS_DCACHE_ON |
| 163 | + 0x0090 // PARAM_CACHE_FLASH_CHANNELS |
| 164 | + }; |
| 165 | + |
| 166 | + fd = open("rom0:XPARAM", O_RDONLY); |
| 167 | + if (fd >= 0) { |
| 168 | + close(fd); |
| 169 | + |
| 170 | + // Reset all the params to default. |
| 171 | + int i; |
| 172 | + for (i = 0; i < 0x12; i++) { |
| 173 | + sprintf(¶ms[12], "0X%02X", i); |
| 174 | + params[16] = 0; |
| 175 | + sprintf(¶ms[17], "0X%08X", default_values[i]); |
| 176 | + params[27] = 0; |
| 177 | + SifLoadModule("rom0:XPARAM", 28, params); |
| 178 | + } |
| 179 | + } |
| 180 | +} |
| 181 | + |
| 182 | +// Note TITLE must be as *IS*, not uppercase or anything. |
| 183 | +void ApplyDeckardXParam(const char *title) |
| 184 | +{ |
| 185 | + int fd; |
| 186 | + |
| 187 | + // Safety check |
| 188 | + if (title == NULL) |
| 189 | + return; |
| 190 | + |
| 191 | + char params[30]; |
| 192 | + memset(params, 0, 30); |
| 193 | + strncpy(params, title, 11); |
| 194 | + params[11] = 0; // Terminate param string. |
| 195 | + |
| 196 | + /* |
| 197 | + Check to see if this is a DECKARD machine or not. |
| 198 | + Bit 31 of GM_IF is for the IOP type. |
| 199 | + 0 Regular IOP |
| 200 | + 1 DECKARD IOP |
| 201 | + */ |
| 202 | + if ((*GM_IF & GM_IOP_TYPE) == 0) |
| 203 | + return; |
| 204 | + |
| 205 | + /* |
| 206 | + See if this PS3/4 emu and apply the config to it. |
| 207 | + PS3 and PS4 are missing the regular param file and only have XPARAM2 in them. |
| 208 | + */ |
| 209 | + fd = open("rom0:XPARAM2", O_RDONLY); |
| 210 | + if (fd >= 0) { |
| 211 | + close(fd); |
| 212 | + SifLoadModule("rom0:XPARAM2", 12, params); |
| 213 | + return; |
| 214 | + } |
| 215 | + |
| 216 | + |
| 217 | + // See if it's the regular PS2 one. |
| 218 | + fd = open("rom0:XPARAM", O_RDONLY); |
| 219 | + if (fd >= 0) { |
| 220 | + close(fd); |
| 221 | + |
| 222 | + if (CheckSpecialDiscXParamTitle(title)) { |
| 223 | + // All of them use 0x10 0 (DCACHE OFF) |
| 224 | + // Params are sent as direct string null separated. |
| 225 | + memcpy(¶ms[12], params_DCACHE_OFF, 7); |
| 226 | + SifLoadModule("rom0:XPARAM", 19, params); |
| 227 | + return; |
| 228 | + } |
| 229 | + |
| 230 | + // Load the default configs found in the XPARAM module. |
| 231 | + SifLoadModule("rom0:XPARAM", 12, params); |
| 232 | + |
| 233 | + /* |
| 234 | + There is a special case here, in all the PS2 bios there are only two XPARAM files. |
| 235 | + The first one is in bios 2.20 with the date 20050620 and has 272 configs in total. |
| 236 | + Starting with 2.20 date 20060210 and all later bios up to the final one there is one single XPARAM which has 286 configs. |
| 237 | + 14 configs were added and the previous ones were unchanged. |
| 238 | + Within those 14 configs, some are for new games, the rest is more params for games that already had one. |
| 239 | + If we are running into this early bios we will get bad compatibility so let's make it uniform and reapply the extra configs just in case because they cause no harm. |
| 240 | + */ |
| 241 | + |
| 242 | + ApplyExtraXParamTitle(title, params); |
| 243 | + |
| 244 | + return; |
| 245 | + } |
| 246 | +} |
0 commit comments