summaryrefslogtreecommitdiffstatshomepage
path: root/plugins
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2016-04-22 20:55:07 -0500
committer cracyc <cracyc@users.noreply.github.com>2016-04-22 20:55:07 -0500
commita7bed872eec3effc7d0899d32bc744cd715b1a05 (patch)
tree745e99d643e53a95dfafc0ce8e479fc2876c9ff4 /plugins
parenta590f52a3a9e6db887416cb704e964e2ddf04724 (diff)
plugins/cheatfind: add bitwise comparisons (nw)
Diffstat (limited to 'plugins')
-rw-r--r--plugins/cheatfind/init.lua65
1 files changed, 55 insertions, 10 deletions
diff --git a/plugins/cheatfind/init.lua b/plugins/cheatfind/init.lua
index bde62f97e81..067b272dc1c 100644
--- a/plugins/cheatfind/init.lua
+++ b/plugins/cheatfind/init.lua
@@ -61,17 +61,43 @@ function cheatfind.startplugin()
return data
end
- -- compare two data blocks, format is as lua string.unpack
+ -- compare two data blocks, format is as lua string.unpack, bne and beq val is table of masks
function cheat.comp(olddata, newdata, oper, format, val, bcd)
local ret = {}
local ref = {} -- this is a helper for comparing two match lists
+ local bitmask = nil
+
+ local function bne(a, b, val, addr)
+ if val == 0 then
+ bitmask = a ~ b
+ return bitmask ~= 0
+ elseif not val[addr] then
+ return false
+ else
+ bitmask = (a ~ b) & val[addr]
+ return bitmask ~= 0
+ end
+ end
+
+ local function beq(a, b, val, addr)
+ if val == 0 then
+ bitmask = ~a ~ b
+ return bitmask ~= 0
+ elseif not val[addr] then
+ return false
+ else
+ bitmask = (~a ~ b) & val[addr]
+ return bitmask ~= 0
+ end
+ end
local cfoper = {
lt = function(a, b, val) return (a < b and val == 0) or (val > 0 and (a + val) == b) end,
gt = function(a, b, val) return (a > b and val == 0) or (val > 0 and (a - val) == b) end,
eq = function(a, b, val) return a == b end,
ne = function(a, b, val) return (a ~= b and val == 0) or
- (val > 0 and ((a - val) == b or (a + val) == b)) end }
+ (val > 0 and ((a - val) == b or (a + val) == b)) end,
+ bne = bne, beq = beq }
local function check_bcd(val)
local a = val + 0x0666666666666666
@@ -101,15 +127,17 @@ function cheatfind.startplugin()
local new = string.unpack(format, newdata.block, i)
local oldc, newc = old, new
local comp = false
+ local addr = olddata.start + i - 1
if not bcd or (check_bcd(old) and check_bcd(new)) then
if bcd then
oldc = frombcd(old)
newc = frombcd(new)
end
- if cfoper[oper](oldc, newc, val) then
- ret[#ret + 1] = { addr = olddata.start + i - 1,
+ if cfoper[oper](oldc, newc, val, addr) then
+ ret[#ret + 1] = { addr = addr,
oldval = old,
- newval = new}
+ newval = new,
+ bitmask = bitmask }
ref[ret[#ret].addr] = #ret
end
end
@@ -117,9 +145,22 @@ function cheatfind.startplugin()
return ret, ref
end
+ local function check_val(oper, val, matches)
+ if oper ~= "beq" and oper ~= "bne" then
+ return val
+ elseif not matches or not matches[1].bitmask then
+ return nil
+ end
+ local masks = {}
+ for num, match in pairs(matches) do
+ masks[match.addr] = match.bitmask
+ end
+ return masks
+ end
+
-- compare two blocks and filter by table of previous matches
function cheat.compnext(olddata, newdata, oldmatch, oper, format, val, bcd)
- local matches, refs = cheat.comp(olddata, newdata, oper, format, val, bcd)
+ local matches, refs = cheat.comp(olddata, newdata, oper, format, check_val(oper, val, oldmatch), bcd)
local nonmatch = {}
local oldrefs = {}
for num, match in pairs(oldmatch) do
@@ -146,13 +187,13 @@ function cheatfind.startplugin()
-- compare a data block to the current state
function cheat.compcur(olddata, oper, format, val, bcd)
local newdata = cheat.save(olddata.space, olddata.start, olddata.size, olddata.space)
- return cheat.comp(olddata, newdata, oper, format, val, bcd)
+ return cheat.comp(olddata, newdata, oper, format, check_val(oper, val, oldmatch), bcd)
end
-- compare a data block to the current state and filter
function cheat.compcurnext(olddata, oldmatch, oper, format, val, bcd)
local newdata = cheat.save(olddata.space, olddata.start, olddata.size, olddata.space)
- return cheat.compnext(olddata, newdata, oldmatch, oper, format, val, bcd)
+ return cheat.compnext(olddata, newdata, oldmatch, oper, format, check_val(oper, val, oldmatch), bcd)
end
@@ -166,7 +207,7 @@ function cheatfind.startplugin()
"little u32", "big u32", "little s32", "big s32", "little u64", "big u64", "little s64", "big s64" }
local width = 1
local bcd = 0
- local optable = { "lt", "gt", "eq", "ne" }
+ local optable = { "lt", "gt", "eq", "ne", "beq", "bne" }
local opsel = 1
local value = 0
local leftop = 1
@@ -368,6 +409,10 @@ function cheatfind.startplugin()
manager:machine():popmessage("Left equal to right, value is ignored")
elseif optable[opsel] == "ne" then
manager:machine():popmessage("Left not equal to right, value is difference")
+ elseif optable[opsel] == "beq" then
+ manager:machine():popmessage("Left equal to right with bitmask, value is ignored")
+ elseif optable[opsel] == "bne" then
+ manager:machine():popmessage("Left not equal to right with bitmask, value is ignored")
end
end
elseif index == midx.val then
@@ -452,7 +497,7 @@ function cheatfind.startplugin()
manager:machine():popmessage("Cheat written to " .. filename)
else
local func = "return space:read"
- local env = { space = devtable[devcur].space, read = devtable[devcur].space.read }
+ local env = { space = devtable[devcur].space }
if not dev.space.shortname then
func = func .. "_" .. wid
end