{-# LINE 1 "System/CWiid.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface #-}

-- |
-- Module      :  System.CWiid
-- Copyright   :  Kiwamu Okabe, Ivan Perez and the cwiid team
-- License     :  GPL-2
--
-- Maintainer  :  ivan.perez@keera.co.uk
-- Stability   :  experimental
-- Portability :  unknown
--
-- Bindings for the cwiid library, a working userspace driver
-- along with various applications implementing event drivers,
-- multiple Wiimote connectivity, gesture recognition, and other
-- Wiimote-based functionality.
--
-- The current implementation is rather incomplete. In particular:
--
-- * Some Haskell functions (those related to rpt mode, rumble, leds)
-- had hard-coded values in them. Therefore, they implemented only a
-- very partial interface to their C counterparts. The new versions
-- should be tested and, if any other function is like this,
-- then exported properly.
--
-- * Not all functions/wiimote fields are accessible. In particular,
-- acceleromoter and IR is in testing stage. Nunchuck, calibration,
-- wiimote plus are not handled at all (but will be in the future).
--
-- All in all, the code works quite well and is currently being used
-- to implement several real games.

module System.CWiid
       (
        -- * Initialization
        cwiidOpen,
        CWiidWiimote,
        -- * State
        CWiidState(..),
        -- * Reception mode
        cwiidSetRptMode,
        -- * Leds
        CWiidLedFlag,
        cwiidLed1,
        cwiidLed2,
        cwiidLed3,
        cwiidLed4,
        -- ** Led operations
        cwiidSetLed,
        combineCwiidLedFlag,
        -- * Rumble
        cwiidSetRumble,
        -- * Buttons
        cwiidGetBtnState, cwiidIsBtnPushed,
        cwiidBtn2, cwiidBtn1, cwiidBtnB, cwiidBtnA, cwiidBtnMinus,
        cwiidBtnHome, cwiidBtnLeft, cwiidBtnRight, cwiidBtnDown, cwiidBtnUp,
        cwiidBtnPlus, combineCwiidBtnFlag, diffCwiidBtnFlag,
        CWiidBtnFlag(..),
        -- * Accelerometers
        cwiidGetAcc,
        CWiidAcc(..),
        -- * Infra-red
        CWiidIRSrc(..),
        cwiidGetIR
        ) where

-- import Foreign.C.Error
import Data.Bits
import Foreign.C.Types
import Foreign.Marshal
import Foreign.Ptr
import Foreign.Storable



-----------------------------------------------------------------------------
-- Data type
---

-- typedef struct {
--         uint8_t b[6];
-- } __attribute__((packed)) bdaddr_t;
-- #define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
data CWiidBdaddr = CWiidBdaddr Int Int Int Int Int Int
instance Storable CWiidBdaddr where
  sizeOf :: CWiidBdaddr -> Int
sizeOf = Int -> CWiidBdaddr -> Int
forall a b. a -> b -> a
const (Int
6)
{-# LINE 86 "System/CWiid.hsc" #-}
  alignment = sizeOf
  poke :: Ptr CWiidBdaddr -> CWiidBdaddr -> IO ()
poke Ptr CWiidBdaddr
bdat (CWiidBdaddr Int
b0 Int
b1 Int
b2 Int
b3 Int
b4 Int
b5) = do
    ((\Ptr CWiidBdaddr
hsc_ptr -> Ptr CWiidBdaddr -> Int -> Int -> IO ()
forall b. Ptr b -> Int -> Int -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CWiidBdaddr
hsc_ptr Int
0)) Ptr CWiidBdaddr
bdat Int
b0
{-# LINE 89 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 1)) bdat b1
{-# LINE 90 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) bdat b2
{-# LINE 91 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 3)) bdat b3
{-# LINE 92 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) bdat b4
{-# LINE 93 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 5)) bdat b5
{-# LINE 94 "System/CWiid.hsc" #-}
  peek bdat = do
    b0 <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) bdat
{-# LINE 96 "System/CWiid.hsc" #-}
    b1 <- ((\hsc_ptr -> peekByteOff hsc_ptr 1)) bdat
{-# LINE 97 "System/CWiid.hsc" #-}
    b2 <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) bdat
{-# LINE 98 "System/CWiid.hsc" #-}
    b3 <- ((\hsc_ptr -> peekByteOff hsc_ptr 3)) bdat
{-# LINE 99 "System/CWiid.hsc" #-}
    b4 <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) bdat
{-# LINE 100 "System/CWiid.hsc" #-}
    b5 <- ((\hsc_ptr -> peekByteOff hsc_ptr 5)) bdat
{-# LINE 101 "System/CWiid.hsc" #-}
    return $ CWiidBdaddr b0 b1 b2 b3 b4 b5

-- typedef struct wiimote cwiid_wiimote_t;
--
-- | A connection to an existing wiimote. Use 'cwiidOpen' to
-- connect to a wiimote and obtain one of these.
newtype CWiidWiimote = CWiidWiimote { CWiidWiimote -> Ptr ()
unCWiidWiimote :: Ptr () }

-- | Try to establish a connection to any existing Wiimote using
-- any existing bluetooth interface.
-- 
-- The function returns 'Nothing' if there is no bluetooth interface
-- or if no wiimote can be located. If the connection succeeds,
-- a 'CWiidWiimote' is returned (inside a 'Just'), which can be used to 
-- poll the wiimote using other functions.
-- 
-- There is a default timeout of 5 seconds.
-- 
-- * TODO: export cwiid_open_time and cwiid_close as well.

-- wiimote = cwiid_open(&bdaddr, 0)))
cwiidOpen :: IO (Maybe CWiidWiimote)
cwiidOpen :: IO (Maybe CWiidWiimote)
cwiidOpen =
  (Ptr CWiidBdaddr -> IO (Maybe CWiidWiimote))
-> IO (Maybe CWiidWiimote)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CWiidBdaddr -> IO (Maybe CWiidWiimote))
 -> IO (Maybe CWiidWiimote))
-> (Ptr CWiidBdaddr -> IO (Maybe CWiidWiimote))
-> IO (Maybe CWiidWiimote)
forall a b. (a -> b) -> a -> b
$ \Ptr CWiidBdaddr
bdAddr -> do
    Ptr CWiidBdaddr -> CWiidBdaddr -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CWiidBdaddr
bdAddr (CWiidBdaddr -> IO ()) -> CWiidBdaddr -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> Int -> Int -> Int -> CWiidBdaddr
CWiidBdaddr Int
0 Int
0 Int
0 Int
0 Int
0 Int
0
    Ptr ()
handle <- Ptr CWiidBdaddr -> CInt -> IO (Ptr ())
c_cwiid_open Ptr CWiidBdaddr
bdAddr CInt
0 -- エラー処理必要
    if Ptr ()
handle Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr ()
forall a. Ptr a
nullPtr
      then Maybe CWiidWiimote -> IO (Maybe CWiidWiimote)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe CWiidWiimote
forall a. Maybe a
Nothing
      else Maybe CWiidWiimote -> IO (Maybe CWiidWiimote)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CWiidWiimote -> IO (Maybe CWiidWiimote))
-> Maybe CWiidWiimote -> IO (Maybe CWiidWiimote)
forall a b. (a -> b) -> a -> b
$ CWiidWiimote -> Maybe CWiidWiimote
forall a. a -> Maybe a
Just (CWiidWiimote -> Maybe CWiidWiimote)
-> CWiidWiimote -> Maybe CWiidWiimote
forall a b. (a -> b) -> a -> b
$ Ptr () -> CWiidWiimote
CWiidWiimote Ptr ()
handle

{--
struct cwiid_state {
        uint8_t rpt_mode;
        uint8_t led;
        uint8_t rumble;
        uint8_t battery;
        uint16_t buttons;
        uint8_t acc[3];
        struct cwiid_ir_src ir_src[CWIID_IR_SRC_COUNT];
        enum cwiid_ext_type ext_type;
        union ext_state ext;
        enum cwiid_error error;
};
--}

-- | The state of the wiimote. Use 'cwiidSetRptMode' to enable/disable
-- sensors.
-- 
-- * FIXME: incomplete state
-- * FIXME: export get_state
data CWiidState = CWiidState
  { CWiidState -> Int
rptMode :: Int, CWiidState -> Int
led :: Int, CWiidState -> Int
rumble :: Int, 
    CWiidState -> Int
battery :: Int, CWiidState -> Int
buttons :: Int, CWiidState -> [Int]
acc :: [Int]
  , CWiidState -> [CWiidIRSrc]
irSrc   :: [CWiidIRSrc]
  }
  deriving Int -> CWiidState -> ShowS
[CWiidState] -> ShowS
CWiidState -> String
(Int -> CWiidState -> ShowS)
-> (CWiidState -> String)
-> ([CWiidState] -> ShowS)
-> Show CWiidState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidState -> ShowS
showsPrec :: Int -> CWiidState -> ShowS
$cshow :: CWiidState -> String
show :: CWiidState -> String
$cshowList :: [CWiidState] -> ShowS
showList :: [CWiidState] -> ShowS
Show

instance Storable CWiidState where
  sizeOf :: CWiidState -> Int
sizeOf = Int -> CWiidState -> Int
forall a b. a -> b -> a
const (Int
64)
{-# LINE 160 "System/CWiid.hsc" #-}
  alignment = sizeOf
  poke :: Ptr CWiidState -> CWiidState -> IO ()
poke Ptr CWiidState
cwst (CWiidState Int
rp Int
l Int
ru Int
ba Int
bu [Int
ac0,Int
ac1,Int
ac2] [CWiidIRSrc]
irs) = do
    ((\Ptr CWiidState
hsc_ptr -> Ptr CWiidState -> Int -> Int -> IO ()
forall b. Ptr b -> Int -> Int -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CWiidState
hsc_ptr Int
0)) Ptr CWiidState
cwst Int
rp
{-# LINE 163 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 1)) cwst l
{-# LINE 164 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) cwst ru
{-# LINE 165 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 3)) cwst ba
{-# LINE 166 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) cwst bu
{-# LINE 167 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 6)) cwst (fromIntegral ac0 :: CUChar)
{-# LINE 168 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 7)) cwst (fromIntegral ac1 :: CUChar)
{-# LINE 169 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) cwst (fromIntegral ac2 :: CUChar)
{-# LINE 170 "System/CWiid.hsc" #-}
    pokeArray (((\hsc_ptr -> hsc_ptr `plusPtr` 10)) cwst) irs 
{-# LINE 171 "System/CWiid.hsc" #-}
  peek cwst = do
    rp <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) cwst
{-# LINE 173 "System/CWiid.hsc" #-}
    l <- ((\hsc_ptr -> peekByteOff hsc_ptr 1)) cwst
{-# LINE 174 "System/CWiid.hsc" #-}
    ru <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) cwst
{-# LINE 175 "System/CWiid.hsc" #-}
    ba <- ((\hsc_ptr -> peekByteOff hsc_ptr 3)) cwst
{-# LINE 176 "System/CWiid.hsc" #-}
    bu <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) cwst
{-# LINE 177 "System/CWiid.hsc" #-}
    ac0 <- ((\hsc_ptr -> peekByteOff hsc_ptr 6)) cwst
{-# LINE 178 "System/CWiid.hsc" #-}
    ac1 <- ((\hsc_ptr -> peekByteOff hsc_ptr 7)) cwst
{-# LINE 179 "System/CWiid.hsc" #-}
    ac2 <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) cwst
{-# LINE 180 "System/CWiid.hsc" #-}
    irs <- peekArray cwiidIrSrcCount (((\hsc_ptr -> hsc_ptr `plusPtr` 10)) cwst)
{-# LINE 181 "System/CWiid.hsc" #-}
    return $ CWiidState rp l ru ba bu [ fromIntegral (ac0 :: CUChar)
                                      , fromIntegral (ac1 :: CUChar)
                                      , fromIntegral (ac2 :: CUChar)]
                                      irs

-- * Infrared

-- | Maximum number of infrared points detected.
--   By default (according to cwiid) it should be 4.
cwiidIrSrcCount :: Int
cwiidIrSrcCount :: Int
cwiidIrSrcCount = (Int
4)
{-# LINE 192 "System/CWiid.hsc" #-}

-- struct cwiid_ir_src {
-- 	char valid;
-- 	uint16_t pos[2];
-- 	int8_t size;
-- };
--
-- The following model is weaker than the counterpart in C (see above). We do
-- so in order to provide something more "natural" in Haskell, but it might
-- be better to use a more precise datatype.

-- | Internal representation of an infrared point. You should no use it
--   unless you know what you are doing; use 'CWiidIR' instead.
data CWiidIRSrc = CWiidIRSrc
  { CWiidIRSrc -> Bool
cwiidIRSrcValid :: Bool
  , CWiidIRSrc -> Int
cwiidIRSrcPosX  :: Int
  , CWiidIRSrc -> Int
cwiidIRSrcPosY  :: Int
  , CWiidIRSrc -> Int
cwiidIRSrcSize  :: Int
  }
 deriving Int -> CWiidIRSrc -> ShowS
[CWiidIRSrc] -> ShowS
CWiidIRSrc -> String
(Int -> CWiidIRSrc -> ShowS)
-> (CWiidIRSrc -> String)
-> ([CWiidIRSrc] -> ShowS)
-> Show CWiidIRSrc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidIRSrc -> ShowS
showsPrec :: Int -> CWiidIRSrc -> ShowS
$cshow :: CWiidIRSrc -> String
show :: CWiidIRSrc -> String
$cshowList :: [CWiidIRSrc] -> ShowS
showList :: [CWiidIRSrc] -> ShowS
Show

instance Storable CWiidIRSrc where
  sizeOf :: CWiidIRSrc -> Int
sizeOf = Int -> CWiidIRSrc -> Int
forall a b. a -> b -> a
const (Int
8)
{-# LINE 215 "System/CWiid.hsc" #-}
  alignment = sizeOf
  poke :: Ptr CWiidIRSrc -> CWiidIRSrc -> IO ()
poke Ptr CWiidIRSrc
cwst (CWiidIRSrc Bool
valid Int
posX Int
posY Int
sz) = do
    ((\Ptr CWiidIRSrc
hsc_ptr -> Ptr CWiidIRSrc -> Int -> CChar -> IO ()
forall b. Ptr b -> Int -> CChar -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CWiidIRSrc
hsc_ptr Int
0))  Ptr CWiidIRSrc
cwst ((if Bool
valid then (-CChar
1) else CChar
0) :: CChar)
{-# LINE 218 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) cwst (fromIntegral posX :: CUShort)
{-# LINE 219 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) cwst (fromIntegral posY :: CUShort)
{-# LINE 220 "System/CWiid.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 6))   cwst (fromIntegral sz   :: CChar)
{-# LINE 221 "System/CWiid.hsc" #-}
  peek cwst = do
    valid <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))  cwst
{-# LINE 223 "System/CWiid.hsc" #-}
    posX  <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) cwst
{-# LINE 224 "System/CWiid.hsc" #-}
    posY  <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) cwst
{-# LINE 225 "System/CWiid.hsc" #-}
    sz    <- ((\hsc_ptr -> peekByteOff hsc_ptr 6))   cwst
{-# LINE 226 "System/CWiid.hsc" #-}
    return $ CWiidIRSrc (not ((valid :: CChar) == 0))
                        (fromIntegral (posX :: CUShort))
                        (fromIntegral (posY :: CUShort))
                        (fromIntegral (sz :: CChar))

cwiidGetIR :: CWiidWiimote -> IO [CWiidIRSrc]
cwiidGetIR :: CWiidWiimote -> IO [CWiidIRSrc]
cwiidGetIR CWiidWiimote
wm = 
  (Ptr CWiidState -> IO [CWiidIRSrc]) -> IO [CWiidIRSrc]
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CWiidState -> IO [CWiidIRSrc]) -> IO [CWiidIRSrc])
-> (Ptr CWiidState -> IO [CWiidIRSrc]) -> IO [CWiidIRSrc]
forall a b. (a -> b) -> a -> b
$ \Ptr CWiidState
wiState -> do
    CInt
_ <- Ptr () -> Ptr CWiidState -> IO CInt
c_cwiid_get_state Ptr ()
handle Ptr CWiidState
wiState
    CWiidState
ws <- Ptr CWiidState -> IO CWiidState
forall a. Storable a => Ptr a -> IO a
peek Ptr CWiidState
wiState
    [CWiidIRSrc] -> IO [CWiidIRSrc]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CWiidState -> [CWiidIRSrc]
irSrc CWiidState
ws)
      where handle :: Ptr ()
handle = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm

-- * Leds
newtype CWiidLedFlag = CWiidLedFlag { CWiidLedFlag -> Int
unCWiidLedFlag :: Int }
                     deriving (CWiidLedFlag -> CWiidLedFlag -> Bool
(CWiidLedFlag -> CWiidLedFlag -> Bool)
-> (CWiidLedFlag -> CWiidLedFlag -> Bool) -> Eq CWiidLedFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CWiidLedFlag -> CWiidLedFlag -> Bool
== :: CWiidLedFlag -> CWiidLedFlag -> Bool
$c/= :: CWiidLedFlag -> CWiidLedFlag -> Bool
/= :: CWiidLedFlag -> CWiidLedFlag -> Bool
Eq, Int -> CWiidLedFlag -> ShowS
[CWiidLedFlag] -> ShowS
CWiidLedFlag -> String
(Int -> CWiidLedFlag -> ShowS)
-> (CWiidLedFlag -> String)
-> ([CWiidLedFlag] -> ShowS)
-> Show CWiidLedFlag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidLedFlag -> ShowS
showsPrec :: Int -> CWiidLedFlag -> ShowS
$cshow :: CWiidLedFlag -> String
show :: CWiidLedFlag -> String
$cshowList :: [CWiidLedFlag] -> ShowS
showList :: [CWiidLedFlag] -> ShowS
Show)

-- | Flag with exactly led 1 enabled. Use 'combineCwiidLedFlag'
--   to create flags with several leds enabled.
cwiidLed1  :: CWiidLedFlag
cwiidLed1 :: CWiidLedFlag
cwiidLed1  = Int -> CWiidLedFlag
CWiidLedFlag Int
1

{-# LINE 248 "System/CWiid.hsc" #-}

-- | Flag with exactly led 2 enabled. Use 'combineCwiidLedFlag'
--   to create flags with several leds enabled.
cwiidLed2  :: CWiidLedFlag
cwiidLed2 :: CWiidLedFlag
cwiidLed2  = Int -> CWiidLedFlag
CWiidLedFlag Int
2

{-# LINE 254 "System/CWiid.hsc" #-}

-- | Flag with exactly led 2 enabled. Use 'combineCwiidLedFlag'
--   to create flags with several leds enabled.
cwiidLed3  :: CWiidLedFlag
cwiidLed3 :: CWiidLedFlag
cwiidLed3  = Int -> CWiidLedFlag
CWiidLedFlag Int
4

{-# LINE 260 "System/CWiid.hsc" #-}

-- | Flag with exactly led 4 enabled. Use 'combineCwiidLedFlag'
--   to create flags with several leds enabled.
cwiidLed4  :: CWiidLedFlag
cwiidLed4 :: CWiidLedFlag
cwiidLed4  = Int -> CWiidLedFlag
CWiidLedFlag Int
8

{-# LINE 266 "System/CWiid.hsc" #-}

-- | Enable/disable certain leds.
--
--   Use 'cwiidLed1' .. 'cwiidLed4' together with 'combineCwiidLedFlag'
--   to create a flag with just the leds you want enabled and change
--   all at once with one operation.
cwiidSetLed :: CWiidWiimote -> CWiidLedFlag -> IO CInt
cwiidSetLed :: CWiidWiimote -> CWiidLedFlag -> IO CInt
cwiidSetLed CWiidWiimote
wm CWiidLedFlag
leds = Ptr () -> CUChar -> IO CInt
c_cwiid_set_led Ptr ()
handle CUChar
ledUChars
  where handle :: Ptr ()
handle    = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm
        ledUChars :: CUChar
ledUChars = Int -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CWiidLedFlag -> Int
unCWiidLedFlag CWiidLedFlag
leds)

-- | Combine several led flags into one led flag with those leds
--   enabled and all other leds disabled.

combineCwiidLedFlag :: [CWiidLedFlag] -> CWiidLedFlag
combineCwiidLedFlag :: [CWiidLedFlag] -> CWiidLedFlag
combineCwiidLedFlag = Int -> CWiidLedFlag
CWiidLedFlag (Int -> CWiidLedFlag)
-> ([CWiidLedFlag] -> Int) -> [CWiidLedFlag] -> CWiidLedFlag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CWiidLedFlag -> Int -> Int) -> Int -> [CWiidLedFlag] -> Int
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Int -> Int -> Int
forall a. Bits a => a -> a -> a
(.|.) (Int -> Int -> Int)
-> (CWiidLedFlag -> Int) -> CWiidLedFlag -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CWiidLedFlag -> Int
unCWiidLedFlag) Int
0

-- * Buttons

newtype CWiidBtnFlag = CWiidBtnFlag { CWiidBtnFlag -> Int
unCWiidBtnFlag :: Int }
                     deriving (CWiidBtnFlag -> CWiidBtnFlag -> Bool
(CWiidBtnFlag -> CWiidBtnFlag -> Bool)
-> (CWiidBtnFlag -> CWiidBtnFlag -> Bool) -> Eq CWiidBtnFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CWiidBtnFlag -> CWiidBtnFlag -> Bool
== :: CWiidBtnFlag -> CWiidBtnFlag -> Bool
$c/= :: CWiidBtnFlag -> CWiidBtnFlag -> Bool
/= :: CWiidBtnFlag -> CWiidBtnFlag -> Bool
Eq, Int -> CWiidBtnFlag -> ShowS
[CWiidBtnFlag] -> ShowS
CWiidBtnFlag -> String
(Int -> CWiidBtnFlag -> ShowS)
-> (CWiidBtnFlag -> String)
-> ([CWiidBtnFlag] -> ShowS)
-> Show CWiidBtnFlag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidBtnFlag -> ShowS
showsPrec :: Int -> CWiidBtnFlag -> ShowS
$cshow :: CWiidBtnFlag -> String
show :: CWiidBtnFlag -> String
$cshowList :: [CWiidBtnFlag] -> ShowS
showList :: [CWiidBtnFlag] -> ShowS
Show)
cwiidBtn2      :: CWiidBtnFlag
cwiidBtn2 :: CWiidBtnFlag
cwiidBtn2      = Int -> CWiidBtnFlag
CWiidBtnFlag Int
1
cwiidBtn1      :: CWiidBtnFlag
cwiidBtn1 :: CWiidBtnFlag
cwiidBtn1      = Int -> CWiidBtnFlag
CWiidBtnFlag Int
2
cwiidBtnB      :: CWiidBtnFlag
cwiidBtnB :: CWiidBtnFlag
cwiidBtnB      = Int -> CWiidBtnFlag
CWiidBtnFlag Int
4
cwiidBtnA      :: CWiidBtnFlag
cwiidBtnA :: CWiidBtnFlag
cwiidBtnA      = Int -> CWiidBtnFlag
CWiidBtnFlag Int
8
cwiidBtnMinus  :: CWiidBtnFlag
cwiidBtnMinus :: CWiidBtnFlag
cwiidBtnMinus  = Int -> CWiidBtnFlag
CWiidBtnFlag Int
16
cwiidBtnHome   :: CWiidBtnFlag
cwiidBtnHome :: CWiidBtnFlag
cwiidBtnHome   = Int -> CWiidBtnFlag
CWiidBtnFlag Int
128
cwiidBtnLeft   :: CWiidBtnFlag
cwiidBtnLeft :: CWiidBtnFlag
cwiidBtnLeft   = Int -> CWiidBtnFlag
CWiidBtnFlag Int
256
cwiidBtnRight  :: CWiidBtnFlag
cwiidBtnRight :: CWiidBtnFlag
cwiidBtnRight  = Int -> CWiidBtnFlag
CWiidBtnFlag Int
512
cwiidBtnDown   :: CWiidBtnFlag
cwiidBtnDown :: CWiidBtnFlag
cwiidBtnDown   = CWiidBtnFlag 1024
cwiidBtnUp     :: CWiidBtnFlag
cwiidBtnUp :: CWiidBtnFlag
cwiidBtnUp     = Int -> CWiidBtnFlag
CWiidBtnFlag Int
2048
cwiidBtnPlus   :: CWiidBtnFlag
cwiidBtnPlus :: CWiidBtnFlag
cwiidBtnPlus   = Int -> CWiidBtnFlag
CWiidBtnFlag Int
4096

{-# LINE 300 "System/CWiid.hsc" #-}

combineCwiidBtnFlag :: [CWiidBtnFlag] -> CWiidBtnFlag
combineCwiidBtnFlag = CWiidBtnFlag . foldr ((.|.) . unCWiidBtnFlag) 0

diffCwiidBtnFlag :: CWiidBtnFlag -> CWiidBtnFlag -> CWiidBtnFlag
diffCwiidBtnFlag a b = CWiidBtnFlag $ ai - (ai .&. bi)
  where ai = unCWiidBtnFlag a
        bi = unCWiidBtnFlag b

-- * Reception mode

-- | Reception modes that select which sensors/wiimote activity
-- we listen to.
newtype CWiidRptMode = CWiidRptMode { CWiidRptMode -> CUChar
unCWiidRptMode :: CUChar }
  deriving (CWiidRptMode -> CWiidRptMode -> Bool
(CWiidRptMode -> CWiidRptMode -> Bool)
-> (CWiidRptMode -> CWiidRptMode -> Bool) -> Eq CWiidRptMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CWiidRptMode -> CWiidRptMode -> Bool
== :: CWiidRptMode -> CWiidRptMode -> Bool
$c/= :: CWiidRptMode -> CWiidRptMode -> Bool
/= :: CWiidRptMode -> CWiidRptMode -> Bool
Eq, Int -> CWiidRptMode -> ShowS
[CWiidRptMode] -> ShowS
CWiidRptMode -> String
(Int -> CWiidRptMode -> ShowS)
-> (CWiidRptMode -> String)
-> ([CWiidRptMode] -> ShowS)
-> Show CWiidRptMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidRptMode -> ShowS
showsPrec :: Int -> CWiidRptMode -> ShowS
$cshow :: CWiidRptMode -> String
show :: CWiidRptMode -> String
$cshowList :: [CWiidRptMode] -> ShowS
showList :: [CWiidRptMode] -> ShowS
Show)

-- | Enable/disable reception of certain sensors.
-- Use 2 to enable buttons.
cwiidSetRptMode :: CWiidWiimote -> CUChar -> IO CInt
cwiidSetRptMode :: CWiidWiimote -> CUChar -> IO CInt
cwiidSetRptMode CWiidWiimote
wm CUChar
u = Ptr () -> CUChar -> IO CInt
c_cwiid_set_rpt_mode Ptr ()
handle CUChar
u -- set BTN
  where handle :: Ptr ()
handle = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm

-- * Rumble

cwiidSetRumble :: CWiidWiimote -> CUChar -> IO CInt
cwiidSetRumble :: CWiidWiimote -> CUChar -> IO CInt
cwiidSetRumble CWiidWiimote
wm CUChar
rm = Ptr () -> CUChar -> IO CInt
c_cwiid_set_rumble Ptr ()
handle CUChar
rm
  where handle :: Ptr ()
handle = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm

-- * Buttons

-- | Returns a mask with the buttons that are currently pushed.
cwiidGetBtnState :: CWiidWiimote -> IO CWiidBtnFlag
cwiidGetBtnState :: CWiidWiimote -> IO CWiidBtnFlag
cwiidGetBtnState CWiidWiimote
wm =
  (Ptr CWiidState -> IO CWiidBtnFlag) -> IO CWiidBtnFlag
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CWiidState -> IO CWiidBtnFlag) -> IO CWiidBtnFlag)
-> (Ptr CWiidState -> IO CWiidBtnFlag) -> IO CWiidBtnFlag
forall a b. (a -> b) -> a -> b
$ \Ptr CWiidState
wiState -> do
    CInt
_ <- Ptr () -> Ptr CWiidState -> IO CInt
c_cwiid_get_state Ptr ()
handle Ptr CWiidState
wiState
    CWiidState
ws <- Ptr CWiidState -> IO CWiidState
forall a. Storable a => Ptr a -> IO a
peek Ptr CWiidState
wiState
    CWiidBtnFlag -> IO CWiidBtnFlag
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CWiidBtnFlag -> IO CWiidBtnFlag)
-> CWiidBtnFlag -> IO CWiidBtnFlag
forall a b. (a -> b) -> a -> b
$ Int -> CWiidBtnFlag
CWiidBtnFlag (Int -> CWiidBtnFlag) -> Int -> CWiidBtnFlag
forall a b. (a -> b) -> a -> b
$ CWiidState -> Int
buttons CWiidState
ws
      where handle :: Ptr ()
handle = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm

-- | Returns 'True' if the button indicated by the flag is pushed,
-- 'False' otherwise.
-- 
-- This is a pure function, so the first argument must be the
-- button flags as returned by 'cwiidGetBtnState'. 
cwiidIsBtnPushed :: CWiidBtnFlag -- ^ The button flags as returned by 'cwiidGetBtnState'. 
                 -> CWiidBtnFlag -- ^ A mask that flags the button/s that we want to check.
                 -> Bool         -- ^ 'True' if they are all pushed, 'False' otherwise.
cwiidIsBtnPushed :: CWiidBtnFlag -> CWiidBtnFlag -> Bool
cwiidIsBtnPushed CWiidBtnFlag
flags CWiidBtnFlag
btn =
  CWiidBtnFlag -> Int
unCWiidBtnFlag CWiidBtnFlag
flags Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. CWiidBtnFlag -> Int
unCWiidBtnFlag CWiidBtnFlag
btn Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== CWiidBtnFlag -> Int
unCWiidBtnFlag CWiidBtnFlag
btn

-- * Accelerometres

-- | Array of accelerometer information. It will always contain
-- exactly three elements.
-- 
-- * TODO: provide a more informative and restrictive interface
-- with exactly three named Int (byte?) fields.
--
newtype CWiidAcc = CWiidAcc { CWiidAcc -> [Int]
unCWiidAcc :: [Int] }
 deriving (CWiidAcc -> CWiidAcc -> Bool
(CWiidAcc -> CWiidAcc -> Bool)
-> (CWiidAcc -> CWiidAcc -> Bool) -> Eq CWiidAcc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CWiidAcc -> CWiidAcc -> Bool
== :: CWiidAcc -> CWiidAcc -> Bool
$c/= :: CWiidAcc -> CWiidAcc -> Bool
/= :: CWiidAcc -> CWiidAcc -> Bool
Eq, Int -> CWiidAcc -> ShowS
[CWiidAcc] -> ShowS
CWiidAcc -> String
(Int -> CWiidAcc -> ShowS)
-> (CWiidAcc -> String) -> ([CWiidAcc] -> ShowS) -> Show CWiidAcc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CWiidAcc -> ShowS
showsPrec :: Int -> CWiidAcc -> ShowS
$cshow :: CWiidAcc -> String
show :: CWiidAcc -> String
$cshowList :: [CWiidAcc] -> ShowS
showList :: [CWiidAcc] -> ShowS
Show)

-- | Obtain accelerometer information.
--   FIXME: read wmgui/main.c:cwiid_acc(1119) to understand how to use
--   this information, what else might need to be exported, and how
--   to calibrate the accelerometers.
cwiidGetAcc :: CWiidWiimote -> IO CWiidAcc
cwiidGetAcc :: CWiidWiimote -> IO CWiidAcc
cwiidGetAcc CWiidWiimote
wm =
  (Ptr CWiidState -> IO CWiidAcc) -> IO CWiidAcc
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CWiidState -> IO CWiidAcc) -> IO CWiidAcc)
-> (Ptr CWiidState -> IO CWiidAcc) -> IO CWiidAcc
forall a b. (a -> b) -> a -> b
$ \Ptr CWiidState
wiState -> do
    CInt
_ <- Ptr () -> Ptr CWiidState -> IO CInt
c_cwiid_get_state Ptr ()
handle Ptr CWiidState
wiState
    CWiidState
ws <- Ptr CWiidState -> IO CWiidState
forall a. Storable a => Ptr a -> IO a
peek Ptr CWiidState
wiState
    CWiidAcc -> IO CWiidAcc
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CWiidAcc -> IO CWiidAcc) -> CWiidAcc -> IO CWiidAcc
forall a b. (a -> b) -> a -> b
$ [Int] -> CWiidAcc
CWiidAcc ([Int] -> CWiidAcc) -> [Int] -> CWiidAcc
forall a b. (a -> b) -> a -> b
$ CWiidState -> [Int]
acc CWiidState
ws
      where handle :: Ptr ()
handle = CWiidWiimote -> Ptr ()
unCWiidWiimote CWiidWiimote
wm
  
-- * Low-level bindings to C functions and back

-----------------------------------------------------------------------------
-- C land
---
-- Haskell => C
---

-- cwiid_wiimote_t *cwiid_open(bdaddr_t *bdaddr, int flags)
foreign import ccall safe "cwiid_open" c_cwiid_open
  :: Ptr CWiidBdaddr -> CInt -> IO (Ptr ())

-- typedef unsigned char             uint8_t
-- int cwiid_set_led(cwiid_wiimote_t *wiimote, uint8_t led)
foreign import ccall safe "cwiid_set_led" c_cwiid_set_led
  :: Ptr () -> CUChar -> IO CInt

-- int cwiid_set_rpt_mode(cwiid_wiimote_t *wiimote, uint8_t rpt_mode);
foreign import ccall safe "cwiid_set_rpt_mode" c_cwiid_set_rpt_mode
  :: Ptr () -> CUChar -> IO CInt

-- int cwiid_set_rumble(cwiid_wiimote_t *wiimote, uint8_t rumble);
foreign import ccall safe "cwiid_set_rumble" c_cwiid_set_rumble
  :: Ptr () -> CUChar -> IO CInt

-- int cwiid_get_state(cwiid_wiimote_t *wiimote, struct cwiid_state *state);
foreign import ccall safe "cwiid_get_state" c_cwiid_get_state
  :: Ptr () -> Ptr CWiidState -> IO CInt


-- C => Haskell
---

-- int cwiid_set_mesg_callback(cwiid_wiimote_t *wiimote,
--                             cwiid_mesg_callback_t *callback)
-- xxxxx
-- typedef void cwiid_mesg_callback_t(cwiid_wiimote_t *, int,
--                                    union cwiid_mesg [], struct timespec *)
-- xxxxx