player movement

This commit is contained in:
jacob 2024-03-05 13:21:50 -06:00
parent bb9b374471
commit 48fef5ce2e
9 changed files with 202 additions and 180 deletions

View File

@ -185,13 +185,13 @@ if (CRTLIB)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -DCRTLIB=1") set(COMPILER_FLAGS "${COMPILER_FLAGS} -DCRTLIB=1")
else() else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -mno-stack-arg-probe -fno-builtin") set(COMPILER_FLAGS "${COMPILER_FLAGS} -mno-stack-arg-probe -fno-builtin")
set(LINKER_FLAGS "${LINKER_FLAGS} -nostdlib") set(LINKER_FLAGS "${LINKER_FLAGS} -nostdlib")
endif() endif()
# Optimization # Optimization
if (UNOPTIMIZED) if (UNOPTIMIZED)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O0 -DUNOPTIMIZED=1") set(COMPILER_FLAGS "${COMPILER_FLAGS} -O0 -DUNOPTIMIZED=1")
set(LINKER_FLAGS "${LINKER_FLAGS} -O0 -DUNOPTIMIZED=1") set(LINKER_FLAGS "${LINKER_FLAGS} -O0")
else() else()
set(COMPILER_FLAGS "${COMPILER_FLAGS} -O3 -flto") set(COMPILER_FLAGS "${COMPILER_FLAGS} -O3 -flto")
set(LINKER_FLAGS "${LINKER_FLAGS} -O3 -flto -fwhole-program") set(LINKER_FLAGS "${LINKER_FLAGS} -O3 -flto -fwhole-program")
@ -200,6 +200,7 @@ endif()
# Debug info # Debug info
if (DEBINFO) if (DEBINFO)
set(COMPILER_FLAGS "${COMPILER_FLAGS} -g -DDEBINFO=1") set(COMPILER_FLAGS "${COMPILER_FLAGS} -g -DDEBINFO=1")
set(LINKER_FLAGS "${LINKER_FLAGS} -g")
endif() endif()
# Developer mode # Developer mode

View File

