{-# LANGUAGE DeriveAnyClass #-}

{-# OPTIONS -Wall #-}

-- | Bindings for camera-related types
module Raylib.Types.Core.Camera
  ( -- * Enumerations
    CameraMode (..),
    CameraProjection (..),

    -- * Structures
    Camera3D (..),
    Camera2D (..),
    Camera,

    -- * Pointer utilities
    p'camera3D'position,
    p'camera3D'target,
    p'camera3D'up,
    p'camera3D'fovy,
    p'camera3D'projection,
    p'camera2D'offset,
    p'camera2D'target,
    p'camera2D'rotation,
    p'camera2D'zoom,
  )
where

import Foreign
  ( Ptr,
    Storable (alignment, peek, poke, sizeOf),
    castPtr,
    plusPtr,
  )
import Foreign.C
  ( CFloat,
    CInt (..),
  )
import Raylib.Internal.Foreign (Freeable)
import Raylib.Types.Core (Vector2, Vector3)

---------------------------------------
-- camera enums -----------------------
---------------------------------------

data CameraMode
  = CameraModeCustom
  | CameraModeFree
  | CameraModeOrbital
  | CameraModeFirstPerson
  | CameraModeThirdPerson
  deriving (Int -> CameraMode
CameraMode -> Int
CameraMode -> [CameraMode]
CameraMode -> CameraMode
CameraMode -> CameraMode -> [CameraMode]
CameraMode -> CameraMode -> CameraMode -> [CameraMode]
(CameraMode -> CameraMode)
-> (CameraMode -> CameraMode)
-> (Int -> CameraMode)
-> (CameraMode -> Int)
-> (CameraMode -> [CameraMode])
-> (CameraMode -> CameraMode -> [CameraMode])
-> (CameraMode -> CameraMode -> [CameraMode])
-> (CameraMode -> CameraMode -> CameraMode -> [CameraMode])
-> Enum CameraMode
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: CameraMode -> CameraMode
succ :: CameraMode -> CameraMode
$cpred :: CameraMode -> CameraMode
pred :: CameraMode -> CameraMode
$ctoEnum :: Int -> CameraMode
toEnum :: Int -> CameraMode
$cfromEnum :: CameraMode -> Int
fromEnum :: CameraMode -> Int
$cenumFrom :: CameraMode -> [CameraMode]
enumFrom :: CameraMode -> [CameraMode]
$cenumFromThen :: CameraMode -> CameraMode -> [CameraMode]
enumFromThen :: CameraMode -> CameraMode -> [CameraMode]
$cenumFromTo :: CameraMode -> CameraMode -> [CameraMode]
enumFromTo :: CameraMode -> CameraMode -> [CameraMode]
$cenumFromThenTo :: CameraMode -> CameraMode -> CameraMode -> [CameraMode]
enumFromThenTo :: CameraMode -> CameraMode -> CameraMode -> [CameraMode]
Enum)

data CameraProjection = CameraPerspective | CameraOrthographic deriving (CameraProjection -> CameraProjection -> Bool
(CameraProjection -> CameraProjection -> Bool)
-> (CameraProjection -> CameraProjection -> Bool)
-> Eq CameraProjection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CameraProjection -> CameraProjection -> Bool
== :: CameraProjection -> CameraProjection -> Bool
$c/= :: CameraProjection -> CameraProjection -> Bool
/= :: CameraProjection -> CameraProjection -> Bool
Eq, Int -> CameraProjection -> ShowS
[CameraProjection] -> ShowS
CameraProjection -> String
(Int -> CameraProjection -> ShowS)
-> (CameraProjection -> String)
-> ([CameraProjection] -> ShowS)
-> Show CameraProjection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CameraProjection -> ShowS
showsPrec :: Int -> CameraProjection -> ShowS
$cshow :: CameraProjection -> String
show :: CameraProjection -> String
$cshowList :: [CameraProjection] -> ShowS
showList :: [CameraProjection] -> ShowS
Show, Int -> CameraProjection
CameraProjection -> Int
CameraProjection -> [CameraProjection]
CameraProjection -> CameraProjection
CameraProjection -> CameraProjection -> [CameraProjection]
CameraProjection
-> CameraProjection -> CameraProjection -> [CameraProjection]
(CameraProjection -> CameraProjection)
-> (CameraProjection -> CameraProjection)
-> (Int -> CameraProjection)
-> (CameraProjection -> Int)
-> (CameraProjection -> [CameraProjection])
-> (CameraProjection -> CameraProjection -> [CameraProjection])
-> (CameraProjection -> CameraProjection -> [CameraProjection])
-> (CameraProjection
    -> CameraProjection -> CameraProjection -> [CameraProjection])
-> Enum CameraProjection
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: CameraProjection -> CameraProjection
succ :: CameraProjection -> CameraProjection
$cpred :: CameraProjection -> CameraProjection
pred :: CameraProjection -> CameraProjection
$ctoEnum :: Int -> CameraProjection
toEnum :: Int -> CameraProjection
$cfromEnum :: CameraProjection -> Int
fromEnum :: CameraProjection -> Int
$cenumFrom :: CameraProjection -> [CameraProjection]
enumFrom :: CameraProjection -> [CameraProjection]
$cenumFromThen :: CameraProjection -> CameraProjection -> [CameraProjection]
enumFromThen :: CameraProjection -> CameraProjection -> [CameraProjection]
$cenumFromTo :: CameraProjection -> CameraProjection -> [CameraProjection]
enumFromTo :: CameraProjection -> CameraProjection -> [CameraProjection]
$cenumFromThenTo :: CameraProjection
-> CameraProjection -> CameraProjection -> [CameraProjection]
enumFromThenTo :: CameraProjection
-> CameraProjection -> CameraProjection -> [CameraProjection]
Enum)

instance Storable CameraProjection where
  sizeOf :: CameraProjection -> Int
sizeOf CameraProjection
_ = Int
4
  alignment :: CameraProjection -> Int
alignment CameraProjection
_ = Int
4
  peek :: Ptr CameraProjection -> IO CameraProjection
peek Ptr CameraProjection
ptr = do
    CInt
val <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek (Ptr CameraProjection -> Ptr CInt
forall a b. Ptr a -> Ptr b
castPtr Ptr CameraProjection
ptr)
    CameraProjection -> IO CameraProjection
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> CameraProjection
forall a. Enum a => Int -> a
toEnum (Int -> CameraProjection) -> Int -> CameraProjection
forall a b. (a -> b) -> a -> b
$ CInt -> Int
forall a. Enum a => a -> Int
fromEnum (CInt
val :: CInt))
  poke :: Ptr CameraProjection -> CameraProjection -> IO ()
poke Ptr CameraProjection
ptr CameraProjection
v = Ptr CInt -> CInt -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr CameraProjection -> Ptr CInt
forall a b. Ptr a -> Ptr b
castPtr Ptr CameraProjection
ptr) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CameraProjection -> Int
forall a. Enum a => a -> Int
fromEnum CameraProjection
v) :: CInt)

