Improve configuration handling

This commit is contained in:
2021-04-08 02:48:25 +02:00
parent ddb1171e2e
commit f1214c0584
14 changed files with 118 additions and 54 deletions
+2
View File
@@ -9,6 +9,7 @@ import Dodge.Update
import Dodge.Event import Dodge.Event
import Dodge.Render import Dodge.Render
import Dodge.LoadConfig import Dodge.LoadConfig
import Dodge.Config.Update
import Dodge.LoadSound import Dodge.LoadSound
import Picture import Picture
import Picture.Render import Picture.Render
@@ -55,6 +56,7 @@ main = do
(fmap (setWindowSize sizex sizey keyConfig) firstWorld) (fmap (setWindowSize sizex sizey keyConfig) firstWorld)
( \preData w -> do ( \preData w -> do
startTicks <- SDL.ticks startTicks <- SDL.ticks
updateDodgeConfig w
void $ doDrawing (_renderData preData) w void $ doDrawing (_renderData preData) w
playPositionalSoundQueue (_loadedChunks $ _soundData preData) (_soundQueue w) playPositionalSoundQueue (_loadedChunks $ _soundData preData) (_soundQueue w)
newPlayingSounds <- playAndUpdate (_soundData preData) (_sounds w) newPlayingSounds <- playAndUpdate (_soundData preData) (_sounds w)
+1 -1
View File
@@ -770,7 +770,7 @@ levLayer HPtLayer = 73
levLayer ShadowLayer = 75 levLayer ShadowLayer = 75
levLayer LabelLayer = 80 levLayer LabelLayer = 80
levLayer InvLayer = 85 levLayer InvLayer = 85
levLayer MenuLayer = 90 levLayer MenuDepth = 90
{- | Transform coordinates from world position to normalised screen coordinates. {- | Transform coordinates from world position to normalised screen coordinates.
-} -}
+22
View File
@@ -0,0 +1,22 @@
{-|
IO actions that apply config side effects and save it to disk.
-}
module Dodge.Config.Update
where
import Dodge.Data
import Dodge.LoadConfig
import Sound
import Data.Aeson (encodeFile)
import Control.Monad (when)
updateDodgeConfig :: World -> IO ()
updateDodgeConfig w = case _menuLayers w of
(ConfigSaveScreen _: _) -> do
putStrLn "Saving config"
encodeFile "data/dodge.config.json" cfig
_ -> when (_configNeedsUpdate w) $ do
setSoundVolume ( _volume_master cfig * _volume_sound cfig)
setMusicVolume ( _volume_master cfig * _volume_music cfig)
where
cfig = _config w
+3 -2
View File
@@ -65,7 +65,7 @@ data World = World
, _pathPoints :: ~(IM.IntMap (IM.IntMap [(Int,Point2)])) , _pathPoints :: ~(IM.IntMap (IM.IntMap [(Int,Point2)]))
, _pathInc :: ~(M.Map Point2 [Point2]) , _pathInc :: ~(M.Map Point2 [Point2])
, _storedLevel :: Maybe World , _storedLevel :: Maybe World
, _menuState :: MenuState , _menuLayers :: [MenuLayer]
, _worldState :: M.Map WorldState Bool , _worldState :: M.Map WorldState Bool
, _windowX :: !Float , _windowX :: !Float
, _windowY :: !Float , _windowY :: !Float
@@ -83,6 +83,7 @@ data World = World
, _varMovementStrafeSpeedModifier :: Float , _varMovementStrafeSpeedModifier :: Float
, _debugMode :: Bool , _debugMode :: Bool
, _config :: Configuration , _config :: Configuration
, _configNeedsUpdate :: Bool
} }
data Corpse = Corpse data Corpse = Corpse
@@ -100,7 +101,7 @@ data Layer
| FlItLayer | FlItLayer
| LabelLayer | LabelLayer
| InvLayer | InvLayer
| MenuLayer | MenuDepth
| PressPlateLayer | PressPlateLayer
| CorpseLayer | CorpseLayer
| UPtLayer | UPtLayer
+2 -2
View File
@@ -1,11 +1,11 @@
{-# LANGUAGE StrictData #-} {-# LANGUAGE StrictData #-}
module Dodge.Data.Menu module Dodge.Data.Menu
where where
data MenuState data MenuLayer
= LevelMenu Int = LevelMenu Int
| PauseMenu | PauseMenu
| GameOverMenu | GameOverMenu
| OptionMenu | OptionMenu
| InGame | ConfigSaveScreen Int
deriving (Eq,Ord) deriving (Eq,Ord)
+2 -1
View File
@@ -210,7 +210,7 @@ defaultWorld = World
, _corpses = IM.empty , _corpses = IM.empty
, _decorations = IM.empty , _decorations = IM.empty
, _storedLevel = Nothing , _storedLevel = Nothing
, _menuState = LevelMenu 1 , _menuLayers = [LevelMenu 1]
, _worldState = M.empty , _worldState = M.empty
, _clickMousePos = (0,0) , _clickMousePos = (0,0)
, _pathGraph = Data.Graph.Inductive.Graph.empty , _pathGraph = Data.Graph.Inductive.Graph.empty
@@ -236,6 +236,7 @@ defaultWorld = World
, _varMovementStrafeSpeedModifier = 3 , _varMovementStrafeSpeedModifier = 3
, _debugMode = True , _debugMode = True
, _config = defaultConfig , _config = defaultConfig
, _configNeedsUpdate = False
} }
youLight = youLight =
TLS { _tlsPos = (0,0) TLS { _tlsPos = (0,0)
+2 -2
View File
@@ -57,8 +57,8 @@ handleMouseButtonEvent mbev w = case mouseButtonEventMotion mbev of
where but = mouseButtonEventButton mbev where but = mouseButtonEventButton mbev
handleMouseWheelEvent :: MouseWheelEventData -> World -> Maybe World handleMouseWheelEvent :: MouseWheelEventData -> World -> Maybe World
handleMouseWheelEvent mwev w = case _menuState w of handleMouseWheelEvent mwev w = case _menuLayers w of
InGame -> case mouseWheelEventPos mwev of [] -> case mouseWheelEventPos mwev of
V2 x y | y > 0 -> Just (wheelUpEvent w) V2 x y | y > 0 -> Just (wheelUpEvent w)
| y < 0 -> Just (wheelDownEvent w) | y < 0 -> Just (wheelDownEvent w)
| otherwise -> Just w | otherwise -> Just w
+3 -4
View File
@@ -57,9 +57,9 @@ handlePressedKeyInGame _ w = Just w
handlePressedKey :: Bool -> Scancode -> World -> Maybe World handlePressedKey :: Bool -> Scancode -> World -> Maybe World
handlePressedKey True _ w = Just w handlePressedKey True _ w = Just w
handlePressedKey _ scode w handlePressedKey _ scode w
| _menuState w == InGame | _menuLayers w == []
= handlePressedKeyInGame scode w = handlePressedKeyInGame scode w
| otherwise = handlePressedKeyInMenu (_menuState w) scode w | otherwise = handlePressedKeyInMenu (head $ _menuLayers w) scode w
handlePressedKey _ _ w = Just w handlePressedKey _ _ w = Just w
debugKey :: Scancode -> World -> Maybe World debugKey :: Scancode -> World -> Maybe World
@@ -70,7 +70,6 @@ debugKey scancode w
| scancode == ScancodeF6 = Just $ dropLight' w | scancode == ScancodeF6 = Just $ dropLight' w
debugKey _ w = Just w debugKey _ w = Just w
spaceAction :: World -> World spaceAction :: World -> World
spaceAction w = case listToMaybe $ _closeActiveObjects w of spaceAction w = case listToMaybe $ _closeActiveObjects w of
Just (Left flit) -> pickUpItem' flit w Just (Left flit) -> pickUpItem' flit w
@@ -78,7 +77,7 @@ spaceAction w = case listToMaybe $ _closeActiveObjects w of
Nothing -> w Nothing -> w
pauseGame :: World -> World pauseGame :: World -> World
pauseGame w = w {_menuState = PauseMenu} pauseGame w = w {_menuLayers = [PauseMenu]}
toggleMap w = w & carteDisplay %~ not toggleMap w = w & carteDisplay %~ not
escapeMap w = w & carteDisplay .~ False escapeMap w = w & carteDisplay .~ False
+19 -4
View File
@@ -7,24 +7,25 @@ import Dodge.Rooms
import Dodge.Floor import Dodge.Floor
import Dodge.Initialisation import Dodge.Initialisation
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.LoadConfig
import Data.Maybe import Data.Maybe
import qualified Data.Set as S import qualified Data.Set as S
import Control.Lens import Control.Lens
import SDL import SDL
handlePressedKeyInMenu :: MenuState -> Scancode -> World -> Maybe World handlePressedKeyInMenu :: MenuLayer -> Scancode -> World -> Maybe World
handlePressedKeyInMenu mState scode w = case mState of handlePressedKeyInMenu mState scode w = case mState of
LevelMenu _ -> case scode of LevelMenu _ -> case scode of
ScancodeEscape -> Nothing ScancodeEscape -> Nothing
ScancodeO -> goToOptionMenu w
_ -> startLevel w _ -> startLevel w
PauseMenu -> case scode of PauseMenu -> case scode of
ScancodeEscape -> Nothing ScancodeEscape -> Nothing
ScancodeR -> return $ fromMaybe w $ _storedLevel w ScancodeR -> return $ fromMaybe w $ _storedLevel w
ScancodeN -> Just $ putSound $ generateLevel 1 ScancodeN -> Just $ putSound $ generateLevel 1
$ initialWorld {_randGen = _randGen w} $ initialWorld {_randGen = _randGen w}
ScancodeO -> goToOptionMenu w
_ -> unpause w _ -> unpause w
GameOverMenu -> case scode of GameOverMenu -> case scode of
ScancodeEscape -> Nothing ScancodeEscape -> Nothing
@@ -32,13 +33,27 @@ handlePressedKeyInMenu mState scode w = case mState of
ScancodeN -> Just $ putSound $ generateLevel 1 ScancodeN -> Just $ putSound $ generateLevel 1
$ initialWorld $ initialWorld
{_randGen = _randGen w} {_randGen = _randGen w}
ScancodeO -> goToOptionMenu w
_ -> Just w _ -> Just w
OptionMenu -> case scode of
ScancodeY -> Just $ w & config . volume_master %~ dec
ScancodeU -> Just $ w & config . volume_master %~ inc
ScancodeH -> Just $ w & config . volume_sound %~ dec
ScancodeJ -> Just $ w & config . volume_sound %~ inc
ScancodeN -> Just $ w & config . volume_music %~ dec
ScancodeM -> Just $ w & config . volume_music %~ inc
_ -> Just $ w & menuLayers %~ (ConfigSaveScreen 1:) . tail
& configNeedsUpdate .~ False
_ -> Just w _ -> Just w
where where
unpause w' = Just . resumeSound $ unpause w' = Just . resumeSound $
w' {_menuState = InGame} w' {_menuLayers = []}
startLevel = unpause . storeLevel startLevel = unpause . storeLevel
putSound = id -- set loadedSounds (_loadedSounds w) putSound = id -- set loadedSounds (_loadedSounds w)
dec x = max 0 (x - 0.1)
inc x = min 1 (x + 0.1)
goToOptionMenu w = Just $ w & menuLayers %~ (OptionMenu :)
& configNeedsUpdate .~ True
storeLevel :: World -> World storeLevel :: World -> World
storeLevel w = case _storedLevel w of storeLevel w = case _storedLevel w of
+1 -1
View File
@@ -47,7 +47,7 @@ initialWorld = defaultWorld
, _sounds = M.empty , _sounds = M.empty
, _decorations = IM.empty , _decorations = IM.empty
, _storedLevel = Nothing , _storedLevel = Nothing
, _menuState = LevelMenu 1 , _menuLayers = [LevelMenu 1]
, _worldState = M.empty , _worldState = M.empty
, _windowX = 800 , _windowX = 800
, _windowY = 600 , _windowY = 600
+13 -6
View File
@@ -1,3 +1,4 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StrictData #-} {-# LANGUAGE StrictData #-}
@@ -6,6 +7,9 @@ module Dodge.LoadConfig
Configuration (..) Configuration (..)
, loadDodgeConfig , loadDodgeConfig
, defaultConfig , defaultConfig
, volume_master
, volume_sound
, volume_music
, module Dodge.LoadConfig.KeyConfig , module Dodge.LoadConfig.KeyConfig
) where ) where
import Dodge.LoadConfig.KeyConfig import Dodge.LoadConfig.KeyConfig
@@ -16,14 +20,17 @@ import GHC.Generics
import qualified GHC.Int import qualified GHC.Int
import qualified SDL import qualified SDL
import System.Directory import System.Directory
import Control.Lens
data Configuration = Configuration data Configuration = Configuration
{ volume_master :: Float { _volume_master :: Float
, volume_sound :: Float , _volume_sound :: Float
, volume_music :: Float , _volume_music :: Float
} }
deriving (Generic, Show) deriving (Generic, Show)
makeLenses ''Configuration
instance ToJSON Configuration where instance ToJSON Configuration where
toEncoding = genericToEncoding defaultOptions toEncoding = genericToEncoding defaultOptions
@@ -39,8 +46,8 @@ loadDodgeConfig = do
return defaultConfig return defaultConfig
defaultConfig = Configuration defaultConfig = Configuration
{ volume_master = 1 { _volume_master = 1
, volume_sound = 1 , _volume_sound = 1
, volume_music = 1 , _volume_music = 1
} }
+39 -23
View File
@@ -3,34 +3,50 @@ module Dodge.Render.MenuScreen
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.LoadConfig
import Dodge.Base (halfWidth,halfHeight) import Dodge.Base (halfWidth,halfHeight)
import Picture import Picture
menuScreen :: World -> Picture menuScreen :: World -> Picture
menuScreen w = case _menuState w of menuScreen w = case _menuLayers w of
InGame -> blank [] -> blank
LevelMenu x -> (LevelMenu x:_) -> pictures
pictures [--color (withAlpha 0.5 black) $ polygon $ screenBox w [color (withAlpha 0.5 black) $ polygon $ screenBox w
tst (-100) 100 0.4 ("LEVEL "++show x) ,tst (-100) 100 0.4 ("LEVEL "++show x)
,controlsList ,controlsList
] ]
PauseMenu -> pictures (PauseMenu:_) -> pictures
[color (withAlpha 0.5 black) $ polygon $ screenBox w [color (withAlpha 0.5 black) $ polygon $ screenBox w
,tst (-100) 100 0.4 "PAUSED" ,tst (-100) 100 0.4 "PAUSED"
,tst (-100) 50 0.2 "n - new level" ,tst (-100) 50 0.2 "n - new level"
,tst (-100) 0 0.2 "r - restart" ,tst (-100) 0 0.2 "r - restart"
,tst (-100) (-50) 0.2 "o - options" ,tst (-100) (-50) 0.2 "o - options"
, controlsList , controlsList
] ]
GameOverMenu -> pictures [color (withAlpha 0.5 black) $ polygon $ screenBox w (GameOverMenu:_) -> pictures
,tst (-100) 100 0.4 "GAME OVER" [color (withAlpha 0.5 black) $ polygon $ screenBox w
,tst (-100) 50 0.2 "n - new level" ,tst (-100) 100 0.4 "GAME OVER"
,tst (-100) 0 0.2 "r - restart" ,tst (-100) 50 0.2 "n - new level"
,tst (-100) (-50) 0.2 "o - options" ,tst (-100) 0 0.2 "r - restart"
,controlsList ,tst (-100) (-50) 0.2 "o - options"
] ,controlsList
where tst x y sc t = translate x y $ scale sc sc $ color white $ text t ]
(OptionMenu : _) -> pictures
[color (withAlpha 0.5 black) $ polygon $ screenBox w
,tst (-100) 100 0.4 "OPTIONS"
,tst (-180) 50 0.2 $ "y - master volume + u : " ++ mavol
,tst (-180) 0 0.2 $ "h - sound volume + j : " ++ snvol
,tst (-180) (-50) 0.2 $ "n - music volume + m : " ++ muvol
,controlsList
]
_ -> blank
where
tst x y sc t = translate x y $ scale sc sc $ color white $ text t
mavol = f $ _volume_master $ _config w
snvol = f $ _volume_sound $ _config w
muvol = f $ _volume_music $ _config w
f x = show $ round $ 10 * x
controlsList = pictures [tst (-250) (-130) 0.15 "controls:" controlsList = pictures [tst (-250) (-130) 0.15 "controls:"
,tst (-150) (-130) 0.15 "wasd" ,tst (-150) (-130) 0.15 "wasd"
+1 -1
View File
@@ -29,7 +29,7 @@ worldPictures w = pictures $ concat
fixedCoordPictures :: World -> Picture fixedCoordPictures :: World -> Picture
fixedCoordPictures w = pictures fixedCoordPictures w = pictures
[ hudDrawings w [ hudDrawings w
, scaler . onLayer MenuLayer $ menuScreen w , scaler . onLayer MenuDepth $ menuScreen w
, customMouseCursor w , customMouseCursor w
] ]
where where
+8 -7
View File
@@ -23,14 +23,15 @@ import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M import qualified Data.Map as M
import Control.Lens import Control.Lens
{- | The update step. {- | The update step.
If the '_menuState' is not 'InGame', this is the identity. If '_menuLayers' is not empty, or the saving screen, this is the identity.
This means that the only way to change the world is using event handling. In such menus, the only way to change the world is using event handling.
-} -}
update :: World -> World update :: World -> World
update w update w = case _menuLayers w of
| _menuState w /= InGame = w (ConfigSaveScreen x: ls) -> w & menuLayers .~ (ConfigSaveScreen (x-1) : ls)
| otherwise = (ConfigSaveScreen 0: ls) -> w & menuLayers .~ ls
let w1 = updateParticles' . updateProjectiles (_ : _) -> w
[] -> let w1 = updateParticles' . updateProjectiles
. updateLightSources . updateLightSources
. zoneClouds . zoneClouds
. updateClouds . updateClouds
@@ -101,7 +102,7 @@ setTestStringIO = fmap (\ w -> set testString (show $ s w) w)
where s w = (-.-) <$> (w ^? creatures . ix 0 . crPos) <*> (w ^? creatures . ix 0 . crOldPos) where s w = (-.-) <$> (w ^? creatures . ix 0 . crPos) <*> (w ^? creatures . ix 0 . crOldPos)
checkEndGame :: World -> World checkEndGame :: World -> World
checkEndGame w | _crHP (you w) < 1 = haltSound $ w {_menuState = GameOverMenu} checkEndGame w | _crHP (you w) < 1 = haltSound $ w {_menuLayers = [GameOverMenu]}
| otherwise = w | otherwise = w
updateClouds :: World -> World updateClouds :: World -> World