tcod-haskell-0.2.0.0: src/Game/TCOD/Noise.hs
{-# LANGUAGE QuasiQuotes #-}
module Game.TCOD.Noise(
TCODNoise(..)
, TCODNoiseType(..)
, noiseMaxOctaves
, noiseMaxDimensions
, noiseDefaultHurst
, noiseDefaultLacunarity
, noiseNew
, noiseDelete
, noiseSetType
, noiseGetEx
, noiseGetFbmEx
, noiseGetTurbulenceEx
, noiseGet
, noiseGetFbm
, noiseGetTurbulence
) where
import Data.Vector.Storable (Vector)
import Foreign
import Foreign.C
import Game.TCOD.Context as C
import Game.TCOD.MersenneTypes
import GHC.Generics
import qualified Data.Vector.Storable as V
context tcodContext
verbatim "#define TCOD_SDL2"
include "libtcod/noise.h"
-- | Reference to TCOD noise object
newtype TCODNoise = TCODNoise { unTCODNoise :: Ptr () }
deriving (Eq, Ord, Show, Generic)
-- | Supported noise generator types
data TCODNoiseType =
NoiseDefault
| NoisePerlin
| NoiseSimplex
| NoiseWavelet
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic)
noiseMaxOctaves :: Int
noiseMaxOctaves = 128
noiseMaxDimensions :: Int
noiseMaxDimensions = 4
noiseDefaultHurst :: Double
noiseDefaultHurst = 0.5
noiseDefaultLacunarity :: Double
noiseDefaultLacunarity = 2.0
-- | Create a new noise object
noiseNew :: Int -- ^ Dimensions
-> Double -- ^ hurst
-> Double -- ^ lacunarity
-> TCODRandom -- ^ random number generator
-> IO TCODNoise
noiseNew d h l (TCODRandom r) = do
let d' = fromIntegral d
h' = realToFrac h
l' = realToFrac l
TCODNoise <$> [C.exp| void* { TCOD_noise_new($(int d'), $(float h'), $(float l'), $(void* r)) } |]
-- | Delete noise object
noiseDelete :: TCODNoise -> IO ()
noiseDelete (TCODNoise n) = [C.exp| void { TCOD_noise_delete($(void* n)) }|]
-- | Choosing a noise type
--
-- Use this function to define the default algorithm used by the noise functions.
-- The default algorithm is simplex. It's much faster than Perlin, especially in 4 dimensions.
-- It has a better contrast too.
noiseSetType :: TCODNoise -> TCODNoiseType -> IO ()
noiseSetType (TCODNoise n) nt = do
let nt' = fromIntegral . fromEnum $ nt
[C.exp| void { TCOD_noise_set_type($(void* n), (TCOD_noise_type_t)$(int nt')) } |]
-- | Getting flat noise
--
-- his function returns the noise function value between -1.0 and 1.0 at given coordinates.
noiseGetEx :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> TCODNoiseType -- ^ The algorithm to use. If not defined, use the default one (set with setType or simplex if not set)
-> IO Double
noiseGetEx (TCODNoise n) vf nt = V.unsafeWith (V.map realToFrac vf) $ \vf' -> do
let nt' = fromIntegral . fromEnum $ nt
realToFrac <$> [C.exp| float { TCOD_noise_get_ex($(void* n), $(float* vf'), (TCOD_noise_type_t)$(int nt')) } |]
-- | This function returns the fbm function value between -1.0 and 1.0 at given
-- coordinates, using fractal hurst and lacunarity defined when the generator has been created.
noiseGetFbmEx :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> Float -- ^ Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128
-> TCODNoiseType -- ^ The algorithm to use
-> IO Float
noiseGetFbmEx (TCODNoise n) vf o nt = V.unsafeWith (V.map realToFrac vf) $ \vf' -> do
let nt' = fromIntegral . fromEnum $ nt
o' = realToFrac o
realToFrac <$> [C.exp| float { TCOD_noise_get_fbm_ex($(void* n), $(float* vf'), $(float o'), (TCOD_noise_type_t)$(int nt')) } |]
-- | Getting turbulence
--
-- This function returns the turbulence function value between -1.0 and 1.0 at
-- given coordinates, using fractal hurst and lacunarity defined when the
-- generator has been created.
noiseGetTurbulenceEx :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> Float -- ^ Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128
-> TCODNoiseType -- ^ The algorithm to use
-> IO Float
noiseGetTurbulenceEx (TCODNoise n) vf o nt = V.unsafeWith (V.map realToFrac vf) $ \vf' -> do
let nt' = fromIntegral . fromEnum $ nt
o' = realToFrac o
realToFrac <$> [C.exp| float { TCOD_noise_get_turbulence_ex($(void* n), $(float* vf'), $(float o'), (TCOD_noise_type_t)$(int nt')) } |]
-- | Getting flat noise
--
-- his function returns the noise function value between -1.0 and 1.0 at given coordinates.
noiseGet :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> IO Double
noiseGet (TCODNoise n) vf = V.unsafeWith (V.map realToFrac vf) $ \vf' ->
realToFrac <$> [C.exp| float { TCOD_noise_get($(void* n), $(float* vf')) } |]
-- | This function returns the fbm function value between -1.0 and 1.0 at given
-- coordinates, using fractal hurst and lacunarity defined when the generator has been created.
noiseGetFbm :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> Float -- ^ Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128
-> IO Float
noiseGetFbm (TCODNoise n) vf o = V.unsafeWith (V.map realToFrac vf) $ \vf' -> do
let o' = realToFrac o
realToFrac <$> [C.exp| float { TCOD_noise_get_fbm($(void* n), $(float* vf'), $(float o')) } |]
-- | Getting turbulence
--
-- This function returns the turbulence function value between -1.0 and 1.0 at
-- given coordinates, using fractal hurst and lacunarity defined when the
-- generator has been created.
noiseGetTurbulence :: TCODNoise -- ^ the generator handler, returned by the initialization function.
-> Vector Double -- ^ An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value.
-> Float -- ^ Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128
-> IO Float
noiseGetTurbulence (TCODNoise n) vf o = V.unsafeWith (V.map realToFrac vf) $ \vf' -> do
let o' = realToFrac o
realToFrac <$> [C.exp| float { TCOD_noise_get_turbulence($(void* n), $(float* vf'), $(float o')) } |]