diff --git a/.gitattributes b/.gitattributes index a4a7a72..bdbda26 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,5 @@ *.jpeg filter=lfs diff=lfs merge=lfs -text *.blend filter=lfs diff=lfs merge=lfs -text *.blend1 filter=lfs diff=lfs merge=lfs -text +*.wav filter=lfs diff=lfs merge=lfs -text +*.mp3 filter=lfs diff=lfs merge=lfs -text diff --git a/assets/engine_loop.wav b/assets/engine_loop.wav new file mode 100644 index 0000000..4651c2b --- /dev/null +++ b/assets/engine_loop.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97f8d472d4ef3990bec9d2cf209ce06531c6db767925bace1e7a1b4811d0e903 +size 234818 diff --git a/game/assets/assets.odin b/game/assets/assets.odin index ec762d6..f35854e 100644 --- a/game/assets/assets.odin +++ b/game/assets/assets.odin @@ -49,6 +49,8 @@ Asset_Manager :: struct { textures: Asset_Cache(rl.Texture2D), models: Asset_Cache(rl.Model), shaders: Asset_Cache(Loaded_Shader), + sounds: Asset_Cache(rl.Sound), + music: Asset_Cache(rl.Music), curves_1d: Asset_Cache([]f32), curves_2d: Asset_Cache(Curve_2D), bvhs: map[cstring]Loaded_BVH, @@ -107,6 +109,26 @@ SHADER_LOADER :: Asset_Cache_Loader(Loaded_Shader) { }, } +SOUND_LOADER :: Asset_Cache_Loader(rl.Sound) { + load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Sound, bool) { + sound := rl.LoadSound(path) + return sound, rl.IsSoundValid(sound) + }, + unload = proc(sound: rl.Sound) { + rl.UnloadSound(sound) + }, +} + +MUSIC_LOADER :: Asset_Cache_Loader(rl.Music) { + load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Music, bool) { + music := rl.LoadMusicStream(path) + return music, rl.IsMusicValid(music) + }, + unload = proc(music: rl.Music) { + rl.UnloadMusicStream(music) + }, +} + MODEL_LOADER :: Asset_Cache_Loader(rl.Model) { load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Model, bool) { model := rl.LoadModel(path) @@ -176,6 +198,12 @@ assetman_init :: proc(assetman: ^Asset_Manager) { assetman.shaders = { loader = SHADER_LOADER, } + assetman.sounds = { + loader = SOUND_LOADER, + } + assetman.music = { + loader = MUSIC_LOADER, + } assetman.textures = { loader = TEXTURE_LOADER, } @@ -321,6 +349,16 @@ get_shader :: proc( return loaded_shader } +get_sound :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Sound { + sound, _, _ := assetcache_fetch_or_load(&assetman.sounds, path) + return sound +} + +get_music :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Music { + sound, _, _ := assetcache_fetch_or_load(&assetman.music, path) + return sound +} + null_bvhs: []bvh.BVH get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH { @@ -784,6 +822,8 @@ shutdown :: proc(assetman: ^Asset_Manager) { assetcache_destroy(&assetman.textures) assetcache_destroy(&assetman.models) assetcache_destroy(&assetman.shaders) + assetcache_destroy(&assetman.sounds) + assetcache_destroy(&assetman.music) assetcache_destroy(&assetman.curves_1d) assetcache_destroy(&assetman.curves_2d) diff --git a/game/game.odin b/game/game.odin index 58f066b..efff1a3 100644 --- a/game/game.odin +++ b/game/game.odin @@ -361,6 +361,7 @@ World_Update_Config :: struct { } update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) { + if !world.pause { car_model := assets.get_model(&g_mem.assetman, "assets/ice_cream_truck.glb") car_bounds := rl.GetModelBoundingBox(car_model) @@ -626,7 +627,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) { axle = physics.Drive_Axle_Config { wheels = {wheel_rl, wheel_rr}, wheel_count = 2, - diff_type = .Open, + diff_type = .Fixed, final_drive_ratio = 4.1, }, }, @@ -747,6 +748,24 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) { step_mode = config.single_step_physics ? physics.Step_Mode.Single : physics.Step_Mode.Accumulated_Time, ) } + + { + engine_loop := assets.get_music(&g_mem.assetman, "assets/engine_loop.wav") + + if !rl.IsMusicStreamPlaying(engine_loop) { + rl.PlayMusicStream(engine_loop) + } + rl.UpdateMusicStream(engine_loop) + + sim_state := physics.get_sim_state(&world.physics_scene) + engine := physics.get_engine(sim_state, world.engine_handle) + rpm_percent := + max(physics.angular_velocity_to_rpm(engine.w) - engine.lowest_rpm, 0.0) / + (engine.rev_limit_rpm - engine.lowest_rpm) + + pitch := linalg.lerp(f32(1.0), f32(3.0), rpm_percent) + rl.SetMusicPitch(engine_loop, pitch) + } } update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) { @@ -1393,6 +1412,7 @@ game_init_window :: proc(args: []string) { rl.SetConfigFlags({.WINDOW_RESIZABLE, .VSYNC_HINT}) rl.InitWindow(1280, 720, "Gutter Runner") + rl.InitAudioDevice() rl.SetExitKey(.KEY_NULL) rl.SetWindowPosition(200, 200) rl.SetTargetFPS(120) @@ -1441,6 +1461,7 @@ game_shutdown :: proc() { @(export) game_shutdown_window :: proc() { + rl.CloseAudioDevice() rl.CloseWindow() deinit_physfs() diff --git a/game/physics/collision/convex.odin b/game/physics/collision/convex.odin index 18c3496..a38b04f 100644 --- a/game/physics/collision/convex.odin +++ b/game/physics/collision/convex.odin @@ -77,6 +77,8 @@ double_sided_triangle_to_convex :: proc( convex.vertices[0].pos = tri[0] convex.vertices[1].pos = tri[1] convex.vertices[2].pos = tri[2] + convex.faces[0].normal = lg.normalize0(lg.cross(tri[1] - tri[0], tri[2] - tri[0])) + convex.faces[1].normal = -convex.faces[0].normal return } diff --git a/game/physics/simulation.odin b/game/physics/simulation.odin index 9ecfab3..54b43d0 100644 --- a/game/physics/simulation.odin +++ b/game/physics/simulation.odin @@ -896,10 +896,10 @@ pgs_solve_contacts :: proc( random_order[i] = i32(i) } - // for i in 0 ..< len(random_order) - 1 { - // j := rand.int_max(len(random_order)) - // slice.swap(random_order, i, j) - // } + for i in 0 ..< len(random_order) - 1 { + j := rand.int_max(len(random_order)) + slice.swap(random_order, i, j) + } } for i in 0 ..< len(sim_state.contact_container.contacts) { @@ -1027,7 +1027,7 @@ lookup_gear_ratio :: #force_inline proc(gear_ratios: []f32, gear: i32) -> (ratio index -= 1 } index = clamp(index, 0, len(gear_ratios) - 1) - return gear_ratios[index] + return gear_ratios[index] * (index == 0 ? -1 : 1) } }