{-# OPTIONS_HADDOCK hide #-}
{- | 
This FunGEn module contains some auxiliary functions.
-}
{- 

FunGEN - Functional Game Engine
http://www.cin.ufpe.br/~haskell/fungen
Copyright (C) 2002  Andre Furtado <awbf@cin.ufpe.br>

This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

-}

module Graphics.UI.Fungen.Util (
        texCoord2, vertex3, texStuff,
        toRad,
        randInt, randFloat, randDouble,
        shiftLeft, toDecimal, pow2, toBinary, make0, dropGLsizei,
        ord2,
        addNoInvisibility,
        racMod,
        matrixToList, matrixSize, 
        inv2color3, pathAndInv2color3List, point2DtoVertex3,
        isEmpty,
        when, unless,
        bindTexture,
        tracewith, strace, ltrace, mtrace
) where

import Graphics.UI.Fungen.Types
import Graphics.Rendering.OpenGL
import System.Random

-- debug helpers
import Debug.Trace (trace)
-- | trace an expression using a custom show function
tracewith :: (a -> String) -> a -> a
tracewith a -> String
f a
e = forall a. String -> a -> a
trace (a -> String
f a
e) a
e
-- | trace a showable expression
strace :: Show a => a -> a
strace :: forall a. Show a => a -> a
strace = forall {a}. (a -> String) -> a -> a
tracewith forall a. Show a => a -> String
show
-- | labelled trace - like strace, with a label prepended
ltrace :: Show a => String -> a -> a
ltrace :: forall a. Show a => String -> a -> a
ltrace String
l a
a = forall a. String -> a -> a
trace (String
l forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
a) a
a
-- | monadic trace - like strace, but works as a standalone line in a monad
mtrace :: (Monad m, Show a) => a -> m a
mtrace :: forall (m :: * -> *) a. (Monad m, Show a) => a -> m a
mtrace a
a = forall a. Show a => a -> a
strace a
a seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Monad m => a -> m a
return a
a
--

texCoord2 :: GLdouble -> GLdouble -> IO ()
texCoord2 :: GLdouble -> GLdouble -> IO ()
texCoord2 GLdouble
x GLdouble
y = forall a. TexCoord a => a -> IO ()
texCoord (forall a. a -> a -> TexCoord2 a
TexCoord2 GLdouble
x GLdouble
y)

vertex3 :: GLdouble -> GLdouble -> GLdouble -> IO ()
vertex3 :: GLdouble -> GLdouble -> GLdouble -> IO ()
vertex3 GLdouble
x GLdouble
y GLdouble
z = forall a. Vertex a => a -> IO ()
vertex (forall a. a -> a -> a -> Vertex3 a
Vertex3 GLdouble
x GLdouble
y GLdouble
z)

bindTexture :: TextureTarget2D -> TextureObject -> IO ()
bindTexture :: TextureTarget2D -> TextureObject -> IO ()
bindTexture TextureTarget2D
tt TextureObject
to = forall t.
BindableTextureTarget t =>
t -> StateVar (Maybe TextureObject)
textureBinding TextureTarget2D
tt forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
$= forall a. a -> Maybe a
Just TextureObject
to

texStuff :: [TextureObject] -> [AwbfBitmap] -> IO ()
texStuff :: [TextureObject] -> [AwbfBitmap] -> IO ()
texStuff [] [AwbfBitmap]
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()
texStuff (TextureObject
t:[TextureObject]
ts) ((GLsizei
bmW,GLsizei
bmH,PixelData GLubyte
bmData):[AwbfBitmap]
bms) = do
        TextureTarget2D -> TextureObject -> IO ()
bindTexture TextureTarget2D
Texture2D TextureObject
t
        forall t a.
TwoDimensionalTextureTarget t =>
t
-> Proxy
-> GLsizei
-> PixelInternalFormat
-> TextureSize2D
-> GLsizei
-> PixelData a
-> IO ()
texImage2D TextureTarget2D
Texture2D Proxy
NoProxy GLsizei
0 PixelInternalFormat
RGBA' (GLsizei -> GLsizei -> TextureSize2D
TextureSize2D GLsizei
bmW GLsizei
bmH) GLsizei
0 PixelData GLubyte
bmData
        forall t.
