module Game.LambdaHack.Client.UI.Frontend.Teletype
( startup, frontendName
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Control.Concurrent.Async
import Data.Char (chr, ord)
import qualified System.IO as SIO
import Game.LambdaHack.Client.UI.Content.Screen
import Game.LambdaHack.Client.UI.Frame
import Game.LambdaHack.Client.UI.Frontend.Common
import qualified Game.LambdaHack.Client.UI.Key as K
import qualified Game.LambdaHack.Definition.Color as Color
import Game.LambdaHack.Common.Point
import qualified Game.LambdaHack.Common.PointArray as PointArray
import Game.LambdaHack.Content.TileKind (floorSymbol)
frontendName :: String
frontendName = "teletype"
startup :: ScreenContent -> IO RawFrontend
startup coscreen = do
rf <- createRawFrontend coscreen (display coscreen) shutdown
let storeKeys :: IO ()
storeKeys = do
l <- SIO.getLine
let c = case l of
[] -> '\n'
hd : _ -> hd
K.KM{..} = keyTranslate c
saveKMP rf modifier key originPoint
storeKeys
void $ async storeKeys
return $! rf
shutdown :: IO ()
shutdown = SIO.hFlush SIO.stdout >> SIO.hFlush SIO.stderr
display :: ScreenContent
-> SingleFrame
-> IO ()
display coscreen SingleFrame{singleFrame} =
let f w l =
let acCharRaw = Color.charFromW32 w
acChar = if acCharRaw == floorSymbol then '.' else acCharRaw
in acChar : l
levelChar = chunk $ PointArray.foldrA f [] singleFrame
chunk [] = []
chunk l = let (ch, r) = splitAt (rwidth coscreen) l
in ch : chunk r
in SIO.hPutStrLn SIO.stderr $ unlines levelChar
keyTranslate :: Char -> K.KM
keyTranslate e = (\(key, modifier) -> K.KM modifier key) $
case e of
'\ESC' -> (K.Esc, K.NoModifier)
'\n' -> (K.Return, K.NoModifier)
'\r' -> (K.Return, K.NoModifier)
' ' -> (K.Space, K.NoModifier)
'\t' -> (K.Tab, K.NoModifier)
c | ord '\^A' <= ord c && ord c <= ord '\^Z' ->
(K.Char $ chr $ ord c - ord '\^A' + ord 'a', K.Control)
| c `elem` ['1'..'9'] -> (K.KP c, K.NoModifier)
| otherwise -> (K.Char c, K.NoModifier)