@ -51,6 +51,15 @@ struct entity {
struct mat3x3 world_xform; /* Calculated post-physics */ struct mat3x3 world_xform; /* Calculated post-physics */
/* ====================================================================== */
/* Physics */
struct v2 velocity;
f32 drag;
/* ENTITY_PROP_PLAYER_CONTROLLED */
f32 player_acceleration_magnitude;
/* ====================================================================== */ /* ====================================================================== */
/* Sprite */ /* Sprite */
@ -71,15 +80,14 @@ struct entity {
struct sheet_frame animation_frame; struct sheet_frame animation_frame;
/* ====================================================================== */ /* ====================================================================== */
/* ENTITY_PROP_TEST */ /* Testing */
/* ENTITY_PROP_TEST */
b32 test_initialized; b32 test_initialized;
struct trs test_start_rel_trs; struct trs test_start_rel_trs;
struct trs test_start_sprite_trs; struct trs test_start_sprite_trs;
/* ====================================================================== */
/* ENTITY_PROP_TEST_SOUND_EMITTER */ /* ENTITY_PROP_TEST_SOUND_EMITTER */
struct string sound_name; struct string sound_name;
struct mixer_desc sound_desc; struct mixer_desc sound_desc;
struct mixer_track_handle sound_handle; struct mixer_track_handle sound_handle;

View File

@ -10,7 +10,7 @@
#include "math.h" #include "math.h"
#include "scratch.h" #include "scratch.h"
#define GAME_FPS 50 #define GAME_FPS 30
GLOBAL struct { GLOBAL struct {
b32 shutdown; b32 shutdown;
@ -164,8 +164,9 @@ INTERNAL void game_update(void)
run = 1; run = 1;
/* Player ent */ /* Player ent */
struct entity *player_ent;
{ {
(UNUSED)entity_tree_attach;
struct string sprite_name = STR("res/graphics/timmy.ase"); struct string sprite_name = STR("res/graphics/timmy.ase");
struct sheet *sheet = sheet_load(sprite_name); struct sheet *sheet = sheet_load(sprite_name);
@ -177,65 +178,20 @@ INTERNAL void game_update(void)
struct entity *e = entity_alloc(); struct entity *e = entity_alloc();
e->active = true; e->active = true;
e->rel_trs = TRS(.t = pos, .r = PI / 4, .s = V2(2, 1)); e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(1, 1));
e->sprite_name = sprite_name; e->sprite_name = sprite_name;
e->sprite_trs = TRS(.s = sprite_size); e->sprite_trs = TRS(.s = sprite_size);
e->sprite_pivot_norm = V2(0, 0.65); e->sprite_pivot_norm = V2(0, 0.65);
e->sprite_tint = COLOR_WHITE; e->sprite_tint = COLOR_WHITE;
//entity_enable_prop(e, ENTITY_PROP_TEST); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE); e->player_acceleration_magnitude = 5.0f;
e->drag = 2.0;
player_ent = e;
}
/* Child ent */
struct entity *child_ent;
{
struct string sprite_name = STR("res/graphics/timmy.ase");
struct v2 sprite_size = V2(1, 1);
struct v2 pos = V2(2, 2);
struct entity *e = entity_alloc();
e->active = true;
e->rel_trs = TRS(.t = pos, .r = 0, .s = V2(1, 1));
e->sprite_name = sprite_name;
e->sprite_trs = TRS(.s = sprite_size);
//e->sprite_pivot_norm = V2(0, 0.65);
e->sprite_tint = RGBA_F(1, 0, 0, 0.5);
entity_enable_prop(e, ENTITY_PROP_TEST);
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
entity_tree_attach(player_ent, e);
child_ent = e;
}
/* Child ent 2 */
{
struct string sprite_name = STR("res/graphics/timmy.ase");
struct v2 sprite_size = V2(1, 1);
struct v2 pos = V2(0, -1);
struct entity *e = entity_alloc();
e->active = true;
e->rel_trs = TRS(.t = pos, .r = PI / 2, .s = V2(1, 1));
e->sprite_name = sprite_name;
e->sprite_trs = TRS(.s = sprite_size);
//e->sprite_pivot_norm = V2(0, 0.65);
e->sprite_tint = RGBA_F(0, 1, 0, 0.2);
//entity_enable_prop(e, ENTITY_PROP_TEST); //entity_enable_prop(e, ENTITY_PROP_TEST);
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE); //entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
entity_tree_attach(child_ent, e);
} }
} }
@ -248,7 +204,18 @@ INTERNAL void game_update(void)
struct game_cmd cmd = game_cmds.cmds[i]; struct game_cmd cmd = game_cmds.cmds[i];
switch (cmd.kind) { switch (cmd.kind) {
case GAME_CMD_KIND_SET_PLAYER_FOCUS: { /* Movement */
case GAME_CMD_KIND_PLAYER_MOVE: {
struct v2 dir = cmd.dir;
if (v2_len(dir) > 1.f) {
/* Clamp magnitude */
dir = v2_norm(dir);
}
L.tick.player_move = dir;
} break;
/* Focus */
case GAME_CMD_KIND_PLAYER_FOCUS: {
L.tick.player_focus = cmd.pos; L.tick.player_focus = cmd.pos;
} break; } break;
@ -339,6 +306,38 @@ break_animation:
if (!ent->active) continue; if (!ent->active) continue;
if (entity_is_valid(ent->parent)) continue; /* Only update parent entities */ if (entity_is_valid(ent->parent)) continue; /* Only update parent entities */
/* ========================== *
* Player movement
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
f32 acc_magnitude = ent->player_acceleration_magnitude * (f32)L.tick.dt;
struct v2 acc = v2_mul(L.tick.player_move, acc_magnitude);
ent->velocity = v2_add(ent->velocity, acc);
}
/* ========================== *
* Apply velocity
* ========================== */
ent->rel_trs.t = v2_add(ent->rel_trs.t, ent->velocity);
if (ent->drag > 0) {
ent->velocity = v2_div(ent->velocity, ent->drag);
}
/* ========================== *
* Player look direction
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct v2 look_pos = L.tick.player_focus;
struct v2 look_dir = v2_sub(ent->rel_trs.t, look_pos);
look_dir = v2_norm(look_dir);
f32 r = math_atan2(look_dir.y, look_dir.x);
ent->rel_trs.r = -r;
}
/* ========================== * /* ========================== *
* Update position from mouse * Update position from mouse
* ========================== */ * ========================== */
@ -350,8 +349,9 @@ break_animation:
} }
/* ========================== * /* ========================== *
* Calculate tree trs * Calculate xforms
* ========================== */ * ========================== */
ent->world_xform = mat3x3_from_trs(ent->rel_trs); ent->world_xform = mat3x3_from_trs(ent->rel_trs);
struct entity *child = entity_from_handle(ent->first); struct entity *child = entity_from_handle(ent->first);

