death events

This commit is contained in:
jacob 2026-04-04 10:50:31 -05:00
parent 2a3a446fdc
commit 0d2871d664
10 changed files with 348 additions and 235 deletions

View File

@ -322,9 +322,6 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
if (wep->is_uzi) if (wep->is_uzi)
{ {
result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/uzi.ase"))); result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/uzi.ase")));
} else if (wep->is_launcher)
{
result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("wep/launcher.ase")));
} }
result.frame_seq = animation_time_ns / animation_rate_ns; result.frame_seq = animation_time_ns / animation_rate_ns;
@ -335,9 +332,9 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent) b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent)
{ {
b32 result = ( b32 result = (
ent->last_roll_time_ns > 0 && ent->last_roll_ns > 0 &&
(frame->time_ns - ent->last_roll_time_ns) > 0 && (frame->time_ns - ent->last_roll_ns) > 0 &&
(frame->time_ns - ent->last_roll_time_ns) < P_RollTimeNs (frame->time_ns - ent->last_roll_ns) < P_RollTimeNs
); );
return result; return result;
} }
@ -2481,16 +2478,16 @@ void P_StepFrame(P_Frame *frame)
if (guy->is_guy) if (guy->is_guy)
{ {
// if (guy->control.roll_presses && !IsVec2Zero(guy->control.move)) // if (guy->control.roll_presses && !IsVec2Zero(guy->control.move))
if (guy->control.roll_presses) if (guy->control.downs[P_Button_Roll])
{ {
// TODO: Not like this // TODO: Not like this
i64 roll_timeout_ns = P_RollTimeoutNs; i64 roll_timeout_ns = P_RollTimeoutNs;
i64 roll_time_ns = P_RollTimeNs; 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) if (frame->time_ns - roll_timeout_ns - roll_time_ns > guy->last_roll_ns || guy->last_roll_ns == 0)
{ {
guy->last_roll_time_ns = frame->time_ns; guy->last_roll_ns = frame->time_ns;
// guy->last_roll_dir = NormVec2(guy->control.move); // guy->last_roll_dir = NormVec2(guy->control.move);
guy->last_roll_dir = NormVec2(guy->control.look); guy->last_roll_dir = NormVec2(guy->control.look);
} }
@ -2552,7 +2549,7 @@ void P_StepFrame(P_Frame *frame)
move_force *= roll_factor; move_force *= roll_factor;
max_speed *= roll_factor; max_speed *= roll_factor;
// if ((frame->time_ns - guy->last_roll_time_ns) > P_RollTurnTimeNs) // if ((frame->time_ns - guy->last_roll_ns) > P_RollTurnTimeNs)
{ {
turn_rate = 0.1; turn_rate = 0.1;
} }
@ -3133,15 +3130,38 @@ void P_StepFrame(P_Frame *frame)
for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer)) for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer))
{ {
P_Ent *weapon = P_EntFromKey(frame, firer->weapon); P_Ent *weapon = P_EntFromKey(frame, firer->weapon);
if (weapon->is_weapon && (firer->control.fire_held || firer->control.fire_presses)) if (weapon->is_weapon)
// if (weapon->is_weapon && firer->control.fire_presses)
{ {
f32 fire_rate = 50; for (P_Button button = 0; button < P_Button_COUNT; ++button)
{
f32 fire_rate = 1; // In bullets per second
f32 bullets_per_fire = 1; f32 bullets_per_fire = 1;
b32 firing = 0;
b32 can_fire = (weapon->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns; b32 is_bomb = 0;
if (button == P_Button_PrimaryFire && (firer->control.held[button] || firer->control.downs[button]))
if (can_fire) {
// fire_rate = 100;
// bullets_per_fire = 4;
fire_rate = 10;
bullets_per_fire = 1;
firing = (weapon->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns;
if (firing)
{
weapon->last_fire_ns = frame->time_ns;
}
}
if (button == P_Button_AltFire && (firer->control.held[button] || firer->control.downs[button]))
{
fire_rate = 10;
bullets_per_fire = 4;
firing = (weapon->last_alt_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns;
is_bomb = 1;
if (firing)
{
weapon->last_alt_fire_ns = frame->time_ns;
}
}
if (firing)
{ {
i64 tick_bullets_count = bullets_per_fire; i64 tick_bullets_count = bullets_per_fire;
if (tick_bullets_count > 0) if (tick_bullets_count > 0)
@ -3151,22 +3171,16 @@ void P_StepFrame(P_Frame *frame)
P_Ent *bullet = P_PushTempEnt(scratch.arena, &bullets_to_spawn); P_Ent *bullet = P_PushTempEnt(scratch.arena, &bullets_to_spawn);
bullet->is_bullet = 1; bullet->is_bullet = 1;
// TDOO: More specific key with seed that only increments on player control (for less misprediction) // TDOO: More specific key with seed that only increments on player control (for less chance of misprediction)
bullet->key = P_EntKeyFromU64(P_RandU64FromEnt(firer)); bullet->key = P_EntKeyFromU64(P_RandU64FromEnt(firer));
bullet->is_bomb = is_bomb;
if (weapon->is_launcher)
{
bullet->is_bomb = 1;
}
bullet->source = weapon->key; bullet->source = weapon->key;
bullet->damage_attribution = firer->source; bullet->damage_attribution = firer->source;
bullet->sim = weapon->sim; bullet->sim = weapon->sim;
} }
} }
weapon->last_fire_ns = frame->time_ns; }
} }
} }
} }
@ -3202,25 +3216,26 @@ void P_StepFrame(P_Frame *frame)
////////////////////////////// //////////////////////////////
//- Bullet properties //- Bullet properties
f32 spread = Tau * 0.05; // f32 spread = Tau * 0.05;
// f32 spread = Tau * 0.2;
// f32 spread = Tau * 0.01; // f32 spread = Tau * 0.01;
// f32 spread = 0; f32 spread = 0;
b32 should_ricochet = 0; b32 should_ricochet = 0;
f32 initial_speed = 1; f32 initial_speed = 1;
f32 speed_falloff = 0; f32 speed_falloff = 0;
if (weapon->is_uzi) if (bullet->is_bomb)
{
initial_speed = TweakFloat("Bullet speed", 75, 1, 100);
}
else if (weapon->is_launcher)
{ {
should_ricochet = 1; should_ricochet = 1;
initial_speed = 50; initial_speed = 50;
// initial_speed = 100; // initial_speed = 100;
speed_falloff = 5; speed_falloff = 5;
} }
else
{
initial_speed = TweakFloat("Bullet speed", 75, 1, 100);
}
////////////////////////////// //////////////////////////////
//- Initialize //- Initialize
@ -3490,7 +3505,7 @@ void P_StepFrame(P_Frame *frame)
{ {
victim->damage_attribution = damager->key; victim->damage_attribution = damager->key;
} }
// victim->health -= 0.25; victim->health -= 0.25;
} }
// Prune out of bounds bullet // Prune out of bounds bullet
@ -3696,17 +3711,19 @@ void P_StepFrame(P_Frame *frame)
////////////////////////////// //////////////////////////////
//- Kill guys //- Kill guys
{
P_EntList ents_to_spawn = Zi;
for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy)) for (P_Ent *guy = P_FirstEnt(frame); !P_IsEntNil(guy); guy = P_NextEnt(guy))
{ {
if (guy->is_guy) if (guy->is_guy && guy->health <= 0)
{
if (guy->health <= 0)
{ {
P_Ent *old_guy = P_EntFromKey(prev_frame, guy->key); P_Ent *old_guy = P_EntFromKey(prev_frame, guy->key);
if (old_guy->health > 0) if (old_guy->health > 0)
{ {
P_Ent *player = P_EntFromKey(frame, guy->source); P_Ent *player = P_EntFromKey(frame, guy->source);
P_Ent *killer = P_EntFromKey(frame, guy->damage_attribution); P_Ent *killer = P_EntFromKey(frame, guy->damage_attribution);
// Update kill info
{
if (player->is_player) if (player->is_player)
{ {
player->deaths += 1; player->deaths += 1;
@ -3717,10 +3734,23 @@ void P_StepFrame(P_Frame *frame)
} }
guy->exists = 0; guy->exists = 0;
guy->continuity_gen += 1; guy->continuity_gen += 1;
guy->health = 1;
}
// Push kill event
{
P_Ent *death = P_PushTempEnt(scratch.arena, &ents_to_spawn);
death->key = P_EntKeyFromU64(MixU64s(guy->key.v, P_DeathBasis + (u64)player->deaths));
death->death_pos = guy->xf.t;
death->is_death = 1;
death->death_player = player->key;
death->death_killer = killer->key;
death->lifetime_seconds = P_ObservationDurationSeconds;
} }
} }
} }
} }
P_SpawnEntsFromList(frame, ents_to_spawn);
}
////////////////////////////// //////////////////////////////
//- Debug draw //- Debug draw

