summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2017-06-14 12:52:18 -0500
committer cracyc <cracyc@users.noreply.github.com>2017-06-14 12:52:18 -0500
commit1a66cfa94acd61d34749629f5ec0a1558511c753 (patch)
tree714077aaa4ccaaca28a5c72a0575d498bba852bf
parent0381699796c997baf321f42764cd33f8cc0408da (diff)
plugins/cheat: more gg and an ar decoder (nw)
-rw-r--r--plugins/cheat/cheat_simple.lua82
1 files changed, 79 insertions, 3 deletions
diff --git a/plugins/cheat/cheat_simple.lua b/plugins/cheat/cheat_simple.lua
index 61c359b44b5..998e4a7fcd1 100644
--- a/plugins/cheat/cheat_simple.lua
+++ b/plugins/cheat/cheat_simple.lua
@@ -1,11 +1,15 @@
-- converter for simple cheats
-- simple cheats are single address every frame ram or gg,ar cheats in one file called cheat.simple
+--
-- ram cheat format: <set name>,<cputag>,<hex offset>,<b|w|d|q - size>,<hex value>,<desc>
--- gg,ar cheat format: <set name>,<gg|ar - type>,<code>,<desc> like "nes/smb,gg,SXIOPO,Infinite Lives"
--- gg for game genie -- nes, snes, megadriv
--- set name is <softlist>/<entry> like "nes/smb" for softlist items
-- only program address space is supported, comments are prepended with ;
-- size is b - u8, w - u16, d - u32, q - u64
+--
+-- gg,ar cheat format: <set name>,<gg|ar - type>,<code>,<desc> like "nes/smb,gg,SXIOPO,Infinite Lives"
+-- gg for game genie -- nes, snes, megadriv, gamegear, gameboy
+-- ar for action replay -- nes
+--
+-- set name is <softlist>/<entry> like "nes/smb" for softlist items
-- Don't use commas in the description
local simple = {}
@@ -62,6 +66,21 @@ function codefuncs.nes_gg(desc, code)
return cheat
end
+function codefuncs.nes_ar(desc, code)
+ local cheat = { desc = desc, space = { cpup = { tag = ":maincpu", type = "program" } } }
+ code = code:gsub("[: %-]", "")
+ if #code ~= 8 then
+ error("error action replay cheat incorrect length " .. desc)
+ end
+ local newval = tonumber(code:sub(7, 8), 16)
+ local addr = tonumber(code:sub(3, 6), 16)
+ if not newval or not addr then
+ error("error parsing action replay cheat " .. desc)
+ end
+ cheat.script = { run = "cpup:write_u8(" .. addr .. "," .. newval .. ", true)" }
+ return cheat
+end
+
function codefuncs.snes_gg(desc, code)
local xlate = { D = 0, F = 1, ["4"] = 2, ["7"] = 3, ["0"] = 4, ["9"] = 5, ["1"] = 6, ["5"] = 7,
["6"] = 8, B = 9, C = 10, ["8"] = 11, A = 12, ["2"] = 13, ["3"] = 14, E = 15 }
@@ -137,6 +156,9 @@ function codefuncs.megadriv_gg(desc, code)
count = count + 1
value = (value << 5) | xlate[s]
end)
+ if count ~= 8 then
+ error("error game genie cheat incorrect length " .. desc)
+ end
local newval = ((value >> 32) & 0xff) | ((value >> 3) & 0x1f00) | ((value << 5) & 0xe000)
local addr = (value & 0xff00ff) | ((value >> 16) & 0xff00)
cheat.script.on = string.format([[
@@ -148,6 +170,60 @@ function codefuncs.megadriv_gg(desc, code)
return cheat
end
+local function gbgg_ggcodes(desc, code, region)
+ local cheat = { desc = desc, region = { rom = region } }
+ cheat.script = { off = "if on then rom:write_u16(addr, save) end" }
+ code = code:gsub("%-", "")
+ local comp
+ if #code == 6 then
+ comp = -1
+ elseif #code == 9 then
+ comp = ~tonumber(code:sub(7, 7) .. code:sub(9, 9), 16) & 0xff
+ comp = ((comp >> 2) | ((comp << 6) & 0xc0)) ~ 0x45
+ else
+ error("error game genie cheat incorrect length " .. desc)
+ end
+ local newval = tonumber(code:sub(1, 2), 16)
+ local addr = tonumber(code:sub(6, 6) .. code:sub(3, 5), 16)
+ if not newval or not addr or not comp then
+ error("error parsing game genie cheat " .. desc)
+ end
+ addr = (~addr & 0xf000) | (addr & 0xfff)
+ if addr > 0x7fff then
+ error("error game genie cheat bad addr " .. desc)
+ end
+ if comp == -1 then
+ cheat.script.on = string.format([[
+ addr = %d
+ save = rom:read_u8(addr)
+ on = true
+ rom:write_u8(addr, %d)
+ ]], addr, newval)
+ else
+ -- assume 8K banks
+ cheat.script.on = string.format([[
+ addr = %d
+ save = %d
+ for i = 0, rom.size, 8192 do
+ if rom:read_u8(i + addr) == save then
+ on = true
+ addr = i + addr
+ rom:write_u8(addr, %d)
+ break
+ end
+ end]], addr & 0x3fff, comp, newval)
+ end
+ return cheat
+end
+
+function codefuncs.gameboy_gg(desc, code)
+ return gbgg_ggcodes(desc, code, ":gbslot:cart:rom")
+end
+
+function codefuncs.gamegear_gg(desc, code)
+ return gbgg_ggcodes(desc, code, ":slot:cart:rom")
+end
+
function simple.conv_cheat(data)
local cheats = {}
for line in data:gmatch('([^\n;]+)') do