plugins/cheat: fix some stuff (nw)

This commit is contained in:
cracyc 2016-04-15 11:35:21 -05:00
parent af31c6a20e
commit c3735cd12c
4 changed files with 154 additions and 51 deletions

View File

@ -67,6 +67,7 @@ function cheat.startplugin()
local output = {} local output = {}
local line = 0 local line = 0
local start_time = 0 local start_time = 0
local stop = true
local function load_cheats() local function load_cheats()
local filename = emu.romname() local filename = emu.romname()
@ -308,10 +309,40 @@ function cheat.startplugin()
end end
end end
end end
menu[#menu + 1] = {"---", "", 0}
menu[#menu + 1] = {"Reset All", "", 0}
menu[#menu + 1] = {"Reload All", "", 0}
return menu return menu
end end
local function menu_callback(index, event) local function menu_callback(index, event)
if index > #cheats and event == "select" then
index = index - #cheats
if index == 2 then
for num, cheat in pairs(cheats) do
if cheat.script and cheat.script.off then
cheat.script.off()
end
cheat.enabled = false
if cheat.parameter then
cheat.parameter.value = cheat.parameter.min
cheat.parameter.index = 0
end
end
elseif index == 3 then
for num, cheat in pairs(cheats) do
if cheat.script and cheat.script.off then
cheat.script.off()
end
end
cheats = load_cheats()
for num, cheat in pairs(cheats) do
parse_cheat(cheat)
end
end
return true
end
local function param_calc(param) local function param_calc(param)
if param.item then if param.item then
if not param.item[param.index] then -- uh oh if not param.item[param.index] then -- uh oh
@ -429,6 +460,10 @@ function cheat.startplugin()
end, "Cheat") end, "Cheat")
emu.register_start(function() emu.register_start(function()
if not stop then
return
end
stop = false
start_time = emu.time() start_time = emu.time()
cheats = load_cheats() cheats = load_cheats()
for num, cheat in pairs(cheats) do for num, cheat in pairs(cheats) do
@ -436,7 +471,14 @@ function cheat.startplugin()
end end
end) end)
emu.register_stop(function()
stop = true
end)
emu.register_frame(function() emu.register_frame(function()
if stop then
return
end
for num, cheat in pairs(cheats) do for num, cheat in pairs(cheats) do
if cheat.enabled and cheat.script.run then if cheat.enabled and cheat.script.run then
cheat.script.run() cheat.script.run()
@ -445,6 +487,9 @@ function cheat.startplugin()
end) end)
emu.register_frame_done(function() emu.register_frame_done(function()
if stop then
return
end
line = 0 line = 0
for num, draw in pairs(output) do for num, draw in pairs(output) do
if draw.type == "text" then if draw.type == "text" then
@ -471,6 +516,21 @@ function cheat.startplugin()
manager:machine():popmessage(newcheat.desc .. " added") manager:machine():popmessage(newcheat.desc .. " added")
end end
function ce.dump(index)
cheat = cheats[index]
if cheat then
for k, v in pairs(cheat.cheat_env) do
print(k, v)
end
end
end
function ce.list()
for num, cheat in pairs(cheats) do
print(num, cheat.desc)
end
end
_G.ce = ce _G.ce = ce
end end

View File

@ -481,7 +481,7 @@ function cheatfind.startplugin()
if not _G.ce then if not _G.ce then
manager:machine():popmessage("Cheat engine not available") manager:machine():popmessage("Cheat engine not available")
else else
ce.inject(cheat) _G.ce.inject(cheat)
end end
else else

View File

@ -999,15 +999,6 @@ int lua_engine::lua_addr_space::l_mem_write(lua_State *L)
// -> manager:machine().devices[":maincpu"].spaces["program"]:read_direct_i8(0xC000) // -> manager:machine().devices[":maincpu"].spaces["program"]:read_direct_i8(0xC000)
//------------------------------------------------- //-------------------------------------------------
UINT8 lua_engine::read_direct_byte(address_space &space, offs_t addr)
{
UINT8 *base = (UINT8 *)space.get_read_ptr(space.address_to_byte(addr));
if(base)
return base[addr];
else
return 0;
}
template <typename T> template <typename T>
int lua_engine::lua_addr_space::l_direct_mem_read(lua_State *L) int lua_engine::lua_addr_space::l_direct_mem_read(lua_State *L)
{ {
@ -1015,15 +1006,18 @@ int lua_engine::lua_addr_space::l_direct_mem_read(lua_State *L)
luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected"); luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
offs_t address = lua_tounsigned(L, 2); offs_t address = lua_tounsigned(L, 2);
T mem_content = 0; T mem_content = 0;
offs_t lowmask = sp.data_width() / 8 - 1;
for(int i = 0; i < sizeof(T); i++) for(int i = 0; i < sizeof(T); i++)
{ {
UINT8 byte; int addr = sp.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + i;
UINT8 *base = (UINT8 *)sp.get_read_ptr(sp.address_to_byte(addr & ~lowmask));
if(!base)
continue;
mem_content <<= 8; mem_content <<= 8;
if(sp.endianness() == ENDIANNESS_BIG) if(sp.endianness() == ENDIANNESS_BIG)
byte = read_direct_byte(sp, address + sizeof(T) - i); mem_content |= base[BYTE8_XOR_BE(addr) & lowmask];
else else
byte = read_direct_byte(sp, address + i); mem_content |= base[BYTE8_XOR_LE(addr) & lowmask];
mem_content |= byte;
} }
if (std::numeric_limits<T>::is_signed) { if (std::numeric_limits<T>::is_signed) {
@ -1040,13 +1034,6 @@ int lua_engine::lua_addr_space::l_direct_mem_read(lua_State *L)
// -> manager:machine().devices[":maincpu"].spaces["program"]:write_direct_u16(0xC000, 0xF00D) // -> manager:machine().devices[":maincpu"].spaces["program"]:write_direct_u16(0xC000, 0xF00D)
//------------------------------------------------- //-------------------------------------------------
void lua_engine::write_direct_byte(address_space &space, offs_t addr, UINT8 byte)
{
UINT8 *base = (UINT8 *)space.get_read_ptr(space.address_to_byte(addr));
if(base)
base[addr] = byte;
}
template <typename T> template <typename T>
int lua_engine::lua_addr_space::l_direct_mem_write(lua_State *L) int lua_engine::lua_addr_space::l_direct_mem_write(lua_State *L)
{ {
@ -1055,12 +1042,17 @@ int lua_engine::lua_addr_space::l_direct_mem_write(lua_State *L)
luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected"); luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected");
offs_t address = lua_tounsigned(L, 2); offs_t address = lua_tounsigned(L, 2);
T val = lua_tounsigned(L, 3); T val = lua_tounsigned(L, 3);
offs_t lowmask = sp.data_width() / 8 - 1;
for(int i = 0; i < sizeof(T); i++) for(int i = 0; i < sizeof(T); i++)
{ {
int addr = sp.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + i;
UINT8 *base = (UINT8 *)sp.get_read_ptr(sp.address_to_byte(addr & ~lowmask));
if(!base)
continue;
if(sp.endianness() == ENDIANNESS_BIG) if(sp.endianness() == ENDIANNESS_BIG)
write_direct_byte(sp, address + sizeof(T) - i, val & 0xff); base[BYTE8_XOR_BE(addr) & lowmask] = val & 0xff;
else else
write_direct_byte(sp, address + i, val & 0xff); base[BYTE8_XOR_LE(addr) & lowmask] = val & 0xff;
val >>= 8; val >>= 8;
} }
@ -1072,14 +1064,6 @@ int lua_engine::lua_addr_space::l_direct_mem_write(lua_State *L)
// -> manager:machine():memory().region[":maincpu"]:read_i8(0xC000) // -> manager:machine():memory().region[":maincpu"]:read_i8(0xC000)
//------------------------------------------------- //-------------------------------------------------
UINT8 lua_engine::read_region_byte(memory_region &region, offs_t addr)
{
if(addr >= region.bytes())
return 0;
return region.u8(addr);
}
template <typename T> template <typename T>
int lua_engine::lua_memory_region::l_region_read(lua_State *L) int lua_engine::lua_memory_region::l_region_read(lua_State *L)
{ {
@ -1087,15 +1071,17 @@ int lua_engine::lua_memory_region::l_region_read(lua_State *L)
luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected"); luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
offs_t address = lua_tounsigned(L, 2); offs_t address = lua_tounsigned(L, 2);
T mem_content = 0; T mem_content = 0;
offs_t lowmask = region.bytewidth() - 1;
for(int i = 0; i < sizeof(T); i++) for(int i = 0; i < sizeof(T); i++)
{ {
UINT8 byte; int addr = region.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + i;
if(addr >= region.bytes())
continue;
mem_content <<= 8; mem_content <<= 8;
if(region.endianness() == ENDIANNESS_BIG) if(region.endianness() == ENDIANNESS_BIG)
byte = read_region_byte(region, address + sizeof(T) - i); mem_content |= region.u8((BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask));
else else
byte = read_region_byte(region, address + i); mem_content |= region.u8((BYTE8_XOR_LE(addr) & lowmask) | (addr & ~lowmask));
mem_content |= byte;
} }
if (std::numeric_limits<T>::is_signed) { if (std::numeric_limits<T>::is_signed) {
@ -1112,14 +1098,6 @@ int lua_engine::lua_memory_region::l_region_read(lua_State *L)
// -> manager:machine():memory().region[":maincpu"]:write_u16(0xC000, 0xF00D) // -> manager:machine():memory().region[":maincpu"]:write_u16(0xC000, 0xF00D)
//------------------------------------------------- //-------------------------------------------------
void lua_engine::write_region_byte(memory_region &region, offs_t addr, UINT8 byte)
{
if(addr >= region.bytes())
return;
region.base()[addr] = byte;
}
template <typename T> template <typename T>
int lua_engine::lua_memory_region::l_region_write(lua_State *L) int lua_engine::lua_memory_region::l_region_write(lua_State *L)
{ {
@ -1128,12 +1106,16 @@ int lua_engine::lua_memory_region::l_region_write(lua_State *L)
luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected"); luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected");
offs_t address = lua_tounsigned(L, 2); offs_t address = lua_tounsigned(L, 2);
T val = lua_tounsigned(L, 3); T val = lua_tounsigned(L, 3);
offs_t lowmask = region.bytewidth() - 1;
for(int i = 0; i < sizeof(T); i++) for(int i = 0; i < sizeof(T); i++)
{ {
int addr = region.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + i;
if(addr >= region.bytes())
continue;
if(region.endianness() == ENDIANNESS_BIG) if(region.endianness() == ENDIANNESS_BIG)
write_region_byte(region, address + sizeof(T) - i, val & 0xff); region.base()[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff;
else else
write_region_byte(region, address + i, val & 0xff); region.base()[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff;
val >>= 8; val >>= 8;
} }
@ -1738,6 +1720,68 @@ lua_engine::~lua_engine()
close(); close();
} }
int lua_engine::compile_with_env(const char *env, const char *script)
{
std::string field = std::string("env_").append(env);
lua_settop(m_lua_state, 0);
lua_getfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
if(!lua_istable(m_lua_state, -1))
{
emu_file file(m_machine->manager().options().plugins_path(), OPEN_FLAG_READ);
// optionally load a script to prepare the environment
if(file.open(env, ".lua") != osd_file::error::NONE)
{
int error = luaL_loadfile(m_lua_state, file.fullpath());
if(error || (error = lua_pcall(m_lua_state, 0, 0, 0) != LUA_OK))
{
if(error == LUA_ERRRUN)
printf("%s\n", lua_tostring(m_lua_state, -1));
lua_pop(m_lua_state, 1);
}
}
if(!lua_istable(m_lua_state, -1))
lua_newtable(m_lua_state);
lua_setfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
lua_getfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
}
if(int error = luaL_loadstring(m_lua_state, script) != LUA_OK)
{
if(error == LUA_ERRSYNTAX)
printf("%s\n", lua_tostring(m_lua_state, -1));
lua_tostring(m_lua_state, -1);
lua_pop(m_lua_state, 2);
return -1;
}
lua_pushvalue(m_lua_state, -2);
lua_setupvalue(m_lua_state, -2, 1);
int ref = luaL_ref(m_lua_state, -2);
lua_pop(m_lua_state, 1);
return ref;
}
void lua_engine::run(const char *env, int ref)
{
std::string field = std::string("env_").append(env);
lua_settop(m_lua_state, 0);
lua_getfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
if(lua_istable(m_lua_state, -1))
{
lua_rawgeti(m_lua_state, -1, ref);
if(lua_isfunction(m_lua_state, -1))
{
if(int error = lua_pcall(m_lua_state, 0, 0, 0) != LUA_OK)
{
if(error == LUA_ERRRUN)
printf("%s\n", lua_tostring(m_lua_state, -1));
lua_pop(m_lua_state, 1);
}
}
lua_pop(m_lua_state, 1);
}
lua_pop(m_lua_state, 1);
}
void lua_engine::menu_populate(std::string &menu, std::vector<menu_item> &menu_list) void lua_engine::menu_populate(std::string &menu, std::vector<menu_item> &menu_list)
{ {
std::string field = "menu_pop_" + menu; std::string field = "menu_pop_" + menu;
@ -1749,9 +1793,9 @@ void lua_engine::menu_populate(std::string &menu, std::vector<menu_item> &menu_l
lua_pop(m_lua_state, 1); lua_pop(m_lua_state, 1);
return; return;
} }
if(int error = lua_pcall(m_lua_state, 0, 1, 0)) if(int error = lua_pcall(m_lua_state, 0, 1, 0) != LUA_OK)
{ {
if(error == 2) if(error == LUA_ERRRUN)
printf("%s\n", lua_tostring(m_lua_state, -1)); printf("%s\n", lua_tostring(m_lua_state, -1));
lua_pop(m_lua_state, 1); lua_pop(m_lua_state, 1);
return; return;

View File

@ -63,6 +63,9 @@ public:
void attach_notifiers(); void attach_notifiers();
void on_frame_done(); void on_frame_done();
int compile_with_env(const char *env, const char *script);
void run(const char *env, int ref);
private: private:
struct hook { struct hook {
lua_State *L; lua_State *L;
@ -153,8 +156,6 @@ private:
int l_popmessage(lua_State *L); int l_popmessage(lua_State *L);
int l_logerror(lua_State *L); int l_logerror(lua_State *L);
}; };
static UINT8 read_direct_byte(address_space &space, offs_t addr);
static void write_direct_byte(address_space &space, offs_t addr, UINT8 byte);
struct lua_addr_space { struct lua_addr_space {
template<typename T> int l_mem_read(lua_State *L); template<typename T> int l_mem_read(lua_State *L);
template<typename T> int l_mem_write(lua_State *L); template<typename T> int l_mem_write(lua_State *L);
@ -194,8 +195,6 @@ private:
static luabridge::LuaRef l_memory_get_banks(const memory_manager *m); static luabridge::LuaRef l_memory_get_banks(const memory_manager *m);
static luabridge::LuaRef l_memory_get_regions(const memory_manager *m); static luabridge::LuaRef l_memory_get_regions(const memory_manager *m);
static UINT8 read_region_byte(memory_region &region, offs_t addr);
static void write_region_byte(memory_region &region, offs_t addr, UINT8 byte);
struct lua_memory_region { struct lua_memory_region {
template<typename T> int l_region_read(lua_State *L); template<typename T> int l_region_read(lua_State *L);
template<typename T> int l_region_write(lua_State *L); template<typename T> int l_region_write(lua_State *L);