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
);
10 static size_t overcommit(const std::string
& name
, const std::string
& cmd
) { return 0; }
13 return ikey
.getname();
15 static int create(lua::state
& L
, lua::parameters
& P
);
17 keyboard::invbind ikey
;
20 class lua_command_binding
: public command::base
23 lua_command_binding(lua::state
& _L
, const std::string
& cmd
, int idx
)
24 : command::base(lsnes_cmd
, cmd
), L(_L
)
26 L
.pushlightuserdata(this);
28 L
.rawset(LUA_REGISTRYINDEX
);
30 void invoke(const std::string
& arguments
) throw(std::bad_alloc
, std::runtime_error
)
32 L
.pushlightuserdata(this);
33 L
.rawget(LUA_REGISTRYINDEX
);
34 L
.pushstring(arguments
.c_str());
35 int r
= L
.pcall(1, 0, 0);
38 err
= L
.get_string(-1, "Lua command callback");
39 else if(r
== LUA_ERRMEM
)
40 err
= "Out of memory";
41 else if(r
== LUA_ERRERR
)
44 err
= "Unknown error";
46 messages
<< "Error running lua command hook: " << err
<< std::endl
;
53 class lua_command_bind
56 lua_command_bind(lua::state
& L
, const std::string
& cmd
, int idx1
, int idx2
);
57 static size_t overcommit(const std::string
& cmd
, int idx1
, int idx2
) { return 0; }
62 return a
->get_name() + "," + b
->get_name();
66 static int create(lua::state
& L
, lua::parameters
& P
);
68 lua_command_binding
* a
;
69 lua_command_binding
* b
;
72 lua_inverse_bind::lua_inverse_bind(lua::state
& L
, const std::string
& name
, const std::string
& cmd
)
73 : ikey(lsnes_mapper
, cmd
, "Lua‣" + name
)
77 lua_command_bind::lua_command_bind(lua::state
& L
, const std::string
& cmd
, int idx1
, int idx2
)
79 if(L
.type(idx2
) == LUA_TFUNCTION
) {
80 a
= new lua_command_binding(L
, "+" + cmd
, idx1
);
81 b
= new lua_command_binding(L
, "-" + cmd
, idx2
);
83 a
= new lua_command_binding(L
, cmd
, idx1
);
88 lua_command_bind::~lua_command_bind()
96 int list_bindings(lua::state
& L
, lua::parameters
& P
)
100 P(P
.optional(target
, ""));
103 for(auto key
: lsnes_mapper
.get_bindings()) {
104 std::string _key
= key
;
105 std::string cmd
= lsnes_mapper
.get(key
);
106 if(target
!= "" && cmd
!= target
)
108 L
.pushlstring(_key
.c_str(), _key
.length());
109 L
.pushlstring(cmd
.c_str(), cmd
.length());
112 for(auto key
: lsnes_mapper
.get_controller_keys()) {
113 for(unsigned i
= 0;; i
++) {
114 std::string _key
= key
->get_string(i
);
117 std::string cmd
= key
->get_command();
119 if(target
!= "" && cmd
!= target
)
121 L
.pushlstring(_key
.c_str(), _key
.length());
122 L
.pushlstring(cmd
.c_str(), cmd
.length());
129 int get_alias(lua::state
& L
, lua::parameters
& P
)
135 std::string a
= lsnes_cmd
.get_alias_for(name
);
143 int set_alias(lua::state
& L
, lua::parameters
& P
)
145 std::string name
, value
;
147 P(name
, P
.optional(value
, ""));
149 lsnes_cmd
.set_alias_for(name
, value
);
150 refresh_alias_binds();
154 lua::functions
alias_fns(lua_func_misc
, "", {
155 {"list_bindings", list_bindings
},
156 {"get_alias", get_alias
},
157 {"set_alias", set_alias
},
160 lua::_class
<lua_inverse_bind
> class_inverse_bind(lua_class_bind
, "INVERSEBIND", {
161 {"new", lua_inverse_bind::create
},
162 }, {}, &lua_inverse_bind::print
);
163 lua::_class
<lua_command_bind
> class_command_bind(lua_class_bind
, "COMMANDBIND", {
164 {"new", lua_command_bind::create
},
165 }, {}, &lua_command_bind::print
);
168 int lua_inverse_bind::create(lua::state
& L
, lua::parameters
& P
)
170 std::string name
, command
;
174 lua::_class
<lua_inverse_bind
>::create(L
, name
, command
);
178 int lua_command_bind::create(lua::state
& L
, lua::parameters
& P
)
181 int lfn1
= 0, lfn2
= 0;
183 P(name
, P
.function(lfn1
));
184 if(P
.is_function() || P
.is_novalue())
187 P
.expected("function or nil");
188 lua::_class
<lua_command_bind
>::create(L
.get_master(), name
, lfn1
, lfn2
);