tcod-haskell-0.2.0.0: src/Game/TCOD/ConsoleTypes.hsc
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CPP #-}
module Game.TCOD.ConsoleTypes(
TCODConsole(..)
, TCODKeyCode(..)
, TCODKey(..)
, defaultTCODKey
, tcodKeyTextSize
, TCODChar(..)
, TCODColorControl(..)
, TCODBackgroundFlag(..)
, TCODKeyStatus(..)
, TCODFontFlag(..)
, combineFontFlags
, TCODRenderer(..)
, TCODAlignment(..)
) where
import Data.Bits
import Data.Char
import Data.Maybe
import Foreign
import Foreign.C
import GHC.Generics
import Game.TCOD.Context as C
import qualified Data.Foldable as F
context tcodContext
#include "libtcod/console_types.h"
include "libtcod/console_types.h"
include "string.h"
-- | Tag to track pointer to `TCOD_console_t`
newtype TCODConsole = TCODConsole { unTCODConsole :: Ptr () }
deriving (Eq, Ord, Show, Generic)
-- | Names for keyboard keys
data TCODKeyCode =
KeyNone
| KeyEscape
| KeyBackspace
| KeyTab
| KeyEnter
| KeyShift
| KeyControl
| KeyAlt
| KeyPause
| KeyCapslock
| KeyPageUp
| KeyPageDown
| KeyEnd
| KeyHome
| KeyUp
| KeyLeft
| KeyRight
| KeyDown
| KeyPrintScreen
| KeyInsert
| KeyDelete
| KeyLWin
| KeyRWin
| KeyApps
| Key0
| Key1
| Key2
| Key3
| Key4
| Key5
| Key6
| Key7
| Key8
| Key9
| KeyKp0
| KeyKp1
| KeyKp2
| KeyKp3
| KeyKp4
| KeyKp5
| KeyKp6
| KeyKp7
| KeyKp8
| KeyKp9
| KeyKpAdd
| KeyKpSub
| KeyKpDiv
| KeyKpMul
| KeyKpDec
| KeyKpEnter
| KeyF1
| KeyF2
| KeyF3
| KeyF4
| KeyF5
| KeyF6
| KeyF7
| KeyF8
| KeyF9
| KeyF10
| KeyF11
| KeyF12
| KeyNumLock
| KeyScrollLock
| KeySpace
| KeyChar
| KeyText
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic)
tcodKeyTextSize :: Int
tcodKeyTextSize = 32
-- | Key data: special code or character or text
data TCODKey = TCODKey {
keyCode :: !TCODKeyCode
, keyChar :: !(Maybe Char) -- Just if keyCode == KeyChar
, keyText :: !(Maybe String) -- Just if keyCode == KeyText
, keyPressed :: !Bool -- ^ does this correspond to a key press or key release event ?
, keyLAlt :: !Bool
, keyLCtrl :: !Bool
, keyLMeta :: !Bool
, keyRAlt :: !Bool
, keyRCtrl :: !Bool
, keyRMeta :: !Bool
, keyShift :: !Bool
} deriving (Eq, Show, Generic)
-- | Get 'TCODKey' with default values
defaultTCODKey :: TCODKey
defaultTCODKey = TCODKey {
keyCode = KeyNone
, keyChar = Nothing
, keyText = Nothing
, keyPressed = False
, keyLAlt = False
, keyLCtrl = False
, keyLMeta = False
, keyRAlt = False
, keyRCtrl = False
, keyRMeta = False
, keyShift = False
}
instance Storable TCODKey where
sizeOf _ = #{size TCOD_key_t}
alignment _ = #{alignment TCOD_key_t}
poke p TCODKey{..} = withCString (take (tcodKeyTextSize-1) $ fromMaybe "" keyText) $ \text' -> do
#{poke TCOD_key_t, vk} p ((fromIntegral :: Int -> CInt) . fromEnum $ keyCode)
#{poke TCOD_key_t, c} p ((fromIntegral :: Int -> CChar) . fromMaybe 0 . fmap ord $ keyChar)
[C.exp| void { strcpy(&(((TCOD_key_t*)$(void* p'))->text[0]), $(const char* text')) } |]
#{poke TCOD_key_t, pressed} p keyPressed
#{poke TCOD_key_t, lalt} p keyLAlt
#{poke TCOD_key_t, lctrl} p keyLCtrl
#{poke TCOD_key_t, lmeta} p keyLMeta
#{poke TCOD_key_t, ralt} p keyRAlt
#{poke TCOD_key_t, rctrl} p keyRCtrl
#{poke TCOD_key_t, rmeta} p keyRMeta
#{poke TCOD_key_t, shift} p keyShift
where p' = castPtr p
peek p = do
let p' = castPtr p
kcode <- toEnum . (fromIntegral :: CInt -> Int) <$> #{peek TCOD_key_t, vk} p
c <- peekCharField kcode
txt <- peekTextField kcode =<< [C.exp| char* {&((TCOD_key_t*)$(void* p'))->text[0]}|]
TCODKey
<$> (pure kcode)
<*> (pure c)
<*> (pure txt)
<*> (#{peek TCOD_key_t, pressed} p)
<*> (#{peek TCOD_key_t, lalt} p)
<*> (#{peek TCOD_key_t, lctrl} p)
<*> (#{peek TCOD_key_t, lmeta} p)
<*> (#{peek TCOD_key_t, ralt} p)
<*> (#{peek TCOD_key_t, rctrl} p)
<*> (#{peek TCOD_key_t, rmeta} p)
<*> (#{peek TCOD_key_t, shift} p)
where
peekCharField KeyChar = Just . chr . (fromIntegral :: CChar -> Int) <$> #{peek TCOD_key_t, c} p
peekCharField _ = pure Nothing
peekTextField KeyText vptr = Just <$> peekCString vptr
peekTextField _ _ = pure Nothing
-- | Special characters
data TCODChar =
-- single walls
CharHline
| CharVline
| CharNe
| CharNw
| CharSe
| CharSw
| CharTeew
| CharTeee
| CharTeen
| CharTees
| CharCross
-- double walls
| CharDhline
| CharDvline
| CharDne
| CharDnw
| CharDse
| CharDsw
| CharDteew
| CharDteee
| CharDteen
| CharDtees
| CharDcross
-- blocks
| CharBlock1
| CharBlock2
| CharBlock3
-- arrows
| CharArrowN
| CharArrowS
| CharArrowE
| CharArrowW
-- arrows without tail
| CharArrow2N
| CharArrow2S
| CharArrow2E
| CharArrow2W
-- double arrows
| CharDarrowH
| CharDarrowV
-- GUI stuff
| CharCheckboxUnset
| CharCheckboxSet
| CharRadioUnset
| CharRadioSet
-- sub-pixel resolution kit
| CharSubpNw
| CharSubpNe
| CharSubpN
| CharSubpSe
| CharSubpDiag
| CharSubpE
| CharSubpSw
-- miscellaneous
| CharSmilie
| CharSmilieInv
| CharHeart
| CharDiamond
| CharClub
| CharSpade
| CharBullet
| CharBulletInv
| CharMale
| CharFemale
| CharNote
| CharNoteDouble
| CharLight
| CharExclamDouble
| CharPilcrow
| CharSection
| CharPound
| CharMultiplication
| CharFunction
| CharReserved
| CharHalf
| CharOneQuarter
| CharCopyright
| CharCent
| CharYen
| CharCurrency
| CharThreeQuarters
| CharDivision
| CharGrade
| CharUmlaut
| CharPow1
| CharPow3
| CharPow2
| CharBulletSquare
deriving (Eq, Ord, Show, Read, Generic)
instance Enum TCODChar where
toEnum n = case n of
196 -> CharHline
179 -> CharVline
191 -> CharNe
218 -> CharNw
217 -> CharSe
192 -> CharSw
180 -> CharTeew
195 -> CharTeee
193 -> CharTeen
194 -> CharTees
197 -> CharCross
205 -> CharDhline
186 -> CharDvline
187 -> CharDne
201 -> CharDnw
188 -> CharDse
200 -> CharDsw
185 -> CharDteew
204 -> CharDteee
202 -> CharDteen
203 -> CharDtees
206 -> CharDcross
176 -> CharBlock1
177 -> CharBlock2
178 -> CharBlock3
24 -> CharArrowN
25 -> CharArrowS
26 -> CharArrowE
27 -> CharArrowW
30 -> CharArrow2N
31 -> CharArrow2S
16 -> CharArrow2E
17 -> CharArrow2W
29 -> CharDarrowH
18 -> CharDarrowV
224 -> CharCheckboxUnset
225 -> CharCheckboxSet
9 -> CharRadioUnset
10 -> CharRadioSet
226 -> CharSubpNw
227 -> CharSubpNe
228 -> CharSubpN
229 -> CharSubpSe
230 -> CharSubpDiag
231 -> CharSubpE
232 -> CharSubpSw
1 -> CharSmilie
2 -> CharSmilieInv
3 -> CharHeart
4 -> CharDiamond
5 -> CharClub
6 -> CharSpade
7 -> CharBullet
8 -> CharBulletInv
11 -> CharMale
12 -> CharFemale
13 -> CharNote
14 -> CharNoteDouble
15 -> CharLight
19 -> CharExclamDouble
20 -> CharPilcrow
21 -> CharSection
156 -> CharPound
158 -> CharMultiplication
159 -> CharFunction
169 -> CharReserved
171 -> CharHalf
172 -> CharOneQuarter
184 -> CharCopyright
189 -> CharCent
190 -> CharYen
207 -> CharCurrency
243 -> CharThreeQuarters
246 -> CharDivision
248 -> CharGrade
249 -> CharUmlaut
251 -> CharPow1
252 -> CharPow3
253 -> CharPow2
254 -> CharBulletSquare
_ -> CharSmilie -- default case
fromEnum v = case v of
CharHline -> 196
CharVline -> 179
CharNe -> 191
CharNw -> 218
CharSe -> 217
CharSw -> 192
CharTeew -> 180
CharTeee -> 195
CharTeen -> 193
CharTees -> 194
CharCross -> 197
CharDhline -> 205
CharDvline -> 186
CharDne -> 187
CharDnw -> 201
CharDse -> 188
CharDsw -> 200
CharDteew -> 185
CharDteee -> 204
CharDteen -> 202
CharDtees -> 203
CharDcross -> 206
CharBlock1 -> 176
CharBlock2 -> 177
CharBlock3 -> 178
CharArrowN -> 24
CharArrowS -> 25
CharArrowE -> 26
CharArrowW -> 27
CharArrow2N -> 30
CharArrow2S -> 31
CharArrow2E -> 16
CharArrow2W -> 17
CharDarrowH -> 29
CharDarrowV -> 18
CharCheckboxUnset -> 224
CharCheckboxSet -> 225
CharRadioUnset -> 9
CharRadioSet -> 10
CharSubpNw -> 226
CharSubpNe -> 227
CharSubpN -> 228
CharSubpSe -> 229
CharSubpDiag -> 230
CharSubpE -> 231
CharSubpSw -> 232
CharSmilie -> 1
CharSmilieInv -> 2
CharHeart -> 3
CharDiamond -> 4
CharClub -> 5
CharSpade -> 6
CharBullet -> 7
CharBulletInv -> 8
CharMale -> 11
CharFemale -> 12
CharNote -> 13
CharNoteDouble -> 14
CharLight -> 15
CharExclamDouble -> 19
CharPilcrow -> 20
CharSection -> 21
CharPound -> 156
CharMultiplication -> 158
CharFunction -> 159
CharReserved -> 169
CharHalf -> 171
CharOneQuarter -> 172
CharCopyright -> 184
CharCent -> 189
CharYen -> 190
CharCurrency -> 207
CharThreeQuarters -> 243
CharDivision -> 246
CharGrade -> 248
CharUmlaut -> 249
CharPow1 -> 251
CharPow3 -> 252
CharPow2 -> 253
CharBulletSquare -> 254
-- | Color control flags for console
data TCODColorControl =
Ctrl_1
| Ctrl_2
| Ctrl_3
| Ctrl_4
| Ctrl_5
| CtrlForeRgb
| CtrlBackRgb
| CtrlStop
deriving (Eq, Ord, Show, Read, Generic)
instance Enum TCODColorControl where
toEnum i = case i of
1 -> Ctrl_1
2 -> Ctrl_2
3 -> Ctrl_3
4 -> Ctrl_4
5 -> Ctrl_5
6 -> CtrlForeRgb
7 -> CtrlBackRgb
8 -> CtrlStop
_ -> CtrlStop
fromEnum v = case v of
Ctrl_1 -> 1
Ctrl_2 -> 2
Ctrl_3 -> 3
Ctrl_4 -> 4
Ctrl_5 -> 5
CtrlForeRgb -> 6
CtrlBackRgb -> 7
CtrlStop -> 8
-- | Background flag
data TCODBackgroundFlag =
BackgroundNone
| BackgroundSet
| BackgroundMultiply
| BackgroundLighten
| BackgroundDarken
| BackgroundScreen
| BackgroundColorDodge
| BackgroundColorBurn
| BackgroundAdd
| BackgroundAdda
| BackgroundBurn
| BackgroundOverlay
| BackgroundAlph
| BackgroundDefault
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic)
-- | Key status
data TCODKeyStatus = KeyPressed | KeyReleased
deriving (Eq, Ord, Show, Read, Bounded, Generic)
instance Enum TCODKeyStatus where
toEnum i = case i of
1 -> KeyPressed
2 -> KeyReleased
_ -> KeyReleased
fromEnum v = case v of
KeyPressed -> 1
KeyReleased -> 2
-- | Custom font flag
data TCODFontFlag =
FontLayoutAsciiInCol
| FontLayoutAsciiInRow
| FontTypeGreyScale
| FontLayoutTcod
deriving (Eq, Ord, Show, Read, Bounded, Generic)
instance Enum TCODFontFlag where
toEnum i = case i of
1 -> FontLayoutAsciiInCol
2 -> FontLayoutAsciiInRow
4 -> FontTypeGreyScale
8 -> FontLayoutTcod
fromEnum v = case v of
FontLayoutAsciiInCol -> 1
FontLayoutAsciiInRow -> 2
FontTypeGreyScale -> 4
FontLayoutTcod -> 8
-- | Assemble flags into int field
combineFontFlags :: Foldable f => f TCODFontFlag -> Int
combineFontFlags = F.foldl' (\acc v -> acc .&. fromEnum v) 0
-- | Availiable renderers
data TCODRenderer =
RendererGLSL
| RendererOpenGL
| RendererSDL
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic)
-- | Different text/element alignments
data TCODAlignment =
AlignLeft
| AlignRight
| AlignCenter
deriving (Eq, Ord, Show, Read, Enum, Bounded, Generic)