Add gamepad support
This commit is contained in:
parent
9b1cead91e
commit
dc1fda6611
3
Makefile
3
Makefile
|
@ -118,8 +118,7 @@ $(BIN)$(DIST): $(BIN)$(NAME) source/shaders/* source/scripts/* assets/*
|
||||||
@echo Creating distribution $(DIST)
|
@echo Creating distribution $(DIST)
|
||||||
@mkdir -p $(BIN)dist
|
@mkdir -p $(BIN)dist
|
||||||
@cp $(BIN)$(NAME) $(BIN)dist
|
@cp $(BIN)$(NAME) $(BIN)dist
|
||||||
@cp -rf assets/fonts $(BIN)dist
|
@cp -rf assets/* $(BIN)dist
|
||||||
@cp -rf assets/icons $(BIN)dist
|
|
||||||
@cp -rf source/shaders $(BIN)dist
|
@cp -rf source/shaders $(BIN)dist
|
||||||
@cp -r source/scripts $(BIN)dist
|
@cp -r source/scripts $(BIN)dist
|
||||||
@tar czf $(DIST) --directory $(BIN)dist .
|
@tar czf $(DIST) --directory $(BIN)dist .
|
||||||
|
|
1908
assets/data/gamecontrollerdb.txt
Normal file
1908
assets/data/gamecontrollerdb.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,13 @@ float deltaT = 0;
|
||||||
cpVect mouse_pos = {0,0};
|
cpVect mouse_pos = {0,0};
|
||||||
cpVect mouse_delta = {0,0};
|
cpVect mouse_delta = {0,0};
|
||||||
|
|
||||||
|
struct joystick {
|
||||||
|
int id;
|
||||||
|
GLFWgamepadstate state;
|
||||||
|
};
|
||||||
|
|
||||||
static int *downkeys = NULL;
|
static int *downkeys = NULL;
|
||||||
|
static struct joystick *joysticks = NULL;
|
||||||
|
|
||||||
static int mquit = 0;
|
static int mquit = 0;
|
||||||
|
|
||||||
|
@ -125,12 +131,46 @@ void char_cb(GLFWwindow *w, unsigned int codepoint)
|
||||||
|
|
||||||
static GLFWcharfun nukechar;
|
static GLFWcharfun nukechar;
|
||||||
|
|
||||||
|
void joystick_add(int id)
|
||||||
|
{
|
||||||
|
struct joystick joy = {0};
|
||||||
|
joy.id = id;
|
||||||
|
arrpush(joysticks, joy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void joystick_cb(int jid, int event)
|
||||||
|
{
|
||||||
|
YughWarn("IN joystick cb");
|
||||||
|
if (event == GLFW_CONNECTED) {
|
||||||
|
for (int i = 0; i < arrlen(joysticks); i++)
|
||||||
|
if (joysticks[i].id == jid) return;
|
||||||
|
|
||||||
|
joystick_add(jid);
|
||||||
|
} else if (event == GLFW_DISCONNECTED) {
|
||||||
|
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||||
|
if (joysticks[i].id == jid) {
|
||||||
|
arrdelswap(joysticks,i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void input_init()
|
void input_init()
|
||||||
{
|
{
|
||||||
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
|
||||||
glfwSetScrollCallback(mainwin->window, scroll_cb);
|
glfwSetScrollCallback(mainwin->window, scroll_cb);
|
||||||
glfwSetMouseButtonCallback(mainwin->window, mb_cb);
|
glfwSetMouseButtonCallback(mainwin->window, mb_cb);
|
||||||
|
glfwSetJoystickCallback(joystick_cb);
|
||||||
nukechar = glfwSetCharCallback(mainwin->window, char_cb);
|
nukechar = glfwSetCharCallback(mainwin->window, char_cb);
|
||||||
|
|
||||||
|
const char *paddb = slurp_text("data/gamecontrollerdb.txt");
|
||||||
|
glfwUpdateGamepadMappings(paddb);
|
||||||
|
free(paddb);
|
||||||
|
|
||||||
|
/* Grab all joysticks initially present */
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
if (glfwJoystickPresent(i)) joystick_add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_to_nuke()
|
void input_to_nuke()
|
||||||
|
@ -154,32 +194,13 @@ const char *keyname_extd(int key, int scancode) {
|
||||||
const char *kkey = NULL;
|
const char *kkey = NULL;
|
||||||
|
|
||||||
if (key > 289 && key < 302) {
|
if (key > 289 && key < 302) {
|
||||||
switch(key) {
|
int num = key-289;
|
||||||
case 290:
|
sprintf(keybuf, "f%d", num);
|
||||||
return "f1";
|
return keybuf;
|
||||||
case 291:
|
} else if (key >= 320 && key <= 329) {
|
||||||
return "f2";
|
int num = key-320;
|
||||||
case 292:
|
sprintf(keybuf, "kp%d",num);
|
||||||
return "f3";
|
return keybuf;
|
||||||
case 293:
|
|
||||||
return "f4";
|
|
||||||
case 294:
|
|
||||||
return "f5";
|
|
||||||
case 295:
|
|
||||||
return "f6";
|
|
||||||
case 296:
|
|
||||||
return "f7";
|
|
||||||
case 297:
|
|
||||||
return "f8";
|
|
||||||
case 298:
|
|
||||||
return "f9";
|
|
||||||
case 299:
|
|
||||||
return "f10";
|
|
||||||
case 300:
|
|
||||||
return "f11";
|
|
||||||
case 301:
|
|
||||||
return "f12";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case GLFW_KEY_ENTER:
|
case GLFW_KEY_ENTER:
|
||||||
|
@ -299,6 +320,40 @@ void call_input_down(int *key) {
|
||||||
call_input_signal(keystr);
|
call_input_signal(keystr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *gamepad2str(int btn)
|
||||||
|
{
|
||||||
|
switch(btn) {
|
||||||
|
case GLFW_GAMEPAD_BUTTON_CROSS: return "cross";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_CIRCLE: return "circle";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_SQUARE: return "square";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_TRIANGLE: return "triangle";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_START: return "start";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: return "lbump";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: return "rbump";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_GUIDE: return "guide";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_BACK: return "back";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_UP: return "dup";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_DOWN: return "ddown";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_LEFT: return "dleft";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: return "dright";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_LEFT_THUMB: return "lthumb";
|
||||||
|
case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: return "rthumb";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *axis2str(int axis)
|
||||||
|
{
|
||||||
|
switch (axis)
|
||||||
|
{
|
||||||
|
case GLFW_GAMEPAD_AXIS_LEFT_X: return "lx";
|
||||||
|
case GLFW_GAMEPAD_AXIS_LEFT_Y: return "ly";
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_X: return "rx";
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_Y: return "ry";
|
||||||
|
case GLFW_GAMEPAD_AXIS_LEFT_TRIGGER: return "ltrigger";
|
||||||
|
case GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER: return "rtrigger";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This is called once every frame - or more if we want it more! */
|
/* This is called once every frame - or more if we want it more! */
|
||||||
void input_poll(double wait)
|
void input_poll(double wait)
|
||||||
{
|
{
|
||||||
|
@ -306,10 +361,30 @@ void input_poll(double wait)
|
||||||
mouseWheelX = 0;
|
mouseWheelX = 0;
|
||||||
mouseWheelY = 0;
|
mouseWheelY = 0;
|
||||||
|
|
||||||
glfwWaitEventsTimeout(wait);
|
glfwPollEvents();
|
||||||
|
|
||||||
|
// glfwWaitEventsTimeout(wait);
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(downkeys); i++)
|
for (int i = 0; i < arrlen(downkeys); i++)
|
||||||
call_input_down(&downkeys[i]);
|
call_input_down(&downkeys[i]);
|
||||||
|
|
||||||
|
for (int i = 0; i < arrlen(joysticks); i++) {
|
||||||
|
GLFWgamepadstate state;
|
||||||
|
if (!glfwGetGamepadState(joysticks[i].id, &state)) continue;
|
||||||
|
|
||||||
|
for (int b = 0; b < 15; b++) {
|
||||||
|
if (state.buttons[b]) {
|
||||||
|
|
||||||
|
if (!joysticks[i].state.buttons[b])
|
||||||
|
YughWarn("Pressed button %s.", gamepad2str(b));
|
||||||
|
}
|
||||||
|
else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
|
||||||
|
YughWarn("Released button %s.", gamepad2str(b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joysticks[i].state = state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int key_is_num(int key) {
|
int key_is_num(int key) {
|
||||||
|
|
|
@ -70,6 +70,7 @@ void js_stacktrace()
|
||||||
void js_dump_stack()
|
void js_dump_stack()
|
||||||
{
|
{
|
||||||
JSValue exception = JS_GetException(js);
|
JSValue exception = JS_GetException(js);
|
||||||
|
if (JS_IsNull(exception)) return;
|
||||||
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
JSValue val = JS_GetPropertyStr(js, exception, "stack");
|
||||||
if (!JS_IsUndefined(val)) {
|
if (!JS_IsUndefined(val)) {
|
||||||
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
|
||||||
|
|
|
@ -41,6 +41,16 @@ var sprite = clone(component, {
|
||||||
this.sync();
|
this.sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
input_kp9_pressed() { this.pos = [0,0]; },
|
||||||
|
input_kp8_pressed() { this.pos = [-0.5,0]; },
|
||||||
|
input_kp7_pressed() { this.pos = [-1,0]; },
|
||||||
|
input_kp6_pressed() { this.pos = [0,-0.5]; },
|
||||||
|
input_kp5_pressed() { this.pos = [-0.5,-0.5]; },
|
||||||
|
input_kp4_pressed() { this.pos = [-1,-0.5]; },
|
||||||
|
input_kp3_pressed() { this.pos = [0, -1]; },
|
||||||
|
input_kp2_pressed() { this.pos = [-0.5,-1]; },
|
||||||
|
input_kp1_pressed() { this.pos = [-1,-1]; },
|
||||||
|
|
||||||
get boundingbox() {
|
get boundingbox() {
|
||||||
if (!this.gameobject) return null;
|
if (!this.gameobject) return null;
|
||||||
var dim = cmd(64, this.path);
|
var dim = cmd(64, this.path);
|
||||||
|
|
|
@ -1191,7 +1191,7 @@ var editor = {
|
||||||
if (!Keys.ctrl()) return;
|
if (!Keys.ctrl()) return;
|
||||||
|
|
||||||
if (this.edit_level.dirty) {
|
if (this.edit_level.dirty) {
|
||||||
Log.warn("Level has changed; save before starting a new one.");
|
Log.info("Level has changed; save before starting a new one.");
|
||||||
this.openpanel(gen_notify("Level is changed. Are you sure you want to close it?", _ => this.clear_level()));
|
this.openpanel(gen_notify("Level is changed. Are you sure you want to close it?", _ => this.clear_level()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2432,7 +2432,8 @@ var gen_notify = function(val, fn) {
|
||||||
var panel = Object.create(notifypanel);
|
var panel = Object.create(notifypanel);
|
||||||
panel.msg = val;
|
panel.msg = val;
|
||||||
panel.yes = fn;
|
panel.yes = fn;
|
||||||
panel.input_y_pressed = function() { panel.yes(); this.close(); };
|
panel.input_y_pressed = function() { panel.yes(); panel.close(); };
|
||||||
|
panel.input_enter_pressed = function() { panel.close(); };
|
||||||
return panel;
|
return panel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
var Log = {
|
var Log = {
|
||||||
set level(x) { cmd(92,x); },
|
set level(x) { cmd(92,x); },
|
||||||
get level() { return cmd(93); },
|
get level() { return cmd(93); },
|
||||||
|
@ -407,6 +406,22 @@ var physics = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* May be a human player; may be an AI player */
|
||||||
|
var Player = {
|
||||||
|
pawns: [],
|
||||||
|
input(fn, ...args) {
|
||||||
|
this.pawns.forEach(x => if (fn in x) x[fn](...args));
|
||||||
|
},
|
||||||
|
|
||||||
|
control(pawn) {
|
||||||
|
this.pawns.pushunique(pawn);
|
||||||
|
},
|
||||||
|
|
||||||
|
uncontrol(pawn) {
|
||||||
|
this.pawns = this.pawns.filter(x => x !== pawn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var Register = {
|
var Register = {
|
||||||
updates: [],
|
updates: [],
|
||||||
update(dt) {
|
update(dt) {
|
||||||
|
@ -433,14 +448,12 @@ var Register = {
|
||||||
this.pawns.forEach(x => {
|
this.pawns.forEach(x => {
|
||||||
if (fn in x) {
|
if (fn in x) {
|
||||||
x[fn](...args);
|
x[fn](...args);
|
||||||
return;
|
|
||||||
var f = x[fn];
|
|
||||||
if (typeof f !== 'function') return;
|
|
||||||
x.f(...args);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
controller_input(
|
||||||
|
|
||||||
debugs: [],
|
debugs: [],
|
||||||
debug() {
|
debug() {
|
||||||
this.debugs.forEach(x => x[0].call(x[1]));
|
this.debugs.forEach(x => x[0].call(x[1]));
|
||||||
|
|
5
source/scripts/play.js
Normal file
5
source/scripts/play.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
if (load("game.js") === false) {
|
||||||
|
Log.error("No game.js. No game.");
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue