-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput.c
145 lines (123 loc) · 3.79 KB
/
input.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* Keyboard input.
*
* Authors: Tim Sjöstrand <[email protected]>
* Johan Yngman <[email protected]>
*/
#include <stdio.h>
#include <string.h>
#include <GLFW/glfw3.h>
#include "log.h"
#include "graphics.h"
#include "input.h"
#include "core.h"
void input_glfw_key_func(GLFWwindow *window, int key, int scancode, int action, int mods);
void input_glfw_char_func(GLFWwindow *window, unsigned int key, int mods);
void input_glfw_mousebutton_callback(GLFWwindow *window, int button, int action, int mods);
int input_init(struct core* core, struct input *input, GLFWwindow *window,
input_callback_t key_callback, input_char_callback_t char_callback, mousebutton_callback_t mousebutton_callback)
{
input->core = core;
input->enabled = 1;
input->callback = key_callback;
input->char_callback = char_callback;
input->mousebutton_callback = mousebutton_callback;
input_global = input;
glfwSetKeyCallback(window, &input_glfw_key_func);
glfwSetCharModsCallback(window, &input_glfw_char_func);
glfwSetMouseButtonCallback(window, &input_glfw_mousebutton_callback);
return GRAPHICS_OK;
}
int key_down(int key)
{
return input_global && input_global->keys[key];
}
int key_pressed(int key)
{
return input_global && (input_global->keys[key] && !input_global->last_keys[key]);
}
int key_released(int key)
{
return input_global && (!input_global->keys[key] && input_global->last_keys[key]);
}
void input_glfw_mousebutton_callback(GLFWwindow *window, int button, int action, int mods)
{
input_global->mousebutton_callback(input_global->core, window, button, action, mods);
}
void input_glfw_key_func(GLFWwindow *window, int key, int scancode, int action, int mods)
{
/* Sanity check */
if(key < 0 || key >= GLFW_KEY_LAST) {
debugf("Input", "Invalid key: %d (scancode=%d)\n", key, scancode);
return;
}
if(!input_global) {
errorf("Input", "ERROR: input_init() not called\n");
return;
}
if(input_global->enabled) {
/* Only care about 'up'/'down', regard 'repeat' as 'down'. */
input_global->keys[key] = !(action == GLFW_RELEASE);
}
if(input_global->callback) {
input_global->callback(input_global->core, input_global, window, key, scancode, action, mods);
}
}
void input_glfw_char_func(GLFWwindow *window, unsigned int key, int mods)
{
if(!input_global) {
printf("ERROR: input_init() not called\n");
return;
}
if(input_global->char_callback) {
input_global->char_callback(input_global->core, input_global, window, key, mods);
}
}
void input_think(struct input *input, float delta_time)
{
/* Remember what keys were pressed the last frame. */
for(int i = 0; i < GLFW_KEY_LAST; i++) {
input->last_keys[i] = input->keys[i];
}
}
/**
* Converts window corrdinates to view coordinates.
*/
void input_window_to_view(float win_x, float win_y, float win_w, float win_h, float *x, float *y)
{
float vx, vy, vw, vh;
core_get_viewport(input_global->core, &vx, &vy, &vw, &vh);
float dw = vw - win_w;
float dh = vh - win_h;
win_x = win_x + vx + dw;
win_y = win_y + vy + dh;
win_w = vw;
win_h = vh;
mat4 projection;
inverse(projection, input_global->core->graphics.projection);
vec4 in_pos;
in_pos[0] = 2.0f * win_x / win_w;
in_pos[1] = 2.0f * (1.0f - win_y / win_h);
in_pos[2] = 0.0f;
in_pos[3] = 1.0f;
vec4 out_pos;
mult_vec4(out_pos, projection, in_pos);
*x = out_pos[0];
*y = out_pos[1];
}
void input_window_get_cursor(GLFWwindow *window, float *x, float *y)
{
double tmp_x = 0, tmp_y = 0;
glfwGetCursorPos(window, &tmp_x, &tmp_y);
*x = (float) tmp_x;
*y = (float) tmp_y;
}
void input_view_get_cursor(GLFWwindow *window, float *x, float *y)
{
float win_x = 0, win_y = 0;
input_window_get_cursor(window, &win_x, &win_y);
int win_w = 0, win_h = 0;
glfwGetWindowSize(window, &win_w, &win_h);
/* Convert screen space => game space. */
input_window_to_view(win_x, win_y, win_w, win_h, x, y);
}