109 lines
4.0 KiB
Haskell
109 lines
4.0 KiB
Haskell
module Dodge.Event.Menu
|
|
( handlePressedKeyInMenu
|
|
) where
|
|
import Dodge.Data
|
|
import Dodge.Data.Menu
|
|
import Dodge.Base
|
|
import Dodge.Floor
|
|
import Dodge.Initialisation
|
|
import Dodge.SoundLogic
|
|
import Dodge.Config.Data
|
|
import Dodge.Config.Update
|
|
import Dodge.Layout
|
|
import Preload.Update
|
|
import Dodge.Debug.Terminal
|
|
|
|
import Data.Maybe
|
|
--import qualified Data.Set as S
|
|
import Control.Lens
|
|
import SDL
|
|
import SDL.Internal.Numbered
|
|
|
|
handlePressedKeyInMenu :: MenuLayer -> Scancode -> World -> Maybe World
|
|
handlePressedKeyInMenu mState scode w = case mState of
|
|
Terminal s -> case scode of
|
|
ScancodeEscape -> popMenu w
|
|
ScancodeReturn -> popMenu $ applyTerminalString s w
|
|
ScancodeBackspace -> popMenu w >>= pushMenu (Terminal $ dropLast s)
|
|
_ -> popMenu w >>= pushMenu (Terminal $ s ++ [scodeToChar scode])
|
|
LevelMenu _ -> case scode of
|
|
ScancodeEscape -> Nothing
|
|
ScancodeO -> pushMenu OptionMenu w
|
|
ScancodeC -> pushMenu ControlList w
|
|
_ -> startLevel w
|
|
PauseMenu -> case scode of
|
|
ScancodeEscape -> Nothing
|
|
ScancodeR -> return $ fromMaybe w $ _storedLevel w
|
|
ScancodeN -> startNewGame
|
|
ScancodeO -> pushMenu OptionMenu w
|
|
ScancodeC -> pushMenu ControlList w
|
|
_ -> unpause w
|
|
GameOverMenu -> case scode of
|
|
ScancodeEscape -> Nothing
|
|
ScancodeR -> Just $ fromMaybe w $ _storedLevel w
|
|
ScancodeN -> startNewGame
|
|
ScancodeO -> pushMenu OptionMenu w
|
|
ScancodeC -> pushMenu ControlList w
|
|
_ -> Just w
|
|
OptionMenu -> case scode of
|
|
ScancodeV -> pushMenu SoundOptionMenu w
|
|
ScancodeG -> pushMenu GraphicsOptionMenu w
|
|
_ -> popMenu w
|
|
SoundOptionMenu -> case scode of
|
|
ScancodeY -> Just $ sw & config . volume_master %~ dec
|
|
ScancodeU -> Just $ sw & config . volume_master %~ inc
|
|
ScancodeH -> Just $ sw & config . volume_sound %~ dec
|
|
ScancodeJ -> Just $ sw & config . volume_sound %~ inc
|
|
ScancodeN -> Just $ sw & config . volume_music %~ dec
|
|
ScancodeM -> Just $ sw & config . volume_music %~ inc
|
|
_ -> popMenu $ w & sideEffects %~ (saveConfig (_config w) :)
|
|
GraphicsOptionMenu -> case scode of
|
|
ScancodeW -> Just $ w & config . wall_textured %~ not
|
|
ScancodeS -> Just $ updateFramebufferSize $ w & config . shadow_resolution %~ cycleResolution
|
|
_ -> popMenu $ w & sideEffects %~ (saveConfig (_config w) :)
|
|
ControlList -> Just $ w & menuLayers %~ tail
|
|
_ -> Just w
|
|
where
|
|
unpause w' = Just . resumeSound $
|
|
w' {_menuLayers = []}
|
|
startLevel = unpause . storeLevel
|
|
dec x = max 0 (x - 0.1)
|
|
inc x = min 1 (x + 0.1)
|
|
pushMenu ml w' = Just $ w' & menuLayers %~ (ml :)
|
|
popMenu w' = Just $ w' & menuLayers %~ tail
|
|
sw = w & sideEffects %~ (setVol (_config w) : )
|
|
startNewGame = Just $ w
|
|
& menuLayers .~ [WaitMessage "GENERATING..." 1]
|
|
& worldEvents .~ const aNewGame
|
|
aNewGame :: World
|
|
aNewGame = updateFramebufferSize $ generateLevelFromRoomList levx $ initialWorld
|
|
& randGen .~ _randGen w
|
|
& config .~ _config w
|
|
dropLast (x:xs) = init (x:xs)
|
|
dropLast _ = []
|
|
|
|
-- | hacky
|
|
scodeToChar :: Scancode -> Char
|
|
scodeToChar = toEnum . (+ 61) . fromIntegral . toNumber
|
|
|
|
updateFramebufferSize :: World -> World
|
|
updateFramebufferSize w = w & sideEffects
|
|
%~ (resizeSpareFBO (x `div` divRes) (y `div` divRes) x y : )
|
|
where
|
|
(x,y) = (round $ getWindowX w, round $ getWindowY w)
|
|
divRes = w ^. config . shadow_resolution
|
|
|
|
|
|
cycleResolution :: (Eq a, Num a, Num p) => a -> p
|
|
cycleResolution 1 = 2
|
|
cycleResolution 2 = 4
|
|
cycleResolution 4 = 1
|
|
cycleResolution _ = 1
|
|
|
|
storeLevel :: World -> World
|
|
storeLevel w = case _storedLevel w of
|
|
Nothing -> w & storedLevel ?~ w
|
|
_ -> w
|
|
|
|
|