From 67171a99067d5bb33cc361da5df7a260a2d3d666 Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 18 Feb 2026 18:07:48 -0600 Subject: [PATCH] roll testing --- src/base/base_math.c | 38 +++++----- src/base/base_string.c | 37 +++++----- src/gpu/gpu_dx12/gpu_dx12_core.c | 2 +- src/meta/meta.c | 5 +- src/pp/pp.c | 116 +++++++++++++++++++++++-------- src/pp/pp.h | 8 ++- src/pp/pp_res/guy/guy.ase | 4 +- src/pp/pp_transcode.c | 20 +++--- src/pp/pp_vis/pp_vis_core.c | 27 +++++-- src/pp/pp_vis/pp_vis_gpu.g | 22 ++---- src/pp/pp_vis/pp_vis_shared.cgh | 1 + 11 files changed, 178 insertions(+), 102 deletions(-) diff --git a/src/base/base_math.c b/src/base/base_math.c index 56622f77..0f768ce7 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -444,29 +444,40 @@ f32 Vec2LenSq(Vec2 a) Vec2 Vec2WithLen(Vec2 a, f32 len) { f32 l_sq = a.x * a.x + a.y * a.y; - if (l_sq != 0) + if (l_sq > 0) { f32 denom = len / SqrtF32(l_sq); a.x *= denom; a.y *= denom; } + else + { + a = VEC2(len, 0); + } return a; } Vec2 ClampVec2Len(Vec2 a, f32 min, f32 max) { f32 l_sq = a.x * a.x + a.y * a.y; - if (l_sq > max * max) + if (l_sq > 0) { - f32 denom = max / SqrtF32(l_sq); - a.x *= denom; - a.y *= denom; + if (l_sq > max * max) + { + f32 denom = max / SqrtF32(l_sq); + a.x *= denom; + a.y *= denom; + } + else if (l_sq < min * min) + { + f32 denom = min / SqrtF32(l_sq); + a.x *= denom; + a.y *= denom; + } } - else if (l_sq < min * min) + else { - f32 denom = min / SqrtF32(l_sq); - a.x *= denom; - a.y *= denom; + a = VEC2(min, 0); } return a; } @@ -1146,14 +1157,7 @@ Xform NormXform(Xform xf) Vec2 NormRot(Vec2 r) { - if (r.x == 0 && r.y == 0) - { - r.x = 1; - } - else - { - r = Vec2WithLen(r, 1); - } + r = Vec2WithLen(r, 1); return r; } diff --git a/src/base/base_string.c b/src/base/base_string.c index 81d29dc6..3b127edc 100644 --- a/src/base/base_string.c +++ b/src/base/base_string.c @@ -1034,18 +1034,16 @@ String Base64FromString(Arena *arena, String str) result.text = PushStructsNoZero(arena, u8, result.len); u64 src_byte_pos = 0; u64 out_byte_pos = 0; - while (src_byte_pos < str.len) + while (src_byte_pos < str.len && out_byte_pos < result.len) { u32 chunk = 0; - chunk |= str.text[src_byte_pos] << 16; - if (src_byte_pos + 1 < str.len) chunk |= str.text[src_byte_pos + 1] << 8; - if (src_byte_pos + 2 < str.len) chunk |= str.text[src_byte_pos + 2] << 0; - result.text[out_byte_pos + 0] = to_base64[(chunk >> 18) & 0x3F]; - result.text[out_byte_pos + 1] = to_base64[(chunk >> 12) & 0x3F]; - result.text[out_byte_pos + 2] = to_base64[(chunk >> 6) & 0x3F]; - result.text[out_byte_pos + 3] = to_base64[(chunk >> 0) & 0x3F]; - src_byte_pos += 3; - out_byte_pos += 4; + if (src_byte_pos < str.len) chunk |= (u32)str.text[src_byte_pos++] << 16; + if (src_byte_pos < str.len) chunk |= (u32)str.text[src_byte_pos++] << 8; + if (src_byte_pos < str.len) chunk |= (u32)str.text[src_byte_pos++] << 0; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = to_base64[(chunk >> 18) & 0x3F]; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = to_base64[(chunk >> 12) & 0x3F]; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = to_base64[(chunk >> 6) & 0x3F]; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = to_base64[(chunk >> 0) & 0x3F]; } return result; } @@ -1058,18 +1056,17 @@ String StringFromBase64(Arena *arena, String str) PERSIST Readonly u8 from_base64[256] = {['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['-']=62,['_']=63}; u64 src_byte_pos = 0; u64 out_byte_pos = 0; - while (src_byte_pos < str.len) + while (src_byte_pos < str.len && out_byte_pos < result.len) { u32 chunk = 0; - chunk |= (from_base64[str.text[src_byte_pos + 0]]) << 18; - chunk |= (from_base64[str.text[src_byte_pos + 1]]) << 12; - chunk |= (from_base64[str.text[src_byte_pos + 2]]) << 6; - chunk |= (from_base64[str.text[src_byte_pos + 3]]) << 0; - result.text[out_byte_pos + 0] = (chunk >> 16) & 0xFF; - result.text[out_byte_pos + 1] = (chunk >> 8) & 0xFF; - result.text[out_byte_pos + 2] = (chunk >> 0) & 0xFF; - src_byte_pos += 4; - out_byte_pos += 3; + b32 ok = 1; + if (src_byte_pos < str.len) chunk |= (u32)from_base64[str.text[src_byte_pos++]] << 18; + if (src_byte_pos < str.len) chunk |= (u32)from_base64[str.text[src_byte_pos++]] << 12; + if (src_byte_pos < str.len) chunk |= (u32)from_base64[str.text[src_byte_pos++]] << 6; + if (src_byte_pos < str.len) chunk |= (u32)from_base64[str.text[src_byte_pos++]] << 0; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = (chunk >> 16) & 0xFF; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = (chunk >> 8) & 0xFF; + if (out_byte_pos < result.len) result.text[out_byte_pos++] = (chunk >> 0) & 0xFF; } return result; } diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 785efbfe..b5941bda 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -3566,7 +3566,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane) at += 16; } break; } - dst->p = 6; + dst->p = 16; } } } diff --git a/src/meta/meta.c b/src/meta/meta.c index 6704df9b..18c40b25 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -251,7 +251,7 @@ M_EmbedObj M_Embed(String store_name, String dir_path) } //////////////////////////////////////////////////////////// -//~ M +//~ Build void M_BuildEntryPoint(WaveLaneCtx *lane) { @@ -528,6 +528,9 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-incompatible-function-pointer-types")); PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-missing-braces")); PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-value")); + PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-variable")); + PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-unused-but-set-variable")); + PushStringToList(perm, &cp.warnings_clang, Lit("-Wno-switch")); } //- Dxc diff --git a/src/pp/pp.c b/src/pp/pp.c index b53b8a97..8182887b 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -242,7 +242,7 @@ P_Shape P_WorldShapeFromEnt(P_Ent *ent) } //////////////////////////////////////////////////////////// -//~ Animation helpers +//~ Status helpers P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) { @@ -255,7 +255,15 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) i64 walk_duration_ns = frame->time_ns; result.frame_seq = walk_duration_ns / animation_rate_ns; // result.span = SPR_SpanKeyFromName(Lit("test")); - result.span = SPR_SpanKeyFromName(Lit("walk")); + + if (P_IsEntRolling(frame, ent)) + { + result.span = SPR_SpanKeyFromName(Lit("roll")); + } + else + { + result.span = SPR_SpanKeyFromName(Lit("walk")); + } } // TODO: Use prefab lookup @@ -264,8 +272,7 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) { result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("guy/guy.ase"))); } - - if (ent->is_guy_spawn) + else if (ent->is_guy_spawn) { result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/GuySpawn.ase"))); } @@ -273,9 +280,7 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) if (wep->is_uzi) { result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/uzi.ase"))); - } - - if (wep->is_launcher) + } else if (wep->is_launcher) { result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/launcher.ase"))); } @@ -283,6 +288,16 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent) return result; } +b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent) +{ + b32 result = ( + ent->last_roll_time_ns > 0 && + (frame->time_ns - ent->last_roll_time_ns) > 0 && + (frame->time_ns - ent->last_roll_time_ns) < P_RollTimeNs + ); + return result; +} + //////////////////////////////////////////////////////////// //~ Collision @@ -2223,6 +2238,7 @@ void P_StepFrame(P_Frame *frame) ZeroStruct(&guy->control); } } + for (P_Ent *player = P_FirstEnt(frame); !P_IsEntNil(player); player = P_NextEnt(player)) { if (player->is_player) @@ -2242,6 +2258,29 @@ void P_StepFrame(P_Frame *frame) } } + ////////////////////////////// + //- Roll guys + + for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy)) + { + if (guy->is_guy) + { + if (guy->control.roll_presses && !IsVec2Zero(guy->control.move)) + { + // TODO: Not like this + + i64 roll_timeout_ns = P_RollTimeoutNs; + i64 roll_time_ns = P_RollTimeNs; + + if (frame->time_ns - roll_timeout_ns + roll_time_ns > guy->last_roll_time_ns || guy->last_roll_time_ns == 0) + { + guy->last_roll_time_ns = frame->time_ns; + guy->last_roll_dir = NormRot(guy->control.move); + } + } + } + } + ////////////////////////////// //- Integrate guy control forces @@ -2265,24 +2304,43 @@ void P_StepFrame(P_Frame *frame) } } + f32 turn_rate = TweakFloat("Guy turn rate", 1, 0, 1); + f32 move_force = TweakFloat("Guy move force", 400, 0, 400); + f32 max_speed = TweakFloat("Guy max speed", 10, 0, 20); + + Vec2 look = control.look; + Vec2 move = control.move; + + // FIXME: Roll timeout + b32 is_rolling = P_IsEntRolling(frame, guy); + if (is_rolling) + { + Vec2 roll_dir = NormRot(guy->last_roll_dir); + + move = roll_dir; + look = roll_dir; + + f32 roll_factor = 1.3; + move_force *= roll_factor; + max_speed *= roll_factor; + } + // Integrate linear movement { - f32 move_force = TweakFloat("Guy move force", 400, 0, 400); - f32 max_speed = TweakFloat("Guy max speed", 10, 0, 20); Vec2 new_velocity = guy->solved_v; - new_velocity = AddVec2(new_velocity, MulVec2(control.move, move_force * sim_dt)); + new_velocity = AddVec2(new_velocity, MulVec2(move, move_force * sim_dt)); if (Vec2Len(new_velocity) > max_speed) { new_velocity = Vec2WithLen(new_velocity, max_speed); } + guy->solved_v = new_velocity; } // Integrate look { - f32 turn_rate = TweakFloat("Guy turn rate", 1, 0, 1); f32 cur_angle = AngleFromVec2(guy->xf.r); - f32 desired_angle = AngleFromVec2(control.look); + f32 desired_angle = AngleFromVec2(look); f32 diff = UnwindAngleF32(desired_angle - cur_angle); f32 look_force = 1.0 / (sim_dt * sim_dt) * turn_rate; guy->solved_w = diff * sim_dt * look_force; @@ -2290,21 +2348,6 @@ void P_StepFrame(P_Frame *frame) } } - ////////////////////////////// - //- Setup constraints store - - i32 solver_steps_count = SIM_PHYSICS_SUBSTEPS; - f32 solver_dt = sim_dt / solver_steps_count; - - // Solid params - // SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 25, 5, 200), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); - SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 100, 5, 200), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); - f32 solid_pushout_velocity = TweakFloat("Contact spring pushout", 3, 0, 50); - - // Gentle params - // f32 gentle_pushout_factor = TweakFloat("Gentle pushout factor", 10, 0, 50); - f32 gentle_pushout_factor = TweakFloat("Gentle pushout factor", 0.5, 0, 50); - ////////////////////////////// //- Bake world @@ -2324,6 +2367,21 @@ void P_StepFrame(P_Frame *frame) P_Space pre_solve_ents_space = P_SpaceFromEnts(scratch.arena, frame); + ////////////////////////////// + //- Setup constraint constants + + i32 solver_steps_count = SIM_PHYSICS_SUBSTEPS; + f32 solver_dt = sim_dt / solver_steps_count; + + // Solid params + // SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 25, 5, 200), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); + SoftSpring solid_spring = MakeSpring(TweakFloat("Contact spring hz", 100, 5, 200), TweakFloat("Contact spring damp", 10, 5, 100), solver_dt); + f32 solid_pushout_velocity = TweakFloat("Contact spring pushout", 3, 0, 50); + + // Gentle params + // f32 gentle_pushout_factor = TweakFloat("Gentle pushout factor", 10, 0, 50); + f32 gentle_pushout_factor = TweakFloat("Gentle pushout factor", 0.5, 0, 50); + ////////////////////////////// //- Generate guy constraints @@ -2842,8 +2900,8 @@ void P_StepFrame(P_Frame *frame) for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer)) { P_Ent *weapon = P_EntFromKey(frame, firer->weapon); - if (weapon->is_weapon && firer->control.fire_held) - // if (weapon->is_weapon && firer->control.fire_presses) + // if (weapon->is_weapon && firer->control.fire_held) + if (weapon->is_weapon && firer->control.fire_presses) { // i64 fire_delta_ns = frame->time_ns - firer->last_fire_ns; diff --git a/src/pp/pp.h b/src/pp/pp.h index ebd8b5bb..ee53e61c 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -80,6 +80,8 @@ Struct(P_DebugDrawNode) #define P_MinPlayerNameLen 1 #define P_MaxPlayerNameLen 24 +#define P_RollTimeNs NsFromSeconds(0.5) +#define P_RollTimeoutNs NsFromSeconds(1) Struct(P_Control) { @@ -93,6 +95,7 @@ Struct(P_Control) Vec2 look; f32 fire_held; f32 fire_presses; + f32 roll_presses; }; Struct(P_Ent) @@ -164,6 +167,8 @@ Struct(P_Ent) //- Guy P_EntKey weapon; + i64 last_roll_time_ns; + Vec2 last_roll_dir; //- Weapon @@ -613,9 +618,10 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent); P_Shape P_WorldShapeFromEnt(P_Ent *ent); //////////////////////////////////////////////////////////// -//~ Animation helpers +//~ Status helpers P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent); +b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent); //////////////////////////////////////////////////////////// //~ Collision diff --git a/src/pp/pp_res/guy/guy.ase b/src/pp/pp_res/guy/guy.ase index 3249e456..b1943b5b 100644 --- a/src/pp/pp_res/guy/guy.ase +++ b/src/pp/pp_res/guy/guy.ase @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98fc28f80634d140f4174f357ea2d51d84d6a2d4a6b7fd8a361da69bf9f1c200 -size 3551 +oid sha256:bbde9ea89b5500db6e6345cbd13dbd451f770e630c3dc7ea2569b8dc8521dae4 +size 4113 diff --git a/src/pp/pp_transcode.c b/src/pp/pp_transcode.c index 3b88c8d5..357a5223 100644 --- a/src/pp/pp_transcode.c +++ b/src/pp/pp_transcode.c @@ -21,13 +21,13 @@ String P_PackWorld(Arena *arena, P_World *src_world) result.len += PushString(arena, Lit("{\n")).len; for (P_Ent *ent = P_FirstEnt(src_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { - // TODO: Pack bullets - b32 should_pack = 1; - if (ent->is_bullet) + // TODO: Pack ignored ents + b32 ignore = 0; + if (ent->is_bullet || ent->is_weapon) { - should_pack = 0; + ignore = 1; } - if (should_pack) + if (!ignore) { result.len += StringF(arena, " 0x%F:\n", FmtHex(ent->key.v)).len; result.len += PushString(arena, Lit(" {\n")).len; @@ -67,9 +67,9 @@ String P_PackWorld(Arena *arena, P_World *src_world) result.len += StringF(arena, " angle: \"%F\"\n", FmtFloat(AngleFromVec2(ent->xf.r))).len; result.len += StringF(arena, " look: \"%F\"\n", FmtFloat2(ent->control.look)).len; result.len += StringF(arena, " exists: \"%F\"\n", FmtFloat(ent->exists)).len; - result.len += StringF(arena, " look: \"%F\"\n", FmtFloat2(ent->control.look)).len; result.len += StringF(arena, " health: \"%F\"\n", FmtFloat(ent->health)).len; result.len += StringF(arena, " guy: \"0x%F\"\n", FmtHex(ent->guy.v)).len; + result.len += StringF(arena, " weapon: \"0x%F\"\n", FmtHex(ent->weapon.v)).len; result.len += StringF(arena, " source: \"0x%F\"\n", FmtHex(ent->source.v)).len; result.len += StringF(arena, " kills: \"%F\"\n", FmtFloat(ent->kills)).len; result.len += StringF(arena, " deaths: \"%F\"\n", FmtFloat(ent->deaths)).len; @@ -202,10 +202,6 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed) { ent->exists = CR_FloatFromString(attr->value); } - if (MatchString(attr->name, Lit("look"))) - { - ent->control.look = CR_Vec2FromString(attr->value); - } if (MatchString(attr->name, Lit("health"))) { ent->health = CR_FloatFromString(attr->value); @@ -214,6 +210,10 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed) { ent->guy.v = CR_IntFromString(attr->value); } + if (MatchString(attr->name, Lit("weapon"))) + { + ent->weapon.v = CR_IntFromString(attr->value); + } if (MatchString(attr->name, Lit("source"))) { ent->source.v = CR_IntFromString(attr->value); diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 338036ba..9a792266 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -598,6 +598,8 @@ void V_TickForever(WaveLaneCtx *lane) frame->ui_debug = prev_frame->ui_debug; frame->show_console = prev_frame->show_console; frame->look = prev_frame->look; + frame->fire_presses = prev_frame->fire_presses; + frame->roll_presses = prev_frame->roll_presses; frame->edit_mode = prev_frame->edit_mode; frame->equipped_tile = prev_frame->equipped_tile; frame->equipped_prefab = prev_frame->equipped_prefab ; @@ -903,9 +905,8 @@ void V_TickForever(WaveLaneCtx *lane) if (frame->held_buttons[Button_S]) move.y += 1; } move = ClampVec2Len(move, 0, 1); - f32 fire_held = frame->held_buttons[Button_M1]; + Vec2 look = Zi; - f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1]; { f32 mouse_sensitivity = TweakFloat("Mouse sensitivity", 1.0, 0.1, 5.0); f32 mouse_scale_factor = 0.007; @@ -924,11 +925,18 @@ void V_TickForever(WaveLaneCtx *lane) look = ClampVec2Len(look, min_look_radius, max_look_radius); } + f32 fire_held = frame->held_buttons[Button_M1]; + f32 roll_held = frame->held_buttons[Button_Space]; + + f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1]; + f32 roll_presses = roll_held && !prev_frame->held_buttons[Button_Space]; + if (frame->is_looking) { frame->look = look; frame->fire_held = fire_held; - frame->fire_presses = fire_presses; + frame->fire_presses += fire_presses; + frame->roll_presses += roll_presses; } if (frame->is_moving) @@ -944,7 +952,8 @@ void V_TickForever(WaveLaneCtx *lane) frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, MulVec2(move, edit_move_speed * frame->dt)); } } - frame->look = frame->look; + + DEBUGBREAKABLE; } ////////////////////////////// @@ -1075,6 +1084,7 @@ void V_TickForever(WaveLaneCtx *lane) frame->af.screen_to_shade = AffineIdentity; { frame->af.shade_to_screen = MulAffine(frame->af.world_to_screen, frame->af.shade_to_world); + frame->af.shade_to_screen.og = RoundVec2(frame->af.shade_to_screen.og); frame->af.screen_to_shade = InvertAffine(frame->af.shade_to_screen); } @@ -1085,6 +1095,7 @@ void V_TickForever(WaveLaneCtx *lane) { frame->af.world_to_cell = ScaleAffine(frame->af.world_to_cell, VEC2(P_CellsPerMeter, P_CellsPerMeter)); frame->af.world_to_cell = TranslateAffine(frame->af.world_to_cell, VEC2((P_WorldPitch / 2.0), (P_WorldPitch / 2.0))); + frame->af.world_to_cell.og = RoundVec2(frame->af.world_to_cell.og); frame->af.cell_to_world = InvertAffine(frame->af.world_to_cell); } @@ -1095,6 +1106,7 @@ void V_TickForever(WaveLaneCtx *lane) { frame->af.world_to_tile = ScaleAffine(frame->af.world_to_tile, VEC2(P_TilesPerMeter, P_TilesPerMeter)); frame->af.world_to_tile = TranslateAffine(frame->af.world_to_tile, VEC2((P_WorldPitch / 2.0), (P_WorldPitch / 2.0))); + // frame->af.world_to_tile.og = RoundVec2(frame->af.world_to_tile.og); frame->af.tile_to_world = InvertAffine(frame->af.world_to_tile); } @@ -1394,8 +1406,11 @@ void V_TickForever(WaveLaneCtx *lane) control.move = frame->move; control.look = frame->look; control.fire_held = frame->fire_held; - // FIXME: Don't propagate fire presses over multiple sim frames control.fire_presses = frame->fire_presses; + control.roll_presses = frame->roll_presses; + + frame->fire_presses = 0; + frame->roll_presses = 0; //- Fill controls buffer backwards i64 max_fill_count = SIM_TICKS_PER_SECOND / 4; @@ -2641,7 +2656,7 @@ void V_TickForever(WaveLaneCtx *lane) // } - // // for (P_QueryResult query = P_FirstRaycast(wrold, ray_start, ray_dir); query. + // // for (P_QueryResult query = P_FirstRaycast(world, ray_start, ray_dir); query. // // P_RaycastWorldResult hits = P_RaycastWorld(local_frame, ray_start, ray_dir) // // { // // } diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 3ff31b54..17d28ba0 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -595,9 +595,9 @@ ComputeShader2D(V_CompositeCS, 8, 8) Vec2 screen_pos = SV_DispatchThreadID.xy + 0.5; Vec2 world_pos = mul(frame.af.screen_to_world, Vec3(screen_pos, 1)); - Vec2 tile_pos = mul(frame.af.world_to_tile, Vec3(world_pos, 1)); Vec2 cell_pos = mul(frame.af.world_to_cell, Vec3(world_pos, 1)); Vec2 shade_pos = mul(frame.af.screen_to_shade, Vec3(screen_pos.xy, 1)); + Vec2 tile_pos = mul(frame.af.world_to_tile, Vec3(world_pos, 1)); Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5; Vec2 world_bounds_screen_p0 = mul(frame.af.world_to_screen, Vec3(-half_world_dims.xy, 1)); @@ -663,32 +663,24 @@ ComputeShader2D(V_CompositeCS, 8, 8) { V_TileDesc tile_desc = frame.tile_descs[tile]; Texture2D tile_tex = G_Dereference(tile_desc.tex); - Vec2 tile_samp_uv = lerp(tile_desc.tex_slice_uv.p0, tile_desc.tex_slice_uv.p1, frac(world_pos)); + Vec2 samp_t = clamp(frac(world_pos), 0.00001, 1.0 - 0.00001); + Vec2 tile_samp_uv = lerp(tile_desc.tex_slice_uv.p0, tile_desc.tex_slice_uv.p1, samp_t); tile_color = tile_tex.SampleLevel(sampler, tile_samp_uv, 0); } - // Checkered grid else if (tile == P_TileKind_Empty) { + // Checkered grid i32 color_idx = 0; Vec4 colors[2] = { LinearFromSrgb(Vec4(0.30, 0.30, 0.30, 1)), LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1)) }; - const f32 checker_size = 0.5; - Vec2 world_pos_modded = fmod(abs(world_pos), Vec2(checker_size * 2, checker_size * 2)); - if (world_pos_modded.x < checker_size) + Vec2 tile_pos_mod = fmod(abs(tile_pos), Vec2(2, 2)); + if (tile_pos_mod.x < 1) { color_idx = !color_idx; } - if (world_pos_modded.y < checker_size) - { - color_idx = !color_idx; - } - if (world_pos.x < 0) - { - color_idx = !color_idx; - } - if (world_pos.y < 0) + if (tile_pos_mod.y < 1) { color_idx = !color_idx; } diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 71d88ea5..43ea0eff 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -335,6 +335,7 @@ Struct(V_SharedFrame) Vec2 look; f32 fire_held; f32 fire_presses; + f32 roll_presses; //- Gpu data