View File

@ -6,16 +6,20 @@ struct tick;
enum game_cmd_kind { enum game_cmd_kind {
GAME_CMD_KIND_NONE, GAME_CMD_KIND_NONE,
GAME_CMD_KIND_SET_PLAYER_FOCUS, GAME_CMD_KIND_PLAYER_MOVE,
GAME_CMD_KIND_PLAYER_FOCUS,
GAME_CMD_KIND_COUNT GAME_CMD_KIND_COUNT
}; };
struct game_cmd { struct game_cmd {
enum game_cmd_kind kind; enum game_cmd_kind kind;
b32 state; /* 1 = start, 0 = stop */
/* GAME_CMD_KIND_SET_PLAYER_FOCUS */ /* GAME_CMD_KIND_PLAYER_MOVE */
struct v2 dir;
/* GAME_CMD_KIND_PLAYER_FOCUS */
struct v2 pos; struct v2 pos;
}; };

View File

@ -249,10 +249,8 @@ INLINE f32 math_atan2(f32 x, f32 y) {
res = swap ? (s >= 0.0f ? (PI / 2.f) : -(PI / 2.f)) - res : res; res = swap ? (s >= 0.0f ? (PI / 2.f) : -(PI / 2.f)) - res : res;
/* Adjust quadrants */ /* Adjust quadrants */
if (x >= 0.0f && y >= 0.0f) {} /* 1st quadrant */ if (x < 0.0f && y >= 0.0f) { res = PI + res; } /* 2nd quadrant */
else if (x < 0.0f && y >= 0.0f) { res = PI + res; } /* 2nd quadrant */ else if (x <= 0.0f && y < 0.0f) { res = -PI + res; } /* 3rd quadrant */
else if (x < 0.0f && y < 0.0f) { res = -PI + res; } /* 3rd quadrant */
else if (x >= 0.0f && y < 0.0f) {} /* 4th quadrant */
return res; return res;
} }
@ -678,16 +676,6 @@ INLINE struct trs trs_from_mat3x3(struct mat3x3 m)
trs.t = mat3x3_get_pos(m); trs.t = mat3x3_get_pos(m);
trs.r = mat3x3_get_rot(m); trs.r = mat3x3_get_rot(m);
trs.s = mat3x3_get_scale(m); trs.s = mat3x3_get_scale(m);
trs.t = V2(m.e[2][0], m.e[2][1]);
struct v2 bx = V2(m.e[0][0], m.e[0][1]);
struct v2 by = V2(m.e[1][0], m.e[1][1]);
trs.s = V2(v2_len(bx), v2_len(by));
trs.r = math_atan2(bx.x, bx.y);
return trs; return trs;
} }

View File

@ -1,10 +1,6 @@
#ifndef MEMORY_H #ifndef MEMORY_H
#define MEMORY_H #define MEMORY_H
#if CRTLIB
# include <memory.h>
#endif
#define MEMZERO_STRUCT(ptr) MEMZERO(ptr, sizeof(*ptr)) #define MEMZERO_STRUCT(ptr) MEMZERO(ptr, sizeof(*ptr))
#define MEMZERO_ARRAY(a) MEMZERO(a, sizeof(a)) #define MEMZERO_ARRAY(a) MEMZERO(a, sizeof(a))
#define MEMZERO(ptr, count) MEMSET(ptr, 0, count) #define MEMZERO(ptr, count) MEMSET(ptr, 0, count)
@ -12,7 +8,12 @@
#define MEMCPY(dest, src, count) memcpy(dest, src, count) #define MEMCPY(dest, src, count) memcpy(dest, src, count)
#define MEMSET(ptr, val, count) memset(ptr, val, count) #define MEMSET(ptr, val, count) memset(ptr, val, count)
#if CRTLIB
# include <memory.h>
#else
void *memcpy(void *__restrict dest, const void *__restrict src, u64 n); void *memcpy(void *__restrict dest, const void *__restrict src, u64 n);
void *memset(void *dest, int c, u64 n); void *memset(void *dest, int c, u64 n);
#endif
#endif #endif

