From be3c3339ecf99a82443adbb422035989df94cfa8 Mon Sep 17 00:00:00 2001 From: jgk Date: Tue, 6 Apr 2021 20:25:25 +0200 Subject: [PATCH] Tweak sound positions --- src/Dodge/Item/Weapon.hs | 6 +- src/Dodge/Item/Weapon/TriggerType.hs | 10 +-- src/Dodge/LoadSound.hs | 2 +- src/Dodge/SoundLogic.hs | 113 ++++++++++++++++++++++++--- 4 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/Dodge/Item/Weapon.hs b/src/Dodge/Item/Weapon.hs index f4c9bf074..d43799a3b 100644 --- a/src/Dodge/Item/Weapon.hs +++ b/src/Dodge/Item/Weapon.hs @@ -879,8 +879,7 @@ tractorBeamAt colID i pos dir = Projectile aGasCloud :: Int -> World -> World aGasCloud cid w - = -- soundFrom Flame fireSound 2 500 - insertCloud $ set randGen g $ + = insertCloud $ set randGen g $ w where (a,g) = randomR (-0.1,0.1) (_randGen w) @@ -896,7 +895,6 @@ aGasCloud cid w aFlame :: Float -> Int -> World -> World aFlame a cid w = shakeCr cid 2 --- $ soundFrom Flame fireSound 2 500 $ insertFlame $ resetAngle $ set randGen g $ w where @@ -1381,7 +1379,7 @@ moveRemoteShell time i cid itid dir w $ set (projectiles . ix i . pjUpdate) (moveRemoteShell (time-1) i cid itid newdir) $ over (projectiles . ix i . pjVel) (\v -> accel +.+ frict *.* v) - $ soundFrom (ShellSound i) (fromIntegral smokeTrailSound) (1) 250 + $ soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) (1) 250 $ smokeGen $ makeFlameletTimed oldPos (0.5 *.* rotateV (pi+sparkD) accel) Nothing 3 10 diff --git a/src/Dodge/Item/Weapon/TriggerType.hs b/src/Dodge/Item/Weapon/TriggerType.hs index 3883d8827..b6257936b 100644 --- a/src/Dodge/Item/Weapon/TriggerType.hs +++ b/src/Dodge/Item/Weapon/TriggerType.hs @@ -43,9 +43,9 @@ withWarmUp t f cid w | fState == 0 = set (pointerToItem . wpFire) (withWarmUp 100 f) $ set (pointerToItem . wpFireState) 2 w - | t > 1 = set (pointerToItem . wpFire) (withWarmUp (t-1) f) + | t > 2 = set (pointerToItem . wpFire) (withWarmUp (t-1) f) $ set (pointerToItem . wpFireState) 2 - $ continueSound 26 + $ soundFrom (CrWeaponSound cid) 26 2 0 w | t > 0 = set (pointerToItem . wpFire) (withWarmUp (t-1) f) $ set (pointerToItem . wpFireState) 2 @@ -54,7 +54,7 @@ withWarmUp t f cid w $ over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1) $ set (pointerToItem . wpFireState) 2 $ f cid - $ continueSound 28 + $ soundFrom (CrWeaponSound cid) 28 2 0 w where cr = _creatures w IM.! cid @@ -64,12 +64,8 @@ withWarmUp t f cid w fState = _wpFireState item fRate = _wpFireRate item reloadCondition = _wpLoadedAmmo item == 0 - continueSound soundID - | cid == 0 = soundFrom (CrWeaponSound cid) soundID 1 0 - | otherwise = soundFromPos (CrWeaponSound cid) (_crPos cr) soundID 1 0 withSound :: Int -> (Int -> World -> World) -> Int -> World -> World -withSound soundid f 0 w = (soundOnce soundid . f 0) w withSound soundid f cid w = (soundOncePos soundid p . f cid) w where p = _crPos (_creatures w IM.! cid) diff --git a/src/Dodge/LoadSound.hs b/src/Dodge/LoadSound.hs index 51367a0e1..f38b5da4e 100644 --- a/src/Dodge/LoadSound.hs +++ b/src/Dodge/LoadSound.hs @@ -14,7 +14,7 @@ import qualified SDL.Mixer as Mix -- }}} loadSounds :: IO (IM.IntMap Mix.Chunk) loadSounds = do - Mix.openAudio Mix.defaultAudio 256 + Mix.openAudio Mix.defaultAudio 128 pFireSound <- Mix.load "./data/sound/tap3.wav" click <- Mix.load "./data/sound/click1.wav" reloadSound' <- Mix.load "./data/sound/reload1.wav" diff --git a/src/Dodge/SoundLogic.hs b/src/Dodge/SoundLogic.hs index e25bd79e0..7534b0228 100644 --- a/src/Dodge/SoundLogic.hs +++ b/src/Dodge/SoundLogic.hs @@ -1,33 +1,89 @@ -module Dodge.SoundLogic where +{-| +Module : Dodge.SoundLogic +Description : Messages to "Sound" backend + +This module allows us to talk to the "Sound" module. +-} +module Dodge.SoundLogic ( + -- * Manipulation of individual sounds + soundOnce + , soundOncePos + , soundOnceOrigin + , soundFromPos + , soundFrom + , soundMultiFrom + , stopSoundFrom + + -- * Manipulation of all sounds + , haltSound + , resumeSound + , pauseSound + + -- * Synonyms for sound identifiers + , clickSound + , reloadSound + , pickUpSound + , putDownSound + , fireSound + , grenadeBang + , tapQuiet + , twoStepSound + , healSound + , doorSound + , twoStepSlowSound + , knifeSound + , buzzSound + , hitSound + , autoGunSound + , shotgunSound + , teleSound + , longGunSound + , launcherSound + , smokeTrailSound + , foot1Sound + , foot2Sound + ) where import Dodge.Data import Sound.Data (SoundStatus (..)) import Geometry.Vector +import Geometry (dist) import Control.Lens import qualified Data.Map as M +import Data.Int (Int16) +{-| Placeholder...-} haltSound :: World -> World haltSound w = w +{-| Placeholder...-} pauseSound :: World -> World pauseSound w = w +{-| Placeholder...-} resumeSound :: World -> World resumeSound w = w +{-| Add a sound to the queue for playback. + -} soundOnce :: Int -> World -> World soundOnce i = over soundQueue ((:) (i,0)) +{-| Play a sound with a given position in the world. +Uses the angle between the given position and '_cameraViewFrom', taking into account '_cameraRot'. + -} soundOncePos :: Int -> Point2 -> World -> World soundOncePos i pos w = over soundQueue ((:) (i,a)) w where - a = round - . radToDeg - . normalizeAngle - . (+ pi) - $ argV (vNormal (pos -.- _cameraViewFrom w)) - _cameraRot w + a = soundAngle pos w -soundOnceOrigin :: Int -> SoundOrigin -> World -> World +{-| Play a sound once, with a given origin. +For each origin only one sound will play at a time. +-} +soundOnceOrigin + :: Int -- ^ ID of the sound to be played + -> SoundOrigin -- ^ The \"creator\" of the sound + -> World -> World soundOnceOrigin sType so = over sounds (M.insertWith (flip const) so sound) where sound = Sound @@ -39,7 +95,13 @@ soundOnceOrigin sType so = over sounds (M.insertWith (flip const) so sound) , _soundPos = Nothing } -soundFromPos :: SoundOrigin -> Point2 -> Int -> Int -> Int -> World -> World +soundFromPos + :: SoundOrigin -- ^ \"Creator\" of sound + -> Point2 -- ^ Position of sound + -> Int -- ^ ID of sound to be played + -> Int -- ^ Frames to play sound for + -> Int -- ^ Time sound fades out after playing for the given number of frames (ms) + -> World -> World soundFromPos so pos sType time fadeTime w = over sounds (M.insertWith f so sound) w where sound = Sound @@ -51,13 +113,29 @@ soundFromPos so pos sType time fadeTime w = over sounds (M.insertWith f so sound , _soundPos = Just (a,0) } f _ s = s {_soundTime = Just time, _soundFadeTime = fadeTime} - a = round + a = soundAngle pos w + +{-| Calculates the angle of a sound with reference to '_cameraViewFrom'. +Within 10 units considers the sound to be directly in front. +-} +soundAngle :: Point2 -> World -> Int16 +{-# INLINE soundAngle #-} +soundAngle p w + | dist p earPos < 10 = 0 + | otherwise = round . radToDeg . normalizeAngle . (+ pi) - $ argV (vNormal (pos -.- _cameraViewFrom w)) - _cameraRot w + $ argV (vNormal (p -.- earPos)) - _cameraRot w + where + earPos = _cameraViewFrom w -soundFrom :: SoundOrigin -> Int -> Int -> Int -> World -> World +soundFrom + :: SoundOrigin + -> Int -- ^ Sound ID + -> Int -- ^ Frames to play + -> Int -- ^ Fade out time (ms) + -> World -> World soundFrom so sType time fadeTime w = over sounds (M.insertWith f so sound) w where sound = Sound @@ -70,7 +148,15 @@ soundFrom so sType time fadeTime w = over sounds (M.insertWith f so sound) w } f _ s = s {_soundTime = Just time, _soundFadeTime = fadeTime} -soundMultiFrom :: [SoundOrigin] -> Int -> Int -> Int -> World -> World +{-| Uses the first free origin from a list. +Does nothing if all origins are already creating sounds. +-} +soundMultiFrom + :: [SoundOrigin] + -> Int -- ^ Sound ID + -> Int -- ^ Frames to play for + -> Int -- ^ Fade out time (ms) + -> World -> World soundMultiFrom [] _ _ _ w = w soundMultiFrom (so:sos) sType time fadeTime w | so `M.member` _sounds w = soundMultiFrom sos sType time fadeTime w @@ -85,7 +171,8 @@ soundMultiFrom (so:sos) sType time fadeTime w , _soundPos = Nothing } - +{- | Sets '_soundTime' to 0. + -} stopSoundFrom :: SoundOrigin -> World -> World stopSoundFrom so = over (sounds . ix so . soundTime) (fmap $ min 0)