---------------------------------------
-- camera structures ------------------
---------------------------------------

data Camera3D = Camera3D
  { Camera3D -> Vector3
camera3D'position :: Vector3,
    Camera3D -> Vector3
camera3D'target :: Vector3,
    Camera3D -> Vector3
camera3D'up :: Vector3,
    Camera3D -> Float
camera3D'fovy :: Float,
    Camera3D -> CameraProjection
camera3D'projection :: CameraProjection
  }
  deriving (Camera3D -> Camera3D -> Bool
(Camera3D -> Camera3D -> Bool)
-> (Camera3D -> Camera3D -> Bool) -> Eq Camera3D
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Camera3D -> Camera3D -> Bool
== :: Camera3D -> Camera3D -> Bool
$c/= :: Camera3D -> Camera3D -> Bool
/= :: Camera3D -> Camera3D -> Bool
Eq, Int -> Camera3D -> ShowS
[Camera3D] -> ShowS
Camera3D -> String
(Int -> Camera3D -> ShowS)
-> (Camera3D -> String) -> ([Camera3D] -> ShowS) -> Show Camera3D
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Camera3D -> ShowS
showsPrec :: Int -> Camera3D -> ShowS
$cshow :: Camera3D -> String
show :: Camera3D -> String
$cshowList :: [Camera3D] -> ShowS
showList :: [Camera3D] -> ShowS
Show, Camera3D -> Ptr Camera3D -> IO ()
(Camera3D -> Ptr Camera3D -> IO ())
-> (Camera3D -> Ptr Camera3D -> IO ()) -> Freeable Camera3D
forall a.
(a -> Ptr a -> IO ()) -> (a -> Ptr a -> IO ()) -> Freeable a
$crlFreeDependents :: Camera3D -> Ptr Camera3D -> IO ()
rlFreeDependents :: Camera3D -> Ptr Camera3D -> IO ()
$crlFree :: Camera3D -> Ptr Camera3D -> IO ()
rlFree :: Camera3D -> Ptr Camera3D -> IO ()
Freeable)

