141 lines
4.2 KiB
Haskell
141 lines
4.2 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 3
|
|
, 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
|
|
, _uvDebugInfo = 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
|
|
rData <- preloadRender
|
|
lChunks <- loadSounds
|
|
lMusic <- loadMusic
|
|
Mix.playMusic Mix.Forever (lMusic IM.! 0)
|
|
return
|
|
PreloadData
|
|
{ _renderData = rData
|
|
, _soundData = SoundData{_loadedChunks = lChunks}
|
|
, _musicData = MusicData{_loadedMusic = lMusic}
|
|
}
|