mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-23 23:33:45 +02:00
391 lines
15 KiB
C++
391 lines
15 KiB
C++
/*
|
|
** input-binding.h
|
|
**
|
|
** This file is part of mkxp.
|
|
**
|
|
** Copyright (C) 2013 - 2021 Amaryllis Kulla <ancurio@mapleshrine.eu>
|
|
**
|
|
** mkxp is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** mkxp is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef MKXPZ_SANDBOX_INPUT_BINDING_H
|
|
#define MKXPZ_SANDBOX_INPUT_BINDING_H
|
|
|
|
#include "sandbox.h"
|
|
#include "core.h"
|
|
#include "input.h"
|
|
#include "sharedstate.h"
|
|
|
|
namespace mkxp_sandbox {
|
|
static VALUE input_module;
|
|
static VALUE symhash;
|
|
|
|
struct {
|
|
const char *str;
|
|
Input::ButtonCode val;
|
|
} static codes[] = {
|
|
{"DOWN", Input::Down},
|
|
{"LEFT", Input::Left},
|
|
{"RIGHT", Input::Right},
|
|
{"UP", Input::Up},
|
|
{"C", Input::C},
|
|
{"Z", Input::Z},
|
|
{"A", Input::A},
|
|
{"B", Input::B},
|
|
{"X", Input::X},
|
|
{"Y", Input::Y},
|
|
{"L", Input::L},
|
|
{"R", Input::R},
|
|
{"SHIFT", Input::Shift},
|
|
{"CTRL", Input::Ctrl},
|
|
{"ALT", Input::Alt},
|
|
{"F5", Input::F5},
|
|
{"F6", Input::F6},
|
|
{"F7", Input::F7},
|
|
{"F8", Input::F8},
|
|
{"F9", Input::F9},
|
|
{"MOUSELEFT", Input::MouseLeft},
|
|
{"MOUSEMIDDLE", Input::MouseMiddle},
|
|
{"MOUSERIGHT", Input::MouseRight},
|
|
{"MOUSEX1", Input::MouseX1},
|
|
{"MOUSEX2", Input::MouseX2},
|
|
};
|
|
|
|
SANDBOX_COROUTINE(input_binding_init,
|
|
SANDBOX_COROUTINE(get_button_arg,
|
|
VALUE value;
|
|
int32_t button;
|
|
|
|
int32_t operator()(VALUE arg) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(value, rb_obj_is_kind_of, arg, sb()->rb_cInteger());
|
|
if (SANDBOX_VALUE_TO_BOOL(value)) {
|
|
SANDBOX_AWAIT_AND_SET(button, rb_num2int, arg);
|
|
} else {
|
|
SANDBOX_AWAIT_AND_SET(value, rb_obj_is_kind_of, arg, sb()->rb_cSymbol());
|
|
if (SANDBOX_VALUE_TO_BOOL(value) && rgssVer >= 3) {
|
|
SANDBOX_AWAIT_AND_SET(value, rb_ll2inum, Input::None);
|
|
SANDBOX_AWAIT_AND_SET(value, rb_hash_lookup2, symhash, arg, value);
|
|
SANDBOX_AWAIT_AND_SET(button, rb_num2int, value);
|
|
} else {
|
|
// FIXME: RMXP allows only few more types that
|
|
// don't make sense (symbols in pre 3, floats)
|
|
button = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return button;
|
|
}
|
|
)
|
|
|
|
static VALUE delta(VALUE self) {
|
|
return sb()->bind<struct rb_float_new>()()(mkxp_retro::input->getDelta());
|
|
}
|
|
|
|
static VALUE update(VALUE self) {
|
|
mkxp_retro::input->update();
|
|
return SANDBOX_NIL;
|
|
}
|
|
|
|
static VALUE press(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isPressed(button));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE trigger(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isTriggered(button));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE repeat(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isRepeated(button));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE release(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isReleased(button));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE count(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
int32_t count;
|
|
VALUE value;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
count = mkxp_retro::input->count(button);
|
|
SANDBOX_AWAIT_AND_SET(value, rb_ll2inum, count);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE time(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
double time;
|
|
VALUE value;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
time = mkxp_retro::input->repeatTime(button);
|
|
SANDBOX_AWAIT_AND_SET(value, rb_float_new, time);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE pressex(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isPressedEx(button, false));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE triggerex(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isTriggeredEx(button, false));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE repeatex(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isRepeatedEx(button, false));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE releaseex(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
return SANDBOX_BOOL_TO_VALUE(mkxp_retro::input->isReleasedEx(button, false));
|
|
}
|
|
|
|
return SANDBOX_UNDEF;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE repeatcount(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
int32_t count;
|
|
VALUE value;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
count = mkxp_retro::input->repeatcount(button, false);
|
|
SANDBOX_AWAIT_AND_SET(value, rb_ll2inum, count);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE timeex(VALUE self, VALUE code) {
|
|
SANDBOX_COROUTINE(coro,
|
|
int32_t button;
|
|
double time;
|
|
VALUE value;
|
|
|
|
VALUE operator()(VALUE self, VALUE code) {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(button, get_button_arg, code);
|
|
time = mkxp_retro::input->repeatTimeEx(button, false);
|
|
SANDBOX_AWAIT_AND_SET(value, rb_float_new, time);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
)
|
|
|
|
return sb()->bind<struct coro>()()(self, code);
|
|
}
|
|
|
|
static VALUE dir4(VALUE self) {
|
|
return sb()->bind<struct rb_ll2inum>()()(mkxp_retro::input->dir4Value());
|
|
}
|
|
|
|
static VALUE dir8(VALUE self) {
|
|
return sb()->bind<struct rb_ll2inum>()()(mkxp_retro::input->dir8Value());
|
|
}
|
|
|
|
static VALUE todo_bool(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
|
return SANDBOX_FALSE;
|
|
}
|
|
|
|
static VALUE todo_number(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
|
return sb()->bind<struct rb_ll2inum>()()(0);
|
|
}
|
|
|
|
VALUE button_val;
|
|
VALUE id_val;
|
|
size_t i;
|
|
ID id;
|
|
|
|
void operator()() {
|
|
BOOST_ASIO_CORO_REENTER (this) {
|
|
SANDBOX_AWAIT_AND_SET(input_module, rb_define_module, "Input");
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "delta", (VALUE (*)(ANYARGS))delta, 0);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "update", (VALUE (*)(ANYARGS))update, 0);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "press?", (VALUE (*)(ANYARGS))press, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "trigger?", (VALUE (*)(ANYARGS))trigger, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "repeat?", (VALUE (*)(ANYARGS))repeat, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "release?", (VALUE (*)(ANYARGS))release, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "count", (VALUE (*)(ANYARGS))count, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "time?", (VALUE (*)(ANYARGS))time, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "pressex?", (VALUE (*)(ANYARGS))pressex, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "triggerex?", (VALUE (*)(ANYARGS))triggerex, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "repeatex?", (VALUE (*)(ANYARGS))repeatex, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "releaseex?", (VALUE (*)(ANYARGS))releaseex, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "repeatcount", (VALUE (*)(ANYARGS))repeatcount, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "timeex?", (VALUE (*)(ANYARGS))timeex, 1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "dir4", (VALUE (*)(ANYARGS))dir4, 0);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "dir8", (VALUE (*)(ANYARGS))dir8, 0);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "mouse_x", (VALUE (*)(ANYARGS))todo_number, -1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "mouse_y", (VALUE (*)(ANYARGS))todo_number, -1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "scroll_v", (VALUE (*)(ANYARGS))todo_number, -1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "mouse_in_window", (VALUE (*)(ANYARGS))todo_bool, -1);
|
|
SANDBOX_AWAIT(rb_define_module_function, input_module, "mouse_in_window?", (VALUE (*)(ANYARGS))todo_bool, -1);
|
|
|
|
if (rgssVer >= 3) {
|
|
SANDBOX_AWAIT_AND_SET(symhash, rb_hash_new);
|
|
|
|
for (i = 0; i < sizeof(codes) / sizeof(*codes); ++i) {
|
|
SANDBOX_AWAIT_AND_SET(id, rb_intern, codes[i].str);
|
|
SANDBOX_AWAIT_AND_SET(button_val, rb_ll2inum, codes[i].val);
|
|
|
|
/* In RGSS3 all Input::XYZ constants are equal to :XYZ symbols,
|
|
* to be compatible with the previous convention */
|
|
SANDBOX_AWAIT_AND_SET(id_val, rb_id2sym, id);
|
|
SANDBOX_AWAIT(rb_const_set, input_module, id, id_val);
|
|
SANDBOX_AWAIT(rb_hash_aset, symhash, id_val, button_val);
|
|
}
|
|
|
|
SANDBOX_AWAIT(rb_iv_set, input_module, "buttoncodes", symhash);
|
|
} else {
|
|
for (i = 0; i < sizeof(codes) / sizeof(*codes); ++i) {
|
|
SANDBOX_AWAIT_AND_SET(id, rb_intern, codes[i].str);
|
|
SANDBOX_AWAIT_AND_SET(button_val, rb_ll2inum, codes[i].val);
|
|
SANDBOX_AWAIT(rb_const_set, input_module, id, button_val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
#endif // MKXPZ_SANDBOX_INPUT_BINDING_H
|