instance Storable Camera3D where
  sizeOf :: Camera3D -> Int
sizeOf Camera3D
_ = Int
44
  alignment :: Camera3D -> Int
alignment Camera3D
_ = Int
4
  peek :: Ptr Camera3D -> IO Camera3D
peek Ptr Camera3D
_p = do
    Vector3
position <- Ptr Vector3 -> IO Vector3
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera3D -> Ptr Vector3
p'camera3D'position Ptr Camera3D
_p)
    Vector3
target <- Ptr Vector3 -> IO Vector3
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera3D -> Ptr Vector3
p'camera3D'target Ptr Camera3D
_p)
    Vector3
up <- Ptr Vector3 -> IO Vector3
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera3D -> Ptr Vector3
p'camera3D'up Ptr Camera3D
_p)
    Float
fovy <- CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (CFloat -> Float) -> IO CFloat -> IO Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFloat -> IO CFloat
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera3D -> Ptr CFloat
p'camera3D'fovy Ptr Camera3D
_p)
    CameraProjection
projection <- Ptr CameraProjection -> IO CameraProjection
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera3D -> Ptr CameraProjection
p'camera3D'projection Ptr Camera3D
_p)
    Camera3D -> IO Camera3D
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Camera3D -> IO Camera3D) -> Camera3D -> IO Camera3D
forall a b. (a -> b) -> a -> b
$ Vector3
-> Vector3 -> Vector3 -> Float -> CameraProjection -> Camera3D
Camera3D Vector3
position Vector3
target Vector3
up Float
fovy CameraProjection
projection
  poke :: Ptr Camera3D -> Camera3D -> IO ()
poke Ptr Camera3D
_p (Camera3D Vector3
position Vector3
target Vector3
up Float
fovy CameraProjection
projection) = do
    Ptr Vector3 -> Vector3 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera3D -> Ptr Vector3
p'camera3D'position Ptr Camera3D
_p) Vector3
position
    Ptr Vector3 -> Vector3 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera3D -> Ptr Vector3
p'camera3D'target Ptr Camera3D
_p) Vector3
target
    Ptr Vector3 -> Vector3 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera3D -> Ptr Vector3
p'camera3D'up Ptr Camera3D
_p) Vector3
up
    Ptr CFloat -> CFloat -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera3D -> Ptr CFloat
p'camera3D'fovy Ptr Camera3D
_p) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fovy)
    Ptr CameraProjection -> CameraProjection -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera3D -> Ptr CameraProjection
p'camera3D'projection Ptr Camera3D
_p) CameraProjection
projection
    () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

p'camera3D'position :: Ptr Camera3D -> Ptr Vector3
p'camera3D'position :: Ptr Camera3D -> Ptr Vector3
p'camera3D'position = (Ptr Camera3D -> Int -> Ptr Vector3
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
0)

p'camera3D'target :: Ptr Camera3D -> Ptr Vector3
p'camera3D'target :: Ptr Camera3D -> Ptr Vector3
p'camera3D'target = (Ptr Camera3D -> Int -> Ptr Vector3
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
12)

p'camera3D'up :: Ptr Camera3D -> Ptr Vector3
p'camera3D'up :: Ptr Camera3D -> Ptr Vector3
p'camera3D'up = (Ptr Camera3D -> Int -> Ptr Vector3
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
24)

p'camera3D'fovy :: Ptr Camera3D -> Ptr CFloat
p'camera3D'fovy :: Ptr Camera3D -> Ptr CFloat
p'camera3D'fovy = (Ptr Camera3D -> Int -> Ptr CFloat
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
36)

p'camera3D'projection :: Ptr Camera3D -> Ptr CameraProjection
p'camera3D'projection :: Ptr Camera3D -> Ptr CameraProjection
p'camera3D'projection = (Ptr Camera3D -> Int -> Ptr CameraProjection
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
40)

type Camera = Camera3D

