|
search.c (346 lines) implements the classic Gameshark-style "narrow down an
unknown address" search: repeated passes over a memory range, each pass filtering the
previous pass's candidate addresses by a new criterion.
Why it's file-backed, not memory-backed: every search pass is streamed to a file, searches/search{N}.dat. This is the reason searches survive across menu sessions and even reboots (undocumented anywhere in the end-user docs, but a real feature — search_init() at boot looks for existing search files and resumes rather than starting over). search.ram (search #0) is special: an initial full memory dump used as input to the very first pass.
The performance rewrite: the changelog documents a search rewrite 25x-253x faster than the original MKUltra-derived implementation. The technique: stream through candidate addresses with buffered file I/O in one tight pass, computing the check inline rather than issuing a separate syscall per address/comparison. The loop also periodically yields:
if(!(address & 0xFFFF)) {
if(!cfg.cheat_pause) {
sceKernelDelayThread(1500); // delay search so we don't crash
}
...
}
That comment is literal, not decorative — removing the yield to "go faster" risks reintroducing crashes on real hardware.
Search modes (the search_mode parameter):
| Mode | Comparison | Typical use |
| 0 | value == check | Find this exact number |
| 1 | value != check | Find anything that changed away from X |
| 2 / 3 | value >= check / value <= check | Range narrowing |
| 4 / 5 | previous +/- delta == check | Increased/decreased by exactly N |
| 6-9 | Same as 0-3, vs. previous pass's per-address value | "Unknown value" search — find what changed without knowing the target |
search_add_result() and search_add_loaded_results() convert search hits
directly into Cheat/Block entries via cheat_new() — this is the SQUARE-on-result
shortcut mentioned in the changelog.
|