packages feed

spice (empty) → 0.1.0.0

raw patch · 12 files changed

+383/−0 lines, 12 filesdep +GLFWdep +OpenGLdep +basesetup-changed

Dependencies added: GLFW, OpenGL, base, containers, data-default, elerea

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Cerek Hillen++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ spice.cabal view
@@ -0,0 +1,35 @@+name:                spice+version:             0.1.0.0+synopsis:            An FRP-based game engine written in Haskell.+description:         An FRP-based game engine written in Haskell. - See the homepage for more information.+homepage:            http://github.com/crockeo/spice+license:             MIT+license-file:        LICENSE+author:              Cerek Hillen+maintainer:          Cerek Hillen <cerekh@gmail.com>+copyright:           (c) 2014, Cerek Hillen+category:            FRP+build-type:          Simple+cabal-version:       >=1.10++library+  exposed-modules:     FRP.Spice+                       FRP.Spice.Config+                       FRP.Spice.Engine+                       FRP.Spice.Game+                       FRP.Spice.Input+                       FRP.Spice.Input.Keyboard+                       FRP.Spice.Input.Mouse+                       FRP.Spice.Input.MousePosition+                       FRP.Spice.Math.Vector++  hs-source-dirs:      src/++  build-depends:       base         == 4.7.*+               ,       elerea       == 2.7.*+               ,       GLFW         == 0.5.*+               ,       containers   == 0.5.*+               ,       data-default == 0.5.*+               ,       OpenGL++  default-language:    Haskell2010
+ src/FRP/Spice.hs view
@@ -0,0 +1,8 @@+module FRP.Spice (module Rexport) where++-----------------------+-- Rexported Imports --+import FRP.Spice.Config as Rexport+import FRP.Spice.Engine as Rexport+import FRP.Spice.Input  as Rexport+import FRP.Spice.Game   as Rexport
+ src/FRP/Spice/Config.hs view
@@ -0,0 +1,31 @@+module FRP.Spice.Config where++--------------------+-- Global Imports --+import Data.Default++----------+-- Code --++-- The window config+data WindowConfig = WindowConfig { getWindowWidth      :: Int+                                 , getWindowHeight     :: Int+                                 , getWindowFullscreen :: Bool+                                 , getWindowResizable  :: Bool+                                 , getWindowTitle      :: String+                                 }+  deriving (Eq, Show, Read)++-- The default window config+defaultWindowConfig :: WindowConfig+defaultWindowConfig = WindowConfig { getWindowWidth      = 640+                                   , getWindowHeight     = 480+                                   , getWindowFullscreen = False+                                   , getWindowResizable  = False+                                   , getWindowTitle      = "Spice Application"+                                   }++-- A default instance for the window+-- config+instance Default WindowConfig where+  def = defaultWindowConfig
+ src/FRP/Spice/Engine.hs view
@@ -0,0 +1,54 @@+module FRP.Spice.Engine where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Data.IORef++-------------------+-- Local Imports --+import FRP.Spice.Engine.RunInput+import FRP.Spice.Engine.Network+import FRP.Spice.Engine.Driver+import FRP.Spice.Config+import FRP.Spice.Input+import FRP.Spice.Game++----------+-- Code --++-- Starting the engine+startEngine :: Game a => WindowConfig -> a -> IO ()+startEngine wc game = do+  -- Opening the window+  initialize+  openWindow (Size 640 480) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window++  -- Checking for the window being closed+  closed <- newIORef False+  windowCloseCallback $= do+    writeIORef closed True+    return True++  -- Getting an external of the game+  (gameSignal, gameSink) <- external game++  -- Getting the input container+  ic <- makeInputContainer++  -- Updating the input+  mousePosCallback    $= makeMousePositionCallback ic+  keyCallback         $= makeKeyboardCallback ic+  mouseButtonCallback $= makeMouseCallback ic++  -- Creating the network+  network <- makeNetwork (getInput ic) gameSignal gameSink++  -- Driving the network+  GLFW.time $= 0+  driveNetwork network $ runInput closed++  -- Closing the window, after all is said and done+  closeWindow
+ src/FRP/Spice/Game.hs view
@@ -0,0 +1,13 @@+module FRP.Spice.Game where++-------------------+-- Local Imports --+import FRP.Spice.Input++----------+-- Code --++-- The game instance, to be used with updating and rendering+class Game a where+  update :: Float -> Input -> a -> a+  render :: a -> IO ()
+ src/FRP/Spice/Input.hs view
@@ -0,0 +1,90 @@+module FRP.Spice.Input ( module Rexport+                       , Sinks (..)+                       , Input (..)+                       , InputContainer (..)+                       , makeInputContainer+                       , makeMousePositionCallback+                       , makeKeyboardCallback+                       , makeMouseCallback+                       ) where++--------------------+-- Global Imports --+import Data.Map.Strict hiding (keys, map)+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import Control.Applicative+import FRP.Elerea.Param++-------------------+-- Local Imports --+import qualified FRP.Spice.Input.MousePosition as MousePosition+import qualified FRP.Spice.Input.Keyboard as Keyboard+import qualified FRP.Spice.Input.Mouse as Mouse+import FRP.Spice.Math.Vector++-----------------------+-- Rexported Imports --+import Data.Map.Strict  as Rexport ((!))+import Graphics.UI.GLFW as Rexport (Key (..), SpecialKey (..), MouseButton (..))++----------+-- Code --++-- The sinks+data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()+                   , keyboardSinks      :: Map Key (Bool -> IO ())+                   , mouseSinks         :: Map MouseButton (Bool -> IO ())+                   }++data Input = Input { mousePosition :: Vector Float+                   , keyboard      :: Map Key Bool+                   , mouse         :: Map MouseButton Bool+                   }++-- The container to go around the+data InputContainer = InputContainer { getSinks :: Sinks+                                     , getInput :: Signal Input+                                     }++-- Creating the input container for use in the program+makeInputContainer :: IO InputContainer+makeInputContainer = do+  mousePositionExternals <- MousePosition.externals+  keyboardExternals      <- Keyboard.externals+  mouseExternals         <- Mouse.externals++  let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals+                    , keyboardSinks      = Keyboard.sinks keyboardExternals+                    , mouseSinks         = Mouse.sinks mouseExternals+                    }++  let input = do mps <- fst mousePositionExternals+                 kbs <- Keyboard.signals keyboardExternals+                 ms  <- Mouse.signals mouseExternals++                 return Input { mousePosition = mps+                              , keyboard      = kbs+                              , mouse         = ms+                              }++  return InputContainer { getSinks = sinks+                        , getInput = input+                        }++-- Creating callbacks for each type+makeMousePositionCallback :: InputContainer -> MousePosCallback+makeMousePositionCallback ic (Position x y) =+  mousePositionSinks (getSinks ic) $ Vector (fromIntegral x / 320 - 1) ((-fromIntegral y) / 240 - 1)++makeKeyboardCallback :: InputContainer -> KeyCallback+makeKeyboardCallback ic key state =+  keyboardSinks (getSinks ic) ! key $ case state of+    Press   -> True+    Release -> False++makeMouseCallback :: InputContainer -> MouseButtonCallback+makeMouseCallback ic button state =+  mouseSinks (getSinks ic) ! button $ case state of+    Press   -> True+    Release -> False
+ src/FRP/Spice/Input/Keyboard.hs view
@@ -0,0 +1,28 @@+module FRP.Spice.Input.Keyboard where++--------------------+-- Global Imports --+import qualified Data.Traversable as T+import Data.Map.Strict hiding (keys, map)+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Control.Monad++----------+-- Code --++-- A set of all keys available via GLFW+keys :: [Key]+keys = map toEnum [0 .. 318]++-- Getting the externals for all of the keys+externals :: IO (Map Key (Signal Bool, Bool -> IO ()))+externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys++-- Getting the signals from the externals+signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool)+signals = T.sequence . fmap fst++-- Getting the sinks from the externals+sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ())+sinks = fmap snd
+ src/FRP/Spice/Input/Mouse.hs view
@@ -0,0 +1,43 @@+module FRP.Spice.Input.Mouse where++--------------------+-- Global Imports --+import qualified Data.Traversable as T (sequence)+import Data.Map.Strict hiding (keys, map)+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Control.Monad+import Data.Default++-------------------+-- Local Imports --+import FRP.Spice.Math.Vector++----------+-- Code --++-- Adding an instance of Ord to MouseButton so it can be used with the map+instance Ord MouseButton where+  mb1 <= mb2 = fromEnum mb1 < fromEnum mb2++-- A set of all mouse buttons available via GLFW+buttons :: [MouseButton]+buttons = [ ButtonLeft+          , ButtonRight+          , ButtonMiddle+          ]+          +++          map ButtonNo [0 .. 7]++-- Getting externals for all of the buttons+externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ()))+externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons++-- Getting the signals from the externals+signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool)+signals = T.sequence . fmap fst++-- Getting the sinks from the externals+sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ())+sinks = fmap snd
+ src/FRP/Spice/Input/MousePosition.hs view
@@ -0,0 +1,24 @@+module FRP.Spice.Input.MousePosition where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Data.Default++-------------------+-- Local Imports --+import FRP.Spice.Math.Vector++-- Getting the external for the mouse position+externals :: IO (Signal (Vector Float), Vector Float -> IO ())+externals = external def++-- Getting the signal from the external+signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float)+signals = fst++-- Getting the signal from the external+sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO ()+sinks = snd
+ src/FRP/Spice/Math/Vector.hs view
@@ -0,0 +1,35 @@+module FRP.Spice.Math.Vector where++--------------------+-- Global Imports --+import Data.Default+import Data.Monoid++----------+-- Code --++-- The vector datatype+data Vector a = Vector a a++-- Default instance+instance Default a => Default (Vector a) where+  def = Vector def def++-- Show instance+instance Show a => Show (Vector a) where+  show (Vector x y) = mconcat ["Vector ", show x, " ", show y]++-- Num instance+instance Num a => Num (Vector a) where+  (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)+  (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2)++  fromInteger n = Vector (fromInteger n) (fromInteger n)++  abs    (Vector x y) = Vector (abs    x) (abs    y)+  signum (Vector x y) = Vector (signum x) (signum y)+  negate (Vector x y) = Vector (negate x) (negate y)++-- Functor instance+instance Functor Vector where+  fmap fn (Vector x y) = Vector (fn x) (fn y)