276 lines
7.5 KiB
Haskell
276 lines
7.5 KiB
Haskell
{- |
|
|
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
|
|
soundStart,
|
|
soundContinue,
|
|
soundContinueVol,
|
|
soundFromGeneral,
|
|
soundMultiFrom,
|
|
stopSoundFrom,
|
|
|
|
-- * helper to determine the angle of a sound given a world position
|
|
soundAngle,
|
|
|
|
-- * Manipulation of all sounds
|
|
haltSound,
|
|
resumeSound,
|
|
pauseSound,
|
|
module Dodge.SoundLogic.LoadSound,
|
|
) where
|
|
|
|
import Control.Lens
|
|
import Data.Int (Int16)
|
|
import qualified Data.Map as M
|
|
import Data.Maybe
|
|
import Dodge.Data.Universe
|
|
import Dodge.SoundLogic.LoadSound
|
|
import Geometry.Data
|
|
import Geometry.Vector
|
|
import Sound.Data
|
|
|
|
-- | Placeholder...
|
|
haltSound :: World -> World
|
|
haltSound w = w
|
|
|
|
-- | Placeholder...
|
|
pauseSound :: World -> World
|
|
pauseSound w = w
|
|
|
|
-- | Placeholder...
|
|
resumeSound :: Universe -> Universe
|
|
resumeSound w = w
|
|
|
|
soundWithStatusVolumeGeneral ::
|
|
-- | Volume factor, 0 - 1
|
|
Float ->
|
|
PlayStatus ->
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
(World -> Point2) ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundWithStatusVolumeGeneral vol status so fpos sType mtime w = w & toPlaySounds %~ M.insertWith f so sound
|
|
where
|
|
sound =
|
|
Sound
|
|
{ _soundChunkID = sType
|
|
, _soundTime = mtime
|
|
, _soundStatus =
|
|
SoundStatus
|
|
{ _playStatus = status
|
|
, _isLooping = isJust mtime
|
|
}
|
|
, _soundChannel = Nothing
|
|
, _soundAngDist = Just (a, floor (225 * (1 - vol)))
|
|
, _soundPos = fpos w
|
|
, _soundVolume = soundToVol sType * vol
|
|
, _soundVolumeFraction = vol
|
|
}
|
|
f _ s = s{_soundTime = mtime}
|
|
a = soundAngle (fpos w) w
|
|
|
|
soundWithStatusVolume ::
|
|
-- | Volume factor, 0 - 1
|
|
Float ->
|
|
PlayStatus ->
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
Point2 ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundWithStatusVolume vol status so pos = soundWithStatusVolumeGeneral vol status so (const pos)
|
|
|
|
--soundWithStatusVolume vol status so pos sType mtime w = w & toPlaySounds %~ M.insertWith f so sound
|
|
-- where
|
|
-- sound = Sound
|
|
-- { _soundChunkID = sType
|
|
-- , _soundTime = mtime
|
|
-- , _soundStatus = SoundStatus
|
|
-- {_playStatus = status
|
|
-- ,_isLooping = isJust mtime
|
|
-- }
|
|
-- , _soundChannel = Nothing
|
|
-- , _soundAngDist = Just (a,floor (225 * (1 - vol)))
|
|
-- , _soundPos = pos
|
|
-- , _soundVolume = soundToVol sType * vol
|
|
-- , _soundVolumeFraction = vol
|
|
-- }
|
|
-- f _ s = s {_soundTime = mtime }
|
|
-- a = soundAngle pos w
|
|
|
|
soundWithStatus ::
|
|
PlayStatus ->
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
Point2 ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundWithStatus = soundWithStatusVolume 1
|
|
|
|
soundStart ::
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
Point2 ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundStart = soundWithStatus ToStart
|
|
|
|
soundContinue ::
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
Point2 ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundContinue = soundWithStatus ToContinueStart
|
|
|
|
-- this needs to all be cleaned up, moved to general sounds
|
|
soundContinueVol ::
|
|
-- | volume
|
|
Float ->
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
Point2 ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundContinueVol vol = soundWithStatusVolume vol ToContinueStart
|
|
|
|
soundFromGeneral ::
|
|
-- | \"Creator\" of sound
|
|
SoundOrigin ->
|
|
-- | Position of sound
|
|
(World -> Point2) ->
|
|
-- | ID of sound to be played
|
|
SoundID ->
|
|
-- | Frames to play sound for, Nothing for until finished
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundFromGeneral = soundWithStatusVolumeGeneral 1 ToStart
|
|
|
|
--soundFromGeneral so fpos sType mtime w = w & toPlaySounds %~ M.insertWith f so sound
|
|
-- where
|
|
-- sound = Sound
|
|
-- { _soundChunkID = sType
|
|
-- , _soundTime = mtime
|
|
-- , _soundStatus = SoundStatus
|
|
-- { _playStatus = ToStart
|
|
-- , _isLooping = isJust mtime
|
|
-- }
|
|
-- , _soundChannel = Nothing
|
|
-- , _soundAngDist = Just (a,0)
|
|
-- , _soundPos = fpos w
|
|
-- , _soundVolume = soundToVol sType
|
|
-- , _soundVolumeFraction = 1
|
|
-- }
|
|
-- f _ s = s {_soundTime = mtime }
|
|
-- a = soundAngle (fpos w) 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 (p -.- earPos)) - (w ^. cWorld . camPos . camRot)
|
|
where
|
|
earPos = w ^. cWorld . camPos . camViewFrom
|
|
|
|
{- | Uses the first free origin from a list.
|
|
Does nothing if all origins are already creating sounds.
|
|
-}
|
|
soundMultiFrom ::
|
|
[SoundOrigin] ->
|
|
-- | Position
|
|
Point2 ->
|
|
-- | Sound ID
|
|
SoundID ->
|
|
-- | Frames to play for, Nothing for full length
|
|
Maybe Int ->
|
|
World ->
|
|
World
|
|
soundMultiFrom [] _ _ _ w = w
|
|
--soundMultiFrom [so] pos sType mtime w
|
|
-- = over toPlaySounds (M.insert so sound) w
|
|
-- where
|
|
-- sound = Sound
|
|
-- { _soundChunkID = sType
|
|
-- , _soundTime = mtime
|
|
-- , _soundStatus = SoundStatus
|
|
-- { _playStatus = ToStart
|
|
-- , _isLooping = isJust mtime
|
|
-- }
|
|
-- , _soundChannel = Nothing
|
|
-- , _soundAngDist = Just (a,0)
|
|
-- , _soundPos = pos
|
|
-- , _soundVolume = soundToVol sType
|
|
-- , _soundVolumeFraction = 1
|
|
-- }
|
|
-- a = soundAngle pos w
|
|
soundMultiFrom (so : sos) pos sType mtime w
|
|
| so `M.member` _playingSounds w = soundMultiFrom sos pos sType mtime w
|
|
| otherwise = over toPlaySounds (M.insert so sound) w
|
|
where
|
|
sound =
|
|
Sound
|
|
{ _soundChunkID = sType
|
|
, _soundTime = mtime
|
|
, _soundStatus =
|
|
SoundStatus
|
|
{ _playStatus = ToStart
|
|
, _isLooping = isJust mtime
|
|
}
|
|
, _soundChannel = Nothing
|
|
, _soundAngDist = Just (a, 0)
|
|
, _soundPos = pos
|
|
, _soundVolume = soundToVol sType
|
|
, _soundVolumeFraction = 1
|
|
}
|
|
a = soundAngle pos w
|
|
|
|
-- | Sets '_soundTime' to 0.
|
|
stopSoundFrom :: SoundOrigin -> World -> World
|
|
stopSoundFrom so = playingSounds . ix so . soundTime ?~ 0
|
|
|
|
--stopSoundFrom so = over (playingSounds . ix so . soundTime) (fmap $ min 0)
|