diff --git a/include/interface/callbacks.hpp b/include/interface/callbacks.hpp index 70a9964c..f1441850 100644 --- a/include/interface/callbacks.hpp +++ b/include/interface/callbacks.hpp @@ -2,6 +2,8 @@ #define _interface__callbacks__hpp__included__ #include +#include +#include #include "library/framebuffer.hpp" /** @@ -21,6 +23,10 @@ public: * Returns the actual input value used. */ virtual int16_t set_input(unsigned port, unsigned index, unsigned control, int16_t value) = 0; +/** + * Notifies about latch. Only called on some systems. + */ + virtual void notify_latch(std::list& l) = 0; /** * Tick the RTC timer. */ diff --git a/include/library/luabase.hpp b/include/library/luabase.hpp index afc61c12..9977358d 100644 --- a/include/library/luabase.hpp +++ b/include/library/luabase.hpp @@ -86,6 +86,13 @@ public: T val; _store_tag(T& a, T v) : addr(a), val(v) {} }; + //Auxillary type for vararg-tag. + struct vararg_tag + { + std::list args; + vararg_tag(std::list& _args) : args(_args) {} + int pushargs(lua_state& L); + }; //Auxillary type for numeric-tag. template struct _numeric_tag @@ -173,6 +180,12 @@ private: tag.addr = NULL; } + template void _callback(int argc, vararg_tag tag, T... args) + { + int e = tag.pushargs(*this); + _callback(argc + e, args...); + } + template void _callback(int argc, nil_tag tag, T... args) { pushnil(); diff --git a/include/lua/lua.hpp b/include/lua/lua.hpp index a9443766..e0576cc8 100644 --- a/include/lua/lua.hpp +++ b/include/lua/lua.hpp @@ -32,6 +32,7 @@ void lua_callback_keyhook(const std::string& key, keyboard_key& p) throw(); void lua_callback_do_unsafe_rewind(const std::vector& save, uint64_t secs, uint64_t ssecs, movie& mov, void* u); bool lua_callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type); void lua_callback_movie_lost(const char* what); +void lua_callback_do_latch(std::list& args); #define LUA_TIMED_HOOK_IDLE 0 #define LUA_TIMED_HOOK_TIMER 1 diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index c6b74abd..74f7cf40 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -419,6 +419,7 @@ uint64_t audio_irq_time; uint64_t controller_irq_time; uint64_t frame_irq_time; + struct lsnes_callbacks : public emucore_callbacks { public: @@ -444,6 +445,11 @@ public: return movb.get_movie().next_input(port, index, control); } + void notify_latch(std::list& args) + { + lua_callback_do_latch(args); + } + void timer_tick(uint32_t increment, uint32_t per_second) { our_movie.rtc_subsecond += increment; @@ -493,6 +499,17 @@ public: namespace { + function_ptr_command test4(lsnes_cmd, "test4", "test", "test", + [](const std::string& args) throw(std::bad_alloc, std::runtime_error) { + std::list _args; + std::string args2 = args; + while(args2 != "") { + std::string sym; + extract_token(args2, sym, " \t"); + _args.push_back(sym); + } + lua_callback_do_latch(_args); + }); function_ptr_command<> count_rerecords(lsnes_cmd, "count-rerecords", "Count rerecords", "Syntax: count-rerecords\nCounts rerecords.\n", []() throw(std::bad_alloc, std::runtime_error) { diff --git a/src/emulation/bsnes-legacy/core.cpp b/src/emulation/bsnes-legacy/core.cpp index d5bb5eec..61bf3def 100644 --- a/src/emulation/bsnes-legacy/core.cpp +++ b/src/emulation/bsnes-legacy/core.cpp @@ -348,6 +348,12 @@ namespace return ecore_callbacks->get_randomseed(); } + void notifyLatched() + { + std::list dummy; + ecore_callbacks->notify_latch(dummy); + } + void videoRefresh(const uint32_t* data, bool hires, bool interlace, bool overscan); void audioSample(int16_t l_sample, int16_t r_sample) diff --git a/src/library/luabase.cpp b/src/library/luabase.cpp index f8ddcba3..51bb770d 100644 --- a/src/library/luabase.cpp +++ b/src/library/luabase.cpp @@ -340,3 +340,24 @@ std::string try_print_userdata(lua_state& L, int index) return i.print(L, index); return "no data available"; } + +int lua_state::vararg_tag::pushargs(lua_state& L) +{ + int e = 0; + for(auto i : args) { + if(i == "") + L.pushnil(); + else if(i == "true") + L.pushboolean(true); + else if(i == "false") + L.pushboolean(false); + else if(regex_match("[+-]?(|0|[1-9][0-9]*)(.[0-9]+)?([eE][+-]?(0|[1-9][0-9]*))?", i)) + L.pushnumber(strtod(i.c_str(), NULL)); + else if(i[0] == ':') + L.pushlstring(i.substr(1)); + else + L.pushlstring(i); + e++; + } + return e; +} diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index 099740a9..b6fd88da 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -271,6 +271,7 @@ namespace DEFINE_CB(pre_rewind); DEFINE_CB(post_rewind); DEFINE_CB(set_rewind); + DEFINE_CB(latch); } void lua_callback_do_paint(struct lua_render_context* ctx, bool non_synthetic) throw() @@ -503,6 +504,11 @@ void lua_callback_movie_lost(const char* what) run_callback(on_movie_lost, std::string(what)); } +void lua_callback_do_latch(std::list& args) +{ + run_callback(on_latch, lua_state::vararg_tag(args)); +} + bool lua_requests_repaint = false; bool lua_requests_subframe_paint = false;