module Main where import Control.Monad.State import Data.Char import Data.FiniteMap import Data.Ix import Data.List import System.Random import System.Environment import Util.Grid import Color import LanguageSelect import Curses import World import Keymap import Vision import Window start :: IO () start = do init_curses raw_mode finish :: IO () finish = do cooked_mode exit_curses -- These are odd numbers, so that the view extends the same distance -- from the midpoint on all sides. view_hsize :: Int view_hsize = 39 view_vsize :: Int view_vsize = 19 draw_map :: (GlyphWindow w) => w -> Position -> World -> IO () draw_map w center world = do sequence_ (map draw_glyph locs) if inRange (window_bounds w) you_loc then move_cursor w you_loc else return () where (hsize, vsize) = window_size w wcenter = (hsize `div` 2, vsize `div` 2) ulcorner = center `subpos` wcenter land = landscape world mons = monsters world locs = range (window_bounds w) you_loc = (you_pos world) `subpos` ulcorner draw_glyph (h, v) = write_glyph w (h, v) (glyph_at land mons (ulcorner `addpos` (h, v))) draw_game_map :: (GlyphWindow w) => w -> World -> IO () draw_game_map w world = draw_map w (you_pos world) world draw_bigmap :: (GlyphWindow w) => w -> Position -> World -> IO () draw_bigmap w center world = do draw_map w center world main_loop :: World -> IO World main_loop world | game_over world = return world main_loop world = do let mode = user_mode world case mode of Mode_game -> do let mapw = mapwin world draw_game_map mapw world refresh_window mapw key <- get_key evalStateT clear_messages world case lookupFM (keymap world) key of Nothing -> do flash main_loop world Just action -> do world' <- execStateT action world main_loop world' Mode_bigmap center -> do let bigw = bigwin world draw_bigmap bigw center world refresh_window bigw key <- get_key case lookupFM (dir_keymap world) key of Nothing -> do -- Make sure the areas not covered by other windows are blanked clear_window bigw refresh_window bigw -- Do this by clearing the screen clear_screen refresh_window (mapwin world) refresh_window (msgwin world) main_loop world { user_mode = Mode_game } Just (dx, dy) -> do main_loop world { user_mode = Mode_bigmap (center `addpos` (10 * dx, 10 * dy)) } get_seed :: IO StdGen get_seed = do args <- getArgs case args of ((a : _) : _) -> return (mkStdGen (digitToInt a)) _ -> getStdGen main :: IO () main = do start msgw <- new_window (0, 0) (79, 0) mapw <- new_window (0, 1) (view_hsize-1, view_vsize) (hsize, vsize) <- screen_size bigw <- new_window (0, 0) (hsize-1, vsize-1) seed <- get_seed write_string mapw Text "Generating world..." refresh_window mapw update_screen let world = set_language English $ new_world seed default_keymap default_dir_keymap msgw mapw bigw main_loop world destroy_window bigw destroy_window mapw destroy_window msgw finish