affection/src/Affection/Util.hs

92 lines
2.6 KiB
Haskell
Raw Normal View History

2018-01-12 21:08:23 +00:00
module Affection.Util where
2017-07-29 19:45:40 +00:00
import Affection.Types
import Affection.Logging
2018-01-12 21:08:23 +00:00
import Affection.MessageBus.Message.WindowMessage
2017-07-29 19:45:40 +00:00
2018-01-12 21:08:23 +00:00
import SDL (($=))
2017-07-29 19:45:40 +00:00
import qualified SDL
2018-01-12 21:08:23 +00:00
import qualified Graphics.Rendering.OpenGL as GL
2017-07-29 19:45:40 +00:00
import System.Clock
import Control.Monad.State
2018-09-25 15:27:35 +00:00
-- | Prehandle SDL events
2017-07-29 19:45:40 +00:00
preHandleEvents :: [SDL.Event] -> Affection us [SDL.EventPayload]
preHandleEvents evs =
return $ map SDL.eventPayload evs
-- | Return the userstate to the user
getAffection :: Affection us us
2018-09-25 14:10:36 +00:00
getAffection = gets userState
2017-07-29 19:45:40 +00:00
-- | Put altered user state back
putAffection
:: us -- User state
-> Affection us ()
putAffection us = do
ad <- get
put $ ad
{ userState = us }
-- | block a thread for a specified amount of time
delaySec
:: Int -- ^ Number of seconds
-> IO ()
delaySec dur = SDL.delay (fromIntegral $ dur * 1000)
-- | Get time since start but always the same in the current tick.
getElapsedTime :: Affection us Double
2018-09-25 14:10:36 +00:00
getElapsedTime = gets elapsedTime
2017-07-29 19:45:40 +00:00
2018-09-25 15:27:35 +00:00
-- | Get delta time (time elapsed from last frame)
2017-07-29 19:45:40 +00:00
getDelta :: Affection us Double
2018-09-25 14:10:36 +00:00
getDelta = gets deltaTime
2017-07-29 19:45:40 +00:00
2018-09-25 15:27:35 +00:00
-- | Quit the engine loop
2017-07-29 19:45:40 +00:00
quit :: Affection us ()
quit = do
ad <- get
put $ ad { quitEvent = True }
-- | Toggle the Screen mode between 'SDL.Windowed' and 'SDL.FullscreenDesktop'.
-- Pauses the Engine in the process.
2017-07-29 19:45:40 +00:00
toggleScreen :: Affection us ()
toggleScreen = do
ad <- get
newMode <- case screenMode ad of
SDL.Windowed -> do
SDL.setWindowMode (drawWindow ad) SDL.FullscreenDesktop
return SDL.FullscreenDesktop
SDL.FullscreenDesktop -> do
2017-07-29 19:45:40 +00:00
SDL.setWindowMode (drawWindow ad) SDL.Windowed
return SDL.Windowed
x -> do
2018-01-12 21:08:23 +00:00
liftIO $ logIO Warn ("Unexpected Screen mode: " ++ show x)
return x
2017-07-29 19:45:40 +00:00
now <- liftIO $ getTime Monotonic
put ad
{ sysTime = now
, screenMode = newMode
}
2018-01-12 21:08:23 +00:00
-- | Fit the GL Viewport to Window size
fitViewport
:: Double -- ^ Image Ratio (width / height)
-> WindowMessage -- ^ Incoming Message. Listens only on
-- 'MsgWindowResize' and ignores all others.
-> Affection us ()
fitViewport ratio (MsgWindowResize _ _ (SDL.V2 w h)) = do
liftIO $ logIO Verbose "Fitting Viewport to size"
if (fromIntegral w / fromIntegral h) > ratio
then do
let nw = floor (fromIntegral h * ratio)
dw = floor ((fromIntegral w - fromIntegral nw) / 2 :: Double)
GL.viewport $= (GL.Position dw 0, GL.Size nw h)
else do
let nh = floor (fromIntegral w / ratio)
dh = floor ((fromIntegral h - fromIntegral nh) / 2 :: Double)
GL.viewport $= (GL.Position 0 dh, GL.Size w nh)
fitViewport _ _ = return ()