ParameterizedTextureTarget t =>
t -> StateVar (MinificationFilter, MagnificationFilter)
textureFilter TextureTarget2D
Texture2D forall t a (m :: * -> *).
(HasSetter t a, MonadIO m) =>
t -> a -> m ()
$= ((MagnificationFilter
Nearest, forall a. Maybe a
Nothing), MagnificationFilter
Nearest)
        [TextureObject] -> [AwbfBitmap] -> IO ()
texStuff [TextureObject]
ts [AwbfBitmap]
bms
texStuff [TextureObject]
_ [AwbfBitmap]
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()

toRad :: Float -> Float
toRad :: Float -> Float
toRad Float
a = ((forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Float
a)forall a. Fractional a => a -> a -> a
/Float
180)

randInt :: (Int,Int) -> IO Int
randInt :: (Int, Int) -> IO Int
randInt (Int
a,Int
b) = forall a (m :: * -> *). (Random a, MonadIO m) => (a, a) -> m a
randomRIO (Int
a,Int
b)

randFloat :: (Float,Float) -> IO Float
randFloat :: (Float, Float) -> IO Float
randFloat (Float
a,Float
b) = forall a (m :: * -> *). (Random a, MonadIO m) => (a, a) -> m a
randomRIO (Float
a,Float
b)

randDouble :: (Double,Double) -> IO Double
randDouble :: (GLdouble, GLdouble) -> IO GLdouble
randDouble (GLdouble
a,GLdouble
b) = forall a (m :: * -> *). (Random a, MonadIO m) => (a, a) -> m a
randomRIO (GLdouble
a,GLdouble
b)

shiftLeft :: String -> Int -> String
shiftLeft :: String -> Int -> String
shiftLeft String
a Int
0 = String
a
shiftLeft (Char
_:String
as) Int
n = String -> Int -> String
shiftLeft(String
as forall a. [a] -> [a] -> [a]
++ String
"0") (Int
nforall a. Num a => a -> a -> a
-Int
1)
shiftLeft String
_ Int
_ = []

toDecimal :: String -> GLsizei
toDecimal :: String -> GLsizei
toDecimal String
a = String -> GLsizei -> GLsizei
toDecimalAux (forall a. [a] -> [a]
reverse String
a) GLsizei
32

toDecimalAux :: String -> GLsizei -> GLsizei
toDecimalAux :: String -> GLsizei -> GLsizei
toDecimalAux [] GLsizei
_ = GLsizei
0
toDecimalAux String
_ GLsizei
0 = GLsizei
0
toDecimalAux (Char
a:String
as) GLsizei
n
                | Char
a forall a. Eq a => a -> a -> Bool
== Char
'0' = String -> GLsizei -> GLsizei
toDecimalAux String
as (GLsizei
nforall a. Num a => a -> a -> a
-GLsizei
1)
                | Bool
otherwise = GLsizei -> GLsizei
pow2 (GLsizei
32 forall a. Num a => a -> a -> a
- GLsizei
n) forall a. Num a => a -> a -> a
+ String -> GLsizei -> GLsizei
toDecimalAux String
as (GLsizei
nforall a. Num a => a -> a -> a
-GLsizei
1)
                
pow2 :: GLsizei -> GLsizei
pow2 :: GLsizei -> GLsizei
pow2 GLsizei
0 = GLsizei
1
pow2 GLsizei
n = GLsizei
2 forall a. Num a => a -> a -> a
* GLsizei -> GLsizei
pow2(GLsizei
nforall a. Num a => a -> a -> a
-GLsizei
1)

