Merge sokol app; fix basic input

This commit is contained in:
John Alanbrook 2023-08-31 08:10:30 +00:00
commit 53ceb9bbf7
18 changed files with 398 additions and 796 deletions

View file

@ -87,7 +87,7 @@ ifeq ($(OS), WIN32)
EXT = .exe EXT = .exe
else else
LINKER_FLAGS = $(QFLAGS) -L/usr/local/lib -pthread -rdynamic LINKER_FLAGS = $(QFLAGS) -L/usr/local/lib -pthread -rdynamic
ELIBS = engine pthread quickjs glfw3 asound GL c m dl ELIBS = engine pthread yughc quickjs GL c m dl X11 Xi Xcursor EGL asound
CLIBS = CLIBS =
endif endif

View file

@ -20,9 +20,6 @@ short cbuf_shift(struct circbuf *buf);
#ifdef CBUF_IMPLEMENT #ifdef CBUF_IMPLEMENT
#include "circbuf.h"
#include "util.h"
#include "assert.h" #include "assert.h"
#include "stdlib.h" #include "stdlib.h"

View file

@ -113,7 +113,7 @@ void debug_flush(HMM_Mat4 *view)
sg_apply_pipeline(line_pipe); sg_apply_pipeline(line_pipe);
sg_apply_bindings(&line_bind); sg_apply_bindings(&line_bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view)); sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view));
float time = lastTick; float time = appTime;
sg_range tr = { sg_range tr = {
.ptr = &time, .ptr = &time,
.size = sizeof(float) .size = sizeof(float)
@ -572,8 +572,8 @@ void draw_arrow(struct cpVect start, struct cpVect end, struct rgba color, int c
void draw_grid(int width, int span, struct rgba color) void draw_grid(int width, int span, struct rgba color)
{ {
cpVect offset = cam_pos(); cpVect offset = cam_pos();
offset.x -= mainwin->width/2; offset.x -= mainwin.width/2;
offset.y -= mainwin->height/2; offset.y -= mainwin.height/2;
offset = cpvmult(offset, 1/cam_zoom()); offset = cpvmult(offset, 1/cam_zoom());
sg_apply_pipeline(grid_pipe); sg_apply_pipeline(grid_pipe);

View file

@ -38,16 +38,6 @@ void error_callback(int error, const char *description) {
} }
void engine_init() { void engine_init() {
glfwSetErrorCallback(error_callback);
/* Initialize GLFW */
if (!glfwInit()) {
YughError("Could not init GLFW. Exiting.");
exit(1);
} else {
YughInfo("Initted GLFW.");
}
resources_init(); resources_init();
YughInfo("Starting physics ..."); YughInfo("Starting physics ...");

View file

@ -400,6 +400,7 @@ JSValue duk_nuke(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
} }
JSValue duk_win_make(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { JSValue duk_win_make(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
/*
const char *title = JS_ToCString(js, argv[0]); const char *title = JS_ToCString(js, argv[0]);
int w = js2int(argv[1]); int w = js2int(argv[1]);
int h = js2int(argv[2]); int h = js2int(argv[2]);
@ -407,6 +408,8 @@ JSValue duk_win_make(JSContext *js, JSValueConst this, int argc, JSValueConst *a
JS_FreeCString(js, title); JS_FreeCString(js, title);
return JS_NewInt64(js, win->id); return JS_NewInt64(js, win->id);
*/
return JS_NULL;
} }
JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
@ -774,10 +777,10 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
return JS_NULL; return JS_NULL;
case 48: case 48:
return JS_NewInt64(js, mainwin->width); return JS_NewInt64(js, mainwin.width);
case 49: case 49:
return JS_NewInt64(js, mainwin->height); return JS_NewInt64(js, mainwin.height);
case 50: case 50:
return JS_NewBool(js, action_down(js2int(argv[1]))); return JS_NewBool(js, action_down(js2int(argv[1])));
@ -882,11 +885,9 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
return JS_NULL; return JS_NULL;
case 77: case 77:
input_to_game();
break; break;
case 78: case 78:
input_to_nuke();
break; break;
case 79: case 79:

View file

@ -15,6 +15,9 @@ int32_t mouseWheelX = 0;
int32_t mouseWheelY = 0; int32_t mouseWheelY = 0;
float deltaT = 0; float deltaT = 0;
static int mouse_states[3] = {INPUT_UP};
static int key_states[512] = {INPUT_UP};
JSValue jsinput; JSValue jsinput;
JSValue jsnum; JSValue jsnum;
JSValue jsgamepadstr[15]; JSValue jsgamepadstr[15];
@ -30,7 +33,7 @@ cpVect mouse_delta = {0, 0};
struct joystick { struct joystick {
int id; int id;
GLFWgamepadstate state; //GLFWgamepadstate state;
}; };
static int *downkeys = NULL; static int *downkeys = NULL;
@ -60,51 +63,6 @@ JSValue input2js(const char *input) {
return n; return n;
} }
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";
}
return "NOBTN";
}
void register_pawn(struct callee c) {
pawn_callee = c;
}
void register_gamepad(struct callee c) {
gamepad_callee = c;
}
void add_downkey(int key) { void add_downkey(int key) {
for (int i = 0; i < arrlen(downkeys); i++) for (int i = 0; i < arrlen(downkeys); i++)
if (downkeys[i] == key) return; if (downkeys[i] == key) return;
@ -120,81 +78,78 @@ void rm_downkey(int key) {
} }
} }
static void cursor_pos_cb(GLFWwindow *w, double xpos, double ypos) { char *mb2str(int btn)
nuke_input_cursor(xpos, ypos); {
switch(btn) {
mouse_delta.x = xpos - mouse_pos.x; case 0:
mouse_delta.y = ypos - mouse_pos.y; return "lmouse";
mouse_pos.x = xpos;
mouse_pos.y = ypos;
JSValue argv[4];
argv[0] = jsinput;
argv[1] = jsmouse;
argv[2] = jspos;
argv[3] = vec2js(mouse_pos);
script_callee(pawn_callee, 4, argv);
JS_FreeValue(js, argv[3]);
}
static void pawn_call_keydown(int key) {
JSValue argv[4];
argv[0] = jsinput;
argv[1] = jsnum;
argv[2] = jsinputstate[2];
/* TODO: Could cache */
argv[3] = JS_NewInt32(js, key);
script_callee(pawn_callee, 4, argv);
JS_FreeValue(js, argv[3]);
}
static void scroll_cb(GLFWwindow *w, double xoffset, double yoffset) {
mouseWheelY = yoffset;
mouseWheelX = xoffset;
nuke_input_scroll(xoffset, yoffset);
}
static void mb_cb(GLFWwindow *w, int button, int action, int mods) {
nuke_input_button(button, mouse_pos.x, mouse_pos.y, action == GLFW_PRESS);
JSValue argv[3];
argv[0] = jsinput;
switch (action) {
case GLFW_PRESS:
argv[2] = jsinputstate[2];
add_downkey(button);
break; break;
case 1:
case GLFW_RELEASE: return "rmouse";
rm_downkey(button);
argv[2] = jsinputstate[0];
argv[1] = jsany;
script_callee(pawn_callee, 3, argv);
break; break;
case 2:
case GLFW_REPEAT: return "mmouse";
argv[2] = jsinputstate[1];
break; break;
} }
return "NULLMOUSE";
}
argv[1] = input2js(keyname_extd(button, button)); void input_mouse(int btn, int state)
{
JSValue argv[2];
argv[0] = input2js(mb2str(btn));
argv[1] = jsinputstate[btn];
script_callee(pawn_callee, 2, argv);
}
void input_mouse_move(float x, float y, float dx, float dy)
{
mouse_pos.x = x;
mouse_pos.y = y;
mouse_delta.x = dx;
mouse_delta.y = dy;
JSValue argv[3];
argv[0] = jsmouse;
argv[1] = jspos;
argv[2] = vec2js(mouse_pos);
script_callee(pawn_callee, 3, argv); script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[2]);
} }
void set_mouse_mode(int mousemode) { void input_mouse_scroll(float x, float y)
glfwSetInputMode(mainwin->window, GLFW_CURSOR, mousemode); {
mouseWheelY = y;
mouseWheelX = x;
} }
void char_cb(GLFWwindow *w, unsigned int codepoint) { void input_btn(int btn, int state, int mod)
nuke_input_char(codepoint); {
char *keystr = keyname_extd(btn);
static char out[2] = {0}; JSValue argv[2];
static JSValue argv[2]; argv[0] = JS_NewString(js, keystr);
argv[1] = jsinputstate[state];
script_callee(pawn_callee, 2, argv);
JS_FreeValue(js, argv[0]);
out[0] = (char)codepoint; if (state == INPUT_DOWN) {
argv[0] = JS_NewString(js, "input_text"); key_states[btn] = INPUT_DOWN;
add_downkey(btn);
}
else if (state == INPUT_UP) {
key_states[btn] = INPUT_UP;
rm_downkey(btn);
}
}
void input_key(int key, uint32_t mod)
{
char out[2] = {0};
out[0] = (char)key;
JSValue argv[3];
argv[0] = JS_NewString(js, "char");
argv[1] = JS_NewString(js, out); argv[1] = JS_NewString(js, out);
script_callee(pawn_callee, 2, argv); script_callee(pawn_callee, 2, argv);
@ -202,58 +157,43 @@ void char_cb(GLFWwindow *w, unsigned int codepoint) {
JS_FreeValue(js, argv[1]); JS_FreeValue(js, argv[1]);
} }
static GLFWcharfun nukechar; void register_pawn(struct callee c) {
pawn_callee = c;
void joystick_add(int id) {
struct joystick joy = {0};
joy.id = id;
arrpush(joysticks, joy);
} }
void joystick_cb(int jid, int event) { void register_gamepad(struct callee c) {
YughWarn("IN joystick cb"); gamepad_callee = c;
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;
}
}
}
} }
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]);
}
/*
0 free
1 lock
*/
void set_mouse_mode(int mousemode) { sapp_lock_mouse(mousemode); }
void input_init() { void input_init() {
glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb);
glfwSetScrollCallback(mainwin->window, scroll_cb);
glfwSetMouseButtonCallback(mainwin->window, mb_cb);
glfwSetJoystickCallback(joystick_cb);
nukechar = glfwSetCharCallback(mainwin->window, char_cb);
char *paddb = slurp_text("data/gamecontrollerdb.txt"); char *paddb = slurp_text("data/gamecontrollerdb.txt");
glfwUpdateGamepadMappings(paddb);
free(paddb); free(paddb);
for (int b = 0; b < 15; b++)
jsgamepadstr[b] = str2js(gamepad2str(b));
jsaxesstr[0] = str2js("ljoy"); jsaxesstr[0] = str2js("ljoy");
jsaxesstr[1] = str2js("rjoy"); jsaxesstr[1] = str2js("rjoy");
jsaxesstr[2] = str2js("ltrigger"); jsaxesstr[2] = str2js("ltrigger");
jsaxesstr[3] = str2js("rtrigger"); jsaxesstr[3] = str2js("rtrigger");
jsaxis = str2js("axis"); jsaxis = str2js("axis");
jsinputstate[INPUT_UP] = str2js("released");
/* Grab all joysticks initially present */ jsinputstate[INPUT_REPEAT] = str2js("rep");
for (int i = 0; i < 16; i++) jsinputstate[INPUT_DOWN] = str2js("pressed");
if (glfwJoystickPresent(i)) joystick_add(i);
jsinputstate[0] = str2js("released");
jsinputstate[1] = str2js("rep");
jsinputstate[2] = str2js("pressed");
jsinputstate[3] = str2js("pressrep"); jsinputstate[3] = str2js("pressrep");
jsinputstate[4] = str2js("down"); jsinputstate[4] = str2js("down");
jsinput = str2js("input"); jsinput = str2js("input");
@ -261,172 +201,135 @@ void input_init() {
jsany = str2js("any"); jsany = str2js("any");
jsmouse = str2js("mouse"); jsmouse = str2js("mouse");
jspos = str2js("pos"); jspos = str2js("pos");
}
void input_to_nuke() { for (int i = 0; i < 512; i++)
glfwSetCharCallback(mainwin->window, nukechar); key_states[i] = INPUT_UP;
}
void input_to_game() { for (int i = 0; i < 3; i++)
glfwSetCharCallback(mainwin->window, char_cb); mouse_states[i] = INPUT_UP;
}
void call_input_signal(char *signal) {
JSValue s = JS_NewString(js, signal);
JS_Call(js, pawn_callee.fn, pawn_callee.obj, 1, &s);
JS_FreeValue(js, s);
} }
char keybuf[50]; char keybuf[50];
const char *keyname_extd(int key, int scancode) { const char *keyname_extd(int key) {
const char *kkey = NULL;
if (key > 289 && key < 302) { if (key > 289 && key < 302) {
int num = key - 289; int num = key - 289;
sprintf(keybuf, "f%d", num); sprintf(keybuf, "f%d", num);
return keybuf; return keybuf;
} else if (key >= 320 && key <= 329) { }
if (key >= 320 && key <= 329) {
int num = key - 320; int num = key - 320;
sprintf(keybuf, "kp%d", num); sprintf(keybuf, "kp%d", num);
return keybuf; return keybuf;
} else { }
switch (key) { switch (key) {
case GLFW_KEY_ENTER: case SAPP_KEYCODE_ENTER:
kkey = "enter"; return "enter";
break; break;
case GLFW_KEY_ESCAPE: case SAPP_KEYCODE_ESCAPE:
kkey = "escape"; return "escape";
break; break;
case GLFW_KEY_DELETE: case SAPP_KEYCODE_DELETE:
kkey = "delete"; return "delete";
break; break;
case GLFW_KEY_INSERT: case SAPP_KEYCODE_INSERT:
kkey = "insert"; return "insert";
break; break;
case GLFW_KEY_TAB: case SAPP_KEYCODE_TAB:
kkey = "tab"; return "tab";
break; break;
case GLFW_KEY_RIGHT: case SAPP_KEYCODE_RIGHT:
kkey = "right"; return "right";
break; break;
case GLFW_KEY_LEFT: case SAPP_KEYCODE_LEFT:
kkey = "left"; return "left";
break; break;
case GLFW_KEY_UP: case SAPP_KEYCODE_UP:
kkey = "up"; return "up";
break; break;
case GLFW_KEY_DOWN: case SAPP_KEYCODE_DOWN:
kkey = "down"; return "down";
break; break;
case GLFW_KEY_LEFT_SHIFT: case SAPP_KEYCODE_LEFT_SHIFT:
kkey = "lshift"; return "lshift";
break; break;
case GLFW_KEY_RIGHT_SHIFT: case SAPP_KEYCODE_RIGHT_SHIFT:
kkey = "rshift"; return "rshift";
break; break;
case GLFW_KEY_LEFT_CONTROL: case SAPP_KEYCODE_LEFT_CONTROL:
kkey = "lctrl"; return "lctrl";
break; break;
case GLFW_KEY_LEFT_ALT: case SAPP_KEYCODE_LEFT_ALT:
kkey = "lalt"; return "lalt";
break; break;
case GLFW_KEY_RIGHT_CONTROL: case SAPP_KEYCODE_RIGHT_CONTROL:
kkey = "rctrl"; return "rctrl";
break; break;
case GLFW_KEY_RIGHT_ALT: case SAPP_KEYCODE_RIGHT_ALT:
kkey = "ralt"; return "ralt";
break; break;
case GLFW_KEY_SPACE: case SAPP_KEYCODE_SPACE:
kkey = "space"; return "space";
break; break;
case GLFW_MOUSE_BUTTON_RIGHT: case SAPP_KEYCODE_KP_ADD:
kkey = "rmouse"; return "plus";
break; break;
case GLFW_MOUSE_BUTTON_LEFT: case SAPP_KEYCODE_KP_SUBTRACT:
kkey = "lmouse"; return "minus";
break;
case SAPP_KEYCODE_GRAVE_ACCENT:
return "backtick";
break; break;
case GLFW_MOUSE_BUTTON_MIDDLE: case SAPP_KEYCODE_LEFT_BRACKET:
kkey = "mmouse"; return "lbracket";
break; break;
case GLFW_KEY_KP_ADD: case SAPP_KEYCODE_RIGHT_BRACKET:
kkey = "plus"; return "rbracket";
break; break;
case GLFW_KEY_KP_SUBTRACT: case SAPP_KEYCODE_BACKSPACE:
kkey = "minus"; return "backspace";
break;
case GLFW_KEY_GRAVE_ACCENT:
kkey = "`";
break;
case GLFW_KEY_LEFT_BRACKET:
kkey = "lbracket";
break;
case GLFW_KEY_RIGHT_BRACKET:
kkey = "rbracket";
break;
case GLFW_KEY_BACKSPACE:
kkey = "backspace";
break; break;
} }
if (kkey) return kkey; if (key >= 32 && key <=90) {
keybuf[0] = tolower(key);
keybuf[1] = '\0';
return keybuf;
} }
kkey = glfwGetKeyName(key, scancode);
if (kkey) return kkey;
return "NULL"; return "NULL";
} }
void call_input_down(int *key) { void call_input_down(int *key) {
JSValue argv[3]; JSValue argv[2];
argv[0] = jsinput; argv[0] = input2js(keyname_extd(*key));
argv[1] = input2js(keyname_extd(*key, *key)); argv[1] = jsinputstate[4];
argv[2] = jsinputstate[4]; script_callee(pawn_callee, 2, argv);
script_callee(pawn_callee, 3, argv);
}
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";
}
return "NOAXIS";
} }
/* 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! */
@ -435,140 +338,19 @@ void input_poll(double wait) {
mouseWheelX = 0; mouseWheelX = 0;
mouseWheelY = 0; mouseWheelY = 0;
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;
JSValue argv[4];
argv[0] = num_cache[joysticks[i].id];
for (int b = 0; b < 15; b++) {
argv[1] = jsgamepadstr[b];
if (state.buttons[b]) {
argv[2] = num_cache[0];
script_callee(gamepad_callee, 3, argv);
if (!joysticks[i].state.buttons[b]) {
argv[2] = num_cache[1];
script_callee(gamepad_callee, 3, argv);
}
} else if (!state.buttons[b] && joysticks[i].state.buttons[b]) {
argv[2] = num_cache[2];
script_callee(gamepad_callee, 3, argv);
}
}
argv[2] = jsaxis;
float deadzone = 0.05;
for (int i = 0; i < 4; i++)
state.axes[i] = fabs(state.axes[i]) > deadzone ? state.axes[i] : 0;
argv[1] = jsaxesstr[0];
cpVect v;
v.x = state.axes[0];
v.y = -state.axes[1];
argv[3] = vec2js(v);
script_callee(gamepad_callee, 4, argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[1];
v.x = state.axes[2];
v.y = -state.axes[3];
argv[3] = vec2js(v);
script_callee(gamepad_callee, 4, argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[2];
argv[3] = num2js((state.axes[4] + 1) / 2);
script_callee(gamepad_callee, 4, argv);
JS_FreeValue(js, argv[3]);
argv[1] = jsaxesstr[3];
argv[3] = num2js((state.axes[5] + 1) / 2);
script_callee(gamepad_callee, 4, argv);
JS_FreeValue(js, argv[3]);
joysticks[i].state = state;
}
} }
int key_is_num(int key) { int key_is_num(int key) {
return key <= 57 && key >= 48; return key <= 57 && key >= 48;
} }
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) { void cursor_hide() { sapp_show_mouse(0); }
JSValue argv[3]; void cursor_show() { sapp_show_mouse(1); }
argv[0] = jsinput;
argv[1] = input2js(keyname_extd(key, scancode));
switch (action) { int action_down(int key) { return key_states[key] == INPUT_DOWN; }
case GLFW_PRESS: int action_up(int key) { return key_states[key] == INPUT_UP; }
argv[2] = jsinputstate[2];
script_callee(pawn_callee, 3, argv);
argv[2] = jsinputstate[3];
script_callee(pawn_callee, 3, argv);
add_downkey(key);
argv[1] = jsany;
argv[2] = jsinputstate[2];
script_callee(pawn_callee, 3, argv);
if (key_is_num(key))
pawn_call_keydown(key - 48);
break;
case GLFW_RELEASE:
argv[2] = jsinputstate[0];
script_callee(pawn_callee, 3, argv);
rm_downkey(key);
argv[1] = jsany;
script_callee(pawn_callee, 3, argv);
break;
case GLFW_REPEAT:
argv[2] = jsinputstate[1];
script_callee(pawn_callee, 3, argv);
argv[2] = jsinputstate[3];
script_callee(pawn_callee, 3, argv);
break;
}
}
void cursor_hide() {
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}
void cursor_show() {
glfwSetInputMode(mainwin->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}
int action_down(int scancode) {
for (int i = 0; i < arrlen(downkeys); i++) {
if (downkeys[i] == scancode)
return 1;
}
return 0;
}
int action_up(int scancode) {
int found = 0;
for (int i = 0; i < arrlen(downkeys); i++) {
if (downkeys[i] == scancode) {
found = 1;
break;
}
}
return !found;
}
int want_quit() { int want_quit() {
return mquit; return mquit;

View file

@ -1,6 +1,8 @@
#ifndef INPUT_H #ifndef INPUT_H
#define INPUT_H #define INPUT_H
#include "sokol/sokol_app.h"
#include "script.h" #include "script.h"
#include "window.h" #include "window.h"
#include <chipmunk/chipmunk.h> #include <chipmunk/chipmunk.h>
@ -12,6 +14,10 @@ extern int32_t mouseWheelY;
extern cpVect mouse_pos; extern cpVect mouse_pos;
extern cpVect mouse_delta; extern cpVect mouse_delta;
#define INPUT_DOWN 0
#define INPUT_UP 1
#define INPUT_REPEAT 2
extern float deltaT; extern float deltaT;
void input_init(); void input_init();
@ -21,9 +27,14 @@ void cursor_hide();
void cursor_show(); void cursor_show();
void set_mouse_mode(int mousemode); void set_mouse_mode(int mousemode);
void call_input_signal(char *signal); void input_mouse(int btn, int state);
const char *keyname_extd(int key, int scancode); void input_mouse_move(float x, float y, float dx, float dy);
int action_down(int scancode); void input_mouse_scroll(float x, float y);
void input_btn(int btn, int state, int mod);
void input_key(int key, uint32_t mod);
const char *keyname_extd(int key);
int action_down(int key);
void register_pawn(struct callee c); void register_pawn(struct callee c);
void register_gamepad(struct callee c); void register_gamepad(struct callee c);
@ -31,13 +42,4 @@ void register_gamepad(struct callee c);
int want_quit(); int want_quit();
void quit(); void quit();
void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods);
struct inputaction {
int scancode;
};
void input_to_nuke();
void input_to_game();
#endif #endif

View file

@ -10,9 +10,8 @@
#define SOKOL_GLCORE33 #define SOKOL_GLCORE33
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
#define SOKOL_NUKLEAR_NO_SOKOL_APP
#define SOKOL_NUKLEAR_IMPL #define SOKOL_NUKLEAR_IMPL
#include "sokol/sokol_app.h"
#include "sokol/sokol_nuklear.h" #include "sokol/sokol_nuklear.h"
#include <stdarg.h> #include <stdarg.h>
@ -28,8 +27,6 @@ struct nk_context *ctx;
//static struct nk_glfw nkglfw = {0}; //static struct nk_glfw nkglfw = {0};
void nuke_init(struct window *win) { void nuke_init(struct window *win) {
window_makecurrent(win);
snk_setup(&(snk_desc_t){ snk_setup(&(snk_desc_t){
.no_default_font = false .no_default_font = false
}); });

View file

@ -116,17 +116,12 @@ static sg_trace_hooks hooks = {
void openglInit() { void openglInit() {
if (!mainwin) {
YughError("No window to init OpenGL on.", 1);
exit(1);
}
sg_trace_hooks hh = sg_install_trace_hooks(&hooks); sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
font_init(NULL); font_init(NULL);
debugdraw_init(); debugdraw_init();
sprite_initialize(); sprite_initialize();
nuke_init(mainwin); nuke_init(&mainwin);
model_init(); model_init();
sg_color c; sg_color c;
@ -245,14 +240,14 @@ void render_winsize()
crt_post.img = sg_make_image(&(sg_image_desc){ crt_post.img = sg_make_image(&(sg_image_desc){
.render_target = true, .render_target = true,
.width = mainwin->width, .width = mainwin.width,
.height = mainwin->height .height = mainwin.height
}); });
crt_post.depth_img = sg_make_image(&(sg_image_desc){ crt_post.depth_img = sg_make_image(&(sg_image_desc){
.render_target = true, .render_target = true,
.width = mainwin->width, .width = mainwin.width,
.height = mainwin->height, .height = mainwin.height,
.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL .pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL
}); });

View file

@ -1,9 +1,6 @@
#ifndef RENDER_H #ifndef RENDER_H
#define RENDER_H #define RENDER_H
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
#include "HandmadeMath.h" #include "HandmadeMath.h"

View file

@ -16,6 +16,8 @@
#include "sys/types.h" #include "sys/types.h"
#include "time.h" #include "time.h"
#include <stdarg.h>
JSContext *js = NULL; JSContext *js = NULL;
JSRuntime *rt = NULL; JSRuntime *rt = NULL;

View file

@ -16,7 +16,6 @@
#include "dsp.h" #include "dsp.h"
#include "mix.h" #include "mix.h"
#define SOKOL_AUDIO_IMPL
#include "sokol/sokol_audio.h" #include "sokol/sokol_audio.h"
#define TSF_IMPLEMENTATION #define TSF_IMPLEMENTATION

View file

@ -82,7 +82,6 @@ void play_song(const char *midi, const char *sf)
cursong.data = &gsong; cursong.data = &gsong;
cursong.filter = dsp_midi_fillbuf; cursong.filter = dsp_midi_fillbuf;
musicbus = first_free_bus(cursong); musicbus = first_free_bus(cursong);
YughWarn("DID IT");
} }
void music_play() void music_play()

View file

@ -13,203 +13,46 @@
#include "stb_ds.h" #include "stb_ds.h"
struct window *mainwin; struct window mainwin;
static struct window *windows = NULL; static struct window *windows = NULL;
struct Texture *icon = NULL; struct Texture *icon = NULL;
int is_win(struct window *s, GLFWwindow *w) { void window_resize(int width, int height)
return s->window == w; {
} mainwin.width = width;
mainwin.height = height;
void window_size_callback(GLFWwindow *w, int width, int height) {
render_winsize(); render_winsize();
}
struct window *winfind(GLFWwindow *w) {
for (int i = 0; i < arrlen(windows); i++) {
if (windows[i].window == w)
return &windows[i];
}
return NULL;
}
void window_iconify_callback(GLFWwindow *w, int iconified) {
struct window *win = winfind(w);
win->iconified = iconified;
}
void window_focus_callback(GLFWwindow *w, int focused) {
struct window *win = winfind(w);
win->mouseFocus = focused;
}
void window_maximize_callback(GLFWwindow *w, int maximized) {
struct window *win = winfind(w);
win->minimized = !maximized;
}
void window_framebuffer_size_cb(GLFWwindow *w, int width, int height) {
struct window *win = mainwin;
win->width = width;
win->height = height;
window_makecurrent(win);
win->render = 1;
JSValue vals[2] = { int2js(width), int2js(height) }; JSValue vals[2] = { int2js(width), int2js(height) };
send_signal("window_resize", 2, vals); send_signal("window_resize", 2, vals);
} }
void window_close_callback(GLFWwindow *w) { void window_quit()
{
quit(); quit();
} }
struct window *MakeSDLWindow(const char *name, int width, int height, uint32_t flags) { void window_focused(int focus)
if (arrcap(windows) == 0) {
arrsetcap(windows, 5); mainwin.focus = focus;
}
if (mainwin != NULL) void window_iconified(int s)
return mainwin; {
mainwin.iconified = s;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES,1);
struct window w = { void window_suspended(int s)
.width = width, {
.height = height,
.id = arrlen(windows),
.window = glfwCreateWindow(width, height, name, NULL, mainwin)};
if (!w.window) {
YughError("Couldn't make GLFW window\n", 1);
return NULL;
}
mainwin = malloc(sizeof(struct window));
*mainwin = w;
glfwMakeContextCurrent(w.window);
YughInfo("Loaded OpenGL %d.%d", 3, 3);
glfwSwapInterval(1);
// Set callbacks
glfwSetWindowCloseCallback(w.window, window_close_callback);
glfwSetWindowSizeCallback(w.window, window_size_callback);
glfwSetFramebufferSizeCallback(w.window, window_framebuffer_size_cb);
glfwSetWindowFocusCallback(w.window, window_focus_callback);
glfwSetKeyCallback(w.window, win_key_callback);
arrput(windows, w);
if (arrlen(windows) == 1)
mainwin = &windows[0];
window_framebuffer_size_cb(mainwin, width, height);
return &arrlast(windows);
} }
void window_set_icon(const char *png) { void window_set_icon(const char *png) {
icon = texture_pullfromfile(png); icon = texture_pullfromfile(png);
window_seticon(mainwin, icon); window_seticon(&mainwin, icon);
}
void window_destroy(struct window *w) {
glfwDestroyWindow(w->window);
arrdelswap(windows, w->id);
}
struct window *window_i(int index) {
return &windows[index];
}
void window_handle_event(struct window *w) {
/*
if (e->type == SDL_WINDOWEVENT && e->window.windowID == w->id) { // TODO: Check ptr direct?
switch (e->window.event) {
case SDL_WINDOWEVENT_SHOWN:
YughLog(0, SDL_LOG_PRIORITY_INFO, "Showed window %d.", w->id);
w->shown = true;
break;
case SDL_WINDOWEVENT_HIDDEN:
w->shown = false;
YughLog(0, SDL_LOG_PRIORITY_INFO, "Hid window %d.", w->id);
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
w->width = e->window.data1;
w->height = e->window.data2;
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Changed size of window %d: width %d, height %d.",
w->id, w->width, w->height);
window_makecurrent(w);
w->render = true;
break;
case SDL_WINDOWEVENT_EXPOSED:
YughLog(0, SDL_LOG_PRIORITY_INFO, "Exposed window %d.", w->id);
w->render = true;
break;
case SDL_WINDOWEVENT_ENTER:
YughLog(0, SDL_LOG_PRIORITY_INFO, "Entered window %d.", w->id);
w->mouseFocus = true;
SDL_RaiseWindow(w->window);
break;
case SDL_WINDOWEVENT_LEAVE:
YughLog(0, SDL_LOG_PRIORITY_INFO, "Left window %d.", w->id);
w->mouseFocus = false;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Lost focus on window %d.", w->id);
w->keyboardFocus = false;
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Gained focus on window %d.", w->id);
w->keyboardFocus = true;
break;
case SDL_WINDOWEVENT_MINIMIZED:
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Minimized window %d.", w->id);
w->minimized = true;
break;
case SDL_WINDOWEVENT_MAXIMIZED:
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Maximized window %d.", w->id);
w->minimized = false;
break;
case SDL_WINDOWEVENT_RESTORED:
YughLog(0, SDL_LOG_PRIORITY_INFO,
"Restored window %d.", w->id);
w->minimized = false;
break;
case SDL_WINDOWEVENT_CLOSE:
YughLog(0, SDL_LOG_PRIORITY_INFO, "Closed window %d.", w->id);
break;
}
}
*/
}
void window_all_handle_events() {
for (int i = 0; i < arrlen(windows); i++)
window_handle_event(&windows[i]);
} }
void window_makefullscreen(struct window *w) { void window_makefullscreen(struct window *w) {
@ -223,48 +66,14 @@ void window_unfullscreen(struct window *w) {
} }
void window_togglefullscreen(struct window *w) { void window_togglefullscreen(struct window *w) {
w->fullscreen = !w->fullscreen; sapp_toggle_fullscreen();
mainwin.fullscreen = sapp_is_fullscreen();
if (w->fullscreen) {
glfwMaximizeWindow(w->window);
} else {
glfwRestoreWindow(w->window);
}
}
void window_makecurrent(struct window *w) {
if (w->window != glfwGetCurrentContext())
glfwMakeContextCurrent(w->window);
glViewport(0, 0, w->width, w->height);
}
void window_swap(struct window *w) {
glfwSwapBuffers(w->window);
} }
void window_seticon(struct window *w, struct Texture *icon) { void window_seticon(struct window *w, struct Texture *icon) {
static GLFWimage images[1];
images[0].width = icon->width;
images[0].height = icon->height;
images[0].pixels = icon->data;
glfwSetWindowIcon(w->window, 1, images);
}
int window_hasfocus(struct window *w) {
return glfwGetWindowAttrib(w->window, GLFW_FOCUSED);
} }
void window_render(struct window *w) { void window_render(struct window *w) {
window_makecurrent(w);
openglRender(w); openglRender(w);
window_swap(w);
}
void window_renderall() {
// arrwalk(windows, window_render);
for (int i = 0; i < arrlen(windows); i++)
window_render(&windows[i]);
} }

View file

@ -1,46 +1,42 @@
#ifndef WINDOW_H #ifndef WINDOW_H
#define WINDOW_H #define WINDOW_H
#include "render.h" #include "render.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
struct window { struct window {
GLFWwindow *window;
int id; int id;
int width; int width;
int height; int height;
/* TODO: Bitfield these */
bool render; bool render;
bool mouseFocus; bool mouseFocus;
bool keyboardFocus; bool keyboardFocus;
bool fullscreen; bool fullscreen;
bool minimized; bool minimized;
bool iconified; bool iconified;
bool focus;
bool shown; bool shown;
void (*nuke_gui)();
}; };
struct Texture; struct Texture;
extern struct window *mainwin; extern struct window mainwin;
void window_resize(int width, int height);
void window_quit();
void window_focused(int focus);
void window_iconified(int s);
void window_suspended(int s);
struct window *MakeSDLWindow(const char *name, int width, int height, uint32_t flags);
void window_set_icon(const char *png);
void window_destroy(struct window *w);
void window_handle_event(struct window *w);
void window_all_handle_events();
void window_makecurrent(struct window *w);
void window_makefullscreen(struct window *w); void window_makefullscreen(struct window *w);
void window_togglefullscreen(struct window *w); void window_togglefullscreen(struct window *w);
void window_unfullscreen(struct window *w); void window_unfullscreen(struct window *w);
void window_swap(struct window *w);
void window_set_icon(const char *png);
void window_seticon(struct window *w, struct Texture *icon); void window_seticon(struct window *w, struct Texture *icon);
int window_hasfocus(struct window *w);
struct window *window_i(int index);
void window_render(struct window *w); void window_render(struct window *w);
void window_renderall();
#endif #endif

View file

@ -33,9 +33,11 @@
#include "string.h" #include "string.h"
#define SOKOL_TRACE_HOOKS #define SOKOL_TRACE_HOOKS
#define SOKOL_GFX_IMPL #define SOKOL_IMPL
#define SOKOL_GLCORE33 #define SOKOL_GLCORE33
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
#include "sokol/sokol_app.h"
#include "sokol/sokol_audio.h"
int physOn = 0; int physOn = 0;
@ -48,15 +50,11 @@ double physMS = 1 / 165.f;
double updateMS = 1 / 165.f; double updateMS = 1 / 165.f;
double lastTick = 0.0;
static int phys_step = 0; static int phys_step = 0;
static float timescale = 1.f; double appTime = 0;
#define FPSBUF 10 static float timescale = 1.f;
static double framems[FPSBUF];
int framei = 0;
int fps;
#define SIM_PLAY 0 #define SIM_PLAY 0
#define SIM_PAUSE 1 #define SIM_PAUSE 1
@ -123,46 +121,11 @@ void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uin
mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg); mYughLog(0, 1, line, file, "tag: %s, msg: %s", tag, msg);
} }
int main(int argc, char **args) { static int argc;
int logout = 1; static char **args;
script_startup();
logout = 0;
for (int i = 1; i < argc; i++) {
if (args[i][0] == '-') {
switch (args[i][1]) {
case 'l':
if (i + 1 < argc && args[i + 1][0] != '-') {
log_setfile(args[i + 1]);
i++;
continue;
} else {
YughError("Expected a file for command line arg '-l'.");
exit(1);
}
case 'v':
printf(engine_info());
exit(1);
break;
case 's':
compile_script(args[2]);
exit(0);
case 'm':
logLevel = atoi(args[2]);
break;
case 'c':
logout = 0;
break;
}
}
}
void c_init() {
int logout = 0;
#if DBG #if DBG
if (logout) { if (logout) {
time_t now = time(NULL); time_t now = time(NULL);
@ -206,10 +169,9 @@ int main(int argc, char **args) {
script_evalf("cmd_args('%s');", cmdstr); script_evalf("cmd_args('%s');", cmdstr);
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
YughInfo("Refresh rate is %d", vidmode->refreshRate);
renderMS = 1.0 / vidmode->refreshRate; mainwin.width = sapp_width();
mainwin.height = sapp_height();
sg_setup(&(sg_desc){ sg_setup(&(sg_desc){
.logger = { .logger = {
@ -223,16 +185,17 @@ int main(int argc, char **args) {
input_init(); input_init();
openglInit(); openglInit();
}
MakeDatastream(); int frame_fps() {
struct datastream v; return 1.0/sapp_frame_duration();
ds_openvideo(&v, "bjork.mpg", NULL); }
void c_frame()
{
double elapsed = sapp_frame_duration();
appTime += elapsed;
while (!want_quit()) {
double elapsed = glfwGetTime() - lastTick;
deltaT = elapsed;
lastTick = glfwGetTime();
//double wait = fmax(0, renderMS - elapsed);
nuke_input_begin(); nuke_input_begin();
// if (sim_playing()) // if (sim_playing())
@ -240,12 +203,6 @@ int main(int argc, char **args) {
// else // else
// input_poll(1000); // input_poll(1000);
window_all_handle_events();
nuke_input_end();
framems[framei++] = elapsed;
if (framei == FPSBUF) framei = 0;
if (sim_play == SIM_PLAY || sim_play == SIM_STEP) { if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
timer_update(elapsed * timescale); timer_update(elapsed * timescale);
physlag += elapsed; physlag += elapsed;
@ -265,22 +222,76 @@ int main(int argc, char **args) {
// if (renderlag >= renderMS) { // if (renderlag >= renderMS) {
// renderlag -= renderMS; // renderlag -= renderMS;
window_renderall(); window_render(&mainwin);
// } // }
gameobjects_cleanup(); gameobjects_cleanup();
}
return 0;
} }
int frame_fps() { void c_clean()
double fpsms = 0; {
for (int i = 0; i < FPSBUF; i++) {
fpsms += framems[i];
}
return FPSBUF / fpsms; }
void c_event(const sapp_event *e)
{
switch (e->type) {
case SAPP_EVENTTYPE_MOUSE_MOVE:
input_mouse_move(e->mouse_x, e->mouse_y, e->mouse_dx, e->mouse_dy);
break;
case SAPP_EVENTTYPE_MOUSE_SCROLL:
input_mouse_scroll(e->scroll_x, e->scroll_y);
break;
case SAPP_EVENTTYPE_KEY_DOWN:
input_btn(e->key_code, e->key_repeat ? INPUT_REPEAT : INPUT_DOWN, e->modifiers);
break;
case SAPP_EVENTTYPE_KEY_UP:
input_btn(e->key_code, INPUT_UP, e->modifiers);
break;
case SAPP_EVENTTYPE_MOUSE_UP:
input_mouse(e->mouse_button, INPUT_UP);
break;
case SAPP_EVENTTYPE_MOUSE_DOWN:
input_mouse(e->mouse_button, INPUT_DOWN);
break;
case SAPP_EVENTTYPE_CHAR:
input_key(e->char_code, e->modifiers);
break;
case SAPP_EVENTTYPE_RESIZED:
window_resize(e->window_width, e->window_height);
break;
case SAPP_EVENTTYPE_ICONIFIED:
window_iconified(1);
break;
case SAPP_EVENTTYPE_RESTORED:
window_iconified(0);
break;
case SAPP_EVENTTYPE_FOCUSED:
window_focused(1);
break;
case SAPP_EVENTTYPE_UNFOCUSED:
window_focused(0);
break;
case SAPP_EVENTTYPE_SUSPENDED:
window_suspended(1);
break;
case SAPP_EVENTTYPE_QUIT_REQUESTED:
window_quit();
break;
}
} }
int sim_playing() { return sim_play == SIM_PLAY; } int sim_playing() { return sim_play == SIM_PLAY; }
@ -311,3 +322,28 @@ double get_timescale()
{ {
return timescale; return timescale;
} }
sapp_desc sokol_main(int sargc, char **sargs) {
argc = sargc;
args = sargs;
script_startup();
return (sapp_desc){
.width = 720,
.height = 480,
.high_dpi = 0,
.sample_count = 8,
.fullscreen = 0,
.window_title = "Yugine",
.enable_clipboard = false,
.clipboard_size = 0,
.enable_dragndrop = true,
.max_dropped_files = 1,
.max_dropped_file_path_length = 2048,
.init_cb = c_init,
.frame_cb = c_frame,
.cleanup_cb = c_clean,
.event_cb = c_event,
};
}

View file

@ -15,7 +15,7 @@ const char *engine_info();
int frame_fps(); int frame_fps();
extern double lastTick; extern double appTime;
#endif #endif

View file

@ -792,19 +792,19 @@ var Mouse = {
var Keys = { var Keys = {
shift() { shift() {
return cmd(50, 340) || cmd(50, 344); return cmd(50, 340);// || cmd(50, 344);
}, },
ctrl() { ctrl() {
return cmd(50, 341) || cmd(50, 344); return cmd(50, 341);// || cmd(50, 344);
}, },
alt() { alt() {
return cmd(50, 342) || cmd(50, 346); return cmd(50, 342);// || cmd(50, 346);
}, },
super() { super() {
return cmd(50, 343) || cmd(50, 347); return cmd(50, 343);// || cmd(50, 347);
}, },
}; };
@ -969,10 +969,10 @@ var Register = {
this.finloop(); this.finloop();
}, },
kbm_input(src, btn, state, ...args) { kbm_input(btn, state, ...args) {
var input = `${src}_${btn}_${state}`; /* var input = `${src}_${btn}_${state}`;
Player.players[0].input(input, ...args); Player.players[0].input(input, ...args);
*/
if (!(state === "pressed" || state === "released" || state === "rep")) return; if (!(state === "pressed" || state === "released" || state === "rep")) return;
if (btn === 'lmouse') if (btn === 'lmouse')
btn = 'lm'; btn = 'lm';