aeson-tiled-0.0.2.0: src/Data/Tiled/GID.hs
{- | Global Tile IDs
https://doc.mapeditor.org/en/latest/reference/global-tile-ids/
-}
module Data.Tiled.GID where
import Data.Aeson (FromJSON(..), ToJSON(..))
import Data.Bits (Bits(..), (.&.))
import Data.Bool (bool)
import Data.Word (Word32)
import Foreign (Storable(..))
import GHC.Generics (Generic)
newtype GID = GID { getGID :: Word32 }
deriving (Eq, Show, Generic)
deriving newtype (FromJSON, ToJSON, Storable, Bits)
pattern FLIPPED_HORIZONTALLY_BIT :: Int
pattern FLIPPED_HORIZONTALLY_BIT = 32
pattern FLIPPED_VERTICALLY_BIT :: Int
pattern FLIPPED_VERTICALLY_BIT = 31
pattern ROTATED_60_BIT :: Int
pattern ROTATED_60_BIT = 30
pattern ROTATED_120_BIT :: Int
pattern ROTATED_120_BIT = 29
data Flags = Flags
{ flippedHorizontally :: Bool
, flippedVertically :: Bool
, rotated60 :: Bool
, rotated120 :: Bool
} deriving (Eq, Show, Generic)
flags :: GID -> Flags
flags (GID bits) = Flags
{ flippedHorizontally = testBit bits FLIPPED_HORIZONTALLY_BIT
, flippedVertically = testBit bits FLIPPED_VERTICALLY_BIT
, rotated60 = testBit bits ROTATED_60_BIT
, rotated120 = testBit bits ROTATED_120_BIT
}
flagBits :: Word32
flagBits =
bit FLIPPED_HORIZONTALLY_BIT .|.
bit FLIPPED_VERTICALLY_BIT .|.
bit ROTATED_60_BIT .|.
bit ROTATED_120_BIT
toLocal :: GID -> Int
toLocal (GID bits) = fromIntegral $ bits .&. complement flagBits
fromLocal :: Flags -> Int -> GID
fromLocal Flags{..} localId =
GID . fromIntegral $
localId
.|. bool 0 FLIPPED_HORIZONTALLY_BIT flippedHorizontally
.|. bool 0 FLIPPED_VERTICALLY_BIT flippedVertically
.|. bool 0 ROTATED_60_BIT rotated60
.|. bool 0 ROTATED_120_BIT rotated120