toBinary :: Int -> String
toBinary :: Int -> String
toBinary Int
n
        | Int
n forall a. Ord a => a -> a -> Bool
< Int
2 = forall a. Show a => a -> String
show Int
n
        | Bool
otherwise = Int -> String
toBinary (Int
n forall a. Integral a => a -> a -> a
`div` Int
2) forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show (Int
n forall a. Integral a => a -> a -> a
`mod` Int
2))
        
make0 :: Int -> String
make0 :: Int -> String
make0 Int
0 = []
make0 Int
n = Char
'0'forall a. a -> [a] -> [a]
:(Int -> String
make0 (Int
nforall a. Num a => a -> a -> a
-Int
1))

ord2 :: Char -> GLubyte
ord2 :: Char -> GLubyte
ord2 Char
a = (forall a. Enum a => Int -> a
toEnumforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Enum a => a -> Int
fromEnum) Char
a

dropGLsizei                :: GLsizei -> [a] -> [a]
dropGLsizei :: forall a. GLsizei -> [a] -> [a]
dropGLsizei GLsizei
0 [a]
xs            = [a]
xs
dropGLsizei GLsizei
_ []            = []
dropGLsizei GLsizei
n (a
_:[a]
xs) | GLsizei
nforall a. Ord a => a -> a -> Bool
>GLsizei
0  = forall a. GLsizei -> [a] -> [a]
dropGLsizei (GLsizei
nforall a. Num a => a -> a -> a
-GLsizei
1) [a]
xs
dropGLsizei GLsizei
_ [a]
_ = forall a. HasCallStack => String -> a
error String
"Util.dropGLsizei error: negative argument"

-- | to be used when no invisibility must be added when loading a file
addNoInvisibility :: [FilePath] -> [(FilePath, Maybe ColorList3)]
addNoInvisibility :: [String] -> [(String, Maybe ColorList3)]
addNoInvisibility [] = []
addNoInvisibility (String
a:[String]
as) = (String
a, forall a. Maybe a
Nothing)forall a. a -> [a] -> [a]
:([String] -> [(String, Maybe ColorList3)]
addNoInvisibility [String]
as)

racMod :: GLdouble -> GLdouble -> GLdouble
racMod :: GLdouble -> GLdouble -> GLdouble
racMod GLdouble
a GLdouble
b | (GLdouble
a forall a. Ord a => a -> a -> Bool
>= GLdouble
0) = GLdouble -> GLdouble -> GLdouble
racModPos GLdouble
a GLdouble
b
           | Bool
otherwise = GLdouble -> GLdouble -> GLdouble
racModNeg GLdouble
a GLdouble
b

racModPos :: GLdouble -> GLdouble -> GLdouble
racModPos :: GLdouble -> GLdouble -> GLdouble
racModPos GLdouble
a GLdouble
b | (GLdouble
a forall a. Num a => a -> a -> a
- GLdouble
b forall a. Ord a => a -> a -> Bool
< GLdouble
0) = GLdouble
a
              | Bool
otherwise = GLdouble -> GLdouble -> GLdouble
racModPos (GLdouble
a forall a. Num a => a -> a -> a
- GLdouble
b) GLdouble
b

racModNeg :: GLdouble -> GLdouble -> GLdouble
racModNeg :: GLdouble -> GLdouble -> GLdouble
racModNeg GLdouble
a GLdouble
b | (GLdouble
a forall a. Num a => a -> a -> a
+ GLdouble
b forall a. Ord a => a -> a -> Bool
> GLdouble
0) = GLdouble
a
              | Bool
otherwise = GLdouble -> GLdouble -> GLdouble
racModPos (GLdouble
a forall a. Num a => a -> a -> a
+ GLdouble
b) GLdouble
b

