1 #include "lua/internal.hpp"
2 #include "core/keymapper.hpp"
3 #include "core/command.hpp"
9 lua_inverse_bind(lua_state
& L
, const std::string
& name
, const std::string
& cmd
);
12 return ikey
.getname();
15 keyboard::invbind ikey
;
18 class lua_command_binding
: public command::base
21 lua_command_binding(lua_state
& _L
, const std::string
& cmd
, int idx
)
22 : command::base(lsnes_cmd
, cmd
), L(_L
)
24 L
.pushlightuserdata(this);
26 L
.rawset(LUA_REGISTRYINDEX
);
28 void invoke(const std::string
& arguments
) throw(std::bad_alloc
, std::runtime_error
)
30 L
.pushlightuserdata(this);
31 L
.rawget(LUA_REGISTRYINDEX
);
32 L
.pushstring(arguments
.c_str());
33 int r
= L
.pcall(1, 0, 0);
36 err
= L
.get_string(-1, "Lua command callback");
37 else if(r
== LUA_ERRMEM
)
38 err
= "Out of memory";
39 else if(r
== LUA_ERRERR
)
42 err
= "Unknown error";
44 messages
<< "Error running lua command hook: " << err
<< std::endl
;
51 class lua_command_bind
54 lua_command_bind(lua_state
& L
, const std::string
& cmd
, int idx1
, int idx2
);
59 return a
->get_name() + "," + b
->get_name();
64 lua_command_binding
* a
;
65 lua_command_binding
* b
;
68 lua_inverse_bind::lua_inverse_bind(lua_state
& L
, const std::string
& name
, const std::string
& cmd
)
69 : ikey(lsnes_mapper
, cmd
, "Lua‣" + name
)
73 lua_command_bind::lua_command_bind(lua_state
& L
, const std::string
& cmd
, int idx1
, int idx2
)
75 if(L
.type(idx2
) == LUA_TFUNCTION
) {
76 a
= new lua_command_binding(L
, "+" + cmd
, idx1
);
77 b
= new lua_command_binding(L
, "-" + cmd
, idx2
);
79 a
= new lua_command_binding(L
, cmd
, idx1
);
84 lua_command_bind::~lua_command_bind()
92 function_ptr_luafun
input_bindings(lua_func_misc
, "list_bindings", [](lua_state
& L
, const std::string
& fname
)
96 target
= L
.get_string(1, fname
.c_str());
98 for(auto key
: lsnes_mapper
.get_bindings()) {
99 std::string _key
= key
;
100 std::string cmd
= lsnes_mapper
.get(key
);
101 if(target
!= "" && cmd
!= target
)
103 L
.pushlstring(_key
.c_str(), _key
.length());
104 L
.pushlstring(cmd
.c_str(), cmd
.length());
107 for(auto key
: lsnes_mapper
.get_controller_keys()) {
108 for(unsigned i
= 0;; i
++) {
109 std::string _key
= key
->get_string(i
);
112 std::string cmd
= key
->get_command();
114 if(target
!= "" && cmd
!= target
)
116 L
.pushlstring(_key
.c_str(), _key
.length());
117 L
.pushlstring(cmd
.c_str(), cmd
.length());
124 function_ptr_luafun
get_alias(lua_func_misc
, "get_alias", [](lua_state
& L
, const std::string
& fname
) -> int {
125 std::string name
= L
.get_string(1, fname
.c_str());
126 std::string a
= lsnes_cmd
.get_alias_for(name
);
128 L
.pushlstring(a
.c_str(), a
.length());
134 function_ptr_luafun
set_alias(lua_func_misc
, "set_alias", [](lua_state
& L
, const std::string
& fname
) -> int {
135 std::string name
= L
.get_string(1, fname
.c_str());
137 if(L
.type(2) != LUA_TNIL
)
138 value
= L
.get_string(2, fname
.c_str());
139 lsnes_cmd
.set_alias_for(name
, value
);
140 refresh_alias_binds();
144 function_ptr_luafun
create_ibind(lua_func_misc
, "create_ibind", [](lua_state
& L
, const std::string
& fname
)
146 std::string name
= L
.get_string(1, fname
.c_str());
147 std::string command
= L
.get_string(2, fname
.c_str());
148 lua_inverse_bind
* b
= lua_class
<lua_inverse_bind
>::create(L
, name
, command
);
152 function_ptr_luafun
create_cmd(lua_func_misc
, "create_command", [](lua_state
& L
, const std::string
& fname
)
154 if(L
.type(2) != LUA_TFUNCTION
)
155 throw std::runtime_error("Argument 2 of create_command must be function");
156 if(L
.type(3) != LUA_TFUNCTION
&& L
.type(3) != LUA_TNIL
&& L
.type(3) != LUA_TNONE
)
157 throw std::runtime_error("Argument 2 of create_command must be function or nil");
158 std::string name
= L
.get_string(1, fname
.c_str());
159 lua_command_bind
* b
= lua_class
<lua_command_bind
>::create(L
, name
, 2, 3);
163 lua_class
<lua_inverse_bind
> class_inverse_bind("INVERSEBIND");
164 lua_class
<lua_command_bind
> class_command_bind("COMMANDBIND");