View File

@ -10,6 +10,7 @@
#define P_BulletSpreadBasis 0xc3b72fe38ca5a1d6ull #define P_BulletSpreadBasis 0xc3b72fe38ca5a1d6ull
#define P_BulletHitBasis 0xbc70fc783c1c507full #define P_BulletHitBasis 0xbc70fc783c1c507full
#define P_BulletTrailBasis 0x27c011f891c571feull #define P_BulletTrailBasis 0x27c011f891c571feull
#define P_DeathBasis 0x2e3c75a3286d872aull
Struct(P_EntKey) Struct(P_EntKey)
{ {
@ -88,6 +89,15 @@ Struct(P_DebugDrawNode)
#define P_RollTimeoutNs NsFromSeconds(0.5) #define P_RollTimeoutNs NsFromSeconds(0.5)
#define P_ObservationDurationSeconds 1 #define P_ObservationDurationSeconds 1
Enum(P_Button)
{
P_Button_PrimaryFire,
P_Button_AltFire,
P_Button_Roll,
P_Button_COUNT
};
Struct(P_Control) Struct(P_Control)
{ {
i64 tick; i64 tick;
@ -98,9 +108,8 @@ Struct(P_Control)
Vec2 move; Vec2 move;
Vec2 look; Vec2 look;
f32 fire_held; f32 held[P_Button_COUNT];
f32 fire_presses; f32 downs[P_Button_COUNT];
f32 roll_presses;
}; };
Struct(P_Ent) Struct(P_Ent)
@ -159,6 +168,11 @@ Struct(P_Ent)
Vec2 hit_entry_velocity; Vec2 hit_entry_velocity;
P_MaterialKind hit_material; P_MaterialKind hit_material;
b32 is_death;
Vec2 death_pos;
P_EntKey death_player;
P_EntKey death_killer;
//- Bomb //- Bomb
b32 is_bomb; b32 is_bomb;
@ -189,8 +203,9 @@ Struct(P_Ent)
P_EntKey guy; P_EntKey guy;
f32 ping; f32 ping;
f32 kills;
f32 deaths; u64 kills;
u64 deaths;
u8 string_len; u8 string_len;
u8 string_text[P_MaxPlayerNameLen + 8]; u8 string_text[P_MaxPlayerNameLen + 8];
@ -198,18 +213,19 @@ Struct(P_Ent)
//- Guy //- Guy
P_EntKey weapon; P_EntKey weapon;
i64 last_roll_time_ns;
Vec2 last_roll_dir; Vec2 last_roll_dir;
i64 walk_time_accum_ns; i64 walk_time_accum_ns;
i64 last_fire_ns;
i64 last_alt_fire_ns;
i64 last_roll_ns;
//- Weapon //- Weapon
b32 is_weapon; b32 is_weapon;
b32 is_uzi; b32 is_uzi;
b32 is_launcher; b32 is_launcher;
i64 last_fire_ns;
//- Spawner //- Spawner
b32 is_guy_spawn; b32 is_guy_spawn;

BIN
src/pp/pp_res/wep/launcher.ase (Stored with Git LFS)

Binary file not shown.

View File

@ -425,7 +425,7 @@ void S_TickForever(WaveLaneCtx *lane)
//- Apply bot controls //- Apply bot controls
{ {
f32 move_bias = TweakFloat("Bot movement bias", 1, -1, 1); f32 move_bias = TweakFloat("Bot movement bias", 0, -1, 1);
f32 move_frequency = TweakFloat("Bot movement frequency", 0, 0, 10); f32 move_frequency = TweakFloat("Bot movement frequency", 0, 0, 10);
f32 turn_frequency = TweakFloat("Bot turn frequency", 0, 0, 10); f32 turn_frequency = TweakFloat("Bot turn frequency", 0, 0, 10);
// b32 bot_movement_enabled = TweakBool("Bot movement enabled", 1); // b32 bot_movement_enabled = TweakBool("Bot movement enabled", 1);

View File

@ -958,8 +958,6 @@ void V_TickForever(WaveLaneCtx *lane)
frame->is_editing = prev_frame->is_editing; frame->is_editing = prev_frame->is_editing;
frame->ui_debug = prev_frame->ui_debug; frame->ui_debug = prev_frame->ui_debug;
frame->look = prev_frame->look; frame->look = prev_frame->look;
frame->fire_presses = prev_frame->fire_presses;
frame->roll_presses = prev_frame->roll_presses;
frame->show_consoles = prev_frame->show_consoles; frame->show_consoles = prev_frame->show_consoles;
frame->show_profilers = prev_frame->show_profilers; frame->show_profilers = prev_frame->show_profilers;
frame->edit_mode = prev_frame->edit_mode; frame->edit_mode = prev_frame->edit_mode;
@ -1443,18 +1441,20 @@ void V_TickForever(WaveLaneCtx *lane)
look = ClampVec2Len(look, min_look_radius, max_look_radius); 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) if (frame->is_looking)
{ {
frame->look = look; frame->look = look;
frame->fire_held = fire_held;
frame->fire_presses += fire_presses; // Update game control
frame->roll_presses += roll_presses; {
P_Control *control = &V.queued_pp_control;
control->held[P_Button_PrimaryFire] = frame->held_buttons[Button_M1];
control->held[P_Button_AltFire] = frame->held_buttons[Button_M2];
control->held[P_Button_Roll] = frame->held_buttons[Button_Space];
control->downs[P_Button_PrimaryFire] += frame->held_buttons[Button_M1] && !prev_frame->held_buttons[Button_M1];
control->downs[P_Button_AltFire] += frame->held_buttons[Button_M2] && !prev_frame->held_buttons[Button_M2];
control->downs[P_Button_Roll] += frame->held_buttons[Button_Space] && !prev_frame->held_buttons[Button_Space];
}
} }
if (frame->is_moving) if (frame->is_moving)
@ -1462,15 +1462,12 @@ void V_TickForever(WaveLaneCtx *lane)
frame->move = move; frame->move = move;
} }
if (!frame->is_looking) if (!frame->is_looking && !frame->is_panning)
{
if (!frame->is_panning)
{ {
f32 edit_move_speed = 20.0 * MaxF32(frame->edit_camera_zoom, min_zoom); f32 edit_move_speed = 20.0 * MaxF32(frame->edit_camera_zoom, min_zoom);
frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, MulVec2(move, edit_move_speed * frame->dt)); frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, MulVec2(move, edit_move_speed * frame->dt));
} }
} }
}
////////////////////////////// //////////////////////////////
//- Compute camera position & zoom //- Compute camera position & zoom
@ -1995,17 +1992,14 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
i64 control_tick = predict_to; i64 control_tick = predict_to;
P_Control control = Zi; P_Control control = V.queued_pp_control;
{
control.tick = control_tick; control.tick = control_tick;
control.orig_tick = control_tick; control.orig_tick = control_tick;
control.move = frame->move; control.move = frame->move;
control.look = frame->look; control.look = frame->look;
control.fire_held = frame->fire_held; ZeroStruct(&V.queued_pp_control);
control.fire_presses = frame->fire_presses; }
control.roll_presses = frame->roll_presses;
frame->fire_presses = 0;
frame->roll_presses = 0;
//- Fill controls buffer backwards //- Fill controls buffer backwards
i64 max_fill_count = SIM_TICKS_PER_SECOND / 4; i64 max_fill_count = SIM_TICKS_PER_SECOND / 4;
@ -2936,7 +2930,7 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
Affine wep_uv_to_world_af = ScaleAffine(wep_pix_to_world_af, DimsFromRng2(wep.tex_rect)); Affine wep_uv_to_world_af = ScaleAffine(wep_pix_to_world_af, DimsFromRng2(wep.tex_rect));
V_Quad *quad = PushStruct(frame->quads_arena, V_Quad); V_GpuQuad *quad = PushStruct(frame->quads_arena, V_GpuQuad);
quad->quad_uv_to_world_af = wep_uv_to_world_af; quad->quad_uv_to_world_af = wep_uv_to_world_af;
quad->tex = wep.tex; quad->tex = wep.tex;
quad->tex_slice_uv = DivRng2Vec2(wep.tex_rect, wep.tex_dims); quad->tex_slice_uv = DivRng2Vec2(wep.tex_rect, wep.tex_dims);
@ -2946,7 +2940,7 @@ void V_TickForever(WaveLaneCtx *lane)
if (body.ready) if (body.ready)
{ {
//- Legs quad //- Legs quad
V_Quad legs_quad = Zi; V_GpuQuad legs_quad = Zi;
{ {
Affine legs_uv_to_world_af = ScaleAffine(legs_pix_to_world_af, DimsFromRng2(legs.tex_rect)); Affine legs_uv_to_world_af = ScaleAffine(legs_pix_to_world_af, DimsFromRng2(legs.tex_rect));
legs_quad.quad_uv_to_world_af = legs_uv_to_world_af; legs_quad.quad_uv_to_world_af = legs_uv_to_world_af;
@ -2955,7 +2949,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
//- Body quad //- Body quad
V_Quad body_quad = Zi; V_GpuQuad body_quad = Zi;
{ {
Affine body_uv_to_world_af = ScaleAffine(body_pix_to_world_af, DimsFromRng2(body.tex_rect)); Affine body_uv_to_world_af = ScaleAffine(body_pix_to_world_af, DimsFromRng2(body.tex_rect));
body_quad.quad_uv_to_world_af = body_uv_to_world_af; body_quad.quad_uv_to_world_af = body_uv_to_world_af;
@ -2968,7 +2962,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
//- Weapon quad //- Weapon quad
V_Quad wep_quad = Zi; V_GpuQuad wep_quad = Zi;
{ {
Affine wep_uv_to_world_af = ScaleAffine(wep_pix_to_world_af, DimsFromRng2(wep.tex_rect)); Affine wep_uv_to_world_af = ScaleAffine(wep_pix_to_world_af, DimsFromRng2(wep.tex_rect));
wep_quad.quad_uv_to_world_af = wep_uv_to_world_af; wep_quad.quad_uv_to_world_af = wep_uv_to_world_af;
@ -2982,21 +2976,21 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
if (anim.weapon_over) if (anim.weapon_over)
{ {
*PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = legs_quad;
*PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = body_quad;
*PushStructNoZero(frame->quads_arena, V_Quad) = wep_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = wep_quad;
} }
else else
{ {
*PushStructNoZero(frame->quads_arena, V_Quad) = wep_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = wep_quad;
*PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = legs_quad;
*PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = body_quad;
} }
} }
else else
{ {
*PushStructNoZero(frame->quads_arena, V_Quad) = legs_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = legs_quad;
*PushStructNoZero(frame->quads_arena, V_Quad) = body_quad; *PushStructNoZero(frame->quads_arena, V_GpuQuad) = body_quad;
} }
} }
} }
@ -3012,7 +3006,7 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Process event entities //- Process world events
for (P_Ent *event = P_FirstEnt(local_frame); !P_IsEntNil(event); event = P_NextEnt(event)) for (P_Ent *event = P_FirstEnt(local_frame); !P_IsEntNil(event); event = P_NextEnt(event))
{ {
@ -3142,8 +3136,11 @@ void V_TickForever(WaveLaneCtx *lane)
// } // }
// Bullet fired
if (event->is_first_trail) if (event->is_first_trail)
{ {
// frame->camera_shake += 0.5;
//- Bullet particle //- Bullet particle
{ {
V_Emitter emitter = Zi; V_Emitter emitter = Zi;
@ -3182,7 +3179,7 @@ void V_TickForever(WaveLaneCtx *lane)
emitter.kind = V_ParticleKind_MuzzleWide; emitter.kind = V_ParticleKind_MuzzleWide;
// emitter.count = MaxF32(1000 * frame->dt, 1); // emitter.count = MaxF32(1000 * frame->dt, 1);
// emitter.count = 128; // emitter.count = 128;
emitter.count = 8; emitter.count = 2;
f32 angle = AngleFromVec2(SubVec2(p1, p0)); f32 angle = AngleFromVec2(SubVec2(p1, p0));
@ -3398,9 +3395,14 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
P_MaterialKind material = event->hit_material; P_MaterialKind material = event->hit_material;
Vec2 hit_entry = event->hit_entry; Vec2 impact_pos = event->hit_entry;
Vec2 hit_entry_normal = event->hit_entry_normal; Vec2 impact_velocity = event->hit_entry_velocity;
Vec2 hit_entry_velocity = event->hit_entry_velocity;
f32 impact_dir_velocity_weight = 0;
Vec2 impact_dir = SlerpVec2(event->hit_entry_normal, NegVec2(impact_velocity), impact_dir_velocity_weight);
f32 impact_offset_angle = rand_angle * (Tau * 0);
impact_dir = RotateVec2Angle(impact_dir, impact_offset_angle);
//- Wall impact particles //- Wall impact particles
if (material != P_MaterialKind_Flesh) if (material != P_MaterialKind_Flesh)
@ -3425,7 +3427,7 @@ void V_TickForever(WaveLaneCtx *lane)
// // emitter.velocity_falloff = 5; // // emitter.velocity_falloff = 5;
// // emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5; // // emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5;
// Vec2 dir = hit_entry_normal; // Vec2 dir = impact_dir;
// f32 angle = AngleFromVec2(dir); // f32 angle = AngleFromVec2(dir);
// f32 angle_spread = Tau * 0.5; // f32 angle_spread = Tau * 0.5;
@ -3441,52 +3443,51 @@ void V_TickForever(WaveLaneCtx *lane)
// V_PushParticles(emitter); // V_PushParticles(emitter);
// } // }
// Fire // Hot debris
// { {
// V_Emitter emitter = Zi; V_Emitter emitter = Zi;
// emitter.kind = V_ParticleKind_Fire; emitter.kind = V_ParticleKind_HotDebris;
// // emitter.count = MaxF32(1000 * frame->dt, 1); // emitter.count = MaxF32(1000 * frame->dt, 1);
// emitter.count = 2; emitter.count = 32;
// // f32 angle = AngleFromVec2(SubVec2(p1, p0)); // f32 angle = AngleFromVec2(SubVec2(p1, p0));
// f32 angle = AngleFromVec2(hit_entry_normal); f32 angle = AngleFromVec2(impact_dir);
// angle += rand_angle * (Tau * 0.05);
// f32 angle_particle_spread = Tau / 4; f32 angle_particle_spread = Tau / 2.5;
// emitter.angle.min = angle - angle_particle_spread / 2; emitter.angle.min = angle - angle_particle_spread / 2;
// emitter.angle.max = angle + angle_particle_spread / 2; emitter.angle.max = angle + angle_particle_spread / 2;
emitter.pos.p0 =
emitter.pos.p1 = impact_pos;
// emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1));
// emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
emitter.speed.min = 0;
emitter.speed.max = 30;
// emitter.angle.min = angle - angle_spread / 2;
// emitter.angle.max = angle + angle_spread / 2;
// emitter.angle.min =
// emitter.angle.max = angle;
// emitter.pos.p0 = // emitter.pos.p0 =
// emitter.pos.p1 = hit_entry; // emitter.pos.p1 = p0;
// // emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1)); // emitter.speed.min =
// emitter.speed.max =
// // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1)); // emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1));
// emitter.speed.min = 0; // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
// emitter.speed.max = 25; // emitter.speed.min =
// emitter.speed.max = Vec2Len(SubVec2(p1, p0)) / frame->dt;
// // emitter.angle.min = angle - angle_spread / 2; V_PushParticles(emitter);
// // emitter.angle.max = angle + angle_spread / 2; }
// // emitter.angle.min =
// // emitter.angle.max = angle;
// // emitter.pos.p0 =
// // emitter.pos.p1 = p0;
// // emitter.speed.min =
// // emitter.speed.max =
// // emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1));
// // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
// // emitter.speed.min =
// // emitter.speed.max = Vec2Len(SubVec2(p1, p0)) / frame->dt;
// V_PushParticles(emitter);
// }
@ -3494,32 +3495,32 @@ void V_TickForever(WaveLaneCtx *lane)
// Wall dust // Wall dust
// { {
// V_Emitter emitter = Zi; V_Emitter emitter = Zi;
// { {
// emitter.kind = V_ParticleKind_Smoke; emitter.kind = V_ParticleKind_WallDust;
// emitter.count = 128; emitter.count = 128;
// emitter.pos.p0 = emitter.pos.p1 = hit_entry; emitter.pos.p0 = emitter.pos.p1 = impact_pos;
// // emitter.color_lin = LinearFromSrgb(VEC4(0.5, 0.5, 0.5, 0.75)); // emitter.color_lin = LinearFromSrgb(VEC4(0.5, 0.5, 0.5, 0.75));
// emitter.speed.min = 10; emitter.speed.min = 1;
// emitter.speed.max = 20; emitter.speed.max = 20;
// // emitter.velocity_falloff = 12; // emitter.velocity_falloff = 12;
// // emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5; // emitter.velocity_falloff_spread = emitter.velocity_falloff_spread * 1.5;
// Vec2 dir = hit_entry_normal; Vec2 dir = impact_dir;
// f32 angle = AngleFromVec2(dir); f32 angle = AngleFromVec2(dir);
// f32 angle_spread = Tau * 0.1; f32 angle_spread = Tau * 0.1;
// emitter.angle.min = angle - angle_spread / 2; emitter.angle.min = angle - angle_spread / 2;
// emitter.angle.max = angle + angle_spread / 2; emitter.angle.max = angle + angle_spread / 2;
// } }
// V_PushParticles(emitter); V_PushParticles(emitter);
// } }
} }
//- Flesh impact particles //- Flesh impact particles
@ -3530,7 +3531,7 @@ void V_TickForever(WaveLaneCtx *lane)
emitter.kind = V_ParticleKind_BloodTrail; emitter.kind = V_ParticleKind_BloodTrail;
// emitter.kind = V_ParticleKind_BloodDebris; // emitter.kind = V_ParticleKind_BloodDebris;
Vec2 dir = NormVec2(NegVec2(hit_entry_velocity)); Vec2 dir = NormVec2(NegVec2(impact_velocity));
f32 angle = AngleFromVec2(dir); f32 angle = AngleFromVec2(dir);
// f32 angle = 0; // f32 angle = 0;
@ -3545,7 +3546,7 @@ void V_TickForever(WaveLaneCtx *lane)
// f32 speed = 100; // f32 speed = 100;
f32 speed_spread = speed * 2; f32 speed_spread = speed * 2;
emitter.pos.p0 = emitter.pos.p1 = hit_entry; emitter.pos.p0 = emitter.pos.p1 = impact_pos;
emitter.speed.min = speed - speed_spread * 0.5; emitter.speed.min = speed - speed_spread * 0.5;
emitter.speed.max = speed + speed_spread * 0.5; emitter.speed.max = speed + speed_spread * 0.5;
emitter.angle.min = angle - angle_spread * 0.5; emitter.angle.min = angle - angle_spread * 0.5;
@ -3557,6 +3558,49 @@ void V_TickForever(WaveLaneCtx *lane)
// V_DrawPoint(victim_raycast.p, Color_Green); // V_DrawPoint(victim_raycast.p, Color_Green);
// V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White); // V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White);
} }
//////////////////////////////
//- Death
if (event->is_death)
{
Vec2 death_pos = event->death_pos;
//- Death particles
{
V_Emitter emitter = Zi;
emitter.kind = V_ParticleKind_BloodTrail;
// emitter.kind = V_ParticleKind_BloodDebris;
// f32 angle = AngleFromVec2(frame->look);
f32 angle = 0;
// f32 angle_spread = Tau * 0.25;
f32 angle_spread = Tau;
// f32 angle_spread = 0;
// f32 speed = 5;
// f32 speed = 25;
f32 speed = 50;
// f32 speed = 100;
f32 speed_spread = speed * 2;
emitter.pos.p0 = emitter.pos.p1 = death_pos;
emitter.speed.min = speed - speed_spread * 0.5;
emitter.speed.max = speed + speed_spread * 0.5;
emitter.angle.min = angle - angle_spread * 0.5;
emitter.angle.max = angle + angle_spread * 0.5;
// emitter.count = Kibi(32) * frame->dt;
// emitter.count = Kibi(1);
emitter.count = Kibi(4);
V_PushParticles(emitter);
}
}
} }
} }
@ -5486,20 +5530,6 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
// //- Test profiler panel
// {
// V_Panel *parent = right_bottom_panel;
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->axis = Axis_X;
// DllQueuePush(panel->parent->first, panel->parent->last, panel);
// panel->box = UI_KeyF("test raah profiler panel");
// panel->contents_box = UI_KeyF("panel contents box %F", FmtUint(panel->box.v));
// panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
// panel->flags |= V_PanelFlag_Profiler;
// panel->flags |= V_PanelFlag_Ignore;
// panel->pct = 2;
// }
//- Test spawn panel //- Test spawn panel
{ {
V_Panel *panel = PushStruct(perm, V_Panel); V_Panel *panel = PushStruct(perm, V_Panel);
@ -5539,6 +5569,20 @@ void V_TickForever(WaveLaneCtx *lane)
panel->flags |= V_PanelFlag_Screen; panel->flags |= V_PanelFlag_Screen;
panel->pct = 1; panel->pct = 1;
} }
// //- Test profiler panel
// {
// V_Panel *panel = PushStruct(perm, V_Panel);
// panel->parent = right_panel;
// panel->axis = Axis_X;
// DllQueuePush(panel->parent->first, panel->parent->last, panel);
// panel->box = UI_RandKey();
// panel->contents_box = UI_KeyF("panel contents box %F", FmtUint(panel->box.v));
// panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
// panel->flags |= V_PanelFlag_Profiler;
// panel->flags |= V_PanelFlag_Ignore;
// panel->pct = 2;
// }
} }
@ -8005,10 +8049,10 @@ void V_TickForever(WaveLaneCtx *lane)
Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y)); Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y));
// Quad buffers // Quad buffers
frame->quads_count = ArenaCount(frame->quads_arena, V_Quad); frame->quads_count = ArenaCount(frame->quads_arena, V_GpuQuad);
frame->quads = G_PushStructsFromCpu( frame->quads = G_PushStructsFromCpu(
cl, gpu_frame_arena, cl, gpu_frame_arena,
ArenaFirst(frame->quads_arena, V_Quad), frame->quads_count, ArenaFirst(frame->quads_arena, V_GpuQuad), frame->quads_count,
.name = StringF(frame->arena, "quads [%F]", FmtSint(frame->tick)) .name = StringF(frame->arena, "quads [%F]", FmtSint(frame->tick))
); );
@ -8085,6 +8129,7 @@ void V_TickForever(WaveLaneCtx *lane)
// Clear particles // Clear particles
if (frame->should_clear_particles) if (frame->should_clear_particles)
{ {
LogDebugF("Clearing particles");
G_Compute(cl, V_ClearParticlesCS, V_ParticlesCap); G_Compute(cl, V_ClearParticlesCS, V_ParticlesCap);
V.particle_seq = 0; V.particle_seq = 0;
} }

