module Game.Controller (Controls (..), init, update) where import Data.Maybe (fromMaybe, isNothing) import Data.Vector ((!?)) import Game.Utils (isPressed, isPressedGamepad) import qualified SDL import qualified SDL.Input.GameController as SDL import qualified SDL.Raw import Prelude hiding (init) data Controls = Controls { cUp :: Bool, cDown :: Bool, cLeft :: Bool, cRight :: Bool, cA :: Bool, cB :: Bool, cMenu :: Bool, cJoy :: Maybe SDL.Raw.Joystick } deriving (Show) getJoystick :: IO (Maybe SDL.Raw.Joystick) getJoystick = do joys <- SDL.availableJoysticks case joys !? 0 of Nothing -> pure Nothing Just x -> Just <$> do -- XXX: are we sure this is a gamepad? putStrLn ("gamepad: " ++ show x) let joyId = SDL.joystickDeviceId x g <- SDL.Raw.gameControllerOpen joyId SDL.Raw.gameControllerGetJoystick g init :: IO Controls init = do Controls False False False False False False False <$> getJoystick updateGamepad :: [SDL.EventPayload] -> Controls -> Controls updateGamepad events controls | isNothing $ cJoy controls = controls -- XXX: deal with disconnection/reconnection | otherwise = controls { cUp = fromMaybe (cUp controls) $ isPressedGamepad SDL.ControllerButtonDpadUp events, cDown = fromMaybe (cDown controls) $ isPressedGamepad SDL.ControllerButtonDpadDown events, cLeft = fromMaybe (cLeft controls) $ isPressedGamepad SDL.ControllerButtonDpadLeft events, cRight = fromMaybe (cRight controls) $ isPressedGamepad SDL.ControllerButtonDpadRight events, cA = fromMaybe (cA controls) $ isPressedGamepad SDL.ControllerButtonA events, cB = fromMaybe (cB controls) $ isPressedGamepad SDL.ControllerButtonB events, cMenu = fromMaybe (cMenu controls) $ isPressedGamepad SDL.ControllerButtonStart events } updateKeyboard :: [SDL.EventPayload] -> Controls -> Controls updateKeyboard events controls = controls { cUp = fromMaybe (cUp controls) $ isPressed SDL.KeycodeUp events, cDown = fromMaybe (cDown controls) $ isPressed SDL.KeycodeDown events, cLeft = fromMaybe (cLeft controls) $ isPressed SDL.KeycodeLeft events, cRight = fromMaybe (cRight controls) $ isPressed SDL.KeycodeRight events, cA = fromMaybe (cA controls) $ isPressed SDL.KeycodeZ events, cB = fromMaybe (cB controls) $ isPressed SDL.KeycodeX events, cMenu = fromMaybe (cMenu controls) $ isPressed SDL.KeycodeReturn events } update :: [SDL.EventPayload] -> Controls -> Controls update events controls = do updateGamepad events $ updateKeyboard events controls