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