View File

@ -10,7 +10,8 @@ struct tick {
f64 dt; f64 dt;
f64 time; f64 time;
struct v2 player_focus; /* Mouse cursor pos in world coordinates */ struct v2 player_move; /* Player movement direction */
struct v2 player_focus; /* Mouse cursor pos in world coordinates */
u64 entities_count; /* Includes 'released' & non-active entities */ u64 entities_count; /* Includes 'released' & non-active entities */
struct entity entities[MAX_ENTITIES]; struct entity entities[MAX_ENTITIES];

View File

@ -54,6 +54,22 @@ GLOBAL struct {
struct v2 screen_mouse; struct v2 screen_mouse;
} L = { 0 } DEBUG_LVAR(L_user); } L = { 0 } DEBUG_LVAR(L_user);
/* ========================== *
* Bind state
* ========================== */
/* TODO: Remove this */
GLOBAL enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
[SYS_BTN_W] = USER_BIND_KIND_MOVE_UP,
[SYS_BTN_S] = USER_BIND_KIND_MOVE_DOWN,
[SYS_BTN_A] = USER_BIND_KIND_MOVE_LEFT,
[SYS_BTN_D] = USER_BIND_KIND_MOVE_RIGHT
};
GLOBAL b32 g_bind_state[USER_BIND_KIND_COUNT] = { 0 };
/* ========================== * /* ========================== *
* Window -> user communication * Window -> user communication
* ========================== */ * ========================== */
@ -260,7 +276,7 @@ INTERNAL void user_update(void)
* Read sys events * Read sys events
* ========================== */ * ========================== */
i32 zooms_to_apply = 0; i32 input_zooms = 0;
for (u64 entity_index = 0; entity_index < events.count; ++entity_index) { for (u64 entity_index = 0; entity_index < events.count; ++entity_index) {
struct sys_event *event = &events.events[entity_index]; struct sys_event *event = &events.events[entity_index];
@ -286,9 +302,9 @@ INTERNAL void user_update(void)
/* Zoom camera/view */ /* Zoom camera/view */
if (event->kind == SYS_EVENT_KIND_BUTTON_DOWN) { if (event->kind == SYS_EVENT_KIND_BUTTON_DOWN) {
if (event->button == SYS_BTN_MWHEELUP) { if (event->button == SYS_BTN_MWHEELUP) {
++zooms_to_apply; ++input_zooms;
} else if (event->button == SYS_BTN_MWHEELDOWN) { } else if (event->button == SYS_BTN_MWHEELDOWN) {
--zooms_to_apply; --input_zooms;
} }
} }
@ -313,8 +329,22 @@ INTERNAL void user_update(void)
} }
} }
} }
/* Bind */
if (event->kind == SYS_EVENT_KIND_BUTTON_DOWN || event->kind == SYS_EVENT_KIND_BUTTON_UP) {
enum sys_btn button = event->button;
button = button >= SYS_BTN_COUNT ? SYS_BTN_NONE : button;
enum user_bind_kind bind = g_binds[button];
if (bind) {
g_bind_state[bind] = event->kind == SYS_EVENT_KIND_BUTTON_DOWN;
}
}
} }
/* ========================== *
* Process input
* ========================== */
/* Pan view */ /* Pan view */
if (L.panning) { if (L.panning) {
struct v2 offset = v2_sub(L.panning_from, view_mouse_pos(L.world_view)); struct v2 offset = v2_sub(L.panning_from, view_mouse_pos(L.world_view));
@ -323,9 +353,9 @@ INTERNAL void user_update(void)
} }
/* Zoom view */ /* Zoom view */
if (zooms_to_apply != 0) { if (input_zooms != 0) {
i32 dir = zooms_to_apply >= 0 ? 1 : -1; i32 dir = input_zooms >= 0 ? 1 : -1;
u32 zooms_abs = zooms_to_apply >= 0 ? zooms_to_apply : -zooms_to_apply; u32 zooms_abs = input_zooms >= 0 ? input_zooms : -input_zooms;
/* Zoom camera/view */ /* Zoom camera/view */
f32 zoom_rate = 2; f32 zoom_rate = 2;
@ -347,6 +377,46 @@ INTERNAL void user_update(void)
L.world_view.center = v2_add(L.world_view.center, offset); L.world_view.center = v2_add(L.world_view.center, offset);
} }
/* Process binds */
struct v2 input_move_dir = { 0 };
for (enum user_bind_kind bind = 0; bind < (i32)ARRAY_COUNT(g_bind_state); ++bind) {
b32 state = g_bind_state[bind];
if (!state) {
continue;
}
switch (bind) {
case USER_BIND_KIND_MOVE_UP: {
input_move_dir.y -= 1;
} break;
case USER_BIND_KIND_MOVE_DOWN: {
input_move_dir.y += 1;
} break;
case USER_BIND_KIND_MOVE_LEFT: {
input_move_dir.x -= 1;
} break;
case USER_BIND_KIND_MOVE_RIGHT: {
input_move_dir.x += 1;
} break;
default: break;
}
}
input_move_dir = v2_norm(input_move_dir);
/* Queue move cmd */
queue_game_cmd(&cmd_list, (struct game_cmd) {
.kind = GAME_CMD_KIND_PLAYER_MOVE,
.dir = input_move_dir
});
/* ========================== *
* Produce interpolated tick
* ========================== */
/* Pull ticks */ /* Pull ticks */
struct interp_ticks interp_ticks = pull_interp_ticks(); struct interp_ticks interp_ticks = pull_interp_ticks();
struct tick *t0 = interp_ticks.from_tick; struct tick *t0 = interp_ticks.from_tick;
@ -385,7 +455,6 @@ INTERNAL void user_update(void)
//DEBUGBREAK; //DEBUGBREAK;
} }
e->world_xform = mat3x3_lerp(e0->world_xform, e1->world_xform, blend); e->world_xform = mat3x3_lerp(e0->world_xform, e1->world_xform, blend);
} }
} }
@ -409,7 +478,6 @@ INTERNAL void user_update(void)
i64 rows = 20; i64 rows = 20;
i64 cols = 20; i64 cols = 20;
/* Draw column lines */ /* Draw column lines */
struct v2 col_ray = V2(0, rows); struct v2 col_ray = V2(0, rows);
for (i64 col = starty; col <= (starty + cols); ++col) { for (i64 col = starty; col <= (starty + cols); ++col) {
@ -433,71 +501,6 @@ INTERNAL void user_update(void)
} }
} }
#if 1
/* Draw math functions */
{
u32 detail = 1000;
f32 thickness = 2.f / PIXELS_PER_UNIT / L.world_view.zoom;
/* sin */
{
u32 color = COLOR_RED;
f32 x_start = -10;
f32 x_end = 10;
struct v2_array v = { .points = arena_push_array(scratch.arena, struct v2, detail), .count = detail };
for (u32 i = 0; i < detail; ++i) {
f32 x = x_start + ((x_end - x_start) * (i / ((f32)detail - 1)));
f32 y = math_sin(x);
v.points[i] = V2(x, -y);
}
draw_solid_poly_line(L.world_canvas, v, false, thickness, color);
}
/* arcsin */
{
u32 color = COLOR_BLUE;
f32 x_start = -1;
f32 x_end = 1;
struct v2_array v = { .points = arena_push_array(scratch.arena, struct v2, detail), .count = detail };
for (u32 i = 0; i < detail; ++i) {
f32 x = x_start + ((x_end - x_start) * (i / ((f32)detail - 1)));
f32 y = math_asin(x);
v.points[i] = V2(x, -y);
}
draw_solid_poly_line(L.world_canvas, v, false, thickness, color);
}
/* arccos */
{
u32 color = COLOR_GREEN;
f32 x_start = -1;
f32 x_end = 1;
struct v2_array v = { .points = arena_push_array(scratch.arena, struct v2, detail), .count = detail };
for (u32 i = 0; i < detail; ++i) {
f32 x = x_start + ((x_end - x_start) * (i / ((f32)detail - 1)));
f32 y = math_acos(x);
v.points[i] = V2(x, -y);
}
draw_solid_poly_line(L.world_canvas, v, false, thickness, color);
}
/* arctan */
{
u32 color = COLOR_BLACK;
f32 x_start = -10;
f32 x_end = 10;
struct v2_array v = { .points = arena_push_array(scratch.arena, struct v2, detail), .count = detail };
for (u32 i = 0; i < detail; ++i) {
f32 x = x_start + ((x_end - x_start) * (i / ((f32)detail - 1)));
f32 y = math_atan2(1, x);
v.points[i] = V2(x, -y);
}
draw_solid_poly_line(L.world_canvas, v, false, thickness, color);
}
}
#endif
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -579,39 +582,45 @@ INTERNAL void user_update(void)
draw_solid_circle(L.world_canvas, mat3x3_get_pos(mtx_pre_pivot), 0.02, color, 20); draw_solid_circle(L.world_canvas, mat3x3_get_pos(mtx_pre_pivot), 0.02, color, 20);
} }
}
#if 0 /* Debug draw info */
/* Debug draw sprite info */ {
if (entity_has_prop(ent, ENTITY_PROP_TEST)) { struct mat3x3 mtx = ent->world_xform;
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f); struct v2 bx = mat3x3_get_right(mtx);
f32 offset = 0.3; struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
struct v2 dir = v2_mul(mat3x3_get_up(mtx), 0.5f); f32 offset = 0.75;
dir = v2_add(dir, v2_mul(v2_norm(dir), offset));
struct v2 pos = v2_add(mat3x3_get_pos(mtx), dir); struct v2 dir = v2_mul(mat3x3_get_up(mtx), 0.5f);
dir = v2_add(dir, v2_mul(v2_norm(dir), offset));
struct v2 pos = v2_add(mat3x3_get_pos(mtx), dir);
if (disp_font) { if (disp_font) {
struct string disp_name = { .len = tex_name.len - 13, .text = tex_name.text + 13 }; struct string disp_name = ent->sprite_name;
if (disp_name.len > 13) {
struct string fmt = STR( disp_name = (struct string) { .len = disp_name.len - 13, .text = disp_name.text + 13 };
"sprite name: %F,\n"
"rel rot: %F,\n"
"sprite rot: %F\n"
);
struct string text = string_format(scratch.arena, fmt,
FMT_STR(disp_name),
FMT_FLOAT((f64)ent->world_trs.r),
FMT_FLOAT((f64)ent->sprite_trs.r)
);
draw_text_ex(L.world_canvas, disp_font, pos, 1.0f / PIXELS_PER_UNIT, text);
} }
struct string fmt = STR(
"sprite name: %F,\n"
"rel rot: %F,\n"
"mtx rot: %F,\n"
"mtx bx: %F, %F\n"
);
struct string text = string_format(scratch.arena, fmt,
FMT_STR(disp_name),
FMT_FLOAT((f64)ent->rel_trs.r),
FMT_FLOAT((f64)trs_from_mat3x3(mtx).r),
FMT_FLOAT((f64)bx.x), FMT_FLOAT((f64)bx.y)
);
draw_text_ex(L.world_canvas, disp_font, pos, 1.0f / PIXELS_PER_UNIT, text);
} }
#endif
} }
/* Debug draw transform */ /* Debug draw transform */
@ -629,8 +638,7 @@ INTERNAL void user_update(void)
/* Send world mouse pos */ /* Send world mouse pos */
struct v2 world_mouse = view_mouse_pos(L.world_view); struct v2 world_mouse = view_mouse_pos(L.world_view);
queue_game_cmd(&cmd_list, (struct game_cmd) { queue_game_cmd(&cmd_list, (struct game_cmd) {
.kind = GAME_CMD_KIND_SET_PLAYER_FOCUS, .kind = GAME_CMD_KIND_PLAYER_FOCUS,
.state = true,
.pos = world_mouse .pos = world_mouse
}); });

View File

@ -3,6 +3,17 @@
struct sys_window; struct sys_window;
enum user_bind_kind {
USER_BIND_KIND_NONE,
USER_BIND_KIND_MOVE_UP,
USER_BIND_KIND_MOVE_DOWN,
USER_BIND_KIND_MOVE_LEFT,
USER_BIND_KIND_MOVE_RIGHT,
USER_BIND_KIND_COUNT
};
void user_startup(struct sys_window *window); void user_startup(struct sys_window *window);
void user_shutdown(void); void user_shutdown(void);