lovrPlatform: Keyboard/mouse;

Update fake.c
This commit is contained in:
bjorn 2018-11-16 03:18:08 -08:00
parent 5c3280ba2a
commit b7deda3758
4 changed files with 149 additions and 70 deletions

View File

@ -66,7 +66,7 @@ void lovrGraphicsSetWindow(WindowFlags* flags) {
lovrAssert(lovrPlatformSetWindow(flags), "Could not create window");
lovrPlatformOnWindowClose(onCloseWindow);
lovrPlatformOnWindowResize(onResizeWindow);
lovrPlatformGetWindowSize(&state.width, &state.height);
lovrPlatformGetFramebufferSize(&state.width, &state.height);
lovrGpuInit(state.gammaCorrect, lovrGetProcAddress);
VertexFormat format;

View File

@ -1,7 +1,7 @@
#include "event/event.h"
#include "graphics/graphics.h"
#include "lib/math.h"
#include "lib/glfw.h"
#include "platform.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdlib.h>
@ -28,37 +28,19 @@ static struct {
double pitch;
float transform[16];
GLFWwindow* window;
double prevCursorX;
double prevCursorY;
} state;
static void onMouseButton(GLFWwindow* window, int button, int action, int mods) {
if (button != GLFW_MOUSE_BUTTON_RIGHT) {
return;
}
Controller* controller; int i;
vec_foreach(&state.controllers, controller, i) {
lovrEventPush((Event) {
.type = action == GLFW_PRESS ? EVENT_CONTROLLER_PRESSED : EVENT_CONTROLLER_RELEASED,
.data.controller = { controller, CONTROLLER_BUTTON_TRIGGER }
});
}
}
static void updateWindow() {
GLFWwindow* window = glfwGetCurrentContext();
if (window == state.window) {
return;
}
state.window = window;
if (window) {
glfwSwapInterval(1);
GLFWmousebuttonfun prevMouseButton = glfwSetMouseButtonCallback(window, onMouseButton);
if (prevMouseButton) glfwSetMouseButtonCallback(window, prevMouseButton);
static void onMouseButton(MouseButton button, ButtonAction action, int x, int y) {
if (button == MOUSE_RIGHT) {
Controller* controller; int i;
vec_foreach(&state.controllers, controller, i) {
lovrEventPush((Event) {
.type = action == BUTTON_PRESSED ? EVENT_CONTROLLER_PRESSED : EVENT_CONTROLLER_RELEASED,
.data.controller = { controller, CONTROLLER_BUTTON_TRIGGER }
});
}
}
}
@ -76,7 +58,7 @@ static bool fakeInit(float offset, int msaa) {
controller->id = 0;
vec_push(&state.controllers, controller);
state.window = NULL;
lovrPlatformOnMouseButton(onMouseButton);
return true;
}
@ -112,14 +94,10 @@ static void fakeSetMirrored(bool mirror, HeadsetEye eye) {
}
static void fakeGetDisplayDimensions(uint32_t* width, uint32_t* height) {
updateWindow();
if (state.window) {
int w, h;
glfwGetFramebufferSize(state.window, &w, &h);
*width = (uint32_t) w;
*height = (uint32_t) h;
}
int w, h;
lovrPlatformGetFramebufferSize(&w, &h);
*width = (uint32_t) w;
*height = (uint32_t) h;
}
static void fakeGetClipDistance(float* clipNear, float* clipFar) {
@ -194,7 +172,7 @@ static float fakeControllerGetAxis(Controller* controller, ControllerAxis axis)
}
static bool fakeControllerIsDown(Controller* controller, ControllerButton button) {
return state.window ? (glfwGetMouseButton(state.window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) : false;
return lovrPlatformIsMouseDown(MOUSE_RIGHT);
}
static bool fakeControllerIsTouched(Controller* controller, ControllerButton button) {
@ -210,7 +188,7 @@ static ModelData* fakeControllerNewModelData(Controller* controller) {
}
static void fakeRenderTo(void (*callback)(void*), void* userdata) {
if (!state.window || !state.mirrored) {
if (!state.mirrored) {
return;
}
@ -229,31 +207,25 @@ static void fakeRenderTo(void (*callback)(void*), void* userdata) {
}
static void fakeUpdate(float dt) {
updateWindow();
if (!state.window) {
return;
}
bool front = glfwGetKey(state.window, GLFW_KEY_W) == GLFW_PRESS || glfwGetKey(state.window, GLFW_KEY_UP) == GLFW_PRESS;
bool back = glfwGetKey(state.window, GLFW_KEY_S) == GLFW_PRESS || glfwGetKey(state.window, GLFW_KEY_DOWN) == GLFW_PRESS;
bool left = glfwGetKey(state.window, GLFW_KEY_A) == GLFW_PRESS || glfwGetKey(state.window, GLFW_KEY_LEFT) == GLFW_PRESS;
bool right = glfwGetKey(state.window, GLFW_KEY_D) == GLFW_PRESS || glfwGetKey(state.window, GLFW_KEY_RIGHT) == GLFW_PRESS;
bool up = glfwGetKey(state.window, GLFW_KEY_Q) == GLFW_PRESS;
bool down = glfwGetKey(state.window, GLFW_KEY_E) == GLFW_PRESS;
bool front = lovrPlatformIsKeyDown(KEY_W) || lovrPlatformIsKeyDown(KEY_UP);
bool back = lovrPlatformIsKeyDown(KEY_S) || lovrPlatformIsKeyDown(KEY_DOWN);
bool left = lovrPlatformIsKeyDown(KEY_A) || lovrPlatformIsKeyDown(KEY_LEFT);
bool right = lovrPlatformIsKeyDown(KEY_D) || lovrPlatformIsKeyDown(KEY_RIGHT);
bool up = lovrPlatformIsKeyDown(KEY_Q);
bool down = lovrPlatformIsKeyDown(KEY_E);
float movespeed = 3.f * dt;
float turnspeed = 3.f * dt;
double damping = MAX(1 - 20 * dt, 0);
if (glfwGetMouseButton(state.window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) {
glfwSetInputMode(state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (lovrPlatformIsMouseDown(MOUSE_LEFT)) {
lovrPlatformSetMouseMode(MOUSE_MODE_GRABBED);
int width, height;
glfwGetWindowSize(state.window, &width, &height);
lovrPlatformGetWindowSize(&width, &height);
double mx, my;
glfwGetCursorPos(state.window, &mx, &my);
lovrPlatformGetMousePosition(&mx, &my);
if (state.prevCursorX == -1 && state.prevCursorY == -1) {
state.prevCursorX = mx;
@ -268,7 +240,7 @@ static void fakeUpdate(float dt) {
state.prevCursorX = mx;
state.prevCursorY = my;
} else {
glfwSetInputMode(state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
lovrPlatformSetMouseMode(MOUSE_MODE_NORMAL);
vec3_scale(state.angularVelocity, damping);
state.prevCursorX = state.prevCursorY = -1;
}

View File

@ -32,8 +32,37 @@ typedef struct {
} icon;
} WindowFlags;
typedef enum {
MOUSE_LEFT,
MOUSE_RIGHT
} MouseButton;
typedef enum {
MOUSE_MODE_NORMAL,
MOUSE_MODE_GRABBED
} MouseMode;
typedef enum {
KEY_W,
KEY_A,
KEY_S,
KEY_D,
KEY_Q,
KEY_E,
KEY_UP,
KEY_DOWN,
KEY_LEFT,
KEY_RIGHT
} KeyCode;
typedef enum {
BUTTON_PRESSED,
BUTTON_RELEASED
} ButtonAction;
typedef void (*windowCloseCallback)();
typedef void (*windowResizeCallback)(uint32_t width, uint32_t height);
typedef void (*mouseButtonCallback)(MouseButton button, ButtonAction action, int x, int y);
typedef void (*gpuProc)(void);
typedef gpuProc (*getProcAddressProc)(const char*);
@ -43,9 +72,15 @@ void lovrPlatformPollEvents();
double lovrPlatformGetTime();
void lovrPlatformSetTime(double t);
bool lovrPlatformSetWindow(WindowFlags* flags);
void lovrPlatformGetWindowSize(uint32_t* width, uint32_t* height);
void lovrPlatformGetWindowSize(int* width, int* height);
void lovrPlatformGetFramebufferSize(int* width, int* height);
void lovrPlatformSwapBuffers();
void lovrPlatformOnWindowClose(windowCloseCallback callback);
void lovrPlatformOnWindowResize(windowResizeCallback callback);
void lovrPlatformSwapBuffers();
void lovrPlatformOnMouseButton(mouseButtonCallback callback);
void lovrPlatformGetMousePosition(double* x, double* y);
void lovrPlatformSetMouseMode(MouseMode mode);
bool lovrPlatformIsMouseDown(MouseButton button);
bool lovrPlatformIsKeyDown(KeyCode key);
void lovrSleep(double seconds);
int lovrGetExecutablePath(char* dest, uint32_t size);

View File

@ -10,6 +10,7 @@ static struct {
GLFWwindow* window;
windowCloseCallback onWindowClose;
windowResizeCallback onWindowResize;
mouseButtonCallback onMouseButton;
} state;
static void onWindowClose(GLFWwindow* window) {
@ -24,6 +25,38 @@ static void onWindowResize(GLFWwindow* window, int width, int height) {
}
}
static void onMouseButton(GLFWwindow* window, int b, int a, int mods) {
if (state.onMouseButton && (b == GLFW_MOUSE_BUTTON_LEFT || b == GLFW_MOUSE_BUTTON_RIGHT)) {
MouseButton button = (b == GLFW_MOUSE_BUTTON_LEFT) ? MOUSE_LEFT : MOUSE_RIGHT;
ButtonAction action = (a == GLFW_PRESS) ? BUTTON_PRESSED : BUTTON_RELEASED;
int x, y;
glfwGetCursorPos(state.window, &x, &y);
state.onMouseButton(button, action, x, y);
}
}
static int convertMouseButton(MouseButton button) {
switch (button) {
case MOUSE_LEFT: return GLFW_MOUSE_BUTTON_LEFT;
case MOUSE_RIGHT: return GLFW_MOUSE_BUTTON_RIGHT;
}
}
static int convertKeyCode(KeyCode key) {
switch (key) {
case KEY_W: return GLFW_KEY_W;
case KEY_A: return GLFW_KEY_A;
case KEY_S: return GLFW_KEY_S;
case KEY_D: return GLFW_KEY_D;
case KEY_Q: return GLFW_KEY_Q;
case KEY_E: return GLFW_KEY_E;
case KEY_UP: return GLFW_KEY_UP;
case KEY_DOWN: return GLFW_KEY_DOWN;
case KEY_LEFT: return GLFW_KEY_LEFT;
case KEY_RIGHT: return GLFW_KEY_RIGHT;
}
}
void lovrPlatformPollEvents() {
glfwPollEvents();
}
@ -76,29 +109,68 @@ bool lovrPlatformSetWindow(WindowFlags* flags) {
}
glfwMakeContextCurrent(state.window);
glfwSetWindowCloseCallback(state.window, onWindowClose);
glfwSetWindowSizeCallback(state.window, onWindowResize);
glfwSetMouseButtonCallback(state.window, onMouseButton);
glfwSwapInterval(flags->vsync);
return true;
}
void lovrPlatformGetWindowSize(uint32_t* width, uint32_t* height) {
int w, h;
glfwGetFramebufferSize(state.window, &w, &h);
*width = w;
*height = h;
void lovrPlatformGetWindowSize(int* width, int* height) {
if (state.window) {
glfwGetWindowSize(state.window, width, height);
} else {
*width = *height = 0;
}
}
void lovrPlatformOnWindowClose(windowCloseCallback callback) {
glfwSetWindowCloseCallback(state.window, callback);
}
void lovrPlatformOnWindowResize(windowResizeCallback callback) {
glfwSetWindowSizeCallback(state.window, callback);
void lovrPlatformGetFramebufferSize(int* width, int* height) {
if (state.window) {
glfwGetFramebufferSize(state.window, width, height);
} else {
*width = *height = 0;
}
}
void lovrPlatformSwapBuffers() {
glfwSwapBuffers(state.window);
}
void lovrPlatformOnWindowClose(windowCloseCallback callback) {
state.onWindowClose = callback;
}
void lovrPlatformOnWindowResize(windowResizeCallback callback) {
state.onWindowResize = callback;
}
void lovrPlatformOnMouseButton(mouseButtonCallback callback) {
state.onMouseButton = callback;
}
void lovrPlatformGetMousePosition(double* x, double* y) {
if (state.window) {
glfwGetCursorPos(state.window, x, y);
} else {
*x = *y = 0.;
}
}
void lovrPlatformSetMouseMode(MouseMode mode) {
if (state.window) {
int m = (mode == MOUSE_MODE_GRABBED) ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL;
glfwSetInputMode(state.window, GLFW_CURSOR, m);
}
}
bool lovrPlatformIsMouseDown(MouseButton button) {
return state.window ? glfwGetMouseButton(state.window, convertMouseButton(button)) == GLFW_PRESS : false;
}
bool lovrPlatformIsKeyDown(KeyCode key) {
return state.window ? glfwGetKey(state.window, convertKeyCode(key)) == GLFW_PRESS : false;
}
void lovrSleep(double seconds) {
Sleep((unsigned int) (seconds * 1000));
}