matrixToList :: [[a]] -> [a]
matrixToList :: forall a. [[a]] -> [a]
matrixToList [] = []
matrixToList ([a]
a:[[a]]
as) = [a]
a forall a. [a] -> [a] -> [a]
++ (forall a. [[a]] -> [a]
matrixToList [[a]]
as)

-- | return the max indexes of a matrix (assumed that its lines have the same length)
matrixSize ::  [[a]] -> (Int,Int)
matrixSize :: forall a. [[a]] -> (Int, Int)
matrixSize [] = (Int
0,Int
0)
matrixSize m :: [[a]]
m@([a]
a:[[a]]
_) = ((forall (t :: * -> *) a. Foldable t => t a -> Int
length [[a]]
m) forall a. Num a => a -> a -> a
- Int
1,(forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
a) forall a. Num a => a -> a -> a
- Int
1)

inv2color3 :: InvList -> Maybe ColorList3
inv2color3 :: InvList -> Maybe ColorList3
inv2color3 InvList
Nothing = forall a. Maybe a
Nothing
inv2color3 (Just [(Int, Int, Int)]
l) = forall a. a -> Maybe a
Just ([(Int, Int, Int)] -> ColorList3
inv2color3Aux [(Int, Int, Int)]
l)

inv2color3Aux :: [(Int,Int,Int)] -> [(GLubyte,GLubyte,GLubyte)]
inv2color3Aux :: [(Int, Int, Int)] -> ColorList3
inv2color3Aux [] = []
inv2color3Aux ((Int
r,Int
g,Int
b):[(Int, Int, Int)]
ls) = (Int -> GLubyte
z Int
r,Int -> GLubyte
z Int
g,Int -> GLubyte
z Int
b)forall a. a -> [a] -> [a]
:([(Int, Int, Int)] -> ColorList3
inv2color3Aux [(Int, Int, Int)]
ls)
                 where z :: Int -> GLubyte
z = forall a. Enum a => Int -> a
toEnumforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Enum a => a -> Int
fromEnum

pathAndInv2color3List :: (FilePath,InvList) -> (FilePath, Maybe ColorList3)
pathAndInv2color3List :: (String, InvList) -> (String, Maybe ColorList3)
pathAndInv2color3List (String
f,InvList
Nothing) = (String
f,forall a. Maybe a
Nothing)
pathAndInv2color3List (String
f,Just [(Int, Int, Int)]
l) = (String
f,forall a. a -> Maybe a
Just ([(Int, Int, Int)] -> ColorList3
inv2color3Aux [(Int, Int, Int)]
l))

point2DtoVertex3 :: [Point2D] -> [Vertex3 GLdouble]
point2DtoVertex3 :: [(GLdouble, GLdouble)] -> [Vertex3 GLdouble]
point2DtoVertex3 [] = []
point2DtoVertex3 ((GLdouble
x,GLdouble
y):[(GLdouble, GLdouble)]
as) = (forall a. a -> a -> a -> Vertex3 a
Vertex3 GLdouble
x GLdouble
y GLdouble
0.0)forall a. a -> [a] -> [a]
:([(GLdouble, GLdouble)] -> [Vertex3 GLdouble]
point2DtoVertex3 [(GLdouble, GLdouble)]
as)

isEmpty :: [a] -> Bool
isEmpty :: forall a. [a] -> Bool
isEmpty [] = Bool
True
isEmpty [a]
_ = Bool
False

when         :: (Monad m) => Bool -> m () -> m ()
when :: forall (m :: * -> *). Monad m => Bool -> m () -> m ()
when Bool
p m ()
s      = if Bool
p then m ()
s else forall (m :: * -> *) a. Monad m => a -> m a
return ()

unless       :: (Monad m) => Bool -> m () -> m ()
unless :: forall (m :: * -> *). Monad m => Bool -> m () -> m ()
unless Bool
p m ()
s    = forall (m :: * -> *). Monad m => Bool -> m () -> m ()
when (Bool -> Bool
not Bool
p) m ()
s