ln, exp, pow, camera lerping
This commit is contained in:
parent
fa6df3152c
commit
39f7b09036
@ -278,6 +278,10 @@ typedef u64 umm;
|
|||||||
#define I32_MIN ((i32)-0x80000000)
|
#define I32_MIN ((i32)-0x80000000)
|
||||||
#define I64_MIN ((i64)-0x8000000000000000LL)
|
#define I64_MIN ((i64)-0x8000000000000000LL)
|
||||||
|
|
||||||
|
#define F32_INFINITY (1.0 / 0.0f)
|
||||||
|
#define F32_MAX (3.402823466e+38F)
|
||||||
|
#define F32_MIN (1.175494351e-38F)
|
||||||
|
|
||||||
#define PI ((f32)3.14159265358979323846)
|
#define PI ((f32)3.14159265358979323846)
|
||||||
#define TAU ((f32)6.28318530717958647693)
|
#define TAU ((f32)6.28318530717958647693)
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,11 @@ struct entity {
|
|||||||
|
|
||||||
/* ENTITY_PROP_CAMERA */
|
/* ENTITY_PROP_CAMERA */
|
||||||
struct entity_handle camera_follow;
|
struct entity_handle camera_follow;
|
||||||
|
struct xform camera_target_xform; /* Calculated from camera_follow */
|
||||||
f32 camera_zoom;
|
f32 camera_zoom;
|
||||||
|
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
||||||
|
u32 camera_lerp_gen;
|
||||||
|
u32 camera_applied_lerp_gen_plus_one; /* Calculated */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_array {
|
struct entity_array {
|
||||||
|
|||||||
33
src/game.c
33
src/game.c
@ -119,7 +119,7 @@ INTERNAL void game_update(void)
|
|||||||
e->sprite_tint = COLOR_WHITE;
|
e->sprite_tint = COLOR_WHITE;
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
e->player_max_speed = 5.f;
|
e->player_max_speed = 4.f;
|
||||||
e->player_acceleration = 20.0f;
|
e->player_acceleration = 20.0f;
|
||||||
e->player_focus_dir = V2(0, -1);
|
e->player_focus_dir = V2(0, -1);
|
||||||
|
|
||||||
@ -452,18 +452,41 @@ INTERNAL void game_update(void)
|
|||||||
* Update camera position
|
* Update camera position
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
/* Camera follow */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
||||||
struct entity *follow = entity_from_handle(&L.world.entity_store, ent->camera_follow);
|
struct entity *follow = entity_from_handle(&L.world.entity_store, ent->camera_follow);
|
||||||
ent->world_xform = follow->world_xform;
|
ent->camera_target_xform = follow->world_xform;
|
||||||
ent->world_xform = xform_with_rotation(ent->world_xform, 0);
|
ent->camera_target_xform = xform_with_rotation(ent->camera_target_xform, 0);
|
||||||
ent->world_xform = xform_with_scale(ent->world_xform, V2(1, 1));
|
ent->camera_target_xform = xform_with_scale(ent->camera_target_xform, V2(1, 1));
|
||||||
|
|
||||||
if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
|
#if 1
|
||||||
|
/* Regular style camera */
|
||||||
|
f32 target_dist_x = 0.5;
|
||||||
|
f32 target_dist_y = target_dist_x * (16.0f / 9.0f);
|
||||||
|
struct v2 focus_dir = follow->player_focus_dir;
|
||||||
|
struct v2 target_dir = v2_mul_v2(v2_norm(focus_dir), V2(target_dist_x, target_dist_y));
|
||||||
|
struct v2 target_pos = v2_add(ent->camera_target_xform.og, target_dir);
|
||||||
|
ent->camera_target_xform.og = target_pos;
|
||||||
|
#else
|
||||||
|
/* "Look" style camera */
|
||||||
struct v2 focus_dir = follow->player_focus_dir;
|
struct v2 focus_dir = follow->player_focus_dir;
|
||||||
struct v2 focus_half_dir = v2_mul(focus_dir, 0.5f);
|
struct v2 focus_half_dir = v2_mul(focus_dir, 0.5f);
|
||||||
struct v2 focus_half_pos = v2_add(follow->world_xform.og, focus_half_dir);
|
struct v2 focus_half_pos = v2_add(follow->world_xform.og, focus_half_dir);
|
||||||
ent->world_xform.og = focus_half_pos;
|
ent->camera_target_xform.og = focus_half_pos;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lerp camera */
|
||||||
|
if (ent->camera_applied_lerp_gen_plus_one == ent->camera_lerp_gen + 1) {
|
||||||
|
f32 t = 1 - math_pow(2.f, -10.f * (f32)L.world.dt);
|
||||||
|
ent->rel_xform = xform_lerp(ent->rel_xform, ent->camera_target_xform, t);
|
||||||
|
} else {
|
||||||
|
/* Skip lerp */
|
||||||
|
ent->rel_xform = ent->camera_target_xform;
|
||||||
|
}
|
||||||
|
ent->camera_applied_lerp_gen_plus_one = ent->camera_lerp_gen + 1;
|
||||||
|
ent->world_xform = ent->rel_xform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
188
src/math.h
188
src/math.h
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "intrinsics.h"
|
#include "intrinsics.h"
|
||||||
|
|
||||||
|
INLINE f32 math_sqrt(f32 x);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Rounding
|
* Rounding
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -37,9 +39,8 @@ INLINE f32 math_fabs(f32 f)
|
|||||||
|
|
||||||
INLINE i32 math_fsign(f32 f)
|
INLINE i32 math_fsign(f32 f)
|
||||||
{
|
{
|
||||||
u32 bits = *(u32 *)&f;
|
u32 sign_bit = (*(u32 *)&f >> 31) & 1;
|
||||||
i32 sign_bit = bits & ((u32)1 << 31);
|
return 1 + -(sign_bit << 1);
|
||||||
return 1 + (sign_bit * -2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -128,6 +129,174 @@ INLINE u64 math_pow_u64(u64 base, u8 exp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Based on FreeBSD's implementation
|
||||||
|
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_logf.c */
|
||||||
|
INLINE f32 math_ln(f32 x)
|
||||||
|
{
|
||||||
|
static const f32 ln2_hi = 6.9313812256e-01;
|
||||||
|
static const f32 ln2_lo = 9.0580006145e-06;
|
||||||
|
|
||||||
|
i32 x_int = *(u32 *)&x;
|
||||||
|
|
||||||
|
i32 k = 0;
|
||||||
|
if (x_int < 0x00800000) {
|
||||||
|
f32 two_p25 = 3.3554432000e+07;
|
||||||
|
if ((x_int & 0x7fffffff) == 0) {
|
||||||
|
/* Return -inf if x is 0 */
|
||||||
|
return -two_p25 / 0;
|
||||||
|
} else if (x_int < 0) {
|
||||||
|
/* Return NaN if x is negative */
|
||||||
|
return (x - x) / 0;
|
||||||
|
}
|
||||||
|
k -= 25;
|
||||||
|
x *= two_p25;
|
||||||
|
x_int = *(u32 *)&x;
|
||||||
|
} else if (x_int >= 0x7f800000) {
|
||||||
|
return x + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
k += (x_int >> 23) - 127;
|
||||||
|
x_int &= 0x007fffff;
|
||||||
|
i32 i = (x_int + (0x95f64 << 3)) & 0x800000;
|
||||||
|
i32 x_int_normalized = x_int | (i ^ 0x3f800000);
|
||||||
|
x = *(f32 *)&x_int_normalized - 1.0f;
|
||||||
|
k += (i >> 23);
|
||||||
|
|
||||||
|
if ((0x007fffff & (0x8000 + x_int)) < 0xc000) {
|
||||||
|
if (x == 0.0f) {
|
||||||
|
if (k == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return (f32)k * ln2_hi + (f32)k * ln2_lo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f32 r = x * x * (0.5f - 0.33333333333333333f * x);
|
||||||
|
if (k == 0) {
|
||||||
|
return x - r;
|
||||||
|
} else {
|
||||||
|
return (f32)k * ln2_hi - ((r - (f32)k * ln2_lo) - x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 s = x / (2.0f + x);
|
||||||
|
f32 z = s * s;
|
||||||
|
f32 w = z * z;
|
||||||
|
f32 r = (z * (0.66666662693f + w * 0.28498786688f)) + (w * (0.40000972152f + w * 0.24279078841f));
|
||||||
|
if (((x_int - (0x6147a << 3)) | ((0x6b851 << 3) - x_int)) > 0) {
|
||||||
|
f32 hfsq = 0.5f * x * x;
|
||||||
|
if (k == 0) {
|
||||||
|
return x - (hfsq - s * (hfsq + r));
|
||||||
|
} else {
|
||||||
|
return (f32)k * ln2_hi - ((hfsq - (s * (hfsq + r) + (f32)k * ln2_lo)) - x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (k == 0) {
|
||||||
|
return x - s * (x - r);
|
||||||
|
} else {
|
||||||
|
return (f32)k * ln2_hi - ((s * (x - r) - (f32)k * ln2_lo) - x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Based on FreeBSD's implementation
|
||||||
|
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_expf.c */
|
||||||
|
INLINE f32 math_exp(f32 x)
|
||||||
|
{
|
||||||
|
static const f32 half[2] = { 0.5, -0.5 };
|
||||||
|
static const f32 o_threshold = 8.8721679688e+01;
|
||||||
|
static const f32 u_threshold = -1.0397208405e+02;
|
||||||
|
static const f32 ln2_hi[2] = { 6.9314575195e-01, -6.9314575195e-01 };
|
||||||
|
static const f32 ln2_lo[2] = { 1.4286067653e-06, -1.4286067653e-06 };
|
||||||
|
static const f32 inv_ln2 = 1.4426950216e+00;
|
||||||
|
static const f32 huge = 1.0e+30;
|
||||||
|
static const f32 two_m100 = 7.8886090522e-31;
|
||||||
|
|
||||||
|
u32 x_uint = *(u32 *)&x;
|
||||||
|
i32 x_sign_bit = (x_uint >> 31) & 1;
|
||||||
|
x_uint &= 0x7fffffff;
|
||||||
|
|
||||||
|
/* Filter out non-finite argument */
|
||||||
|
if (x_uint >= 0x42b17218) { /* if |x|>=88.721... */
|
||||||
|
if (x_uint > 0x7f800000) {
|
||||||
|
return x + x; /* NaN */
|
||||||
|
} else if (x_uint == 0x7f800000) {
|
||||||
|
return (x_sign_bit == 0) ? x : 0.0;
|
||||||
|
}
|
||||||
|
if (x > o_threshold) {
|
||||||
|
/* Overflow */
|
||||||
|
return huge * huge;
|
||||||
|
} else if (x < u_threshold) {
|
||||||
|
/* Underflow */
|
||||||
|
return two_m100 * two_m100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Argument reduction */
|
||||||
|
i32 k = 0;
|
||||||
|
f32 hi = 0;
|
||||||
|
f32 lo = 0;
|
||||||
|
if (x_uint > 0x3eb17218) {
|
||||||
|
if (x_uint < 0x3F851592) {
|
||||||
|
hi = x - ln2_hi[x_sign_bit];
|
||||||
|
lo = ln2_lo[x_sign_bit];
|
||||||
|
k = 1 - x_sign_bit - x_sign_bit;
|
||||||
|
} else {
|
||||||
|
k = inv_ln2 * x + half[x_sign_bit];
|
||||||
|
hi = x - (f32)k * ln2_hi[0];
|
||||||
|
lo = (f32)k * ln2_lo[0];
|
||||||
|
}
|
||||||
|
x = hi - lo;
|
||||||
|
} else if (x_uint < 0x39000000) {
|
||||||
|
if (huge + x > 1.0f) {
|
||||||
|
return 1.0f + x;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
k = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 two_pk;
|
||||||
|
if (k >= -125) {
|
||||||
|
u32 temp = ((u32)(0x7f + k)) << 23;
|
||||||
|
two_pk = *(f32 *)&temp;
|
||||||
|
} else {
|
||||||
|
u32 temp = ((u32)(0x7f + (k + 100))) << 23;
|
||||||
|
two_pk = *(f32 *)&temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 t = x * x;
|
||||||
|
f32 c = x - t * (1.6666625440e-1f + t * -2.7667332906e-3f);
|
||||||
|
if (k == 0) {
|
||||||
|
return 1.0f - ((x * c) / (c - 2.0f) - x);
|
||||||
|
} else {
|
||||||
|
f32 y = 1.0f - ((lo - (x * c)/(2.0f - c))-hi);
|
||||||
|
if (k >= -125) {
|
||||||
|
if (k==128) {
|
||||||
|
u32 temp = 0x7f800000;
|
||||||
|
return y * 2.0f * (*(f32 *)&temp);
|
||||||
|
}
|
||||||
|
return y * two_pk;
|
||||||
|
} else {
|
||||||
|
return y * two_pk * two_m100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE f32 math_pow(f32 a, f32 b)
|
||||||
|
{
|
||||||
|
if (a >= 0) {
|
||||||
|
/* a is positive */
|
||||||
|
return math_exp(math_ln(a) * b);
|
||||||
|
} else {
|
||||||
|
/* a is negative */
|
||||||
|
i32 res_sign = math_round(b) % 2 == 0 ? 1 : -1;
|
||||||
|
return math_exp(math_ln(-a) * b) * res_sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE f32 math_sqrt(f32 x)
|
||||||
|
{
|
||||||
|
return ix_sqrt_f32(x);
|
||||||
|
}
|
||||||
|
|
||||||
INLINE f32 math_rsqrt(f32 x)
|
INLINE f32 math_rsqrt(f32 x)
|
||||||
{
|
{
|
||||||
@ -145,15 +314,10 @@ INLINE f32 math_rsqrt_fast(f32 x)
|
|||||||
i32 i = *(i32 *)&y;
|
i32 i = *(i32 *)&y;
|
||||||
i = 0x5f3759df - (i >> 1);
|
i = 0x5f3759df - (i >> 1);
|
||||||
y = *(f32 *)&i;
|
y = *(f32 *)&i;
|
||||||
y *= three_halfs - (x2 * y * y); /* 1st iteration */
|
y *= three_halfs - (x2 * y * y);
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE f32 math_sqrt(f32 x)
|
|
||||||
{
|
|
||||||
return ix_sqrt_f32(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Trig
|
* Trig
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -224,7 +388,7 @@ INLINE f32 math_acos(f32 x)
|
|||||||
* Lerp
|
* Lerp
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INLINE f32 math_lerp_f32(f32 val0, f32 val1, f32 t)
|
INLINE f32 math_lerp(f32 val0, f32 val1, f32 t)
|
||||||
{
|
{
|
||||||
return val0 + ((val1 - val0) * t);
|
return val0 + ((val1 - val0) * t);
|
||||||
}
|
}
|
||||||
@ -364,8 +528,8 @@ INLINE b32 v2_eq(struct v2 a, struct v2 b)
|
|||||||
INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
||||||
{
|
{
|
||||||
struct v2 res;
|
struct v2 res;
|
||||||
res.x = math_lerp_f32(val0.x, val1.x, t);
|
res.x = math_lerp(val0.x, val1.x, t);
|
||||||
res.y = math_lerp_f32(val0.y, val1.y, t);
|
res.y = math_lerp(val0.y, val1.y, t);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
src/mixer.c
10
src/mixer.c
@ -370,8 +370,8 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
|
|||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
f32 t = in_frame_pos_exact - (f32)in_frame_pos_prev;
|
f32 t = in_frame_pos_exact - (f32)in_frame_pos_prev;
|
||||||
f32 sample1 = math_lerp_f32(sample1_prev, sample1_next, t);
|
f32 sample1 = math_lerp(sample1_prev, sample1_next, t);
|
||||||
f32 sample2 = math_lerp_f32(sample2_prev, sample2_next, t);
|
f32 sample2 = math_lerp(sample2_prev, sample2_next, t);
|
||||||
|
|
||||||
out_samples[(out_frame_pos * 2) + 0] += sample1;
|
out_samples[(out_frame_pos * 2) + 0] += sample1;
|
||||||
out_samples[(out_frame_pos * 2) + 1] += sample2;
|
out_samples[(out_frame_pos * 2) + 1] += sample2;
|
||||||
@ -389,7 +389,7 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
|
|||||||
|
|
||||||
/* Lerp */
|
/* Lerp */
|
||||||
f32 t = (f32)in_frame_pos_exact - in_frame_pos_prev;
|
f32 t = (f32)in_frame_pos_exact - in_frame_pos_prev;
|
||||||
f32 sample = math_lerp_f32(sample_prev, sample_next, t);
|
f32 sample = math_lerp(sample_prev, sample_next, t);
|
||||||
|
|
||||||
out_samples[(out_frame_pos * 2) + 0] += sample;
|
out_samples[(out_frame_pos * 2) + 0] += sample;
|
||||||
out_samples[(out_frame_pos * 2) + 1] += sample;
|
out_samples[(out_frame_pos * 2) + 1] += sample;
|
||||||
@ -440,8 +440,8 @@ struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_count)
|
|||||||
/* Spatialize samples */
|
/* Spatialize samples */
|
||||||
for (u64 frame_pos = 0; frame_pos < frame_count; ++frame_pos) {
|
for (u64 frame_pos = 0; frame_pos < frame_count; ++frame_pos) {
|
||||||
f32 t = (f32)frame_pos / (f32)(frame_count - 1);
|
f32 t = (f32)frame_pos / (f32)(frame_count - 1);
|
||||||
f32 volume = math_lerp_f32(volume_start, volume_end, t);
|
f32 volume = math_lerp(volume_start, volume_end, t);
|
||||||
f32 pan = math_lerp_f32(pan_start, pan_end, t);
|
f32 pan = math_lerp(pan_start, pan_end, t);
|
||||||
|
|
||||||
u64 sample1_index = frame_pos * 2;
|
u64 sample1_index = frame_pos * 2;
|
||||||
u64 sample2_index = sample1_index + 1;
|
u64 sample2_index = sample1_index + 1;
|
||||||
|
|||||||
12
src/sys.h
12
src/sys.h
@ -13,8 +13,8 @@ enum sys_event_kind {
|
|||||||
|
|
||||||
SYS_EVENT_KIND_BUTTON_DOWN,
|
SYS_EVENT_KIND_BUTTON_DOWN,
|
||||||
SYS_EVENT_KIND_BUTTON_UP,
|
SYS_EVENT_KIND_BUTTON_UP,
|
||||||
|
SYS_EVENT_KIND_CURSOR_MOVE,
|
||||||
SYS_EVENT_KIND_MOUSE_MOVE,
|
SYS_EVENT_KIND_MOUSE_MOVE,
|
||||||
SYS_EVENT_KIND_RAW_MOUSE_MOVE,
|
|
||||||
SYS_EVENT_KIND_TEXT,
|
SYS_EVENT_KIND_TEXT,
|
||||||
SYS_EVENT_KIND_QUIT,
|
SYS_EVENT_KIND_QUIT,
|
||||||
|
|
||||||
@ -128,15 +128,19 @@ enum sys_btn {
|
|||||||
struct sys_event {
|
struct sys_event {
|
||||||
enum sys_event_kind kind;
|
enum sys_event_kind kind;
|
||||||
|
|
||||||
|
/* SYS_EVENT_KIND_BUTTON_DOWN */
|
||||||
|
/* SYS_EVENT_KIND_BUTTON_UP */
|
||||||
enum sys_btn button;
|
enum sys_btn button;
|
||||||
b32 is_repeat;
|
b32 is_repeat;
|
||||||
|
|
||||||
|
/* SYS_EVENT_KIND_TEXT */
|
||||||
u32 text_character;
|
u32 text_character;
|
||||||
|
|
||||||
struct v2 mouse_position;
|
/* SYS_EVENT_KIND_CURSOR_MOVE */
|
||||||
struct v2 mouse_delta;
|
struct v2 cursor_position;
|
||||||
|
|
||||||
struct v2 raw_mouse_delta;
|
/* SYS_EVENT_KIND_MOUSE_MOVE */
|
||||||
|
struct v2 mouse_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sys_event_array {
|
struct sys_event_array {
|
||||||
|
|||||||
@ -59,7 +59,6 @@ struct win32_window {
|
|||||||
* their pre-minimized values) */
|
* their pre-minimized values) */
|
||||||
i32 x, y, width, height;
|
i32 x, y, width, height;
|
||||||
|
|
||||||
struct v2 cursor_pos;
|
|
||||||
u32 cursor_set_flags;
|
u32 cursor_set_flags;
|
||||||
struct v2 cursor_set_position;
|
struct v2 cursor_set_position;
|
||||||
|
|
||||||
@ -788,7 +787,7 @@ INTERNAL void win32_update_window_from_settings(struct win32_window *window, str
|
|||||||
INTERNAL void win32_window_wake(struct win32_window *window)
|
INTERNAL void win32_window_wake(struct win32_window *window)
|
||||||
{
|
{
|
||||||
/* Post a blank message to the window's thread message queue to wake it. */
|
/* Post a blank message to the window's thread message queue to wake it. */
|
||||||
PostThreadMessageA(window->tid, 0, 0, 0);
|
PostThreadMessageA(window->tid, WM_NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
@ -915,8 +914,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
window,
|
window,
|
||||||
(struct sys_event) {
|
(struct sys_event) {
|
||||||
.kind = event_kind,
|
.kind = event_kind,
|
||||||
.button = button,
|
.button = button
|
||||||
.mouse_position = window->cursor_pos
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -938,15 +936,11 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
case WM_MOUSEMOVE: {
|
case WM_MOUSEMOVE: {
|
||||||
i32 x = GET_X_LPARAM(lparam);
|
i32 x = GET_X_LPARAM(lparam);
|
||||||
i32 y = GET_Y_LPARAM(lparam);
|
i32 y = GET_Y_LPARAM(lparam);
|
||||||
struct v2 old = window->cursor_pos;
|
|
||||||
window->cursor_pos = V2(x, y);
|
|
||||||
struct v2 delta = v2_sub(window->cursor_pos, old);
|
|
||||||
win32_window_process_event(
|
win32_window_process_event(
|
||||||
window,
|
window,
|
||||||
(struct sys_event) {
|
(struct sys_event) {
|
||||||
.kind = SYS_EVENT_KIND_MOUSE_MOVE,
|
.kind = SYS_EVENT_KIND_CURSOR_MOVE,
|
||||||
.mouse_position = window->cursor_pos,
|
.cursor_position = V2(x, y)
|
||||||
.mouse_delta = delta
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
@ -972,8 +966,8 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||||||
win32_window_process_event(
|
win32_window_process_event(
|
||||||
window,
|
window,
|
||||||
(struct sys_event) {
|
(struct sys_event) {
|
||||||
.kind = SYS_EVENT_KIND_RAW_MOUSE_MOVE,
|
.kind = SYS_EVENT_KIND_MOUSE_MOVE,
|
||||||
.raw_mouse_delta = delta
|
.mouse_delta = delta
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@ extern "C"
|
|||||||
#include "ttf.h"
|
#include "ttf.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "scratch.h"
|
#include "scratch.h"
|
||||||
#include "math.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* TODO: remove this */
|
/* TODO: remove this */
|
||||||
|
|||||||
43
src/user.c
43
src/user.c
@ -64,9 +64,9 @@ GLOBAL struct {
|
|||||||
f64 dt;
|
f64 dt;
|
||||||
struct v2 screen_size;
|
struct v2 screen_size;
|
||||||
struct v2 screen_center;
|
struct v2 screen_center;
|
||||||
struct v2 screen_mouse;
|
struct v2 screen_cursor;
|
||||||
struct v2 screen_mouse_delta;
|
struct v2 world_cursor;
|
||||||
struct v2 world_mouse;
|
struct v2 mouse_delta;
|
||||||
struct v2 last_focus_screen_pos;
|
struct v2 last_focus_screen_pos;
|
||||||
} L = { 0 }, DEBUG_LVAR(L_user);
|
} L = { 0 }, DEBUG_LVAR(L_user);
|
||||||
|
|
||||||
@ -405,13 +405,14 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend);
|
e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend);
|
||||||
e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend);
|
e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend);
|
||||||
e->player_acceleration = math_lerp_f32(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
e->player_acceleration = math_lerp(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
||||||
e->player_focus_dir = v2_lerp(e0->player_focus_dir, e1->player_focus_dir, tick_blend);
|
e->player_focus_dir = v2_lerp(e0->player_focus_dir, e1->player_focus_dir, tick_blend);
|
||||||
|
|
||||||
e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend);
|
e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend);
|
||||||
e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
||||||
|
|
||||||
e->camera_zoom = math_lerp_f32(e0->camera_zoom, e1->camera_zoom, tick_blend);
|
e->camera_zoom = math_lerp(e0->camera_zoom, e1->camera_zoom, tick_blend);
|
||||||
|
e->camera_target_xform = xform_lerp(e0->camera_target_xform, e1->camera_target_xform, tick_blend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -436,7 +437,7 @@ INTERNAL void user_update(void)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
L.screen_mouse_delta = V2(0, 0);
|
L.mouse_delta = V2(0, 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];
|
||||||
@ -475,13 +476,13 @@ INTERNAL void user_update(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Update mouse pos */
|
/* Update mouse pos */
|
||||||
if (event->kind == SYS_EVENT_KIND_MOUSE_MOVE) {
|
if (event->kind == SYS_EVENT_KIND_CURSOR_MOVE) {
|
||||||
L.screen_mouse = event->mouse_position;
|
L.screen_cursor = event->cursor_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update mouse delta */
|
/* Update mouse delta */
|
||||||
if (event->kind == SYS_EVENT_KIND_RAW_MOUSE_MOVE) {
|
if (event->kind == SYS_EVENT_KIND_MOUSE_MOVE) {
|
||||||
L.screen_mouse_delta = v2_add(L.screen_mouse_delta, event->raw_mouse_delta);
|
L.mouse_delta = v2_add(L.mouse_delta, event->mouse_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update bind states */
|
/* Update bind states */
|
||||||
@ -540,12 +541,12 @@ INTERNAL void user_update(void)
|
|||||||
/* Pan view */
|
/* Pan view */
|
||||||
if (L.bind_states[USER_BIND_KIND_PAN].is_held) {
|
if (L.bind_states[USER_BIND_KIND_PAN].is_held) {
|
||||||
if (!L.debug_camera_panning) {
|
if (!L.debug_camera_panning) {
|
||||||
L.debug_camera_pan_start = xform_invert_mul_v2(L.world_view, L.screen_mouse);
|
L.debug_camera_pan_start = xform_invert_mul_v2(L.world_view, L.screen_cursor);
|
||||||
}
|
}
|
||||||
L.debug_camera_panning = true;
|
L.debug_camera_panning = true;
|
||||||
struct v2 offset = v2_sub(L.debug_camera_pan_start, xform_invert_mul_v2(L.world_view, L.screen_mouse));
|
struct v2 offset = v2_sub(L.debug_camera_pan_start, xform_invert_mul_v2(L.world_view, L.screen_cursor));
|
||||||
L.world_view = xform_translate(L.world_view, v2_neg(offset));
|
L.world_view = xform_translate(L.world_view, v2_neg(offset));
|
||||||
L.debug_camera_pan_start = xform_invert_mul_v2(L.world_view, L.screen_mouse);
|
L.debug_camera_pan_start = xform_invert_mul_v2(L.world_view, L.screen_cursor);
|
||||||
} else {
|
} else {
|
||||||
L.debug_camera_panning = false;
|
L.debug_camera_panning = false;
|
||||||
}
|
}
|
||||||
@ -567,13 +568,12 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zoom to mouse */
|
/* Zoom to cursor */
|
||||||
struct v2 world_mouse = xform_invert_mul_v2(L.world_view, L.screen_mouse);
|
struct v2 world_cursor = xform_invert_mul_v2(L.world_view, L.screen_cursor);
|
||||||
L.world_view = xform_translate(L.world_view, world_mouse);
|
L.world_view = xform_translate(L.world_view, world_cursor);
|
||||||
L.world_view = xform_scale(L.world_view, V2(zoom, zoom));
|
L.world_view = xform_scale(L.world_view, V2(zoom, zoom));
|
||||||
L.world_view = xform_translate(L.world_view, v2_neg(world_mouse));
|
L.world_view = xform_translate(L.world_view, v2_neg(world_cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Keep cursor invisible and in screen */
|
/* Keep cursor invisible and in screen */
|
||||||
sys_window_cursor_hide(L.window);
|
sys_window_cursor_hide(L.window);
|
||||||
@ -602,6 +602,7 @@ INTERNAL void user_update(void)
|
|||||||
L.world_view = xform_translate(L.world_view, pivot);
|
L.world_view = xform_translate(L.world_view, pivot);
|
||||||
L.world_view = xform_trs_pivot_rs(L.world_view, trs, pivot);
|
L.world_view = xform_trs_pivot_rs(L.world_view, trs, pivot);
|
||||||
}
|
}
|
||||||
|
L.world_cursor = xform_invert_mul_v2(L.world_view, L.screen_cursor);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update listener
|
* Update listener
|
||||||
@ -658,7 +659,7 @@ INTERNAL void user_update(void)
|
|||||||
.move_dir = player_move_dir
|
.move_dir = player_move_dir
|
||||||
};
|
};
|
||||||
if (!L.debug_camera) {
|
if (!L.debug_camera) {
|
||||||
struct v2 focus_move_dir = xform_basis_invert_mul_v2(L.world_view, L.screen_mouse_delta); /* Make focus relative to world view direction */
|
struct v2 focus_move_dir = xform_basis_invert_mul_v2(L.world_view, L.mouse_delta); /* Make focus relative to world view direction */
|
||||||
focus_move_dir = v2_mul(focus_move_dir, MOUSE_SENSITIVITY);
|
focus_move_dir = v2_mul(focus_move_dir, MOUSE_SENSITIVITY);
|
||||||
cmd.focus_move_dir = focus_move_dir;
|
cmd.focus_move_dir = focus_move_dir;
|
||||||
}
|
}
|
||||||
@ -887,7 +888,7 @@ INTERNAL void user_update(void)
|
|||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("screen_center: (%F, %F)"), FMT_FLOAT((f64)L.screen_center.x), FMT_FLOAT((f64)L.screen_center.y)));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("screen_center: (%F, %F)"), FMT_FLOAT((f64)L.screen_center.x), FMT_FLOAT((f64)L.screen_center.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("screen_mouse: (%F, %F)"), FMT_FLOAT((f64)L.screen_mouse.x), FMT_FLOAT((f64)L.screen_mouse.y)));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("screen_cursor: (%F, %F)"), FMT_FLOAT((f64)L.screen_cursor.x), FMT_FLOAT((f64)L.screen_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_view.og: (%F, %F)"), FMT_FLOAT((f64)L.world_view.og.x), FMT_FLOAT((f64)L.world_view.og.y)));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_view.og: (%F, %F)"), FMT_FLOAT((f64)L.world_view.og.x), FMT_FLOAT((f64)L.world_view.og.y)));
|
||||||
@ -899,7 +900,7 @@ INTERNAL void user_update(void)
|
|||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_view scale: (%F, %F)"), FMT_FLOAT((f64)xform_get_scale(L.world_view).x), FMT_FLOAT((f64)xform_get_scale(L.world_view).x)));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_view scale: (%F, %F)"), FMT_FLOAT((f64)xform_get_scale(L.world_view).x), FMT_FLOAT((f64)xform_get_scale(L.world_view).x)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_mouse: (%F, %F)"), FMT_FLOAT((f64)L.world_mouse.x), FMT_FLOAT((f64)L.world_mouse.y)));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("world_cursor: (%F, %F)"), FMT_FLOAT((f64)L.world_cursor.x), FMT_FLOAT((f64)L.world_cursor.y)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("debug_camera: %F"), FMT_STR(L.debug_camera ? STR("true") : STR("false"))));
|
draw_text(L.screen_canvas, font, pos, string_format(temp.arena, STR("debug_camera: %F"), FMT_STR(L.debug_camera ? STR("true") : STR("false"))));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user