pre-generate rand.dat file for deterministic noise. calculate shake based on world time
This commit is contained in:
parent
4c194d3b39
commit
ad7ca7d68c
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -25,3 +25,4 @@ Makefile text eol=lf
|
||||
*.ase filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.mp3 filter=lfs diff=lfs merge=lfs -text
|
||||
*.dat filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
BIN
res/rand.dat
(Stored with Git LFS)
Normal file
BIN
res/rand.dat
(Stored with Git LFS)
Normal file
Binary file not shown.
29
src/app.c
29
src/app.c
@ -21,6 +21,7 @@
|
||||
#include "math.h"
|
||||
#include "renderer.h"
|
||||
#include "phys.h"
|
||||
#include "rng.h"
|
||||
|
||||
struct exit_callback {
|
||||
app_exit_callback_func *func;
|
||||
@ -117,6 +118,30 @@ void app_register_exit_callback(app_exit_callback_func *func)
|
||||
sys_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Generate random number file
|
||||
* (unused function)
|
||||
* ========================== */
|
||||
|
||||
#if 0
|
||||
#include "rng.h"
|
||||
INTERNAL void gen_random_file(struct string path, u32 count)
|
||||
{
|
||||
{
|
||||
/* Clear file */
|
||||
struct sys_file f = sys_file_open_write(path);
|
||||
sys_file_write(f, BUFFER(0, 0));
|
||||
sys_file_close(f);
|
||||
}
|
||||
struct sys_file f = sys_file_open_append(path);
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
u64 rand = rng_rand_u64();
|
||||
sys_file_write(f, BUFFER_FROM_STRUCT(&rand));
|
||||
}
|
||||
sys_file_close(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================== *
|
||||
* Entry point
|
||||
* ========================== */
|
||||
@ -204,9 +229,10 @@ void app_entry_point(void)
|
||||
}
|
||||
|
||||
/* Startup systems */
|
||||
struct resource_startup_receipt resource_sr = resource_startup();
|
||||
struct rng_startup_receipt rng_sr = rng_startup(&resource_sr);
|
||||
struct renderer_startup_receipt renderer_sr = renderer_startup(&window);
|
||||
struct work_startup_receipt work_sr = work_startup(worker_count);
|
||||
struct resource_startup_receipt resource_sr = resource_startup();
|
||||
struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup(&work_sr);
|
||||
struct ttf_startup_receipt ttf_sr = ttf_startup();
|
||||
struct font_startup_receipt font_sr = font_startup(&work_sr, &renderer_sr, &asset_cache_sr, &ttf_sr, &resource_sr);
|
||||
@ -221,6 +247,7 @@ void app_entry_point(void)
|
||||
|
||||
(UNUSED)user_sr;
|
||||
(UNUSED)playback_sr;
|
||||
(UNUSED)rng_sr;
|
||||
|
||||
/* Show window */
|
||||
sys_window_show(&window);
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
|
||||
#define PIXELS_PER_UNIT 256.0
|
||||
|
||||
#define GAME_FPS 50.0
|
||||
#define GAME_TIMESCALE 1.0
|
||||
#define GAME_FPS 100.0
|
||||
#define GAME_TIMESCALE 1
|
||||
|
||||
#define GAME_PHYSICS_SUBSTEPS 4
|
||||
#define GAME_PHYSICS_ENABLE_WARM_STARTING 1
|
||||
@ -65,4 +65,4 @@
|
||||
|
||||
#define AUDIO_ENABLED 0
|
||||
#define VSYNC_ENABLED 0
|
||||
#define USER_FRAME_LIMIT 300.0
|
||||
#define USER_FRAME_LIMIT 300
|
||||
|
||||
@ -254,6 +254,7 @@ struct entity {
|
||||
/* ENTITY_PROP_QUAKE */
|
||||
|
||||
f32 quake_intensity;
|
||||
f32 quake_frequency;
|
||||
f32 quake_fade; /* How much intensity to lose per second */
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
11
src/game.c
11
src/game.c
@ -12,6 +12,7 @@
|
||||
#include "log.h"
|
||||
#include "phys.h"
|
||||
#include "collider.h"
|
||||
#include "rng.h"
|
||||
|
||||
GLOBAL struct {
|
||||
struct atomic_i32 game_thread_shutdown;
|
||||
@ -413,7 +414,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
|
||||
/* Create test blood */
|
||||
/* TODO: Remove this */
|
||||
{
|
||||
struct xform xf = XFORM_TRS(.t = point, .r = sys_rand_f32(0, TAU));
|
||||
struct xform xf = XFORM_TRS(.t = point, .r = rng_rand_f32(0, TAU));
|
||||
struct entity *decal = entity_alloc(root);
|
||||
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
|
||||
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f);
|
||||
@ -421,10 +422,10 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
|
||||
|
||||
f32 perp_range = 0.5;
|
||||
struct v2 linear_velocity = v2_mul(normal, 0.5);
|
||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), sys_rand_f32(-perp_range, perp_range)));
|
||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rng_rand_f32(-perp_range, perp_range)));
|
||||
|
||||
f32 angular_velocity_range = 5;
|
||||
f32 angular_velocity = sys_rand_f32(-angular_velocity_range, angular_velocity_range);
|
||||
f32 angular_velocity = rng_rand_f32(-angular_velocity_range, angular_velocity_range);
|
||||
|
||||
entity_enable_prop(decal, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
||||
entity_set_linear_velocity(decal, linear_velocity);
|
||||
@ -1149,8 +1150,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
{
|
||||
struct entity *quake = entity_alloc(root);
|
||||
entity_set_xform(quake, XFORM_POS(pos));
|
||||
quake->quake_intensity = 0.02f;
|
||||
quake->quake_fade = quake->quake_intensity / 0.01f;
|
||||
quake->quake_intensity = 0.2f;
|
||||
quake->quake_fade = quake->quake_intensity / 0.1f;
|
||||
entity_enable_prop(quake, ENTITY_PROP_QUAKE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,7 +819,7 @@ INLINE struct mat4x4 mat4x4_from_xform(struct xform xf)
|
||||
|
||||
INLINE struct mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near_z, f32 far_z)
|
||||
{
|
||||
struct mat4x4 m = {0};
|
||||
struct mat4x4 m = ZI;
|
||||
|
||||
f32 rl = 1.0f / (right - left);
|
||||
f32 tb = 1.0f / (top - bottom);
|
||||
|
||||
79
src/rng.c
Normal file
79
src/rng.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include "rng.h"
|
||||
#include "sys.h"
|
||||
#include "resource.h"
|
||||
|
||||
GLOBAL struct {
|
||||
u64 *noise;
|
||||
u64 noise_count;
|
||||
} G = ZI, DEBUG_ALIAS(G, G_rng);
|
||||
|
||||
/* ========================== *
|
||||
* Startup
|
||||
* ========================== */
|
||||
|
||||
struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource_sr)
|
||||
{
|
||||
(UNUSED)resource_sr;
|
||||
struct string rand_path = STR("res/rand.dat");
|
||||
if (resource_exists(rand_path)) {
|
||||
struct resource r = resource_open(rand_path);
|
||||
G.noise = (u64 *)r.bytes.data;
|
||||
G.noise_count = r.bytes.size / sizeof(*G.noise);
|
||||
} else {
|
||||
sys_panic(STR("Failed to locate pre-computed noise resource"));
|
||||
}
|
||||
return (struct rng_startup_receipt) { 0 };
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Rand
|
||||
* ========================== */
|
||||
|
||||
u32 rng_rand_u32(void)
|
||||
{
|
||||
u32 v = 0;
|
||||
sys_rand(BUFFER_FROM_STRUCT(&v));
|
||||
return v;
|
||||
}
|
||||
|
||||
u64 rng_rand_u64(void)
|
||||
{
|
||||
u64 v = 0;
|
||||
sys_rand(BUFFER_FROM_STRUCT(&v));
|
||||
return v;
|
||||
}
|
||||
|
||||
f32 rng_rand_f32(f32 range_start, f32 range_end)
|
||||
{
|
||||
return ((f32)rng_rand_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
|
||||
f64 rng_rand_f64(f64 range_start, f64 range_end)
|
||||
{
|
||||
return ((f64)rng_rand_u64() / (f64)U64_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Noise
|
||||
* Functions that return a deterministic pre-computed random number based on the provided seed
|
||||
* ========================== */
|
||||
|
||||
u32 rng_noise_u32(u32 seed)
|
||||
{
|
||||
return (u32)G.noise[seed % G.noise_count];
|
||||
}
|
||||
|
||||
u64 rng_noise_u64(u64 seed)
|
||||
{
|
||||
return G.noise[seed % G.noise_count];
|
||||
}
|
||||
|
||||
f32 rng_noise_f32(u64 seed, f32 range_start, f32 range_end)
|
||||
{
|
||||
return ((f32)rng_noise_u32(seed) / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
|
||||
f32 rng_noise_f64(u64 seed, f64 range_start, f64 range_end)
|
||||
{
|
||||
return ((f64)rng_noise_u64(seed) / (f64)U64_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
22
src/rng.h
Normal file
22
src/rng.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef RNG_H
|
||||
#define RNG_H
|
||||
|
||||
struct resource_startup_receipt;
|
||||
|
||||
/* Startup */
|
||||
struct rng_startup_receipt { i32 _; };
|
||||
struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource_sr);
|
||||
|
||||
/* Rand */
|
||||
u32 rng_rand_u32(void);
|
||||
u64 rng_rand_u64(void);
|
||||
f32 rng_rand_f32(f32 range_start, f32 range_end);
|
||||
f64 rng_rand_f64(f64 range_start, f64 range_end);
|
||||
|
||||
/* Noise */
|
||||
u32 rng_noise_u32(u32 seed);
|
||||
u64 rng_noise_u64(u64 seed);
|
||||
f32 rng_noise_f32(u64 seed, f32 range_start, f32 range_end);
|
||||
f32 rng_noise_f64(u64 seed, f64 range_start, f64 range_end);
|
||||
|
||||
#endif
|
||||
@ -441,14 +441,9 @@ struct string sys_get_clipboard_text(struct arena *arena);
|
||||
/* ========================== *
|
||||
* Util
|
||||
* ========================== */
|
||||
|
||||
void sys_rand(struct buffer b);
|
||||
u32 sys_num_logical_processors(void);
|
||||
|
||||
void sys_exit(void);
|
||||
|
||||
u32 sys_rand_u32(void);
|
||||
f32 sys_rand_f32(f32 range_start, f32 range_end);
|
||||
|
||||
void sys_panic(struct string msg);
|
||||
|
||||
/* ========================== *
|
||||
|
||||
@ -19,16 +19,16 @@
|
||||
# include <ShlObj_core.h>
|
||||
# include <fileapi.h>
|
||||
# include <dwmapi.h>
|
||||
# include <NTSecAPI.h>
|
||||
# include <bcrypt.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#pragma comment(lib, "kernel32")
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "shell32")
|
||||
#pragma comment(lib, "ole32")
|
||||
#pragma comment(lib, "advapi32")
|
||||
#pragma comment(lib, "winmm")
|
||||
#pragma comment(lib, "dwmapi")
|
||||
#pragma comment(lib, "bcrypt")
|
||||
|
||||
#define SYS_WINDOW_EVENT_LISTENERS_MAX 512
|
||||
#define WINDOW_CLASS_NAME L"power_play_window_class"
|
||||
@ -737,7 +737,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(window_thread_entry_point, arg)
|
||||
sync_flag_set(&window->ready_sf);
|
||||
|
||||
while (!window->event_thread_shutdown) {
|
||||
MSG msg = {0};
|
||||
MSG msg = ZI;
|
||||
GetMessageW(&msg, 0, 0, 0);
|
||||
|
||||
/* Update cursor */
|
||||
@ -859,10 +859,10 @@ INTERNAL void win32_update_window_from_system(struct win32_window *window)
|
||||
{
|
||||
HWND hwnd = window->hwnd;
|
||||
|
||||
RECT window_rect = {0};
|
||||
RECT window_rect = ZI;
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
|
||||
RECT client_rect = {0};
|
||||
RECT client_rect = ZI;
|
||||
GetClientRect(hwnd, (LPRECT)&client_rect);
|
||||
ClientToScreen(hwnd, (LPPOINT)&client_rect.left);
|
||||
ClientToScreen(hwnd, (LPPOINT)&client_rect.right);
|
||||
@ -1852,9 +1852,14 @@ struct string sys_get_clipboard_text(struct arena *arena)
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Util
|
||||
* RNG
|
||||
* ========================== */
|
||||
|
||||
void sys_rand(struct buffer b)
|
||||
{
|
||||
BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (PUCHAR)b.data, b.size, 0);
|
||||
}
|
||||
|
||||
u32 sys_num_logical_processors(void)
|
||||
{
|
||||
return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
@ -1865,18 +1870,6 @@ void sys_exit(void)
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
u32 sys_rand_u32(void)
|
||||
{
|
||||
u32 v;
|
||||
RtlGenRandom(&v, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
f32 sys_rand_f32(f32 range_start, f32 range_end)
|
||||
{
|
||||
return ((f32)sys_rand_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
||||
}
|
||||
|
||||
void sys_panic(struct string msg)
|
||||
{
|
||||
ASSERT(false);
|
||||
|
||||
25
src/user.c
25
src/user.c
@ -17,6 +17,7 @@
|
||||
#include "mixer.h"
|
||||
#include "atomic.h"
|
||||
#include "collider.h"
|
||||
#include "rng.h"
|
||||
|
||||
struct bind_state {
|
||||
b32 is_held; /* Is this bind held down this frame */
|
||||
@ -682,13 +683,29 @@ INTERNAL void user_update(void)
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
if (!entity_is_valid_and_active(ent)) continue;
|
||||
if (ent->shake <= 0) continue;
|
||||
|
||||
/* How much time between camera shakes */
|
||||
const f32 frequency = 0.01;
|
||||
f32 shake = ent->shake;
|
||||
if (shake > 0) {
|
||||
u64 basis = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&ent->handle));
|
||||
u32 angle_seed0 = basis + (u64)(G.world.time / frequency);
|
||||
u32 angle_seed1 = angle_seed0 + 1;
|
||||
f32 angle0 = rng_noise_f32(angle_seed0, 0, TAU);
|
||||
f32 angle1 = rng_noise_f32(angle_seed1, 0, TAU);
|
||||
|
||||
struct xform xf = entity_get_xform(ent);
|
||||
xf.og = v2_add(xf.og, v2_mul(v2_from_angle(sys_rand_f32(0, TAU)), shake));
|
||||
entity_set_xform(ent, xf);
|
||||
struct v2 vec0 = v2_with_len(v2_from_angle(angle0), shake);
|
||||
/* NOTE: vec1 not completely accurate since shake can change between frames, just a prediction */
|
||||
struct v2 vec1 = v2_with_len(v2_from_angle(angle1), shake);
|
||||
|
||||
/* TODO: Cubic interp? */
|
||||
f32 blend = math_fmod64(G.world.time, frequency) / frequency;
|
||||
struct v2 vec = v2_lerp(vec0, vec1, blend);
|
||||
|
||||
struct xform xf = entity_get_xform(ent);
|
||||
xf.og = v2_add(xf.og, v2_mul(vec, shake));
|
||||
entity_set_xform(ent, xf);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "memory.h"
|
||||
#include "arena.h"
|
||||
#include "atomic.h"
|
||||
#include "math.h"
|
||||
|
||||
/* Utility functions and stuff that don't have a home :( */
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user