module Rattletrap.Decode.CompressedWord ( decodeCompressedWordBits ) where import Rattletrap.Decode.Common import Rattletrap.Type.CompressedWord import qualified Data.Bits as Bits decodeCompressedWordBits :: Word -> DecodeBits CompressedWord decodeCompressedWordBits limit = CompressedWord limit <$> step limit (getMaxBits limit) 0 0 getMaxBits :: Word -> Word getMaxBits x = do let n :: Word n = max 1 (ceiling (logBase (2 :: Double) (fromIntegral (max 1 x)))) if x < 1024 && x == 2 ^ n then n + 1 else n step :: Word -> Word -> Word -> Word -> DecodeBits Word step limit maxBits position value = do let x = Bits.shiftL 1 (fromIntegral position) :: Word if position < maxBits && value + x <= limit then do bit <- getBool let newValue = if bit then value + x else value step limit maxBits (position + 1) newValue else pure value