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 if(port
>= f
.get_port_count())
100 return NULL
; //Port does not exist.
101 const portctrl::type
& p
= f
.get_port_type(port
);
102 return p
.controller_info
;
105 int set(lua::state
& L
, lua::parameters
& P
)
108 unsigned controller
, index
, value
;
110 if(!core
.lua2
->input_controllerdata
) return 0;
112 P(controller
, index
, value
);
114 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
115 return input_set(L
, _controller
.first
, _controller
.second
, index
, value
);
118 int set2(lua::state
& L
, lua::parameters
& P
)
120 unsigned port
, controller
, index
;
123 P(port
, controller
, index
, value
);
125 return input_set(L
, port
, controller
, index
, value
);
128 int get(lua::state
& L
, lua::parameters
& P
)
131 unsigned controller
, index
;
133 if(!core
.lua2
->input_controllerdata
) return 0;
135 P(controller
, index
);
137 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
138 return input_get(L
, _controller
.first
, _controller
.second
, index
);
141 int get2(lua::state
& L
, lua::parameters
& P
)
143 unsigned port
, controller
, index
;
145 P(port
, controller
, index
);
147 return input_get(L
, port
, controller
, index
);
150 int seta(lua::state
& L
, lua::parameters
& P
)
156 if(!core
.lua2
->input_controllerdata
) return 0;
160 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
161 return input_seta(L
, _controller
.first
, _controller
.second
, base
, P
);
164 int seta2(lua::state
& L
, lua::parameters
& P
)
166 unsigned port
, controller
;
169 P(port
, controller
, base
);
171 return input_seta(L
, port
, controller
, base
, P
);
174 int geta(lua::state
& L
, lua::parameters
& P
)
179 if(!core
.lua2
->input_controllerdata
) return 0;
183 auto _controller
= core
.lua2
->input_controllerdata
->porttypes().legacy_pcid_to_pair(controller
);
184 return input_geta(L
, _controller
.first
, _controller
.second
);
187 int geta2(lua::state
& L
, lua::parameters
& P
)
189 unsigned port
, controller
;
193 return input_geta(L
, port
, controller
);
196 int controllertype(lua::state
& L
, lua::parameters
& P
)
203 auto& m
= core
.mlogic
->get_movie();
204 const portctrl::type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
205 auto _controller
= s
.legacy_pcid_to_pair(controller
);
206 return input_controllertype(L
, _controller
.first
, _controller
.second
);
209 int controllertype2(lua::state
& L
, lua::parameters
& P
)
211 unsigned port
, controller
;
215 return input_controllertype(L
, port
, controller
);
218 int reset(lua::state
& L
, lua::parameters
& P
)
223 if(!core
.lua2
->input_controllerdata
) return 0;
225 P(P
.optional(cycles
, 0));
229 short lo
= cycles
% 10000;
230 short hi
= cycles
/ 10000;
231 core
.lua2
->input_controllerdata
->axis3(0, 0, 1, 1);
232 core
.lua2
->input_controllerdata
->axis3(0, 0, 2, hi
);
233 core
.lua2
->input_controllerdata
->axis3(0, 0, 3, lo
);
237 int raw(lua::state
& L
, lua::parameters
& P
)
241 for(auto i
: core
.keyboard
->all_keys()) {
242 L
.pushlstring(i
->get_name());
243 push_keygroup_parameters(L
, *i
);
249 int keyhook(lua::state
& L
, lua::parameters
& P
)
257 keyboard::key
* key
= core
.keyboard
->try_lookup_key(x
);
259 throw std::runtime_error("Invalid key name");
260 bool ostate
= core
.lua2
->hooked_keys
.count(x
) > 0;
264 core
.lua2
->hooked_keys
.insert(x
);
265 key
->add_listener(S_keyhook_listener
, true);
267 core
.lua2
->hooked_keys
.erase(x
);
268 key
->remove_listener(S_keyhook_listener
);
273 int joyget(lua::state
& L
, lua::parameters
& P
)
280 if(!core
.lua2
->input_controllerdata
)
282 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
284 throw std::runtime_error("Invalid controller for input.joyget");
286 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(pcid
.first
);
287 const portctrl::controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
288 unsigned lcnt
= ctrl
.buttons
.size();
289 for(unsigned i
= 0; i
< lcnt
; i
++) {
290 if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_NULL
)
292 L
.pushlstring(ctrl
.buttons
[i
].name
);
293 if(ctrl
.buttons
[i
].is_analog())
294 L
.pushnumber(core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
));
295 else if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_BUTTON
)
296 L
.pushboolean(core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) !=
303 int joyset(lua::state
& L
, lua::parameters
& P
)
309 P(lcid
, P
.table(ltbl
));
311 if(!core
.lua2
->input_controllerdata
)
313 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
315 throw std::runtime_error("Invalid controller for input.joyset");
316 const portctrl::type
& pt
= core
.lua2
->input_controllerdata
->get_port_type(pcid
.first
);
317 const portctrl::controller
& ctrl
= pt
.controller_info
->controllers
[pcid
.second
];
318 unsigned lcnt
= ctrl
.buttons
.size();
319 for(unsigned i
= 0; i
< lcnt
; i
++) {
320 if(ctrl
.buttons
[i
].type
== portctrl::button::TYPE_NULL
)
322 L
.pushlstring(ctrl
.buttons
[i
].name
);
325 if(ctrl
.buttons
[i
].is_analog()) {
326 if(L
.type(-1) == LUA_TNIL
)
327 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
331 if(L
.type(-1) == LUA_TNIL
)
332 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
333 else if(L
.type(-1) == LUA_TSTRING
)
334 s
= core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) ^ 1;
336 s
= L
.toboolean(-1) ? 1 : 0;
338 core
.lua2
->input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
, s
);
344 int lcid_to_pcid(lua::state
& L
, lua::parameters
& P
)
351 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
354 int legacy_pcid
= -1;
355 for(unsigned i
= 0;; i
++)
357 auto p
= core
.controls
->legacy_pcid_to_pair(i
);
358 if(p
.first
== pcid
.first
&& p
.second
== pcid
.second
) {
366 L
.pushnumber(legacy_pcid
);
368 L
.pushboolean(false);
369 L
.pushnumber(pcid
.first
);
370 L
.pushnumber(pcid
.second
);
374 int lcid_to_pcid2(lua::state
& L
, lua::parameters
& P
)
381 auto pcid
= core
.controls
->lcid_to_pcid(lcid
- 1);
384 L
.pushnumber(pcid
.first
);
385 L
.pushnumber(pcid
.second
);
389 int _port_type(lua::state
& L
, lua::parameters
& P
)
396 auto& m
= core
.mlogic
->get_movie();
397 const portctrl::type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
399 const portctrl::type
& p
= s
.port_type(port
);
400 L
.pushlstring(p
.name
);
407 int veto_button(lua::state
& L
, lua::parameters
& P
)
410 if(core
.lua2
->veto_flag
) *core
.lua2
->veto_flag
= true;
414 int controller_info(lua::state
& L
, lua::parameters
& P
)
417 unsigned port
, controller
;
421 const portctrl::controller_set
* ps
;
423 unsigned classnum
= 1;
424 ps
= lookup_ps(port
);
425 if(!ps
|| ps
->controllers
.size() <= controller
)
427 for(unsigned i
= 0; i
< 8; i
++) {
428 auto pcid
= core
.controls
->lcid_to_pcid(i
);
431 if(pcid
.first
== (int)port
&& pcid
.second
== (int)controller
) {
435 const portctrl::controller_set
* ps2
= lookup_ps(pcid
.first
);
436 if(ps
->controllers
[controller
].cclass
== ps2
->controllers
[pcid
.second
].cclass
)
439 const portctrl::controller
& cs
= ps
->controllers
[controller
];
441 L
.pushstring("type");
442 L
.pushlstring(cs
.type
);
444 L
.pushstring("class");
445 L
.pushlstring(cs
.cclass
);
447 L
.pushstring("classnum");
448 L
.pushnumber(classnum
);
450 L
.pushstring("lcid");
453 L
.pushstring("button_count");
454 L
.pushnumber(cs
.buttons
.size());
456 L
.pushstring("buttons");
459 for(unsigned i
= 0; i
< cs
.buttons
.size(); i
++) {
462 L
.pushstring("type");
463 switch(cs
.buttons
[i
].type
) {
464 case portctrl::button::TYPE_NULL
: L
.pushstring("null"); break;
465 case portctrl::button::TYPE_BUTTON
: L
.pushstring("button"); break;
466 case portctrl::button::TYPE_AXIS
: L
.pushstring("axis"); break;
467 case portctrl::button::TYPE_RAXIS
: L
.pushstring("raxis"); break;
468 case portctrl::button::TYPE_TAXIS
: L
.pushstring("axis"); break;
469 case portctrl::button::TYPE_LIGHTGUN
: L
.pushstring("lightgun"); break;
472 if(cs
.buttons
[i
].symbol
) {
473 L
.pushstring("symbol");
474 L
.pushlstring(&cs
.buttons
[i
].symbol
, 1);
477 if(cs
.buttons
[i
].macro
!= "") {
478 L
.pushstring("macro");
479 L
.pushlstring(cs
.buttons
[i
].macro
);
482 if(cs
.buttons
[i
].is_analog()) {
483 L
.pushstring("rmin");
484 L
.pushnumber(cs
.buttons
[i
].rmin
);
486 L
.pushstring("rmax");
487 L
.pushnumber(cs
.buttons
[i
].rmax
);
490 L
.pushstring("name");
491 L
.pushlstring(cs
.buttons
[i
].name
);
493 L
.pushstring("hidden");
494 L
.pushboolean(cs
.buttons
[i
].shadow
);
502 lua::functions
LUA_input_fns(lua_func_misc
, "input", {
511 {"controllertype", controllertype
},
512 {"controllertype2", controllertype2
},
515 {"keyhook", keyhook
},
518 {"lcid_to_pcid", lcid_to_pcid
},
519 {"lcid_to_pcid2", lcid_to_pcid2
},
520 {"port_type", _port_type
},
521 {"veto_button", veto_button
},
522 {"controller_info", controller_info
},