From f9bbd7dce31a09bdc9f71c4372682322cbcbf6fe Mon Sep 17 00:00:00 2001 From: Michael Twomey Date: Tue, 15 Nov 2016 19:45:18 +0000 Subject: [PATCH] Upgrade to Elm 0.18 As a side effect of running `elm upgrade` we're also formatted using `elm format`. Upgrade dependencies to 0.18 versions. --- Makefile | 8 + elm-package.json | 14 +- examples/Basic.elm | 15 +- examples/HelloPico8.elm | 29 +- examples/HelloWorld.elm | 64 +++-- src/Elmo8/Console.elm | 90 +++++-- src/Elmo8/Display.elm | 82 ++++-- src/Elmo8/Layers/Background.elm | 7 +- src/Elmo8/Layers/Common.elm | 11 +- src/Elmo8/Layers/Pixels.elm | 99 ++++--- src/Elmo8/Layers/Sprites.elm | 65 +++-- src/Elmo8/Layers/Text.elm | 354 ++++++++++++++----------- src/Elmo8/Pico8.elm | 92 +++++-- src/Elmo8/Textures/Pico8Font.elm | 5 +- src/Elmo8/Textures/Pico8PaletteMap.elm | 5 +- 15 files changed, 596 insertions(+), 344 deletions(-) diff --git a/Makefile b/Makefile index 1eca65a..b2d8bac 100644 --- a/Makefile +++ b/Makefile @@ -26,3 +26,11 @@ $(PICO_8_FONT_ELM): Makefile $(CONVERTER) $(PICO_8_FONT_PNG) documentation.json: $(SOURCES) elm make --docs=documentation.json --warn + +.PHONY: format +format: + elm format --upgrade --yes src/ examples/ + +.PHONY: upgrade +upgrade: + elm upgrade diff --git a/elm-package.json b/elm-package.json index 0638b6f..8564b78 100644 --- a/elm-package.json +++ b/elm-package.json @@ -12,12 +12,12 @@ "Elmo8.Pico8" ], "dependencies": { - "elm-community/elm-linear-algebra": "2.0.3 <= v < 3.0.0", - "elm-community/elm-webgl": "3.0.3 <= v < 4.0.0", - "elm-lang/animation-frame": "1.0.0 <= v < 2.0.0", - "elm-lang/core": "4.0.5 <= v < 5.0.0", - "elm-lang/html": "1.1.0 <= v < 2.0.0", - "elm-lang/window": "1.0.0 <= v < 2.0.0" + "elm-community/linear-algebra": "1.0.0 <= v < 2.0.0", + "elm-community/webgl": "1.0.0 <= v < 2.0.0", + "elm-lang/animation-frame": "1.0.1 <= v < 2.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", + "elm-lang/window": "1.0.1 <= v < 2.0.0" }, - "elm-version": "0.17.0 <= v < 0.18.0" + "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/examples/Basic.elm b/examples/Basic.elm index 76abfb9..3ed4a5b 100644 --- a/examples/Basic.elm +++ b/examples/Basic.elm @@ -1,19 +1,26 @@ +module Main exposing (..) + import Elmo8.Console as Console import Elmo8.Pico8 as Pico8 -type alias Model = {} -draw : Model -> List Console.Command +type alias Model = + {} + + +draw : Model -> List Console.Command draw model = [ Console.putPixel 10 10 Pico8.peach , Console.print "Hello World" 10 50 Pico8.orange , Console.sprite 0 60 90 ] + update : Model -> Model -update model = model +update model = + model + -main : Program Never main = Console.boot { draw = draw diff --git a/examples/HelloPico8.elm b/examples/HelloPico8.elm index b6cc0a8..f822408 100644 --- a/examples/HelloPico8.elm +++ b/examples/HelloPico8.elm @@ -1,3 +1,5 @@ +module Main exposing (..) + {-| PICO-8 style hello world Draws pixels in the corners, writes a message and then shows a sprite. @@ -9,27 +11,32 @@ This uses the full PICO-8 API for all functions, which can be a little unwieldy import Elmo8.Console as Console import Elmo8.Pico8 as Pico8 -type alias Model = {} -draw : Model -> List Console.Command +type alias Model = + {} + + +draw : Model -> List Console.Command draw model = [ Pico8.pset 0 0 Pico8.red , Pico8.pset 127 0 Pico8.yellow , Pico8.pset 0 127 Pico8.green , Pico8.pset 127 127 Pico8.blue , Pico8.print "Hello" 20 20 Pico8.orange - -- Note that Elmo8.Console's sprite is simpler + -- Note that Elmo8.Console's sprite is simpler , Pico8.spr 0 60 30 1 1 False False ] + update : Model -> Model -update model = model +update model = + model + -main : Program Never main = - Console.boot - { draw = draw - , init = {} - , update = update - , spritesUrl = "birdwatching.png" - } + Console.boot + { draw = draw + , init = {} + , update = update + , spritesUrl = "birdwatching.png" + } diff --git a/examples/HelloWorld.elm b/examples/HelloWorld.elm index 13518c2..a9794be 100644 --- a/examples/HelloWorld.elm +++ b/examples/HelloWorld.elm @@ -1,3 +1,5 @@ +module Main exposing (..) + {-| PICO-8's Hello.lua redone in ELMO-8 Couple of differences: @@ -7,50 +9,66 @@ Couple of differences: import Elmo8.Console as Console -type alias Model = { - t : Int -} + +type alias Model = + { t : Int + } + init : Model -init = { t = 0 } +init = + { t = 0 } + update : Model -> Model update model = { model | t = model.t + 1 } + draw_letter : Int -> Int -> Int -> List Console.Command draw_letter t i j0 = let - j = 7 - j0 - col = 7 + j - t1 = t + i*4 - j*2 + j = + 7 - j0 + + col = + 7 + j + + t1 = + t + i * 4 - j * 2 + -- x = cos(t) * 5 -- PICO-8 example: cos(nil) * 5 -> 1 * 5 - x = 5 - y = 38 + j + cos(t1/3.5) * 5 + x = + 5 + + y = + 38.0 + toFloat (j) + cos (toFloat (t1) / 3.5) * 5.0 in - [ Console.sprite (16+i) (8+i*8 + x + 2) (round y + 2) - , Console.sprite (32+i) (8+i*8 + x + 1) (round y + 1) - , Console.sprite (48+i) (8+i*8 + x) (round y) + [ Console.sprite (16 + i) (8 + i * 8 + x + 2) (round y + 2) + , Console.sprite (32 + i) (8 + i * 8 + x + 1) (round y + 1) + , Console.sprite (48 + i) (8 + i * 8 + x) (round y) ] -draw : Model -> List Console.Command + +draw : Model -> List Console.Command draw model = - [ List.map2 (\i j -> draw_letter model.t i j) [1..11] [0..10] |> List.concat - , List.map (\i -> Console.putPixel i 0 i) [0..15] + [ List.map2 (\i j -> draw_letter model.t i j) (List.range 1 11) (List.range 0 10) |> List.concat + , List.map (\i -> Console.putPixel i 0 i) (List.range 0 15) , [ Console.sprite 1 60 100 , Console.putPixel 9 79 10 , Console.print "Welcome to ELMO-8!" 10 80 9 , Console.print "Hello World" 0 1 6 , Console.print "Ö" 60 120 5 ] - ] |> List.concat + ] + |> List.concat + -main : Program Never main = - Console.boot - { draw = draw - , init = init - , update = update - , spritesUrl = "hello_world.png" - } + Console.boot + { draw = draw + , init = init + , update = update + , spritesUrl = "hello_world.png" + } diff --git a/src/Elmo8/Console.elm b/src/Elmo8/Console.elm index e50627e..78acbc0 100644 --- a/src/Elmo8/Console.elm +++ b/src/Elmo8/Console.elm @@ -50,28 +50,33 @@ To start up the console you need to do a little bit of configuration (the patter import AnimationFrame import Html import Html.Attributes -import Html.App import Time exposing (..) - import Elmo8.Display + type alias Model model = { display : Elmo8.Display.Model , model : model , lastTick : Time.Time } -type alias Colour = Int + +type alias Colour = + Int + {-| Represents the console for interacting via functions -} -type Console model = A (Model model) +type Console model + = A (Model model) + type Msg = DisplayMsg Elmo8.Display.Msg | Tick Time.Time + {-| Commands to give to the console Normally you don't create these directly, instead use the drawing functions to interact with the console. @@ -80,12 +85,13 @@ Normally you don't create these directly, instead use the drawing functions to i type Command = PutPixel Int Int Colour | Print Int Int Colour String - | Sprite { x: Int, y: Int, index: Int } + | Sprite { x : Int, y : Int, index : Int } | PixelPalette Int Int | ScreenPalette Int Int | ResetPalette | Noop String + {-| Draw a pixel at the given position (x, y) e.g. putPixel 64 64 9 -> draw a pixel in the middle and set the colour to orange (9). @@ -97,6 +103,7 @@ putPixel : Int -> Int -> Colour -> Command putPixel x y colour = PutPixel x y colour + {-| Read a colour value from the given pixel -} @@ -104,6 +111,7 @@ getPixel : Console model -> Int -> Int -> Colour getPixel (A console) x y = Elmo8.Display.getPixel console.display x y + {-| Print a string at the given position -} @@ -111,6 +119,7 @@ print : String -> Int -> Int -> Colour -> Command print string x y colour = Print x y colour string + {-| Remap a colour in the palette used for drawing operations (See screenPalette for the `pal c0 c1 1` operation.) @@ -131,6 +140,7 @@ palette : Colour -> Colour -> Command palette old new = PixelPalette old new + {-| Remap a colour globally (screen) Equivalent to PICO-8 `pal c0 c1 1` @@ -142,11 +152,14 @@ screenPalette : Colour -> Colour -> Command screenPalette old new = ScreenPalette old new + {-| Reset all palette remappings -} resetPalette : Command -resetPalette = ResetPalette +resetPalette = + ResetPalette + {-| Render a sprite (n) at the given position (x, y) @@ -161,72 +174,94 @@ To render sprite 0 at (10, 10): -} sprite : Int -> Int -> Int -> Command sprite n x y = - Sprite {x = x, y = y, index = n} + Sprite { x = x, y = y, index = n } + -init : model -> String -> (Model model, Cmd Msg) +init : model -> String -> ( Model model, Cmd Msg ) init model spritesUrl = let - (displayModel, displayMsg) = Elmo8.Display.init spritesUrl + ( displayModel, displayMsg ) = + Elmo8.Display.init spritesUrl in { display = displayModel, model = model, lastTick = 0 } - ! [ Cmd.map DisplayMsg displayMsg ] + ! [ Cmd.map DisplayMsg displayMsg ] processCommand : Command -> Model model -> Model model processCommand command model = case command of - Noop message -> model + Noop message -> + model + PutPixel x y colour -> { model | display = Elmo8.Display.setPixel model.display x y colour } + Sprite s -> { model | display = Elmo8.Display.sprite model.display s } + Print x y colour string -> { model | display = Elmo8.Display.print model.display x y colour string } + PixelPalette from to -> { model | display = Elmo8.Display.pixelPalette model.display from to } + ScreenPalette from to -> { model | display = Elmo8.Display.screenPalette model.display from to } + ResetPalette -> { model | display = Elmo8.Display.resetPalette model.display } -update : (model -> List Command) -> (model -> model) -> Msg -> Model model -> (Model model, Cmd Msg) + +update : (model -> List Command) -> (model -> model) -> Msg -> Model model -> ( Model model, Cmd Msg ) update draw updateModel msg model = case msg of Tick time -> let - shouldTick = (time - model.lastTick) >= (1.0 / 30) + shouldTick = + (time - model.lastTick) >= (1.0 / 30) in case shouldTick of True -> let - clearedDisplayModel = { model | display = Elmo8.Display.clear model.display } - commands = draw model.model - updatedModel = List.foldl processCommand clearedDisplayModel commands + clearedDisplayModel = + { model | display = Elmo8.Display.clear model.display } + + commands = + draw model.model + + updatedModel = + List.foldl processCommand clearedDisplayModel commands in - { updatedModel | model = updateModel model.model, lastTick = time } ! [ ] + { updatedModel | model = updateModel model.model, lastTick = time } ! [] + False -> model ! [] + DisplayMsg displayMsg -> let - (display, cmd) = Elmo8.Display.update displayMsg model.display + ( display, cmd ) = + Elmo8.Display.update displayMsg model.display in - { model | display = display} ! [ Cmd.map DisplayMsg cmd ] + { model | display = display } ! [ Cmd.map DisplayMsg cmd ] + subscriptions : Model model -> Sub Msg subscriptions model = AnimationFrame.times (Tick << Time.inSeconds) + view : Model model -> Html.Html Msg view model = Html.div [ Html.Attributes.style [ ( "background-color", "#000" ) - , ( "display", "flex" ) - , ( "align-items", "center") + , ( "display", "flex" ) + , ( "align-items", "center" ) , ( "justify-content", "center" ) ] ] - [ Elmo8.Display.view model.display |> Html.App.map DisplayMsg ] + [ Elmo8.Display.view model.display |> Html.map DisplayMsg ] + {-| Console configuration @@ -240,20 +275,21 @@ spriteUrl (String) is a URL pointing to a 128x128 sprite sheet (16x16 8x8 sprite -} type alias Config model = - { draw: model -> List Command - , update: model -> model - , init: model + { draw : model -> List Command + , update : model -> model + , init : model , spritesUrl : String } + {-| Boot your console! Supply a Config. -} -boot : Config model -> Program Never +boot : Config model -> Program Never (Model model) Msg boot config = - Html.App.program + Html.program { init = init config.init config.spritesUrl , update = update config.draw config.update , subscriptions = subscriptions diff --git a/src/Elmo8/Display.elm b/src/Elmo8/Display.elm index ccb089c..dd58a5e 100644 --- a/src/Elmo8/Display.elm +++ b/src/Elmo8/Display.elm @@ -15,61 +15,79 @@ import Elmo8.Layers.Pixels import Elmo8.Layers.Text import Elmo8.Layers.Sprites + type alias Model = { windowSize : Window.Size - , canvasSize: CanvasSize + , canvasSize : CanvasSize , pixels : Elmo8.Layers.Pixels.Model , text : Elmo8.Layers.Text.Model , sprites : Elmo8.Layers.Sprites.Model } + type Msg = PixelsMsg Elmo8.Layers.Pixels.Msg | TextMsg Elmo8.Layers.Text.Msg | SpritesMsg Elmo8.Layers.Sprites.Msg + clear : Model -> Model clear model = { model - | sprites = Elmo8.Layers.Sprites.clear model.sprites - , text = Elmo8.Layers.Text.clear model.text + | sprites = Elmo8.Layers.Sprites.clear model.sprites + , text = Elmo8.Layers.Text.clear model.text } + setPixel : Model -> Int -> Int -> Int -> Model setPixel model x y colour = { model | pixels = Elmo8.Layers.Pixels.setPixel model.pixels x y colour } + getPixel : Model -> Int -> Int -> Int getPixel model x y = Elmo8.Layers.Pixels.getPixel model.pixels x y -sprite : Model -> { x: Int, y: Int, index: Int } -> Model + +sprite : Model -> { x : Int, y : Int, index : Int } -> Model sprite model s = { model | sprites = Elmo8.Layers.Sprites.sprite model.sprites s } + pixelPalette : Model -> Int -> Int -> Model pixelPalette model from to = { model | pixels = Elmo8.Layers.Pixels.pixelPalette model.pixels from to } + screenPalette : Model -> Int -> Int -> Model screenPalette model from to = { model | pixels = Elmo8.Layers.Pixels.screenPalette model.pixels from to } + resetPalette : Model -> Model resetPalette model = { model | pixels = Elmo8.Layers.Pixels.resetPalette model.pixels } + print : Model -> Int -> Int -> Int -> String -> Model print model x y colour string = { model | text = Elmo8.Layers.Text.print model.text x y colour string } -init : String -> (Model, Cmd Msg) + +init : String -> ( Model, Cmd Msg ) init spritesUrl = let - canvasSize = { width = 512.0, height = 512.0} - (pixels, pixelsCmd) = Elmo8.Layers.Pixels.init canvasSize - (text, textCmd) = Elmo8.Layers.Text.init canvasSize - (sprites, spritesCmd) = Elmo8.Layers.Sprites.init canvasSize spritesUrl + canvasSize = + { width = 512.0, height = 512.0 } + + ( pixels, pixelsCmd ) = + Elmo8.Layers.Pixels.init canvasSize + + ( text, textCmd ) = + Elmo8.Layers.Text.init canvasSize + + ( sprites, spritesCmd ) = + Elmo8.Layers.Sprites.init canvasSize spritesUrl in { windowSize = { width = 0, height = 0 } , canvasSize = canvasSize @@ -77,54 +95,60 @@ init spritesUrl = , text = text , sprites = sprites } - ! - [ Cmd.map PixelsMsg pixelsCmd - , Cmd.map TextMsg textCmd - , Cmd.map SpritesMsg spritesCmd - ] + ! [ Cmd.map PixelsMsg pixelsCmd + , Cmd.map TextMsg textCmd + , Cmd.map SpritesMsg spritesCmd + ] + -update : Msg -> Model -> (Model, Cmd Msg) +update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of PixelsMsg pixelsMsg -> let - (pixels, cmd) = Elmo8.Layers.Pixels.update pixelsMsg model.pixels + ( pixels, cmd ) = + Elmo8.Layers.Pixels.update pixelsMsg model.pixels in { model | pixels = pixels } ! [ Cmd.map PixelsMsg cmd ] + TextMsg sms -> let - (text, cmd) = Elmo8.Layers.Text.update sms model.text + ( text, cmd ) = + Elmo8.Layers.Text.update sms model.text in { model | text = text } ! [ Cmd.map TextMsg cmd ] + SpritesMsg spritesMsg -> let - (sprites, cmd) = Elmo8.Layers.Sprites.update spritesMsg model.sprites + ( sprites, cmd ) = + Elmo8.Layers.Sprites.update spritesMsg model.sprites in { model | sprites = sprites } ! [ Cmd.map SpritesMsg cmd ] + getRenderables : Model -> List WebGL.Renderable getRenderables model = List.concat - [ - -- TODO: Text disabled due to problems - Elmo8.Layers.Text.render model.text, - Elmo8.Layers.Pixels.render model.pixels - , Elmo8.Layers.Sprites.render model.sprites - ] + [ -- TODO: Text disabled due to problems + Elmo8.Layers.Text.render model.text + , Elmo8.Layers.Pixels.render model.pixels + , Elmo8.Layers.Sprites.render model.sprites + ] + view : Model -> Html.Html Msg view model = WebGL.toHtmlWith [ WebGL.Enable WebGL.Blend - , WebGL.BlendFunc (WebGL.SrcAlpha, WebGL.OneMinusSrcAlpha) + , WebGL.BlendFunc ( WebGL.SrcAlpha, WebGL.OneMinusSrcAlpha ) ] [ Html.Attributes.width (round model.canvasSize.width) , Html.Attributes.height (round model.canvasSize.height) , Html.Attributes.style - [ ("display", "block") - -- , ("margin-left", "auto") - -- , ("margin-right", "auto") - -- , ("border", "1px solid red") + [ ( "display", "block" ) + -- , ("margin-left", "auto") + -- , ("margin-right", "auto") + -- , ("border", "1px solid red") ] ] (getRenderables model) diff --git a/src/Elmo8/Layers/Background.elm b/src/Elmo8/Layers/Background.elm index 5a0e58a..a045a0a 100644 --- a/src/Elmo8/Layers/Background.elm +++ b/src/Elmo8/Layers/Background.elm @@ -14,8 +14,11 @@ import WebGL -- From http://blog.tojicode.com/2012/07/sprite-tile-maps-on-gpu.html -- TODO: make this work :) -tileMapVertextShader : WebGL.Shader { attr | position : Vec2, texture : Vec2} { uniform | viewOffset : Vec2, viewportSize : Vec2, inverseTileTextureSize : Vec2, inverseTileSize : Float} { pixelCoord : Vec2, texCoord : Vec2 } -tileMapVertextShader = [glsl| + + +tileMapVertextShader : WebGL.Shader { attr | position : Vec2, texture : Vec2 } { uniform | viewOffset : Vec2, viewportSize : Vec2, inverseTileTextureSize : Vec2, inverseTileSize : Float } { pixelCoord : Vec2, texCoord : Vec2 } +tileMapVertextShader = + [glsl| precision mediump float; attribute vec2 position; attribute vec2 texture; diff --git a/src/Elmo8/Layers/Common.elm b/src/Elmo8/Layers/Common.elm index 5591c9c..84f9f96 100644 --- a/src/Elmo8/Layers/Common.elm +++ b/src/Elmo8/Layers/Common.elm @@ -5,16 +5,21 @@ module Elmo8.Layers.Common exposing (..) -} import Math.Vector2 exposing (Vec2) -import Math.Matrix4 exposing(Mat4, makeOrtho2D) +import Math.Matrix4 exposing (Mat4, makeOrtho2D) + {-| Canvas size is the physical size of the canvas WebGL is rendering to This is used to scale the pixel sizes correctly. -} -type alias CanvasSize = { width: Float, height: Float} +type alias CanvasSize = + { width : Float, height : Float } + + +type alias Vertex = + { position : Vec2 } -type alias Vertex = { position : Vec2 } {-| Create a 2D projection matrix. diff --git a/src/Elmo8/Layers/Pixels.elm b/src/Elmo8/Layers/Pixels.elm index 2776d5f..786782d 100644 --- a/src/Elmo8/Layers/Pixels.elm +++ b/src/Elmo8/Layers/Pixels.elm @@ -8,23 +8,30 @@ The most basic layer, theoretically all you need :) import Dict import Math.Vector2 exposing (Vec2, vec2, fromTuple) -import Math.Matrix4 exposing(Mat4, makeOrtho2D) +import Math.Matrix4 exposing (Mat4, makeOrtho2D) import Task import WebGL - import Elmo8.Layers.Common exposing (CanvasSize, Vertex, makeProjectionMatrix) import Elmo8.Textures.Pico8PaletteMap exposing (pico8PaletteMapDataUri) -type alias X = Int -type alias Y = Int + +type alias X = + Int + + +type alias Y = + Int + {-| An index into the palette, usually 0 - 15 for 16 colour palettes -} -type alias PixelColour = Int +type alias PixelColour = + Int + type alias Model = - { pixels : Dict.Dict (X, Y) PixelColour + { pixels : Dict.Dict ( X, Y ) PixelColour , screenSize : Vec2 , maybePalette : Maybe WebGL.Texture , pixelPalette : Dict.Dict PixelColour PixelColour @@ -34,45 +41,53 @@ type alias Model = , projectionMatrix : Mat4 } + type Msg = SetPixel X Y PixelColour | TextureError WebGL.Error | TextureLoad WebGL.Texture | Clear + setPixel : Model -> Int -> Int -> PixelColour -> Model setPixel model x y colour = - { model | pixels = Dict.insert (x, y) colour model.pixels } + { model | pixels = Dict.insert ( x, y ) colour model.pixels } + getPixel : Model -> Int -> Int -> PixelColour getPixel model x y = - Dict.get (x, y) model.pixels + Dict.get ( x, y ) model.pixels |> Maybe.withDefault 0 + pixelPalette : Model -> PixelColour -> PixelColour -> Model pixelPalette model from to = { model | pixelPalette = Dict.insert from to model.pixelPalette } + screenPalette : Model -> PixelColour -> PixelColour -> Model screenPalette model from to = { model | screenPalette = Dict.insert from to model.screenPalette } + resetPalette : Model -> Model resetPalette model = - { model | screenPalette = Dict.empty , pixelPalette = Dict.empty } + { model | screenPalette = Dict.empty, pixelPalette = Dict.empty } + -corners : Dict.Dict (X, Y) PixelColour +corners : Dict.Dict ( X, Y ) PixelColour corners = Dict.fromList - [ ( (0, 0), 0 ) - , ( (127, 0), 1 ) - , ( (127, 127), 2 ) - , ( (0, 127), 3 ) - , ( (0, 126), 4 ) - , ( (63, 63), 5 ) + [ ( ( 0, 0 ), 0 ) + , ( ( 127, 0 ), 1 ) + , ( ( 127, 127 ), 2 ) + , ( ( 0, 127 ), 3 ) + , ( ( 0, 126 ), 4 ) + , ( ( 63, 63 ), 5 ) ] -init : CanvasSize -> (Model, Cmd Msg) + +init : CanvasSize -> ( Model, Cmd Msg ) init canvasSize = { pixels = Dict.empty , screenSize = vec2 128.0 128.0 @@ -83,32 +98,48 @@ init canvasSize = , paletteSize = vec2 16.0 16.0 , projectionMatrix = makeProjectionMatrix } - ! - [ WebGL.loadTexture pico8PaletteMapDataUri |> Task.perform TextureError TextureLoad - ] + ! [ WebGL.loadTexture pico8PaletteMapDataUri + |> Task.attempt + (\result -> + case result of + Err err -> + TextureError err + + Ok val -> + TextureLoad val + ) + ] + -update : Msg -> Model -> (Model, Cmd Msg) +update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of SetPixel x y colour -> - { model | pixels = Dict.insert (x, y) colour model.pixels } ! [] + { model | pixels = Dict.insert ( x, y ) colour model.pixels } ! [] + Clear -> { model | pixels = Dict.empty } ! [] + TextureError error -> model ! [] + TextureLoad texture -> { model | maybePalette = Just texture } ! [] + render : Model -> List WebGL.Renderable render model = case model.maybePalette of - Nothing -> [] + Nothing -> + [] + Just texture -> Dict.toList model.pixels |> List.map (renderPixel model texture) -renderPixel : Model -> WebGL.Texture -> ((X, Y), PixelColour) -> WebGL.Renderable -renderPixel model texture ((x, y), colour) = + +renderPixel : Model -> WebGL.Texture -> ( ( X, Y ), PixelColour ) -> WebGL.Renderable +renderPixel model texture ( ( x, y ), colour ) = WebGL.render pixelsVertexShader pixelsFragmentShader @@ -124,15 +155,15 @@ renderPixel model texture ((x, y), colour) = , remap = Dict.get colour model.screenPalette |> Maybe.withDefault 0 } + mesh : WebGL.Drawable Vertex mesh = - WebGL.Points [ Vertex (vec2 0 0)] + WebGL.Points [ Vertex (vec2 0 0) ] + -pixelsVertexShader : WebGL.Shader - { attr | position : Vec2 } - { unif | canvasSize : Vec2, screenSize : Vec2, projectionMatrix : Mat4, pixelX : Int, pixelY : Int, index : Int, remap : Int } - { colourIndex : Float, colourRemap : Float } -pixelsVertexShader = [glsl| +pixelsVertexShader : WebGL.Shader { attr | position : Vec2 } { unif | canvasSize : Vec2, screenSize : Vec2, projectionMatrix : Mat4, pixelX : Int, pixelY : Int, index : Int, remap : Int } { colourIndex : Float, colourRemap : Float } +pixelsVertexShader = + [glsl| precision mediump float; attribute vec2 position; uniform vec2 canvasSize; @@ -154,8 +185,10 @@ pixelsVertexShader = [glsl| } |] -pixelsFragmentShader : WebGL.Shader {} { uniform | paletteTexture : WebGL.Texture , paletteSize : Vec2 } { colourIndex : Float, colourRemap : Float } -pixelsFragmentShader = [glsl| + +pixelsFragmentShader : WebGL.Shader {} { uniform | paletteTexture : WebGL.Texture, paletteSize : Vec2 } { colourIndex : Float, colourRemap : Float } +pixelsFragmentShader = + [glsl| precision mediump float; uniform sampler2D paletteTexture; uniform vec2 paletteSize; diff --git a/src/Elmo8/Layers/Sprites.elm b/src/Elmo8/Layers/Sprites.elm index bcf97c2..469d0fd 100644 --- a/src/Elmo8/Layers/Sprites.elm +++ b/src/Elmo8/Layers/Sprites.elm @@ -6,12 +6,14 @@ import Task import WebGL import Elmo8.Layers.Common exposing (CanvasSize, makeProjectionMatrix, Vertex) + type alias Sprite = - { sprite: Int + { sprite : Int , x : Int , y : Int } + type alias Model = { maybeTexture : Maybe WebGL.Texture , sprites : List Sprite @@ -21,22 +23,24 @@ type alias Model = , projectionMatrix : Mat4 } + type Msg = TextureLoad WebGL.Texture | TextureError WebGL.Error -sprite : Model -> { x: Int, y: Int, index: Int } -> Model -sprite model {x, y, index} = +sprite : Model -> { x : Int, y : Int, index : Int } -> Model +sprite model { x, y, index } = -- TODO replace this with something less memory leaky, Set isn't any use, probably use Lazy if possible, or a Dict - { model | sprites = (Sprite index x y ) :: model.sprites } + { model | sprites = (Sprite index x y) :: model.sprites } + clear : Model -> Model clear model = { model | sprites = [] } -init : CanvasSize -> String -> (Model, Cmd Msg) +init : CanvasSize -> String -> ( Model, Cmd Msg ) init canvasSize uri = { maybeTexture = Nothing , sprites = [] @@ -44,23 +48,34 @@ init canvasSize uri = , screenSize = vec2 canvasSize.width canvasSize.height , textureSize = vec2 0 0 , projectionMatrix = makeProjectionMatrix - } ! - [ WebGL.loadTexture uri |> Task.perform TextureError TextureLoad - ] + } + ! [ WebGL.loadTexture uri + |> Task.attempt + (\result -> + case result of + Err err -> + TextureError err + + Ok val -> + TextureLoad val + ) + ] + -update : Msg -> Model -> (Model, Cmd Msg) +update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of TextureLoad texture -> - {model + { model | maybeTexture = Just texture - , textureSize = vec2 (toFloat (fst (WebGL.textureSize texture))) (toFloat (snd (WebGL.textureSize texture))) + , textureSize = vec2 (toFloat (Tuple.first (WebGL.textureSize texture))) (toFloat (Tuple.second (WebGL.textureSize texture))) } - ! - [] + ! [] + TextureError _ -> model ! [] + renderSprite : Model -> WebGL.Texture -> Sprite -> WebGL.Renderable renderSprite model texture sprite = WebGL.render @@ -76,10 +91,13 @@ renderSprite model texture sprite = , spriteIndex = sprite.sprite } + render : Model -> List WebGL.Renderable render model = case model.maybeTexture of - Nothing -> [] + Nothing -> + [] + Just texture -> List.map (renderSprite model texture) model.sprites @@ -88,17 +106,16 @@ render model = -} mesh : WebGL.Drawable Vertex -mesh = +mesh = WebGL.Triangle [ ( Vertex (vec2 0 0), Vertex (vec2 8 8), Vertex (vec2 8 0) ) , ( Vertex (vec2 0 0), Vertex (vec2 0 8), Vertex (vec2 8 8) ) ] -vertexShader : WebGL.Shader - {attr | position : Vec2 } - {unif | screenSize : Vec2, projectionMatrix : Mat4, spriteX: Int, spriteY: Int } - {texturePos : Vec2} -vertexShader = [glsl| + +vertexShader : WebGL.Shader { attr | position : Vec2 } { unif | screenSize : Vec2, projectionMatrix : Mat4, spriteX : Int, spriteY : Int } { texturePos : Vec2 } +vertexShader = + [glsl| precision mediump float; attribute vec2 position; uniform int spriteX; @@ -113,11 +130,9 @@ vertexShader = [glsl| |] -fragmentShader : WebGL.Shader - {} - {u | texture : WebGL.Texture, textureSize : Vec2, projectionMatrix : Mat4, spriteIndex : Int } - {texturePos : Vec2} -fragmentShader = [glsl| +fragmentShader : WebGL.Shader {} { u | texture : WebGL.Texture, textureSize : Vec2, projectionMatrix : Mat4, spriteIndex : Int } { texturePos : Vec2 } +fragmentShader = + [glsl| precision mediump float; uniform mat4 projectionMatrix; uniform sampler2D texture; diff --git a/src/Elmo8/Layers/Text.elm b/src/Elmo8/Layers/Text.elm index 7879e98..42a00b8 100644 --- a/src/Elmo8/Layers/Text.elm +++ b/src/Elmo8/Layers/Text.elm @@ -2,16 +2,18 @@ module Elmo8.Layers.Text exposing (..) import Dict import Math.Vector2 exposing (Vec2, vec2) -import Math.Matrix4 exposing(Mat4, makeOrtho2D) +import Math.Matrix4 exposing (Mat4, makeOrtho2D) import String import Task import WebGL - import Elmo8.Layers.Common exposing (CanvasSize, Vertex, makeProjectionMatrix) import Elmo8.Textures.Pico8Font exposing (pico8FontDataUri) import Elmo8.Textures.Pico8PaletteMap exposing (pico8PaletteMapDataUri) + -- TODO: represent more of the metrics for better layout. + + type alias Character = { x : Int , y : Int @@ -19,6 +21,7 @@ type alias Character = , height : Int } + type alias Message = { x : Int , y : Int @@ -26,32 +29,37 @@ type alias Message = , characters : String } + type alias Model = { maybeTexture : Maybe WebGL.Texture , textureSize : Vec2 , maybePaletteTexture : Maybe WebGL.Texture , paletteTextureSize : Vec2 , messages : List Message - , meshes : Dict.Dict (Int, Int) (WebGL.Drawable Vertex) + , meshes : Dict.Dict ( Int, Int ) (WebGL.Drawable Vertex) , canvasSize : Vec2 , projectionMatrix : Mat4 } + type Msg = TextureLoad WebGL.Texture | TextureError WebGL.Error | PaletteTextureLoad WebGL.Texture | PaletteTextureError WebGL.Error + clear : Model -> Model clear model = { model | messages = [] } + print : Model -> Int -> Int -> Int -> String -> Model print model x y colour string = { model | messages = (Message x y colour string) :: model.messages } -init : CanvasSize -> (Model, Cmd Msg) + +init : CanvasSize -> ( Model, Cmd Msg ) init canvasSize = { maybeTexture = Nothing , messages = [] @@ -62,29 +70,51 @@ init canvasSize = , maybePaletteTexture = Nothing , paletteTextureSize = vec2 16.0 16.0 } - ! - [ WebGL.loadTexture pico8FontDataUri |> Task.perform TextureError TextureLoad - , WebGL.loadTexture pico8PaletteMapDataUri |> Task.perform PaletteTextureError PaletteTextureLoad - ] + ! [ WebGL.loadTexture pico8FontDataUri + |> Task.attempt + (\result -> + case result of + Err err -> + TextureError err + + Ok val -> + TextureLoad val + ) + , WebGL.loadTexture pico8PaletteMapDataUri + |> Task.attempt + (\result -> + case result of + Err err -> + PaletteTextureError err -update : Msg -> Model -> (Model, Cmd Msg) + Ok val -> + PaletteTextureLoad val + ) + ] + + +update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of TextureError error -> model ! [] + TextureLoad texture -> { model | maybeTexture = Just texture } ! [] + PaletteTextureError error -> model ! [] + PaletteTextureLoad texture -> { model | maybePaletteTexture = Just texture } ! [] -renderChar : Model -> WebGL.Texture -> WebGL.Texture -> Int -> (Int, Int) -> Character -> WebGL.Renderable -renderChar model texture paletteTexture colour (x, y) character = + +renderChar : Model -> WebGL.Texture -> WebGL.Texture -> Int -> ( Int, Int ) -> Character -> WebGL.Renderable +renderChar model texture paletteTexture colour ( x, y ) character = WebGL.render vertexShader fragmentShader - (Dict.get (character.width, character.height) model.meshes |> Maybe.withDefault mesh) + (Dict.get ( character.width, character.height ) model.meshes |> Maybe.withDefault mesh) { screenSize = model.canvasSize , fontTexture = texture , textureSize = model.textureSize @@ -96,27 +126,35 @@ renderChar model texture paletteTexture colour (x, y) character = , theMatrix = Math.Matrix4.translate3 (toFloat x) (toFloat y) 0.0 model.projectionMatrix |> Math.Matrix4.scale3 0.5 0.5 1.0 } -getNextPosition : Character -> (Int, Int) -> (Int, Int) -getNextPosition character (x, y) = + +getNextPosition : Character -> ( Int, Int ) -> ( Int, Int ) +getNextPosition character ( x, y ) = -- Account for double width chars in font texture - (x + 1 + (character.width // 2), y) + ( x + 1 + (character.width // 2), y ) + renderMessage : Model -> WebGL.Texture -> WebGL.Texture -> Message -> List WebGL.Renderable renderMessage model texture paletteTexture message = let - characters = String.toList message.characters - |> List.map (\c -> Dict.get c fontMap |> Maybe.withDefault (Character 102 78 14 10)) - positions = List.scanl getNextPosition (message.x, message.y) characters + characters = + String.toList message.characters + |> List.map (\c -> Dict.get c fontMap |> Maybe.withDefault (Character 102 78 14 10)) + + positions = + List.scanl getNextPosition ( message.x, message.y ) characters in List.map2 (renderChar model texture paletteTexture message.colour) positions characters + render : Model -> List WebGL.Renderable render model = - case (model.maybeTexture, model.maybePaletteTexture) of - (Just texture, Just paletteTexture) -> + case ( model.maybeTexture, model.maybePaletteTexture ) of + ( Just texture, Just paletteTexture ) -> List.map (renderMessage model texture paletteTexture) model.messages |> List.concat - (_, _) -> [] + + ( _, _ ) -> + [] {-| mesh for a character @@ -129,6 +167,7 @@ mesh = , ( Vertex (vec2 0 0), Vertex (vec2 0 1), Vertex (vec2 1 1) ) ] + meshWidthHeight : Float -> Float -> WebGL.Drawable Vertex meshWidthHeight width height = WebGL.Triangle @@ -136,16 +175,16 @@ meshWidthHeight width height = , ( Vertex (vec2 0 0), Vertex (vec2 0 height), Vertex (vec2 width height) ) ] -meshesFromCharacters : Dict.Dict (Int, Int) (WebGL.Drawable Vertex) + +meshesFromCharacters : Dict.Dict ( Int, Int ) (WebGL.Drawable Vertex) meshesFromCharacters = - List.map (\(_, char) -> ((char.width, char.height), meshWidthHeight (toFloat char.width) (toFloat char.height))) fontList + List.map (\( _, char ) -> ( ( char.width, char.height ), meshWidthHeight (toFloat char.width) (toFloat char.height) )) fontList |> Dict.fromList -vertexShader : WebGL.Shader - {attr | position : Vec2 } - {unif | screenSize : Vec2, theMatrix : Mat4 , colour : Int } - {texturePos : Vec2, colourIndex : Float} -vertexShader = [glsl| + +vertexShader : WebGL.Shader { attr | position : Vec2 } { unif | screenSize : Vec2, theMatrix : Mat4, colour : Int } { texturePos : Vec2, colourIndex : Float } +vertexShader = + [glsl| precision mediump float; attribute vec2 position; uniform vec2 screenSize; @@ -161,11 +200,9 @@ vertexShader = [glsl| |] -fragmentShader : WebGL.Shader - {} - {u | fontTexture : WebGL.Texture, textureSize : Vec2, projectionMatrix : Mat4, charCoords : Vec2, paletteTexture : WebGL.Texture, paletteTextureSize : Vec2 } - {texturePos : Vec2, colourIndex : Float } -fragmentShader = [glsl| +fragmentShader : WebGL.Shader {} { u | fontTexture : WebGL.Texture, textureSize : Vec2, projectionMatrix : Mat4, charCoords : Vec2, paletteTexture : WebGL.Texture, paletteTextureSize : Vec2 } { texturePos : Vec2, colourIndex : Float } +fragmentShader = + [glsl| precision mediump float; uniform mat4 projectionMatrix; uniform sampler2D fontTexture; @@ -190,136 +227,141 @@ fragmentShader = [glsl| } |] + + -- https://github.com/andryblack/fontbuilder -- -- {char="A",width=8,x=79,y=12,w=6,h=10,ox=0,oy=10} -- grep Char fonts/pico-8_regular_8.xml | awk -F'"' '{print ", (\'"$8"\', Character "$6, ")"}' | pbcopy -fontList : List (Char, Character) + + +fontList : List ( Char, Character ) fontList = - [ (' ', Character 1 11 0 0 ) - , ('!', Character 2 1 2 10 ) - , ('"', Character 5 1 6 4 ) - , ('#', Character 12 1 6 10 ) - , ('$', Character 19 1 6 10 ) - , ('%', Character 26 1 6 10 ) - , ('&', Character 33 1 6 10 ) - , ('\'', Character 40 1 4 4 ) - , ('(', Character 45 1 4 10 ) - , (')', Character 50 1 4 10 ) - , ('*', Character 55 1 6 10 ) - , ('+', Character 62 3 6 6 ) - , (',', Character 69 7 4 4 ) - , ('-', Character 74 5 6 2 ) - , ('.', Character 81 9 2 2 ) - , ('/', Character 84 1 6 10 ) - , ('0', Character 91 1 6 10 ) - , ('1', Character 98 1 6 10 ) - , ('2', Character 105 1 6 10 ) - , ('3', Character 112 1 6 10 ) - , ('4', Character 119 1 6 10 ) - , ('5', Character 1 12 6 10 ) - , ('6', Character 8 12 6 10 ) - , ('7', Character 15 12 6 10 ) - , ('8', Character 22 12 6 10 ) - , ('9', Character 29 12 6 10 ) - , (':', Character 36 14 2 6 ) - , (';', Character 39 14 4 8 ) - , ('<', Character 44 12 6 10 ) - , ('=', Character 51 14 6 6 ) - , ('>', Character 58 12 6 10 ) - , ('?', Character 65 12 6 10 ) - , ('@', Character 72 12 6 10 ) - , ('A', Character 79 12 6 10 ) - , ('B', Character 86 12 6 10 ) - , ('C', Character 93 12 6 10 ) - , ('D', Character 100 12 6 10 ) - , ('E', Character 107 12 6 10 ) - , ('F', Character 114 12 6 10 ) - , ('G', Character 1 23 6 10 ) - , ('H', Character 8 23 6 10 ) - , ('I', Character 15 23 6 10 ) - , ('J', Character 22 23 6 10 ) - , ('K', Character 29 23 6 10 ) - , ('L', Character 36 23 6 10 ) - , ('M', Character 43 23 6 10 ) - , ('N', Character 50 23 6 10 ) - , ('O', Character 57 23 6 10 ) - , ('P', Character 64 23 6 10 ) - , ('Q', Character 71 23 6 10 ) - , ('R', Character 78 23 6 10 ) - , ('S', Character 85 23 6 10 ) - , ('T', Character 92 23 6 10 ) - , ('U', Character 99 23 6 10 ) - , ('V', Character 106 23 6 10 ) - , ('W', Character 113 23 6 10 ) - , ('X', Character 120 23 6 10 ) - , ('Y', Character 1 34 6 10 ) - , ('Z', Character 8 34 6 10 ) - , ('[', Character 15 34 4 10 ) - , ('\\', Character 20 34 6 10 ) - , (']', Character 27 34 4 10 ) - , ('^', Character 32 34 6 4 ) - , ('_', Character 39 42 6 2 ) - , ('`', Character 46 34 4 4 ) - , ('a', Character 51 36 6 8 ) - , ('b', Character 58 36 6 8 ) - , ('c', Character 65 36 6 8 ) - , ('d', Character 72 36 6 8 ) - , ('e', Character 79 36 6 8 ) - , ('f', Character 86 36 6 8 ) - , ('g', Character 93 36 6 8 ) - , ('h', Character 100 36 6 8 ) - , ('i', Character 107 36 6 8 ) - , ('j', Character 114 36 6 8 ) - , ('k', Character 1 47 6 8 ) - , ('l', Character 8 47 6 8 ) - , ('m', Character 15 47 6 8 ) - , ('n', Character 22 47 6 8 ) - , ('o', Character 29 47 6 8 ) - , ('p', Character 36 47 6 8 ) - , ('q', Character 43 47 6 8 ) - , ('r', Character 50 47 6 8 ) - , ('s', Character 57 47 6 8 ) - , ('t', Character 64 47 6 8 ) - , ('u', Character 71 47 6 8 ) - , ('v', Character 78 47 6 8 ) - , ('w', Character 85 47 6 8 ) - , ('x', Character 92 47 6 8 ) - , ('y', Character 99 47 6 8 ) - , ('z', Character 106 47 6 8 ) - , ('{', Character 113 45 6 10 ) - , ('|', Character 120 45 2 10 ) - , ('}', Character 1 56 6 10 ) - , ('~', Character 8 58 6 6 ) - -- Exciting magical bonus characters :) - , ('À', Character 15 56 14 10 ) - , ('Á', Character 30 56 14 10 ) - , ('Â', Character 45 56 14 10 ) - , ('Ã', Character 60 56 14 10 ) - , ('Ä', Character 75 56 14 10 ) - , ('Å', Character 90 56 10 10 ) - , ('Æ', Character 101 56 10 10 ) - , ('Ç', Character 112 56 10 10 ) - , ('È', Character 1 67 14 10 ) - , ('É', Character 16 67 10 10 ) - , ('Ê', Character 27 67 14 10 ) - , ('Ë', Character 42 67 14 10 ) - , ('Ì', Character 57 67 14 10 ) - , ('Í', Character 72 67 10 10 ) - , ('Î', Character 83 67 14 10 ) - , ('Ï', Character 98 67 10 10 ) - , ('Ð', Character 109 71 14 2 ) - , ('Ñ', Character 1 78 14 10 ) - , ('Ò', Character 16 78 14 10 ) - , ('Ó', Character 31 78 10 10 ) - , ('Ô', Character 42 78 14 10 ) - , ('Õ', Character 57 80 14 6 ) - , ('Ö', Character 72 80 14 6 ) - , ('×', Character 87 78 14 10 ) - , ('Ø', Character 102 78 14 10 ) - , ('Ù', Character 1 89 14 10 ) + [ ( ' ', Character 1 11 0 0 ) + , ( '!', Character 2 1 2 10 ) + , ( '"', Character 5 1 6 4 ) + , ( '#', Character 12 1 6 10 ) + , ( '$', Character 19 1 6 10 ) + , ( '%', Character 26 1 6 10 ) + , ( '&', Character 33 1 6 10 ) + , ( '\'', Character 40 1 4 4 ) + , ( '(', Character 45 1 4 10 ) + , ( ')', Character 50 1 4 10 ) + , ( '*', Character 55 1 6 10 ) + , ( '+', Character 62 3 6 6 ) + , ( ',', Character 69 7 4 4 ) + , ( '-', Character 74 5 6 2 ) + , ( '.', Character 81 9 2 2 ) + , ( '/', Character 84 1 6 10 ) + , ( '0', Character 91 1 6 10 ) + , ( '1', Character 98 1 6 10 ) + , ( '2', Character 105 1 6 10 ) + , ( '3', Character 112 1 6 10 ) + , ( '4', Character 119 1 6 10 ) + , ( '5', Character 1 12 6 10 ) + , ( '6', Character 8 12 6 10 ) + , ( '7', Character 15 12 6 10 ) + , ( '8', Character 22 12 6 10 ) + , ( '9', Character 29 12 6 10 ) + , ( ':', Character 36 14 2 6 ) + , ( ';', Character 39 14 4 8 ) + , ( '<', Character 44 12 6 10 ) + , ( '=', Character 51 14 6 6 ) + , ( '>', Character 58 12 6 10 ) + , ( '?', Character 65 12 6 10 ) + , ( '@', Character 72 12 6 10 ) + , ( 'A', Character 79 12 6 10 ) + , ( 'B', Character 86 12 6 10 ) + , ( 'C', Character 93 12 6 10 ) + , ( 'D', Character 100 12 6 10 ) + , ( 'E', Character 107 12 6 10 ) + , ( 'F', Character 114 12 6 10 ) + , ( 'G', Character 1 23 6 10 ) + , ( 'H', Character 8 23 6 10 ) + , ( 'I', Character 15 23 6 10 ) + , ( 'J', Character 22 23 6 10 ) + , ( 'K', Character 29 23 6 10 ) + , ( 'L', Character 36 23 6 10 ) + , ( 'M', Character 43 23 6 10 ) + , ( 'N', Character 50 23 6 10 ) + , ( 'O', Character 57 23 6 10 ) + , ( 'P', Character 64 23 6 10 ) + , ( 'Q', Character 71 23 6 10 ) + , ( 'R', Character 78 23 6 10 ) + , ( 'S', Character 85 23 6 10 ) + , ( 'T', Character 92 23 6 10 ) + , ( 'U', Character 99 23 6 10 ) + , ( 'V', Character 106 23 6 10 ) + , ( 'W', Character 113 23 6 10 ) + , ( 'X', Character 120 23 6 10 ) + , ( 'Y', Character 1 34 6 10 ) + , ( 'Z', Character 8 34 6 10 ) + , ( '[', Character 15 34 4 10 ) + , ( '\\', Character 20 34 6 10 ) + , ( ']', Character 27 34 4 10 ) + , ( '^', Character 32 34 6 4 ) + , ( '_', Character 39 42 6 2 ) + , ( '`', Character 46 34 4 4 ) + , ( 'a', Character 51 36 6 8 ) + , ( 'b', Character 58 36 6 8 ) + , ( 'c', Character 65 36 6 8 ) + , ( 'd', Character 72 36 6 8 ) + , ( 'e', Character 79 36 6 8 ) + , ( 'f', Character 86 36 6 8 ) + , ( 'g', Character 93 36 6 8 ) + , ( 'h', Character 100 36 6 8 ) + , ( 'i', Character 107 36 6 8 ) + , ( 'j', Character 114 36 6 8 ) + , ( 'k', Character 1 47 6 8 ) + , ( 'l', Character 8 47 6 8 ) + , ( 'm', Character 15 47 6 8 ) + , ( 'n', Character 22 47 6 8 ) + , ( 'o', Character 29 47 6 8 ) + , ( 'p', Character 36 47 6 8 ) + , ( 'q', Character 43 47 6 8 ) + , ( 'r', Character 50 47 6 8 ) + , ( 's', Character 57 47 6 8 ) + , ( 't', Character 64 47 6 8 ) + , ( 'u', Character 71 47 6 8 ) + , ( 'v', Character 78 47 6 8 ) + , ( 'w', Character 85 47 6 8 ) + , ( 'x', Character 92 47 6 8 ) + , ( 'y', Character 99 47 6 8 ) + , ( 'z', Character 106 47 6 8 ) + , ( '{', Character 113 45 6 10 ) + , ( '|', Character 120 45 2 10 ) + , ( '}', Character 1 56 6 10 ) + , ( '~', Character 8 58 6 6 ) + -- Exciting magical bonus characters :) + , ( 'À', Character 15 56 14 10 ) + , ( 'Á', Character 30 56 14 10 ) + , ( 'Â', Character 45 56 14 10 ) + , ( 'Ã', Character 60 56 14 10 ) + , ( 'Ä', Character 75 56 14 10 ) + , ( 'Å', Character 90 56 10 10 ) + , ( 'Æ', Character 101 56 10 10 ) + , ( 'Ç', Character 112 56 10 10 ) + , ( 'È', Character 1 67 14 10 ) + , ( 'É', Character 16 67 10 10 ) + , ( 'Ê', Character 27 67 14 10 ) + , ( 'Ë', Character 42 67 14 10 ) + , ( 'Ì', Character 57 67 14 10 ) + , ( 'Í', Character 72 67 10 10 ) + , ( 'Î', Character 83 67 14 10 ) + , ( 'Ï', Character 98 67 10 10 ) + , ( 'Ð', Character 109 71 14 2 ) + , ( 'Ñ', Character 1 78 14 10 ) + , ( 'Ò', Character 16 78 14 10 ) + , ( 'Ó', Character 31 78 10 10 ) + , ( 'Ô', Character 42 78 14 10 ) + , ( 'Õ', Character 57 80 14 6 ) + , ( 'Ö', Character 72 80 14 6 ) + , ( '×', Character 87 78 14 10 ) + , ( 'Ø', Character 102 78 14 10 ) + , ( 'Ù', Character 1 89 14 10 ) ] + fontMap : Dict.Dict Char Character fontMap = Dict.fromList fontList diff --git a/src/Elmo8/Pico8.elm b/src/Elmo8/Pico8.elm index e62d020..61f8ab3 100644 --- a/src/Elmo8/Pico8.elm +++ b/src/Elmo8/Pico8.elm @@ -1,7 +1,25 @@ -module Elmo8.Pico8 exposing - ( black, darkblue, darkpurple, darkgreen, brown, darkgrey, lightgrey, white, red, orange, yellow, green, blue, indigo, pink, peach - , pset, spr, print - ) +module Elmo8.Pico8 + exposing + ( black + , darkblue + , darkpurple + , darkgreen + , brown + , darkgrey + , lightgrey + , white + , red + , orange + , yellow + , green + , blue + , indigo + , pink + , peach + , pset + , spr + , print + ) {-| (Mostly) PICO-8 Compatible API @@ -25,85 +43,117 @@ The PICO-8 has a fairly snazzy palette of 16 colours, identified by an int from import Elmo8.Console exposing (Command) + {-| Black (0) -} black : Int -black = 0 +black = + 0 + {-| Dark Blue (1) -} darkblue : Int -darkblue = 1 +darkblue = + 1 + {-| Dark Purple (2) -} darkpurple : Int -darkpurple = 2 +darkpurple = + 2 + {-| Dark Green (3) -} darkgreen : Int -darkgreen = 3 +darkgreen = + 3 + {-| Brown (4) -} brown : Int -brown = 4 +brown = + 4 + {-| Dark Grey (5) -} darkgrey : Int -darkgrey = 5 +darkgrey = + 5 + {-| Light Grey (6) -} lightgrey : Int -lightgrey = 6 +lightgrey = + 6 + {-| White (7) -} white : Int -white = 7 +white = + 7 + {-| Red (8) -} red : Int -red = 8 +red = + 8 + {-| Orange (9) -} orange : Int -orange = 9 +orange = + 9 + {-| Yellow (10) -} yellow : Int -yellow = 10 +yellow = + 10 + {-| Green (11) -} green : Int -green = 11 +green = + 11 + {-| Blue (12) -} blue : Int -blue = 12 +blue = + 12 + {-| Indigo (13) -} indigo : Int -indigo = 13 +indigo = + 13 + {-| Ping (14) -} pink : Int -pink = 14 +pink = + 14 + {-| Peach (15) -} peach : Int -peach = 15 +peach = + 15 {-| Set the colour of a pixel at (x,y) using colour (c) @@ -118,6 +168,7 @@ pset : Int -> Int -> Int -> Command pset x y colour = Elmo8.Console.putPixel x y colour + {-| Draw a sprite n at (x,y) Sames as PICO-8's `spr n x y [w h] [flip_x] [flip_y]` @@ -134,6 +185,7 @@ spr : Int -> Int -> Int -> Int -> Int -> Bool -> Bool -> Command spr index x y width height flip_x flip_y = Elmo8.Console.sprite index x y + {-| Print string (str) at (x,y) using colour (c) Same as PICO-8's `print str [x y [col]]`. diff --git a/src/Elmo8/Textures/Pico8Font.elm b/src/Elmo8/Textures/Pico8Font.elm index cb747f4..440e088 100644 --- a/src/Elmo8/Textures/Pico8Font.elm +++ b/src/Elmo8/Textures/Pico8Font.elm @@ -1,7 +1,8 @@ module Elmo8.Textures.Pico8Font exposing (..) -- Generated from pico-8_regular_8.png -pico8FontDataUri: String + + +pico8FontDataUri : String pico8FontDataUri = "data:image/png;base64,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" - diff --git a/src/Elmo8/Textures/Pico8PaletteMap.elm b/src/Elmo8/Textures/Pico8PaletteMap.elm index 4e0be09..9915d62 100644 --- a/src/Elmo8/Textures/Pico8PaletteMap.elm +++ b/src/Elmo8/Textures/Pico8PaletteMap.elm @@ -1,7 +1,8 @@ module Elmo8.Textures.Pico8PaletteMap exposing (..) -- Generated from pico-8-palette-map.png -pico8PaletteMapDataUri: String + + +pico8PaletteMapDataUri : String pico8PaletteMapDataUri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAANNJREFUOBGlkzsKwlAQRe+MWNlapk4RSBELmyxA9yBoI0JAFFyF23ABNjYBdQsG0lnbpxOsdGSEB0HyeUkWcDh3PpcAiBuusH4Dm/kHl/SBuOdgttxi5DrAeAfsD0AYgF5D+PczouSIqD8AJgTuApM3Bbc1K6xybhPbwCrnpjPnYZVzk4X9wyqnW5KKzbaLYJWTPDOpO1UZrKcm8RZSdecqWJOTnCBlT1IHa3KSLJCiD7OBNTl3gX/J/atI/rdtzWZs7gJrsdi0qqnZtJK1km1hlX8Bnpcdm8aa7AQAAAAASUVORK5CYII=" -