Liquorice-0.0.1: Liquorice.hs
{-# OPTIONS_GHC -F -pgmF htfpp #-}
{-# OPTIONS_HADDOCK prune #-}
{-|
Module : Liquorice
Description : Liquorice fundamental data-types.
Copyright : © Jonathan Dowland, 2020
License : GPL-3
Maintainer : jon+hackage@dow.land
Stability : experimental
Portability : POSIX
The Liquorice fundamental data-types.
-}
module Liquorice
(
Context(..)
, Point
, Orientation(..)
, prev
, next
, Thing(..)
, Sector(..)
, start
, htf_thisModulesTests
) where
import Test.Framework
import Data.Function ((&))
import Data.List (nub)
import Liquorice.Line
-- | Utility function, a wrapping alternative to `succ`.
next :: (Eq a, Bounded a, Enum a) => a -> a
next a = if a == maxBound then minBound else succ a
-- | Utility function, a wrapping alternative to `pred`.
prev :: (Eq a, Bounded a, Enum a) => a -> a
prev a = if a == minBound then maxBound else pred a
-- | Possible orientations for the Pen: The four cardinal directions.
data Orientation = North | East | South | West deriving (Show, Eq, Enum, Bounded)
-- | A `Context` holds the entirety of all geometry that has been defined at
-- a point in a program: properties of the Pen: `location` and `orientation`;
-- "Palette"-like properties of the Pen: the current thing Type, textures for
-- parts of `Line`s and `Sector`s, etc.;
-- Lists of geometric objects (`linedefs`,`sectors`,`things`).
data Context = Context { location :: Point
, orientation :: Orientation
, linedefs :: [Line]
, sectors :: [Sector]
, things :: [Thing]
-- "palette": thing type; texture choices, etc
, curThingType :: Int
, paletteTop :: String
, paletteMid :: String
, paletteBot :: String
, paletteFloor :: String
, paletteCeil :: String
, paletteLineType :: Int
, paletteLineTag :: Int
, paletteSectorType :: Int
, paletteSectorTag :: Int
, paletteXoff :: Int
, paletteYoff :: Int
, mapName :: String
} deriving (Show, Eq)
-- | An approximation of Doom's Sector data-type, with unboxed fields.
-- Unlike Doom's Sector data structure, we maintain a list of lines
-- that belong to a given Sector.
data Sector = Sector { floorHeight :: Int
, ceilHeight :: Int
, floorFlat :: String
, ceilFlat :: String
, lightLevel :: Int
, sectorType :: Int
, sectorTag :: Int
, sectorLines :: [Line]
} deriving (Show, Eq)
-- XXX all are short (unsigned?) ints, 8 byte strings
-- | An approximation of Doom's Thing data-type, with unboxed fields.
data Thing = Thing { thingPos :: Point
, thingAngle :: Int -- all shorts
, thingType :: Int
, thingFlags :: Int
} deriving (Show, Eq)
-- | An initial Context, from which to derive a new map. `Empty` lines
-- and `Sector` lists and sensible default values for "palette" parameters.
start :: Context
start = Context { location=(0,0)
, orientation=North
, linedefs=[]
, sectors=[]
, curThingType=1
, things=[]
, paletteTop="STARTAN3"
, paletteMid="STARTAN3"
, paletteBot="STARTAN3"
, paletteFloor="FLAT23"
, paletteCeil="F_SKY1"
, paletteLineType=0
, paletteLineTag=0
, paletteSectorType=0
, paletteSectorTag=0
, mapName="MAP01"
, paletteXoff=0
, paletteYoff=0
}