diff options
author | 2017-06-02 17:59:55 -0500 | |
---|---|---|
committer | 2017-06-02 18:03:25 -0500 | |
commit | 33c65a2afccb8031e5c929498cdbdb6c83bb645e (patch) | |
tree | e91bc89b1ffdaac44a8f4bbb2fb135e1221db597 /plugins/cheat/cheat_xml.lua | |
parent | e6ee45d670bc54cf033a2d71454095b0392bbf3b (diff) |
plugins/cheat: add hotkey support [Carl]
Diffstat (limited to 'plugins/cheat/cheat_xml.lua')
-rw-r--r-- | plugins/cheat/cheat_xml.lua | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/plugins/cheat/cheat_xml.lua b/plugins/cheat/cheat_xml.lua new file mode 100644 index 00000000000..a14aee034cb --- /dev/null +++ b/plugins/cheat/cheat_xml.lua @@ -0,0 +1,251 @@ +local xml = {} + +function xml.filename(name) + return name .. ".xml" +end + +-- basic xml parser for mamecheat only +local function xml_parse(data) + local function fix_gt(str) + str = str:gsub(">=", " ge ") + str = str:gsub(">", " gt ") + return str + end + data = data:gsub("(condition=%b\"\")", fix_gt) + local cheat_str = data:match("<mamecheat.->(.*)</ *mamecheat>") + + local function get_tags(str) + local arr = {} + while str ~= "" do + local tag, attr, stop + tag, attr, stop, str = str:match("<([%w!%-]+) ?(.-)(/?)[ %-]->(.*)") + + if not tag then + return arr + end + if tag:sub(0, 3) ~= "!--" then + local block = {} + if stop ~= "/" then + local nest + nest, str = str:match("(.-)</ *" .. tag .. " *>(.*)") + local children = get_tags(nest) + if not next(children) then + nest = nest:gsub("<!--.-%-%->", "") + nest = nest:gsub("^%s*(.-)%s*$", "%1") + block["text"] = nest + else + block = children + end + end + if attr then + for name, value in attr:gmatch("(%w-)=\"(.-)\"") do + block[name] = value:gsub("^%s*(.-)%s*$", "%1") + end + end + if not arr[tag] then + arr[tag] = {} + end + arr[tag][#arr[tag] + 1] = block + end + end + return arr + end + local xml_table = get_tags(cheat_str) + return xml_table +end + +function xml.conv_cheat(data) + local spaces, regions, output + data = xml_parse(data) + local function convert_expr(data) + local write = false + + local function convert_memref(cpu, phys, space, width, addr, rw) + local mod = "" + local count + if space == "p" then + fullspace = "program" + elseif space == "d" then + fullspace = "data" + elseif space == "i" then + fullspace = "io" + elseif space == "r" or space == "o" then + fullspace = "program" + mod = "direct_" + space = "p" + end + if width == "b" then + width = "u8" + elseif width == "w" then + width = "u16" + elseif width == "d" then + width = "u32" + elseif width == "q" then + width = "u64" + end + local cpuname = cpu:gsub(":", "_") + if space == "m" then + regions[cpuname .. space] = ":" .. cpu + else + spaces[cpuname .. space] = { tag = ":" .. cpu, type = fullspace } + if phys ~= "p" and mod == "" then + mod = "log_" + end + end + if rw == "=" then + write = true + ret = cpuname .. space .. ":" .. "write_" .. mod .. width .. "(" .. addr .. "," + else + ret = cpuname .. space .. ":" .. "read_" .. mod .. width .. "(" .. addr .. ")" + end + if rw == "==" then + ret = ret .. "==" + end + return ret + end + + local function frame() + output = true + return "screen:frame_number()" + end + + data = data:lower() + data = data:gsub("^[(](.-)[)]$", "%1") + data = data:gsub("%f[%w]lt%f[%W]", "<") + data = data:gsub("%f[%w]ge%f[%W]", ">=") + data = data:gsub("%f[%w]gt%f[%W]", ">") + data = data:gsub("%f[%w]le%f[%W]", "<=") + data = data:gsub("%f[%w]eq%f[%W]", "==") + data = data:gsub("%f[%w]ne%f[%W]", "~=") + data = data:gsub("!=", "~=") + data = data:gsub("||", " or ") + data = data:gsub("%f[%w]frame%f[%W]", frame) + data = data:gsub("%f[%w]band%f[%W]", "&") + data = data:gsub("%f[%w]bor%f[%W]", "|") + data = data:gsub("%f[%w]rshift%f[%W]", ">>") + data = data:gsub("%f[%w]lshift%f[%W]", "<<") + data = data:gsub("(%w-)%+%+", "%1 = %1 + 1") + data = data:gsub("%f[%w](%x+)%f[%W]", "0x%1") + data = data:gsub("([%w_:]-)%.(p?)([pmrodi3])([bwdq])@(%w+) *(=*)", convert_memref) + repeat + data, count = data:gsub("([%w_:]-)%.(p?)([pmrodi3])([bwdq])@(%b()) *(=*)", convert_memref) + until count == 0 + if write then + data = data .. ")" + end + return data + end + + local function convert_output(data) + local str = "draw_text(screen," + if data["align"] then + str = str .. data["align"] + else + str = str .. "\"left\"" + end + if data["line"] then + str = str .. ",\"" .. data["line"] .. "\"" + else + str = str .. ", \"auto\"" + end + str = str .. ", nil,\"" .. data["format"] .. "\"" + if data["argument"] then + for count, block in pairs(data["argument"]) do + local expr = convert_expr(block["text"]) + if block["count"] then + for i = 0, block["count"] - 1 do + str = str .. "," .. expr:gsub("argindex", i) + end + else + str = str .. "," .. expr + end + end + end + return str .. ")" + end + + local function convert_script(data) + local str = "" + local state = "run" + for tag, block in pairs(data) do + if tag == "state" then + state = block + elseif tag == "action" then + for count, action in pairs(block) do + if action["condition"] then + str = str .. " if (" .. convert_expr(action["condition"]) .. ") then " + for expr in action["text"]:gmatch("([^,]+)") do + str = str .. convert_expr(expr) .. " " + end + str = str .. "end" + else + for expr in action["text"]:gmatch("([^,]+)") do + str = str .. " " .. convert_expr(expr) .. " " + end + end + end + elseif tag == "output" then + output = true + for count, output in pairs(block) do + if output["condition"] then + str = str .. " if " .. convert_expr(output["condition"]) .. " then " + str = str .. convert_output(output) .. " end " + else + str = str .. " " .. convert_output(output) .. " " + end + end + end + end + return state, str + end + + for count, cheat in pairs(data["cheat"]) do + spaces = {} + regions = {} + output = false + for tag, block in pairs(cheat) do + if tag == "comment" then + data["cheat"][count]["comment"] = block[1]["text"] + elseif tag == "script" then + local scripts = {} + for count2, script in pairs(block) do + local state, str = convert_script(script) + scripts[state] = str + end + data["cheat"][count]["script"] = scripts + elseif tag == "parameter" then + if block[1]["min"] then + block[1]["min"] = block[1]["min"]:gsub("%$","0x") + end + if block[1]["max"] then + block[1]["max"] = block[1]["max"]:gsub("%$","0x") + end + if block[1]["step"] then + block[1]["step"] = block[1]["step"]:gsub("%$","0x") + end + data["cheat"][count]["parameter"] = block[1] + end + end + if next(spaces) then + data["cheat"][count]["space"] = {} + for name, space in pairs(spaces) do + data["cheat"][count]["space"] = {} + data["cheat"][count]["space"][name] = { type = space["type"], tag = space["tag"] } + end + end + if next(regions) then + data["cheat"][count]["region"] = {} + for name, region in pairs(regions) do + data["cheat"][count]["region"] = {} + data["cheat"][count]["region"][name] = region + end + end + if output then + data["cheat"][count]["screen"] = {} + data["cheat"][count]["screen"]["screen"] = ":screen" + end + end + return data["cheat"] +end + +return xml |