Cleanup, haddocks
This commit is contained in:
+39
-13
@@ -1,45 +1,64 @@
|
||||
{-|
|
||||
Module : Sound
|
||||
Description : Channel selection and storage
|
||||
|
||||
This module checks for empty channels and plays sounds on them, using data chunks loaded into an IntMap,
|
||||
and sound specifications of type 'Sound' loaded into a Map.
|
||||
Uses SDL.Mixer.
|
||||
-}
|
||||
module Sound
|
||||
where
|
||||
import Sound.Preload
|
||||
|
||||
import Control.Monad
|
||||
|
||||
import qualified SDL.Mixer as Mix
|
||||
|
||||
import Data.Maybe
|
||||
import qualified Data.IntMap as IM
|
||||
import qualified Data.Map as M
|
||||
|
||||
import Control.Monad
|
||||
import Control.Lens
|
||||
|
||||
{- | Play sounds from a list of indices.
|
||||
Each sound is played once if there is a free channel.
|
||||
-}
|
||||
playSoundQueue :: SoundData a -> [Int] -> IO ()
|
||||
playSoundQueue sd ns = forM_ ns $ \n -> playIfFree (_loadedChunks sd IM.! n) Mix.Once
|
||||
|
||||
-- this can be cleaned up
|
||||
{- | Given a chunk, attempt to play this on a free channel a given number of
|
||||
times. Returns 'Just' the channel if succeeds.
|
||||
-}
|
||||
playIfFree :: Mix.Chunk -> Mix.Times -> IO (Maybe Mix.Channel)
|
||||
playIfFree c times = do
|
||||
mayChan <- Mix.getAvailable Mix.DefaultGroup
|
||||
case mayChan of
|
||||
Nothing -> return Nothing
|
||||
Just i -> Just <$> Mix.playOn i times c
|
||||
|
||||
{- | Given a chunk and sound specification, play the chunk according to the specification
|
||||
if there is a free channel.
|
||||
On success return 'Just' an updated sound specification.
|
||||
-}
|
||||
playSoundIfFree :: Mix.Chunk -> Sound -> IO (Maybe Sound)
|
||||
playSoundIfFree c s = case _soundTime s of
|
||||
Just _ -> (playIfFree c Mix.Forever) >>= return . f
|
||||
Just _ -> playIfFree c Mix.Forever >>= return . f
|
||||
Nothing -> playIfFree c Mix.Once >>= return . f
|
||||
where
|
||||
f :: Maybe Mix.Channel -> Maybe Sound
|
||||
f = fmap (\chan -> (s & soundChannel .~ Just chan))
|
||||
f = fmap ( \chan -> s & soundChannel ?~ chan)
|
||||
|
||||
{- Stop a channel if it was playing.
|
||||
Always returns 'IO' 'Nothing'.
|
||||
-}
|
||||
haltMaybe :: Maybe Mix.Channel -> IO (Maybe Sound)
|
||||
haltMaybe (Just x) = Mix.halt x >> return Nothing
|
||||
haltMaybe Nothing = return Nothing
|
||||
|
||||
-- logic: check if sound is playing:
|
||||
-- if so, decrement timers, and/or stop playing and remove
|
||||
-- if not, check if there is free channel:
|
||||
-- if so, start playing
|
||||
-- if not, remove sound
|
||||
{- Play a sound according to it's specification.
|
||||
Logic: check if sound is playing:
|
||||
|
||||
- If so, decrement timers, and/or stop playing and remove
|
||||
- If not, check if there is free channel:
|
||||
- If so, start playing
|
||||
- If not, remove sound.
|
||||
-}
|
||||
playSound :: SoundData a -> Sound -> IO (Maybe Sound)
|
||||
playSound sd s = case _soundChannel s of
|
||||
Just i -> case _soundTime s of
|
||||
@@ -51,15 +70,22 @@ playSound sd s = case _soundChannel s of
|
||||
)
|
||||
Nothing -> playSoundIfFree (_loadedChunks sd IM.! _soundType s) s
|
||||
|
||||
{- Play all sounds and create new sound data.
|
||||
-}
|
||||
playSounds :: SoundData a -> IO (SoundData a)
|
||||
playSounds sd = do
|
||||
newSounds <- mapM (playSound sd) (_playingSounds sd)
|
||||
return $ sd & playingSounds .~ M.mapMaybe id newSounds
|
||||
|
||||
{- Update sound specifications by overwriting an old Map with a new Map.
|
||||
Copies any information about channels from the old Map to the new Map.
|
||||
-}
|
||||
updatePlaying :: Ord a => M.Map a Sound -> M.Map a Sound -> M.Map a Sound
|
||||
updatePlaying new old = M.unionWith f new old
|
||||
where
|
||||
f newSound oldSound = newSound {_soundChannel = _soundChannel oldSound}
|
||||
|
||||
{- Start playing new sounds and update sound specifications.
|
||||
-}
|
||||
playAndUpdate :: Ord a => M.Map a Sound -> SoundData a -> IO (SoundData a)
|
||||
playAndUpdate new sd = playSounds $ over playingSounds (updatePlaying new) sd
|
||||
|
||||
Reference in New Issue
Block a user