85 lines
2.2 KiB
Diff
85 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000001046
|
|
# UNDF: UNDF-2026-XXXXXXXXX
|
|
--- a/src/cheat.cpp
|
|
+++ b/src/cheat.cpp
|
|
@@ -67,6 +67,10 @@ CHEATF_SUBFAST SubCheats[256];
|
|
uint32 numsubcheats = 0;
|
|
int globalCheatDisabled = 0;
|
|
int disableAutoLSCheats = 0;
|
|
bool disableShowGG = 0;
|
|
static _8BYTECHEATMAP* cheatMap = NULL;
|
|
struct CHEATF *cheats = 0, *cheatsl = 0;
|
|
+
|
|
+// O(1) direct-address lookup replacing the O(C) SubCheats[] linear scan.
|
|
+// Index -1 means no cheat at this address.
|
|
+static int cheat_idx[0x10000];
|
|
|
|
|
|
#define CHEATC_NONE 0x8000
|
|
@@ -79,16 +83,16 @@ static uint16 *CheatComp = 0;
|
|
|
|
static DECLFR(SubCheatsRead)
|
|
{
|
|
- CHEATF_SUBFAST *s = SubCheats;
|
|
- int x=numsubcheats;
|
|
-
|
|
- do
|
|
- {
|
|
- if(s->addr==A)
|
|
- {
|
|
- if(s->compare>=0)
|
|
- {
|
|
- uint8 pv=s->PrevRead(A);
|
|
-
|
|
- if(pv==s->compare)
|
|
- return(s->val);
|
|
- else return(pv);
|
|
- }
|
|
- else return(s->val);
|
|
- }
|
|
- s++;
|
|
- } while(--x);
|
|
- return(0); /* We should never get here. */
|
|
+ // O(1): look up this address directly instead of scanning all active cheats.
|
|
+ int idx = cheat_idx[A];
|
|
+ if(idx < 0) return(0); /* should never happen if installed correctly */
|
|
+ CHEATF_SUBFAST *s = &SubCheats[idx];
|
|
+ if(s->compare>=0)
|
|
+ {
|
|
+ uint8 pv=s->PrevRead(A);
|
|
+ if(pv==s->compare)
|
|
+ return(s->val);
|
|
+ else return(pv);
|
|
+ }
|
|
+ return(s->val);
|
|
}
|
|
|
|
void RebuildSubCheats(void)
|
|
@@ -96,6 +100,8 @@ void RebuildSubCheats(void)
|
|
uint32 x;
|
|
struct CHEATF *c = cheats;
|
|
+ // Clear the direct-lookup table for addresses we're about to remove.
|
|
for (x = 0; x < numsubcheats; x++)
|
|
{
|
|
+ cheat_idx[SubCheats[x].addr] = -1;
|
|
SetReadHandler(SubCheats[x].addr, SubCheats[x].addr, SubCheats[x].PrevRead);
|
|
if (cheatMap)
|
|
FCEUI_SetCheatMapByte(SubCheats[x].addr, false);
|
|
@@ -113,6 +119,7 @@ void RebuildSubCheats(void)
|
|
SubCheats[numsubcheats].val = c->val;
|
|
SubCheats[numsubcheats].compare = c->compare;
|
|
SetReadHandler(c->addr, c->addr, SubCheatsRead);
|
|
+ cheat_idx[c->addr] = (int)numsubcheats;
|
|
if (cheatMap)
|
|
FCEUI_SetCheatMapByte(SubCheats[numsubcheats].addr, true);
|
|
numsubcheats++;
|
|
@@ -123,6 +130,14 @@ void RebuildSubCheats(void)
|
|
FrozenAddressCount = numsubcheats;
|
|
}
|
|
|
|
+// Call once at startup to initialise the direct-lookup table.
|
|
+void FCEU_CheatIdxInit(void)
|
|
+{
|
|
+ for(int i = 0; i < 0x10000; i++)
|
|
+ cheat_idx[i] = -1;
|
|
+}
|