diff --git a/plugins/cheatfind/init.lua b/plugins/cheatfind/init.lua index 27290f6fe93..7d10aa4fa6b 100644 --- a/plugins/cheatfind/init.lua +++ b/plugins/cheatfind/init.lua @@ -98,11 +98,14 @@ function cheatfind.startplugin() return data end - -- compare two data blocks, format is as lua string.unpack, bne and beq val is table of masks - function cheat.comp(newdata, olddata, oper, format, val, bcd) + -- compare two data blocks, format is as lua string.unpack, bne and beq val is table of masks, step is address increment value + function cheat.comp(newdata, olddata, oper, format, val, bcd, step) local ret = {} local ref = {} -- this is a helper for comparing two match lists local bitmask = nil + if not step or step <= 0 then + step = 1 + end local cfoper = { lt = function(a, b, val) return (a < b and val == 0) or (val > 0 and (a + val) == b) end, @@ -167,7 +170,7 @@ function cheatfind.startplugin() val = 0 end - for i = 1, olddata.size do + for i = 1, olddata.size, step do local oldstat, old = pcall(string.unpack, format, olddata.block, i) local newstat, new = pcall(string.unpack, format, newdata.block, i) if oldstat and newstat then @@ -211,8 +214,8 @@ function cheatfind.startplugin() end -- compare two blocks and filter by table of previous matches - function cheat.compnext(newdata, olddata, oldmatch, oper, format, val, bcd) - local matches, refs = cheat.comp(newdata, olddata, oper, format, check_val(oper, val, oldmatch), bcd) + function cheat.compnext(newdata, olddata, oldmatch, oper, format, val, bcd, step) + local matches, refs = cheat.comp(newdata, olddata, oper, format, check_val(oper, val, oldmatch), bcd, step) local nonmatch = {} local oldrefs = {} for num, match in pairs(oldmatch) do @@ -237,15 +240,15 @@ function cheatfind.startplugin() -- compare a data block to the current state - function cheat.compcur(olddata, oper, format, val, bcd) + function cheat.compcur(olddata, oper, format, val, bcd, step) local newdata = cheat.save(olddata.space, olddata.start, olddata.size, olddata.space) - return cheat.comp(newdata, olddata, oper, format, val, bcd) + return cheat.comp(newdata, olddata, oper, format, val, bcd, step) end -- compare a data block to the current state and filter - function cheat.compcurnext(olddata, oldmatch, oper, format, val, bcd) + function cheat.compcurnext(olddata, oldmatch, oper, format, val, bcd, step) local newdata = cheat.save(olddata.space, olddata.start, olddata.size, olddata.space) - return cheat.compnext(newdata, olddata, oldmatch, oper, format, val, bcd) + return cheat.compnext(newdata, olddata, oldmatch, oper, format, val, bcd, step) end @@ -254,11 +257,13 @@ function cheatfind.startplugin() local devtable = {} local devsel = 1 local devcur = 1 - local formtable = { "I1", "i1", "I2", "i2", "I4", "i4", "I8", "i8" } + local formtable = { " I1", " i1", "I2", "i2", "I4", "i4", "I8", "i8", }-- " f", " d" } local formname = { "u8", "s8", "little u16", "big u16", "little s16", "big s16", - "little u32", "big u32", "little s32", "big s32", "little u64", "big u64", "little s64", "big s64" } + "little u32", "big u32", "little s32", "big s32", "little u64", "big u64", "little s64", "big s64", } + -- "little float", "big float", "little double", "big double" } local width = 1 local bcd = 0 + local align = 0 local optable = { "lt", "gt", "eq", "ne", "beq", "bne", "ltv", "gtv", "eqv", "nev" } local opsel = 1 local value = 0 @@ -507,15 +512,23 @@ function cheatfind.startplugin() local function f(event) if event == "select" then local count = 0 + local step = align == 1 and formtable[width]:sub(3, 3) or "1" + if step == "f" then + step = 4 + elseif step == "d" then + step = 8 + else + step = tonumber(step) + end if #matches == 0 then matches[1] = {} for num = 1, #menu_blocks do if leftop == #menu_blocks[1] + 1 then matches[1][num] = cheat.compcur(menu_blocks[num][rightop], optable[opsel], - formtable[width], value, bcd == 1) + formtable[width], value, bcd == 1, step) else matches[1][num] = cheat.comp(menu_blocks[num][leftop], menu_blocks[num][rightop], - optable[opsel], formtable[width], value, bcd == 1) + optable[opsel], formtable[width], value, bcd == 1, step) end count = count + #matches[1][num] end @@ -525,10 +538,10 @@ function cheatfind.startplugin() for num = 1, #menu_blocks do if leftop == #menu_blocks[1] + 1 then matches[#matches][num] = cheat.compcurnext(menu_blocks[num][rightop], lastmatch[num], - optable[opsel], formtable[width], value, bcd == 1) + optable[opsel], formtable[width], value, bcd == 1, step) else matches[#matches][num] = cheat.compnext(menu_blocks[num][leftop], menu_blocks[num][rightop], - lastmatch[num], optable[opsel], formtable[width], value, bcd == 1) + lastmatch[num], optable[opsel], formtable[width], value, bcd == 1, step) end count = count + #matches[#matches][num] end @@ -620,6 +633,17 @@ function cheatfind.startplugin() end return m, function(event) local r bcd, r = incdec(event, bcd, 0, 1) return r end end + menu[#menu + 1] = function() + if formtable[width]:sub(3, 3) == "1" then + return nil + end + local m = { "Aligned only", _("Off"), 0 } + menu_lim(align, 0, 1, m) + if align == 1 then + m[2] = _("On") + end + return m, function(event) local r align, r = incdec(event, align, 0, 1) return r end + end if #matches ~= 0 then menu[#menu + 1] = function() local function f(event) @@ -674,13 +698,15 @@ function cheatfind.startplugin() end return mpairs_it, list, 0 end - local bitwidth = formtable[width]:sub(3, 3):lower() + local bitwidth = formtable[width]:sub(3, 3) if bitwidth == "2" then bitwidth = " %04x" elseif bitwidth == "4" then bitwidth = " %08x" elseif bitwidth == "8" then bitwidth = " %016x" + elseif bitwidth == "f" or bitwidth == "d" then + bitwidth = " %010f" else bitwidth = " %02x" end @@ -688,7 +714,7 @@ function cheatfind.startplugin() local function match_exec(match) local dev = devtable[devcur] local cheat = { desc = string.format(_("Test cheat at addr %08X"), match.addr), script = {} } - local wid = formtable[width]:sub(3, 3):lower() + local wid = formtable[width]:sub(3, 3) local widchar local form if wid == "2" then @@ -703,6 +729,14 @@ function cheatfind.startplugin() wid = "u64" form = "%08x %016x" widchar = "q" + elseif wid == "f" then + wid = "u32" + form = "%08x %f" + widchar = "d" + elseif wid == "d" then + wid = "u64" + form = "%08x %f" + widchar = "q" else wid = "u8" form = "%08x %02x"