psxmem: try to choose mem addresses more carefully
[pcsx_rearmed.git] / libpcsxcore / cheat.c
CommitLineData
ef79bbde
P
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
25Cheat *Cheats = NULL;
26int NumCheats = 0;
9c27c205 27int NumCheatsAllocated = 0;
ef79bbde
P
28
29CheatCode *CheatCodes = NULL;
30int NumCodes = 0;
9c27c205 31int NumCodesAllocated = 0;
ef79bbde
P
32
33s8 *prevM = NULL;
34u32 *SearchResults = NULL;
35int NumSearchResults = 0;
36static int NumSearchResultsAllocated = 0;
37
38#define ALLOC_INCREMENT 100
39
40void 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
64void 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 }
2c843d96 111 Cheats[NumCheats].WasEnabled = 0;
ef79bbde
P
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
152void 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
184void ApplyCheats() {
185 int i, j, k, endindex;
2c843d96 186 int was_enabled;
ef79bbde
P
187
188 for (i = 0; i < NumCheats; i++) {
2c843d96 189 was_enabled = Cheats[i].WasEnabled;
ef79bbde 190 if (!Cheats[i].Enabled) {
2c843d96 191 if (!Cheats[i].WasEnabled)
192 continue;
ef79bbde 193 }
2c843d96 194 Cheats[i].WasEnabled = Cheats[i].Enabled;
ef79bbde
P
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
2c843d96 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
ef79bbde
P
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
326int 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;
2c843d96 345 Cheats[NumCheats].WasEnabled = 0;
ef79bbde
P
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
399void 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
412int 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
472void FreeCheatSearchResults() {
473 if (SearchResults != NULL) {
474 free(SearchResults);
475 }
476 SearchResults = NULL;
477
478 NumSearchResults = 0;
479 NumSearchResultsAllocated = 0;
480}
481
482void FreeCheatSearchMem() {
483 if (prevM != NULL) {
484 free(prevM);
485 }
486 prevM = NULL;
487}
488
489void CheatSearchBackupMemory() {
490 if (prevM != NULL) {
491 memcpy(prevM, psxM, 0x200000);
492 }
493}
494
495static void CheatSearchInitBackupMemory() {
496 if (prevM == NULL) {
497 prevM = (s8 *)malloc(0x200000);
498 CheatSearchBackupMemory();
499 }
500}
501
502static 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
517void 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
544void 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
571void 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
598void 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
625void 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
652void 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
679void 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
706void 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
733void 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
760void 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
776void 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
792void 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
808void 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
824void 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
840void 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
856void 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
872void 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
888void 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
904void 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
920void 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
936void 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
952void 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
968void 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
984void 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
1000void 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
1016void 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
1032void 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}