View File

@ -418,8 +418,8 @@ Struct(V_Frame)
f64 blend_sim_tick; f64 blend_sim_tick;
f64 blend_predict_tick; f64 blend_predict_tick;
Button held_buttons[Button_COUNT]; // User input state captured for gameplay b32 held_buttons[Button_COUNT]; // User input state captured for gameplay
Button real_held_buttons[Button_COUNT]; // Actual state of user input regardless of keyboard / mouse focus b32 real_held_buttons[Button_COUNT]; // Actual state of user input regardless of keyboard / mouse focus
V_Palette palette; V_Palette palette;
UI_Key text_input_focus; UI_Key text_input_focus;
@ -460,6 +460,8 @@ Struct(V_Ctx)
V_CmdNode *last_queued_cmd_node; V_CmdNode *last_queued_cmd_node;
V_CmdNode *first_free_cmd_node; V_CmdNode *first_free_cmd_node;
P_Control queued_pp_control;

View File

@ -17,6 +17,14 @@ f32 V_LifetimeFromParticleDesc(V_ParticleDesc desc, u32 particle_idx)
return result; return result;
} }
f32 V_FalloffFromParticleDesc(V_ParticleDesc desc, u32 particle_idx)
{
u64 seed = MixU64(V_ParticleFalloffBasis ^ particle_idx);
f32 rand_falloff = Norm16(seed >> 16);
f32 result = lerp(desc.falloff_min, desc.falloff_max, rand_falloff);
return result;
}
Vec4 V_ColorFromParticleDesc(V_ParticleDesc desc, u32 particle_idx, f32 alive_seconds, u32 density) Vec4 V_ColorFromParticleDesc(V_ParticleDesc desc, u32 particle_idx, f32 alive_seconds, u32 density)
{ {
Vec4 result = 0; Vec4 result = 0;
@ -36,7 +44,7 @@ Vec4 V_ColorFromParticleDesc(V_ParticleDesc desc, u32 particle_idx, f32 alive_se
result.a += (1.0 - result.a) * (t); result.a += (1.0 - result.a) * (t);
} }
else if (desc.kind == V_ParticleKind_BloodTrail || desc.kind == V_ParticleKind_BloodDebris) else if (desc.kind == V_ParticleKind_BloodTrail)
{ {
// f32 t = (f32)density / 5; // f32 t = (f32)density / 5;
// t = pow(t, 2); // t = pow(t, 2);
@ -209,7 +217,8 @@ ComputeShader(V_PrepareCellsCS)
} }
else else
{ {
f32 dry_rate = saturate(frame.dt * 0.1); // f32 dry_rate = saturate(frame.dt * 0.1);
f32 dry_rate = saturate(frame.dt * 0.2);
Vec4 before_stain = stains[cell_pos]; Vec4 before_stain = stains[cell_pos];
Vec4 before_dry_stain = dry_stains[cell_pos]; Vec4 before_dry_stain = dry_stains[cell_pos];
@ -360,9 +369,9 @@ ComputeShader(V_BackdropUpCS)
VertexShader(V_QuadVS, V_QuadPSInput) VertexShader(V_QuadVS, V_QuadPSInput)
{ {
V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0]; V_SharedFrame frame = G_Deref(V_GpuReg_Frame, StructuredBuffer<V_SharedFrame>)[0];
StructuredBuffer<V_Quad> quads = G_Deref(frame.quads, StructuredBuffer<V_Quad>); StructuredBuffer<V_GpuQuad> quads = G_Deref(frame.quads, StructuredBuffer<V_GpuQuad>);
V_Quad quad = quads[SV_InstanceID]; V_GpuQuad quad = quads[SV_InstanceID];
Vec2 rect_uv = RectUvFromIdx(SV_VertexID); Vec2 rect_uv = RectUvFromIdx(SV_VertexID);
Vec2 world_pos = mul(quad.quad_uv_to_world_af, Vec3(rect_uv, 1)); Vec2 world_pos = mul(quad.quad_uv_to_world_af, Vec3(rect_uv, 1));
@ -387,7 +396,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState); SamplerState sampler = G_Deref(frame.basic_samplers[G_BasicSamplerKind_PointClamp], SamplerState);
RWTexture2D<u32> occluders = G_Deref(frame.occluders, RWTexture2D<u32>); RWTexture2D<u32> occluders = G_Deref(frame.occluders, RWTexture2D<u32>);
V_Quad quad = input.quad; V_GpuQuad quad = input.quad;
Texture2D<Vec4> tex = G_Deref(quad.tex, Texture2D<Vec4>); Texture2D<Vec4> tex = G_Deref(quad.tex, Texture2D<Vec4>);
Vec2 world_pos = input.world_pos; Vec2 world_pos = input.world_pos;
@ -465,7 +474,6 @@ ComputeShader(V_SimParticlesCS)
f32 rand_offset = Norm16(seed0 >> 0); f32 rand_offset = Norm16(seed0 >> 0);
f32 rand_angle = Norm16(seed0 >> 16); f32 rand_angle = Norm16(seed0 >> 16);
f32 rand_speed = Norm16(seed0 >> 32); f32 rand_speed = Norm16(seed0 >> 32);
f32 rand_falloff = Norm16(seed0 >> 48);
////////////////////////////// //////////////////////////////
//- Init particle //- Init particle
@ -711,9 +719,13 @@ ComputeShader(V_SimParticlesCS)
} }
} }
f32 rand_falloff = Norm16(seed0 >> 48);
// f32 falloff = saturate(lerp(1, 2, rand_falloff) * frame.dt); // f32 falloff = saturate(lerp(1, 2, rand_falloff) * frame.dt);
// f32 falloff = saturate(lerp(10, 20, rand_falloff) * frame.dt); // f32 falloff = saturate(lerp(10, 20, rand_falloff * frame.dt));
f32 falloff = 0; // f32 falloff = saturate(lerp(5, 10, rand_falloff * frame.dt));
// f32 falloff = 20 * frame.dt;
f32 falloff = V_FalloffFromParticleDesc(desc, particle_idx) * frame.dt;
particle.velocity *= 1.0f - falloff; particle.velocity *= 1.0f - falloff;
particle.pos = p0 + (p1 - p0) * t; particle.pos = p0 + (p1 - p0) * t;
@ -1291,13 +1303,8 @@ ComputeShader(V_BloomDownCS)
f32 knee_weight = 1; f32 knee_weight = 1;
if (is_first_pass) if (is_first_pass)
{ {
// f32 luminance = LuminanceFromColor(src);
// f32 max_rgb = max(max(src.r, src.g), src.b); // So that we can get bloom on colors with high rgb, not just high luminance
f32 luminance = LuminanceFromColor(src); f32 luminance = LuminanceFromColor(src);
f32 max_rgb = -1; // So that we can get bloom on colors with high rgb, not just high luminance f32 max_rgb = max(max(src.r, src.g), src.b); // So that we can get bloom on colors with high rgb, not just high luminance
f32 bright = max(luminance, (max_rgb - 1.0) * 0.5); f32 bright = max(luminance, (max_rgb - 1.0) * 0.5);
if (bright > 0) if (bright > 0)
{ {

View File

@ -6,7 +6,7 @@ Struct(V_QuadPSInput)
Vec4 Semantic(sv_position); Vec4 Semantic(sv_position);
Vec2 Semantic(world_pos); Vec2 Semantic(world_pos);
Vec2 Semantic(samp_uv); Vec2 Semantic(samp_uv);
nointerpolation V_Quad Semantic(quad); nointerpolation V_GpuQuad Semantic(quad);
}; };
Struct(V_QuadPSOutput) Struct(V_QuadPSOutput)
@ -46,6 +46,7 @@ Struct(V_DVertPSOutput)
f32 V_RandFromPos(Vec3 pos); f32 V_RandFromPos(Vec3 pos);
f32 V_LifetimeFromParticleDesc(V_ParticleDesc desc, u32 particle_idx); f32 V_LifetimeFromParticleDesc(V_ParticleDesc desc, u32 particle_idx);
f32 V_FalloffFromParticleDesc(V_ParticleDesc desc, u32 particle_idx);
Vec4 V_ColorFromParticleDesc(V_ParticleDesc desc, u32 particle_idx, f32 alive_seconds, u32 density); Vec4 V_ColorFromParticleDesc(V_ParticleDesc desc, u32 particle_idx, f32 alive_seconds, u32 density);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -4,7 +4,7 @@
V_ParticleDesc V_DescFromParticleKind(V_ParticleKind kind) V_ParticleDesc V_DescFromParticleKind(V_ParticleKind kind)
{ {
V_ParticleDesc descs[V_ParticleKind_COUNT] = { V_ParticleDesc descs[V_ParticleKind_COUNT] = {
#define X(name, flags, layer, stain_rate, pen_rate, lifetime_min, lifetime_max, prune_speed_threshold, base_color, dry_factor) \ #define X(name, flags, layer, stain_rate, pen_rate, lifetime_min, lifetime_max, falloff_min, falloff_max, prune_speed_threshold, base_color, dry_factor) \
{ \ { \
V_ParticleKind_##name, \ V_ParticleKind_##name, \
flags, \ flags, \
@ -13,6 +13,8 @@ V_ParticleDesc V_DescFromParticleKind(V_ParticleKind kind)
pen_rate, \ pen_rate, \
lifetime_min, \ lifetime_min, \
lifetime_max, \ lifetime_max, \
falloff_min, \
falloff_max, \
prune_speed_threshold, \ prune_speed_threshold, \
LinearFromSrgb(base_color), \ LinearFromSrgb(base_color), \
LinearFromSrgb(dry_factor) \ LinearFromSrgb(dry_factor) \

View File

@ -25,6 +25,7 @@ G_DeclRegister(i32, V_GpuReg_MipIdx, 4);
#define V_ParticleCellBasis 0xf60c0cff344b0c5dull #define V_ParticleCellBasis 0xf60c0cff344b0c5dull
#define V_ParticleStainBasis 0x3c64e8226d98d376ull #define V_ParticleStainBasis 0x3c64e8226d98d376ull
#define V_ParticleLifetimeBasis 0x4969cf8f60816abfull #define V_ParticleLifetimeBasis 0x4969cf8f60816abfull
#define V_ParticleFalloffBasis 0xa475ffbeeeef3b9dull
Enum(V_ParticleFlag) Enum(V_ParticleFlag)
{ {
@ -46,7 +47,7 @@ Enum(V_ParticleLayer)
V_ParticleLayer_COUNT V_ParticleLayer_COUNT
}; };
// NOTE: Higher particle enum values take priority over lower ones // NOTE: Higher particle enum values take priority over lower within the same layer ones when drawing / staining
#define V_ParticlesXList(X) \ #define V_ParticlesXList(X) \
X( \ X( \
/* Name */ None, \ /* Name */ None, \
@ -54,6 +55,7 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Ground, \ /* Layer */ V_ParticleLayer_Ground, \
/* Stain rate, pen chance */ 30, 0, \ /* Stain rate, pen chance */ 30, 0, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0.01, \ /* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(0, 0, 0, 0), \ /* Base color */ VEC4(0, 0, 0, 0), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \ /* Dry color factor */ VEC4(1, 1, 1, 1) \
@ -66,26 +68,18 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Ground, \ /* Layer */ V_ParticleLayer_Ground, \
/* Stain rate, pen chance */ 100, 0.25, \ /* Stain rate, pen chance */ 100, 0.25, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 10, 20, \
/* Prune speed threshold */ 0.5, \ /* Prune speed threshold */ 0.5, \
/* Base color */ VEC4(0.6, 0.1, 0.1, 0.05), \ /* Base color */ VEC4(0.6, 0.1, 0.1, 0.05), \
/* Dry color factor */ VEC4(0.4, 0.4, 0.4, 1) \ /* Dry color factor */ VEC4(0.4, 0.4, 0.4, 1) \
) \ ) \
X( \
/* Name */ BloodDebris, \
/* Flags */ V_ParticleFlag_StainWhenPruned, \
/* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 30, 0, \
/* Lifetime */ Inf, Inf, \
/* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(0.5, 0.1, 0.1, 0.8), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \
) \
X( \ X( \
/* Name */ Debris, \ /* Name */ Debris, \
/* Flags */ V_ParticleFlag_StainWhenPruned, \ /* Flags */ V_ParticleFlag_StainWhenPruned, \
/* Layer */ V_ParticleLayer_Mid, \ /* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 10, 20, \
/* Prune speed threshold */ 0.01, \ /* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(0.4, 0.3, 0.2, 1), \ /* Base color */ VEC4(0.4, 0.3, 0.2, 1), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \ /* Dry color factor */ VEC4(1, 1, 1, 1) \
@ -96,38 +90,42 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Mid, \ /* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 10, 20, \
/* Prune speed threshold */ 0.1, \ /* Prune speed threshold */ 0.1, \
/* Base color */ VEC4(2, 0.5, 0, 1), \ /* Base color */ VEC4(2, 0.5, 0, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
) \ ) \
X( \
/* Name */ HotDebris, \
/* Flags */ V_ParticleFlag_StainWhenPruned, \
/* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \
/* Falloff */ 20, 30, \
/* Prune speed threshold */ 0.1, \
/* Base color */ VEC4(0.4, 0.3, 0.2, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.1, 1) \
) \
X( \ X( \
/* Name */ Spark, \ /* Name */ Spark, \
/* Flags */ V_ParticleFlag_StainWhenPruned, \ /* Flags */ V_ParticleFlag_StainWhenPruned, \
/* Layer */ V_ParticleLayer_Mid, \ /* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.2, 0.3, \ /* Lifetime */ 0.2, 0.3, \
/* Falloff */ 10, 20, \
/* Prune speed threshold */ 0.1, \ /* Prune speed threshold */ 0.1, \
/* Base color */ VEC4(2, 0.5, 0, 1), \ /* Base color */ VEC4(2, 0.5, 0, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
) \ ) \
\ \
/* Air particles */ \ /* Air particles */ \
X( \
/* Name */ Smoke, \
/* Flags */ V_ParticleFlag_OnlyCollideWithWalls | V_ParticleFlag_GasBlend | V_ParticleFlag_FadeLifetime, \
/* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \
/* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(0.25, 0.25, 0.25, 0.75), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \
) \
X( \ X( \
/* Name */ BulletSmoke, \ /* Name */ BulletSmoke, \
/* Flags */ V_ParticleFlag_OnlyCollideWithWalls | V_ParticleFlag_GasBlend | V_ParticleFlag_FadeLifetime, \ /* Flags */ V_ParticleFlag_OnlyCollideWithWalls | V_ParticleFlag_GasBlend | V_ParticleFlag_FadeLifetime, \
/* Layer */ V_ParticleLayer_Mid, \ /* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.075, 0.2, \ /* Lifetime */ 0.075, 0.2, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0.00, \ /* Prune speed threshold */ 0.00, \
/* Base color */ VEC4(0.8, 0.6, 0.2, 0.005), \ /* Base color */ VEC4(0.8, 0.6, 0.2, 0.005), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \ /* Dry color factor */ VEC4(1, 1, 1, 1) \
@ -138,6 +136,7 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Air, \ /* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.0, .05, \ /* Lifetime */ 0.0, .05, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0, \ /* Prune speed threshold */ 0, \
/* Base color */ VEC4(10, 3.5, 0, 1), \ /* Base color */ VEC4(10, 3.5, 0, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
@ -148,6 +147,7 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Air, \ /* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.0, 0.05, \ /* Lifetime */ 0.0, 0.05, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0, \ /* Prune speed threshold */ 0, \
/* Base color */ VEC4(10, 3.5, 0, 1), \ /* Base color */ VEC4(10, 3.5, 0, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
@ -158,6 +158,7 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Air, \ /* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.075, 0.075, \ /* Lifetime */ 0.075, 0.075, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0, \ /* Prune speed threshold */ 0, \
/* Base color */ VEC4(3, 1.5, 0, 1), \ /* Base color */ VEC4(3, 1.5, 0, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
@ -168,9 +169,21 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Air, \ /* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0.01, \ /* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(5, 1.75, 0.75, 1), \ /* Base color */ VEC4(5, 1.75, 0.75, 1), \
/* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \ /* Dry color factor */ VEC4(0.2, 0.1, 0.0, 1) \
) \
X( \
/* Name */ WallDust, \
/* Flags */ V_ParticleFlag_OnlyCollideWithWalls | V_ParticleFlag_GasBlend | V_ParticleFlag_FadeLifetime, \
/* Layer */ V_ParticleLayer_Air, \
/* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ 0.1, 0.25, \
/* Falloff */ 10, 20, \
/* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(0.5, 0.5, 0.5, 0.35), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \
) \ ) \
\ \
/* Test particles */ \ /* Test particles */ \
@ -180,6 +193,7 @@ Enum(V_ParticleLayer)
/* Layer */ V_ParticleLayer_Mid, \ /* Layer */ V_ParticleLayer_Mid, \
/* Stain rate, pen chance */ 0, 0, \ /* Stain rate, pen chance */ 0, 0, \
/* Lifetime */ Inf, Inf, \ /* Lifetime */ Inf, Inf, \
/* Falloff */ 0, 0, \
/* Prune speed threshold */ 0.01, \ /* Prune speed threshold */ 0.01, \
/* Base color */ VEC4(1, 1, 0, 1), \ /* Base color */ VEC4(1, 1, 0, 1), \
/* Dry color factor */ VEC4(1, 1, 1, 1) \ /* Dry color factor */ VEC4(1, 1, 1, 1) \
@ -228,6 +242,8 @@ Struct(V_ParticleDesc)
f32 pen_rate; f32 pen_rate;
f32 lifetime_min; f32 lifetime_min;
f32 lifetime_max; f32 lifetime_max;
f32 falloff_min;
f32 falloff_max;
f32 prune_speed_threshold; f32 prune_speed_threshold;
Vec4 base_color; Vec4 base_color;
Vec4 dry_factor; Vec4 dry_factor;
@ -244,14 +260,14 @@ Struct(V_ParticleDesc)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Quad types //~ Quad types
Enum(V_QuadFlag) Enum(V_GpuQuadFlag)
{ {
V_QuadFlag_None = 0, V_QuadFlag_None = 0,
}; };
Struct(V_Quad) Struct(V_GpuQuad)
{ {
V_QuadFlag flags; V_GpuQuadFlag flags;
u32 occluder_id; u32 occluder_id;
Affine quad_uv_to_world_af; Affine quad_uv_to_world_af;
G_TextureRef tex; G_TextureRef tex;
@ -433,9 +449,6 @@ Struct(V_SharedFrame)
Vec2 move; Vec2 move;
Vec2 look; Vec2 look;
f32 fire_held;
f32 fire_presses;
f32 roll_presses;
//- Gpu data //- Gpu data