3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 cheat_type cheats[MAX_CHEATS];
25 void decrypt_gsa_code(u32 *address_ptr, u32 *value_ptr, cheat_variant_enum
29 u32 address = *address_ptr;
30 u32 value = *value_ptr;
35 0x09f4fbbd, 0x9681884a, 0x352027e9, 0xf3dee5a7
39 0x7aa9648f, 0x7fae6994, 0xc0efaad5, 0x42712c57
43 if(cheat_variant == CHEAT_TYPE_GAMESHARK_V1)
48 for(i = 0; i < 32; i++)
50 value -= ((address << 4) + seeds[2]) ^ (address + r) ^
51 ((address >> 5) + seeds[3]);
52 address -= ((value << 4) + seeds[0]) ^ (value + r) ^
53 ((value >> 5) + seeds[1]);
57 *address_ptr = address;
61 void add_cheats(char *cheats_filename)
64 char current_line[256];
69 u32 cheat_name_length;
70 cheat_variant_enum current_cheat_variant;
74 cheats_file = fopen(cheats_filename, "rb");
78 while(fgets(current_line, 256, cheats_file))
80 // Get the header line first
81 name_ptr = strchr(current_line, ' ');
88 if(!strcasecmp(current_line, "gameshark_v1") ||
89 !strcasecmp(current_line, "gameshark_v2") ||
90 !strcasecmp(current_line, "PAR_v1") ||
91 !strcasecmp(current_line, "PAR_v2"))
93 current_cheat_variant = CHEAT_TYPE_GAMESHARK_V1;
97 if(!strcasecmp(current_line, "gameshark_v3") ||
98 !strcasecmp(current_line, "PAR_v3"))
100 current_cheat_variant = CHEAT_TYPE_GAMESHARK_V3;
104 current_cheat_variant = CHEAT_TYPE_INVALID;
107 if(current_cheat_variant != CHEAT_TYPE_INVALID)
109 strncpy(cheats[num_cheats].cheat_name, name_ptr, CHEAT_NAME_LENGTH - 1);
110 cheats[num_cheats].cheat_name[CHEAT_NAME_LENGTH - 1] = 0;
111 cheat_name_length = strlen(cheats[num_cheats].cheat_name);
112 if(cheat_name_length &&
113 ((cheats[num_cheats].cheat_name[cheat_name_length - 1] == '\n') ||
114 (cheats[num_cheats].cheat_name[cheat_name_length - 1] == '\r')))
116 cheats[num_cheats].cheat_name[cheat_name_length - 1] = 0;
120 if(cheat_name_length &&
121 cheats[num_cheats].cheat_name[cheat_name_length - 1] == '\r')
123 cheats[num_cheats].cheat_name[cheat_name_length - 1] = 0;
126 cheats[num_cheats].cheat_variant = current_cheat_variant;
127 cheat_code_ptr = cheats[num_cheats].cheat_codes;
130 while(fgets(current_line, 256, cheats_file))
132 if(strlen(current_line) < 3)
135 sscanf(current_line, "%08x %08x", &address, &value);
137 decrypt_gsa_code(&address, &value, current_cheat_variant);
139 cheat_code_ptr[0] = address;
140 cheat_code_ptr[1] = value;
146 cheats[num_cheats].num_cheat_lines = num_cheat_lines;
156 void process_cheat_gs1(cheat_type *cheat)
159 u32 *code_ptr = cheat->cheat_codes;
163 for(i = 0; i < cheat->num_cheat_lines; i++)
165 address = code_ptr[0];
170 cheat_opcode = address >> 28;
171 address &= 0xFFFFFFF;
176 write_memory8(address, value);
180 write_memory16(address, value);
184 write_memory32(address, value);
189 u32 num_addresses = address & 0xFFFF;
190 u32 address1, address2;
193 for(i2 = 0; i2 < num_addresses; i2++)
195 address1 = code_ptr[0];
196 address2 = code_ptr[1];
200 write_memory32(address1, value);
202 write_memory32(address2, value);
207 // ROM patch not supported yet
211 // GS button down not supported yet
215 // Reencryption (DEADFACE) not supported yet
217 if(read_memory16(address) != (value & 0xFFFF))
225 if(read_memory16(value & 0xFFFFFFF) != (address & 0xFFFF))
227 u32 skip = ((address >> 16) & 0x03);
228 code_ptr += skip * 2;
233 // Hook routine not supported yet (not important??)
240 // These are especially incomplete.
242 void process_cheat_gs3(cheat_type *cheat)
245 u32 *code_ptr = cheat->cheat_codes;
249 for(i = 0; i < cheat->num_cheat_lines; i++)
251 address = code_ptr[0];
256 cheat_opcode = address >> 28;
257 address &= 0xFFFFFFF;
262 cheat_opcode = address >> 24;
263 address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
269 u32 iterations = value >> 24;
274 for(i2 = 0; i2 <= iterations; i2++, address++)
276 write_memory8(address, value);
283 u32 iterations = value >> 16;
288 for(i2 = 0; i2 <= iterations; i2++, address += 2)
290 write_memory16(address, value);
296 write_memory32(address, value);
302 cheat_opcode = address >> 24;
303 address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
308 address = read_memory32(address) + (value >> 24);
309 write_memory8(address, value & 0xFF);
313 address = read_memory32(address) + ((value >> 16) * 2);
314 write_memory16(address, value & 0xFFFF);
318 address = read_memory32(address);
319 write_memory32(address, value);
326 cheat_opcode = address >> 24;
327 address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
332 value = (value & 0xFF) + read_memory8(address);
333 write_memory8(address, value);
337 value = (value & 0xFFFF) + read_memory16(address);
338 write_memory16(address, value);
342 value = value + read_memory32(address);
343 write_memory32(address, value);
349 cheat_opcode = address >> 24;
350 address = (address & 0xFFFFFF) + 0x4000000;
355 write_memory16(address, value);
359 write_memory32(address, value);
368 void process_cheats()
372 for(i = 0; i < num_cheats; i++)
374 if(cheats[i].cheat_active)
376 switch(cheats[i].cheat_variant)
378 case CHEAT_TYPE_GAMESHARK_V1:
379 process_cheat_gs1(cheats + i);
382 case CHEAT_TYPE_GAMESHARK_V3:
383 process_cheat_gs3(cheats + i);