{-# LANGUAGE RankNTypes #-}{-# OPTIONS_HADDOCK hide #-}moduleGraphics.Gloss.Internals.Interface.Game(gameInWindow,Event(..))whereimportGraphics.Gloss.Data.ColorimportGraphics.Gloss.Data.PictureimportGraphics.Gloss.Internals.Render.PictureimportGraphics.Gloss.Internals.Render.ViewPortimportGraphics.Gloss.Internals.Interface.WindowimportGraphics.Gloss.Internals.Interface.CallbackimportGraphics.Gloss.Internals.Interface.Common.ExitimportGraphics.Gloss.Internals.Interface.ViewPortimportGraphics.Gloss.Internals.Interface.ViewPort.ReshapeimportGraphics.Gloss.Internals.Interface.Animate.TimingimportGraphics.Gloss.Internals.Interface.Simulate.IdleimportqualifiedGraphics.Gloss.Internals.Interface.CallbackasCallbackimportqualifiedGraphics.Gloss.Internals.Interface.Simulate.StateasSMimportqualifiedGraphics.Gloss.Internals.Interface.Animate.StateasANimportqualifiedGraphics.Gloss.Internals.Render.OptionsasROimportqualifiedGraphics.UI.GLUTasGLUTimportqualifiedGraphics.Rendering.OpenGL.GLasGLimportData.IORefimportSystem.Mem-- | Possible input events.dataEvent=EventKeyGLUT.KeyGLUT.KeyStateGLUT.Modifiers(Float,Float)|EventMotion(Float,Float)deriving(Eq,Show)-- | Run a game in a window. gameInWindow::forallworld.String-- ^ Name of the window.->(Int,Int)-- ^ Initial size of the window, in pixels.->(Int,Int)-- ^ Initial position of the window, in pixels.->Color-- ^ Background color.->Int-- ^ Number of simulation steps to take for each second of real time.->world-- ^ The initial world.->(world->Picture)-- ^ A function to convert the world a picture.->(Event->world->world)-- ^ A function to handle input events.->(Float->world->world)-- ^ A function to step the world one iteration.-- It is passed the period of time (in seconds) needing to be advanced.->IO()gameInWindowwindowNamewindowSizewindowPosbackgroundColorsimResolutionworldStartworldToPictureworldHandleEventworldAdvance=doletsingleStepTime=1-- make the simulation statestateSR<-newIORef$SM.stateInitsimResolution-- make a reference to the initial worldworldSR<-newIORefworldStart-- make the initial GL view and render statesviewSR<-newIORefviewPortInitrenderSR<-newIORefRO.optionsInitanimateSR<-newIORefAN.stateInitletdisplayFun=do-- convert the world to a pictureworld<-readIORefworldSRletpicture=worldToPictureworld-- display the picture in the current viewrenderS<-readIORefrenderSRviewS<-readIORefviewSR-- render the framewithViewPortviewS(renderPicturerenderSviewSpicture)-- perform garbage collectionperformGCletcallbacks=[Callback.Display(animateBeginanimateSR),Callback.DisplaydisplayFun,Callback.Display(animateEndanimateSR),Callback.Idle(callback_simulate_idlestateSRanimateSRviewSRworldSRworldStart(\_->worldAdvance)singleStepTime),callback_exit(),callback_keyMouseworldSRviewSRworldHandleEvent,callback_motionworldSRworldHandleEvent,callback_viewPort_reshape]createWindowwindowNamewindowSizewindowPosbackgroundColorcallbacks-- | Callback for KeyMouse events.callback_keyMouse::IORefworld-- ^ ref to world state->IORefViewPort->(Event->world->world)-- ^ fn to handle input events->Callbackcallback_keyMouseworldRefviewRefeventFn=KeyMouse(handle_keyMouseworldRefviewRefeventFn)handle_keyMouse::IORefa->t->(Event->a->a)->GLUT.Key->GLUT.KeyState->GLUT.Modifiers->GL.Position->IO()handle_keyMouseworldRef_eventFnkeykeyStatekeyModspos=dopos'<-convertPointposworldRef`modifyIORef`\world->eventFn(EventKeykeykeyStatekeyModspos')world-- | Callback for Motion events.callback_motion::IORefworld-- ^ ref to world state->(Event->world->world)-- ^ fn to handle input events->Callbackcallback_motionworldRefeventFn=Motion(handle_motionworldRefeventFn)handle_motion::IORefa->(Event->a->a)->GL.Position->IO()handle_motionworldRefeventFnpos=dopos'<-convertPointposworldRef`modifyIORef`\world->eventFn(EventMotionpos')worldconvertPoint::GL.Position->IO(Float,Float)convertPointpos=do(GLUT.SizesizeX_sizeY_)<-GL.getGLUT.windowSizelet(sizeX,sizeY)=(fromIntegralsizeX_,fromIntegralsizeY_)letGLUT.Positionpx_py_=posletpx=fromIntegralpx_letpy=sizeY-fromIntegralpy_letpx'=px-sizeX/2letpy'=py-sizeY/2letpos'=(px',py')returnpos'