lovr/src/api/headset.c

333 lines
8.9 KiB
C
Raw Normal View History

2017-03-11 11:08:07 +00:00
#include "api/lovr.h"
2016-11-19 09:28:01 +00:00
#include "headset/headset.h"
2016-08-11 04:17:14 +00:00
2017-03-11 11:08:07 +00:00
map_int_t ControllerAxes;
map_int_t ControllerButtons;
2017-08-13 05:58:59 +00:00
map_int_t ControllerHands;
map_int_t HeadsetDrivers;
2017-03-11 11:08:07 +00:00
map_int_t HeadsetEyes;
2017-08-04 05:21:49 +00:00
map_int_t HeadsetOrigins;
2017-08-13 04:35:01 +00:00
map_int_t HeadsetTypes;
2017-03-11 11:08:07 +00:00
2017-04-16 23:56:49 +00:00
typedef struct {
lua_State* L;
int ref;
} HeadsetRenderData;
static HeadsetRenderData headsetRenderData;
static void renderHelper(HeadsetEye eye, void* userdata) {
2017-04-16 23:56:49 +00:00
HeadsetRenderData* renderData = userdata;
lua_State* L = renderData->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, renderData->ref);
luax_pushenum(L, &HeadsetEyes, eye);
2016-08-11 04:17:14 +00:00
lua_call(L, 1, 0);
}
int l_lovrHeadsetInit(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrHeadset);
2017-01-21 03:46:45 +00:00
luax_registertype(L, "Controller", lovrController);
2016-10-03 14:40:20 +00:00
2016-11-15 00:20:56 +00:00
map_init(&ControllerAxes);
map_set(&ControllerAxes, "trigger", CONTROLLER_AXIS_TRIGGER);
2017-08-13 05:58:59 +00:00
map_set(&ControllerAxes, "grip", CONTROLLER_AXIS_GRIP);
2016-11-15 00:20:56 +00:00
map_set(&ControllerAxes, "touchx", CONTROLLER_AXIS_TOUCHPAD_X);
map_set(&ControllerAxes, "touchy", CONTROLLER_AXIS_TOUCHPAD_Y);
2016-11-15 03:57:23 +00:00
map_init(&ControllerButtons);
2017-08-13 05:58:59 +00:00
map_set(&ControllerButtons, "unknown", CONTROLLER_BUTTON_UNKNOWN);
2016-11-15 03:57:23 +00:00
map_set(&ControllerButtons, "system", CONTROLLER_BUTTON_SYSTEM);
map_set(&ControllerButtons, "menu", CONTROLLER_BUTTON_MENU);
2017-08-13 05:58:59 +00:00
map_set(&ControllerButtons, "trigger", CONTROLLER_BUTTON_TRIGGER);
2016-11-15 03:57:23 +00:00
map_set(&ControllerButtons, "grip", CONTROLLER_BUTTON_GRIP);
map_set(&ControllerButtons, "touchpad", CONTROLLER_BUTTON_TOUCHPAD);
2017-08-13 05:58:59 +00:00
map_set(&ControllerButtons, "a", CONTROLLER_BUTTON_A);
map_set(&ControllerButtons, "b", CONTROLLER_BUTTON_B);
map_set(&ControllerButtons, "x", CONTROLLER_BUTTON_X);
map_set(&ControllerButtons, "y", CONTROLLER_BUTTON_Y);
map_init(&ControllerHands);
map_set(&ControllerHands, "unknown", HAND_UNKNOWN);
map_set(&ControllerHands, "left", HAND_LEFT);
map_set(&ControllerHands, "right", HAND_RIGHT);
2016-11-15 03:57:23 +00:00
2017-08-04 05:21:49 +00:00
map_init(&HeadsetEyes);
map_set(&HeadsetEyes, "left", EYE_LEFT);
map_set(&HeadsetEyes, "right", EYE_RIGHT);
map_init(&HeadsetOrigins);
map_set(&HeadsetOrigins, "head", ORIGIN_HEAD);
map_set(&HeadsetOrigins, "floor", ORIGIN_FLOOR);
2017-08-13 04:35:01 +00:00
map_init(&HeadsetTypes);
map_set(&HeadsetTypes, "unknown", HEADSET_UNKNOWN);
map_set(&HeadsetTypes, "vive", HEADSET_VIVE);
map_set(&HeadsetTypes, "rift", HEADSET_RIFT);
map_init(&HeadsetDrivers);
map_set(&HeadsetDrivers, "fake", DRIVER_FAKE);
map_set(&HeadsetDrivers, "openvr", DRIVER_OPENVR);
map_set(&HeadsetDrivers, "webvr", DRIVER_WEBVR);
luax_pushconf(L);
lua_getfield(L, -1, "headset");
vec_t(HeadsetDriver) drivers;
vec_init(&drivers);
bool mirror = false;
if (lua_istable(L, -1)) {
// Drivers
lua_getfield(L, -1, "drivers");
int n = lua_objlen(L, -1);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, -1, i + 1);
vec_push(&drivers, *(HeadsetDriver*) luax_checkenum(L, -1, &HeadsetDrivers, "headset driver"));
lua_pop(L, 1);
}
lua_pop(L, 1);
// Mirror
lua_getfield(L, -1, "mirror");
mirror = lua_toboolean(L, -1);
lua_pop(L, 1);
}
lovrHeadsetInit(drivers.data, drivers.length);
lovrHeadsetSetMirrored(mirror);
vec_deinit(&drivers);
lua_pop(L, 2);
2016-10-03 14:40:20 +00:00
2017-04-23 06:21:29 +00:00
headsetRenderData.ref = LUA_NOREF;
2016-08-11 04:17:14 +00:00
return 1;
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetIsPresent(lua_State* L) {
lua_pushboolean(L, lovrHeadsetIsPresent());
return 1;
}
int l_lovrHeadsetGetDriver(lua_State* L) {
const HeadsetDriver* driver = lovrHeadsetGetDriver();
if (driver) {
luax_pushenum(L, &HeadsetDrivers, *driver);
} else {
lua_pushnil(L);
}
return 1;
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetGetType(lua_State* L) {
2017-08-13 04:35:01 +00:00
luax_pushenum(L, &HeadsetTypes, lovrHeadsetGetType());
2016-10-01 21:12:55 +00:00
return 1;
2016-08-11 04:17:14 +00:00
}
2017-08-04 05:21:49 +00:00
int l_lovrHeadsetGetOriginType(lua_State* L) {
luax_pushenum(L, &HeadsetOrigins, lovrHeadsetGetOriginType());
return 1;
}
int l_lovrHeadsetIsMirrored(lua_State* L) {
lua_pushboolean(L, lovrHeadsetIsMirrored());
return 1;
}
int l_lovrHeadsetSetMirrored(lua_State* L) {
int mirror = lua_toboolean(L, 1);
lovrHeadsetSetMirrored(mirror);
return 0;
}
2016-10-24 23:03:29 +00:00
int l_lovrHeadsetGetDisplayWidth(lua_State* L) {
int width;
lovrHeadsetGetDisplayDimensions(&width, NULL);
lua_pushnumber(L, width);
return 1;
}
int l_lovrHeadsetGetDisplayHeight(lua_State* L) {
int height;
lovrHeadsetGetDisplayDimensions(NULL, &height);
lua_pushnumber(L, height);
return 1;
}
int l_lovrHeadsetGetDisplayDimensions(lua_State* L) {
int width, height;
lovrHeadsetGetDisplayDimensions(&width, &height);
lua_pushnumber(L, width);
lua_pushnumber(L, height);
return 2;
}
2016-09-27 06:48:09 +00:00
int l_lovrHeadsetGetClipDistance(lua_State* L) {
float near, far;
lovrHeadsetGetClipDistance(&near, &far);
lua_pushnumber(L, near);
lua_pushnumber(L, far);
return 2;
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetSetClipDistance(lua_State* L) {
float near = luaL_checknumber(L, 1);
float far = luaL_checknumber(L, 2);
lovrHeadsetSetClipDistance(near, far);
return 0;
}
int l_lovrHeadsetGetBoundsWidth(lua_State* L) {
lua_pushnumber(L, lovrHeadsetGetBoundsWidth());
return 1;
}
int l_lovrHeadsetGetBoundsDepth(lua_State* L) {
lua_pushnumber(L, lovrHeadsetGetBoundsDepth());
return 1;
}
int l_lovrHeadsetGetBoundsDimensions(lua_State* L) {
lua_pushnumber(L, lovrHeadsetGetBoundsWidth());
lua_pushnumber(L, lovrHeadsetGetBoundsDepth());
2016-10-01 21:17:26 +00:00
return 2;
}
int l_lovrHeadsetGetBoundsGeometry(lua_State* L) {
float geometry[12];
2017-04-23 06:21:29 +00:00
lovrHeadsetGetBoundsGeometry(geometry);
lua_newtable(L);
for (int i = 0; i < 4; i++) {
lua_newtable(L);
for (int j = 0; j < 3; j++) {
lua_pushnumber(L, geometry[3 * i + j]);
lua_rawseti(L, -2, j + 1);
}
2016-11-24 05:01:46 +00:00
lua_rawseti(L, -2, i + 1);
}
return 1;
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetGetPosition(lua_State* L) {
float x, y, z;
lovrHeadsetGetPosition(&x, &y, &z);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 3;
}
int l_lovrHeadsetGetEyePosition(lua_State* L) {
float x, y, z;
2017-03-02 04:19:37 +00:00
HeadsetEye eye = *(HeadsetEye*) luax_optenum(L, 1, "left", &HeadsetEyes, "eye");
lovrHeadsetGetEyePosition(eye, &x, &y, &z);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 3;
}
2016-09-17 02:43:43 +00:00
int l_lovrHeadsetGetOrientation(lua_State* L) {
2017-01-20 02:04:45 +00:00
float angle, x, y, z;
lovrHeadsetGetOrientation(&angle, &x, &y, &z);
lua_pushnumber(L, angle);
2016-09-17 02:43:43 +00:00
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 4;
2016-08-11 04:17:14 +00:00
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetGetVelocity(lua_State* L) {
2016-09-17 02:43:43 +00:00
float x, y, z;
2016-10-01 21:12:55 +00:00
lovrHeadsetGetVelocity(&x, &y, &z);
2016-09-17 02:43:43 +00:00
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 3;
2016-08-11 04:17:14 +00:00
}
2016-10-01 21:12:55 +00:00
int l_lovrHeadsetGetAngularVelocity(lua_State* L) {
2016-09-17 02:43:43 +00:00
float x, y, z;
2016-10-01 21:12:55 +00:00
lovrHeadsetGetAngularVelocity(&x, &y, &z);
2016-09-17 02:43:43 +00:00
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 3;
2016-09-16 06:57:01 +00:00
}
2016-12-01 07:03:58 +00:00
int l_lovrHeadsetGetControllers(lua_State* L) {
vec_controller_t* controllers = lovrHeadsetGetControllers();
2016-12-02 01:06:27 +00:00
if (!controllers) {
lua_newtable(L);
return 1;
}
2016-12-01 07:03:58 +00:00
lua_newtable(L);
Controller* controller; int i;
vec_foreach(controllers, controller, i) {
luax_pushtype(L, Controller, controller);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
int l_lovrHeadsetGetControllerCount(lua_State* L) {
vec_controller_t* controllers = lovrHeadsetGetControllers();
2016-12-02 01:06:27 +00:00
if (controllers) {
lua_pushnumber(L, controllers->length);
} else {
lua_pushnumber(L, 0);
}
2016-10-03 14:40:20 +00:00
return 1;
}
2016-08-11 04:17:14 +00:00
int l_lovrHeadsetRenderTo(lua_State* L) {
2017-04-16 23:56:49 +00:00
lua_settop(L, 1);
2016-08-11 04:17:14 +00:00
luaL_checktype(L, 1, LUA_TFUNCTION);
2017-04-21 04:17:25 +00:00
2017-04-23 06:21:29 +00:00
if (headsetRenderData.ref != LUA_NOREF) {
2017-04-21 04:17:25 +00:00
luaL_unref(L, LUA_REGISTRYINDEX, headsetRenderData.ref);
}
2017-04-16 23:56:49 +00:00
headsetRenderData.ref = luaL_ref(L, LUA_REGISTRYINDEX);
headsetRenderData.L = L;
lovrHeadsetRenderTo(renderHelper, &headsetRenderData);
2016-08-11 04:17:14 +00:00
return 0;
}
2017-03-11 11:08:07 +00:00
int l_lovrHeadsetUpdate(lua_State* L) {
float dt = luaL_checknumber(L, 1);
lovrHeadsetUpdate(dt);
return 0;
}
2017-03-11 11:08:07 +00:00
const luaL_Reg lovrHeadset[] = {
{ "isPresent", l_lovrHeadsetIsPresent },
{ "getDriver", l_lovrHeadsetGetDriver },
2017-03-11 11:08:07 +00:00
{ "getType", l_lovrHeadsetGetType },
2017-08-07 06:56:22 +00:00
{ "getOriginType", l_lovrHeadsetGetOriginType },
{ "isMirrored", l_lovrHeadsetIsMirrored },
{ "setMirrored", l_lovrHeadsetSetMirrored },
2017-03-11 11:08:07 +00:00
{ "getDisplayWidth", l_lovrHeadsetGetDisplayWidth },
{ "getDisplayHeight", l_lovrHeadsetGetDisplayHeight },
{ "getDisplayDimensions", l_lovrHeadsetGetDisplayDimensions },
{ "getClipDistance", l_lovrHeadsetGetClipDistance },
{ "setClipDistance", l_lovrHeadsetSetClipDistance },
{ "getBoundsWidth", l_lovrHeadsetGetBoundsWidth },
{ "getBoundsDepth", l_lovrHeadsetGetBoundsDepth },
{ "getBoundsDimensions", l_lovrHeadsetGetBoundsDimensions },
{ "getBoundsGeometry", l_lovrHeadsetGetBoundsGeometry },
{ "getPosition", l_lovrHeadsetGetPosition },
{ "getEyePosition", l_lovrHeadsetGetEyePosition },
{ "getOrientation", l_lovrHeadsetGetOrientation },
{ "getVelocity", l_lovrHeadsetGetVelocity },
{ "getAngularVelocity", l_lovrHeadsetGetAngularVelocity },
{ "getControllers", l_lovrHeadsetGetControllers },
{ "getControllerCount", l_lovrHeadsetGetControllerCount },
{ "renderTo", l_lovrHeadsetRenderTo },
{ "update", l_lovrHeadsetUpdate },
2017-03-11 11:08:07 +00:00
{ NULL, NULL }
};