diff --git a/plugins/cheat/init.lua b/plugins/cheat/init.lua index 35717e3bb0b..c15b662675f 100644 --- a/plugins/cheat/init.lua +++ b/plugins/cheat/init.lua @@ -67,6 +67,7 @@ function cheat.startplugin() local output = {} local line = 0 local start_time = 0 + local stop = true local function load_cheats() local filename = emu.romname() @@ -308,10 +309,40 @@ function cheat.startplugin() end end end + menu[#menu + 1] = {"---", "", 0} + menu[#menu + 1] = {"Reset All", "", 0} + menu[#menu + 1] = {"Reload All", "", 0} return menu end 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) if param.item then if not param.item[param.index] then -- uh oh @@ -429,6 +460,10 @@ function cheat.startplugin() end, "Cheat") emu.register_start(function() + if not stop then + return + end + stop = false start_time = emu.time() cheats = load_cheats() for num, cheat in pairs(cheats) do @@ -436,7 +471,14 @@ function cheat.startplugin() end end) + emu.register_stop(function() + stop = true + end) + emu.register_frame(function() + if stop then + return + end for num, cheat in pairs(cheats) do if cheat.enabled and cheat.script.run then cheat.script.run() @@ -445,6 +487,9 @@ function cheat.startplugin() end) emu.register_frame_done(function() + if stop then + return + end line = 0 for num, draw in pairs(output) do if draw.type == "text" then @@ -471,6 +516,21 @@ function cheat.startplugin() manager:machine():popmessage(newcheat.desc .. " added") 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 end diff --git a/plugins/cheatfind/init.lua b/plugins/cheatfind/init.lua index eadcb5b6c42..49195ed060c 100644 --- a/plugins/cheatfind/init.lua +++ b/plugins/cheatfind/init.lua @@ -481,7 +481,7 @@ function cheatfind.startplugin() if not _G.ce then manager:machine():popmessage("Cheat engine not available") else - ce.inject(cheat) + _G.ce.inject(cheat) end else diff --git a/src/emu/luaengine.cpp b/src/emu/luaengine.cpp index b1ebf60d88a..08482eccd5c 100644 --- a/src/emu/luaengine.cpp +++ b/src/emu/luaengine.cpp @@ -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) //------------------------------------------------- -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 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"); offs_t address = lua_tounsigned(L, 2); T mem_content = 0; + offs_t lowmask = sp.data_width() / 8 - 1; 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; if(sp.endianness() == ENDIANNESS_BIG) - byte = read_direct_byte(sp, address + sizeof(T) - i); + mem_content |= base[BYTE8_XOR_BE(addr) & lowmask]; else - byte = read_direct_byte(sp, address + i); - mem_content |= byte; + mem_content |= base[BYTE8_XOR_LE(addr) & lowmask]; } if (std::numeric_limits::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) //------------------------------------------------- -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 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"); offs_t address = lua_tounsigned(L, 2); T val = lua_tounsigned(L, 3); + offs_t lowmask = sp.data_width() / 8 - 1; 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) - write_direct_byte(sp, address + sizeof(T) - i, val & 0xff); + base[BYTE8_XOR_BE(addr) & lowmask] = val & 0xff; else - write_direct_byte(sp, address + i, val & 0xff); + base[BYTE8_XOR_LE(addr) & lowmask] = val & 0xff; 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) //------------------------------------------------- -UINT8 lua_engine::read_region_byte(memory_region ®ion, offs_t addr) -{ - if(addr >= region.bytes()) - return 0; - - return region.u8(addr); -} - template 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"); offs_t address = lua_tounsigned(L, 2); T mem_content = 0; + offs_t lowmask = region.bytewidth() - 1; 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; 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 - byte = read_region_byte(region, address + i); - mem_content |= byte; + mem_content |= region.u8((BYTE8_XOR_LE(addr) & lowmask) | (addr & ~lowmask)); } if (std::numeric_limits::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) //------------------------------------------------- -void lua_engine::write_region_byte(memory_region ®ion, offs_t addr, UINT8 byte) -{ - if(addr >= region.bytes()) - return; - - region.base()[addr] = byte; -} - template 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"); offs_t address = lua_tounsigned(L, 2); T val = lua_tounsigned(L, 3); + offs_t lowmask = region.bytewidth() - 1; 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) - write_region_byte(region, address + sizeof(T) - i, val & 0xff); + region.base()[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff; else - write_region_byte(region, address + i, val & 0xff); + region.base()[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff; val >>= 8; } @@ -1738,6 +1720,68 @@ lua_engine::~lua_engine() 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_list) { std::string field = "menu_pop_" + menu; @@ -1749,9 +1793,9 @@ void lua_engine::menu_populate(std::string &menu, std::vector &menu_l lua_pop(m_lua_state, 1); 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)); lua_pop(m_lua_state, 1); return; diff --git a/src/emu/luaengine.h b/src/emu/luaengine.h index aaa774d00e6..721f9728c7b 100644 --- a/src/emu/luaengine.h +++ b/src/emu/luaengine.h @@ -63,6 +63,9 @@ public: void attach_notifiers(); void on_frame_done(); + int compile_with_env(const char *env, const char *script); + void run(const char *env, int ref); + private: struct hook { lua_State *L; @@ -153,8 +156,6 @@ private: int l_popmessage(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 { template int l_mem_read(lua_State *L); template 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_regions(const memory_manager *m); - static UINT8 read_region_byte(memory_region ®ion, offs_t addr); - static void write_region_byte(memory_region ®ion, offs_t addr, UINT8 byte); struct lua_memory_region { template int l_region_read(lua_State *L); template int l_region_write(lua_State *L);