get the flycam going already

This commit is contained in:
wanp 2024-07-30 18:05:28 -03:00
parent f00bae7cfc
commit 7f1efce310
8 changed files with 146 additions and 12 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 \