1 /*  Cheat Support for PCSX-Reloaded
2  *  Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA
17  */
18 
19 #include "psxcommon.h"
20 #include "r3000a.h"
21 #include "psxmem.h"
22 
23 #include "cheat.h"
24 
25 Cheat *Cheats = NULL;
26 int NumCheats = 0;
27 int NumCheatsAllocated = 0;
28 
29 CheatCode *CheatCodes = NULL;
30 int NumCodes = 0;
31 int NumCodesAllocated = 0;
32 
33 s8 *prevM = NULL;
34 u32 *SearchResults = NULL;
35 int NumSearchResults = 0;
36 static int NumSearchResultsAllocated = 0;
37 
38 #define ALLOC_INCREMENT		100
39 
ClearAllCheats()40 void ClearAllCheats() {
41 	int i;
42 
43 	if (Cheats != NULL) {
44 		for (i = 0; i < NumCheats; i++) {
45 			free(Cheats[i].Descr);
46 		}
47 		free(Cheats);
48 	}
49 
50 	Cheats = NULL;
51 	NumCheats = 0;
52 	NumCheatsAllocated = 0;
53 
54 	if (CheatCodes != NULL) {
55 		free(CheatCodes);
56 	}
57 
58 	CheatCodes = NULL;
59 	NumCodes = 0;
60 	NumCodesAllocated = 0;
61 }
62 
63 // load cheats from the specific filename
LoadCheats(const char * filename)64 void LoadCheats(const char *filename) {
65 	FILE				*fp;
66 	char				buf[256];
67 	int					count = 0;
68 	unsigned int		t1, t2;
69 
70 	fp = fopen(filename, "r");
71 	if (fp == NULL) {
72 		return;
73 	}
74 
75 	ClearAllCheats();
76 
77 	while (fgets(buf, 255, fp) != NULL) {
78 		buf[255] = '\0';
79 		trim(buf);
80 
81 		// Skip comment or blank lines
82 		if (buf[0] == '#' || buf[0] == ';' || buf[0] == '/' || buf[0] == '\"' || buf[0] == '\0')
83 			continue;
84 
85 		if (buf[0] == '[' && buf[strlen(buf) - 1] == ']') {
86 			if (NumCheats > 0)
87 				Cheats[NumCheats - 1].n = count;
88 
89 			if (NumCheats >= NumCheatsAllocated) {
90 				NumCheatsAllocated += ALLOC_INCREMENT;
91 
92 				if (Cheats == NULL) {
93 					assert(NumCheats == 0);
94 					assert(NumCheatsAllocated == ALLOC_INCREMENT);
95 					Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
96 				} else {
97 					Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
98 				}
99 			}
100 
101 			buf[strlen(buf) - 1] = '\0';
102 			count = 0;
103 
104 			if (buf[1] == '*') {
105 				Cheats[NumCheats].Descr = strdup(buf + 2);
106 				Cheats[NumCheats].Enabled = 1;
107 			} else {
108 				Cheats[NumCheats].Descr = strdup(buf + 1);
109 				Cheats[NumCheats].Enabled = 0;
110 			}
111 			Cheats[NumCheats].WasEnabled = 0;
112 
113 			Cheats[NumCheats].First = NumCodes;
114 
115 			NumCheats++;
116 			continue;
117 		}
118 
119 		if (NumCheats <= 0)
120 			continue;
121 
122 		if (NumCodes >= NumCodesAllocated) {
123 			NumCodesAllocated += ALLOC_INCREMENT;
124 
125 			if (CheatCodes == NULL) {
126 				assert(NumCodes == 0);
127 				assert(NumCodesAllocated == ALLOC_INCREMENT);
128 				CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
129 			} else {
130 				CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
131 			}
132 		}
133 
134 		sscanf(buf, "%x %x", &t1, &t2);
135 
136 		CheatCodes[NumCodes].Addr = t1;
137 		CheatCodes[NumCodes].Val = t2;
138 
139 		NumCodes++;
140 		count++;
141 	}
142 
143 	if (NumCheats > 0)
144 		Cheats[NumCheats - 1].n = count;
145 
146 	fclose(fp);
147 
148 	SysPrintf(_("Cheats loaded from: %s\n"), filename);
149 }
150 
151 // save all cheats to the specified filename
SaveCheats(const char * filename)152 void SaveCheats(const char *filename) {
153 	FILE		*fp;
154 	int			i, j;
155 
156 	fp = fopen(filename, "w");
157 	if (fp == NULL) {
158 		return;
159 	}
160 
161 	for (i = 0; i < NumCheats; i++) {
162 		// write the description
163 		if (Cheats[i].Enabled)
164 			fprintf(fp, "[*%s]\n", Cheats[i].Descr);
165 		else
166 			fprintf(fp, "[%s]\n", Cheats[i].Descr);
167 
168 		// write all cheat codes
169 		for (j = 0; j < Cheats[i].n; j++) {
170 			fprintf(fp, "%.8X %.4X\n",
171 				CheatCodes[Cheats[i].First + j].Addr,
172 				CheatCodes[Cheats[i].First + j].Val);
173 		}
174 
175 		fprintf(fp, "\n");
176 	}
177 
178 	fclose(fp);
179 
180 	SysPrintf(_("Cheats saved to: %s\n"), filename);
181 }
182 
183 // apply all enabled cheats
ApplyCheats()184 void ApplyCheats() {
185 	int		i, j, k, endindex;
186 	int		was_enabled;
187 
188 	for (i = 0; i < NumCheats; i++) {
189 		was_enabled = Cheats[i].WasEnabled;
190 		if (!Cheats[i].Enabled) {
191 			if (!Cheats[i].WasEnabled)
192 				continue;
193 		}
194 		Cheats[i].WasEnabled = Cheats[i].Enabled;
195 
196 		// process all cheat codes
197 		endindex = Cheats[i].First + Cheats[i].n;
198 
199 		for (j = Cheats[i].First; j < endindex; j++) {
200 			u8		type = (uint8_t)(CheatCodes[j].Addr >> 24);
201 			u32		addr = (CheatCodes[j].Addr & 0x001FFFFF);
202 			u16		val = CheatCodes[j].Val;
203 			u32		taddr;
204 
205 			if (!was_enabled) {
206 				switch (type) {
207 					case CHEAT_CONST16:
208 						CheatCodes[j].OldVal = psxMu16(addr);
209 						break;
210 					case CHEAT_CONST8:
211 						CheatCodes[j].OldVal = psxMu8(addr);
212 						break;
213 				}
214 			}
215 			else if (!Cheats[i].Enabled) {
216 				val = CheatCodes[j].OldVal;
217 				if (type != CHEAT_CONST16 && type != CHEAT_CONST8)
218 					continue;
219 			}
220 
221 			switch (type) {
222 				case CHEAT_CONST8:
223 					psxMu8ref(addr) = (u8)val;
224 					break;
225 
226 				case CHEAT_CONST16:
227 					psxMu16ref(addr) = SWAPu16(val);
228 					break;
229 
230 				case CHEAT_INC16:
231 					psxMu16ref(addr) = SWAPu16(psxMu16(addr) + val);
232 					break;
233 
234 				case CHEAT_DEC16:
235 					psxMu16ref(addr) = SWAPu16(psxMu16(addr) - val);
236 					break;
237 
238 				case CHEAT_INC8:
239 					psxMu8ref(addr) += (u8)val;
240 					break;
241 
242 				case CHEAT_DEC8:
243 					psxMu8ref(addr) -= (u8)val;
244 					break;
245 
246 				case CHEAT_SLIDE:
247 					j++;
248 					if (j >= endindex)
249 						break;
250 
251 					type = (uint8_t)(CheatCodes[j].Addr >> 24);
252 					taddr = (CheatCodes[j].Addr & 0x001FFFFF);
253 					val = CheatCodes[j].Val;
254 
255 					if (type == CHEAT_CONST8) {
256 						for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
257 							psxMu8ref(taddr) = (u8)val;
258 							taddr += (s8)(addr & 0xFF);
259 							val += (s8)(CheatCodes[j - 1].Val & 0xFF);
260 						}
261 					}
262 					else if (type == CHEAT_CONST16) {
263 						for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
264 							psxMu16ref(taddr) = SWAPu16(val);
265 							taddr += (s8)(addr & 0xFF);
266 							val += (s8)(CheatCodes[j - 1].Val & 0xFF);
267 						}
268 					}
269 					break;
270 
271 				case CHEAT_MEMCPY:
272 					j++;
273 					if (j >= endindex)
274 						break;
275 
276 					taddr = (CheatCodes[j].Addr & 0x001FFFFF);
277 					for (k = 0; k < val; k++) {
278 						psxMu8ref(taddr + k) = PSXMu8(addr + k);
279 					}
280 					break;
281 
282 				case CHEAT_EQU8:
283 					if (PSXMu8(addr) != (u8)val)
284 						j++; // skip the next code
285 					break;
286 
287 				case CHEAT_NOTEQU8:
288 					if (PSXMu8(addr) == (u8)val)
289 						j++; // skip the next code
290 					break;
291 
292 				case CHEAT_LESSTHAN8:
293 					if (PSXMu8(addr) >= (u8)val)
294 						j++; // skip the next code
295 					break;
296 
297 				case CHEAT_GREATERTHAN8:
298 					if (PSXMu8(addr) <= (u8)val)
299 						j++; // skip the next code
300 					break;
301 
302 				case CHEAT_EQU16:
303 					if (PSXMu16(addr) != val)
304 						j++; // skip the next code
305 					break;
306 
307 				case CHEAT_NOTEQU16:
308 					if (PSXMu16(addr) == val)
309 						j++; // skip the next code
310 					break;
311 
312 				case CHEAT_LESSTHAN16:
313 					if (PSXMu16(addr) >= val)
314 						j++; // skip the next code
315 					break;
316 
317 				case CHEAT_GREATERTHAN16:
318 					if (PSXMu16(addr) <= val)
319 						j++; // skip the next code
320 					break;
321 			}
322 		}
323 	}
324 }
325 
AddCheat(const char * descr,char * code)326 int AddCheat(const char *descr, char *code) {
327 	int c = 1;
328 	char *p1, *p2;
329 
330 	if (NumCheats >= NumCheatsAllocated) {
331 		NumCheatsAllocated += ALLOC_INCREMENT;
332 
333 		if (Cheats == NULL) {
334 			assert(NumCheats == 0);
335 			assert(NumCheatsAllocated == ALLOC_INCREMENT);
336 			Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
337 		}
338 		else {
339 			Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
340 		}
341 	}
342 
343 	Cheats[NumCheats].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
344 	Cheats[NumCheats].Enabled = 0;
345 	Cheats[NumCheats].WasEnabled = 0;
346 	Cheats[NumCheats].First = NumCodes;
347 	Cheats[NumCheats].n = 0;
348 
349 	p1 = code;
350 	p2 = code;
351 
352 	while (c) {
353 		unsigned int t1, t2;
354 
355 		while (*p2 != '\n' && *p2 != '\0')
356 			p2++;
357 
358 		if (*p2 == '\0')
359 			c = 0;
360 
361 		*p2 = '\0';
362 		p2++;
363 
364 		t1 = 0;
365 		t2 = 0;
366 		sscanf(p1, "%x %x", &t1, &t2);
367 
368 		if (t1 > 0x10000000) {
369 			if (NumCodes >= NumCodesAllocated) {
370 				NumCodesAllocated += ALLOC_INCREMENT;
371 
372 				if (CheatCodes == NULL) {
373 					assert(NumCodes == 0);
374 					assert(NumCodesAllocated == ALLOC_INCREMENT);
375 					CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
376 				}
377 				else {
378 					CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
379 				}
380 			}
381 
382 			CheatCodes[NumCodes].Addr = t1;
383 			CheatCodes[NumCodes].Val = t2;
384 			NumCodes++;
385 			Cheats[NumCheats].n++;
386 		}
387 
388 		p1 = p2;
389 	}
390 
391 	if (Cheats[NumCheats].n == 0) {
392 		return -1;
393 	}
394 
395 	NumCheats++;
396 	return 0;
397 }
398 
RemoveCheat(int index)399 void RemoveCheat(int index) {
400 	assert(index >= 0 && index < NumCheats);
401 
402 	free(Cheats[index].Descr);
403 
404 	while (index < NumCheats - 1) {
405 		Cheats[index] = Cheats[index + 1];
406 		index++;
407 	}
408 
409 	NumCheats--;
410 }
411 
EditCheat(int index,const char * descr,char * code)412 int EditCheat(int index, const char *descr, char *code) {
413 	int c = 1;
414 	int prev = NumCodes;
415 	char *p1, *p2;
416 
417 	assert(index >= 0 && index < NumCheats);
418 
419 	p1 = code;
420 	p2 = code;
421 
422 	while (c) {
423 		unsigned int t1, t2;
424 
425 		while (*p2 != '\n' && *p2 != '\0')
426 			p2++;
427 
428 		if (*p2 == '\0')
429 			c = 0;
430 
431 		*p2 = '\0';
432 		p2++;
433 
434 		t1 = 0;
435 		t2 = 0;
436 		sscanf(p1, "%x %x", &t1, &t2);
437 
438 		if (t1 > 0x10000000) {
439 			if (NumCodes >= NumCodesAllocated) {
440 				NumCodesAllocated += ALLOC_INCREMENT;
441 
442 				if (CheatCodes == NULL) {
443 					assert(NumCodes == 0);
444 					assert(NumCodesAllocated == ALLOC_INCREMENT);
445 					CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
446 				}
447 				else {
448 					CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
449 				}
450 			}
451 
452 			CheatCodes[NumCodes].Addr = t1;
453 			CheatCodes[NumCodes].Val = t2;
454 			NumCodes++;
455 		}
456 
457 		p1 = p2;
458 	}
459 
460 	if (NumCodes == prev) {
461 		return -1;
462 	}
463 
464 	free(Cheats[index].Descr);
465 	Cheats[index].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
466 	Cheats[index].First = prev;
467 	Cheats[index].n = NumCodes - prev;
468 
469 	return 0;
470 }
471 
FreeCheatSearchResults()472 void FreeCheatSearchResults() {
473 	if (SearchResults != NULL) {
474 		free(SearchResults);
475 	}
476 	SearchResults = NULL;
477 
478 	NumSearchResults = 0;
479 	NumSearchResultsAllocated = 0;
480 }
481 
FreeCheatSearchMem()482 void FreeCheatSearchMem() {
483 	if (prevM != NULL) {
484 		free(prevM);
485 	}
486 	prevM = NULL;
487 }
488 
CheatSearchBackupMemory()489 void CheatSearchBackupMemory() {
490 	if (prevM != NULL) {
491 		memcpy(prevM, psxM, 0x200000);
492 	}
493 }
494 
CheatSearchInitBackupMemory()495 static void CheatSearchInitBackupMemory() {
496 	if (prevM == NULL) {
497 		prevM = (s8 *)malloc(0x200000);
498 		CheatSearchBackupMemory();
499 	}
500 }
501 
CheatSearchAddResult(u32 addr)502 static void CheatSearchAddResult(u32 addr) {
503 	if (NumSearchResults >= NumSearchResultsAllocated) {
504 		NumSearchResultsAllocated += ALLOC_INCREMENT;
505 
506 		if (SearchResults == NULL) {
507 			SearchResults = (u32 *)malloc(sizeof(u32) * NumSearchResultsAllocated);
508 		}
509 		else {
510 			SearchResults = (u32 *)realloc(SearchResults, sizeof(u32) * NumSearchResultsAllocated);
511 		}
512 	}
513 
514 	SearchResults[NumSearchResults++] = addr;
515 }
516 
CheatSearchEqual8(u8 val)517 void CheatSearchEqual8(u8 val) {
518 	u32 i, j;
519 
520 	CheatSearchInitBackupMemory();
521 
522 	if (SearchResults == NULL) {
523 		// search the whole memory
524 		for (i = 0; i < 0x200000; i++) {
525 			if (PSXMu8(i) == val) {
526 				CheatSearchAddResult(i);
527 			}
528 		}
529 	}
530 	else {
531 		// only search within the previous results
532 		j = 0;
533 
534 		for (i = 0; i < NumSearchResults; i++) {
535 			if (PSXMu8(SearchResults[i]) == val) {
536 				SearchResults[j++] = SearchResults[i];
537 			}
538 		}
539 
540 		NumSearchResults = j;
541 	}
542 }
543 
CheatSearchEqual16(u16 val)544 void CheatSearchEqual16(u16 val) {
545 	u32 i, j;
546 
547 	CheatSearchInitBackupMemory();
548 
549 	if (SearchResults == NULL) {
550 		// search the whole memory
551 		for (i = 0; i < 0x200000; i += 2) {
552 			if (PSXMu16(i) == val) {
553 				CheatSearchAddResult(i);
554 			}
555 		}
556 	}
557 	else {
558 		// only search within the previous results
559 		j = 0;
560 
561 		for (i = 0; i < NumSearchResults; i++) {
562 			if (PSXMu16(SearchResults[i]) == val) {
563 				SearchResults[j++] = SearchResults[i];
564 			}
565 		}
566 
567 		NumSearchResults = j;
568 	}
569 }
570 
CheatSearchEqual32(u32 val)571 void CheatSearchEqual32(u32 val) {
572 	u32 i, j;
573 
574 	CheatSearchInitBackupMemory();
575 
576 	if (SearchResults == NULL) {
577 		// search the whole memory
578 		for (i = 0; i < 0x200000; i += 4) {
579 			if (PSXMu32(i) == val) {
580 				CheatSearchAddResult(i);
581 			}
582 		}
583 	}
584 	else {
585 		// only search within the previous results
586 		j = 0;
587 
588 		for (i = 0; i < NumSearchResults; i++) {
589 			if (PSXMu32(SearchResults[i]) == val) {
590 				SearchResults[j++] = SearchResults[i];
591 			}
592 		}
593 
594 		NumSearchResults = j;
595 	}
596 }
597 
CheatSearchNotEqual8(u8 val)598 void CheatSearchNotEqual8(u8 val) {
599 	u32 i, j;
600 
601 	CheatSearchInitBackupMemory();
602 
603 	if (SearchResults == NULL) {
604 		// search the whole memory
605 		for (i = 0; i < 0x200000; i++) {
606 			if (PSXMu8(i) != val) {
607 				CheatSearchAddResult(i);
608 			}
609 		}
610 	}
611 	else {
612 		// only search within the previous results
613 		j = 0;
614 
615 		for (i = 0; i < NumSearchResults; i++) {
616 			if (PSXMu8(SearchResults[i]) != val) {
617 				SearchResults[j++] = SearchResults[i];
618 			}
619 		}
620 
621 		NumSearchResults = j;
622 	}
623 }
624 
CheatSearchNotEqual16(u16 val)625 void CheatSearchNotEqual16(u16 val) {
626 	u32 i, j;
627 
628 	CheatSearchInitBackupMemory();
629 
630 	if (SearchResults == NULL) {
631 		// search the whole memory
632 		for (i = 0; i < 0x200000; i += 2) {
633 			if (PSXMu16(i) != val) {
634 				CheatSearchAddResult(i);
635 			}
636 		}
637 	}
638 	else {
639 		// only search within the previous results
640 		j = 0;
641 
642 		for (i = 0; i < NumSearchResults; i++) {
643 			if (PSXMu16(SearchResults[i]) != val) {
644 				SearchResults[j++] = SearchResults[i];
645 			}
646 		}
647 
648 		NumSearchResults = j;
649 	}
650 }
651 
CheatSearchNotEqual32(u32 val)652 void CheatSearchNotEqual32(u32 val) {
653 	u32 i, j;
654 
655 	CheatSearchInitBackupMemory();
656 
657 	if (SearchResults == NULL) {
658 		// search the whole memory
659 		for (i = 0; i < 0x200000; i += 4) {
660 			if (PSXMu32(i) != val) {
661 				CheatSearchAddResult(i);
662 			}
663 		}
664 	}
665 	else {
666 		// only search within the previous results
667 		j = 0;
668 
669 		for (i = 0; i < NumSearchResults; i++) {
670 			if (PSXMu32(SearchResults[i]) != val) {
671 				SearchResults[j++] = SearchResults[i];
672 			}
673 		}
674 
675 		NumSearchResults = j;
676 	}
677 }
678 
CheatSearchRange8(u8 min,u8 max)679 void CheatSearchRange8(u8 min, u8 max) {
680 	u32 i, j;
681 
682 	CheatSearchInitBackupMemory();
683 
684 	if (SearchResults == NULL) {
685 		// search the whole memory
686 		for (i = 0; i < 0x200000; i++) {
687 			if (PSXMu8(i) >= min && PSXMu8(i) <= max) {
688 				CheatSearchAddResult(i);
689 			}
690 		}
691 	}
692 	else {
693 		// only search within the previous results
694 		j = 0;
695 
696 		for (i = 0; i < NumSearchResults; i++) {
697 			if (PSXMu8(SearchResults[i]) >= min && PSXMu8(SearchResults[i]) <= max) {
698 				SearchResults[j++] = SearchResults[i];
699 			}
700 		}
701 
702 		NumSearchResults = j;
703 	}
704 }
705 
CheatSearchRange16(u16 min,u16 max)706 void CheatSearchRange16(u16 min, u16 max) {
707 	u32 i, j;
708 
709 	CheatSearchInitBackupMemory();
710 
711 	if (SearchResults == NULL) {
712 		// search the whole memory
713 		for (i = 0; i < 0x200000; i += 2) {
714 			if (PSXMu16(i) >= min && PSXMu16(i) <= max) {
715 				CheatSearchAddResult(i);
716 			}
717 		}
718 	}
719 	else {
720 		// only search within the previous results
721 		j = 0;
722 
723 		for (i = 0; i < NumSearchResults; i++) {
724 			if (PSXMu16(SearchResults[i]) >= min && PSXMu16(SearchResults[i]) <= max) {
725 				SearchResults[j++] = SearchResults[i];
726 			}
727 		}
728 
729 		NumSearchResults = j;
730 	}
731 }
732 
CheatSearchRange32(u32 min,u32 max)733 void CheatSearchRange32(u32 min, u32 max) {
734 	u32 i, j;
735 
736 	CheatSearchInitBackupMemory();
737 
738 	if (SearchResults == NULL) {
739 		// search the whole memory
740 		for (i = 0; i < 0x200000; i += 4) {
741 			if (PSXMu32(i) >= min && PSXMu32(i) <= max) {
742 				CheatSearchAddResult(i);
743 			}
744 		}
745 	}
746 	else {
747 		// only search within the previous results
748 		j = 0;
749 
750 		for (i = 0; i < NumSearchResults; i++) {
751 			if (PSXMu32(SearchResults[i]) >= min && PSXMu32(SearchResults[i]) <= max) {
752 				SearchResults[j++] = SearchResults[i];
753 			}
754 		}
755 
756 		NumSearchResults = j;
757 	}
758 }
759 
CheatSearchIncreasedBy8(u8 val)760 void CheatSearchIncreasedBy8(u8 val) {
761 	u32 i, j;
762 
763 	assert(prevM != NULL); // not possible for the first search
764 
765 	j = 0;
766 
767 	for (i = 0; i < NumSearchResults; i++) {
768 		if (PSXMu8(SearchResults[i]) - PrevMu8(SearchResults[i]) == val) {
769 			SearchResults[j++] = SearchResults[i];
770 		}
771 	}
772 
773 	NumSearchResults = j;
774 }
775 
CheatSearchIncreasedBy16(u16 val)776 void CheatSearchIncreasedBy16(u16 val) {
777 	u32 i, j;
778 
779 	assert(prevM != NULL); // not possible for the first search
780 
781 	j = 0;
782 
783 	for (i = 0; i < NumSearchResults; i++) {
784 		if (PSXMu16(SearchResults[i]) - PrevMu16(SearchResults[i]) == val) {
785 			SearchResults[j++] = SearchResults[i];
786 		}
787 	}
788 
789 	NumSearchResults = j;
790 }
791 
CheatSearchIncreasedBy32(u32 val)792 void CheatSearchIncreasedBy32(u32 val) {
793 	u32 i, j;
794 
795 	assert(prevM != NULL); // not possible for the first search
796 
797 	j = 0;
798 
799 	for (i = 0; i < NumSearchResults; i++) {
800 		if (PSXMu32(SearchResults[i]) - PrevMu32(SearchResults[i]) == val) {
801 			SearchResults[j++] = SearchResults[i];
802 		}
803 	}
804 
805 	NumSearchResults = j;
806 }
807 
CheatSearchDecreasedBy8(u8 val)808 void CheatSearchDecreasedBy8(u8 val) {
809 	u32 i, j;
810 
811 	assert(prevM != NULL); // not possible for the first search
812 
813 	j = 0;
814 
815 	for (i = 0; i < NumSearchResults; i++) {
816 		if (PrevMu8(SearchResults[i]) - PSXMu8(SearchResults[i]) == val) {
817 			SearchResults[j++] = SearchResults[i];
818 		}
819 	}
820 
821 	NumSearchResults = j;
822 }
823 
CheatSearchDecreasedBy16(u16 val)824 void CheatSearchDecreasedBy16(u16 val) {
825 	u32 i, j;
826 
827 	assert(prevM != NULL); // not possible for the first search
828 
829 	j = 0;
830 
831 	for (i = 0; i < NumSearchResults; i++) {
832 		if (PrevMu16(SearchResults[i]) - PSXMu16(SearchResults[i]) == val) {
833 			SearchResults[j++] = SearchResults[i];
834 		}
835 	}
836 
837 	NumSearchResults = j;
838 }
839 
CheatSearchDecreasedBy32(u32 val)840 void CheatSearchDecreasedBy32(u32 val) {
841 	u32 i, j;
842 
843 	assert(prevM != NULL); // not possible for the first search
844 
845 	j = 0;
846 
847 	for (i = 0; i < NumSearchResults; i++) {
848 		if (PrevMu32(SearchResults[i]) - PSXMu32(SearchResults[i]) == val) {
849 			SearchResults[j++] = SearchResults[i];
850 		}
851 	}
852 
853 	NumSearchResults = j;
854 }
855 
CheatSearchIncreased8()856 void CheatSearchIncreased8() {
857 	u32 i, j;
858 
859 	assert(prevM != NULL); // not possible for the first search
860 
861 	j = 0;
862 
863 	for (i = 0; i < NumSearchResults; i++) {
864 		if (PrevMu8(SearchResults[i]) < PSXMu8(SearchResults[i])) {
865 			SearchResults[j++] = SearchResults[i];
866 		}
867 	}
868 
869 	NumSearchResults = j;
870 }
871 
CheatSearchIncreased16()872 void CheatSearchIncreased16() {
873 	u32 i, j;
874 
875 	assert(prevM != NULL); // not possible for the first search
876 
877 	j = 0;
878 
879 	for (i = 0; i < NumSearchResults; i++) {
880 		if (PrevMu16(SearchResults[i]) < PSXMu16(SearchResults[i])) {
881 			SearchResults[j++] = SearchResults[i];
882 		}
883 	}
884 
885 	NumSearchResults = j;
886 }
887 
CheatSearchIncreased32()888 void CheatSearchIncreased32() {
889 	u32 i, j;
890 
891 	assert(prevM != NULL); // not possible for the first search
892 
893 	j = 0;
894 
895 	for (i = 0; i < NumSearchResults; i++) {
896 		if (PrevMu32(SearchResults[i]) < PSXMu32(SearchResults[i])) {
897 			SearchResults[j++] = SearchResults[i];
898 		}
899 	}
900 
901 	NumSearchResults = j;
902 }
903 
CheatSearchDecreased8()904 void CheatSearchDecreased8() {
905 	u32 i, j;
906 
907 	assert(prevM != NULL); // not possible for the first search
908 
909 	j = 0;
910 
911 	for (i = 0; i < NumSearchResults; i++) {
912 		if (PrevMu8(SearchResults[i]) > PSXMu8(SearchResults[i])) {
913 			SearchResults[j++] = SearchResults[i];
914 		}
915 	}
916 
917 	NumSearchResults = j;
918 }
919 
CheatSearchDecreased16()920 void CheatSearchDecreased16() {
921 	u32 i, j;
922 
923 	assert(prevM != NULL); // not possible for the first search
924 
925 	j = 0;
926 
927 	for (i = 0; i < NumSearchResults; i++) {
928 		if (PrevMu16(SearchResults[i]) > PSXMu16(SearchResults[i])) {
929 			SearchResults[j++] = SearchResults[i];
930 		}
931 	}
932 
933 	NumSearchResults = j;
934 }
935 
CheatSearchDecreased32()936 void CheatSearchDecreased32() {
937 	u32 i, j;
938 
939 	assert(prevM != NULL); // not possible for the first search
940 
941 	j = 0;
942 
943 	for (i = 0; i < NumSearchResults; i++) {
944 		if (PrevMu32(SearchResults[i]) > PSXMu32(SearchResults[i])) {
945 			SearchResults[j++] = SearchResults[i];
946 		}
947 	}
948 
949 	NumSearchResults = j;
950 }
951 
CheatSearchDifferent8()952 void CheatSearchDifferent8() {
953 	u32 i, j;
954 
955 	assert(prevM != NULL); // not possible for the first search
956 
957 	j = 0;
958 
959 	for (i = 0; i < NumSearchResults; i++) {
960 		if (PrevMu8(SearchResults[i]) != PSXMu8(SearchResults[i])) {
961 			SearchResults[j++] = SearchResults[i];
962 		}
963 	}
964 
965 	NumSearchResults = j;
966 }
967 
CheatSearchDifferent16()968 void CheatSearchDifferent16() {
969 	u32 i, j;
970 
971 	assert(prevM != NULL); // not possible for the first search
972 
973 	j = 0;
974 
975 	for (i = 0; i < NumSearchResults; i++) {
976 		if (PrevMu16(SearchResults[i]) != PSXMu16(SearchResults[i])) {
977 			SearchResults[j++] = SearchResults[i];
978 		}
979 	}
980 
981 	NumSearchResults = j;
982 }
983 
CheatSearchDifferent32()984 void CheatSearchDifferent32() {
985 	u32 i, j;
986 
987 	assert(prevM != NULL); // not possible for the first search
988 
989 	j = 0;
990 
991 	for (i = 0; i < NumSearchResults; i++) {
992 		if (PrevMu32(SearchResults[i]) != PSXMu32(SearchResults[i])) {
993 			SearchResults[j++] = SearchResults[i];
994 		}
995 	}
996 
997 	NumSearchResults = j;
998 }
999 
CheatSearchNoChange8()1000 void CheatSearchNoChange8() {
1001 	u32 i, j;
1002 
1003 	assert(prevM != NULL); // not possible for the first search
1004 
1005 	j = 0;
1006 
1007 	for (i = 0; i < NumSearchResults; i++) {
1008 		if (PrevMu8(SearchResults[i]) == PSXMu8(SearchResults[i])) {
1009 			SearchResults[j++] = SearchResults[i];
1010 		}
1011 	}
1012 
1013 	NumSearchResults = j;
1014 }
1015 
CheatSearchNoChange16()1016 void CheatSearchNoChange16() {
1017 	u32 i, j;
1018 
1019 	assert(prevM != NULL); // not possible for the first search
1020 
1021 	j = 0;
1022 
1023 	for (i = 0; i < NumSearchResults; i++) {
1024 		if (PrevMu16(SearchResults[i]) == PSXMu16(SearchResults[i])) {
1025 			SearchResults[j++] = SearchResults[i];
1026 		}
1027 	}
1028 
1029 	NumSearchResults = j;
1030 }
1031 
CheatSearchNoChange32()1032 void CheatSearchNoChange32() {
1033 	u32 i, j;
1034 
1035 	assert(prevM != NULL); // not possible for the first search
1036 
1037 	j = 0;
1038 
1039 	for (i = 0; i < NumSearchResults; i++) {
1040 		if (PrevMu32(SearchResults[i]) == PSXMu32(SearchResults[i])) {
1041 			SearchResults[j++] = SearchResults[i];
1042 		}
1043 	}
1044 
1045 	NumSearchResults = j;
1046 }
1047