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
->controller_count
)
41 L
.pushstring(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
->controller_count
)
55 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
]->button_count
; 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
->controller_count
)
73 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
]->button_count
; i
++)
74 if(lua_input_controllerdata
->axis3(port
, controller
, i
))
77 for(unsigned i
= 0; i
< pt
.controller_info
->controllers
[controller
]->button_count
; i
++)
78 L
.pushnumber(lua_input_controllerdata
->axis3(port
, controller
, i
));
79 return pt
.controller_info
->controllers
[controller
]->button_count
+ 1;
82 function_ptr_luafun
iset(LS
, "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(LS
, "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(LS
, "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(LS
, "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(LS
, "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(LS
, "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(LS
, "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(LS
, "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(LS
, "input.controllertype", [](lua_state
& L
, const std::string
& fname
) -> int {
147 unsigned controller
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
148 auto& m
= get_movie();
149 const port_type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
150 auto _controller
= s
.legacy_pcid_to_pair(controller
);
151 return input_controllertype(L
, _controller
.first
, _controller
.second
);
154 function_ptr_luafun
igett2(LS
, "input.controllertype2", [](lua_state
& L
, const std::string
& fname
) -> int {
155 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
156 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
157 return input_controllertype(L
, port
, controller
);
160 function_ptr_luafun
ireset(LS
, "input.reset", [](lua_state
& L
, const std::string
& fname
) -> int {
161 if(!lua_input_controllerdata
)
164 L
.get_numeric_argument(1, cycles
, fname
.c_str());
167 short lo
= cycles
% 10000;
168 short hi
= cycles
/ 10000;
169 lua_input_controllerdata
->axis3(0, 0, 1, 1);
170 lua_input_controllerdata
->axis3(0, 0, 2, hi
);
171 lua_input_controllerdata
->axis3(0, 0, 3, lo
);
175 function_ptr_luafun
iraw(LS
, "input.raw", [](lua_state
& L
, const std::string
& fname
) -> int {
177 for(auto i
: lsnes_kbd
.all_keys()) {
178 L
.pushstring(i
->get_name().c_str());
179 push_keygroup_parameters(L
, *i
);
185 class _keyhook_listener
: public keyboard_event_listener
187 void on_key_event(keyboard_modifier_set
& modifiers
, keyboard_key
& key
, keyboard_event
& event
)
189 lua_callback_keyhook(key
.get_name(), key
);
192 std::set
<std::string
> hooked
;
194 function_ptr_luafun
ireq(LS
, "input.keyhook", [](lua_state
& L
, const std::string
& fname
) -> int {
196 std::string x
= L
.get_string(1, fname
.c_str());
197 state
= L
.get_bool(2, fname
.c_str());
198 keyboard_key
* key
= lsnes_kbd
.try_lookup_key(x
);
200 L
.pushstring("Invalid key name");
204 bool ostate
= hooked
.count(x
) > 0;
209 key
->add_listener(keyhook_listener
, true);
212 key
->remove_listener(keyhook_listener
);
217 function_ptr_luafun
ijget(LS
, "input.joyget", [](lua_state
& L
, const std::string
& fname
) -> int {
218 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
219 if(!lua_input_controllerdata
)
221 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
223 L
.pushstring("Invalid controller for input.joyget");
228 const port_type
& pt
= lua_input_controllerdata
->get_port_type(pcid
.first
);
229 const port_controller
& ctrl
= *pt
.controller_info
->controllers
[pcid
.second
];
230 unsigned lcnt
= ctrl
.button_count
;
231 for(unsigned i
= 0; i
< lcnt
; i
++) {
232 if(ctrl
.buttons
[i
]->type
== port_controller_button::TYPE_NULL
)
234 L
.pushstring(ctrl
.buttons
[i
]->name
);
235 if(ctrl
.buttons
[i
]->is_analog())
236 L
.pushnumber(lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
));
237 else if(ctrl
.buttons
[i
]->type
== port_controller_button::TYPE_BUTTON
)
238 L
.pushboolean(lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) != 0);
244 function_ptr_luafun
ijset(LS
, "input.joyset", [](lua_state
& L
, const std::string
& fname
) -> int {
245 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
246 if(L
.type(2) != LUA_TTABLE
) {
247 L
.pushstring("Invalid type for input.joyset");
251 if(!lua_input_controllerdata
)
253 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
255 L
.pushstring("Invalid controller for input.joyset");
259 const port_type
& pt
= lua_input_controllerdata
->get_port_type(pcid
.first
);
260 const port_controller
& ctrl
= *pt
.controller_info
->controllers
[pcid
.second
];
261 unsigned lcnt
= ctrl
.button_count
;
262 for(unsigned i
= 0; i
< lcnt
; i
++) {
263 if(ctrl
.buttons
[i
]->type
== port_controller_button::TYPE_NULL
)
265 L
.pushstring(ctrl
.buttons
[i
]->name
);
268 if(ctrl
.buttons
[i
]->is_analog()) {
269 if(L
.type(-1) == LUA_TNIL
)
270 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
274 if(L
.type(-1) == LUA_TNIL
)
275 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
);
276 else if(L
.type(-1) == LUA_TSTRING
)
277 s
= lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
) ^ 1;
279 s
= L
.toboolean(-1) ? 1 : 0;
281 lua_input_controllerdata
->axis3(pcid
.first
, pcid
.second
, i
, s
);
287 function_ptr_luafun
ijlcid_to_pcid(LS
, "input.lcid_to_pcid", [](lua_state
& L
, const std::string
& fname
) ->
289 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
290 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
293 int legacy_pcid
= -1;
294 for(unsigned i
= 0;; i
++)
296 auto p
= controls
.legacy_pcid_to_pair(i
);
297 if(p
.first
== pcid
.first
&& p
.second
== pcid
.second
) {
305 L
.pushnumber(legacy_pcid
);
307 L
.pushboolean(false);
308 L
.pushnumber(pcid
.first
);
309 L
.pushnumber(pcid
.second
);
315 function_ptr_luafun
ijlcid_to_pcid2(LS
, "input.lcid_to_pcid2", [](lua_state
& L
, const std::string
& fname
) ->
317 unsigned lcid
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
318 auto pcid
= controls
.lcid_to_pcid(lcid
- 1);
321 L
.pushnumber(pcid
.first
);
322 L
.pushnumber(pcid
.second
);
326 function_ptr_luafun
iporttype(LS
, "input.port_type", [](lua_state
& L
, const std::string
& fname
) -> int {
327 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
328 auto& m
= get_movie();
329 const port_type_set
& s
= m
.read_subframe(m
.get_current_frame(), 0).porttypes();
331 const port_type
& p
= s
.port_type(port
);
332 L
.pushlstring(p
.name
);
339 const port_controller_set
* lookup_ps(unsigned port
)
341 auto& m
= get_movie();
342 controller_frame f
= m
.read_subframe(m
.get_current_frame(), 0);
343 const port_type
& p
= f
.get_port_type(port
);
344 return p
.controller_info
;
347 function_ptr_luafun
iveto(LS
, "input.veto_button", [](lua_state
& LS
, const std::string
& fname
) -> int {
348 if(lua_veto_flag
) *lua_veto_flag
= true;
352 function_ptr_luafun
ictrlinfo(LS
, "input.controller_info", [](lua_state
& L
, const std::string
& fname
) -> int {
353 unsigned port
= L
.get_numeric_argument
<unsigned>(1, fname
.c_str());
354 unsigned controller
= L
.get_numeric_argument
<unsigned>(2, fname
.c_str());
355 const port_controller_set
* ps
;
357 unsigned classnum
= 1;
358 ps
= lookup_ps(port
);
359 if(!ps
|| ps
->controller_count
<= controller
)
361 for(unsigned i
= 0; i
< 8; i
++) {
362 auto pcid
= controls
.lcid_to_pcid(i
);
365 if(pcid
.first
== port
&& pcid
.second
== controller
) {
369 const port_controller_set
* ps2
= lookup_ps(pcid
.first
);
370 if(!strcmp(ps
->controllers
[controller
]->cclass
, ps2
->controllers
[pcid
.second
]->cclass
))
373 port_controller
* cs
= ps
->controllers
[controller
];
375 L
.pushstring("type");
376 L
.pushstring(cs
->type
);
378 L
.pushstring("class");
379 L
.pushstring(cs
->cclass
);
381 L
.pushstring("classnum");
382 L
.pushnumber(classnum
);
384 L
.pushstring("lcid");
387 L
.pushstring("button_count");
388 L
.pushnumber(cs
->button_count
);
390 L
.pushstring("buttons");
393 for(unsigned i
= 0; i
< cs
->button_count
; i
++) {
396 L
.pushstring("type");
397 switch(cs
->buttons
[i
]->type
) {
398 case port_controller_button::TYPE_NULL
: L
.pushstring("null"); break;
399 case port_controller_button::TYPE_BUTTON
: L
.pushstring("button"); break;
400 case port_controller_button::TYPE_AXIS
: L
.pushstring("axis"); break;
401 case port_controller_button::TYPE_RAXIS
: L
.pushstring("raxis"); break;
402 case port_controller_button::TYPE_TAXIS
: L
.pushstring("axis"); break;
405 if(cs
->buttons
[i
]->symbol
) {
406 L
.pushstring("symbol");
407 L
.pushlstring(&cs
->buttons
[i
]->symbol
, 1);
410 L
.pushstring("name");
411 L
.pushstring(cs
->buttons
[i
]->name
);
413 L
.pushstring("hidden");
414 L
.pushboolean(cs
->buttons
[i
]->shadow
);