1 #include "core/keymapper.hpp"
2 #include "lua/internal.hpp"
3 #include "core/instance.hpp"
4 #include "core/moviedata.hpp"
5 #include "core/controller.hpp"
6 #include "interface/romtype.hpp"
11 int input_set(lua::state
& L
, unsigned port
, unsigned controller
, unsigned index
, short value
)
14 if(!core
.lua2
->input_controllerdata
)
16 core
.lua2
->input_controllerdata
->axis3(port
, controller
, index
, value
);
20 int input_get(lua::state
& L
, unsigned port
, unsigned controller
, unsigned index
)
23 if(!core
.lua2
->input_controllerdata
)
25 L
.pushnumber(core
.lua2
->input_controllerdata
->axis3(port
, controller
, index
));
29 int input_controllertype(lua::state
& L
, unsigned port
, unsigned controller
)
32 auto& m
= core
.mlogic
->get_movie();
33 portctrl::frame f
= m
.read_subframe(m
.get_current_frame(), 0);
34 if(port
>= f
.get_port_count()) {
38 const portctrl::type
& p
= f
.get_port_type(port
);
39 if(controller
>= p
.controller_info
->controllers
.size())
42 L
.pushlstring(p
.controller_info
->controllers
[controller
].type
);
46 int input_seta(lua::state
& L
, unsigned port
, unsigned controller
, uint64_t base
, lua::parameters
& P
)
49 if(!core
.lua2
->input_controllerdata
)
52 if(port
>= core
.lua2
->input_controllerdata
->get_port_count())
54 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(port
);
55 if(controller
>= pt
.controller_info
->controllers
.size())
57 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++) {
58 val
= (base
>> i
) & 1;
59 P(P
.optional(val
, val
));
60 core
.lua2
->input_controllerdata
->axis3(port
, controller
, i
, val
);
65 int input_geta(lua::state
& L
, unsigned port
, unsigned controller
)
68 if(!core
.lua2
->input_controllerdata
)
70 if(port
>= core
.lua2
->input_controllerdata
->get_port_count())
72 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(port
);
73 if(controller
>= pt
.controller_info
->controllers
.size())
76 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++)
77 if(core
.lua2
->input_controllerdata
->axis3(port
, controller
, i
))
80 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
].buttons
.size(); i
++)
81 L
.pushnumber(core
.lua2
->input_controllerdata
->axis3(port
, controller
, i
));
82 return pt
.controller_info
->controllers
[controller
].buttons
.size() + 1;
85 class _keyhook_listener
: public keyboard::event_listener
87 void on_key_event(keyboard::modifier_set
& modifiers
, keyboard::key
& key
, keyboard::event
& event
)
90 core
.lua2
->callback_keyhook(key
.get_name(), key
);
94 const portctrl::controller_set
* lookup_ps(unsigned port
)
97 auto& m
= core
.mlogic
->get_movie();
98 portctrl::frame f
= m
.read_subframe(m
.get_current_frame(), 0);
99 const portctrl::type
& p
= f
.get_port_type(port
);
100 return p
.controller_info
;
103 int set(lua::state
& L
, lua::parameters
& P
)
106 unsigned controller
, index
, value
;
108 if(!core
.lua2
->input_controllerdata
) return 0;
110 P(controller
, index
, value
);
112 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
113 return input_set(L
, _controller
.first
, _controller
.second
, index
, value
);
116 int set2(lua::state
& L
, lua::parameters
& P
)
118 unsigned port
, controller
, index
;
121 P(port
, controller
, index
, value
);
123 return input_set(L
, port
, controller
, index
, value
);
126 int get(lua::state
& L
, lua::parameters
& P
)
129 unsigned controller
, index
;
131 if(!core
.lua2
->input_controllerdata
) return 0;
133 P(controller
, index
);
135 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
136 return input_get(L
, _controller
.first
, _controller
.second
, index
);
139 int get2(lua::state
& L
, lua::parameters
& P
)
141 unsigned port
, controller
, index
;
143 P(port
, controller
, index
);
145 return input_get(L
, port
, controller
, index
);
148 int seta(lua::state
& L
, lua::parameters
& P
)
154 if(!core
.lua2
->input_controllerdata
) return 0;
158 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
159 return input_seta(L
, _controller
.first
, _controller
.second
, base
, P
);
162 int seta2(lua::state
& L
, lua::parameters
& P
)
164 unsigned port
, controller
;
167 P(port
, controller
, base
);
169 return input_seta(L
, port
, controller
, base
, P
);
172 int geta(lua::state
& L
, lua::parameters
& P
)
177 if(!core
.lua2
->input_controllerdata
) return 0;
181 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
182 return input_geta(L
, _controller
.first
, _controller
.second
);
185 int geta2(lua::state
& L
, lua::parameters
& P
)
187 unsigned port
, controller
;
191 return input_geta(L
, port
, controller
);
194 int controllertype(lua::state
& L
, lua::parameters
& P
)
201 auto& m
= core
.mlogic
->get_movie();
202 const portctrl::type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
203 auto _controller
= s
.legacy_pcid_to_pair(controller
);
204 return input_controllertype(L
, _controller
.first
, _controller
.second
);
207 int controllertype2(lua::state
& L
, lua::parameters
& P
)
209 unsigned port
, controller
;
213 return input_controllertype(L
, port
, controller
);
216 int reset(lua::state
& L
, lua::parameters
& P
)
221 if(!core
.lua2
->input_controllerdata
) return 0;
223 P(P
.optional(cycles
, 0));
227 short lo
= cycles
% 10000;
228 short hi
= cycles
/ 10000;
229 core
.lua2
->input_controllerdata
->axis3(0, 0, 1, 1);
230 core
.lua2
->input_controllerdata
->axis3(0, 0, 2, hi
);
231 core
.lua2
->input_controllerdata
->axis3(0, 0, 3, lo
);
235 int raw(lua::state
& L
, lua::parameters
& P
)
239 for(auto i
: core
.keyboard
->all_keys()) {
240 L
.pushlstring(i
->get_name());
241 push_keygroup_parameters(L
, *i
);
247 int keyhook(lua::state
& L
, lua::parameters
& P
)
255 keyboard::key
* key
= core
.keyboard
->try_lookup_key(x
);
257 throw std::runtime_error("Invalid key name");
258 bool ostate
= core
.lua2
->hooked_keys
.count(x
) > 0;
262 core
.lua2
->hooked_keys
.insert(x
);
263 key
->add_listener(S_keyhook_listener
, true);
265 core
.lua2
->hooked_keys
.erase(x
);
266 key
->remove_listener(S_keyhook_listener
);
271 int joyget(lua::state
& L
, lua::parameters
& P
)
278 if(!core
.lua2
->input_controllerdata
)
280 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
282 throw std::runtime_error("Invalid controller for input.joyget");
284 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(pcid
.first
);
285 const portctrl::controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
286 unsigned lcnt
= ctrl
.buttons
.size();
287 for(unsigned i
= 0; i
< lcnt
; i
++) {
288 if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_NULL
)
290 L
.pushlstring(ctrl
.buttons
[i
].name
);
291 if(ctrl
.buttons
[i
].is_analog())
292 L
.pushnumber(core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
));
293 else if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_BUTTON
)
294 L
.pushboolean(core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) !=
301 int joyset(lua::state
& L
, lua::parameters
& P
)
307 P(lcid
, P
.table(ltbl
));
309 if(!core
.lua2
->input_controllerdata
)
311 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
313 throw std::runtime_error("Invalid controller for input.joyset");
314 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(pcid
.first
);
315 const portctrl::controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
316 unsigned lcnt
= ctrl
.buttons
.size();
317 for(unsigned i
= 0; i
< lcnt
; i
++) {
318 if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_NULL
)
320 L
.pushlstring(ctrl
.buttons
[i
].name
);
323 if(ctrl
.buttons
[i
].is_analog()) {
324 if(L
.type(-1) == LUA_TNIL
)
325 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
329 if(L
.type(-1) == LUA_TNIL
)
330 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
331 else if(L
.type(-1) == LUA_TSTRING
)
332 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) ^ 1;
334 s
= L
.toboolean(-1) ? 1 : 0;
336 core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
, s
);
342 int lcid_to_pcid(lua::state
& L
, lua::parameters
& P
)
349 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
352 int legacy_pcid
= -1;
353 for(unsigned i
= 0;; i
++)
355 auto p
= core
.controls
->legacy_pcid_to_pair(i
);
356 if(p
.first
== pcid
.first
&& p
.second
== pcid
.second
) {
364 L
.pushnumber(legacy_pcid
);
366 L
.pushboolean(false);
367 L
.pushnumber(pcid
.first
);
368 L
.pushnumber(pcid
.second
);
372 int lcid_to_pcid2(lua::state
& L
, lua::parameters
& P
)
379 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
382 L
.pushnumber(pcid
.first
);
383 L
.pushnumber(pcid
.second
);
387 int _port_type(lua::state
& L
, lua::parameters
& P
)
394 auto& m
= core
.mlogic
->get_movie();
395 const portctrl::type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
397 const portctrl::type
& p
= s
.port_type(port
);
398 L
.pushlstring(p
.name
);
405 int veto_button(lua::state
& L
, lua::parameters
& P
)
408 if(core
.lua2
->veto_flag
) *core
.lua2
->veto_flag
= true;
412 int controller_info(lua::state
& L
, lua::parameters
& P
)
415 unsigned port
, controller
;
419 const portctrl::controller_set
* ps
;
421 unsigned classnum
= 1;
422 ps
= lookup_ps(port
);
423 if(!ps
|| ps
->controllers
.size() <= controller
)
425 for(unsigned i
= 0; i
< 8; i
++) {
426 auto pcid
= core
.controls
->lcid_to_pcid(i
);
429 if(pcid
.first
== (int)port
&& pcid
.second
== (int)controller
) {
433 const portctrl::controller_set
* ps2
= lookup_ps(pcid
.first
);
434 if(ps
->controllers
[controller
].cclass
== ps2
->controllers
[pcid
.second
].cclass
)
437 const portctrl::controller
& cs
= ps
->controllers
[controller
];
439 L
.pushstring("type");
440 L
.pushlstring(cs
.type
);
442 L
.pushstring("class");
443 L
.pushlstring(cs
.cclass
);
445 L
.pushstring("classnum");
446 L
.pushnumber(classnum
);
448 L
.pushstring("lcid");
451 L
.pushstring("button_count");
452 L
.pushnumber(cs
.buttons
.size());
454 L
.pushstring("buttons");
457 for(unsigned i
= 0; i
< cs
.buttons
.size(); i
++) {
460 L
.pushstring("type");
461 switch(cs
.buttons
[i
].type
) {
462 case portctrl::button::TYPE_NULL
: L
.pushstring("null"); break;
463 case portctrl::button::TYPE_BUTTON
: L
.pushstring("button"); break;
464 case portctrl::button::TYPE_AXIS
: L
.pushstring("axis"); break;
465 case portctrl::button::TYPE_RAXIS
: L
.pushstring("raxis"); break;
466 case portctrl::button::TYPE_TAXIS
: L
.pushstring("axis"); break;
467 case portctrl::button::TYPE_LIGHTGUN
: L
.pushstring("lightgun"); break;
470 if(cs
.buttons
[i
].symbol
) {
471 L
.pushstring("symbol");
472 L
.pushlstring(&cs
.buttons
[i
].symbol
, 1);
475 if(cs
.buttons
[i
].macro
!= "") {
476 L
.pushstring("macro");
477 L
.pushlstring(cs
.buttons
[i
].macro
);
480 if(cs
.buttons
[i
].is_analog()) {
481 L
.pushstring("rmin");
482 L
.pushnumber(cs
.buttons
[i
].rmin
);
484 L
.pushstring("rmax");
485 L
.pushnumber(cs
.buttons
[i
].rmax
);
488 L
.pushstring("name");
489 L
.pushlstring(cs
.buttons
[i
].name
);
491 L
.pushstring("hidden");
492 L
.pushboolean(cs
.buttons
[i
].shadow
);
500 lua::functions
LUA_input_fns(lua_func_misc
, "input", {
509 {"controllertype", controllertype
},
510 {"controllertype2", controllertype2
},
513 {"keyhook", keyhook
},
516 {"lcid_to_pcid", lcid_to_pcid
},
517 {"lcid_to_pcid2", lcid_to_pcid2
},
518 {"port_type", _port_type
},
519 {"veto_button", veto_button
},
520 {"controller_info", controller_info
},