prosperon/source/engine/input.c

402 lines
7.9 KiB
C
Raw Normal View History

2021-11-30 21:29:18 -06:00
#include "input.h"
2022-08-26 09:19:17 -05:00
2023-05-12 13:22:05 -05:00
#include "ffi.h"
#include "font.h"
#include "log.h"
#include "script.h"
2022-08-26 09:19:17 -05:00
#include "stb_ds.h"
2023-04-25 16:59:12 -05:00
#include "time.h"
2023-05-12 13:22:05 -05:00
#include <stdio.h>
#include <ctype.h>
#include "resources.h"
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
#include "stb_ds.h"
2023-05-03 13:50:37 -05:00
2021-11-30 21:29:18 -06:00
float deltaT = 0;
2023-08-31 03:10:30 -05:00
static int mouse_states[3] = {INPUT_UP};
static int key_states[512] = {INPUT_UP};
2023-05-03 13:50:37 -05:00
JSValue jsinput;
JSValue jsnum;
JSValue jsgamepadstr[15];
JSValue jsaxesstr[4];
JSValue jsinputstate[5];
JSValue jsaxis;
JSValue jsany;
JSValue jsmouse;
JSValue jspos;
JSValue jsmove;
JSValue jsscroll;
2023-05-03 13:50:37 -05:00
cpVect mousewheel = {0,0};
2023-05-12 13:22:05 -05:00
cpVect mouse_pos = {0, 0};
cpVect mouse_delta = {0, 0};
2022-02-06 10:14:57 -06:00
2023-04-25 14:59:26 -05:00
struct joystick {
int id;
//GLFWgamepadstate state;
2023-04-25 14:59:26 -05:00
};
2022-08-26 09:19:17 -05:00
static int *downkeys = NULL;
2023-04-25 14:59:26 -05:00
static struct joystick *joysticks = NULL;
2022-08-12 14:03:56 -05:00
static int mquit = 0;
2023-04-19 15:16:35 -05:00
static struct callee pawn_callee;
2023-04-25 16:59:12 -05:00
static struct callee gamepad_callee;
2022-12-19 18:15:38 -06:00
2023-05-03 13:50:37 -05:00
static struct {
char *key;
JSValue value;
} *jshash = NULL;
2023-05-12 13:22:05 -05:00
JSValue input2js(const char *input) {
2023-05-03 13:50:37 -05:00
int idx = shgeti(jshash, input);
if (idx != -1)
return jshash[idx].value;
if (shlen(jshash) == 0)
sh_new_arena(jshash);
JSValue n = str2js(input);
shput(jshash, input, str2js(input));
return n;
}
2023-02-03 13:41:53 -06:00
void add_downkey(int key) {
for (int i = 0; i < arrlen(downkeys); i++)
if (downkeys[i] == key) return;
arrput(downkeys, key);
}
void rm_downkey(int key) {
for (int i = 0; i < arrlen(downkeys); i++)
if (downkeys[i] == key) {
arrdelswap(downkeys, i);
return;
}
}
char *mb2str(int btn)
{
switch(btn) {
case 0:
return "lm";
break;
case 1:
return "rm";
break;
case 2:
return "mm";
break;
}
return "NULLMOUSE";
2023-02-13 08:30:35 -06:00
}
void input_mouse(int btn, int state, uint32_t mod)
{
char out[16] = {0};
snprintf(out, 16, "%s%s%s%s",
mod & SAPP_MODIFIER_CTRL ? "C-" : "",
mod & SAPP_MODIFIER_ALT ? "M-" : "",
mod & SAPP_MODIFIER_SUPER ? "S-" : "",
mb2str(btn)
);
2023-09-11 17:09:21 -05:00
JSValue argv[3];
argv[0] = JS_NewString(js, "emacs");
argv[1] = JS_NewString(js, out);
2023-09-11 17:09:21 -05:00
argv[2] = jsinputstate[state];
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[0]);
JS_FreeValue(js, argv[1]);
2022-02-06 10:14:57 -06:00
}
void input_mouse_move(float x, float y, float dx, float dy, uint32_t mod)
{
mouse_pos.x = x;
mouse_pos.y = y;
mouse_delta.x = dx;
mouse_delta.y = -dy;
JSValue argv[4];
argv[0] = jsmouse;
argv[1] = jsmove;
argv[2] = vec2js(mouse_pos);
argv[3] = vec2js(mouse_delta);
script_callee(pawn_callee, 4, argv);
JS_FreeValue(js, argv[2]);
JS_FreeValue(js, argv[3]);
}
void input_mouse_scroll(float x, float y, uint32_t mod)
{
mousewheel.x = x;
mousewheel.y = y;
JSValue argv[4];
argv[0] = jsmouse;
char out[16] = {0};
snprintf(out, 16, "%s%s%sscroll",
mod & SAPP_MODIFIER_CTRL ? "C-" : "",
mod & SAPP_MODIFIER_ALT ? "M-" : "",
mod & SAPP_MODIFIER_SUPER ? "S-" : ""
);
argv[1] = JS_NewString(js,out);
argv[2] = vec2js(mousewheel);
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[1]);
JS_FreeValue(js, argv[2]);
2023-02-04 22:53:54 -06:00
}
void input_btn(int btn, int state, uint32_t mod)
{
char *keystr = keyname_extd(btn);
2023-05-12 13:22:05 -05:00
if (strlen(keystr) == 1 && mod & SAPP_MODIFIER_SHIFT)
keystr[0] = toupper(keystr[0]);
char out[16] = {0};
snprintf(out, 16, "%s%s%s%s",
mod & SAPP_MODIFIER_CTRL ? "C-" : "",
mod & SAPP_MODIFIER_ALT ? "M-" : "",
mod & SAPP_MODIFIER_SUPER ? "S-" : "",
keystr
);
JSValue argv[3];
argv[1] = JS_NewString(js, out);
argv[2] = jsinputstate[state];
argv[0] = JS_NewString(js, "emacs");
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[0]);
2023-08-22 23:19:09 -05:00
argv[0] = JS_NewString(js, "action");
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[0]);
JS_FreeValue(js, argv[1]);
if (state == INPUT_DOWN) {
key_states[btn] = INPUT_DOWN;
add_downkey(btn);
}
else if (state == INPUT_UP) {
key_states[btn] = INPUT_UP;
rm_downkey(btn);
}
}
2023-05-12 13:22:05 -05:00
2023-08-31 03:10:30 -05:00
void input_key(int key, uint32_t mod)
{
if (mod != 0) return;
JSValue argv[2];
char out[2] = {0};
out[0] = (char)key;
argv[0] = JS_NewString(js, "char");
2023-04-19 15:16:35 -05:00
argv[1] = JS_NewString(js, out);
script_callee(pawn_callee, 2, argv);
2023-04-19 15:16:35 -05:00
JS_FreeValue(js, argv[0]);
JS_FreeValue(js, argv[1]);
2023-02-13 13:35:01 -06:00
}
void register_pawn(struct callee c) {
pawn_callee = c;
}
2023-03-10 13:13:48 -06:00
void register_gamepad(struct callee c) {
gamepad_callee = c;
2023-04-25 14:59:26 -05:00
}
static void pawn_call_keydown(int key) {
JSValue argv[4];
argv[0] = jsinput;
argv[1] = jsnum;
argv[2] = jsinputstate[INPUT_DOWN];
/* TODO: Could cache */
argv[3] = JS_NewInt32(js, key);
script_callee(pawn_callee, 4, argv);
JS_FreeValue(js, argv[3]);
2023-04-25 14:59:26 -05:00
}
/*
0 free
1 lock
*/
void set_mouse_mode(int mousemode) { sapp_lock_mouse(mousemode); }
2023-05-12 13:22:05 -05:00
void input_init() {
2023-05-12 13:22:05 -05:00
jsaxesstr[0] = str2js("ljoy");
jsaxesstr[1] = str2js("rjoy");
jsaxesstr[2] = str2js("ltrigger");
jsaxesstr[3] = str2js("rtrigger");
jsaxis = str2js("axis");
jsinputstate[INPUT_UP] = str2js("released");
jsinputstate[INPUT_REPEAT] = str2js("rep");
jsinputstate[INPUT_DOWN] = str2js("pressed");
2023-05-12 13:22:05 -05:00
jsinputstate[3] = str2js("pressrep");
jsinputstate[4] = str2js("down");
jsinput = str2js("input");
jsnum = str2js("num");
jsany = str2js("any");
jsmouse = str2js("mouse");
jspos = str2js("pos");
jsmove = str2js("move");
jsscroll = str2js("scroll");
2023-03-10 13:13:48 -06:00
2023-08-31 03:10:30 -05:00
for (int i = 0; i < 512; i++)
key_states[i] = INPUT_UP;
2022-08-12 14:03:56 -05:00
2023-08-31 03:10:30 -05:00
for (int i = 0; i < 3; i++)
mouse_states[i] = INPUT_UP;
2022-12-20 08:16:26 -06:00
}
2023-04-28 20:55:24 -05:00
char keybuf[50];
const char *keyname_extd(int key) {
2023-05-12 13:22:05 -05:00
if (key > 289 && key < 302) {
int num = key - 289;
sprintf(keybuf, "f%d", num);
return keybuf;
}
if (key >= 320 && key <= 329) {
2023-05-12 13:22:05 -05:00
int num = key - 320;
sprintf(keybuf, "kp%d", num);
return keybuf;
}
2023-05-12 13:22:05 -05:00
switch (key) {
case SAPP_KEYCODE_ENTER:
return "enter";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_ESCAPE:
return "escape";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_DELETE:
return "delete";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_INSERT:
return "insert";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_TAB:
return "tab";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_RIGHT:
return "right";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_LEFT:
return "left";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_UP:
return "up";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_DOWN:
return "down";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_LEFT_SHIFT:
return "lshift";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_RIGHT_SHIFT:
return "rshift";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_LEFT_CONTROL:
return "lctrl";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_LEFT_ALT:
return "lalt";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_RIGHT_CONTROL:
return "rctrl";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_RIGHT_ALT:
return "ralt";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_SPACE:
return "space";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_KP_ADD:
return "plus";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_KP_SUBTRACT:
return "minus";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_GRAVE_ACCENT:
return "`";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_LEFT_BRACKET:
return "lbracket";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_RIGHT_BRACKET:
return "rbracket";
2023-05-12 13:22:05 -05:00
break;
case SAPP_KEYCODE_BACKSPACE:
return "backspace";
2023-05-12 13:22:05 -05:00
break;
}
2023-08-31 03:10:30 -05:00
if (key >= 32 && key <=90) {
keybuf[0] = tolower(key);
keybuf[1] = '\0';
return keybuf;
}
2023-05-12 13:22:05 -05:00
2023-02-08 15:30:12 -06:00
2023-05-12 13:22:05 -05:00
return "NULL";
2022-12-22 16:58:06 -06:00
}
2022-12-22 16:58:06 -06:00
void call_input_down(int *key) {
JSValue argv[3];
argv[0] = JS_NewString(js, "emacs");
argv[1] = input2js(keyname_extd(*key));
argv[2] = jsinputstate[4];
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[0]);
2023-04-25 14:59:26 -05:00
}
2022-12-22 16:58:06 -06:00
/* This is called once every frame - or more if we want it more! */
2023-05-12 13:22:05 -05:00
void input_poll(double wait) {
for (int i = 0; i < arrlen(downkeys); i++)
call_input_down(&downkeys[i]);
2022-12-22 16:58:06 -06:00
}
2023-02-13 08:30:35 -06:00
int key_is_num(int key) {
return key <= 57 && key >= 48;
}
void cursor_hide() { sapp_show_mouse(0); }
void cursor_show() { sapp_show_mouse(1); }
2022-08-26 09:19:17 -05:00
int action_down(int key) { return key_states[key] == INPUT_DOWN; }
int action_up(int key) { return key_states[key] == INPUT_UP; }
void quit() {
sapp_quit();
}