1 #include "core/keymapper.hpp"
2 #include "lua/internal.hpp"
3 #include "core/movie.hpp"
4 #include "core/moviedata.hpp"
5 #include "core/controller.hpp"
6 #include "interface/romtype.hpp"
9 extern bool* lua_veto_flag
;
13 int input_set(lua_state
& L
, unsigned port
, unsigned controller
, unsigned index
, short value
)
15 if(!lua_input_controllerdata
)
17 lua_input_controllerdata
->axis3(port
, controller
, index
, value
);
21 int input_get(lua_state
& L
, unsigned port
, unsigned controller
, unsigned index
)
23 if(!lua_input_controllerdata
)
25 L
.pushnumber(lua_input_controllerdata
->axis3(port
, controller
, index
));
29 int input_controllertype(lua_state
& L
, unsigned port
, unsigned controller
)
31 auto& m
= get_movie();
32 controller_frame f
= m
.read_subframe(m
.get_current_frame(), 0);
33 if(port
>= f
.get_port_count()) {
37 const port_type
& p
= f
.get_port_type(port
);
38 if(controller
>= p
.controller_info
->controllers
.size())
41 L
.pushlstring(p
.controller_info
->controllers
[controller
].type
);
45 int input_seta(lua_state
& L
, unsigned port
, unsigned controller
, uint64_t base
, const char* fname
)
47 if(!lua_input_controllerdata
)
50 if(port
>= lua_input_controllerdata
->get_port_count())
52 const port_type
& pt
= lua_input_controllerdata
->get_port_type(port
);
53 if(controller
>= pt
.controller_info
->controllers
.size())
55 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++) {
56 val
= (base
>> i
) & 1;
57 L
.get_numeric_argument
<short>(i
+ base
, val
, fname
);
58 lua_input_controllerdata
->axis3(port
, controller
, i
, val
);
63 int input_geta(lua_state
& L
, unsigned port
, unsigned controller
)
65 if(!lua_input_controllerdata
)
67 if(port
>= lua_input_controllerdata
->get_port_count())
69 const port_type
& pt
= lua_input_controllerdata
->get_port_type(port
);
70 if(controller
>= pt
.controller_info
->controllers
.size())
73 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++)
74 if(lua_input_controllerdata
->axis3(port
, controller
, i
))
77 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++)
78 L
.pushnumber(lua_input_controllerdata
->axis3(port
, controller
, i
));
79 return pt
.controller_info
->controllers
[controller
].buttons
.size() + 1;
82 function_ptr_luafun
iset(lua_func_misc
, "input.set", [](lua_state
& L
, const std::string
& fname
) -> int {
83 if(!lua_input_controllerdata
)
85 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
86 unsigned index
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
87 short value
= L
.get_numeric_argument
<short>(3, fname
.c_str());
88 auto _controller
= lua_input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
89 return input_set(L
, _controller
.first
, _controller
.second
, index
, value
);
92 function_ptr_luafun
iset2(lua_func_misc
, "input.set2", [](lua_state
& L
, const std::string
& fname
) -> int {
93 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
94 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
95 unsigned index
= L
.get_numeric_argument
<unsigned>(3, fname
.c_str());
96 short value
= L
.get_numeric_argument
<short>(4, fname
.c_str());
97 return input_set(L
, port
, controller
, index
, value
);
100 function_ptr_luafun
iget(lua_func_misc
, "input.get", [](lua_state
& L
, const std::string
& fname
) -> int {
101 if(!lua_input_controllerdata
)
103 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
104 unsigned index
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
105 auto _controller
= lua_input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
106 return input_get(L
, _controller
.first
, _controller
.second
, index
);
109 function_ptr_luafun
iget2(lua_func_misc
, "input.get2", [](lua_state
& L
, const std::string
& fname
) -> int {
110 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
111 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
112 unsigned index
= L
.get_numeric_argument
<unsigned>(3, fname
.c_str());
113 return input_get(L
, port
, controller
, index
);
116 function_ptr_luafun
iseta(lua_func_misc
, "input.seta", [](lua_state
& L
, const std::string
& fname
) -> int {
117 if(!lua_input_controllerdata
)
119 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
120 uint64_t base
= L
.get_numeric_argument
<uint64_t>(2, fname
.c_str());
121 auto _controller
= lua_input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
122 return input_seta(L
, _controller
.first
, _controller
.second
, base
, fname
.c_str());
125 function_ptr_luafun
iseta2(lua_func_misc
, "input.seta2", [](lua_state
& L
, const std::string
& fname
) -> int {
126 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
127 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
128 uint64_t base
= L
.get_numeric_argument
<uint64_t>(3, fname
.c_str());
129 return input_seta(L
, port
, controller
, base
, fname
.c_str());
132 function_ptr_luafun
igeta(lua_func_misc
, "input.geta", [](lua_state
& L
, const std::string
& fname
) -> int {
133 if(!lua_input_controllerdata
)
135 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
136 auto _controller
= lua_input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
137 return input_geta(L
, _controller
.first
, _controller
.second
);
140 function_ptr_luafun
igeta2(lua_func_misc
, "input.geta2", [](lua_state
& L
, const std::string
& fname
) -> int {
141 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
142 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
143 return input_geta(L
, port
, controller
);
146 function_ptr_luafun
igett(lua_func_misc
, "input.controllertype", [](lua_state
& L
, const std::string
& fname
)
148 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
149 auto& m
= get_movie();
150 const port_type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
151 auto _controller
= s
.legacy_pcid_to_pair(controller
);
152 return input_controllertype(L
, _controller
.first
, _controller
.second
);
155 function_ptr_luafun
igett2(lua_func_misc
, "input.controllertype2", [](lua_state
& L
, const std::string
& fname
)
157 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
158 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
159 return input_controllertype(L
, port
, controller
);
162 function_ptr_luafun
ireset(lua_func_misc
, "input.reset", [](lua_state
& L
, const std::string
& fname
) -> int {
163 if(!lua_input_controllerdata
)
166 L
.get_numeric_argument(1, cycles
, fname
.c_str());
169 short lo
= cycles
% 10000;
170 short hi
= cycles
/ 10000;
171 lua_input_controllerdata
->axis3(0, 0, 1, 1);
172 lua_input_controllerdata
->axis3(0, 0, 2, hi
);
173 lua_input_controllerdata
->axis3(0, 0, 3, lo
);
177 function_ptr_luafun
iraw(lua_func_misc
, "input.raw", [](lua_state
& L
, const std::string
& fname
) -> int {
179 for(auto i
: lsnes_kbd
.all_keys()) {
180 L
.pushlstring(i
->get_name());
181 push_keygroup_parameters(L
, *i
);
187 class _keyhook_listener
: public keyboard_event_listener
189 void on_key_event(keyboard_modifier_set
& modifiers
, keyboard_key
& key
, keyboard_event
& event
)
191 lua_callback_keyhook(key
.get_name(), key
);
194 std::set
<std::string
> hooked
;
196 function_ptr_luafun
ireq(lua_func_misc
, "input.keyhook", [](lua_state
& L
, const std::string
& fname
) -> int {
198 std::string x
= L
.get_string(1, fname
.c_str());
199 state
= L
.get_bool(2, fname
.c_str());
200 keyboard_key
* key
= lsnes_kbd
.try_lookup_key(x
);
202 throw std::runtime_error("Invalid key name");
203 bool ostate
= hooked
.count(x
) > 0;
208 key
->add_listener(keyhook_listener
, true);
211 key
->remove_listener(keyhook_listener
);
216 function_ptr_luafun
ijget(lua_func_misc
, "input.joyget", [](lua_state
& L
, const std::string
& fname
) -> int {
217 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
218 if(!lua_input_controllerdata
)
220 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
222 throw std::runtime_error("Invalid controller for input.joyget");
224 const port_type
& pt
= lua_input_controllerdata
->get_port_type(pcid
.first
);
225 const port_controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
226 unsigned lcnt
= ctrl
.buttons
.size();
227 for(unsigned i
= 0; i
< lcnt
; i
++) {
228 if(ctrl
.buttons
[i
].type
== port_controller_button::TYPE_NULL
)
230 L
.pushlstring(ctrl
.buttons
[i
].name
);
231 if(ctrl
.buttons
[i
].is_analog())
232 L
.pushnumber(lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
));
233 else if(ctrl
.buttons
[i
].type
== port_controller_button::TYPE_BUTTON
)
234 L
.pushboolean(lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) != 0);
240 function_ptr_luafun
ijset(lua_func_misc
, "input.joyset", [](lua_state
& L
, const std::string
& fname
) -> int {
241 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
242 if(L
.type(2) != LUA_TTABLE
)
243 throw std::runtime_error("Invalid type for input.joyset");
244 if(!lua_input_controllerdata
)
246 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
248 throw std::runtime_error("Invalid controller for input.joyset");
249 const port_type
& pt
= lua_input_controllerdata
->get_port_type(pcid
.first
);
250 const port_controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
251 unsigned lcnt
= ctrl
.buttons
.size();
252 for(unsigned i
= 0; i
< lcnt
; i
++) {
253 if(ctrl
.buttons
[i
].type
== port_controller_button::TYPE_NULL
)
255 L
.pushlstring(ctrl
.buttons
[i
].name
);
258 if(ctrl
.buttons
[i
].is_analog()) {
259 if(L
.type(-1) == LUA_TNIL
)
260 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
264 if(L
.type(-1) == LUA_TNIL
)
265 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
266 else if(L
.type(-1) == LUA_TSTRING
)
267 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) ^ 1;
269 s
= L
.toboolean(-1) ? 1 : 0;
271 lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
, s
);
277 function_ptr_luafun
ijlcid_to_pcid(lua_func_misc
, "input.lcid_to_pcid", [](lua_state
& L
,
278 const std::string
& fname
) -> int {
279 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
280 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
283 int legacy_pcid
= -1;
284 for(unsigned i
= 0;; i
++)
286 auto p
= controls
.legacy_pcid_to_pair(i
);
287 if(p
.first
== pcid
.first
&& p
.second
== pcid
.second
) {
295 L
.pushnumber(legacy_pcid
);
297 L
.pushboolean(false);
298 L
.pushnumber(pcid
.first
);
299 L
.pushnumber(pcid
.second
);
305 function_ptr_luafun
ijlcid_to_pcid2(lua_func_misc
, "input.lcid_to_pcid2", [](lua_state
& L
,
306 const std::string
& fname
) -> int {
307 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
308 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
311 L
.pushnumber(pcid
.first
);
312 L
.pushnumber(pcid
.second
);
316 function_ptr_luafun
iporttype(lua_func_misc
, "input.port_type", [](lua_state
& L
, const std::string
& fname
)
318 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
319 auto& m
= get_movie();
320 const port_type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
322 const port_type
& p
= s
.port_type(port
);
323 L
.pushlstring(p
.name
);
330 const port_controller_set
* lookup_ps(unsigned port
)
332 auto& m
= get_movie();
333 controller_frame f
= m
.read_subframe(m
.get_current_frame(), 0);
334 const port_type
& p
= f
.get_port_type(port
);
335 return p
.controller_info
;
338 function_ptr_luafun
iveto(lua_func_misc
, "input.veto_button", [](lua_state
& L
, const std::string
& fname
)
340 if(lua_veto_flag
) *lua_veto_flag
= true;
344 function_ptr_luafun
ictrlinfo(lua_func_misc
, "input.controller_info", [](lua_state
& L
,
345 const std::string
& fname
) -> int {
346 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
347 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
348 const port_controller_set
* ps
;
350 unsigned classnum
= 1;
351 ps
= lookup_ps(port
);
352 if(!ps
|| ps
->controllers
.size() <= controller
)
354 for(unsigned i
= 0; i
< 8; i
++) {
355 auto pcid
= controls
.lcid_to_pcid(i
);
358 if(pcid
.first
== port
&& pcid
.second
== controller
) {
362 const port_controller_set
* ps2
= lookup_ps(pcid
.first
);
363 if(ps
->controllers
[controller
].cclass
== ps2
->controllers
[pcid
.second
].cclass
)
366 const port_controller
& cs
= ps
->controllers
[controller
];
368 L
.pushstring("type");
369 L
.pushlstring(cs
.type
);
371 L
.pushstring("class");
372 L
.pushlstring(cs
.cclass
);
374 L
.pushstring("classnum");
375 L
.pushnumber(classnum
);
377 L
.pushstring("lcid");
380 L
.pushstring("button_count");
381 L
.pushnumber(cs
.buttons
.size());
383 L
.pushstring("buttons");
386 for(unsigned i
= 0; i
< cs
.buttons
.size(); i
++) {
389 L
.pushstring("type");
390 switch(cs
.buttons
[i
].type
) {
391 case port_controller_button::TYPE_NULL
: L
.pushstring("null"); break;
392 case port_controller_button::TYPE_BUTTON
: L
.pushstring("button"); break;
393 case port_controller_button::TYPE_AXIS
: L
.pushstring("axis"); break;
394 case port_controller_button::TYPE_RAXIS
: L
.pushstring("raxis"); break;
395 case port_controller_button::TYPE_TAXIS
: L
.pushstring("axis"); break;
396 case port_controller_button::TYPE_LIGHTGUN
: L
.pushstring("lightgun"); break;
399 if(cs
.buttons
[i
].symbol
) {
400 L
.pushstring("symbol");
401 L
.pushlstring(&cs
.buttons
[i
].symbol
, 1);
404 if(cs
.buttons
[i
].macro
!= "") {
405 L
.pushstring("macro");
406 L
.pushlstring(cs
.buttons
[i
].macro
);
409 if(cs
.buttons
[i
].is_analog()) {
410 L
.pushstring("rmin");
411 L
.pushnumber(cs
.buttons
[i
].rmin
);
413 L
.pushstring("rmax");
414 L
.pushnumber(cs
.buttons
[i
].rmax
);
417 L
.pushstring("name");
418 L
.pushlstring(cs
.buttons
[i
].name
);
420 L
.pushstring("hidden");
421 L
.pushboolean(cs
.buttons
[i
].shadow
);