data Camera2D = Camera2D
  { Camera2D -> Vector2
camera2D'offset :: Vector2,
    Camera2D -> Vector2
camera2D'target :: Vector2,
    Camera2D -> Float
camera2D'rotation :: Float,
    Camera2D -> Float
camera2D'zoom :: Float
  }
  deriving (Camera2D -> Camera2D -> Bool
(Camera2D -> Camera2D -> Bool)
-> (Camera2D -> Camera2D -> Bool) -> Eq Camera2D
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Camera2D -> Camera2D -> Bool
== :: Camera2D -> Camera2D -> Bool
$c/= :: Camera2D -> Camera2D -> Bool
/= :: Camera2D -> Camera2D -> Bool
Eq, Int -> Camera2D -> ShowS
[Camera2D] -> ShowS
Camera2D -> String
(Int -> Camera2D -> ShowS)
-> (Camera2D -> String) -> ([Camera2D] -> ShowS) -> Show Camera2D
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Camera2D -> ShowS
showsPrec :: Int -> Camera2D -> ShowS
$cshow :: Camera2D -> String
show :: Camera2D -> String
$cshowList :: [Camera2D] -> ShowS
showList :: [Camera2D] -> ShowS
Show, Camera2D -> Ptr Camera2D -> IO ()
(Camera2D -> Ptr Camera2D -> IO ())
-> (Camera2D -> Ptr Camera2D -> IO ()) -> Freeable Camera2D
forall a.
(a -> Ptr a -> IO ()) -> (a -> Ptr a -> IO ()) -> Freeable a
$crlFreeDependents :: Camera2D -> Ptr Camera2D -> IO ()
rlFreeDependents :: Camera2D -> Ptr Camera2D -> IO ()
$crlFree :: Camera2D -> Ptr Camera2D -> IO ()
rlFree :: Camera2D -> Ptr Camera2D -> IO ()
Freeable)

instance Storable Camera2D where
  sizeOf :: Camera2D -> Int
sizeOf Camera2D
_ = Int
24
  alignment :: Camera2D -> Int
alignment Camera2D
_ = Int
4
  peek :: Ptr Camera2D -> IO Camera2D
peek Ptr Camera2D
_p = do
    Vector2
offset <- Ptr Vector2 -> IO Vector2
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera2D -> Ptr Vector2
p'camera2D'offset Ptr Camera2D
_p)
    Vector2
target <- Ptr Vector2 -> IO Vector2
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera2D -> Ptr Vector2
p'camera2D'target Ptr Camera2D
_p)
    Float
rotation <- CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (CFloat -> Float) -> IO CFloat -> IO Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFloat -> IO CFloat
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera2D -> Ptr CFloat
p'camera2D'rotation Ptr Camera2D
_p)
    Float
zoom <- CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (CFloat -> Float) -> IO CFloat -> IO Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CFloat -> IO CFloat
forall a. Storable a => Ptr a -> IO a
peek (Ptr Camera2D -> Ptr CFloat
p'camera2D'zoom Ptr Camera2D
_p)
    Camera2D -> IO Camera2D
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Camera2D -> IO Camera2D) -> Camera2D -> IO Camera2D
forall a b. (a -> b) -> a -> b
$ Vector2 -> Vector2 -> Float -> Float -> Camera2D
Camera2D Vector2
offset Vector2
target Float
rotation Float
zoom
  poke :: Ptr Camera2D -> Camera2D -> IO ()
poke Ptr Camera2D
_p (Camera2D Vector2
offset Vector2
target Float
rotation Float
zoom) = do
    Ptr Vector2 -> Vector2 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera2D -> Ptr Vector2
p'camera2D'offset Ptr Camera2D
_p) Vector2
offset
    Ptr Vector2 -> Vector2 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera2D -> Ptr Vector2
p'camera2D'target Ptr Camera2D
_p) Vector2
target
    Ptr CFloat -> CFloat -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera2D -> Ptr CFloat
p'camera2D'rotation Ptr Camera2D
_p) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
rotation)
    Ptr CFloat -> CFloat -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Camera2D -> Ptr CFloat
p'camera2D'zoom Ptr Camera2D
_p) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
zoom)
    () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

p'camera2D'offset :: Ptr Camera2D -> Ptr Vector2
p'camera2D'offset :: Ptr Camera2D -> Ptr Vector2
p'camera2D'offset = (Ptr Camera2D -> Int -> Ptr Vector2
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
0)

p'camera2D'target :: Ptr Camera2D -> Ptr Vector2
p'camera2D'target :: Ptr Camera2D -> Ptr Vector2
p'camera2D'target = (Ptr Camera2D -> Int -> Ptr Vector2
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
8)

p'camera2D'rotation :: Ptr Camera2D -> Ptr CFloat
p'camera2D'rotation :: Ptr Camera2D -> Ptr CFloat
p'camera2D'rotation = (Ptr Camera2D -> Int -> Ptr CFloat
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
16)

p'camera2D'zoom :: Ptr Camera2D -> Ptr CFloat
p'camera2D'zoom :: Ptr Camera2D -> Ptr CFloat
p'camera2D'zoom = (Ptr Camera2D -> Int -> Ptr CFloat
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
20)