switch-0.1.0.0: src/Device/Nintendo/Switch/Utils.hs
module Device.Nintendo.Switch.Utils where
-- attoparsec
import Data.Attoparsec.ByteString (Parser, anyWord8)
-- base
import Data.Bits ((.|.), (.&.), Bits, shiftL)
import Data.Word (Word8)
checkMask :: (Bits a, Eq a) => a -> a -> Bool
checkMask mask value =
mask .&. value == mask
clamp :: Ord a => a -> a -> a -> a
clamp low high value
| value <= low = low
| value >= high = high
| otherwise = value
combine :: Word8 -> Word8 -> Word8
combine high low =
shiftL high 4 .|. low
pairs :: [a] -> [(a,a)]
pairs (x:y:rest) = (x,y) : pairs rest
pairs _ = []
discretize :: (Real a, Integral b) => a -> a -> b -> b -> a -> b
discretize srcMin srcMax tgtMin tgtMax value
| value <= srcMin = tgtMin
| value >= srcMax = tgtMax
| otherwise = round $ fromIntegral tgtMin + frac * fromIntegral (tgtMax - tgtMin)
where
frac = (realToFrac (value - srcMin) / realToFrac (srcMax - srcMin)) :: Float
tripleZipWith :: (a -> b -> c) -> (a, a, a) -> (b, b, b) -> (c, c, c)
tripleZipWith f (a1, a2, a3) (b1, b2, b3) = (f a1 b1, f a2 b2, f a3 b3)
tripleMap :: (a -> b) -> (a, a, a) -> (b, b, b)
tripleMap f (a1, a2, a3) = (f a1, f a2, f a3)
littleEndianWord16Parser :: (Bits a, Num a) => Parser a
littleEndianWord16Parser = do
byte0 <- fromIntegral <$> anyWord8
byte1 <- fromIntegral <$> anyWord8
pure $ shiftL byte1 8 .|. byte0
tripleParser :: (Bits a, Num a) => Parser (a, a, a)
tripleParser = do
x <- littleEndianWord16Parser
y <- littleEndianWord16Parser
z <- littleEndianWord16Parser
pure (x, y, z)