module Game.LambdaHack.Client.UI.Frontend.Teletype
( startup, frontendName
) where
import Prelude ()
import Game.LambdaHack.Common.Prelude
import Control.Concurrent.Async
import Data.Char (chr, ord)
import qualified Data.Char as Char
import qualified System.IO as SIO
import Game.LambdaHack.Client.ClientOptions
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.Common.Color as Color
import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.Point
import qualified Game.LambdaHack.Common.PointArray as PointArray
frontendName :: String
frontendName = "teletype"
startup :: ClientOptions -> IO RawFrontend
startup _soptions = do
rf <- createRawFrontend display 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 :: SingleFrame
-> IO ()
display SingleFrame{singleFrame} =
let f w l =
let acCharRaw = Color.charFromW32 w
acChar = if Char.ord acCharRaw == 183 then '.' else acCharRaw
in acChar : l
levelChar = chunk $ PointArray.foldrA f [] singleFrame
lxsize = fst normalLevelBound + 1
chunk [] = []
chunk l = let (ch, r) = splitAt lxsize 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)