get the flycam going already
This commit is contained in:
parent
f00bae7cfc
commit
7f1efce310
@ -3,6 +3,7 @@
|
|||||||
#include "scenes/scene.h"
|
#include "scenes/scene.h"
|
||||||
#include "scenes/title.h"
|
#include "scenes/title.h"
|
||||||
|
|
||||||
|
#include <SDL_scancode.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -22,16 +23,28 @@ void game_tick(void) {
|
|||||||
input_bind_action_scancode(&ctx.input, "debug_toggle", SDL_SCANCODE_BACKSPACE);
|
input_bind_action_scancode(&ctx.input, "debug_toggle", SDL_SCANCODE_BACKSPACE);
|
||||||
|
|
||||||
input_add_action(&ctx.input, "player_left");
|
input_add_action(&ctx.input, "player_left");
|
||||||
input_bind_action_scancode(&ctx.input, "player_left", SDL_SCANCODE_LEFT);
|
input_bind_action_scancode(&ctx.input, "player_left", SDL_SCANCODE_A);
|
||||||
|
|
||||||
input_add_action(&ctx.input, "player_right");
|
input_add_action(&ctx.input, "player_right");
|
||||||
input_bind_action_scancode(&ctx.input, "player_right", SDL_SCANCODE_RIGHT);
|
input_bind_action_scancode(&ctx.input, "player_right", SDL_SCANCODE_D);
|
||||||
|
|
||||||
|
input_add_action(&ctx.input, "player_forward");
|
||||||
|
input_bind_action_scancode(&ctx.input, "player_forward", SDL_SCANCODE_W);
|
||||||
|
|
||||||
|
input_add_action(&ctx.input, "player_backward");
|
||||||
|
input_bind_action_scancode(&ctx.input, "player_backward", SDL_SCANCODE_S);
|
||||||
|
|
||||||
input_add_action(&ctx.input, "player_jump");
|
input_add_action(&ctx.input, "player_jump");
|
||||||
input_bind_action_scancode(&ctx.input, "player_jump", SDL_SCANCODE_X);
|
input_bind_action_scancode(&ctx.input, "player_jump", SDL_SCANCODE_SPACE);
|
||||||
|
|
||||||
|
input_add_action(&ctx.input, "player_run");
|
||||||
|
input_bind_action_scancode(&ctx.input, "player_run", SDL_SCANCODE_LSHIFT);
|
||||||
|
|
||||||
input_add_action(&ctx.input, "ui_accept");
|
input_add_action(&ctx.input, "ui_accept");
|
||||||
input_bind_action_scancode(&ctx.input, "ui_accept", SDL_SCANCODE_RETURN);
|
input_bind_action_scancode(&ctx.input, "ui_accept", SDL_SCANCODE_RETURN);
|
||||||
|
|
||||||
|
input_add_action(&ctx.input, "mouse_capture_toggle");
|
||||||
|
input_bind_action_scancode(&ctx.input, "mouse_capture_toggle", SDL_SCANCODE_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct state *state = ctx.udata;
|
struct state *state = ctx.udata;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "ingame.h"
|
#include "ingame.h"
|
||||||
|
#include "src/input.h"
|
||||||
#include "title.h"
|
#include "title.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
|
|
||||||
@ -12,14 +13,45 @@ static void ingame_tick(struct state *state) {
|
|||||||
player_calc(scn->player);
|
player_calc(scn->player);
|
||||||
|
|
||||||
static t_camera cam = { .pos = { 32, 0, 1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 };
|
static t_camera cam = { .pos = { 32, 0, 1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 };
|
||||||
cam.target = m_vec_norm(((t_fvec3){ -1, 0, 1 }));
|
|
||||||
|
|
||||||
|
const float sensitivity = 0.6f; /* TODO: put this in a better place */
|
||||||
|
scn->yaw += (float)ctx.input.mouse_relative_position.x * sensitivity;
|
||||||
|
scn->pitch -= (float)ctx.input.mouse_relative_position.y * sensitivity;
|
||||||
|
scn->pitch = clampf(scn->pitch, -89.0f, 89.0f);
|
||||||
|
|
||||||
|
const float yaw_rad = scn->yaw * (float)DEG2RAD;
|
||||||
|
const float pitch_rad = scn->pitch * (float)DEG2RAD;
|
||||||
|
|
||||||
|
cam.target = m_vec_norm(((t_fvec3){
|
||||||
|
cosf(yaw_rad) * cosf(pitch_rad),
|
||||||
|
sinf(pitch_rad),
|
||||||
|
sinf(yaw_rad) * cosf(pitch_rad)
|
||||||
|
}));
|
||||||
|
|
||||||
|
const t_fvec3 right = m_vec_norm(m_vec_cross(cam.target, cam.up));
|
||||||
|
const float speed = 0.04f; /* TODO: put this in a better place */
|
||||||
if (input_is_action_pressed(&ctx.input, "player_left"))
|
if (input_is_action_pressed(&ctx.input, "player_left"))
|
||||||
cam.pos.x -= 0.01f;
|
cam.pos = fvec3_sub(cam.pos, m_vec_scale(right, speed));
|
||||||
|
|
||||||
if (input_is_action_pressed(&ctx.input, "player_right"))
|
if (input_is_action_pressed(&ctx.input, "player_right"))
|
||||||
cam.pos.x += 0.01f;
|
cam.pos = fvec3_add(cam.pos, m_vec_scale(right, speed));
|
||||||
|
|
||||||
|
if (input_is_action_pressed(&ctx.input, "player_forward"))
|
||||||
|
cam.pos = fvec3_add(cam.pos, m_vec_scale(cam.target, speed));
|
||||||
|
|
||||||
|
if (input_is_action_pressed(&ctx.input, "player_backward"))
|
||||||
|
cam.pos = fvec3_sub(cam.pos, m_vec_scale(cam.target, speed));
|
||||||
|
|
||||||
if (input_is_action_pressed(&ctx.input, "player_jump"))
|
if (input_is_action_pressed(&ctx.input, "player_jump"))
|
||||||
cam.pos.z += 0.01f;
|
cam.pos.y += speed;
|
||||||
|
|
||||||
|
if (input_is_action_pressed(&ctx.input, "player_run"))
|
||||||
|
cam.pos.y -= speed;
|
||||||
|
|
||||||
|
/* toggle mouse capture with end key */
|
||||||
|
if (input_is_action_just_pressed(&ctx.input, "mouse_capture_toggle")) {
|
||||||
|
input_set_mouse_captured(&ctx.input, !input_is_mouse_captured(&ctx.input));
|
||||||
|
}
|
||||||
|
|
||||||
m_sprite(m_set(path, "/assets/light.png"),
|
m_sprite(m_set(path, "/assets/light.png"),
|
||||||
m_set(rect, ((t_frect){ 48, 64, 64, 64 })),
|
m_set(rect, ((t_frect){ 48, 64, 64, 64 })),
|
||||||
@ -93,5 +125,7 @@ struct scene *ingame_scene(struct state *state) {
|
|||||||
.repeat = true,
|
.repeat = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
input_set_mouse_captured(&ctx.input, true);
|
||||||
|
|
||||||
return (struct scene *)new_scene;
|
return (struct scene *)new_scene;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@ struct scene_ingame {
|
|||||||
|
|
||||||
struct world *world;
|
struct world *world;
|
||||||
struct player *player;
|
struct player *player;
|
||||||
|
|
||||||
|
/* TODO: put this in a better place */
|
||||||
|
float yaw;
|
||||||
|
float pitch;
|
||||||
|
float roll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
15
src/input.c
15
src/input.c
@ -1,5 +1,6 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
@ -190,6 +191,9 @@ void input_state_update(struct input_state *input) {
|
|||||||
input->mouse_state = SDL_GetMouseState(&input->mouse_window_position.x,
|
input->mouse_state = SDL_GetMouseState(&input->mouse_window_position.x,
|
||||||
&input->mouse_window_position.y);
|
&input->mouse_window_position.y);
|
||||||
|
|
||||||
|
SDL_GetRelativeMouseState(&input->mouse_relative_position.x,
|
||||||
|
&input->mouse_relative_position.y);
|
||||||
|
|
||||||
for (size_t i = 0; i < shlenu(input->action_hash); ++i) {
|
for (size_t i = 0; i < shlenu(input->action_hash); ++i) {
|
||||||
struct action *action = &input->action_hash[i].value;
|
struct action *action = &input->action_hash[i].value;
|
||||||
update_action_pressed_state(input, action);
|
update_action_pressed_state(input, action);
|
||||||
@ -296,3 +300,14 @@ t_fvec2 input_get_action_position(struct input_state *input, char *action_name)
|
|||||||
|
|
||||||
return action->value.position;
|
return action->value.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void input_set_mouse_captured(struct input_state *input, bool enabled) {
|
||||||
|
/* TODO: returns -1 if not supported, but like... do we care? */
|
||||||
|
SDL_SetRelativeMouseMode(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool input_is_mouse_captured(struct input_state *input) {
|
||||||
|
return SDL_GetRelativeMouseMode();
|
||||||
|
}
|
||||||
|
11
src/input.h
11
src/input.h
@ -2,6 +2,7 @@
|
|||||||
#define INPUT_H
|
#define INPUT_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "src/vec.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
@ -39,8 +40,12 @@ struct button {
|
|||||||
/* that is, changes in the states of any of the bound buttons will affect it */
|
/* that is, changes in the states of any of the bound buttons will affect it */
|
||||||
struct action {
|
struct action {
|
||||||
size_t num_bindings;
|
size_t num_bindings;
|
||||||
|
|
||||||
|
/* if you bind more than NUM_KEYBIND_SLOTS (set in config.h) */
|
||||||
|
/* it forgets the first button to add the new one at the end */
|
||||||
struct button bindings[NUM_KEYBIND_SLOTS];
|
struct button bindings[NUM_KEYBIND_SLOTS];
|
||||||
t_fvec2 position; /* set if applicable */
|
|
||||||
|
t_fvec2 position; /* set if applicable, e.g. mouse click */
|
||||||
bool is_pressed;
|
bool is_pressed;
|
||||||
bool just_changed;
|
bool just_changed;
|
||||||
};
|
};
|
||||||
@ -57,6 +62,7 @@ struct input_state {
|
|||||||
const uint8_t *keyboard_state; /* array of booleans indexed by scancode */
|
const uint8_t *keyboard_state; /* array of booleans indexed by scancode */
|
||||||
uint32_t mouse_state; /* SDL mouse button bitmask */
|
uint32_t mouse_state; /* SDL mouse button bitmask */
|
||||||
t_vec2 mouse_window_position;
|
t_vec2 mouse_window_position;
|
||||||
|
t_vec2 mouse_relative_position;
|
||||||
enum button_source last_active_source;
|
enum button_source last_active_source;
|
||||||
bool is_anything_just_pressed;
|
bool is_anything_just_pressed;
|
||||||
};
|
};
|
||||||
@ -85,7 +91,10 @@ void input_delete_action(struct input_state *input, char *action_name);
|
|||||||
bool input_is_action_pressed(struct input_state *input, char *action_name);
|
bool input_is_action_pressed(struct input_state *input, char *action_name);
|
||||||
bool input_is_action_just_pressed(struct input_state *input, char *action_name);
|
bool input_is_action_just_pressed(struct input_state *input, char *action_name);
|
||||||
bool input_is_action_just_released(struct input_state *input, char *action_name);
|
bool input_is_action_just_released(struct input_state *input, char *action_name);
|
||||||
|
|
||||||
t_fvec2 input_get_action_position(struct input_state *input, char *action_name);
|
t_fvec2 input_get_action_position(struct input_state *input, char *action_name);
|
||||||
|
|
||||||
|
void input_set_mouse_captured(struct input_state *input, bool value);
|
||||||
|
bool input_is_mouse_captured(struct input_state *input);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
19
src/util.c
19
src/util.c
@ -101,6 +101,25 @@ void *ccalloc(size_t num, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double clamp(double d, double min, double max) {
|
||||||
|
const double t = d < min ? min : d;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float clampf(float f, float min, float max) {
|
||||||
|
const float t = f < min ? min : f;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int clampi(int i, int min, int max) {
|
||||||
|
const int t = i < min ? min : i;
|
||||||
|
return t > max ? max : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int64_t file_to_bytes(const char *path, unsigned char **buf_out) {
|
int64_t file_to_bytes(const char *path, unsigned char **buf_out) {
|
||||||
SDL_RWops *handle = PHYSFSRWOPS_openRead(path);
|
SDL_RWops *handle = PHYSFSRWOPS_openRead(path);
|
||||||
|
|
||||||
|
@ -53,6 +53,15 @@ void *ccalloc(size_t num, size_t size);
|
|||||||
#define M_PI 3.14159265358979323846264338327950288 /**< pi */
|
#define M_PI 3.14159265358979323846264338327950288 /**< pi */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* multiply by these to convert degrees <---> radians */
|
||||||
|
#define DEG2RAD (M_PI / 180)
|
||||||
|
#define RAD2DEG (180 / M_PI)
|
||||||
|
|
||||||
|
/* TODO: this is why generics were invented. sorry, i'm tired today */
|
||||||
|
double clamp(double d, double min, double max);
|
||||||
|
float clampf(float f, float min, float max);
|
||||||
|
int clampi(int i, int min, int max);
|
||||||
|
|
||||||
/* sets buf_out to a pointer to a byte buffer which must be freed. */
|
/* sets buf_out to a pointer to a byte buffer which must be freed. */
|
||||||
/* returns the size of this buffer. */
|
/* returns the size of this buffer. */
|
||||||
int64_t file_to_bytes(const char *path, unsigned char **buf_out);
|
int64_t file_to_bytes(const char *path, unsigned char **buf_out);
|
||||||
|
30
src/vec.h
30
src/vec.h
@ -66,6 +66,10 @@ static inline t_fvec2 fvec2_from_shvec2(t_shvec2 vec) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline t_fvec3 fvec3_add(t_fvec3 a, t_fvec3 b) {
|
||||||
|
return (t_fvec3) { a.x + b.x, a.y + b.y, a.z + b.z };
|
||||||
|
}
|
||||||
|
|
||||||
static inline t_fvec3 fvec3_sub(t_fvec3 a, t_fvec3 b) {
|
static inline t_fvec3 fvec3_sub(t_fvec3 a, t_fvec3 b) {
|
||||||
return (t_fvec3) { a.x - b.x, a.y - b.y, a.z - b.z };
|
return (t_fvec3) { a.x - b.x, a.y - b.y, a.z - b.z };
|
||||||
}
|
}
|
||||||
@ -97,6 +101,32 @@ static inline t_fvec3 fvec3_norm(t_fvec3 a) {
|
|||||||
return fvec3_scale(a, 1.0f / n);
|
return fvec3_scale(a, 1.0f / n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline t_fvec3 fvec3_rotate(t_fvec3 v, float angle, t_fvec3 axis) {
|
||||||
|
/* from cglm */
|
||||||
|
t_fvec3 v1, v2, k;
|
||||||
|
float c, s;
|
||||||
|
|
||||||
|
c = cosf(angle);
|
||||||
|
s = sinf(angle);
|
||||||
|
|
||||||
|
k = fvec3_norm(axis);
|
||||||
|
|
||||||
|
/* Right Hand, Rodrigues' rotation formula:
|
||||||
|
v = v*cos(t) + (kxv)sin(t) + k*(k.v)(1 - cos(t))
|
||||||
|
*/
|
||||||
|
v1 = fvec3_scale(v, c);
|
||||||
|
|
||||||
|
v2 = fvec3_cross(k, v);
|
||||||
|
v2 = fvec3_scale(v2, s);
|
||||||
|
|
||||||
|
v1 = fvec3_add(v1, v2);
|
||||||
|
|
||||||
|
v2 = fvec3_scale(k, fvec3_dot(k, v) * (1.0f - c));
|
||||||
|
v = fvec3_add(v1, v2);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
#define m_to_fvec2(p_any_vec2) (_Generic((p_any_vec2), \
|
#define m_to_fvec2(p_any_vec2) (_Generic((p_any_vec2), \
|
||||||
t_vec2: fvec2_from_vec2, \
|
t_vec2: fvec2_from_vec2, \
|
||||||
t_shvec2: fvec2_from_shvec2 \
|
t_shvec2: fvec2_from_shvec2 \
|
||||||
|
Loading…
Reference in New Issue
Block a user