Files
loop/appDodge/Main.hs
T
2023-04-11 14:55:57 +01:00

146 lines
4.4 KiB
Haskell

module Main (
main,
) where
import Control.Lens
import Control.Monad
import Control.Parallel
import qualified Data.Map.Strict as M
--import Data.Preload.Render
import qualified Data.Text as T
import Dodge.Concurrent
import Dodge.Config.Load
import Dodge.Config.Update
import Dodge.Data
import Dodge.Event
import Dodge.Initialisation
import Dodge.LoadSeed
import Dodge.Menu
import Dodge.Render
import Dodge.SoundLogic.LoadSound
import Dodge.TestString
import Dodge.Update
--import qualified IntMapHelp as IM
import Loop
import Music
--import Picture
import Preload
import Preload.Render
--import Render
import SDL (($=))
import qualified SDL
--import qualified SDL.Mixer as Mix
import Sound
import System.Directory
main :: IO ()
main = do
-- load the config to get the window size and position
con <- loadDodgeConfig
let sizex = _windowX con
sizey = _windowY con
posx = _windowPosX con
posy = _windowPosY con
setupConLoop'
20
(T.pack "Simple Game Loop")
(winConfig sizex sizey (Just (posx, posy)))
theCleanup
(firstWorldLoad con)
conEffects
theUpdateStep
(flip handleEvent)
-- | Create an OpenGL SDL window configuration with a given x and y size.
winConfig :: Int -> Int -> Maybe (Int, Int) -> SDL.WindowConfig
winConfig x y winpos =
SDL.defaultWindow
{ SDL.windowGraphicsContext =
SDL.OpenGLContext $
SDL.defaultOpenGL
{ SDL.glProfile = SDL.Core SDL.Normal 4 5
, SDL.glColorPrecision = SDL.V4 8 8 8 8
}
, SDL.windowPosition = theWinPos
, SDL.windowInitialSize = SDL.V2 (fromIntegral x) (fromIntegral y)
, SDL.windowResizable = True
}
where
theWinPos = case winpos of
Just (px, py) -> SDL.Absolute (SDL.P (SDL.V2 (fromIntegral px) (fromIntegral py)))
Nothing -> SDL.Wherever
theCleanup :: Universe -> IO ()
theCleanup uv = SDL.cursorVisible $= True >> cleanUpPreload (_preloadData uv)
firstWorldLoad :: Configuration -> IO Universe
firstWorldLoad theConfig = do
SDL.cursorVisible $= False
pdata <- doPreload >>= applyWorldConfig theConfig
cancontinue <- doesFileExist "saveSlot/0"
mseed <- loadSeed
let u =
Universe
{ _uvWorld = splashScreen
, _uvConfig = theConfig
, _preloadData = pdata
, _uvScreenLayers = []
, _uvIOEffects = return
, _uvTestString = testStringInit
, _uvSideEffects = mempty
, _uvCanContinue = cancontinue
, _uvMSeed = mseed
, _uvLastFrameTicks = 0
, _uvFrameTicks = 0
, _uvRAMSave = Nothing
, _uvDebug = mempty
}
return $ u & uvScreenLayers .~ [splashMenu u]
theUpdateStep :: SDL.Window -> Universe -> IO Universe
theUpdateStep win = doSideEffects <=< updateRenderSplit win
updateRenderSplit :: SDL.Window -> Universe -> IO Universe
updateRenderSplit win u = do
updateUniverse u `par` void (doDrawing win u)
return $! updateUniverse u
playSoundUnlessRewinding :: Universe -> IO (M.Map SoundOrigin Sound)
playSoundUnlessRewinding u = case w ^. timeFlow of
NormalTimeFlow -> playSoundAndUpdate (_soundData $ _preloadData u) (_playingSounds w) (_toPlaySounds w)
_ -> stopAllSounds >> return M.empty
where
w = _uvWorld u
doSideEffects :: Universe -> IO Universe
doSideEffects u = do
newPlayingSounds <- playSoundUnlessRewinding u
u' <- _uvIOEffects u u
endTicks <- SDL.ticks
return $
u'
& uvLastFrameTicks .~ (u ^. uvFrameTicks)
& uvFrameTicks .~ endTicks
& uvWorld . playingSounds .~ newPlayingSounds
& uvWorld . toPlaySounds .~ M.empty
& uvIOEffects .~ return
doPreload :: IO PreloadData
doPreload = do
putStrLn "Start Render preload"
rData <- preloadRender
putStrLn "Start sound preload"
lChunks <- loadSounds
putStrLn "Skip music preload!"
-- lMusic <- loadMusic
-- Mix.playMusic Mix.Forever (lMusic IM.! 0)
putStrLn "Return PreloadData"
return
PreloadData
{ _renderData = rData
, _soundData = SoundData{_loadedChunks = lChunks}
--, _musicData = MusicData{_loadedMusic = lMusic}
, _musicData = MusicData{_loadedMusic = undefined}
}