aboutsummaryrefslogtreecommitdiff
path: root/src/Game
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-02-23 12:21:24 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-02-23 12:21:24 +0000
commitce13d7eaa45b59647325b97e40906c54dbcf4b38 (patch)
tree7de8d3ddf19313c54f892fb9024d161835921354 /src/Game
parent3312d78396821bf8fee9e158066fde05bde77a9e (diff)
downloadspace-plat-hs-ce13d7eaa45b59647325b97e40906c54dbcf4b38.tar.gz
space-plat-hs-ce13d7eaa45b59647325b97e40906c54dbcf4b38.zip
Bitmap font
Diffstat (limited to 'src/Game')
-rw-r--r--src/Game/BitmapFont.hs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/Game/BitmapFont.hs b/src/Game/BitmapFont.hs
new file mode 100644
index 0000000..d42f293
--- /dev/null
+++ b/src/Game/BitmapFont.hs
@@ -0,0 +1,49 @@
+module Game.BitmapFont (BitmapFont, load, renderText) where
+
+import Control.Monad
+import Data.Map (Map)
+import qualified Data.Map as Map
+import Data.Maybe (fromMaybe)
+import Foreign.C.Types (CInt)
+import qualified Game.Utils as U
+import qualified SDL
+import Text.JSON
+
+data FontDesc = FontDesc Int Int (Map Char (SDL.Rectangle CInt))
+
+data BitmapFont = BitmapFont FontDesc SDL.Texture
+
+instance JSON FontDesc where
+ showJSON = undefined
+ readJSON (JSObject obj) = do
+ w <- valFromObj "width" obj
+ h <- valFromObj "height" obj
+ m <- valFromObj "map" obj
+ pure $ FontDesc w h $ Map.fromList (zipWith (curry (toRect w h)) m [0 ..])
+ where
+ -- we store a Map from char to the SDL rect containing the glyph
+ toRect :: Int -> Int -> (Char, Int) -> (Char, SDL.Rectangle CInt)
+ toRect w h (c, i) = (c, U.rect (i * w) 0 w h)
+ readJSON _ = mzero
+
+-- | Load a bitmap font description from a JSON file.
+--
+-- The texture is expected to have the glyphs in a single line plus a special one at the end to be used when a character is not found in the font map.
+load :: String -> SDL.Texture -> IO BitmapFont
+load filename tex = do
+ d <- readFile filename
+ case decode d :: Result FontDesc of
+ Ok desc -> pure $ BitmapFont desc tex
+ Error e -> error e
+
+-- | Render a string at position x, y using the prodided bitmap font.
+renderText :: SDL.Renderer -> BitmapFont -> Int -> Int -> String -> IO ()
+renderText renderer (BitmapFont (FontDesc w h m) tex) x y text = mapM_ renderOne (zip [0 ..] text)
+ where
+ renderOne :: (Int, Char) -> IO ()
+ renderOne (i, c) =
+ SDL.copy renderer tex (Just src) (Just dst)
+ where
+ -- find the glyph or render the special one as error
+ src = fromMaybe (U.rect (length m * w) 0 w h) (Map.lookup c m)
+ dst = U.rect (x + i * w) y w h