release r26
[pcsx_rearmed.git] / libpcsxcore / cheat.c
... / ...
CommitLineData
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 <stdio.h>
20#include <assert.h>
21#include "psxcommon.h"
22#include "r3000a.h"
23#include "psxmem.h"
24#include "misc.h"
25#include "../frontend/plugin_lib.h" // in_keystate for D4
26
27#include "cheat.h"
28
29Cheat *Cheats = NULL;
30int NumCheats = 0;
31int NumCheatsAllocated = 0;
32
33CheatCode *CheatCodes = NULL;
34int NumCodes = 0;
35int NumCodesAllocated = 0;
36
37#define ALLOC_INCREMENT 16
38
39void ClearAllCheats() {
40 int i;
41
42 if (Cheats != NULL) {
43 for (i = 0; i < NumCheats; i++) {
44 free(Cheats[i].Descr);
45 }
46 free(Cheats);
47 }
48
49 Cheats = NULL;
50 NumCheats = 0;
51 NumCheatsAllocated = 0;
52
53 if (CheatCodes != NULL) {
54 free(CheatCodes);
55 }
56
57 CheatCodes = NULL;
58 NumCodes = 0;
59 NumCodesAllocated = 0;
60}
61
62// load cheats from the specific filename
63void LoadCheats(const char *filename) {
64 FILE *fp;
65 char buf[256];
66 int count = 0;
67 unsigned int t1, t2;
68
69 fp = fopen(filename, "r");
70 if (fp == NULL) {
71 return;
72 }
73
74 ClearAllCheats();
75
76 while (fgets(buf, 255, fp) != NULL) {
77 buf[255] = '\0';
78 trim(buf);
79
80 // Skip comment or blank lines
81 if (buf[0] == '#' || buf[0] == ';' || buf[0] == '/' || buf[0] == '\"' || buf[0] == '\0')
82 continue;
83
84 if (buf[0] == '[' && buf[strlen(buf) - 1] == ']') {
85 if (NumCheats > 0)
86 Cheats[NumCheats - 1].n = count;
87
88 if (NumCheats >= NumCheatsAllocated) {
89 NumCheatsAllocated += ALLOC_INCREMENT;
90
91 if (Cheats == NULL) {
92 assert(NumCheats == 0);
93 assert(NumCheatsAllocated == ALLOC_INCREMENT);
94 Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
95 } else {
96 Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
97 }
98 }
99
100 buf[strlen(buf) - 1] = '\0';
101 count = 0;
102
103 if (buf[1] == '*') {
104 Cheats[NumCheats].Descr = strdup(buf + 2);
105 Cheats[NumCheats].Enabled = 1;
106 } else {
107 Cheats[NumCheats].Descr = strdup(buf + 1);
108 Cheats[NumCheats].Enabled = 0;
109 }
110 Cheats[NumCheats].WasEnabled = 0;
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 int was_enabled;
186
187 for (i = 0; i < NumCheats; i++) {
188 was_enabled = Cheats[i].WasEnabled;
189 if (!Cheats[i].Enabled) {
190 if (!Cheats[i].WasEnabled)
191 continue;
192 }
193 Cheats[i].WasEnabled = Cheats[i].Enabled;
194
195 // process all cheat codes
196 endindex = Cheats[i].First + Cheats[i].n;
197
198 for (j = Cheats[i].First; j < endindex; j++) {
199 u8 type = (uint8_t)(CheatCodes[j].Addr >> 24);
200 u32 addr = (CheatCodes[j].Addr & 0x001FFFFF);
201 u16 val = CheatCodes[j].Val;
202 u32 taddr;
203
204 if (!was_enabled) {
205 switch (type) {
206 case CHEAT_CONST16:
207 CheatCodes[j].OldVal = psxMu16(addr);
208 break;
209 case CHEAT_CONST8:
210 CheatCodes[j].OldVal = psxMu8(addr);
211 break;
212 }
213 }
214 else if (!Cheats[i].Enabled) {
215 val = CheatCodes[j].OldVal;
216 if (type != CHEAT_CONST16 && type != CHEAT_CONST8)
217 continue;
218 }
219
220 switch (type) {
221 case CHEAT_CONST8:
222 psxMu8ref(addr) = (u8)val;
223 break;
224
225 case CHEAT_CONST16:
226 psxMu16ref(addr) = SWAPu16(val);
227 break;
228
229 case CHEAT_SCRATCHPAD16: // 1F
230 psxHu16ref(addr) = SWAPu16(val);
231 break;
232
233 case CHEAT_INC16:
234 psxMu16ref(addr) = SWAPu16(psxMu16(addr) + val);
235 break;
236
237 case CHEAT_DEC16:
238 psxMu16ref(addr) = SWAPu16(psxMu16(addr) - val);
239 break;
240
241 case CHEAT_INC8:
242 psxMu8ref(addr) += (u8)val;
243 break;
244
245 case CHEAT_DEC8:
246 psxMu8ref(addr) -= (u8)val;
247 break;
248
249 case CHEAT_SLIDE:
250 j++;
251 if (j >= endindex)
252 break;
253
254 type = (uint8_t)(CheatCodes[j].Addr >> 24);
255 taddr = (CheatCodes[j].Addr & 0x001FFFFF);
256 val = CheatCodes[j].Val;
257
258 if (type == CHEAT_CONST8) {
259 for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
260 psxMu8ref(taddr) = (u8)val;
261 taddr += (s8)(addr & 0xFF);
262 val += (s8)(CheatCodes[j - 1].Val & 0xFF);
263 }
264 }
265 else if (type == CHEAT_CONST16) {
266 for (k = 0; k < ((addr >> 8) & 0xFF); k++) {
267 psxMu16ref(taddr) = SWAPu16(val);
268 taddr += (s8)(addr & 0xFF);
269 val += (s8)(CheatCodes[j - 1].Val & 0xFF);
270 }
271 }
272 break;
273
274 case CHEAT_MEMCPY:
275 j++;
276 if (j >= endindex)
277 break;
278
279 taddr = (CheatCodes[j].Addr & 0x001FFFFF);
280 for (k = 0; k < val; k++) {
281 psxMu8ref(taddr + k) = PSXMu8(addr + k);
282 }
283 break;
284
285 case CHEAT_EQU8:
286 if (PSXMu8(addr) != (u8)val)
287 j++; // skip the next code
288 break;
289
290 case CHEAT_NOTEQU8:
291 if (PSXMu8(addr) == (u8)val)
292 j++; // skip the next code
293 break;
294
295 case CHEAT_LESSTHAN8:
296 if (PSXMu8(addr) >= (u8)val)
297 j++; // skip the next code
298 break;
299
300 case CHEAT_GREATERTHAN8:
301 if (PSXMu8(addr) <= (u8)val)
302 j++; // skip the next code
303 break;
304
305 case CHEAT_EQU16:
306 if (PSXMu16(addr) != val)
307 j++; // skip the next code
308 break;
309
310 case CHEAT_NOTEQU16:
311 if (PSXMu16(addr) == val)
312 j++; // skip the next code
313 break;
314
315 case CHEAT_LESSTHAN16:
316 if (PSXMu16(addr) >= val)
317 j++; // skip the next code
318 break;
319
320 case CHEAT_GREATERTHAN16:
321 if (PSXMu16(addr) <= val)
322 j++; // skip the next code
323 break;
324
325 case CHEAT_BUTTONS1_16: { // D4
326 u16 keys = in_keystate[0];
327 keys = (keys << 8) | (keys >> 8);
328 if (keys != val)
329 j++; // skip the next code
330 break;
331 }
332
333 default:
334 SysPrintf("unhandled cheat %d,%d code %08X\n",
335 i, j, CheatCodes[j].Addr);
336 Cheats[i].WasEnabled = Cheats[i].Enabled = 0;
337 break;
338 }
339 }
340 }
341}
342
343int AddCheat(const char *descr, char *code) {
344 int c = 1;
345 char *p1, *p2;
346
347 if (NumCheats >= NumCheatsAllocated) {
348 NumCheatsAllocated += ALLOC_INCREMENT;
349
350 if (Cheats == NULL) {
351 assert(NumCheats == 0);
352 assert(NumCheatsAllocated == ALLOC_INCREMENT);
353 Cheats = (Cheat *)malloc(sizeof(Cheat) * NumCheatsAllocated);
354 }
355 else {
356 Cheats = (Cheat *)realloc(Cheats, sizeof(Cheat) * NumCheatsAllocated);
357 }
358 }
359
360 Cheats[NumCheats].Enabled = 0;
361 Cheats[NumCheats].WasEnabled = 0;
362 Cheats[NumCheats].First = NumCodes;
363 Cheats[NumCheats].n = 0;
364
365 p1 = code;
366 p2 = code;
367
368 while (c) {
369 unsigned int t1, t2, r;
370
371 while (*p2 != '\n' && *p2 != '\0')
372 p2++;
373
374 if (*p2 == '\0')
375 c = 0;
376
377 *p2 = '\0';
378 p2++;
379
380 t1 = 0;
381 t2 = 0;
382 r = sscanf(p1, "%x %x", &t1, &t2);
383
384 if (r != 2)
385 SysPrintf("cheat %d: couldn't parse '%s'\n", NumCodes, p1);
386 else if (t1 >= 0x10000000) {
387 if (NumCodes >= NumCodesAllocated) {
388 NumCodesAllocated += ALLOC_INCREMENT;
389
390 if (CheatCodes == NULL) {
391 assert(NumCodes == 0);
392 assert(NumCodesAllocated == ALLOC_INCREMENT);
393 CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
394 }
395 else {
396 CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
397 }
398 }
399
400 CheatCodes[NumCodes].Addr = t1;
401 CheatCodes[NumCodes].Val = t2;
402 NumCodes++;
403 Cheats[NumCheats].n++;
404 }
405
406 p1 = p2;
407 }
408
409 if (Cheats[NumCheats].n == 0) {
410 return -1;
411 }
412
413 Cheats[NumCheats].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
414 NumCheats++;
415 return 0;
416}
417
418void RemoveCheat(int index) {
419 assert(index >= 0 && index < NumCheats);
420
421 free(Cheats[index].Descr);
422 Cheats[index].Descr = NULL;
423
424 while (index < NumCheats - 1) {
425 Cheats[index] = Cheats[index + 1];
426 index++;
427 }
428
429 NumCheats--;
430}
431
432int EditCheat(int index, const char *descr, char *code) {
433 int c = 1;
434 int prev = NumCodes;
435 char *p1, *p2;
436
437 assert(index >= 0 && index < NumCheats);
438
439 p1 = code;
440 p2 = code;
441
442 while (c) {
443 unsigned int t1, t2;
444
445 while (*p2 != '\n' && *p2 != '\0')
446 p2++;
447
448 if (*p2 == '\0')
449 c = 0;
450
451 *p2 = '\0';
452 p2++;
453
454 t1 = 0;
455 t2 = 0;
456 sscanf(p1, "%x %x", &t1, &t2);
457
458 if (t1 > 0x10000000) {
459 if (NumCodes >= NumCodesAllocated) {
460 NumCodesAllocated += ALLOC_INCREMENT;
461
462 if (CheatCodes == NULL) {
463 assert(NumCodes == 0);
464 assert(NumCodesAllocated == ALLOC_INCREMENT);
465 CheatCodes = (CheatCode *)malloc(sizeof(CheatCode) * NumCodesAllocated);
466 }
467 else {
468 CheatCodes = (CheatCode *)realloc(CheatCodes, sizeof(CheatCode) * NumCodesAllocated);
469 }
470 }
471
472 CheatCodes[NumCodes].Addr = t1;
473 CheatCodes[NumCodes].Val = t2;
474 NumCodes++;
475 }
476
477 p1 = p2;
478 }
479
480 if (NumCodes == prev) {
481 return -1;
482 }
483
484 free(Cheats[index].Descr);
485 Cheats[index].Descr = strdup(descr[0] ? descr : _("(Untitled)"));
486 Cheats[index].First = prev;
487 Cheats[index].n = NumCodes - prev;
488
489 return 0;
490}
491
492#if 0
493static int NumSearchResultsAllocated = 0;
494int NumSearchResults = 0;
495u32 *SearchResults = NULL;
496s8 *prevM = NULL;
497
498void FreeCheatSearchResults() {
499 if (SearchResults != NULL) {
500 free(SearchResults);
501 }
502 SearchResults = NULL;
503
504 NumSearchResults = 0;
505 NumSearchResultsAllocated = 0;
506}
507
508void FreeCheatSearchMem() {
509 if (prevM != NULL) {
510 free(prevM);
511 }
512 prevM = NULL;
513}
514
515void CheatSearchBackupMemory() {
516 if (prevM != NULL) {
517 memcpy(prevM, psxRegs.ptrs.psxM, 0x200000);
518 }
519}
520
521static void CheatSearchInitBackupMemory() {
522 if (prevM == NULL) {
523 prevM = (s8 *)malloc(0x200000);
524 CheatSearchBackupMemory();
525 }
526}
527
528static void CheatSearchAddResult(u32 addr) {
529 if (NumSearchResults >= NumSearchResultsAllocated) {
530 NumSearchResultsAllocated += ALLOC_INCREMENT;
531
532 if (SearchResults == NULL) {
533 SearchResults = (u32 *)malloc(sizeof(u32) * NumSearchResultsAllocated);
534 }
535 else {
536 SearchResults = (u32 *)realloc(SearchResults, sizeof(u32) * NumSearchResultsAllocated);
537 }
538 }
539
540 SearchResults[NumSearchResults++] = addr;
541}
542
543void CheatSearchEqual8(u8 val) {
544 u32 i, j;
545
546 CheatSearchInitBackupMemory();
547
548 if (SearchResults == NULL) {
549 // search the whole memory
550 for (i = 0; i < 0x200000; i++) {
551 if (PSXMu8(i) == val) {
552 CheatSearchAddResult(i);
553 }
554 }
555 }
556 else {
557 // only search within the previous results
558 j = 0;
559
560 for (i = 0; i < NumSearchResults; i++) {
561 if (PSXMu8(SearchResults[i]) == val) {
562 SearchResults[j++] = SearchResults[i];
563 }
564 }
565
566 NumSearchResults = j;
567 }
568}
569
570void CheatSearchEqual16(u16 val) {
571 u32 i, j;
572
573 CheatSearchInitBackupMemory();
574
575 if (SearchResults == NULL) {
576 // search the whole memory
577 for (i = 0; i < 0x200000; i += 2) {
578 if (PSXMu16(i) == val) {
579 CheatSearchAddResult(i);
580 }
581 }
582 }
583 else {
584 // only search within the previous results
585 j = 0;
586
587 for (i = 0; i < NumSearchResults; i++) {
588 if (PSXMu16(SearchResults[i]) == val) {
589 SearchResults[j++] = SearchResults[i];
590 }
591 }
592
593 NumSearchResults = j;
594 }
595}
596
597void CheatSearchEqual32(u32 val) {
598 u32 i, j;
599
600 CheatSearchInitBackupMemory();
601
602 if (SearchResults == NULL) {
603 // search the whole memory
604 for (i = 0; i < 0x200000; i += 4) {
605 if (PSXMu32(i) == val) {
606 CheatSearchAddResult(i);
607 }
608 }
609 }
610 else {
611 // only search within the previous results
612 j = 0;
613
614 for (i = 0; i < NumSearchResults; i++) {
615 if (PSXMu32(SearchResults[i]) == val) {
616 SearchResults[j++] = SearchResults[i];
617 }
618 }
619
620 NumSearchResults = j;
621 }
622}
623
624void CheatSearchNotEqual8(u8 val) {
625 u32 i, j;
626
627 CheatSearchInitBackupMemory();
628
629 if (SearchResults == NULL) {
630 // search the whole memory
631 for (i = 0; i < 0x200000; i++) {
632 if (PSXMu8(i) != val) {
633 CheatSearchAddResult(i);
634 }
635 }
636 }
637 else {
638 // only search within the previous results
639 j = 0;
640
641 for (i = 0; i < NumSearchResults; i++) {
642 if (PSXMu8(SearchResults[i]) != val) {
643 SearchResults[j++] = SearchResults[i];
644 }
645 }
646
647 NumSearchResults = j;
648 }
649}
650
651void CheatSearchNotEqual16(u16 val) {
652 u32 i, j;
653
654 CheatSearchInitBackupMemory();
655
656 if (SearchResults == NULL) {
657 // search the whole memory
658 for (i = 0; i < 0x200000; i += 2) {
659 if (PSXMu16(i) != val) {
660 CheatSearchAddResult(i);
661 }
662 }
663 }
664 else {
665 // only search within the previous results
666 j = 0;
667
668 for (i = 0; i < NumSearchResults; i++) {
669 if (PSXMu16(SearchResults[i]) != val) {
670 SearchResults[j++] = SearchResults[i];
671 }
672 }
673
674 NumSearchResults = j;
675 }
676}
677
678void CheatSearchNotEqual32(u32 val) {
679 u32 i, j;
680
681 CheatSearchInitBackupMemory();
682
683 if (SearchResults == NULL) {
684 // search the whole memory
685 for (i = 0; i < 0x200000; i += 4) {
686 if (PSXMu32(i) != val) {
687 CheatSearchAddResult(i);
688 }
689 }
690 }
691 else {
692 // only search within the previous results
693 j = 0;
694
695 for (i = 0; i < NumSearchResults; i++) {
696 if (PSXMu32(SearchResults[i]) != val) {
697 SearchResults[j++] = SearchResults[i];
698 }
699 }
700
701 NumSearchResults = j;
702 }
703}
704
705void CheatSearchRange8(u8 min, u8 max) {
706 u32 i, j;
707
708 CheatSearchInitBackupMemory();
709
710 if (SearchResults == NULL) {
711 // search the whole memory
712 for (i = 0; i < 0x200000; i++) {
713 if (PSXMu8(i) >= min && PSXMu8(i) <= max) {
714 CheatSearchAddResult(i);
715 }
716 }
717 }
718 else {
719 // only search within the previous results
720 j = 0;
721
722 for (i = 0; i < NumSearchResults; i++) {
723 if (PSXMu8(SearchResults[i]) >= min && PSXMu8(SearchResults[i]) <= max) {
724 SearchResults[j++] = SearchResults[i];
725 }
726 }
727
728 NumSearchResults = j;
729 }
730}
731
732void CheatSearchRange16(u16 min, u16 max) {
733 u32 i, j;
734
735 CheatSearchInitBackupMemory();
736
737 if (SearchResults == NULL) {
738 // search the whole memory
739 for (i = 0; i < 0x200000; i += 2) {
740 if (PSXMu16(i) >= min && PSXMu16(i) <= max) {
741 CheatSearchAddResult(i);
742 }
743 }
744 }
745 else {
746 // only search within the previous results
747 j = 0;
748
749 for (i = 0; i < NumSearchResults; i++) {
750 if (PSXMu16(SearchResults[i]) >= min && PSXMu16(SearchResults[i]) <= max) {
751 SearchResults[j++] = SearchResults[i];
752 }
753 }
754
755 NumSearchResults = j;
756 }
757}
758
759void CheatSearchRange32(u32 min, u32 max) {
760 u32 i, j;
761
762 CheatSearchInitBackupMemory();
763
764 if (SearchResults == NULL) {
765 // search the whole memory
766 for (i = 0; i < 0x200000; i += 4) {
767 if (PSXMu32(i) >= min && PSXMu32(i) <= max) {
768 CheatSearchAddResult(i);
769 }
770 }
771 }
772 else {
773 // only search within the previous results
774 j = 0;
775
776 for (i = 0; i < NumSearchResults; i++) {
777 if (PSXMu32(SearchResults[i]) >= min && PSXMu32(SearchResults[i]) <= max) {
778 SearchResults[j++] = SearchResults[i];
779 }
780 }
781
782 NumSearchResults = j;
783 }
784}
785
786void CheatSearchIncreasedBy8(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 (PSXMu8(SearchResults[i]) - PrevMu8(SearchResults[i]) == val) {
795 SearchResults[j++] = SearchResults[i];
796 }
797 }
798
799 NumSearchResults = j;
800}
801
802void CheatSearchIncreasedBy16(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 (PSXMu16(SearchResults[i]) - PrevMu16(SearchResults[i]) == val) {
811 SearchResults[j++] = SearchResults[i];
812 }
813 }
814
815 NumSearchResults = j;
816}
817
818void CheatSearchIncreasedBy32(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 (PSXMu32(SearchResults[i]) - PrevMu32(SearchResults[i]) == val) {
827 SearchResults[j++] = SearchResults[i];
828 }
829 }
830
831 NumSearchResults = j;
832}
833
834void CheatSearchDecreasedBy8(u8 val) {
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]) == val) {
843 SearchResults[j++] = SearchResults[i];
844 }
845 }
846
847 NumSearchResults = j;
848}
849
850void CheatSearchDecreasedBy16(u16 val) {
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]) == val) {
859 SearchResults[j++] = SearchResults[i];
860 }
861 }
862
863 NumSearchResults = j;
864}
865
866void CheatSearchDecreasedBy32(u32 val) {
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]) == val) {
875 SearchResults[j++] = SearchResults[i];
876 }
877 }
878
879 NumSearchResults = j;
880}
881
882void CheatSearchIncreased8() {
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 CheatSearchIncreased16() {
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 CheatSearchIncreased32() {
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 CheatSearchDecreased8() {
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 CheatSearchDecreased16() {
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 CheatSearchDecreased32() {
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 CheatSearchDifferent8() {
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 CheatSearchDifferent16() {
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 CheatSearchDifferent32() {
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}
1025
1026void CheatSearchNoChange8() {
1027 u32 i, j;
1028
1029 assert(prevM != NULL); // not possible for the first search
1030
1031 j = 0;
1032
1033 for (i = 0; i < NumSearchResults; i++) {
1034 if (PrevMu8(SearchResults[i]) == PSXMu8(SearchResults[i])) {
1035 SearchResults[j++] = SearchResults[i];
1036 }
1037 }
1038
1039 NumSearchResults = j;
1040}
1041
1042void CheatSearchNoChange16() {
1043 u32 i, j;
1044
1045 assert(prevM != NULL); // not possible for the first search
1046
1047 j = 0;
1048
1049 for (i = 0; i < NumSearchResults; i++) {
1050 if (PrevMu16(SearchResults[i]) == PSXMu16(SearchResults[i])) {
1051 SearchResults[j++] = SearchResults[i];
1052 }
1053 }
1054
1055 NumSearchResults = j;
1056}
1057
1058void CheatSearchNoChange32() {
1059 u32 i, j;
1060
1061 assert(prevM != NULL); // not possible for the first search
1062
1063 j = 0;
1064
1065 for (i = 0; i < NumSearchResults; i++) {
1066 if (PrevMu32(SearchResults[i]) == PSXMu32(SearchResults[i])) {
1067 SearchResults[j++] = SearchResults[i];
1068 }
1069 }
1070
1071 NumSearchResults = j;
1072}
1073#endif