diff --git a/.gitignore b/.gitignore index 48b0632..e9f74f3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ elm.js index.html _site .sass-cache +_example diff --git a/Makefile b/Makefile index b2d8bac..6d83d9c 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,44 @@ PICO_8_PALETTE_MAP_ELM=src/Elmo8/Textures/Pico8PaletteMap.elm PICO_8_PALETTE_MAP_PNG=palettes/pico-8-palette-map.png + PICO_8_FONT_ELM=src/Elmo8/Textures/Pico8Font.elm PICO_8_FONT_PNG=font/pico-8_regular_8.png + CONVERTER=tools/convert_to_data_uri.py + SOURCES=$(shell find examples src -name '*.elm') .PHONY: all -all: $(PICO_8_PALETTE_MAP_ELM) $(PICO_8_FONT_ELM) +all: $(PICO_8_PALETTE_MAP_ELM) $(PICO_8_FONT_ELM) examples $(PICO_8_PALETTE_MAP_ELM): Makefile $(CONVERTER) $(PICO_8_PALETTE_MAP_PNG) + mkdir -p src/Elmo8/Textures python3 $(CONVERTER) \ Elmo8.Textures.Pico8PaletteMap \ pico8PaletteMapDataUri \ image/png \ $(PICO_8_PALETTE_MAP_PNG) \ $(PICO_8_PALETTE_MAP_ELM) + elm format --yes $(PICO_8_PALETTE_MAP_ELM) $(PICO_8_FONT_ELM): Makefile $(CONVERTER) $(PICO_8_FONT_PNG) + mkdir -p src/Elmo8/Textures python3 $(CONVERTER) \ Elmo8.Textures.Pico8Font \ pico8FontDataUri \ image/png \ $(PICO_8_FONT_PNG) \ $(PICO_8_FONT_ELM) + elm format --yes $(PICO_8_FONT_ELM) + +.PHONY: examples +examples: + mkdir -p _example + elm make --output _example/examples.js examples/*.elm + cp examples/*.png _example/ + mkdir -p assets + cp $(PICO_8_PALETTE_MAP_PNG) assets/ + cp $(PICO_8_FONT_PNG) assets/ documentation.json: $(SOURCES) elm make --docs=documentation.json --warn @@ -34,3 +50,4 @@ format: .PHONY: upgrade upgrade: elm upgrade + diff --git a/assets/pico-8-palette-map.png b/assets/pico-8-palette-map.png new file mode 100644 index 0000000..2d3136d Binary files /dev/null and b/assets/pico-8-palette-map.png differ diff --git a/assets/pico-8_regular_8.png b/assets/pico-8_regular_8.png new file mode 100644 index 0000000..066b329 Binary files /dev/null and b/assets/pico-8_regular_8.png differ diff --git a/elm-package.json b/elm-package.json index 08542c6..d6f2d34 100644 --- a/elm-package.json +++ b/elm-package.json @@ -17,7 +17,8 @@ "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-lang/window": "1.0.1 <= v < 2.0.0", + "nphollon/update-clock": "1.0.3 <= v < 2.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/src/Elmo8/Assets.elm b/src/Elmo8/Assets.elm new file mode 100644 index 0000000..327605b --- /dev/null +++ b/src/Elmo8/Assets.elm @@ -0,0 +1,28 @@ +module Elmo8.Assets exposing (..) + +import WebGL +import Task + + +type alias URL = + String + + +{-| Try multiple sources to load texture + +Give a list of URLs to try, e.g.: + +- data url (not always available due to CORS) +- relative url (loads from same place as code) +- fallback CDN (will work except when there are network issues, least prefereble) + +-} +loadWebglTextureWithFallbacks : List URL -> Task.Task WebGL.Error WebGL.Texture +loadWebglTextureWithFallbacks urls = + case urls of + [] -> + Task.fail WebGL.Error + + url :: remainingUrls -> + WebGL.loadTexture url + |> Task.onError (\_ -> loadWebglTextureWithFallbacks remainingUrls) diff --git a/src/Elmo8/Layers/Common.elm b/src/Elmo8/Layers/Common.elm index 8f8dbe3..7a6b956 100644 --- a/src/Elmo8/Layers/Common.elm +++ b/src/Elmo8/Layers/Common.elm @@ -12,11 +12,21 @@ import Math.Matrix4 exposing (Mat4, makeOrtho2D) -- TODO: configure this at app startup, with sensible defaults +pico8FontRelativeUri : String +pico8FontRelativeUri = + "/assets/pico-8_regular_8.png" + + pico8FontUri : String pico8FontUri = "http://elmo-8.twomeylee.name/assets/pico-8_regular_8.png" +pico8PaletteMapRelativeUri : String +pico8PaletteMapRelativeUri = + "/assets/pico-8-palette-map.png" + + pico8PaletteMapUri : String pico8PaletteMapUri = "http://elmo-8.twomeylee.name/assets/pico-8-palette-map.png" diff --git a/src/Elmo8/Layers/Pixels.elm b/src/Elmo8/Layers/Pixels.elm index cd360ad..eaab7dc 100644 --- a/src/Elmo8/Layers/Pixels.elm +++ b/src/Elmo8/Layers/Pixels.elm @@ -11,7 +11,9 @@ import Math.Vector2 exposing (Vec2, vec2, fromTuple) import Math.Matrix4 exposing (Mat4, makeOrtho2D) import Task import WebGL -import Elmo8.Layers.Common exposing (CanvasSize, Vertex, makeProjectionMatrix, pico8PaletteMapUri) +import Elmo8.Assets +import Elmo8.Layers.Common exposing (CanvasSize, Vertex, makeProjectionMatrix, pico8PaletteMapUri, pico8PaletteMapRelativeUri) +import Elmo8.Textures.Pico8PaletteMap exposing (pico8PaletteMapDataUri) type alias X = @@ -97,7 +99,7 @@ init canvasSize = , paletteSize = vec2 16.0 16.0 , projectionMatrix = makeProjectionMatrix } - ! [ WebGL.loadTexture pico8PaletteMapUri + ! [ Elmo8.Assets.loadWebglTextureWithFallbacks [ pico8PaletteMapDataUri, pico8PaletteMapRelativeUri, pico8PaletteMapUri ] |> Task.attempt (\result -> case result of diff --git a/src/Elmo8/Layers/Text.elm b/src/Elmo8/Layers/Text.elm index 0abc75c..9cc1133 100644 --- a/src/Elmo8/Layers/Text.elm +++ b/src/Elmo8/Layers/Text.elm @@ -6,7 +6,10 @@ import Math.Matrix4 exposing (Mat4, makeOrtho2D) import String import Task import WebGL +import Elmo8.Assets import Elmo8.Layers.Common exposing (CanvasSize, Vertex, makeProjectionMatrix, pico8FontUri, pico8PaletteMapUri) +import Elmo8.Textures.Pico8Font exposing (pico8FontDataUri) +import Elmo8.Textures.Pico8PaletteMap exposing (pico8PaletteMapDataUri) -- TODO: represent more of the metrics for better layout. @@ -68,7 +71,7 @@ init canvasSize = , maybePaletteTexture = Nothing , paletteTextureSize = vec2 16.0 16.0 } - ! [ WebGL.loadTexture pico8FontUri + ! [ Elmo8.Assets.loadWebglTextureWithFallbacks [ pico8FontDataUri, "/assets/pico-8_regular_8.png", pico8FontUri ] |> Task.attempt (\result -> case result of @@ -78,7 +81,7 @@ init canvasSize = Ok val -> TextureLoad val ) - , WebGL.loadTexture pico8PaletteMapUri + , Elmo8.Assets.loadWebglTextureWithFallbacks [ pico8PaletteMapDataUri, "/assets/pico-8-palette-map.png", pico8PaletteMapUri ] |> Task.attempt (\result -> case result of diff --git a/src/Elmo8/Pico8.elm b/src/Elmo8/Pico8.elm index 61f8ab3..3fa15ec 100644 --- a/src/Elmo8/Pico8.elm +++ b/src/Elmo8/Pico8.elm @@ -37,6 +37,8 @@ Even if a function has the full PICO-8 function signature note all flags might b The PICO-8 has a fairly snazzy palette of 16 colours, identified by an int from 0 to 15. You can also use these handy identifiers. +You can view the palette (and download appropriate palettes for your apps) here: http://www.romanzolotarev.com/pico-8-color-palette/ + @docs black, darkblue, darkpurple, darkgreen, brown, darkgrey, lightgrey, white, red, orange, yellow, green, blue, indigo, pink, peach -} diff --git a/src/Elmo8/Textures/Pico8Font.elm b/src/Elmo8/Textures/Pico8Font.elm new file mode 100644 index 0000000..440e088 --- /dev/null +++ b/src/Elmo8/Textures/Pico8Font.elm @@ -0,0 +1,8 @@ +module Elmo8.Textures.Pico8Font exposing (..) + +-- Generated from pico-8_regular_8.png + + +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 new file mode 100644 index 0000000..9915d62 --- /dev/null +++ b/src/Elmo8/Textures/Pico8PaletteMap.elm @@ -0,0 +1,8 @@ +module Elmo8.Textures.Pico8PaletteMap exposing (..) + +-- Generated from pico-8-palette-map.png + + +pico8PaletteMapDataUri : String +pico8PaletteMapDataUri = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAANNJREFUOBGlkzsKwlAQRe+MWNlapk4RSBELmyxA9yBoI0JAFFyF23ABNjYBdQsG0lnbpxOsdGSEB0HyeUkWcDh3PpcAiBuusH4Dm/kHl/SBuOdgttxi5DrAeAfsD0AYgF5D+PczouSIqD8AJgTuApM3Bbc1K6xybhPbwCrnpjPnYZVzk4X9wyqnW5KKzbaLYJWTPDOpO1UZrKcm8RZSdecqWJOTnCBlT1IHa3KSLJCiD7OBNTl3gX/J/atI/rdtzWZs7gJrsdi0qqnZtJK1km1hlX8Bnpcdm8aa7AQAAAAASUVORK5CYII="